all repos — min @ c560d16ad86ddd591458a4e487f442e597af9731

A small but practical concatenative programming language.

Updated docs.
h3rald h3rald@h3rald.com
Sun, 03 Jun 2018 13:10:09 +0200
commit

c560d16ad86ddd591458a4e487f442e597af9731

parent

126d4a3ae7e15d15e54713231d1134ce15bd819c

M site/contents/_defs_.mdsite/contents/_defs_.md

@@ -7,8 +7,8 @@ {{1 => [<sub>1</sub>](class:kwd)}}

{{2 => [<sub>2</sub>](class:kwd)}} {{3 => [<sub>3</sub>](class:kwd)}} {{4 => [<sub>4</sub>](class:kwd)}} -{{e => [err](class:kwd)}} -{{tinfo => [tinfo](class:kwd)}} +{{e => [dict:error](class:kwd)}} +{{tinfo => [dict:timeinfo](class:kwd)}} {{d => [dict](class:kwd)}} {{d1 => [dict<sub>1</sub>](class:kwd)}} {{d2 => [dict<sub>2</sub>](class:kwd)}}

@@ -45,11 +45,11 @@ {{sl2 => [&apos;sym<sub>2</sub>](class:kwd)}}

{{f => [false](class:kwd)}} {{t => [true](class:kwd)}} {{null => &#x2205;}} -{{sock => [socket](class:kwd)}} +{{sock => [dict:socket](class:kwd)}} {{req => [request](class:kwd)}} {{res => [response](class:kwd)}} -{{sock1 => [socket<sub>1</sub>](class:kwd)}} -{{sock2 => [socket<sub>2</sub>](class:kwd)}} +{{sock1 => [dict:socket<sub>1</sub>](class:kwd)}} +{{sock2 => [dict:socket<sub>2</sub>](class:kwd)}} {{m => _min_}} {{sgregex => [sgregex](https://github.com/snake5/sgregex).}}
M site/contents/learn-control-flow.mdsite/contents/learn-control-flow.md

@@ -79,3 +79,5 @@ ) map

1 (+) reduce This program calculates the size in bytes of all files included in the current directory. Because the {#link-operator||fs||fsize#} symbol throws an error if the argument provided is not a file (for example if it is a directory), the `try` symbol is used to remove the error from the stack and push `0` on the stack instead. + +{#link-learn||shell||Shell#}
M site/contents/learn-data-types.mdsite/contents/learn-data-types.md

@@ -14,20 +14,20 @@ : A floating-point number like 3.14 or -56.9876.

string : A series of characters wrapped in double quotes: "Hello, World!". quotation -: A list of elements, which may also contain symbols. Quotations can be be used to create heterogenous lists of elements of any data type, and also to create a block of code that will be evaluated later on (quoted program). +: A list of elements, which may also contain symbols. Quotations can be be used to create heterogenous lists of elements of any data type, and also to create a block of code that will be evaluated later on (quoted program). Example: (1 2 3 + \*) +dictionary +: A key/value table. Dictionaries are implemented as an immediately-dequoted quotation, are enclosed in curly braces, and are represented by their symbol definitions. Note that dictionary keys are symbols and therefore can only contain characters allowed in symbols. The {#link-module||dict#} provides some operators on dictionaries. -Additionally, quotations structured in a particular way can be used as dictionaries, and a few operators are available to manage them more easily (`dhas?`, `dget`, `ddel` and `dset`). A dictionary is a quotation containing zero or more quotations of two elements, the first of which is a string that has not already be used in any of the other inner quotations. - -> %sidebar% -> Example -> -> The following is a simple dictionary containing three keys: *name*, *paradigm*, and *first-release-year*: -> -> ( -> ("name" "min") -> ("paradigm" "concatenative") -> ("first-release-year" 2017) -> ) + > %sidebar% + > Example + > + > The following is a simple dictionary containing three keys: *name*, *paradigm*, and *first-release-year*: + > + > { + > "min" :name + > "concatenative" :paradigm + > 2017 :first-release-year + > } The {#link-module||logic#} provides predicate operators to check if an element belong to a particular data type or pseudo-type (`boolean?`, `number?`, `integer?`, `float?`, `string?`, `quotation?`, `dictionary?`).
M site/contents/learn-extending.mdsite/contents/learn-extending.md

@@ -96,7 +96,7 @@

> %warning% > Warning > -> This technique is currently experimental, it has not been tested extensively and it may not even work on Windows. +> This technique is currently highly experimental, it has not been tested extensively and it may not even work properly. If you just want to add a new module to min providing functinalities that cannot be built natively with min operators, you can also implement a min module in Nim and compile it to a dynamic library which can be linked dynamically when min is started.
A site/contents/reference-dict.md

@@ -0,0 +1,51 @@

+----- +content-type: "page" +title: "dict Module" +----- +{@ _defs_.md || 0 @} + +{#sig||/||dget#} + +{#sig||?||dhas?#} + +{#sig||%||dset#} + +{#op||ddup||{{d1}}||{{d2}}|| +Returns a copy of {{d1}}. #} + +{#op||ddel||{{d}} {{sl}}||{{d}}|| +Removes {{sl}} from {{d1}} and returns {{d1}}. #} + +{#op||dget||{{d}} {{sl}}||{{any}}|| +Returns the value of key {{sl}} from dictionary {{d}}. #} + +{#op||dhas?||{{d}} {{sl}}||{{b}}|| +> Returns {{t}} if dictionary {{d}} contains the key {{sl}}, {{f}} otherwise. +> +> > %sidebar% +> > Example +> > +> > The following program returns {{t}}: +> > +> > {true :a1 "aaa" :a2 false :a3} 'a2 dhas? + #} + +{#op||dkeys||{{d}}||({{s}}{{0p}})|| +Returns a quotation containing all the keys of dictionary {{d}}. #} + +{#op||dpick||{{d1}} {{q}}||{{d2}}|| +> Returns a new dictionary {{d2}} containing the elements of {{d1}} whose keys are included in {{q}}. +> +> > %sidebar% +> > Example +> > +> > The following program returns `{4 :a 7 :d}`: +> > +> > {5 :q 4 :a 6 :c 7 :d "d" :a} ("a" "d") dpick + #} + +{#op||dset||{{d}} {{any}} {{sl}}||{{d}}|| +Sets the value of the {{sl}} of {{d1}} to {{any}}, and returns the modified dictionary {{d}}. #} + +{#op||dvalues||{{d}}||({{a0p}})|| +Returns a quotation containing all the values of dictionary {{d}}. #}
M site/contents/reference-fs.mdsite/contents/reference-fs.md

@@ -23,22 +23,22 @@ > > Example

> > > > Assuming that `min` is a file, the following: > > -> > `'min fstats` +> > `"min" fstats` > > > > produces: > > -> > ( -> > ("name" (min)) -> > ("device" 16777220) -> > ("file" 50112479) -> > ("type" "file") -> > ("size" 617068) -> > ("permissions" 755) -> > ("nlinks" 1) -> > ("ctime" 1496583112.0) -> > ("atime" 1496584370.0) -> > ("mtime" 1496583112.0) -> > )#} +> > { +> > "min" :name +> > 16777220 :device +> > 50112479 :file +> > "file" :type +> > 617068 :size +> > 755 :permissions +> > 1 :nlinks +> > 1496583112.0 :ctime +> > 1496584370.0 :atime +> > 1496583112.0 :mtime +> > }#} {#op||ftype||{{sl}}||{{s}}|| Returns the type of file/directory {{sl}} (`"file"` or `"dir"`).#}
M site/contents/reference-http.mdsite/contents/reference-http.md

@@ -18,7 +18,7 @@ > > Example

> > > > The following code constructs a {{req}} dictionary using the **tap** operator and passes it to the **request** operator to perform an HTTP GET request to <http://httpbin.org/ip>: > > -> > () ( +> > {} ( > > ("GET" %method) > > ("http://httpbin.org/ip" %url) > > ) tap request

@@ -42,7 +42,7 @@ > >

> > The following program starts a very simple HTTP server that can display the current timestamp or date and time in ISO 8601 format: > > > > ( -> > =req +> > :req > > req /url :url > > ;Set response body > > "Invalid Request: $1" (url) => % :body

@@ -57,18 +57,16 @@ > > "Stopping server..." puts!

> > stop-server > > ) when > > ;Prepare response -> > () ( -> > (body %body) -> > ) tap +> > {body :body} > > ) =handler > > > > ;Start server > > "Server started on port 5555." puts! > > "Press Ctrl+C to stop." puts! -> > () ( -> > (handler %handler) -> > (5555 %port) -> > ) tap start-server +> > { +> > handler :handler +> > 5555 :port +> > } tap start-server #} {#op||stop-server||{{null}}||{{null}}||
M site/contents/reference-lang.mdsite/contents/reference-lang.md

@@ -57,8 +57,8 @@ > * If {{any}} is a non-zero numeric value, it is converted to {{t}}, otherwise it is converted to {{f}}.

> * If {{any}} is a non-empty quotation, it is converted to {{t}}, otherwise it is converted to {{f}}. > * If {{any}} is a non-empty string or not `"false"`, it is converted to {{t}}, otherwise it is converted to {{f}}.#} -{#op||call||{{q}} {{sl}}||{{a0p}}|| -Calls operator {{sl}} defined in scope {{q}}. #} +{#op||call||{{d}} {{sl}}||{{a0p}}|| +Calls operator {{sl}} defined in dictionary {{d}}. #} {#op||case||(({{q1}} {{q2}}){{0p}})||{{a0p}}|| > This operator takes a quotation containing _n_ different conditional branches.

@@ -98,7 +98,14 @@ {#op||exit||{{i}}||{{null}}||

Exits the program or shell with {{i}} as return code. #} {#op||expect||{{q1}}||{{q2}}|| -> Validates the first _n_ elements of the stack against the type descriptions specified in {{q1}} (_n_ is {{q1}}'s length) and if all the elements are valid returns them wrapped in {{q2}} (in reverse order). +> Validates the first _n_ elements of the stack against the type descriptions specified in {{q1}} (_n_ is {{q1}}'s length) and if all the elements are valid returns them wrapped in {{q2}} (in reverse order). + +> > %tip% +> > Tips +> > +> > * You can specify a typed dictionary by prepending the type name with `dict:`. Example: `dict:socket` +> > * You can specify two or more matching types by separating the type names with a pipe: `string|quot` + > > %sidebar% > > Example > >

@@ -129,7 +136,7 @@ > > Example

> > > > The following: > > -> > `((error "MyError") (message "This is a test error")) format-error` +> > `{"MyError" :error "This is a test error" :message} 'error set-type format-error` > > > > produces: `"This is a test error"`#}

@@ -191,14 +198,14 @@ > > Note

> > > > The default logging level is _notice_.#} -{#op||module||{{q}} {{sl}}||{{null}}|| -Creates a new module {{sl}} based on quotation {{q}}. #} +{#op||module||{{d}} {{sl}}||{{null}}|| +Creates a new module {{sl}} based on dictionary {{d}}. #} -{#op||module-sigils||{{q}}||({{s0p}})|| -Returns a list of all sigils defined in module {{q}}.#} +{#op||scope-sigils||{{d}}||({{s0p}})|| +Returns a list of all sigils defined in dictionary {{d}}.#} -{#op||module-symbols||{{q}}||({{s0p}})|| -Returns a list of all symbols defined in module {{q}}.#} +{#op||scope-symbols||{{d}}||({{s0p}})|| +Returns a list of all symbols defined in dictionary {{d}}.#} {#op||opts||{{null}}||{{d}}|| Returns a dictionary of all options passed to the current program, with their respective values.#}

@@ -213,8 +220,8 @@ > ("[$1]$$ " (.) => %)

> > Unlike other predefined symbols, this symbol is _unsealed_, which means it can be modified.#} -{#op||publish||{{sl}} {{q}}||{{null}}|| -> Publishes symbol {{sl}} to the scope of {{q}}. +{#op||publish||{{sl}} {{d}}||{{null}}|| +> Publishes symbol {{sl}} to the scope of {{d}}. > > > %sidebar% > > Example

@@ -254,6 +261,9 @@ Saves the contents of symbol {{sl}} to the [.min\_symbols](class:file) file. #}

{#op||seal||{{sl}}||{{null}}|| Seals symbol {{sl}}, so that it cannot be re-assigned. #} + +{#op||set-type||{{d}} {{sl}}||{{d}}|| +Sets the type for dictionary {{d}} to {{sl}}.#} {#op||sigils||{{null}}||({{s0p}})|| Returns a list of all sigils defined in the [ROOT](class:kwd) scope.#}
M site/contents/reference-logic.mdsite/contents/reference-logic.md

@@ -108,6 +108,9 @@

{#op||quotation?||{{any}}||{{b}}|| Returns {{t}} if {{any}} is a quotation, {{f}} otherwise. #} +{#op||type?||{{any}} {{sl}}||{{b}}|| +Returns {{t}} if {{any}} is a dictionary of the specified type {{sl}}, {{f}} otherwise. #} + {#op||xor||{{b1}} {{b2}}||{{b3}}|| Returns {{t}} if {{b1}} and {{b2}} are different, {{f}} otherwise.#}
M site/contents/reference-net.mdsite/contents/reference-net.md

@@ -18,7 +18,7 @@ > > Example

> > > > The following code shows how to send a message to a server running on localhost:7777. The message is passed as the first argument to the program. > > -> > () socket "localhost" 7777 connect =cli +> > {} socket "localhost" 7777 connect =cli > > > > args 1 get :msg > >

@@ -44,11 +44,11 @@ > > Example

> > > > The following code shows how to create a simple server that listens on port 7777, prints data received from clients, and exits when it receives the string `exit`: > > -> > () socket (("address" "127.0.0.1") ("port" 7777)) listen =srv +> > {} socket {"127.0.0.1" :address 7777 :port} listen =srv > > > > "Server listening on localhost:7777" puts! > > -> > () socket =cli +> > {} socket =cli > > "" :line > > (line "exit" !=) > > (

@@ -74,12 +74,12 @@ > >

> > The following code shows how to make a simple GET request to <http://httpbin.org/uuid> to receive a random UUID and display its response: > > > > -> > () socket "httpbin.org" 80 connect =cli +> > {} socket "httpbin.org" 80 connect =cli > > > > cli "GET /uuid HTTP/1.1\r\nHost: httpbin.org\r\n\r\n" send > > > > cli recv-line puts :line -> > (line "}" !=) +> > (line "\}" match not) > > ( > > cli recv-line puts @line > > ) while
M site/contents/reference.mdsite/contents/reference.md

@@ -11,7 +11,9 @@ : Defines the basic language constructs, such as control flow, type conversions, symbol definition and binding, exception handling, etc.

{#link-module||stack#} : Defines combinators and stack-shufflers like dip, dup, swap, cons, etc. {#link-module||seq#} -: Defines operators for quotations and dictionaries, like map, filter, reduce, etc. +: Defines operators for quotations, like map, filter, reduce, etc. +{#link-module||dict#} +: Defines operators for dictionaries, like dget, ddup, dset, etc. {#link-module||io#} : Provides operators for reading and writing files as well as printing to STDOUT and reading from STDIN. {#link-module||fs#}

@@ -65,62 +67,65 @@ : A dictionary value.

{{tinfo}} : A timeinfo dictionary: - ( - ("year" 2017) - ("month" 7) - ("day" 8) - ("weekday" 6) - ("yearday" 188) - ("hour" 15) - ("minute" 16) - ("second" 25) - ("dst" true) - ("timezone" -3600) - ) + { + 2017 :year + 7 :month + 8 :day + 6 :weekday + 188 :yearday + 15 :hour + 16 :minute + 25 :second + true :dst + -3600 :timezone + ;timeinfo + } {{e}} : An error dictionary: - ( - ("error" "MyError") - ("message" "An error occurred") - ("symbol" "symbol1") - ("filename" "dir1/file1.min") - ("line" 3) - ("column" 13) - ) + { + "MyError" :error + "An error occurred" :message + "symbol1" :symbol + "dir1/file1.min" :filename + 3 :line + 13 :column + ;error + } {{sock}} : A socket dictionary that must be created through the {#link-operator||net||socket#} operator: - ( - ("domain" "ipv4") - ("type" "stream") - ("protocol" "tcp") + { + "ipv4" :domain + "stream" :type + "tcp" :protocol ;socket - ) + } {{req}} : A request dictionary, representing an HTTP request to be performed through the operators exposed by the {#link-module||http#}: - ( - ("url" "http://httpbin.org/put") - ("method" "PUT") - ("version" "1.1") ;optional - ("hostname" "h3rald.com") ;optional - ("headers" ( ;optional - ("Accept-Language" "it-id") - ("Host" "httpbin.org"))) - ("body" "test body") ;optional - ) + { + "http://httpbin.org/put" :url + "PUT" :method + "1.1" :version ;optional + "h3rald.com" :hostname ;optional + { + "it-id" :Accept-Language + "httpbin.org" :Host + } :headers ;optional + "test body" :body ;optional + } {{res}} : A response dictionary, representing an HTTP response returned by some of the operators exposed by the {#link-module||http#}: - ( - ("version" "1.1") ;optional - ("status" 200) ;optional - ("headers" ;optional - (("Content-Type" "application/json"))) - ("body" ;optional - "{\"test\": \"This is a test\"}") - ) + { + "1.1" :version ;optional + 200 :status ;optional + { + "application/json" :Content-Type + } :headers ;optional + "{\"test\": \"This is a test\"}" :body + } {{t}} : true (boolean type). {{f}}
M site/settings.jsonsite/settings.json

@@ -5,6 +5,6 @@ "templates": "templates",

"temp": "temp", "output": "output", "title": "min language", - "version": "0.16.0", + "version": "0.17.0", "rules": "rules.min" }