all repos — min @ 096d17f697e672f20468254dbcf9b0973dab326d

A small but practical concatenative programming language.

Added quote-map, dequote-and, dequote-or + fixed docs.
* Closes #15
* Closes #16
h3rald h3rald@h3rald.com
Sat, 18 Nov 2017 21:12:04 +0100
commit

096d17f697e672f20468254dbcf9b0973dab326d

parent

b77cb210a0a14d45a329fdee9d6ab183166ef2c9

M Min_DeveloperGuide.htmMin_DeveloperGuide.htm

@@ -4526,11 +4526,11 @@

<p>You can download one of the following pre-built min binaries:</p> <ul> -<li><a href="https://github.com/h3rald/min/releases/download/v0.12.0/min_v0.12.0_macosx_x64.zip">min v0.12.0 for macOS (x64)</a></li> -<li><a href="https://github.com/h3rald/min/releases/download/v0.12.0/min_v0.12.0_windows_x64.zip">min v0.12.0 for Windows (x64)</a></li> -<li><a href="https://github.com/h3rald/min/releases/download/v0.12.0/min_v0.12.0_linux_x64.zip">min v0.12.0 for Linux (x64)</a></li> -<li><a href="https://github.com/h3rald/min/releases/download/v0.12.0/min_v0.12.0_linux_x86.zip">min v0.12.0 for Linux (x86)</a></li> -<li><a href="https://github.com/h3rald/min/releases/download/v0.12.0/min_v0.12.0_linux_arm.zip">min v0.12.0 for Linux (arm)</a></li> +<li><a href="https://github.com/h3rald/min/releases/download/v0.13.0/min_v0.13.0_macosx_x64.zip">min v0.13.0 for macOS (x64)</a></li> +<li><a href="https://github.com/h3rald/min/releases/download/v0.13.0/min_v0.13.0_windows_x64.zip">min v0.13.0 for Windows (x64)</a></li> +<li><a href="https://github.com/h3rald/min/releases/download/v0.13.0/min_v0.13.0_linux_x64.zip">min v0.13.0 for Linux (x64)</a></li> +<li><a href="https://github.com/h3rald/min/releases/download/v0.13.0/min_v0.13.0_linux_x86.zip">min v0.13.0 for Linux (x86)</a></li> +<li><a href="https://github.com/h3rald/min/releases/download/v0.13.0/min_v0.13.0_linux_arm.zip">min v0.13.0 for Linux (arm)</a></li> </ul>

@@ -5460,15 +5460,27 @@ <p>See <a href="#op-apply">apply</a>.</p></div>

<p><span class="reference-title">#</span> <span class="sigil"></span></p> -<div class="operator"><p><span class="kwd"> #<span class="kwd">string</span> <strong>&rArr;</strong> <span class="kwd">string</span> quote-define</span></p> +<div class="operator"><p><span class="kwd"> #<span class="kwd">string</span> <strong>&rArr;</strong> <span class="kwd">string</span> quote-bind</span></p> -<p>See <a href="#op-quote-define">quote-define</a>.</p></div> +<p>See <a href="#op-quote-bind">quote-bind</a>.</p></div> -<p><span class="reference-title">=</span> <span class="sigil"></span></p> +<p><span class="reference-title">#</span></p> -<div class="operator"><p><span class="kwd"> =<span class="kwd">string</span> <strong>&rArr;</strong> <span class="kwd">string</span> quote-bind</span></p> +<div class="operator"><p><span class="kwd"> # <strong>&rArr;</strong> quote-bind</span></p> <p>See <a href="#op-quote-bind">quote-bind</a>.</p></div> + +<p><span class="reference-title">=</span> <span class="sigil"></span></p> + +<div class="operator"><p><span class="kwd"> =<span class="kwd">string</span> <strong>&rArr;</strong> <span class="kwd">string</span> quote-define</span></p> + +<p>See <a href="#op-quote-define">quote-define</a>.</p></div> + +<p><span class="reference-title">=</span></p> + +<div class="operator"><p><span class="kwd"> = <strong>&rArr;</strong> quote-define</span></p> + +<p>See <a href="#op-quote-define">quote-define</a>.</p></div> <p><a id="op-apply"></a> <span class="reference-title">apply</span></p>

@@ -5539,20 +5551,6 @@ ((true) ("Exactly 3" put!))

) case </code></pre></div></div> -<p><a id="op-debug"></a> -<span class="reference-title">debug</span></p> - -<div class="operator"><p><span class="kwd"> &#x2205; <strong>&rArr;</strong> &#x2205;</span></p> - -<p>Toggles debug mode.</p></div> - -<p><a id="op-debug?"></a> -<span class="reference-title">debug?</span></p> - -<div class="operator"><p><span class="kwd"> &#x2205; <strong>&rArr;</strong> <span class="kwd">bool</span></span></p> - -<p>Returns <span class="kwd">true</span> if debug mode is on, <span class="kwd">false</span> otherwise.</p></div> - <p><a id="op-define"></a> <span class="reference-title">define</span></p>

@@ -5776,6 +5774,13 @@ <div class="operator"><p><span class="kwd"> &#x2205; <strong>&rArr;</strong> <span class="kwd">dict</span></span></p>

<p>Returns a dictionary of all options passed to the current program, with their respective values.</p></div> +<p><a id="op-parse"></a> +<span class="reference-title">parse</span></p> + +<div class="operator"><p><span class="kwd"> <span class="kwd">string</span> <strong>&rArr;</strong> <span class="kwd">quot</span></span></p> + +<p>Parses <span class="kwd">string</span> and returns a quoted program <span class="kwd">quot</span>.</p></div> + <p><a id="op-prompt"></a> <span class="reference-title">prompt</span></p>

@@ -5827,6 +5832,13 @@

<div class="operator"><p><span class="kwd"> <span class="kwd">err</span> <strong>&rArr;</strong> &#x2205;</span></p> <p>Raises the error specified via the dictionary <span class="kwd">err</span>.</p></div> + +<p><a id="op-read"></a> +<span class="reference-title">read</span></p> + +<div class="operator"><p><span class="kwd"> <span class="kwd">&apos;sym</span> <strong>&rArr;</strong> <span class="kwd">quot</span></span></p> + +<p>Reads and parses the specified <em>min</em> file <span class="kwd">&apos;sym</span> and returns a quoted program <span class="kwd">quot</span>.</p></div> <p><a id="op-remove-symbol"></a> <span class="reference-title">remove-symbol</span></p>

@@ -6461,6 +6473,13 @@ <div class="operator"><p><span class="kwd"> <span class="kwd">a</span> <span class="kwd">quot</span> <strong>&rArr;</strong> (<span class="kwd">a</span> <span class="kwd">a<sub>*</sub></span>)</span></p>

<p>Returns a new quotation containing the contents of <span class="kwd">quot</span> with <span class="kwd">a</span> prepended.</p></div> +<p><a id="op-quote-map"></a> +<span class="reference-title">quote-map</span></p> + +<div class="operator"><p><span class="kwd"> <span class="kwd">quot<sub>1</sub></span> <strong>&rArr;</strong> <span class="kwd">quot<sub>2</sub></span></span></p> + +<p>Returns a new quotation <span class="kwd">quot<sub>2</sub></span> obtained by quoting each element of <span class="kwd">quot<sub>1</sub></span>.</p></div> + <p><a id="op-reduce"></a> <span class="reference-title">reduce</span></p>

@@ -6861,6 +6880,58 @@

<div class="operator"><p><span class="kwd"> <span class="kwd">a</span> <strong>&rArr;</strong> <span class="kwd">bool</span></span></p> <p>Returns <span class="kwd">true</span> if <span class="kwd">a</span> is a boolean, <span class="kwd">false</span> otherwise.</p></div> + +<p><a id="op-dequote-and"></a> +<span class="reference-title">dequote-and</span></p> + +<div class="operator"><p><span class="kwd"> <span class="kwd">a<sub>1</sub></span> <span class="kwd">a<sub>2</sub></span> <strong>&rArr;</strong> <span class="kwd">bool</span></span></p> + +<p>Short-circuited logical and. It performs the following operations:</p> + +<ol> +<li>Pops <span class="kwd">a<sub>1</sub></span> and <span class="kwd">a<sub>2</sub></span> off the stack.</li> +<li>Dequotes <span class="kwd">a<sub>1</sub></span>, if <span class="kwd">false</span> is on the stack, it pushes <span class="kwd">false</span> on the stack and stops, otherwise it carries on.</li> +<li>Dequotes <span class="kwd">a<sub>2</sub></span>.</li> +<li>If <span class="kwd">a<sub>2</sub></span> is <span class="kwd">true</span>, it pushes <span class="kwd">true</span> on the stack.</li> +</ol> + + +<div class="note"><p>Note</p> + +<p><span class="kwd">a<sub>1</sub></span> (and <span class="kwd">a<sub>2</sub></span>, if dequoted) must evaluate to a boolean value, otherwise an exception is raised.</p></div> + +<div class="sidebar"><p>Example</p> + +<p>The following program returns <span class="kwd">false</span> and never executes the second quotation.</p> + +<pre><code> "test" :x (x number?) (x 5 &lt;) dequote-and +</code></pre></div></div> + +<p><a id="op-dequote-or"></a> +<span class="reference-title">dequote-or</span></p> + +<div class="operator"><p><span class="kwd"> <span class="kwd">a<sub>1</sub></span> <span class="kwd">a<sub>2</sub></span> <strong>&rArr;</strong> <span class="kwd">bool</span></span></p> + +<p>Short-circuited logical or. It performs the following operations:</p> + +<ol> +<li>Pops <span class="kwd">a<sub>1</sub></span> and <span class="kwd">a<sub>2</sub></span> off the stack.</li> +<li>Dequotes <span class="kwd">a<sub>1</sub></span>, if <span class="kwd">true</span> is on the stack, it pushes <span class="kwd">true</span> on the stack and stops, otherwise it carries on.</li> +<li>Dequotes <span class="kwd">a<sub>2</sub></span>.</li> +<li>If <span class="kwd">a<sub>2</sub></span> is <span class="kwd">false</span>, it pushes <span class="kwd">false</span> on the stack.</li> +</ol> + + +<div class="note"><p>Note</p> + +<p><span class="kwd">a<sub>1</sub></span> (and <span class="kwd">a<sub>2</sub></span>, if dequoted) must evaluate to a boolean value, otherwise an exception is raised.</p></div> + +<div class="sidebar"><p>Example</p> + +<p>The following program returns <span class="kwd">true</span> and never executes the second quotation.</p> + +<pre><code> "test" :x (x string?) (x quotation?) dequote-or +</code></pre></div></div> <p><a id="op-dictionary?"></a> <span class="reference-title">dictionary?</span></p>

@@ -7783,7 +7854,7 @@

<p>Truncates <span class="kwd">num</span> to the decimal point.</p></div> </div> <div id="footer"> - <p><span class="copy"></span> Fabio Cevasco &ndash; November 2, 2017</p> + <p><span class="copy"></span> Fabio Cevasco &ndash; November 18, 2017</p> <p><span>Powered by</span> <a href="https://h3rald.com/hastyscribe"><span class="hastyscribe"></span></a></p> </div> </div>
M Min_DeveloperGuide.mdMin_DeveloperGuide.md

@@ -42,97 +42,97 @@ </style>

## About min -{@ site/contents/_includes/_about.md || 1 @} +{@ site/contents/about.md || 1 @} ## Getting Started -{@ site/contents/_includes/_download.md || 1 @} +{@ site/contents/download.md || 1 @} ## Learning the min Language -{@ site/contents/_includes/_learn.md || 1 @} +{@ site/contents/learn.md || 1 @} ### Data Types -{@ site/contents/_includes/_learn-data-types.md || 2 @} +{@ site/contents/learn-data-types.md || 2 @} ### Quotations -{@ site/contents/_includes/_learn-quotations.md || 2 @} +{@ site/contents/learn-quotations.md || 2 @} ### Operators -{@ site/contents/_includes/_learn-operators.md || 2 @} +{@ site/contents/learn-operators.md || 2 @} ### Definitions -{@ site/contents/_includes/_learn-definitions.md || 2 @} +{@ site/contents/learn-definitions.md || 2 @} ### Control Flow -{@ site/contents/_includes/_learn-control.flow.md || 2 @} +{@ site/contents/learn-control-flow.md || 2 @} ## Using the min Shell -{@ site/contents/_includes/_learn-shell.md || 1 @} +{@ site/contents/learn-shell.md || 1 @} ## Extending min -{@ site/contents/_includes/_learn-extending.md || 1 @} +{@ site/contents/learn-extending.md || 1 @} ## Reference -{@ site/contents/_includes/_reference.md || 1 @} +{@ site/contents/reference.md || 1 @} ### `lang` Module -{@ site/contents/_includes/_reference-lang.md || 1 @} +{@ site/contents/reference-lang.md || 1 @} ### `stack` Module -{@ site/contents/_includes/_reference-stack.md || 1 @} +{@ site/contents/reference-stack.md || 1 @} ### `seq` Module -{@ site/contents/_includes/_reference-seq.md || 1 @} +{@ site/contents/reference-seq.md || 1 @} ### `io` Module -{@ site/contents/_includes/_reference-io.md || 1 @} +{@ site/contents/reference-io.md || 1 @} ### `fs` Module -{@ site/contents/_includes/_reference-fs.md || 1 @} +{@ site/contents/reference-fs.md || 1 @} ### `logic` Module -{@ site/contents/_includes/_reference-logic.md || 1 @} +{@ site/contents/reference-logic.md || 1 @} ### `str` Module -{@ site/contents/_includes/_reference-str.md || 1 @} +{@ site/contents/reference-str.md || 1 @} ### `sys` Module -{@ site/contents/_includes/_reference-sys.md || 1 @} +{@ site/contents/reference-sys.md || 1 @} ### `num` Module -{@ site/contents/_includes/_reference-num.md || 1 @} +{@ site/contents/reference-num.md || 1 @} ### `time` Module -{@ site/contents/_includes/_reference-time.md || 1 @} +{@ site/contents/reference-time.md || 1 @} ### `crypto` Module -{@ site/contents/_includes/_reference-crypto.md || 1 @} +{@ site/contents/reference-crypto.md || 1 @} ### `math` Module -{@ site/contents/_includes/_reference-math.md || 1 @} +{@ site/contents/reference-math.md || 1 @}
M lib/min_logic.nimlib/min_logic.nim

@@ -127,12 +127,46 @@ let a = vals[0]

let b = vals[1] i.push newVal(a.boolVal and b.boolVal) + def.symbol("dequote-and") do (i: In): + let vals = i.expect("a", "a") + var a = vals[0] + var b = vals[1] + i.dequote(b) + let resB = i.pop + if (resB.isBool and resB.boolVal == false): + i.push(false.newVal) + else: + i.dequote(a) + let resA = i.pop + if not resA.isBool: + raiseInvalid("Result of first quotation is not a boolean value") + if not resB.isBool: + raiseInvalid("Result of second quotation is not a boolean value") + i.push newVal(resA.boolVal and resB.boolVal) + def.symbol("or") do (i: In): let vals = i.expect("bool", "bool") let a = vals[0] let b = vals[1] i.push newVal(a.boolVal or b.boolVal) + def.symbol("dequote-or") do (i: In): + let vals = i.expect("a", "a") + var a = vals[0] + var b = vals[1] + i.dequote(b) + let resB = i.pop + if (resB.isBool and resB.boolVal == true): + i.push(true.newVal) + else: + i.dequote(a) + let resA = i.pop + if not resA.isBool: + raiseInvalid("Result of first quotation is not a boolean value") + if not resB.isBool: + raiseInvalid("Result of second quotation is not a boolean value") + i.push newVal(resA.boolVal and resB.boolVal) + def.symbol("xor") do (i: In): let vals = i.expect("bool", "bool") let a = vals[0]

@@ -140,43 +174,44 @@ let b = vals[1]

i.push newVal(a.boolVal xor b.boolVal) def.symbol("string?") do (i: In): - if i.peek.kind == minString: + if i.pop.kind == minString: i.push true.newVal else: i.push false.newVal def.symbol("integer?") do (i: In): - if i.peek.kind == minInt: + if i.pop.kind == minInt: i.push true.newVal else: i.push false.newVal def.symbol("float?") do (i: In): - if i.peek.kind == minFloat: + if i.pop.kind == minFloat: i.push true.newVal else: i.push false.newVal def.symbol("number?") do (i: In): - if i.peek.kind == minFloat or i.peek.kind == minInt: + let a = i.pop + if a.kind == minFloat or a.kind == minInt: i.push true.newVal else: i.push false.newVal def.symbol("boolean?") do (i: In): - if i.peek.kind == minBool: + if i.pop.kind == minBool: i.push true.newVal else: i.push false.newVal def.symbol("quotation?") do (i: In): - if i.peek.kind == minQuotation: + if i.pop.kind == minQuotation: i.push true.newVal else: i.push false.newVal def.symbol("dictionary?") do (i: In): - if i.peek.isDictionary: + if i.pop.isDictionary: i.push true.newVal else: i.push false.newVal
M lib/min_seq.nimlib/min_seq.nim

@@ -125,6 +125,14 @@ i.dequote(prog)

res.add i.pop i.push res.newVal(i.scope) + def.symbol("quote-map") do (i: In): + let vals = i.expect("quot") + let list = vals[0] + var res = newSeq[MinValue](0) + for litem in list.qVal: + res.add @[litem].newVal(i.scope) + i.push res.newVal(i.scope) + def.symbol("reverse") do (i: In): let vals = i.expect("quot") let q = vals[0]
M min.vimmin.vim

@@ -11,7 +11,7 @@

setl iskeyword=@,36-39,+,-,/,*,.,:,~,!,48-57,60-65,94-95,192-255 setl iskeyword+=^ -syntax keyword minDefaultSymbol ! != $ & ' * + # - % ^ -> . .. / : = # < <= == => =~ > >= @ -inf ROOT acos aes all? and any? append apply args asin ask atan atime bind bool boolean? call call! capitalize case cd ceil chmod choose clear-stack cleave column-print concat confirm cons cos cosh cp cpu crypto ctime d2r datetime ddel debug decode define defined? delete dget dhas? dkeys dictionary? dip dir? dirname div dpick dprint dprint! dset dsort dup dvalues e encode env? error eval even? exists? exit expect fappend fatal find file? filename filter first flatten float float? floor foreach fperms fread from-json format-error fs fsize fstats ftype fwrite get gets get-env get-stack hardlink harvest hidden? id if import in? indent indexof inf info insert int integer? interpolate interval io join keep last length linrec ln load load-symbol log2 log10 logic loglevel loglevel? lowercase ls ls-r map map-reduce match math md5 mkdir mod module module-symbols module-sigils mtime mv nan newline nip not notice now num number? odd? opts os over parse partition password pi pick pop popd pow pred prepend print print! prompt publish puts puts! put-env q quotation? quote quote-bind quote-define r2d random raise read reduce regex reject remove remove-symbol repeat replace rest reverse rm rmdir round run save-symbol scope scope? seal search seq set set-stack sha1 sha224 sha256 sha384 sha512 shorten sigils sin sinh sip size sleep slice sort source split spread sqrt stack startup stored-symbols str string string? strip succ sum swap swons symbols symlink symlink? sys system take tan tanh tap tap! tau tformat time timeinfo times timestamp titleize to-json to-timestamp try trunc dequote uppercase unzip version warn when which while with xor zip +syntax keyword minDefaultSymbol ! != $ & ' * + # - % ^ -> . .. / : = # < <= == => =~ > >= @ -inf ROOT acos aes all? and any? append apply args asin ask atan atime bind bool boolean? call call! capitalize case cd ceil chmod choose clear-stack cleave column-print concat confirm cons cos cosh cp cpu crypto ctime d2r datetime ddel debug decode define defined? delete dequote dequote-and dequote-or dget dhas? dkeys dictionary? dip dir? dirname div dpick dprint dprint! dset dsort dup dvalues e encode env? error eval even? exists? exit expect fappend fatal find file? filename filter first flatten float float? floor foreach fperms fread from-json format-error fs fsize fstats ftype fwrite get gets get-env get-stack hardlink harvest hidden? id if import in? indent indexof inf info insert int integer? interpolate interval io join keep last length linrec ln load load-symbol log2 log10 logic loglevel loglevel? lowercase ls ls-r map map-reduce match math md5 mkdir mod module module-symbols module-sigils mtime mv nan newline nip not notice now num number? odd? opts os over parse partition password pi pick pop popd pow pred prepend print print! prompt publish puts puts! put-env q quotation? quote quote-bind quote-define quote-map r2d random raise read reduce regex reject remove remove-symbol repeat replace rest reverse rm rmdir round run save-symbol scope scope? seal search seq set set-stack sha1 sha224 sha256 sha384 sha512 shorten sigils sin sinh sip size sleep slice sort source split spread sqrt stack startup stored-symbols str string string? strip succ sum swap swons symbols symlink symlink? sys system take tan tanh tap tap! tau tformat time timeinfo times timestamp titleize to-json to-timestamp try trunc uppercase unzip version warn when which while with xor zip syntax match minDefaultSigil ;\<[:@'~!?$%&$=<>#^*#+/]; contained syntax match minSpecialSymbols ;[:@'~!?$%&$=<>#^*#+/]; contained
D site/contents/_includes/_about.md

@@ -1,36 +0,0 @@

-{@ _defs_.md || 0 @} - -**min** is an concatenative, fully-homoiconic, functional, interpreted programming language. - -This basically means that: - -* It is based on a somewhat obscure and slightly unintuitive programming paradigm, think of [Forth](http://www.forth.org/), [Factor](http://factorcode.org/) and [Joy](http://www.kevinalbrecht.com/code/joy-mirror/) but with parethesis for an extra [Lisp](https://common-lisp.net/)y flavor. -* Programs written in min are actually written using *quotations*, i.e. lists. -* It comes with map, filter, find, map-reduce and loads of other functional goodies. See the {#link-module||seq#} for more. -* It is probably slower than the average production-ready programming language. - -## Why? - -Because creating a programming language is something that every programmer needs to do, at some point in life. And also because there are way too few [concatenative](http://concatenative.org/wiki/view/Front%20Page) programming language out there -- so people are likely to be _less_ pissed off than if I made a yet another Lisp instead. - -I always wanted to build a minimalist language, but that could also be used for real work and provided a standard library for common tasks and functionalities like regular expression support, cryptography, execution of external programs, shell-like operators and keywords to work with files, and more. - -Also, I wanted it to be fully self-contained, cross platform, and tiny. About 1MB (depending on the platform) is not really tiny, but I feel it's a good compromise compared to the alternatives out there, considering that you only need _one file_ to run any min program. - -I am currently building a static site generator called [HastySite](https://github.com/h3rald/hastysite), that also powers <https://min-lang.org>. HastySite internally uses min as the language to write the [rules](https://github.com/h3rald/min/blob/master/site/rules.min) to process the source files of the site, and also all its [scripts](https://github.com/h3rald/min/tree/master/site/scripts). - -Finally, I think more and more people should get to know concatenative programming languages, because [concatenative programming matters](http://evincarofautumn.blogspot.it/2012/02/why-concatenative-programming-matters.html). - -## How? - -min is developed entirely in [Nim](https://nim-lang.org) -- the name is (almost) entirely a coincidence. I wanted to call it _minim_ but then shortened it for more... minimalism. - -min's parser started off as a fork of Nim's JSON parser -- adapted to process a concatenative programming language with less primitive types than JSON. It is interpreted in the traditional sense: no bytecode, no JIT, just plain read, parse and run. - -## Who? - -min was created and implemented by [Fabio Cevasco](https://h3rald.com), with contributions by [Peter Munch-Ellingsen](https://peterme.net). - -## When? - -min source code [repository](https://github.com/h3rald/min) was created on November 8^th 2014. This only means that I've been very slowly developing something that was actually made public at the end of July 2017.
D site/contents/_includes/_download.md

@@ -1,60 +0,0 @@

-{@ _defs_.md || 0 @} - -You can download one of the following pre-built min binaries: - -* {#release||{{$version}}||macosx||macOS||x64#} -* {#release||{{$version}}||windows||Windows||x64#} -* {#release||{{$version}}||linux||Linux||x64#} -* {#release||{{$version}}||linux||Linux||x86#} -* {#release||{{$version}}||linux||Linux||arm#} - -{#release -> [min v$1 for $3 ($4)](https://github.com/h3rald/min/releases/download/v$1/min\_v$1\_$2\_$4.zip) #} - -{{guide-download}} - -## Building from Source - -Alternatively, you can build min from source as follows: - -1. Download and install [nim](https://nim-lang.org). -2. Download and build [Nifty](https://github.com/h3rald/nifty), and put the nifty executable somewhere in your [$PATH](class:kwd). -3. Clone the min [repository](https://github.com/h3rald/min). -4. Navigate to the min repository local folder. -5. Run **nifty install** to download min’s dependencies. -7. Run **nim c -d:release min.nim**. - -## Running then min Shell - -To start min shell, run [min -i](class:cmd). You will be presented with a prompt displaying the path to the current directory: - -> %min-terminal% -> [[/Users/h3rald/test]$](class:prompt) - -You can type min code and press [ENTER](class:kbd) to evaluate it immediately: - -> %min-terminal% -> [[/Users/h3rald/test]$](class:prompt) 2 2 + -> {1} -> 4 -> [[/Users/h3rald/test]$](class:prompt) - -The result of each operation will be placed on top of the stack, and it will be available to subsequent operation - -> %min-terminal% -> [[/Users/h3rald/test]$](class:prompt) dup * -> {1} -> 16 -> [[/Users/h3rald/test]$](class:prompt) - -To exit min shell, press [CTRL+C](class:kbd) or type [exit](class:cmd) and press [ENTER](class:kbd). - -## Executing a min Program - -To execute a min script, you can: - -* Run `min -e:"... program ..."` to execute a program inline. -* Run `min myfile.min` to execute a program contained in a file. - -min also supports running programs from standard input, so the following command can also be used (on Unix-like system) to run a program saved in [myfile.min](class:file): - -> %min-terminal% -> -> [$](class:prompt) cat myfile.min | min
D site/contents/_includes/_learn-control.flow.md

@@ -1,76 +0,0 @@

-{@ _defs_.md || 0 @} - -The {#link-module||lang#} provide some symbols that can be used for the most common control flow statements. Unlike most programming language, min does not differentiate between functions and statements -- control flow statements are just ordinary symbols that manipulate the main stack. - - -## Conditionals - -The following symbols provide ways to implement common conditional statements: - -* {#link-operator||lang||case#} -* {#link-operator||lang||if#} -* {#link-operator||lang||unless#} -* {#link-operator||lang||when#} - -For example, consider the following program: - - ( - ( - "" :type - (("\.(md|markdown)$") ("markdown" @type)) - (("\.txt$") ("text" @type)) - (("\.min$") ("min" @type)) - (("\.html?$") ("HTML" @type)) - ((true) ("unknown" @type)) - ) case - "This is a $1 file." (type) % echo - ) :display-file-info - -This program defines a symbol `display-file-info` that takes a file name and outputs a message displaying its type, if known. - - -## Loops - -The following symbols provide ways to implement common loops: - -* {#link-operator||lang||foreach#} -* {#link-operator||lang||times#} -* {#link-operator||lang||while#} - - -For example, consider the following program: - - ( - :n - 1 :i - 1 :f - (i n <=) - ( - f i * @f - i succ @i - ) while - f - ) :factorial - -This program defines a symbol `factorial` that calculates the factorial of an integer iteratively using the symbol {#link-operator||lang||while#}. - -## Error handling - -The following symbols provide ways to manage errors in min: - -* {#link-operator||lang||format-error#} -* {#link-operator||lang||raise#} -* {#link-operator||lang||try#} - -For example, consider the following program: - - . ls - ( - ( - (fsize) - (pop 0) - ) try - ) 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.
D site/contents/_includes/_learn-data-types.md

@@ -1,34 +0,0 @@

-{@ _defs_.md || 0 @} - -The type system of min is very simple -- only the following data types are available: - -integer -: An integer number like 1, 27 or -15. -float -: 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). - -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 symbol 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) -> ) - -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?`). - -> %note% -> Note -> -> Most of the operators defined in the {#link-module||num#} are able to operate on both integers and floats. - -{#link-learn||operators||Operators#}
D site/contents/_includes/_learn-definitions.md

@@ -1,109 +0,0 @@

-{@ _defs_.md || 0 @} - -Being a concatenative language, min does not really need named parameters or variables: simbols just pop elements off the main stack in order, and that's normally enough. There is however one small problem witht the traditional concatenative paradigm; consider the following program for example: - - dup dup - "\.zip$" match - swap fsize 1000000 > and - swap mtime now 3600 - > - -This program takes a single string corresponding to a file path and returns true if it's a .zip file bigger than 1MB that was modified in the last how. Sure, it is remarkable that no variables are needed for such a program, but it is not very readable: because no variables are used, it is often necessary to make copies of elements and push them to the end of the stack -- that's what the {#link-operator||stack||dup#} and {#link-operator||stack||swap#} are used for. - -The good news is that you can use the {#link-operator||lang||define#} operator and the `:` sigil to define new symbols, and symbols can also be set to literals of course. - -Consider the following program: - - :filepath - filepath "\.zip$" match - filepath fsize 1000000 > - filepath mtime now 3600 - > - and and - -In this case, the `filepath` symbol is defined and then used on the following three lines, each of which defines a condition to be evaluated. The last line contains just two {#link-operator||logic||and#} symbols necessary to compare the three conditions. - - -## Lexical scoping and binding - -min, like many other programming languages, uses [lexical scoping](https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scope_vs._dynamic_scope) to resolve symbols. - -Consider the following program: - - - 4 :a - ( - a 3 + :a - ( - a 1 + :a - (a dup * :a) dequote - ) dequote - ) dequote - -...What is the value of the symbol `a` after executing it? - -Simple: `4`. Every quotation defines its own scope, and in each scope a new variable called `a` is defined. In the innermost scope containing the quotation `(a dup * :a)` the value of `a` is set to `64`, but this value is not propagated to the outer scopes. Note also that the value of `a` in the innermost scope is first retrieved from the outer scope (8). - -If we want to change the value of the original `a` symbol defined in the outermost scope, we have to use the {#link-operator||lang||bind#} or its shorthand sigil `@`, so that the programs becomes the following: - - 4 :a ;First definition of the symbol a - ( - a 3 + @a ;The value of a is updated to 7. - ( - a 1 + @a ;The value of a is updated to 8 - (a dup * @a) dequote ;The value of a is now 64 - ) dequote - ) dequote - -## quote-define and quote-bind - -So far, we saw how to use the {#link-operator||lang||define#} and {#link-operator||lang||bind#} operator (or better, their shorthand sigils `:` and `@`) to define new symbols or bind values to existing ones. - -Consider the following example: - - (1 2 3 4 5) :my-list - my-list (dup *) map - -If run the program above in min shell by pasting the first and then the second line in it, you'll get an error similar to the following: - - (!) <repl>(1,19) [map]: Incorrect values found on the stack: - - expected: {top} quot quot {bottom} - - got: {top} quot int {bottom} - <repl>(1,19) in symbol: map - -This error says that when the {#link-operator||lang||map#} operator was evaluated, there were incorrect values on the stack. Two quotations were expected, but instead a quotation and an integer were found. How did this happen? - -Basically, when `my-list` was pushed on the stack, it pushed all its item on top of the stack. If you run {#link-operator||stack||get-stack#}, it will return the following list: - - (1 2 3 4 5 (dup *)) - -This happens because by default min assumes that when you define a quotation you want to define a new operator rather than a list. The following program works as expected, and it returns a list containing the squares of the first five integer numbers: - - (dup *) :square - (1 2 3 4 5) (square) map - -To avoid this behavior -- i.e. whenever you want to define a list of items rather than an operator that will be immediately evaluated when pushed on the stack, you have to use the {#link-operator||lang||quote-define#} and the {#link-operator||lang||quote-bind#} or their respective sigils `#` and `=`: - - (1 2 3 4 5) #my-list - my-list (dup *) map ;Returns (1 4 9 16 25) - -## Sealing symbols - -Finally, symbols can be sealed to pervent accidental updates or deletions. By default, all symbols defined in the core min modules are sealed, so the following code if run in min shell will result in an error: - - - 5 :quote - -...because the symbol quote is already defned in the root scope. However, note that the folliwng code will _not_ return an error: - - (5 :quote quote dup *) -> ;returns 25 - -...because the `quote` symbol is only defined in the root scope and can therefore be redefined in child scopes. - -If you want, you can {#link-operator||lang||seal#} your own symbols so that they may not be redefined using the {#link-operator||lang||bind#} operator or deleted using the {#link-operator||lang||delete#}. - -> %info% -> Note -> -> The {#link-operator||lang||unseal#} operator can be used to effectively un-seal a previously-sealed symbol. Use with caution! - - -{#link-learn||control-flow||Control Flow#}
D site/contents/_includes/_learn-extending.md

@@ -1,157 +0,0 @@

-{@ _defs_.md || 0 @} - -min provides a fairly complete standard library with many useful modules. However, you may feel the need to extend min in order to perform more specialized tasks. - -In such situations, you basically have three options: - -* Implement new min modules in min -* Embed min in your [Nim](https://nim-lang.org) program -* Implemet min modules as dynamic libraries in Nim - -## Implementing new min modules using min itself - -When you just want to create more high-level min operator using functionalities that are already available in min, the easiest way is to create your own reusable min modules. - -The {#link-operator||lang||module#} (and the **+** sigil) allows you to create a new min module: - -``` -( - (dup *) :pow2 - - (dup dup * *) :pow3 - - (dup dup dup * * *) :pow4 - -) +quickpows - -``` - -Save your code to a file (e.g. *quickpows.min*) and you can use it in other nim files using the {#link-operator||lang||load#} operator and the {#link-operator||lang||import#}: - -``` -'quickpows load -'quickpows import - -2 pow3 pow2 puts ;prints 64 -``` - -## Embedding min in your Nim program - -If you'd like to use min as a scripting language within your own program, and maybe extend it by implementing additional operators, you can use min as a Nim library. - -To do so: - -1. Install min sources using Nifty as explained in the {#link-page||download||Download#} section. -2. Import it in your Nim file. -3. Implement a new `proc` to define the module. - -The following code is taken from [HastySite](https://github.com/h3rald/hastysite) and shows how to define a new `hastysite` module containing some symbols (`preprocess`, `postprocess`, `process-rules`, ...): - -``` -import packages/min/min - -proc hastysite_module*(i: In, hs1: HastySite) = - var hs = hs1 - let def = i.define() - - def.symbol("preprocess") do (i: In): - hs.preprocess() - - def.symbol("postprocess") do (i: In): - hs.postprocess() - - def.symbol("process-rules") do (i: In): - hs.interpret(hs.files.rules) - - # ... - - def.finalize("hastysite") -``` - -Then you need to: - -4. Instantiate a new min interpreter using the `newMinInterpreter` proc. -5. Run the `proc` used to define the module. -6. Call the `interpret` method to interpret a min file or string: - -``` -proc interpret(hs: HastySite, file: string) = - var i = newMinInterpreter(file, file.parentDir) - i.hastysite_module(hs) - i.interpret(newFileStream(file, fmRead)) -``` - -> %tip% -> Tip -> -> For more information on how to create new modules with Nim, have a look in the [lib folder](https://github.com/h3rald/min/tree/master/lib) of the min repository, which contains all the min modules included in the standard library. - - -## Implementing min modules as dynamic libraries - -> %warning% -> Warning -> -> This technique is currently experimental, it has not been tested extensively and it may not even work on Windows. - -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. - -In order to do this, you don't even need to download the whole min source code, you just need to download the [mindyn.nim](https://github.com/h3rald/min/blob/master/mindyn.nim) file and import it in your Nim program. - -The following code shows how to create a simple min module called *dyntest* containing only a single operator *dynplus*, which essentially returns the sum of two numbers: - -``` -import mindyn - -proc dyntest*(i: In) {.dynlib, exportc.} = - - let def = i.define() - - def.symbol("dynplus") do (i: In): - let vals = i.expect("num", "num") - let a = vals[0] - let b = vals[1] - if a.isInt: - if b.isInt: - i.push newVal(a.intVal + b.intVal) - else: - i.push newVal(a.intVal.float + b.floatVal) - else: - if b.isFloat: - i.push newVal(a.floatVal + b.floatVal) - else: - i.push newVal(a.floatVal + b.intVal.float) - - def.finalize("dyntest") -``` - -Note that the `mindym.nim` file contains the signatures of all the `proc`s that are commonly used to define min modules, but not their implementation. Such `proc`s will become available at run time when the dynamic library is linked to the min executable. - -You can compile the following library by running the following command: - -> %min-terminal% -> [$](class:prompt) nim c \-\-app:lib -d:release \-\-noMain dyntest.nim - -If you are using [clang](https://clang.llvm.org/) to compile Nim code, you may need to run the following command instead: - -> %min-terminal% -> [$](class:prompt) nim c \-\-app:lib -d:release \-\-noMain -l:&#34;-undefined dynamic\_lookup&#34; dyntest.nim - -Now you should have a `libdyntest.so|dyn|dll` file. To make min load it and link it automatically when it starts, just run: - -> %min-terminal% -> [$](class:prompt) min \-\-install:libdyntest.dyn - -This command will copy the library file to `$HOME/.minlibs/` (`%HOMEPATH%\.minlibs\` on Windows). min looks for dynamic libraries in this folder when it starts. - -> %note% -> Notes -> -> * The dynamic library file must have the same name as the module it defines (*dyntest* in this case). -> * At startup, min links all your installed dynamic libraries but does not import the modules automatically. - -If you wish to uninstall the library, run the following command instead: - -> %min-terminal% -> [$](class:prompt) min \-\-uninstall:libdyntest.dyn -
D site/contents/_includes/_learn-operators.md

@@ -1,59 +0,0 @@

-{@ _defs_.md || 0 @} - -Every min program needs _operators_ to: - -* Manipulate elements on the stack -* Perform operations on data -* Provide side effects (read/print to standard input/output/files, etc.) - -There are two types of operators: _symbols_ and _sigils_. - -_Symbols_ are the most common type of operator. A min symbol is a single word that is either provided by one of the predefined min {#link-page||reference||modules#} like `dup` or `.` or defined by the user. User-defined symbols must: - -* Start with a letter or an underscore (\_). -* Contain zero or more letters, numbers and/or any of the following characters: `/ ! ? + * . _ -` - -It is possible to define symbols using the {#link-operator||lang||define#} symbol. The following min program defines a new symbol called square that duplicates the first element on the stack and multiplies the two elements: - - (dup *) "square" define - -Besides symbols, min provides a set of predefined _sigils_ for commonly-used symbols. For example, the previous definition could be rewritten as follows using sigils: - - (dup *) :square - -A sigil like `:` can be prepended to a single-word string instead of using the corresponding symbol. Essentially, sigils are nothing more than syntactic sugar. Currently min provides the following sigils: - -+ -: Alias for {#link-operator||lang||module#}. -~ -: Alias for {#link-operator||lang||delete#}. -' -: Alias for {#link-operator||lang||quote#}. -\: -: Alias for {#link-operator||lang||define#}. -^ -: Alias for {#link-operator||lang||call#}. -@ -: Alias for {#link-operator||lang||bind#}. -> -: Alias for {#link-operator||lang||save-symbol#}. -< -: Alias for {#link-operator||lang||load-symbol#}. -&#61; -: Alias for {#link-operator||lang||quote-bind#}. -\# -: Alias for {#link-operator||lang||quote-define#}. -/ -: Alias for {#link-operator||seq||dget#}. -% -: Alias for {#link-operator||seq||dset#}. -? -: Alias for {#link-operator||seq||dhas?#}. -! -: Alias for {#link-operator||sys||system#}. -& -: Alias for {#link-operator||sys||run#}. -$ -: Alias for {#link-operator||sys||get-env#}. - -{#link-learn||quotations||Quotations#}
D site/contents/_includes/_learn-quotations.md

@@ -1,43 +0,0 @@

-{@ _defs_.md || 0 @} - -Quotations are the most important thing to understand in min. Besides being the data type used for lists, they are also used to delimit blocks of min code that is not going to be immediately executed. - -Consider for example the following min code which returns all the files present in the current folder sorted by name: - - . ls (ftype "file" ==) filter '> sort - -The symbol {#link-operator||seq||filter#} takes two quotations as arguments -- the first quotation on the stack is applied to all the elements of the second quotation on the stack, to determine which elements of the second quotation will be part of the resulting quotation. This is an example of how quotations can be used both as lists and programs. - -Let's examine this program step-by-step: - -{{fdlist => ("dir1" "dir2" file1.txt "file2.txt" "file3.md" "file4.md")}} -{{flist => ("file1.txt" "file2.txt" "file3.md" "file4.md")}} - -1. The `.` symbol is pushed on the stack, and it is immediately evaluated to the full path to the current directory. -2. The `ls` symbol is pushed on the stack, it consumes the string already on the stack and returns a quotation containing all files and directories within the current directory. -3. The quotation `(ftype 'file ==)` is pushed on the stack. It is treated exactly like a list of data and it is not evaluated. -4. The `filter` symbol is pushed on the stack. This symbol takes two quotations as input, and applies the result of the first quotation on the stack (`(ftype "file" ==)`) to all elements of the second quotation of the stack (the list of files and directories), returning a new quotation containing only those elements of the second quotation on the stack that satisfy the result of the first quotation. In this case, it returns a new quotation containing only files. -5. `'>` is pushed on the stack. The `'` sigil can be used instead of the `quote` symbol to quote a single symbol, `<` in this case. In other words, it is instantly evaluated to the quotation `(>)`. -6. The symbol `sort` is pushed on the stack. This symbol, like `filter`, takes two quotations as input, and applies the first quotation to each element of the second quotation, effectively sorting each element of the second quotation using the predicate expressed by the first quotation. In this case, all files are sorted by name in ascending order. - -> %tip% -> Tip -> -> The {{#link-module||seq#}} provides several symbols to work with quotations in a functional way. - - -## Quoting, dequoting, and applying - -When a quotation is created, it is treated as data, no matter what it contains: it is placed on the stack, like an integer or a string would. However, unlike other data types, a quotation can be evaluated in certain situations and when it happens its contents are pushed on the stack. - -Consider the following program: - - (1 2 3 4 5 6 7) (odd?) filter - -This programs returns a new quotation containing all odd numbers contained in quotation `(1 2 3 4 5 6 7)`. - -In this case, the second quotation is used to _quote_ the symbol `odd?` so that instead of being executed immediately, it will be executed by the symbol `filter` on each element of the first quotation. In this way, we may say that `(odd?)` is _dequoted_ by the symbol `filter`. - -The synbol {#link-operator||lang||dequote#} or its alias `->` can be used to dequote a quotation by pushing all its element on the main stack, while the symbol {#link-operator||lang||apply#} can be used to dequote a quotation by pushing its element on a separate stack. - -{#link-learn||definitions||Definitions#}
D site/contents/_includes/_learn-shell.md

@@ -1,60 +0,0 @@

-{@ _defs_.md || 0 @} - -The min executable also provide an interactive REPL (Read-Eval-Print Loop) when launched with the `-i` flag: - -> %min-terminal% -> [$](class:prompt) min -i -> <span class="prompt">&#91;/Users/h3rald/Development/min&#93;$</span> - -Although not as advanced, the min REPL is not dissimilar from an OS system shell like Bash, and as a matter of fact it provides many functionalities that are found in other shells or command prompts, such as: - -* Auto-completion -* Persistent line history -* A customizable prompt -* Access to environment variables - -...plus in can obviously leverage the entire min language for complex scripting. - -## Autocompletion and shortcuts - -The min shell features smart tab autocompletion and keyboard shortcut implemented using the [nimline](https://github.com/h3rald/nimline) library. - -The following behaviors are implemented when pressing the `TAB` key within: - -Context | Result ----------------------------------------------------------------|-------------- -...a string | Auto-completes the current word using file and directory names. -...a word starting with `!` or `&` | Auto-completes the current word using executable file names. -...a word starting with `$` | Auto-completes the current word using environment variable names. -...a word starting with `'`, `~`, `@`, `#`, `>`, `<`, `*`, `(` | Auto-completes the current word using symbol names. - -Additionally, at least some of the following systems should also be available, depending on your operating system: - -Key | Effect ----------------|------------------------ -`INSERT` | Switches between insert and replace mode. -`UP` | Displays the previous history entry. -`DOWN` | Displays the next history entry. -`CTRL+c` | Terminates min shell. -`CTRL+x` | Clears the current line. -`CTRL+b` | Goes to the beginning of the line. -`CTRL+e` | Goes to the end of the line. - - -## Shell configuration files - -When the min interpreter is first launched, the following files are created automatically in the $HOME directory (%HOMEPROFILE% on Windows). - -### .minrc - -This file is interpreted first every time min is run. By default it is empty, but it can be used to define code to execute at startup. - -### .min\_history - -This file is used to persist all commands entered in the min shell, and it is loaded in memory at startup to provide line history support. - -### .min\_symbols - -This files contains all symbol definitions in JSON format that were previously-saved using the {#link-operator||lang||save-symbol#} symbol. Symbols can be loaded using the {#link-operator||lang||load-symbol#} symbol. - -{#link-learn||extending||Extending min#}
D site/contents/_includes/_learn.md

@@ -1,31 +0,0 @@

-{@ _defs_.md || 0 @} - -{{learn-links}} - -*min* is a stack-based, concatenative programming language that uses postfix notation. If you already know [Forth](http://www.forth.org/), [Factor](http://factorcode.org/) or [Joy](http://www.kevinalbrecht.com/code/joy-mirror/), or if you ever used an [RPN](https://en.wikipedia.org/wiki/Reverse_Polish_notation) calculator, then min will look somewhat familiar to you. - -If not, well, here's how a short min program looks like: - - ; This is a comment - (1 2 3 4 5) (dup *) map - -This program returns a list containing the square values of the first five integer numbers: - - (1 4 9 16 25) - -Let's see how it works: - -1. First a list containing the first five integer is pushed on the stack. -2. Then, another list containing two symbols (`dup` and `*`) is pushed on the stack. This constitutes a quoted program which, when executed duplicates (`dup`) the first element on the stack and then multiplies (`*`) the two elements together. -3. Finally, the symbol `map` is pushed on the stack. Map takes a list of elements and a quoted program and applies the program to each element. - -Note that: - -* There are no variable assignments. -* elements are pushed on the stack one by one. -* Parentheses are grouped together one or more elements, so that they are treated as a single element and they are not evaluated immediately. -* Symbols can be used to perform operations on the whole stack. - -Unlike more traditional programming languages, in a concatenative programming language there is no inherent need of variables or named parameters, as symbols acts as stack operators that consume elements that are placed in order on top of a stack. - -{#link-learn||data-types||Data Types#}
D site/contents/_includes/_reference-crypto.md

@@ -1,30 +0,0 @@

-{@ _defs_.md || 0 @} - - -{#op||md5||{{sl}}||{{s}}|| -Returns the MD5 hash of {{sl}}. #} - -{#op||sha1||{{sl}}||{{s}}|| -Returns the SHA1 hash of {{sl}}. #} - -{#op||sha224||{{sl}}||{{s}}|| -Returns the SHA224 hash of {{sl}}. #} - -{#op||sha256||{{sl}}||{{s}}|| -Returns the SHA256 hash of {{sl}}. #} - -{#op||sha384||{{sl}}||{{s}}|| -Returns the SHA384 hash of {{sl}}. #} - -{#op||sha512||{{sl}}||{{s}}|| -Returns the SHA512 hash of {{sl}}. #} - -{#op||encode||{{sl}}||{{s}}|| -Base64-encodes {{sl}}. #} - -{#op||encode||{{sl}}||{{s}}|| -Decodes the Base64-encoded string {{sl}}. #} - -{#op||aes||{{sl1}} {{sl2}}||{{s}}|| -Encrypts or decrypts {{sl1}} using the Advanced Encryption Standard (AES), using {{sl2}} as password. #} -
D site/contents/_includes/_reference-fs.md

@@ -1,47 +0,0 @@

-{@ _defs_.md || 0 @} - -{#op||atime||{{sl}}||{{flt}}|| -Returns a timestamp corresponding to the time that file/directory {{sl}} was last accessed.#} - -{#op||ctime||{{sl}}||{{flt}}|| -Returns a timestamp corresponding to the time that file/directory {{sl}} was created.#} - -{#op||fperms||{{sl}}||{{i}}|| -Returns the Unix permissions (expressed as a three-digit number) of file/directory {{sl}}.#} - -{#op||fsize||{{sl}}||{{i}}|| -Returns the size in bytes of file/directory {{sl}}.#} - -{#op||fstats||{{sl}}||{{d}}|| -> Returns a dictionary {{d}} containing information on file/directory {{sl}}. -> > %sidebar% -> > Example -> > -> > Assuming that `min` is a file, the following: -> > -> > `'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) -> > )#} - -{#op||ftype||{{sl}}||{{s}}|| -Returns the type of file/directory {{sl}} (`"file"` or `"dir"`).#} - -{#op||hidden?||{{sl}}||{{b}}|| -Returns {{t}} if file/directory {{sl}} is hidden, {{f}} otherwise.#} - -{#op||mtime||{{sl}}||{{flt}}|| -Returns a timestamp corresponding to the time that file/directory {{sl}} was last modified.#} -
D site/contents/_includes/_reference-io.md

@@ -1,68 +0,0 @@

-{@ _defs_.md || 0 @} - -{#op||ask||{{s1}}||{{s2}}|| -Prints {{s1}} (prompt), reads a line from STDIN and places it on top of the stack as a string.#} - -{#op||choose||(({{s1}} {{q1}}){{1p}}) {{s2}}||{{a0p}}|| -> Prints {{s2}}, then prints all {{s1}} included in the quotation prepended with a number, and waits from valid input from the user. -> -> If the user enters a number that matches one of the choices, then the corresponding quotation {{q1}} is executed, otherwise the choice menu is displayed again until a valid choice is made. #} - -{#op||column-print||{{q}} {{i}}||{{any}}|| -Prints all elements of {{q}} to STDOUT, in {{i}} columns.#} - -{#op||confirm||{{s}}||{{b}}|| -> Prints {{s}} (prompt) appending `" [yes/no]: "`, reads a line from STDIN and: -> -> * if it matches `/^y(es)$/i`, puts {{t}} on the stack. -> * if it matches `/^no?$/i`, puts {{f}} on the stack. -> * Otherwise, it prints `Invalid answer. Please enter 'yes' or 'no': ` and waits for a new answer. #} - -{#op||debug||{{any}}||{{any}}|| -Prints {{any}} and a new line to STDOUT, if logging level is set to [debug](class:kwd) or lower.#} - -{#op||error||{{any}}||{{any}}|| -Prints {{any}} and a new line to STDERR, if logging level is set to [error](class:kwd) or lower.#} - -{#op||fappend||{{s1}} {{s2}}||{{null}}|| -Appends {{s1}} to the end of file {{s2}}. #} - -{#op||fatal||{{any}}||{{any}}|| -Prints {{any}} and a new line to STDERR, and exists the program with error code `100`.#} - -{#op||fread||{{s}}||{{s}}|| -Reads the file {{s}} and puts its contents on the top of the stack as a string.#} - -{#op||fwrite||{{s1}} {{s2}}||{{null}}|| -Writes {{s1}} to the file {{s2}}, erasing all its contents first. #} - -{#op||gets||{{null}}||{{s}}|| -Reads a line from STDIN and places it on top of the stack as a string.#} - -{#op||info||{{any}}||{{any}}|| -Prints {{any}} and a new line to STDOUT, if logging level is set to [info](class:kwd) or lower.#} - -{#op||newline||{{null}}||{{null}}|| -Prints a new line to STDOUT.#} - -{#op||notice||{{any}}||{{any}}|| -Prints {{any}} and a new line to STDOUT, if logging level is set to [notice](class:kwd) (default) or lower.#} - -{#op||password||{{null}}||{{s}}|| -Reads a line from STDIN displaying \* for each typed character, and places it on top of the stack as a string.#} - -{#op||print||{{any}}||{{any}}|| -Prints {{any}} to STDOUT.#} - -{#op||print!||{{any}}||{{null}}|| -Prints {{any}} to STDOUT and removes {{any}} from the stack.#} - -{#op||puts||{{any}}||{{any}}|| -Prints {{any}} and a new line to STDOUT.#} - -{#op||puts!||{{any}}||{{null}}|| -Prints {{any}} and a new line to STDOUT, removing {{any}} from the stack.#} - -{#op||warning||{{any}}||{{any}}|| -Prints {{any}} and a new line to STDERR, if logging level is set to [warning](class:kwd) or lower.#} -
D site/contents/_includes/_reference-lang.md

@@ -1,358 +0,0 @@

-{@ _defs_.md || 0 @} - -{#sig||&apos;||quote#} - -{#alias||&apos;||quote#} - -{#sig||:||define#} - -{#alias||:||define#} - -{#sig||~||delete#} - -{#sig||+||module#} - -{#sig||^||call#} - -{#alias||^||call#} - -{#sig||@||bind#} - -{#alias||@||bind#} - -{#sig||>||save-symbol#} - -{#sig||<||load-symbol#} - -{#alias||->||dequote#} - -{#alias||=>||apply#} - -{#sig||#||quote-bind#} - -{#alias||#||quote-bind#} - -{#sig||=||quote-define#} - -{#alias||=||quote-define#} - -{#op||apply||{{q}}||({{a0p}})|| -Returns a new quotation {{q}} obtained by evaluating each element of {{q}} in a separate stack.#} - -{#op||args||{{null}}||{{q}}|| -Returns a list of all arguments passed to the current program.#} - -{#op||bind||{{any}} {{sl}}||{{null}}|| -Binds the specified value (auto-quoted) to an existing symbol {{sl}}.#} - -{#op||bool||{{any}}||{{b}}|| -> Converts {{any}} to a boolean value based on the following rules: -> -> * If {{any}} is a boolean value, no conversion is performed. -> * 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||case||(({{q1}} {{q2}}){{0p}})||{{a0p}}|| -> This operator takes a quotation containing _n_ different conditional branches. -> -> Each branch must be a quotation containing two quotations, and it is processed as follows: -> -> * if {{q1}} evaluates to {{t}}, then the {{q2}} is executed. -> * if {{q1}} evaluates to {{f}}, then the following branch is processed (if any). -> -> > %sidebar% -> > Example -> > -> > The following program prints "Smaller than 3": -> > -> > 2 ( -> > ((> 3) ("Greater than 3" put!)) -> > ((< 3) ("Smaller than 3" put!)) -> > ((true) ("Exactly 3" put!)) -> > ) case #} - -{#op||debug||{{null}}||{{null}}|| -Toggles debug mode. #} - -{#op||debug?||{{null}}||{{b}}|| -Returns {{t}} if debug mode is on, {{f}} otherwise. #} - -{#op||define||{{any}} {{sl}}||{{null}}|| -Defines a new symbol {{sl}}, containing the specified value (auto-quoted if not already a quotation).#} - -{#op||defined?||{{sl}}||{{b}}|| -Returns {{t}} if {{sl}} is defined, {{f}} otherwise.#} - -{#op||delete||{{sl}}||{{null}}|| -Deletes the specified symbol {{sl}}.#} - -{#op||dequote||{{q}}||{{a0p}}|| -Pushes the contents of quotation {{q}} on the stack. #} - -{#op||eval||{{s}}||{{a0p}}|| -Parses and interprets {{s}}. #} - -{#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). -> > %sidebar% -> > Example -> > -> > Assuming that the following elements are on the stack (from top to bottom): -> > -> > `1 "test" 3.4` -> > -> > the following program evaluates to `true`: -> > -> > `(int string num) expect (3.4 "test" 1) ==`#} - -{#op||float||{{any}}||{{flt}}|| -> Converts {{any}} to an integer value based on the following rules: -> -> * If {{any}} is {{t}}, it is converted to `1.0`. -> * If {{any}} is {{f}}, it is converted to `0.0`. -> * If {{any}} is a integer, it is converted to float value. -> * If {{any}} is a float, no conversion is performed. -> * If {{any}} is a string, it is parsed as a float value.#} - -{#op||foreach||{{q1}} {{q2}}||{{a0p}}|| -Applies the quotation {{q2}} to each element of {{q1}}.#} - -{#op||format-error||{{e}}||{{s}}|| -> Formats the error {{e}} as a string. -> > %sidebar% -> > Example -> > -> > The following: -> > -> > `((error "MyError") (message "This is a test error")) format-error` -> > -> > produces: `"This is a test error"`#} - -{#op||from-json||{{s}}||{{a0p}}|| -Converts a JSON string into {{m}} data.#} - -{#op||if||{{q1}} {{q2}} {{q3}}||{{a0p}}|| -If {{q1}} evaluates to {{t}} then evaluates {{q2}}, otherwise evaluates {{q3}}.#} - -{#op||import||{{sl}}||{{null}}|| -Imports the a previously-loaded module {{sl}}, defining all its symbols in the current scope. #} - -{#op||int||{{any}}||{{i}}|| -> Converts {{any}} to an integer value based on the following rules: -> -> * If {{any}} is {{t}}, it is converted to `1`. -> * If {{any}} is {{f}}, it is converted to `0`. -> * If {{any}} is an integer, no conversion is performed. -> * If {{any}} is a float, it is converted to an integer value by truncating its decimal part. -> * If {{any}} is a string, it is parsed as an integer value.#} - -{#op||linrec||{{q1}} {{q2}} {{q3}} {{q4}}||{{a0p}}|| -> Implements linear recursions as follows: -> -> 1. Evaluates {{q1}}. -> * If {{q1}} evaluates to {{t}}, then it evaluates {{q2}}. -> * Otherwises it executes {{q3}} and recurses using the same four quotations. -> 2. Finally, it executes {{q4}}. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `120` on the stack, the factorial of 5: -> > -> > (dup 0 ==) 'succ (dup pred) '* linrec - #} - -{#op||load||{{sl}}||{{a0p}}|| -Parses and interprets the specified {{m}} file, adding [.min](class:ext) if not specified. #} - -{#op||load-symbol||{{sl}}||{{a0p}}|| -Loads the contents of symbol {{sl}} from the [.min\_symbols](class:file) file. #} - -{#op||loglevel||{{sl}}||{{null}}|| -> Sets the current logging level to {{sl}}. {{sl}} must be one of the following strings or quoted symbols: -> -> * debug -> * info -> * notice -> * warn -> * error -> * fatal -> -> > %note% -> > Note -> > -> > The default logging level is _notice_.#} - -{#op||module||{{q}} {{sl}}||{{null}}|| -Creates a new module {{sl}} based on quotation {{q}}. #} - -{#op||module-sigils||{{q}}||({{s0p}})|| -Returns a list of all sigils defined in module {{q}}.#} - -{#op||module-symbols||{{q}}||({{s0p}})|| -Returns a list of all symbols defined in module {{q}}.#} - -{#op||opts||{{null}}||{{d}}|| -Returns a dictionary of all options passed to the current program, with their respective values.#} - -{#op||parse||{{s}}||{{q}}|| -Parses {{s}} and returns a quoted program {{q}}. #} - -{#op||prompt||{{null}}||{{s}}|| -> This symbol is used to configure the prompt of the min shell. By default, it is set to the following quotation: -> -> ([$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}}. -> -> > %sidebar% -> > Example -> > -> Publish symbol [my-local-symbol](class:kwd) to [ROOT](class:kwd) scope: -> > `'my-local-symbol ROOT publish` #} - -{#op||quote||{{any}}||({{any}})|| -Wraps {{any}} in a quotation. #} - -{#op||quote-bind||{{any}} {{sl}}||{{null}}|| -Quotes {{any}} and binds the quotation to the existing symbol {{sl}}. #} - -{#op||quote-define||{{any}} {{sl}}||{{null}}|| -Quotes {{any}} and assigns the quotation to the symbol {{sl}}, creating it if not already defined. #} - -{#op||raise||{{e}}||{{null}}|| -Raises the error specified via the dictionary {{e}}.#} - -{#op||read||{{sl}}||{{q}}|| -Reads and parses the specified {{m}} file {{sl}} and returns a quoted program {{q}}. #} - -{#op||remove-symbol||{{sl}}||{{null}}|| -Removes the symbol {{sl}} from the [.min\_symbols](class:file) file. #} - -{#op||save-symbol||{{sl}}||{{null}}|| -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||sigils||{{null}}||({{s0p}})|| -Returns a list of all sigils defined in the [ROOT](class:kwd) scope.#} - -{#op||source||{{sl}}||{{q}}|| -Display the source code of symbol {{sl}} (if it has been implemented a {{m}} quotation). #} - -{#op||stored-symbols||{{null}}||({{s0p}})|| -Returns a quotation containing all symbols stored in the [.min\_symbols](class:file) file. #} - -{#op||string||{{any}}||{{s}}|| -Converts {{any}} to its string representation.#} - -{#op||symbols||{{null}}||({{s0p}})|| -Returns a list of all symbols defined in the [ROOT](class:kwd) scope.#} - -{#op||tap||{{any}} {{q}}||{{any}}|| -> Performs the following operations: -> -> 1. Removes {{any}} from the stack. -> 2. For each quotation defined in {{q}} (which is a quotation of quotations each requiring one argument and returning one argument): -> 1. Pushes {{any}} back to the stack. -> 2. Dequotes the quotation and saves the result as {{any}}. -> 3. Push the resulting {{any}} back on the stack. -> -> > %sidebar% -> > Example -> > -> > The following program: -> > -> > ( -> > (("a" 1) ("b" 2) ("c" 3)) ( -> > (dup /a succ succ %a) -> > (dup /b succ %b) -> > ) tap -> > -> > Returns `(("a" 3) ("b" 3) ("c" 3))`.#} - -{#op||tap!||{{any}} {{q}}||{{any}}|| -> Performs the following operations: -> -> 1. Removes {{any}} from the stack. -> 2. For each quotation defined in {{q}} (which is a quotation of quotations each requiring one argument and returning one argument): -> 1. Pushes {{any}} back to the stack. -> 2. Dequotes the quotation and saves the result as {{any}}. -> -> > %sidebar% -> > Example -> > -> > The following program: -> > -> > "" :s1 -> > "test" ( -> > (' "1" swap append "" join) -> > (' "2" swap append "" join) -> > (' "3" swap append "" join @s1 s1) -> > ) tap! -> > -> > Sets `s1` to `"test123"`. #} - -{#op||times||{{q}} {{i}}||{{a0p}}|| -Applies the quotation {{q}} {{i}} times.#} - -{#op||to-json||{{q}}||{{s}}|| -Converts {{q}} into a JSON string {{s}}.#} - -{#op||try||({{q1}} {{q}}{{2}}{{01}} {{q}}{{3}}{{01}})||{{a0p}}|| -> Evaluates a quotation as a try/catch/finally block. -> -> The must contain the following elements: -> -> 1. A quotation {{q1}} containing the code to be evaluated (_try_ block). -> 1. _(optional)_ A quotation {{q2}} containing the code to execute in case of error (_catch_ block). -> 1. _(optional)_ A quotation {{q3}} containing the code to execute after the code has been evaluated, whether an error occurred or not (_finally_ block). -> -> > %sidebar% -> > Example -> > -> > The following program executed on an empty stack prints the message "Insufficient items on the stack" and pushes 0 on the stack: -> > -> > ( -> > (pop) -> > (format-error puts) -> > (0) -> > ) try #} - -{#op||unless||{{q1}} {{q2}}||{{a0p}}|| -If {{1}} evaluates to {{f}} then evaluates {{2}}.#} - -{#op||unseal||{{sl}}||{{null}}|| -Unseals symbol {{sl}}, so that it can be re-assigned. #} - -{#op||version||{{null}}||{{s}}|| -Returns the current min version number. #} - -{#op||when||{{q1}} {{q2}}||{{a0p}}|| -If {{q1}} evaluates to {{t}} then evaluates {{q2}}.#} - -{#op||while||{{q1}} {{q2}}||{{a0p}}|| -> Executes {{q2}} while {{q1}} evaluates to {{t}}. -> -> > %sidebar% -> > Example -> > -> > The following program prints all natural numbers from 0 to 10: -> > -> > 0 :count -> > (count 10 <=) -> > (count puts succ @count) while #} - -{#op||with||{{q1}} {{q2}}||{{a0p}}|| -Applies quotation {{q1}} within the scope of {{q2}}. #}
D site/contents/_includes/_reference-logic.md

@@ -1,66 +0,0 @@

-{@ _defs_.md || 0 @} - -{#op||&gt;||{{a1}} {{a2}}||{{b}}|| -> Returns {{t}} if {{a1}} is greater than {{a2}}, {{f}} otherwise. -> > %note% -> > Note -> > -> > Only comparisons among two numbers or two strings are supported.#} - -{#op||&gt;=||{{a1}} {{a2}}||{{b}}|| -> Returns {{t}} if {{a1}} is greater than or equal to {{a2}}, {{f}} otherwise. -> > %note% -> > Note -> > -> > Only comparisons among two numbers or two strings are supported.#} - -{#op||&lt;||{{a1}} {{a2}}||{{b}}|| -> Returns {{t}} if {{a1}} is smaller than {{a2}}, {{f}} otherwise. -> > %note% -> > Note -> > -> > Only comparisons among two numbers or two strings are supported.#} - -{#op||&lt;=||{{a1}} {{a2}}||{{b}}|| -> Returns {{t}} if {{a1}} is smaller than or equal to {{a2}}, {{f}} otherwise. -> > %note% -> > Note -> > -> > Only comparisons among two numbers or two strings are supported.#} - -{#op||==||{{a1}} {{a2}}||{{b}}|| -Returns {{t}} if {{a1}} is equal to {{a2}}, {{f}} otherwise. #} - -{#op||!=||{{a1}} {{a2}}||{{b}}|| -Returns {{t}} if {{a1}} is not equal to {{a2}}, {{f}} otherwise. #} - -{#op||and||{{b1}} {{b2}}||{{b3}}|| -Returns {{t}} if {{b1}} is equal to {{b2}}, {{f}} otherwise.#} - -{#op||boolean?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a boolean, {{f}} otherwise. #} - -{#op||dictionary?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a dictionary, {{f}} otherwise. #} - -{#op||float?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a float, {{f}} otherwise. #} - -{#op||or||{{b1}} {{b2}}||{{b3}}|| -Returns {{t}} if {{b1}} or {{b2}} is {{t}}, {{f}} otherwise.#} - -{#op||integer?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is an integer, {{f}} otherwise. #} - -{#op||not||{{b1}}||{{b2}}|| -Negates {{b1}}.#} - -{#op||number?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a number, {{f}} otherwise. #} - -{#op||quotation?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a quotation, {{f}} otherwise. #} - -{#op||xor||{{b1}} {{b2}}||{{b3}}|| -Returns {{t}} if {{b1}} and {{b2}} are different, {{f}} otherwise.#} -
D site/contents/_includes/_reference-math.md

@@ -1,72 +0,0 @@

-{@ _defs_.md || 0 @} - - -{#op||acos||{{n1}}||{{n2}}|| -Calculates the arc cosine of {{n1}} (in radians). #} - -{#op||asin||{{n1}}||{{n2}}|| -Calculates the arc sine of {{n1}} (in radians). #} - -{#op||atan||{{n1}}||{{n2}}|| -Calculates the arc tangent of {{n1}} (in radians). #} - -{#op||ceil||{{n}}||{{i}}|| -Returns the smallest integer {{i}} that is not smaller than {{n}}. #} - -{#op||cos||{{n1}}||{{n2}}|| -Calculates the cosine of {{n1}} (in radians). #} - -{#op||cosh||{{n1}}||{{n2}}|| -Calculates the hyperbolic cosine of {{n1}} (in radians). #} - -{#op||d2r||{{n1}}||{{n2}}|| -Converts {{n1}} from degrees to radians. #} - -{#op||e||{{null}}||{{n}}|| -Returns the value of the _e_ constant (Euler's number). #} - -{#op||floor||{{n}}||{{i}}|| -Returns the largest integer {{i}} that is not greater than {{n}}. #} - -{#op||ln||{{n1}}||{{n2}}|| -Calculates the natural logarithm of {{n1}}. #} - -{#op||log10||{{n1}}||{{n2}}|| -Calculates the common logarithm of {{n1}}. #} - -{#op||log2||{{n1}}||{{n2}}|| -Calculates the binary logarithm of {{n1}}. #} - -{#op||pi||{{null}}||{{n}}|| -Returns the value of the &pi; constant. #} - -{#op||pow||{{n1}} {{n2}}||{{n3}}|| -Computes {{n1}} to power raised of {{n2}}.#} - -{#op||r2d||{{n1}}||{{n2}}|| -Converts {{n1}} from radians to degrees. #} - -{#op||round||{{n1}} {{i}}||{{n2}}|| -Rounds {{n1}} to the {{i}}^th decimal place. #} - -{#op||sin||{{n1}}||{{n2}}|| -Calculates the sine of {{n1}} (in radians). #} - -{#op||sinh||{{n1}}||{{n2}}|| -Calculates the hyperbolic sine of {{n1}} (in radians). #} - -{#op||sqrt||{{n1}}||{{n2}}|| -Returns square root of {{n1}}. #} - -{#op||tan||{{n1}}||{{n2}}|| -Calculates the tangent of {{n1}} (in radians). #} - -{#op||tanh||{{n1}}||{{n2}}|| -Calculates the hyperbolic tangent of {{n1}} (in radians). #} - -{#op||tau||{{null}}||{{n}}|| -Returns the value of the &tau; constant (2&pi;). #} - -{#op||trunc||{{n1}}||{{n2}}|| -Truncates {{n}} to the decimal point. #} -
D site/contents/_includes/_reference-num.md

@@ -1,47 +0,0 @@

-{@ _defs_.md || 0 @} - - -{#op||+||{{n1}} {{n2}}||{{n3}}|| -Sums {{n1}} and {{n2}}. #} - -{#op||-||{{n1}} {{n2}}||{{n3}}|| -Subtracts {{n2}} from {{n1}}. #} - -{#op||-inf||{{null}}||{{n}}|| -Returns negative infinity. #} - -{#op||\*||{{n1}} {{n2}}||{{n3}}|| -Multiplies {{n1}} by {{n2}}. #} - -{#op||/||{{n1}} {{n2}}||{{n3}}|| -Divides {{n1}} by {{n2}}. #} - -{#op||even?||{{i}}||{{b}}|| -Returns {{t}} if {{i}} is even, {{f}} otherwise. #} - -{#op||div||{{i1}} {{i2}}||{{i3}}|| -Divides {{i1}} by {{i2}} (integer division). #} - -{#op||inf||{{null}}||{{n}}|| -Returns infinity. #} - -{#op||mod||{{i1}} {{i2}}||{{i3}}|| -Returns the integer module of {{i1}} divided by {{i2}}. #} - -{#op||nan||{{null}}||nan|| -Returns **NaN** (not a number). #} - -{#op||odd?||{{i}}||{{b}}|| -Returns {{t}} if {{i}} is odd, {{f}} otherwise. #} - -{#op||pred||{{i1}}||{{i2}}|| -Returns the predecessor of {{i1}}.#} - -{#op||random||{{i1}}||{{i2}}|| -Returns a random number {{i2}} between 0 and {{i1}}-1. #} - -{#op||succ||{{i1}}||{{i2}}|| -Returns the successor of {{i1}}.#} - -{#op||sum||{{q}}||{{i}}|| -Returns the sum of all items of {{q}}. {{q}} is a quotation of integers. #}
D site/contents/_includes/_reference-seq.md

@@ -1,206 +0,0 @@

-{@ _defs_.md || 0 @} - -{#sig||/||dget#} - -{#sig||?||dhas?#} - -{#sig||%||dset#} - -{#op||all?||{{q1}} {{q2}}||{{b}}|| -Applies predicate {{q2}} to each element of {{q1}} and returns {{t}} if all elements of {{q1}} satisfy predicate {{q2}}, {{f}} otherwise. #} - -{#op||any?||{{q1}} {{q2}}||{{b}}|| -Applies predicate {{q2}} to each element of {{q1}} and returns {{t}} if at least one element of {{q1}} satisfies predicate {{q2}}, {{f}} otherwise. #} - -{#op||append||{{any}} {{q}}||({{a0p}} {{any}})|| -Returns a new quotation containing the contents of {{q}} with {{any}} appended. #} - -{#op||get||{{q}} {{i}}||{{any}}|| -Returns the _n^th_ element of {{q}} (zero-based).#} - -{#op||concat||{{q1}} {{q2}}||{{q3}}|| -Concatenates {{q1}} with {{q2}}. #} - -{#op||ddel||{{d1}} {{sl}}||{{d2}}|| -Returns a copy of {{d1}} without the element with key {{sl}}. #} - -{#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}}: -> > -> > (("a1" true) ("a2" "aaa") ("a3" false)) '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 `(("a" 4) ("d" 7))`: -> > -> > (("q" 5) ("a" 4) ("c" 6) ("d" 7)) ("a" "d") dpick - #} - -{#op||dset||{{d1}} {{any}} {{sl}}||{{d2}}|| -Sets the value of the {{sl}} of {{d1}} to {{any}}, and returns the modified copy of the dictionary {{d2}}. #} - -{#op||dsort||{{d1}}||{{d2}}|| -> Returns a new dictionary {{d2}} containing all elements of {{d1}} sorted by key in ascending order. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `(("a" 342) ("b" true) ("c" -4) ("d" 22))` on the stack: -> > -> > (("b" true) ("d" 22) ("c" -4) ("a" 342)) dsort#} - -{#op||dvalues||{{d}}||({{a0p}})|| -Returns a quotation containing all the values of dictionary {{d}}. #} - -{#op||filter||{{q1}} {{q2}}||{{q3}}|| -> Returns a new quotation {{q3}} containing all elements of {{q1}} that satisfy predicate {{q2}}. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `(2 6 8 12)` on the stack: -> > -> > (1 37 34 2 6 8 12 21) -> > (dup 20 < swap even? and) filter #} - -{#op||find||{{q1}} {{q2}}||{{i}}|| -> Returns the index of the first element within {{q1}} that satisfies predicate {{q2}}. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `3` on the stack: -> > -> > (1 2 4 8 16) -> > (5 >) find #} - -{#op||first||{{q}}||{{any}}|| -Returns the first element of {{q}}. #} - -{#op||flatten||{{q1}}||{{q2}}|| -> Flattens all quotations within {{q1}} and returns the resulting sequence {{q2}}. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `(1 2 3 4 5 6 7 8)` on the stack: -> > -> > (1 (2 3 4) 5 (6 7) 8) -> > flatten #} - -{#op||harvest||{{q1}}||{{q2}}|| -> Creates a new quotation {{q2}} containing all elements of {{q1}} except for empty quotations. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `(1 2 3)` on the stack: -> > -> > (1 () () () 2 () 3) -> > harvest #} - -{#op||in?||{{q}} {{any}}||{{b}}|| -Returns {{t}} if {{any}} is contained in {{q}}, {{f}} otherwise.#} - -{#op||insert||{{q1}} {{any}} {{i}}||{{q2}}|| -Inserts {{any}} as the value of the _n^th_ element {{q1}} (zero-based), and returns the modified copy of the quotation {{q2}}. #} - -{#op||last||{{q}}||{{any}}|| -Returns the last element of {{q}}. #} - -{#op||map||{{q1}} {{q2}}||{{q3}}|| -Returns a new quotation {{q3}} obtained by applying {{q2}} to each element of {{q1}}.#} - -{#op||map-reduce||{{q1}} {{q2}} {{q3}}||{{i}}|| -> Applies {{q2}} (map) to each element of {{q1}} and then applies {{q3}} (reduce) to each successive element of {{q1}}. {{q1}} must have at least one element. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `35` on the stack: -> > -> > (1 3 5) -> > (dup *) (+) map-reduce #} - -{#op||partition||{{q1}} {{q2}}||{{q3}} {{q4}}|| -> Partitions {{q1}} into two quotations: {{q3}} contains all elements of {{q1}} that satisfy predicate {{q2}}, {{q4}} all the others. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `(1 2 3) (2 4 6)` on the stack: -> > -> > (1 2 3 4 5 6) -> > (odd?) partition #} - -{#op||prepend||{{any}} {{q}}||({{any}} {{a0p}})|| -Returns a new quotation containing the contents of {{q}} with {{any}} prepended. #} - -{#op||reduce||{{q1}} {{any}} {{q2}}||{{i}}|| -> Combines each successive element of {{q1}} using {{q2}}. On the first iteration, the first two inputs processed by {{q2}} are {{any}} and the first element of {{q1}}. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `120` on the stack: -> > -> > (1 2 3 4 5) -> > 1 (*) reduce #} - -{#op||reject||{{q1}} {{q2}}||{{q3}}|| -Returns a new quotatios {{q3}} including all elements of {{q1}} that do not satisfy predicate {{q2}} (i.e. the opposite of `filter`)#} - -{#op||remove||{{q1}} {{i}}||{{q2}}|| -Returns the _n^th_ element of {{q1}} (zero-based), and returns the modified copy of the quotation {{q2}}.#} - -{#op||rest||{{q1}}||{{q2}}|| -Returns a new quotation {{q2}} containing all elements of {{q1}} quotation except for the first. #} - -{#op||reverse||{{q1}}||{{q2}}|| -Returns a new quotation {{q2}} containing all elements of {{q1}} in reverse order. #} - -{#op||set||{{q1}} {{any}} {{i}}||{{q2}}|| -Sets the value of the _n^th_ element {{q1}} (zero-based) to {{any}}, and returns the modified copy of the quotation {{q2}}. #} - -{#op||shorten||{{q1}} {{i}}||{{q2}}|| -Returns a quotation {{q2}} containing the first _n_ values of the input quotation {{q1}}. #} - -{#op||size||{{q}}||{{i}}|| -Returns the length of {{q}}.#} - -{#op||slice||{{q1}} {{i1}} {{i2}}||{{q2}}|| -> Creates a new quotation {{q2}} obtaining by selecting all elements of {{q1}} between indexes {{i1}} and {{i2}}. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `(3 4 5)` on the stack: -> > -> > (1 2 3 4 5 6) -> > 2 4 slice #} - -{#op||sort||{{q1}} {{q2}}||{{q3}}|| -> Sorts all elements of {{q1}} according to predicate {{q2}}. -> -> > %sidebar% -> > Example -> > -> > The following program leaves `(1 3 5 7 9 13 16)` on the stack: -> > -> > (1 9 5 13 16 3 7) '> sort #}
D site/contents/_includes/_reference-stack.md

@@ -1,76 +0,0 @@

-{@ _defs_.md || 0 @} - -{#op||clear-stack||{{null}}||{{null}}|| -Empties the stack.#} - -{#op||cleave||{{a1}} ({{q}}{{0p}})||{{a0p}}|| -> Applies each quotation contained in the first element to the second element {{a1}}. -> > %sidebar% -> > Example -> > -> > The following program leaves 2 on the stack: -> > -> > `(1 2 3) ((sum) (size)) cleave /`#} - -{#op||cons||{{a1}} ({{a0p}})||({{a1}} {{a0p}})|| -Prepends {{a1}} to the quotation on top of the stack.#} - -{#op||dip||{{a1}} ({{a2}})||{{a0p}} {{a1}}|| -Removes the first and second element from the stack, dequotes the first element, and restores the second element.#} - -{#op||dup||{{a1}}||{{a1}} {{a1}}|| -Duplicates the first element on the stack.#} - -{#op||get-stack||{{null}}||({{a0p}})|| -Returns a quotation containing the contents of the stack.#} - -{#op||id||{{null}}||{{null}}|| -Does nothing.#} - -{#op||keep||{{a1}} {{q}}||{{a0p}} {{a1}}|| -> Applies each quotation contained in the first element to each subsequent corresponding element. -> > %sidebar% -> > Example -> > -> > The following program leaves `5 3` on the stack: -> > -> > `2 3 '+ keep` #} - -{#op||nip||{{a1}} {{a2}}||{{a2}}|| -Removes the second element from the stack.#} - -{#op||over||{{a1}} {{a2}}||{{a1}} {{a2}} {{a1}}|| -Pushes a copy of the second element on top of the stack.#} - -{#op||pick||{{a1}} {{a2}} {{a3}}||{{a1}} {{a2}} {{a3}} {{a1}}|| -Pushes a copy of the third element on top of the stack.#} - -{#op||pop||{{any}}||{{null}}|| -Removes the first element from the stack.#} - -{#op||rolldown||{{a1}} {{a2}} {{a3}}||{{a2}} {{a3}} {{a1}}|| -Moves the third element in first position, the second in third position and the the first in second position.#} - -{#op||rollup||{{a1}} {{a2}} {{a3}}||{{a3}} {{a2}} {{a1}}|| -Moves the third and second element into second and third position and moves the first element into third position.#} - -{#op||set-stack||{{q}}||{{a0p}}|| -Substitute the existing stack with the contents of {{q}}.#} - -{#op||sip||{{a1}} ({{a2}})||{{a0p}} {{a1}}|| -Saves the {{a1}}, dequotes {{a2}}, and restores {{a1}}.#} - -{#op||spread||{{a0p}} ({{q}}{{0p}})||{{a0p}}|| -> Applies each quotation contained in the first element to each subsequent corresponding element. -> > %sidebar% -> > Example -> > -> > The following program leaves `(1 4)` on the stack: -> > -> > `(1 2) (3 4) ((0 get) (1 get)) spread` #} - -{#op||swap||{{a1}} {{a2}}||{{a2}} {{a1}}|| -Swaps the first two elements on the stack. #} - -{#op||swons||({{a0p}}) {{a1}}||({{a1}} {{a0p}})|| -Prepends {{a1}} to the quotation that follows it.#}
D site/contents/_includes/_reference-str.md

@@ -1,140 +0,0 @@

-{@ _defs_.md || 0 @} - -{#alias||%||interpolate#} - -{#alias||=~||regex#} - -{#op||capitalize||{{sl}}||{{s}}|| -Returns a copy of {{sl}} with the first character capitalized.#} - -{#op||indent||{{sl}} {{i}}||{{s}}|| -Returns {{s}} containing {{sl}} indented with {{i}} spaces.#} - -{#op||indexof||{{s1}} {{s2}}||{{i}}|| -If {{s2}} is contained in {{s1}}, returns the index of the first match or -1 if no match is found. #} - -{#op||interpolate||{{s}} {{q}}||{{s}}|| -> Substitutes the placeholders included in {{s}} with the values in {{q}}. -> > %note% -> > Note -> > -> > If {{q}} contains symbols or quotations, they are not interpreted. To do so, call `apply` before interpolating. -> -> > %sidebar% -> > Example -> > -> > The following code (executed in a directory called '/Users/h3rald/Development/min' containing 19 files): -> > -> > `"Directory '$1' includes $2 files." (. (. ls 'file? filter size)) apply interpolate` -> > -> > produces: -> > -> > `"Directory '/Users/h3rald/Development/min' includes 19 files."`#} - -{#op||join||{{q}} {{sl}}||{{s}}|| -Joins the elements of {{q}} using separator {{sl}}, producing {{s}}.#} - -{#op||length||{{sl}}||{{i}}|| -Returns the length of {{sl}}.#} - -{#op||lowercase||{{sl}}||{{s}}|| -Returns a copy of {{sl}} converted to lowercase.#} - -{#op||match||{{s1}} {{s2}}||{{b}}|| -> Returns {{t}} if {{s2}} matches {{s1}}, {{f}} otherwise. -> > %tip% -> > Tip -> > -> > {{s2}} can be a {{sgregex}}-compatible regular expression.#} - -{#op||repeat||{{sl}} {{i}}||{{s}}|| -Returns {{s}} containing {{sl}} repeated {{i}} times.#} - -{#op||replace||{{s1}} {{s2}} {{s3}}||{{s4}}|| -> Returns a copy of {{s1}} containing all occurrences of {{s2}} replaced by {{s3}} -> > %tip% -> > Tip -> > -> > {{s2}} can be a {{sgregex}}-compatible regular expression. -> -> > %sidebar% -> > Example -> > -> > The following: -> > -> > `"This is a stupid test. Is it really a stupid test?" " s[a-z]+" " simple" replace` -> > -> > produces: `"This is a simple test. Is it really a simple test?"`#} - -{#op||regex||{{s1}} {{s2}}||{{q}}|| -> Performs a search and/or a search-and-replace operation using pattern {{s2}}. -> -> {{s2}} can be one of the following patterns: -> -> * **/**_search-regex_**/**_modifiers_ -> * **s/**_search-regex_**/**_replacemenet_**/**_modifiers_ -> -> {{q}} is always a quotation containing: -> -> * One or more strings containing the first match and captures (if any), like for the `search` operator. -> * A string containing the resuling string after the search-and-replace operation. -> -> > %tip% -> > Tip -> > -> > * _search-regex_ can be a {{sgregex}}-compatible regular expression. -> > * _modifiers_ are optionals can contain one or more of the following characters, in any order: -> > * **i**: case-insensitive match. -> > * **m**: multi-line match. -> > * **s**: dot character includes newlines. -> -> > %sidebar% -> > Example: Search -> > -> > The following: -> > -> > `"This is a GOOD idea." "/(good) idea/i" regex` -> > -> > produces: `("GOOD idea", "GOOD")` -> -> > %sidebar% -> > Example: Search and Replace -> > -> > The following: -> > -> > `"This is a GOOD idea." "s/good/bad/i" regex` -> > -> > produces: `("This is a bad idea")`#} - -{#op||search||{{s1}} {{s2}}||{{q}}|| -> Returns a quotation containing the first occurrence of {{s2}} within {{s2}}. Note that: -> -> * The first element of {{q}} is the matching substring. -> * Other elements (if any) contain captured substrings. -> -> > %tip% -> > Tip -> > -> > {{s2}} can be a {{sgregex}}-compatible regular expression. -> -> > %sidebar% -> > Example -> > -> > The following: -> > -> > `"192.168.1.1, 127.0.0.1" "[0-9]+\.[0-9]+\.([0-9]+)\.([0-9]+)" search` -> > -> > produces: `("192.168.1.1", "1", "1")`#} - -{#op||split||{{sl1}} {{sl2}}||{{q}}|| -Splits {{sl1}} using separator {{sl2}} and returns the resulting strings within the quotation {{q}}. #} - -{#op||strip||{{sl}}||{{s}}|| -Returns {{s}}, which is set to {{sl}} with leading and trailing spaces removed.#} - -{#op||titleize||{{sl}}||{{s}}|| -Returns a copy of {{sl}} in which the first character of each word is capitalized.#} - -{#op||uppercase||{{sl1}}||{{sl2}}|| -Returns a copy of {{sl}} converted to uppercase.#} -
D site/contents/_includes/_reference-sys.md

@@ -1,110 +0,0 @@

-{@ _defs_.md || 0 @} - -{#sig||$||get-env#} - -{#alias||$||get-env#} - -{#sig||\!||system#} - -{#alias||\!||system#} - -{#sig||&||run#} - -{#alias||&||run#} - -{#op||.||{{null}}||{{s}}|| -Returns the full path to the current directory. #} - -{#op||..||{{null}}||{{s}}|| -Returns the full path to the parent directory. #} - -{#op||chmod||{{sl}} {{i}}||{{null}}|| -> Sets the permissions of file or directory {{sl}} to {{i}}. {{i}} is a three-digit representation of user, group and other permissions. See the [Unix Permissions Calculator](http://permissions-calculator.org/) for examples and conversions. -> -> > %sidebar% -> > Example -> > -> > The following program makes the file **/tmp/test.txt** readable, writable and executable by its owner, and readable and executable by users of the same group and all other users: -> > -> > `/tmp/test.txt 755 chmod`#} - -{#op||cd||{{sl}}||{{null}}|| -Change the current directory to {{{sl}}. #} - -{#op||cp||{{sl1}} {{sl2}}||{{null}}|| -Copies the file or directory {{sl1}} to {{sl2}}. #} - -{#op||cpu||{{null}}||{{s}}|| -Returns the host CPU. It can be one of the following strings i386, alpha, powerpc, powerpc64, powerpc64el, sparc, amd64, mips, mipsel, arm, arm64. #} - -{#op||env?||{{sl}}||{{b}}|| -Returns {{t}} if environment variable {{sl}} exists, {{f}} otherwise. #} - -{#op||dir?||{{sl}}||{{b}}|| -Returns {{t}} if the specified path {{sl}} exists and is a directory. #} - -{#op||dirname||{{sl}}||{{s}}|| -Returns the path of the directory containing path {{sl}}.#} - -{#op||exists?||{{sl}}||{{b}}|| -Returns {{t}} if the specified file or directory {{sl}} exists. #} - -{#op||file?||{{sl}}||{{b}}|| -Returns {{t}} if the specified path {{sl}} exists and is a file. #} - -{#op||filename||{{sl}}||{{s}}|| -Returns the file name of path {{sl}}.#} - -{#op||get-env||{{sl}}||{{s}}|| -Returns environment variable {{sl}}. #} - -{#op||hardlink||{{sl1}} {{sl2}}||{{null}}|| -Creates hardlink {{sl2}} for file or directory {{sl1}}. #} - -{#op||ls||{{sl}}||{{q}}|| -Returns a quotation {{q}} containing all children (files and directories) of the directory {{sl}}. #} - -{#op||ls-r||{{sl}}||{{q}}|| -Returns a quotation {{q}} containing all children (files and directories) of the directory {{sl}}, recursively. #} - -{#op||mkdir||{{sl}}||{{null}}|| -Creates the specified directory {{sl}}. #} - -{#op||mv||{{sl1}} {{sl2}}||{{null}}|| -Moves the file or directory {{sl1}} to {{sl2}}. #} - -{#op||os||{{null}}||{{s}}|| -Returns the host operating system. It can be one of the following strings: windows, macosx, linux, netbsd, freebsd, openbsd, solaris, aix, standalone. #} - -{#op||put-env||{{sl1}} {{sl2}}||{{s}}|| -Sets environment variable {{sl2}} to {{sl1}}. #} - -{#op||rm||{{sl}}||{{null}}|| -Deletes the specified file {{sl}}. #} - -{#op||rmdir||{{sl}}||{{null}}|| -Deletes the specified directory {{sl}} and all its subdirectories recursively. #} - -{#op||run||{{sl}}||{{d}}|| -Executes the external command {{sl}} in the current directory without displaying its output. Returns a dictionary containing the command output and return code (in keys **output** and **code** respectively). #} - -{#op||sleep||{{i}}||{{null}}|| -Halts program execution for {{i}} milliseconds.#} - -{#op||symlink||{{sl1}} {{sl2}}||{{null}}|| -Creates symlink {{sl2}} for file or directory {{sl1}}. #} - -{#op||symlink?||{{sl}}||{{b}}|| -Returns {{t}} if the specified path {{sl}} exists and is a symbolic link. #} - -{#op||system||{{sl}}||{{null}}|| -Executes the external command {{sl}} in the current directory. #} - -{#op||unzip||{{sl}}||{{null}}|| -Decompresses zip file {{sl}}.#} - -{#op||which||{{sl}}||{{s}}|| -Returns the full path to the directory containing executable {{sl}}, or an empty string if the executable is not found in **$PATH**. #} - -{#op||zip||{{sl}} {{q}}||{{null}}|| -Compresses files included in quotation {{q}} into zip file {{sl}}.#}
D site/contents/_includes/_reference-time.md

@@ -1,25 +0,0 @@

-{@ _defs_.md || 0 @} - -{#op||now||{{null}}||{{flt}}|| -Returns the current time as Unix timestamp with microseconds. #} - -{#op||timestamp||{{null}}||{{i}}|| -Returns the current time as Unix timestamp. #} - -{#op||timeinfo||{{i}}||{{tinfo}}|| -Returns a timeinfo dictionary from timestamp {{i}}. #} - -{#op||to-timestamp||{{tinfo}}||{{i}}|| -Converts the timeinfo dictionary {{tinfo}} to the corresponding Unix timestamp. #} - -{#op||datetime||{{i}}||{{s}}|| -Returns an ISO 8601 string representing the combined date and time in UTC of timestamp {{i}}. #} - - -{#op||tformat||{{i}} {{s}}||{{s}}|| -> Formats timestamp {{i}} using string {{s}}. -> -> > %tip% -> > Tip -> > -> > For information on special characters in the format string, see the [format](https://nim-lang.org/docs/times.html#format,TimeInfo,string) nim method. #}
D site/contents/_includes/_reference.md

@@ -1,104 +0,0 @@

-{@ _defs_.md || 0 @} - -min includes a small but powerful standard library organized into the following _modules_: - -{#link-module||lang#} -: 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. -{#link-module||io#} -: Provides operators for reading and writing files as well as printing to STDOUT and reading from STDIN. -{#link-module||fs#} -: Provides operators for accessing file information and properties. -{#link-module||logic#} -: Provides comparison operators for all min data types and other boolean logic operators. -{#link-module||str#} -: Provides operators to perform operations on strings, use regular expressions, interpolation, etc.. -{#link-module||sys#} -: Provides operators to use as basic shell commands, access environment variables, and execute external commands. -{#link-module||num#} -: Provides operators to perform simple mathematical operations on integer and floating point numbers. -{#link-module||time#} -: Provides a few basic operators to manage dates, times, and timestamps. -{#link-module||crypto#} -: Provides operators to compute hashes (MD5, SHA1, SHA224, SHA256, SHA384, sha512), base64 encoding/decoding, and AES encryption/decryption. -{#link-module||math#} -: Provides many mathematical operators and constants such as trigonometric functions, square root, logarithms, etc. - -## Notation - -The following notation is used in the signature of all min operators: - -### Types and Values - -{{null}} -: No value. -{{any}} -: A value of any type. -{{b}} -: A boolean value -{{i}} -: An integer value. -{{flt}} -: A float value. -{{n}} -: A numeric (integer or float) value. -{{s}} -: A string value. -{{sl}} -: A string-like value (string or quoted symbol). -{{q}} -: A quotation (also expressed as parenthesis enclosing other values). -{{d}} -: A dictionary value. -{{tinfo}} -: A timeinfo dictionary: - <pre><code>( - ("year" 2017) - ("month" 7) - ("day" 8) - ("weekday" 6) - ("yearday" 188) - ("hour" 15) - ("minute" 16) - ("second" 25) - ("dst" true) - ("timezone" -3600) - ) - </code></pre> -{{e}} -: An error dictionary: - <pre><code>( - ("error" "MyError") - ("message" "An error occurred") - ("symbol" "symbol1") - ("filename" "dir1/file1.min") - ("line" 3) - ("column" 13) - ) - </code></pre> -{{t}} -: true (boolean type). -{{f}} -: false (boolean type) - -### Suffixes - -The following suffixes can be placed at the end of a value or type to indicate ordering or quantities. - -{{1}} -: The first value of the specified type. -{{2}} -: The second value of the specified type. -{{3}} -: The third value of the specified type. -{{4}} -: The fourth value of the specified type. -{{01}} -: Zero or one. -{{0p}} -: Zero or more. -{{1p}} -: One or more
M site/contents/about.mdsite/contents/about.md

@@ -2,4 +2,39 @@ -----

content-type: "page" title: "About" ----- -{@ _includes/_about.md || 1 @} +{@ _defs_.md || 0 @} + +**min** is an concatenative, fully-homoiconic, functional, interpreted programming language. + +This basically means that: + +* It is based on a somewhat obscure and slightly unintuitive programming paradigm, think of [Forth](http://www.forth.org/), [Factor](http://factorcode.org/) and [Joy](http://www.kevinalbrecht.com/code/joy-mirror/) but with parethesis for an extra [Lisp](https://common-lisp.net/)y flavor. +* Programs written in min are actually written using *quotations*, i.e. lists. +* It comes with map, filter, find, map-reduce and loads of other functional goodies. See the {#link-module||seq#} for more. +* It is probably slower than the average production-ready programming language. + +## Why? + +Because creating a programming language is something that every programmer needs to do, at some point in life. And also because there are way too few [concatenative](http://concatenative.org/wiki/view/Front%20Page) programming language out there -- so people are likely to be _less_ pissed off than if I made a yet another Lisp instead. + +I always wanted to build a minimalist language, but that could also be used for real work and provided a standard library for common tasks and functionalities like regular expression support, cryptography, execution of external programs, shell-like operators and keywords to work with files, and more. + +Also, I wanted it to be fully self-contained, cross platform, and tiny. About 1MB (depending on the platform) is not really tiny, but I feel it's a good compromise compared to the alternatives out there, considering that you only need _one file_ to run any min program. + +I am currently building a static site generator called [HastySite](https://github.com/h3rald/hastysite), that also powers <https://min-lang.org>. HastySite internally uses min as the language to write the [rules](https://github.com/h3rald/min/blob/master/site/rules.min) to process the source files of the site, and also all its [scripts](https://github.com/h3rald/min/tree/master/site/scripts). + +Finally, I think more and more people should get to know concatenative programming languages, because [concatenative programming matters](http://evincarofautumn.blogspot.it/2012/02/why-concatenative-programming-matters.html). + +## How? + +min is developed entirely in [Nim](https://nim-lang.org) -- the name is (almost) entirely a coincidence. I wanted to call it _minim_ but then shortened it for more... minimalism. + +min's parser started off as a fork of Nim's JSON parser -- adapted to process a concatenative programming language with less primitive types than JSON. It is interpreted in the traditional sense: no bytecode, no JIT, just plain read, parse and run. + +## Who? + +min was created and implemented by [Fabio Cevasco](https://h3rald.com), with contributions by [Peter Munch-Ellingsen](https://peterme.net). + +## When? + +min source code [repository](https://github.com/h3rald/min) was created on November 8^th 2014. This only means that I've been very slowly developing something that was actually made public at the end of July 2017.
M site/contents/download.mdsite/contents/download.md

@@ -2,4 +2,64 @@ -----

content-type: "page" title: "Download" ----- -{@ _includes/_download.md || 1 @} +{@ _defs_.md || 0 @} + + +You can download one of the following pre-built min binaries: + +* {#release||{{$version}}||macosx||macOS||x64#} +* {#release||{{$version}}||windows||Windows||x64#} +* {#release||{{$version}}||linux||Linux||x64#} +* {#release||{{$version}}||linux||Linux||x86#} +* {#release||{{$version}}||linux||Linux||arm#} + +{#release -> [min v$1 for $3 ($4)](https://github.com/h3rald/min/releases/download/v$1/min\_v$1\_$2\_$4.zip) #} + +{{guide-download}} + +## Building from Source + +Alternatively, you can build min from source as follows: + +1. Download and install [nim](https://nim-lang.org). +2. Download and build [Nifty](https://github.com/h3rald/nifty), and put the nifty executable somewhere in your [$PATH](class:kwd). +3. Clone the min [repository](https://github.com/h3rald/min). +4. Navigate to the min repository local folder. +5. Run **nifty install** to download min’s dependencies. +7. Run **nim c -d:release min.nim**. + +## Running then min Shell + +To start min shell, run [min -i](class:cmd). You will be presented with a prompt displaying the path to the current directory: + +> %min-terminal% +> [[/Users/h3rald/test]$](class:prompt) + +You can type min code and press [ENTER](class:kbd) to evaluate it immediately: + +> %min-terminal% +> [[/Users/h3rald/test]$](class:prompt) 2 2 + +> {1} -> 4 +> [[/Users/h3rald/test]$](class:prompt) + +The result of each operation will be placed on top of the stack, and it will be available to subsequent operation + +> %min-terminal% +> [[/Users/h3rald/test]$](class:prompt) dup * +> {1} -> 16 +> [[/Users/h3rald/test]$](class:prompt) + +To exit min shell, press [CTRL+C](class:kbd) or type [exit](class:cmd) and press [ENTER](class:kbd). + +## Executing a min Program + +To execute a min script, you can: + +* Run `min -e:"... program ..."` to execute a program inline. +* Run `min myfile.min` to execute a program contained in a file. + +min also supports running programs from standard input, so the following command can also be used (on Unix-like system) to run a program saved in [myfile.min](class:file): + +> %min-terminal% +> +> [$](class:prompt) cat myfile.min | min
M site/contents/learn-control-flow.mdsite/contents/learn-control-flow.md

@@ -2,4 +2,80 @@ -----

content-type: "page" title: "Learn: Control Flow" ----- -{@ _includes/_learn-control.flow.md || 0 @} +{@ _defs_.md || 0 @} + + +The {#link-module||lang#} provide some symbols that can be used for the most common control flow statements. Unlike most programming language, min does not differentiate between functions and statements -- control flow statements are just ordinary symbols that manipulate the main stack. + + +## Conditionals + +The following symbols provide ways to implement common conditional statements: + +* {#link-operator||lang||case#} +* {#link-operator||lang||if#} +* {#link-operator||lang||unless#} +* {#link-operator||lang||when#} + +For example, consider the following program: + + ( + ( + "" :type + (("\.(md|markdown)$") ("markdown" @type)) + (("\.txt$") ("text" @type)) + (("\.min$") ("min" @type)) + (("\.html?$") ("HTML" @type)) + ((true) ("unknown" @type)) + ) case + "This is a $1 file." (type) % echo + ) :display-file-info + +This program defines a symbol `display-file-info` that takes a file name and outputs a message displaying its type, if known. + + +## Loops + +The following symbols provide ways to implement common loops: + +* {#link-operator||lang||foreach#} +* {#link-operator||lang||times#} +* {#link-operator||lang||while#} + + +For example, consider the following program: + + ( + :n + 1 :i + 1 :f + (i n <=) + ( + f i * @f + i succ @i + ) while + f + ) :factorial + +This program defines a symbol `factorial` that calculates the factorial of an integer iteratively using the symbol {#link-operator||lang||while#}. + +## Error handling + +The following symbols provide ways to manage errors in min: + +* {#link-operator||lang||format-error#} +* {#link-operator||lang||raise#} +* {#link-operator||lang||try#} + +For example, consider the following program: + + . ls + ( + ( + (fsize) + (pop 0) + ) try + ) 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.
M site/contents/learn-data-types.mdsite/contents/learn-data-types.md

@@ -2,4 +2,38 @@ -----

content-type: "page" title: "Learn: Data Types" ----- -{@ _includes/_learn-data-types.md || 0 @} +{@ _defs_.md || 0 @} + + +The type system of min is very simple -- only the following data types are available: + +integer +: An integer number like 1, 27 or -15. +float +: 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). + +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 symbol 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) +> ) + +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?`). + +> %note% +> Note +> +> Most of the operators defined in the {#link-module||num#} are able to operate on both integers and floats. + +{#link-learn||operators||Operators#}
M site/contents/learn-definitions.mdsite/contents/learn-definitions.md

@@ -2,4 +2,113 @@ -----

content-type: "page" title: "Learn: Definitions" ----- -{@ _includes/_learn-definitions.md || 0 @} +{@ _defs_.md || 0 @} + + +Being a concatenative language, min does not really need named parameters or variables: simbols just pop elements off the main stack in order, and that's normally enough. There is however one small problem witht the traditional concatenative paradigm; consider the following program for example: + + dup dup + "\.zip$" match + swap fsize 1000000 > and + swap mtime now 3600 - > + +This program takes a single string corresponding to a file path and returns true if it's a .zip file bigger than 1MB that was modified in the last how. Sure, it is remarkable that no variables are needed for such a program, but it is not very readable: because no variables are used, it is often necessary to make copies of elements and push them to the end of the stack -- that's what the {#link-operator||stack||dup#} and {#link-operator||stack||swap#} are used for. + +The good news is that you can use the {#link-operator||lang||define#} operator and the `:` sigil to define new symbols, and symbols can also be set to literals of course. + +Consider the following program: + + :filepath + filepath "\.zip$" match + filepath fsize 1000000 > + filepath mtime now 3600 - > + and and + +In this case, the `filepath` symbol is defined and then used on the following three lines, each of which defines a condition to be evaluated. The last line contains just two {#link-operator||logic||and#} symbols necessary to compare the three conditions. + + +## Lexical scoping and binding + +min, like many other programming languages, uses [lexical scoping](https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scope_vs._dynamic_scope) to resolve symbols. + +Consider the following program: + + + 4 :a + ( + a 3 + :a + ( + a 1 + :a + (a dup * :a) dequote + ) dequote + ) dequote + +...What is the value of the symbol `a` after executing it? + +Simple: `4`. Every quotation defines its own scope, and in each scope a new variable called `a` is defined. In the innermost scope containing the quotation `(a dup * :a)` the value of `a` is set to `64`, but this value is not propagated to the outer scopes. Note also that the value of `a` in the innermost scope is first retrieved from the outer scope (8). + +If we want to change the value of the original `a` symbol defined in the outermost scope, we have to use the {#link-operator||lang||bind#} or its shorthand sigil `@`, so that the programs becomes the following: + + 4 :a ;First definition of the symbol a + ( + a 3 + @a ;The value of a is updated to 7. + ( + a 1 + @a ;The value of a is updated to 8 + (a dup * @a) dequote ;The value of a is now 64 + ) dequote + ) dequote + +## quote-define and quote-bind + +So far, we saw how to use the {#link-operator||lang||define#} and {#link-operator||lang||bind#} operator (or better, their shorthand sigils `:` and `@`) to define new symbols or bind values to existing ones. + +Consider the following example: + + (1 2 3 4 5) :my-list + my-list (dup *) map + +If run the program above in min shell by pasting the first and then the second line in it, you'll get an error similar to the following: + + (!) <repl>(1,19) [map]: Incorrect values found on the stack: + - expected: {top} quot quot {bottom} + - got: {top} quot int {bottom} + <repl>(1,19) in symbol: map + +This error says that when the {#link-operator||lang||map#} operator was evaluated, there were incorrect values on the stack. Two quotations were expected, but instead a quotation and an integer were found. How did this happen? + +Basically, when `my-list` was pushed on the stack, it pushed all its item on top of the stack. If you run {#link-operator||stack||get-stack#}, it will return the following list: + + (1 2 3 4 5 (dup *)) + +This happens because by default min assumes that when you define a quotation you want to define a new operator rather than a list. The following program works as expected, and it returns a list containing the squares of the first five integer numbers: + + (dup *) :square + (1 2 3 4 5) (square) map + +To avoid this behavior -- i.e. whenever you want to define a list of items rather than an operator that will be immediately evaluated when pushed on the stack, you have to use the {#link-operator||lang||quote-define#} and the {#link-operator||lang||quote-bind#} or their respective sigils `#` and `=`: + + (1 2 3 4 5) #my-list + my-list (dup *) map ;Returns (1 4 9 16 25) + +## Sealing symbols + +Finally, symbols can be sealed to pervent accidental updates or deletions. By default, all symbols defined in the core min modules are sealed, so the following code if run in min shell will result in an error: + + + 5 :quote + +...because the symbol quote is already defned in the root scope. However, note that the folliwng code will _not_ return an error: + + (5 :quote quote dup *) -> ;returns 25 + +...because the `quote` symbol is only defined in the root scope and can therefore be redefined in child scopes. + +If you want, you can {#link-operator||lang||seal#} your own symbols so that they may not be redefined using the {#link-operator||lang||bind#} operator or deleted using the {#link-operator||lang||delete#}. + +> %info% +> Note +> +> The {#link-operator||lang||unseal#} operator can be used to effectively un-seal a previously-sealed symbol. Use with caution! + + +{#link-learn||control-flow||Control Flow#}
M site/contents/learn-extending.mdsite/contents/learn-extending.md

@@ -2,4 +2,160 @@ -----

content-type: "page" title: "Learn: Extending min" ----- -{@ _includes/_learn-extending.md || 0 @} +{@ _defs_.md || 0 @} + +min provides a fairly complete standard library with many useful modules. However, you may feel the need to extend min in order to perform more specialized tasks. + +In such situations, you basically have three options: + +* Implement new min modules in min +* Embed min in your [Nim](https://nim-lang.org) program +* Implemet min modules as dynamic libraries in Nim + +## Implementing new min modules using min itself + +When you just want to create more high-level min operator using functionalities that are already available in min, the easiest way is to create your own reusable min modules. + +The {#link-operator||lang||module#} (and the **+** sigil) allows you to create a new min module: + +``` +( + (dup *) :pow2 + + (dup dup * *) :pow3 + + (dup dup dup * * *) :pow4 + +) +quickpows + +``` + +Save your code to a file (e.g. *quickpows.min*) and you can use it in other nim files using the {#link-operator||lang||load#} operator and the {#link-operator||lang||import#}: + +``` +'quickpows load +'quickpows import + +2 pow3 pow2 puts ;prints 64 +``` + +## Embedding min in your Nim program + +If you'd like to use min as a scripting language within your own program, and maybe extend it by implementing additional operators, you can use min as a Nim library. + +To do so: + +1. Install min sources using Nifty as explained in the {#link-page||download||Download#} section. +2. Import it in your Nim file. +3. Implement a new `proc` to define the module. + +The following code is taken from [HastySite](https://github.com/h3rald/hastysite) and shows how to define a new `hastysite` module containing some symbols (`preprocess`, `postprocess`, `process-rules`, ...): + +``` +import packages/min/min + +proc hastysite_module*(i: In, hs1: HastySite) = + var hs = hs1 + let def = i.define() + + def.symbol("preprocess") do (i: In): + hs.preprocess() + + def.symbol("postprocess") do (i: In): + hs.postprocess() + + def.symbol("process-rules") do (i: In): + hs.interpret(hs.files.rules) + + # ... + + def.finalize("hastysite") +``` + +Then you need to: + +4. Instantiate a new min interpreter using the `newMinInterpreter` proc. +5. Run the `proc` used to define the module. +6. Call the `interpret` method to interpret a min file or string: + +``` +proc interpret(hs: HastySite, file: string) = + var i = newMinInterpreter(file, file.parentDir) + i.hastysite_module(hs) + i.interpret(newFileStream(file, fmRead)) +``` + +> %tip% +> Tip +> +> For more information on how to create new modules with Nim, have a look in the [lib folder](https://github.com/h3rald/min/tree/master/lib) of the min repository, which contains all the min modules included in the standard library. + + +## Implementing min modules as dynamic libraries + +> %warning% +> Warning +> +> This technique is currently experimental, it has not been tested extensively and it may not even work on Windows. + +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. + +In order to do this, you don't even need to download the whole min source code, you just need to download the [mindyn.nim](https://github.com/h3rald/min/blob/master/mindyn.nim) file and import it in your Nim program. + +The following code shows how to create a simple min module called *dyntest* containing only a single operator *dynplus*, which essentially returns the sum of two numbers: + +``` +import mindyn + +proc dyntest*(i: In) {.dynlib, exportc.} = + + let def = i.define() + + def.symbol("dynplus") do (i: In): + let vals = i.expect("num", "num") + let a = vals[0] + let b = vals[1] + if a.isInt: + if b.isInt: + i.push newVal(a.intVal + b.intVal) + else: + i.push newVal(a.intVal.float + b.floatVal) + else: + if b.isFloat: + i.push newVal(a.floatVal + b.floatVal) + else: + i.push newVal(a.floatVal + b.intVal.float) + + def.finalize("dyntest") +``` + +Note that the `mindym.nim` file contains the signatures of all the `proc`s that are commonly used to define min modules, but not their implementation. Such `proc`s will become available at run time when the dynamic library is linked to the min executable. + +You can compile the following library by running the following command: + +> %min-terminal% +> [$](class:prompt) nim c \-\-app:lib -d:release \-\-noMain dyntest.nim + +If you are using [clang](https://clang.llvm.org/) to compile Nim code, you may need to run the following command instead: + +> %min-terminal% +> [$](class:prompt) nim c \-\-app:lib -d:release \-\-noMain -l:&#34;-undefined dynamic\_lookup&#34; dyntest.nim + +Now you should have a `libdyntest.so|dyn|dll` file. To make min load it and link it automatically when it starts, just run: + +> %min-terminal% +> [$](class:prompt) min \-\-install:libdyntest.dyn + +This command will copy the library file to `$HOME/.minlibs/` (`%HOMEPATH%\.minlibs\` on Windows). min looks for dynamic libraries in this folder when it starts. + +> %note% +> Notes +> +> * The dynamic library file must have the same name as the module it defines (*dyntest* in this case). +> * At startup, min links all your installed dynamic libraries but does not import the modules automatically. + +If you wish to uninstall the library, run the following command instead: + +> %min-terminal% +> [$](class:prompt) min \-\-uninstall:libdyntest.dyn +
M site/contents/learn-operators.mdsite/contents/learn-operators.md

@@ -2,4 +2,62 @@ -----

content-type: "page" title: "Learn: Operators" ----- -{@ _includes/_learn-operators.md || 0 @} +{@ _defs_.md || 0 @} + +Every min program needs _operators_ to: + +* Manipulate elements on the stack +* Perform operations on data +* Provide side effects (read/print to standard input/output/files, etc.) + +There are two types of operators: _symbols_ and _sigils_. + +_Symbols_ are the most common type of operator. A min symbol is a single word that is either provided by one of the predefined min {#link-page||reference||modules#} like `dup` or `.` or defined by the user. User-defined symbols must: + +* Start with a letter or an underscore (\_). +* Contain zero or more letters, numbers and/or any of the following characters: `/ ! ? + * . _ -` + +It is possible to define symbols using the {#link-operator||lang||define#} symbol. The following min program defines a new symbol called square that duplicates the first element on the stack and multiplies the two elements: + + (dup *) "square" define + +Besides symbols, min provides a set of predefined _sigils_ for commonly-used symbols. For example, the previous definition could be rewritten as follows using sigils: + + (dup *) :square + +A sigil like `:` can be prepended to a single-word string instead of using the corresponding symbol. Essentially, sigils are nothing more than syntactic sugar. Currently min provides the following sigils: + ++ +: Alias for {#link-operator||lang||module#}. +~ +: Alias for {#link-operator||lang||delete#}. +' +: Alias for {#link-operator||lang||quote#}. +\: +: Alias for {#link-operator||lang||define#}. +^ +: Alias for {#link-operator||lang||call#}. +@ +: Alias for {#link-operator||lang||bind#}. +> +: Alias for {#link-operator||lang||save-symbol#}. +< +: Alias for {#link-operator||lang||load-symbol#}. +&#61; +: Alias for {#link-operator||lang||quote-bind#}. +\# +: Alias for {#link-operator||lang||quote-define#}. +/ +: Alias for {#link-operator||seq||dget#}. +% +: Alias for {#link-operator||seq||dset#}. +? +: Alias for {#link-operator||seq||dhas?#}. +! +: Alias for {#link-operator||sys||system#}. +& +: Alias for {#link-operator||sys||run#}. +$ +: Alias for {#link-operator||sys||get-env#}. + +{#link-learn||quotations||Quotations#}
M site/contents/learn-quotations.mdsite/contents/learn-quotations.md

@@ -2,4 +2,46 @@ -----

content-type: "page" title: "Learn: Quotations" ----- -{@ _includes/_learn-quotations.md || 0 @} +{@ _defs_.md || 0 @} + +Quotations are the most important thing to understand in min. Besides being the data type used for lists, they are also used to delimit blocks of min code that is not going to be immediately executed. + +Consider for example the following min code which returns all the files present in the current folder sorted by name: + + . ls (ftype "file" ==) filter '> sort + +The symbol {#link-operator||seq||filter#} takes two quotations as arguments -- the first quotation on the stack is applied to all the elements of the second quotation on the stack, to determine which elements of the second quotation will be part of the resulting quotation. This is an example of how quotations can be used both as lists and programs. + +Let's examine this program step-by-step: + +{{fdlist => ("dir1" "dir2" file1.txt "file2.txt" "file3.md" "file4.md")}} +{{flist => ("file1.txt" "file2.txt" "file3.md" "file4.md")}} + +1. The `.` symbol is pushed on the stack, and it is immediately evaluated to the full path to the current directory. +2. The `ls` symbol is pushed on the stack, it consumes the string already on the stack and returns a quotation containing all files and directories within the current directory. +3. The quotation `(ftype 'file ==)` is pushed on the stack. It is treated exactly like a list of data and it is not evaluated. +4. The `filter` symbol is pushed on the stack. This symbol takes two quotations as input, and applies the result of the first quotation on the stack (`(ftype "file" ==)`) to all elements of the second quotation of the stack (the list of files and directories), returning a new quotation containing only those elements of the second quotation on the stack that satisfy the result of the first quotation. In this case, it returns a new quotation containing only files. +5. `'>` is pushed on the stack. The `'` sigil can be used instead of the `quote` symbol to quote a single symbol, `<` in this case. In other words, it is instantly evaluated to the quotation `(>)`. +6. The symbol `sort` is pushed on the stack. This symbol, like `filter`, takes two quotations as input, and applies the first quotation to each element of the second quotation, effectively sorting each element of the second quotation using the predicate expressed by the first quotation. In this case, all files are sorted by name in ascending order. + +> %tip% +> Tip +> +> The {{#link-module||seq#}} provides several symbols to work with quotations in a functional way. + + +## Quoting, dequoting, and applying + +When a quotation is created, it is treated as data, no matter what it contains: it is placed on the stack, like an integer or a string would. However, unlike other data types, a quotation can be evaluated in certain situations and when it happens its contents are pushed on the stack. + +Consider the following program: + + (1 2 3 4 5 6 7) (odd?) filter + +This programs returns a new quotation containing all odd numbers contained in quotation `(1 2 3 4 5 6 7)`. + +In this case, the second quotation is used to _quote_ the symbol `odd?` so that instead of being executed immediately, it will be executed by the symbol `filter` on each element of the first quotation. In this way, we may say that `(odd?)` is _dequoted_ by the symbol `filter`. + +The synbol {#link-operator||lang||dequote#} or its alias `->` can be used to dequote a quotation by pushing all its element on the main stack, while the symbol {#link-operator||lang||apply#} can be used to dequote a quotation by pushing its element on a separate stack. + +{#link-learn||definitions||Definitions#}
M site/contents/learn-shell.mdsite/contents/learn-shell.md

@@ -2,4 +2,63 @@ -----

content-type: "page" title: "Learn: Shell" ----- -{@ _includes/_learn-shell.md || 0 @} +{@ _defs_.md || 0 @} + +The min executable also provide an interactive REPL (Read-Eval-Print Loop) when launched with the `-i` flag: + +> %min-terminal% +> [$](class:prompt) min -i +> <span class="prompt">&#91;/Users/h3rald/Development/min&#93;$</span> + +Although not as advanced, the min REPL is not dissimilar from an OS system shell like Bash, and as a matter of fact it provides many functionalities that are found in other shells or command prompts, such as: + +* Auto-completion +* Persistent line history +* A customizable prompt +* Access to environment variables + +...plus in can obviously leverage the entire min language for complex scripting. + +## Autocompletion and shortcuts + +The min shell features smart tab autocompletion and keyboard shortcut implemented using the [nimline](https://github.com/h3rald/nimline) library. + +The following behaviors are implemented when pressing the `TAB` key within: + +Context | Result +---------------------------------------------------------------|-------------- +...a string | Auto-completes the current word using file and directory names. +...a word starting with `!` or `&` | Auto-completes the current word using executable file names. +...a word starting with `$` | Auto-completes the current word using environment variable names. +...a word starting with `'`, `~`, `@`, `#`, `>`, `<`, `*`, `(` | Auto-completes the current word using symbol names. + +Additionally, at least some of the following systems should also be available, depending on your operating system: + +Key | Effect +---------------|------------------------ +`INSERT` | Switches between insert and replace mode. +`UP` | Displays the previous history entry. +`DOWN` | Displays the next history entry. +`CTRL+c` | Terminates min shell. +`CTRL+x` | Clears the current line. +`CTRL+b` | Goes to the beginning of the line. +`CTRL+e` | Goes to the end of the line. + + +## Shell configuration files + +When the min interpreter is first launched, the following files are created automatically in the $HOME directory (%HOMEPROFILE% on Windows). + +### .minrc + +This file is interpreted first every time min is run. By default it is empty, but it can be used to define code to execute at startup. + +### .min\_history + +This file is used to persist all commands entered in the min shell, and it is loaded in memory at startup to provide line history support. + +### .min\_symbols + +This files contains all symbol definitions in JSON format that were previously-saved using the {#link-operator||lang||save-symbol#} symbol. Symbols can be loaded using the {#link-operator||lang||load-symbol#} symbol. + +{#link-learn||extending||Extending min#}
M site/contents/learn.mdsite/contents/learn.md

@@ -2,4 +2,34 @@ -----

content-type: "page" title: "Learn" ----- -{@ _includes/_learn.md || 0 @} +{@ _defs_.md || 0 @} + +{{learn-links}} + +*min* is a stack-based, concatenative programming language that uses postfix notation. If you already know [Forth](http://www.forth.org/), [Factor](http://factorcode.org/) or [Joy](http://www.kevinalbrecht.com/code/joy-mirror/), or if you ever used an [RPN](https://en.wikipedia.org/wiki/Reverse_Polish_notation) calculator, then min will look somewhat familiar to you. + +If not, well, here's how a short min program looks like: + + ; This is a comment + (1 2 3 4 5) (dup *) map + +This program returns a list containing the square values of the first five integer numbers: + + (1 4 9 16 25) + +Let's see how it works: + +1. First a list containing the first five integer is pushed on the stack. +2. Then, another list containing two symbols (`dup` and `*`) is pushed on the stack. This constitutes a quoted program which, when executed duplicates (`dup`) the first element on the stack and then multiplies (`*`) the two elements together. +3. Finally, the symbol `map` is pushed on the stack. Map takes a list of elements and a quoted program and applies the program to each element. + +Note that: + +* There are no variable assignments. +* elements are pushed on the stack one by one. +* Parentheses are grouped together one or more elements, so that they are treated as a single element and they are not evaluated immediately. +* Symbols can be used to perform operations on the whole stack. + +Unlike more traditional programming languages, in a concatenative programming language there is no inherent need of variables or named parameters, as symbols acts as stack operators that consume elements that are placed in order on top of a stack. + +{#link-learn||data-types||Data Types#}
M site/contents/reference-crypto.mdsite/contents/reference-crypto.md

@@ -2,4 +2,32 @@ -----

content-type: "page" title: "crypto Module" ----- -{@ _includes/_reference-crypto.md || 1 @} +{@ _defs_.md || 0 @} + +{#op||md5||{{sl}}||{{s}}|| +Returns the MD5 hash of {{sl}}. #} + +{#op||sha1||{{sl}}||{{s}}|| +Returns the SHA1 hash of {{sl}}. #} + +{#op||sha224||{{sl}}||{{s}}|| +Returns the SHA224 hash of {{sl}}. #} + +{#op||sha256||{{sl}}||{{s}}|| +Returns the SHA256 hash of {{sl}}. #} + +{#op||sha384||{{sl}}||{{s}}|| +Returns the SHA384 hash of {{sl}}. #} + +{#op||sha512||{{sl}}||{{s}}|| +Returns the SHA512 hash of {{sl}}. #} + +{#op||encode||{{sl}}||{{s}}|| +Base64-encodes {{sl}}. #} + +{#op||encode||{{sl}}||{{s}}|| +Decodes the Base64-encoded string {{sl}}. #} + +{#op||aes||{{sl1}} {{sl2}}||{{s}}|| +Encrypts or decrypts {{sl1}} using the Advanced Encryption Standard (AES), using {{sl2}} as password. #} +
M site/contents/reference-fs.mdsite/contents/reference-fs.md

@@ -2,4 +2,50 @@ -----

content-type: "page" title: "fs Module" ----- -{@ _includes/_reference-fs.md || 1 @} +{@ _defs_.md || 0 @} + +{#op||atime||{{sl}}||{{flt}}|| +Returns a timestamp corresponding to the time that file/directory {{sl}} was last accessed.#} + +{#op||ctime||{{sl}}||{{flt}}|| +Returns a timestamp corresponding to the time that file/directory {{sl}} was created.#} + +{#op||fperms||{{sl}}||{{i}}|| +Returns the Unix permissions (expressed as a three-digit number) of file/directory {{sl}}.#} + +{#op||fsize||{{sl}}||{{i}}|| +Returns the size in bytes of file/directory {{sl}}.#} + +{#op||fstats||{{sl}}||{{d}}|| +> Returns a dictionary {{d}} containing information on file/directory {{sl}}. +> > %sidebar% +> > Example +> > +> > Assuming that `min` is a file, the following: +> > +> > `'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) +> > )#} + +{#op||ftype||{{sl}}||{{s}}|| +Returns the type of file/directory {{sl}} (`"file"` or `"dir"`).#} + +{#op||hidden?||{{sl}}||{{b}}|| +Returns {{t}} if file/directory {{sl}} is hidden, {{f}} otherwise.#} + +{#op||mtime||{{sl}}||{{flt}}|| +Returns a timestamp corresponding to the time that file/directory {{sl}} was last modified.#} +
M site/contents/reference-io.mdsite/contents/reference-io.md

@@ -2,4 +2,71 @@ -----

content-type: "page" title: "io Module" ----- -{@ _includes/_reference-io.md || 1 @} +{@ _defs_.md || 0 @} + +{#op||ask||{{s1}}||{{s2}}|| +Prints {{s1}} (prompt), reads a line from STDIN and places it on top of the stack as a string.#} + +{#op||choose||(({{s1}} {{q1}}){{1p}}) {{s2}}||{{a0p}}|| +> Prints {{s2}}, then prints all {{s1}} included in the quotation prepended with a number, and waits from valid input from the user. +> +> If the user enters a number that matches one of the choices, then the corresponding quotation {{q1}} is executed, otherwise the choice menu is displayed again until a valid choice is made. #} + +{#op||column-print||{{q}} {{i}}||{{any}}|| +Prints all elements of {{q}} to STDOUT, in {{i}} columns.#} + +{#op||confirm||{{s}}||{{b}}|| +> Prints {{s}} (prompt) appending `" [yes/no]: "`, reads a line from STDIN and: +> +> * if it matches `/^y(es)$/i`, puts {{t}} on the stack. +> * if it matches `/^no?$/i`, puts {{f}} on the stack. +> * Otherwise, it prints `Invalid answer. Please enter 'yes' or 'no': ` and waits for a new answer. #} + +{#op||debug||{{any}}||{{any}}|| +Prints {{any}} and a new line to STDOUT, if logging level is set to [debug](class:kwd) or lower.#} + +{#op||error||{{any}}||{{any}}|| +Prints {{any}} and a new line to STDERR, if logging level is set to [error](class:kwd) or lower.#} + +{#op||fappend||{{s1}} {{s2}}||{{null}}|| +Appends {{s1}} to the end of file {{s2}}. #} + +{#op||fatal||{{any}}||{{any}}|| +Prints {{any}} and a new line to STDERR, and exists the program with error code `100`.#} + +{#op||fread||{{s}}||{{s}}|| +Reads the file {{s}} and puts its contents on the top of the stack as a string.#} + +{#op||fwrite||{{s1}} {{s2}}||{{null}}|| +Writes {{s1}} to the file {{s2}}, erasing all its contents first. #} + +{#op||gets||{{null}}||{{s}}|| +Reads a line from STDIN and places it on top of the stack as a string.#} + +{#op||info||{{any}}||{{any}}|| +Prints {{any}} and a new line to STDOUT, if logging level is set to [info](class:kwd) or lower.#} + +{#op||newline||{{null}}||{{null}}|| +Prints a new line to STDOUT.#} + +{#op||notice||{{any}}||{{any}}|| +Prints {{any}} and a new line to STDOUT, if logging level is set to [notice](class:kwd) (default) or lower.#} + +{#op||password||{{null}}||{{s}}|| +Reads a line from STDIN displaying \* for each typed character, and places it on top of the stack as a string.#} + +{#op||print||{{any}}||{{any}}|| +Prints {{any}} to STDOUT.#} + +{#op||print!||{{any}}||{{null}}|| +Prints {{any}} to STDOUT and removes {{any}} from the stack.#} + +{#op||puts||{{any}}||{{any}}|| +Prints {{any}} and a new line to STDOUT.#} + +{#op||puts!||{{any}}||{{null}}|| +Prints {{any}} and a new line to STDOUT, removing {{any}} from the stack.#} + +{#op||warning||{{any}}||{{any}}|| +Prints {{any}} and a new line to STDERR, if logging level is set to [warning](class:kwd) or lower.#} +
M site/contents/reference-lang.mdsite/contents/reference-lang.md

@@ -2,4 +2,355 @@ -----

content-type: "page" title: "lang Module" ----- -{@ _includes/_reference-lang.md || 1 @} +{@ _defs_.md || 0 @} + +{#sig||&apos;||quote#} + +{#alias||&apos;||quote#} + +{#sig||:||define#} + +{#alias||:||define#} + +{#sig||~||delete#} + +{#sig||+||module#} + +{#sig||^||call#} + +{#alias||^||call#} + +{#sig||@||bind#} + +{#alias||@||bind#} + +{#sig||>||save-symbol#} + +{#sig||<||load-symbol#} + +{#alias||->||dequote#} + +{#alias||=>||apply#} + +{#sig||#||quote-bind#} + +{#alias||#||quote-bind#} + +{#sig||=||quote-define#} + +{#alias||=||quote-define#} + +{#op||apply||{{q}}||({{a0p}})|| +Returns a new quotation {{q}} obtained by evaluating each element of {{q}} in a separate stack.#} + +{#op||args||{{null}}||{{q}}|| +Returns a list of all arguments passed to the current program.#} + +{#op||bind||{{any}} {{sl}}||{{null}}|| +Binds the specified value (auto-quoted) to an existing symbol {{sl}}.#} + +{#op||bool||{{any}}||{{b}}|| +> Converts {{any}} to a boolean value based on the following rules: +> +> * If {{any}} is a boolean value, no conversion is performed. +> * 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||case||(({{q1}} {{q2}}){{0p}})||{{a0p}}|| +> This operator takes a quotation containing _n_ different conditional branches. +> +> Each branch must be a quotation containing two quotations, and it is processed as follows: +> +> * if {{q1}} evaluates to {{t}}, then the {{q2}} is executed. +> * if {{q1}} evaluates to {{f}}, then the following branch is processed (if any). +> +> > %sidebar% +> > Example +> > +> > The following program prints "Smaller than 3": +> > +> > 2 ( +> > ((> 3) ("Greater than 3" put!)) +> > ((< 3) ("Smaller than 3" put!)) +> > ((true) ("Exactly 3" put!)) +> > ) case #} + +{#op||define||{{any}} {{sl}}||{{null}}|| +Defines a new symbol {{sl}}, containing the specified value (auto-quoted if not already a quotation).#} + +{#op||defined?||{{sl}}||{{b}}|| +Returns {{t}} if {{sl}} is defined, {{f}} otherwise.#} + +{#op||delete||{{sl}}||{{null}}|| +Deletes the specified symbol {{sl}}.#} + +{#op||dequote||{{q}}||{{a0p}}|| +Pushes the contents of quotation {{q}} on the stack. #} + +{#op||eval||{{s}}||{{a0p}}|| +Parses and interprets {{s}}. #} + +{#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). +> > %sidebar% +> > Example +> > +> > Assuming that the following elements are on the stack (from top to bottom): +> > +> > `1 "test" 3.4` +> > +> > the following program evaluates to `true`: +> > +> > `(int string num) expect (3.4 "test" 1) ==`#} + +{#op||float||{{any}}||{{flt}}|| +> Converts {{any}} to an integer value based on the following rules: +> +> * If {{any}} is {{t}}, it is converted to `1.0`. +> * If {{any}} is {{f}}, it is converted to `0.0`. +> * If {{any}} is a integer, it is converted to float value. +> * If {{any}} is a float, no conversion is performed. +> * If {{any}} is a string, it is parsed as a float value.#} + +{#op||foreach||{{q1}} {{q2}}||{{a0p}}|| +Applies the quotation {{q2}} to each element of {{q1}}.#} + +{#op||format-error||{{e}}||{{s}}|| +> Formats the error {{e}} as a string. +> > %sidebar% +> > Example +> > +> > The following: +> > +> > `((error "MyError") (message "This is a test error")) format-error` +> > +> > produces: `"This is a test error"`#} + +{#op||from-json||{{s}}||{{a0p}}|| +Converts a JSON string into {{m}} data.#} + +{#op||if||{{q1}} {{q2}} {{q3}}||{{a0p}}|| +If {{q1}} evaluates to {{t}} then evaluates {{q2}}, otherwise evaluates {{q3}}.#} + +{#op||import||{{sl}}||{{null}}|| +Imports the a previously-loaded module {{sl}}, defining all its symbols in the current scope. #} + +{#op||int||{{any}}||{{i}}|| +> Converts {{any}} to an integer value based on the following rules: +> +> * If {{any}} is {{t}}, it is converted to `1`. +> * If {{any}} is {{f}}, it is converted to `0`. +> * If {{any}} is an integer, no conversion is performed. +> * If {{any}} is a float, it is converted to an integer value by truncating its decimal part. +> * If {{any}} is a string, it is parsed as an integer value.#} + +{#op||linrec||{{q1}} {{q2}} {{q3}} {{q4}}||{{a0p}}|| +> Implements linear recursions as follows: +> +> 1. Evaluates {{q1}}. +> * If {{q1}} evaluates to {{t}}, then it evaluates {{q2}}. +> * Otherwises it executes {{q3}} and recurses using the same four quotations. +> 2. Finally, it executes {{q4}}. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `120` on the stack, the factorial of 5: +> > +> > (dup 0 ==) 'succ (dup pred) '* linrec + #} + +{#op||load||{{sl}}||{{a0p}}|| +Parses and interprets the specified {{m}} file, adding [.min](class:ext) if not specified. #} + +{#op||load-symbol||{{sl}}||{{a0p}}|| +Loads the contents of symbol {{sl}} from the [.min\_symbols](class:file) file. #} + +{#op||loglevel||{{sl}}||{{null}}|| +> Sets the current logging level to {{sl}}. {{sl}} must be one of the following strings or quoted symbols: +> +> * debug +> * info +> * notice +> * warn +> * error +> * fatal +> +> > %note% +> > Note +> > +> > The default logging level is _notice_.#} + +{#op||module||{{q}} {{sl}}||{{null}}|| +Creates a new module {{sl}} based on quotation {{q}}. #} + +{#op||module-sigils||{{q}}||({{s0p}})|| +Returns a list of all sigils defined in module {{q}}.#} + +{#op||module-symbols||{{q}}||({{s0p}})|| +Returns a list of all symbols defined in module {{q}}.#} + +{#op||opts||{{null}}||{{d}}|| +Returns a dictionary of all options passed to the current program, with their respective values.#} + +{#op||parse||{{s}}||{{q}}|| +Parses {{s}} and returns a quoted program {{q}}. #} + +{#op||prompt||{{null}}||{{s}}|| +> This symbol is used to configure the prompt of the min shell. By default, it is set to the following quotation: +> +> ([$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}}. +> +> > %sidebar% +> > Example +> > +> Publish symbol [my-local-symbol](class:kwd) to [ROOT](class:kwd) scope: +> > `'my-local-symbol ROOT publish` #} + +{#op||quote||{{any}}||({{any}})|| +Wraps {{any}} in a quotation. #} + +{#op||quote-bind||{{any}} {{sl}}||{{null}}|| +Quotes {{any}} and binds the quotation to the existing symbol {{sl}}. #} + +{#op||quote-define||{{any}} {{sl}}||{{null}}|| +Quotes {{any}} and assigns the quotation to the symbol {{sl}}, creating it if not already defined. #} + +{#op||raise||{{e}}||{{null}}|| +Raises the error specified via the dictionary {{e}}.#} + +{#op||read||{{sl}}||{{q}}|| +Reads and parses the specified {{m}} file {{sl}} and returns a quoted program {{q}}. #} + +{#op||remove-symbol||{{sl}}||{{null}}|| +Removes the symbol {{sl}} from the [.min\_symbols](class:file) file. #} + +{#op||save-symbol||{{sl}}||{{null}}|| +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||sigils||{{null}}||({{s0p}})|| +Returns a list of all sigils defined in the [ROOT](class:kwd) scope.#} + +{#op||source||{{sl}}||{{q}}|| +Display the source code of symbol {{sl}} (if it has been implemented a {{m}} quotation). #} + +{#op||stored-symbols||{{null}}||({{s0p}})|| +Returns a quotation containing all symbols stored in the [.min\_symbols](class:file) file. #} + +{#op||string||{{any}}||{{s}}|| +Converts {{any}} to its string representation.#} + +{#op||symbols||{{null}}||({{s0p}})|| +Returns a list of all symbols defined in the [ROOT](class:kwd) scope.#} + +{#op||tap||{{any}} {{q}}||{{any}}|| +> Performs the following operations: +> +> 1. Removes {{any}} from the stack. +> 2. For each quotation defined in {{q}} (which is a quotation of quotations each requiring one argument and returning one argument): +> 1. Pushes {{any}} back to the stack. +> 2. Dequotes the quotation and saves the result as {{any}}. +> 3. Push the resulting {{any}} back on the stack. +> +> > %sidebar% +> > Example +> > +> > The following program: +> > +> > ( +> > (("a" 1) ("b" 2) ("c" 3)) ( +> > (dup /a succ succ %a) +> > (dup /b succ %b) +> > ) tap +> > +> > Returns `(("a" 3) ("b" 3) ("c" 3))`.#} + +{#op||tap!||{{any}} {{q}}||{{any}}|| +> Performs the following operations: +> +> 1. Removes {{any}} from the stack. +> 2. For each quotation defined in {{q}} (which is a quotation of quotations each requiring one argument and returning one argument): +> 1. Pushes {{any}} back to the stack. +> 2. Dequotes the quotation and saves the result as {{any}}. +> +> > %sidebar% +> > Example +> > +> > The following program: +> > +> > "" :s1 +> > "test" ( +> > (' "1" swap append "" join) +> > (' "2" swap append "" join) +> > (' "3" swap append "" join @s1 s1) +> > ) tap! +> > +> > Sets `s1` to `"test123"`. #} + +{#op||times||{{q}} {{i}}||{{a0p}}|| +Applies the quotation {{q}} {{i}} times.#} + +{#op||to-json||{{q}}||{{s}}|| +Converts {{q}} into a JSON string {{s}}.#} + +{#op||try||({{q1}} {{q}}{{2}}{{01}} {{q}}{{3}}{{01}})||{{a0p}}|| +> Evaluates a quotation as a try/catch/finally block. +> +> The must contain the following elements: +> +> 1. A quotation {{q1}} containing the code to be evaluated (_try_ block). +> 1. _(optional)_ A quotation {{q2}} containing the code to execute in case of error (_catch_ block). +> 1. _(optional)_ A quotation {{q3}} containing the code to execute after the code has been evaluated, whether an error occurred or not (_finally_ block). +> +> > %sidebar% +> > Example +> > +> > The following program executed on an empty stack prints the message "Insufficient items on the stack" and pushes 0 on the stack: +> > +> > ( +> > (pop) +> > (format-error puts) +> > (0) +> > ) try #} + +{#op||unless||{{q1}} {{q2}}||{{a0p}}|| +If {{1}} evaluates to {{f}} then evaluates {{2}}.#} + +{#op||unseal||{{sl}}||{{null}}|| +Unseals symbol {{sl}}, so that it can be re-assigned. #} + +{#op||version||{{null}}||{{s}}|| +Returns the current min version number. #} + +{#op||when||{{q1}} {{q2}}||{{a0p}}|| +If {{q1}} evaluates to {{t}} then evaluates {{q2}}.#} + +{#op||while||{{q1}} {{q2}}||{{a0p}}|| +> Executes {{q2}} while {{q1}} evaluates to {{t}}. +> +> > %sidebar% +> > Example +> > +> > The following program prints all natural numbers from 0 to 10: +> > +> > 0 :count +> > (count 10 <=) +> > (count puts succ @count) while #} + +{#op||with||{{q1}} {{q2}}||{{a0p}}|| +Applies quotation {{q1}} within the scope of {{q2}}. #}
M site/contents/reference-logic.mdsite/contents/reference-logic.md

@@ -2,4 +2,112 @@ -----

content-type: "page" title: "logic Module" ----- -{@ _includes/_reference-logic.md || 1 @} +{@ _defs_.md || 0 @} + +{#op||&gt;||{{a1}} {{a2}}||{{b}}|| +> Returns {{t}} if {{a1}} is greater than {{a2}}, {{f}} otherwise. +> > %note% +> > Note +> > +> > Only comparisons among two numbers or two strings are supported.#} + +{#op||&gt;=||{{a1}} {{a2}}||{{b}}|| +> Returns {{t}} if {{a1}} is greater than or equal to {{a2}}, {{f}} otherwise. +> > %note% +> > Note +> > +> > Only comparisons among two numbers or two strings are supported.#} + +{#op||&lt;||{{a1}} {{a2}}||{{b}}|| +> Returns {{t}} if {{a1}} is smaller than {{a2}}, {{f}} otherwise. +> > %note% +> > Note +> > +> > Only comparisons among two numbers or two strings are supported.#} + +{#op||&lt;=||{{a1}} {{a2}}||{{b}}|| +> Returns {{t}} if {{a1}} is smaller than or equal to {{a2}}, {{f}} otherwise. +> > %note% +> > Note +> > +> > Only comparisons among two numbers or two strings are supported.#} + +{#op||==||{{a1}} {{a2}}||{{b}}|| +Returns {{t}} if {{a1}} is equal to {{a2}}, {{f}} otherwise. #} + +{#op||!=||{{a1}} {{a2}}||{{b}}|| +Returns {{t}} if {{a1}} is not equal to {{a2}}, {{f}} otherwise. #} + +{#op||and||{{b1}} {{b2}}||{{b3}}|| +Returns {{t}} if {{b1}} is equal to {{b2}}, {{f}} otherwise.#} + +{#op||boolean?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a boolean, {{f}} otherwise. #} + +{#op||dequote-and||{{a1}} {{a2}}||{{b}}|| +> Short-circuited logical and. It performs the following operations: +> +> 1. Pops {{a1}} and {{a2}} off the stack. +> 2. Dequotes {{a1}}, if {{f}} is on the stack, it pushes {{f}} on the stack and stops, otherwise it carries on. +> 3. Dequotes {{a2}}. +> 4. If {{a2}} is {{t}}, it pushes {{t}} on the stack. +> +> > %note% +> > Note +> > +> > {{a1}} (and {{a2}}, if dequoted) must evaluate to a boolean value, otherwise an exception is raised. +> +> > %sidebar% +> > Example +> > +> > The following program returns {{f}} and never executes the second quotation. +> > +> > "test" :x (x number?) (x 5 <) dequote-and + + #} + +{#op||dequote-or||{{a1}} {{a2}}||{{b}}|| +> Short-circuited logical or. It performs the following operations: +> +> 1. Pops {{a1}} and {{a2}} off the stack. +> 2. Dequotes {{a1}}, if {{t}} is on the stack, it pushes {{t}} on the stack and stops, otherwise it carries on. +> 3. Dequotes {{a2}}. +> 4. If {{a2}} is {{f}}, it pushes {{f}} on the stack. +> +> > %note% +> > Note +> > +> > {{a1}} (and {{a2}}, if dequoted) must evaluate to a boolean value, otherwise an exception is raised. +> +> > %sidebar% +> > Example +> > +> > The following program returns {{t}} and never executes the second quotation. +> > +> > "test" :x (x string?) (x quotation?) dequote-or + #} + +{#op||dictionary?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a dictionary, {{f}} otherwise. #} + +{#op||float?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a float, {{f}} otherwise. #} + +{#op||or||{{b1}} {{b2}}||{{b3}}|| +Returns {{t}} if {{b1}} or {{b2}} is {{t}}, {{f}} otherwise.#} + +{#op||integer?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is an integer, {{f}} otherwise. #} + +{#op||not||{{b1}}||{{b2}}|| +Negates {{b1}}.#} + +{#op||number?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a number, {{f}} otherwise. #} + +{#op||quotation?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a quotation, {{f}} otherwise. #} + +{#op||xor||{{b1}} {{b2}}||{{b3}}|| +Returns {{t}} if {{b1}} and {{b2}} are different, {{f}} otherwise.#} +
M site/contents/reference-math.mdsite/contents/reference-math.md

@@ -2,4 +2,74 @@ -----

content-type: "page" title: "math Module" ----- -{@ _includes/_reference-math.md || 1 @} +{@ _defs_.md || 0 @} + +{#op||acos||{{n1}}||{{n2}}|| +Calculates the arc cosine of {{n1}} (in radians). #} + +{#op||asin||{{n1}}||{{n2}}|| +Calculates the arc sine of {{n1}} (in radians). #} + +{#op||atan||{{n1}}||{{n2}}|| +Calculates the arc tangent of {{n1}} (in radians). #} + +{#op||ceil||{{n}}||{{i}}|| +Returns the smallest integer {{i}} that is not smaller than {{n}}. #} + +{#op||cos||{{n1}}||{{n2}}|| +Calculates the cosine of {{n1}} (in radians). #} + +{#op||cosh||{{n1}}||{{n2}}|| +Calculates the hyperbolic cosine of {{n1}} (in radians). #} + +{#op||d2r||{{n1}}||{{n2}}|| +Converts {{n1}} from degrees to radians. #} + +{#op||e||{{null}}||{{n}}|| +Returns the value of the _e_ constant (Euler's number). #} + +{#op||floor||{{n}}||{{i}}|| +Returns the largest integer {{i}} that is not greater than {{n}}. #} + +{#op||ln||{{n1}}||{{n2}}|| +Calculates the natural logarithm of {{n1}}. #} + +{#op||log10||{{n1}}||{{n2}}|| +Calculates the common logarithm of {{n1}}. #} + +{#op||log2||{{n1}}||{{n2}}|| +Calculates the binary logarithm of {{n1}}. #} + +{#op||pi||{{null}}||{{n}}|| +Returns the value of the &pi; constant. #} + +{#op||pow||{{n1}} {{n2}}||{{n3}}|| +Computes {{n1}} to power raised of {{n2}}.#} + +{#op||r2d||{{n1}}||{{n2}}|| +Converts {{n1}} from radians to degrees. #} + +{#op||round||{{n1}} {{i}}||{{n2}}|| +Rounds {{n1}} to the {{i}}^th decimal place. #} + +{#op||sin||{{n1}}||{{n2}}|| +Calculates the sine of {{n1}} (in radians). #} + +{#op||sinh||{{n1}}||{{n2}}|| +Calculates the hyperbolic sine of {{n1}} (in radians). #} + +{#op||sqrt||{{n1}}||{{n2}}|| +Returns square root of {{n1}}. #} + +{#op||tan||{{n1}}||{{n2}}|| +Calculates the tangent of {{n1}} (in radians). #} + +{#op||tanh||{{n1}}||{{n2}}|| +Calculates the hyperbolic tangent of {{n1}} (in radians). #} + +{#op||tau||{{null}}||{{n}}|| +Returns the value of the &tau; constant (2&pi;). #} + +{#op||trunc||{{n1}}||{{n2}}|| +Truncates {{n}} to the decimal point. #} +
M site/contents/reference-num.mdsite/contents/reference-num.md

@@ -2,4 +2,49 @@ -----

content-type: "page" title: "num Module" ----- -{@ _includes/_reference-num.md || 1 @} +{@ _defs_.md || 0 @} + +{#op||+||{{n1}} {{n2}}||{{n3}}|| +Sums {{n1}} and {{n2}}. #} + +{#op||-||{{n1}} {{n2}}||{{n3}}|| +Subtracts {{n2}} from {{n1}}. #} + +{#op||-inf||{{null}}||{{n}}|| +Returns negative infinity. #} + +{#op||\*||{{n1}} {{n2}}||{{n3}}|| +Multiplies {{n1}} by {{n2}}. #} + +{#op||/||{{n1}} {{n2}}||{{n3}}|| +Divides {{n1}} by {{n2}}. #} + +{#op||even?||{{i}}||{{b}}|| +Returns {{t}} if {{i}} is even, {{f}} otherwise. #} + +{#op||div||{{i1}} {{i2}}||{{i3}}|| +Divides {{i1}} by {{i2}} (integer division). #} + +{#op||inf||{{null}}||{{n}}|| +Returns infinity. #} + +{#op||mod||{{i1}} {{i2}}||{{i3}}|| +Returns the integer module of {{i1}} divided by {{i2}}. #} + +{#op||nan||{{null}}||nan|| +Returns **NaN** (not a number). #} + +{#op||odd?||{{i}}||{{b}}|| +Returns {{t}} if {{i}} is odd, {{f}} otherwise. #} + +{#op||pred||{{i1}}||{{i2}}|| +Returns the predecessor of {{i1}}.#} + +{#op||random||{{i1}}||{{i2}}|| +Returns a random number {{i2}} between 0 and {{i1}}-1. #} + +{#op||succ||{{i1}}||{{i2}}|| +Returns the successor of {{i1}}.#} + +{#op||sum||{{q}}||{{i}}|| +Returns the sum of all items of {{q}}. {{q}} is a quotation of integers. #}
M site/contents/reference-seq.mdsite/contents/reference-seq.md

@@ -2,4 +2,212 @@ -----

content-type: "page" title: "seq Module" ----- -{@ _includes/_reference-seq.md || 1 @} +{@ _defs_.md || 0 @} + +{#sig||/||dget#} + +{#sig||?||dhas?#} + +{#sig||%||dset#} + +{#op||all?||{{q1}} {{q2}}||{{b}}|| +Applies predicate {{q2}} to each element of {{q1}} and returns {{t}} if all elements of {{q1}} satisfy predicate {{q2}}, {{f}} otherwise. #} + +{#op||any?||{{q1}} {{q2}}||{{b}}|| +Applies predicate {{q2}} to each element of {{q1}} and returns {{t}} if at least one element of {{q1}} satisfies predicate {{q2}}, {{f}} otherwise. #} + +{#op||append||{{any}} {{q}}||({{a0p}} {{any}})|| +Returns a new quotation containing the contents of {{q}} with {{any}} appended. #} + +{#op||get||{{q}} {{i}}||{{any}}|| +Returns the _n^th_ element of {{q}} (zero-based).#} + +{#op||concat||{{q1}} {{q2}}||{{q3}}|| +Concatenates {{q1}} with {{q2}}. #} + +{#op||ddel||{{d1}} {{sl}}||{{d2}}|| +Returns a copy of {{d1}} without the element with key {{sl}}. #} + +{#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}}: +> > +> > (("a1" true) ("a2" "aaa") ("a3" false)) '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 `(("a" 4) ("d" 7))`: +> > +> > (("q" 5) ("a" 4) ("c" 6) ("d" 7)) ("a" "d") dpick + #} + +{#op||dset||{{d1}} {{any}} {{sl}}||{{d2}}|| +Sets the value of the {{sl}} of {{d1}} to {{any}}, and returns the modified copy of the dictionary {{d2}}. #} + +{#op||dsort||{{d1}}||{{d2}}|| +> Returns a new dictionary {{d2}} containing all elements of {{d1}} sorted by key in ascending order. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `(("a" 342) ("b" true) ("c" -4) ("d" 22))` on the stack: +> > +> > (("b" true) ("d" 22) ("c" -4) ("a" 342)) dsort#} + +{#op||dvalues||{{d}}||({{a0p}})|| +Returns a quotation containing all the values of dictionary {{d}}. #} + +{#op||filter||{{q1}} {{q2}}||{{q3}}|| +> Returns a new quotation {{q3}} containing all elements of {{q1}} that satisfy predicate {{q2}}. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `(2 6 8 12)` on the stack: +> > +> > (1 37 34 2 6 8 12 21) +> > (dup 20 < swap even? and) filter #} + +{#op||find||{{q1}} {{q2}}||{{i}}|| +> Returns the index of the first element within {{q1}} that satisfies predicate {{q2}}. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `3` on the stack: +> > +> > (1 2 4 8 16) +> > (5 >) find #} + +{#op||first||{{q}}||{{any}}|| +Returns the first element of {{q}}. #} + +{#op||flatten||{{q1}}||{{q2}}|| +> Flattens all quotations within {{q1}} and returns the resulting sequence {{q2}}. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `(1 2 3 4 5 6 7 8)` on the stack: +> > +> > (1 (2 3 4) 5 (6 7) 8) +> > flatten #} + +{#op||harvest||{{q1}}||{{q2}}|| +> Creates a new quotation {{q2}} containing all elements of {{q1}} except for empty quotations. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `(1 2 3)` on the stack: +> > +> > (1 () () () 2 () 3) +> > harvest #} + +{#op||in?||{{q}} {{any}}||{{b}}|| +Returns {{t}} if {{any}} is contained in {{q}}, {{f}} otherwise.#} + +{#op||insert||{{q1}} {{any}} {{i}}||{{q2}}|| +Inserts {{any}} as the value of the _n^th_ element {{q1}} (zero-based), and returns the modified copy of the quotation {{q2}}. #} + +{#op||last||{{q}}||{{any}}|| +Returns the last element of {{q}}. #} + +{#op||map||{{q1}} {{q2}}||{{q3}}|| +Returns a new quotation {{q3}} obtained by applying {{q2}} to each element of {{q1}}.#} + +{#op||map-reduce||{{q1}} {{q2}} {{q3}}||{{i}}|| +> Applies {{q2}} (map) to each element of {{q1}} and then applies {{q3}} (reduce) to each successive element of {{q1}}. {{q1}} must have at least one element. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `35` on the stack: +> > +> > (1 3 5) +> > (dup *) (+) map-reduce #} + +{#op||partition||{{q1}} {{q2}}||{{q3}} {{q4}}|| +> Partitions {{q1}} into two quotations: {{q3}} contains all elements of {{q1}} that satisfy predicate {{q2}}, {{q4}} all the others. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `(1 2 3) (2 4 6)` on the stack: +> > +> > (1 2 3 4 5 6) +> > (odd?) partition #} + +{#op||prepend||{{any}} {{q}}||({{any}} {{a0p}})|| +Returns a new quotation containing the contents of {{q}} with {{any}} prepended. #} + +{#op||quote-map||{{q1}}||{{q2}}|| +Returns a new quotation {{q2}} obtained by quoting each element of {{q1}}.#} + +{#op||reduce||{{q1}} {{any}} {{q2}}||{{i}}|| +> Combines each successive element of {{q1}} using {{q2}}. On the first iteration, the first two inputs processed by {{q2}} are {{any}} and the first element of {{q1}}. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `120` on the stack: +> > +> > (1 2 3 4 5) +> > 1 (*) reduce #} + +{#op||reject||{{q1}} {{q2}}||{{q3}}|| +Returns a new quotatios {{q3}} including all elements of {{q1}} that do not satisfy predicate {{q2}} (i.e. the opposite of `filter`)#} + +{#op||remove||{{q1}} {{i}}||{{q2}}|| +Returns the _n^th_ element of {{q1}} (zero-based), and returns the modified copy of the quotation {{q2}}.#} + +{#op||rest||{{q1}}||{{q2}}|| +Returns a new quotation {{q2}} containing all elements of {{q1}} quotation except for the first. #} + +{#op||reverse||{{q1}}||{{q2}}|| +Returns a new quotation {{q2}} containing all elements of {{q1}} in reverse order. #} + +{#op||set||{{q1}} {{any}} {{i}}||{{q2}}|| +Sets the value of the _n^th_ element {{q1}} (zero-based) to {{any}}, and returns the modified copy of the quotation {{q2}}. #} + +{#op||shorten||{{q1}} {{i}}||{{q2}}|| +Returns a quotation {{q2}} containing the first _n_ values of the input quotation {{q1}}. #} + +{#op||size||{{q}}||{{i}}|| +Returns the length of {{q}}.#} + +{#op||slice||{{q1}} {{i1}} {{i2}}||{{q2}}|| +> Creates a new quotation {{q2}} obtaining by selecting all elements of {{q1}} between indexes {{i1}} and {{i2}}. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `(3 4 5)` on the stack: +> > +> > (1 2 3 4 5 6) +> > 2 4 slice #} + +{#op||sort||{{q1}} {{q2}}||{{q3}}|| +> Sorts all elements of {{q1}} according to predicate {{q2}}. +> +> > %sidebar% +> > Example +> > +> > The following program leaves `(1 3 5 7 9 13 16)` on the stack: +> > +> > (1 9 5 13 16 3 7) '> sort #}
M site/contents/reference-stack.mdsite/contents/reference-stack.md

@@ -2,4 +2,79 @@ -----

content-type: "page" title: "stack Module" ----- -{@ _includes/_reference-stack.md || 1 @} +{@ _defs_.md || 0 @} + +{#op||clear-stack||{{null}}||{{null}}|| +Empties the stack.#} + +{#op||cleave||{{a1}} ({{q}}{{0p}})||{{a0p}}|| +> Applies each quotation contained in the first element to the second element {{a1}}. +> > %sidebar% +> > Example +> > +> > The following program leaves 2 on the stack: +> > +> > `(1 2 3) ((sum) (size)) cleave /`#} + +{#op||cons||{{a1}} ({{a0p}})||({{a1}} {{a0p}})|| +Prepends {{a1}} to the quotation on top of the stack.#} + +{#op||dip||{{a1}} ({{a2}})||{{a0p}} {{a1}}|| +Removes the first and second element from the stack, dequotes the first element, and restores the second element.#} + +{#op||dup||{{a1}}||{{a1}} {{a1}}|| +Duplicates the first element on the stack.#} + +{#op||get-stack||{{null}}||({{a0p}})|| +Returns a quotation containing the contents of the stack.#} + +{#op||id||{{null}}||{{null}}|| +Does nothing.#} + +{#op||keep||{{a1}} {{q}}||{{a0p}} {{a1}}|| +> Applies each quotation contained in the first element to each subsequent corresponding element. +> > %sidebar% +> > Example +> > +> > The following program leaves `5 3` on the stack: +> > +> > `2 3 '+ keep` #} + +{#op||nip||{{a1}} {{a2}}||{{a2}}|| +Removes the second element from the stack.#} + +{#op||over||{{a1}} {{a2}}||{{a1}} {{a2}} {{a1}}|| +Pushes a copy of the second element on top of the stack.#} + +{#op||pick||{{a1}} {{a2}} {{a3}}||{{a1}} {{a2}} {{a3}} {{a1}}|| +Pushes a copy of the third element on top of the stack.#} + +{#op||pop||{{any}}||{{null}}|| +Removes the first element from the stack.#} + +{#op||rolldown||{{a1}} {{a2}} {{a3}}||{{a2}} {{a3}} {{a1}}|| +Moves the third element in first position, the second in third position and the the first in second position.#} + +{#op||rollup||{{a1}} {{a2}} {{a3}}||{{a3}} {{a2}} {{a1}}|| +Moves the third and second element into second and third position and moves the first element into third position.#} + +{#op||set-stack||{{q}}||{{a0p}}|| +Substitute the existing stack with the contents of {{q}}.#} + +{#op||sip||{{a1}} ({{a2}})||{{a0p}} {{a1}}|| +Saves the {{a1}}, dequotes {{a2}}, and restores {{a1}}.#} + +{#op||spread||{{a0p}} ({{q}}{{0p}})||{{a0p}}|| +> Applies each quotation contained in the first element to each subsequent corresponding element. +> > %sidebar% +> > Example +> > +> > The following program leaves `(1 4)` on the stack: +> > +> > `(1 2) (3 4) ((0 get) (1 get)) spread` #} + +{#op||swap||{{a1}} {{a2}}||{{a2}} {{a1}}|| +Swaps the first two elements on the stack. #} + +{#op||swons||({{a0p}}) {{a1}}||({{a1}} {{a0p}})|| +Prepends {{a1}} to the quotation that follows it.#}
M site/contents/reference-str.mdsite/contents/reference-str.md

@@ -2,4 +2,143 @@ -----

content-type: "page" title: "str Module" ----- -{@ _includes/_reference-str.md || 1 @} +{@ _defs_.md || 0 @} + +{#alias||%||interpolate#} + +{#alias||=~||regex#} + +{#op||capitalize||{{sl}}||{{s}}|| +Returns a copy of {{sl}} with the first character capitalized.#} + +{#op||indent||{{sl}} {{i}}||{{s}}|| +Returns {{s}} containing {{sl}} indented with {{i}} spaces.#} + +{#op||indexof||{{s1}} {{s2}}||{{i}}|| +If {{s2}} is contained in {{s1}}, returns the index of the first match or -1 if no match is found. #} + +{#op||interpolate||{{s}} {{q}}||{{s}}|| +> Substitutes the placeholders included in {{s}} with the values in {{q}}. +> > %note% +> > Note +> > +> > If {{q}} contains symbols or quotations, they are not interpreted. To do so, call `apply` before interpolating. +> +> > %sidebar% +> > Example +> > +> > The following code (executed in a directory called '/Users/h3rald/Development/min' containing 19 files): +> > +> > `"Directory '$1' includes $2 files." (. (. ls 'file? filter size)) apply interpolate` +> > +> > produces: +> > +> > `"Directory '/Users/h3rald/Development/min' includes 19 files."`#} + +{#op||join||{{q}} {{sl}}||{{s}}|| +Joins the elements of {{q}} using separator {{sl}}, producing {{s}}.#} + +{#op||length||{{sl}}||{{i}}|| +Returns the length of {{sl}}.#} + +{#op||lowercase||{{sl}}||{{s}}|| +Returns a copy of {{sl}} converted to lowercase.#} + +{#op||match||{{s1}} {{s2}}||{{b}}|| +> Returns {{t}} if {{s2}} matches {{s1}}, {{f}} otherwise. +> > %tip% +> > Tip +> > +> > {{s2}} can be a {{sgregex}}-compatible regular expression.#} + +{#op||repeat||{{sl}} {{i}}||{{s}}|| +Returns {{s}} containing {{sl}} repeated {{i}} times.#} + +{#op||replace||{{s1}} {{s2}} {{s3}}||{{s4}}|| +> Returns a copy of {{s1}} containing all occurrences of {{s2}} replaced by {{s3}} +> > %tip% +> > Tip +> > +> > {{s2}} can be a {{sgregex}}-compatible regular expression. +> +> > %sidebar% +> > Example +> > +> > The following: +> > +> > `"This is a stupid test. Is it really a stupid test?" " s[a-z]+" " simple" replace` +> > +> > produces: `"This is a simple test. Is it really a simple test?"`#} + +{#op||regex||{{s1}} {{s2}}||{{q}}|| +> Performs a search and/or a search-and-replace operation using pattern {{s2}}. +> +> {{s2}} can be one of the following patterns: +> +> * **/**_search-regex_**/**_modifiers_ +> * **s/**_search-regex_**/**_replacemenet_**/**_modifiers_ +> +> {{q}} is always a quotation containing: +> +> * One or more strings containing the first match and captures (if any), like for the `search` operator. +> * A string containing the resuling string after the search-and-replace operation. +> +> > %tip% +> > Tip +> > +> > * _search-regex_ can be a {{sgregex}}-compatible regular expression. +> > * _modifiers_ are optionals can contain one or more of the following characters, in any order: +> > * **i**: case-insensitive match. +> > * **m**: multi-line match. +> > * **s**: dot character includes newlines. +> +> > %sidebar% +> > Example: Search +> > +> > The following: +> > +> > `"This is a GOOD idea." "/(good) idea/i" regex` +> > +> > produces: `("GOOD idea", "GOOD")` +> +> > %sidebar% +> > Example: Search and Replace +> > +> > The following: +> > +> > `"This is a GOOD idea." "s/good/bad/i" regex` +> > +> > produces: `("This is a bad idea")`#} + +{#op||search||{{s1}} {{s2}}||{{q}}|| +> Returns a quotation containing the first occurrence of {{s2}} within {{s2}}. Note that: +> +> * The first element of {{q}} is the matching substring. +> * Other elements (if any) contain captured substrings. +> +> > %tip% +> > Tip +> > +> > {{s2}} can be a {{sgregex}}-compatible regular expression. +> +> > %sidebar% +> > Example +> > +> > The following: +> > +> > `"192.168.1.1, 127.0.0.1" "[0-9]+\.[0-9]+\.([0-9]+)\.([0-9]+)" search` +> > +> > produces: `("192.168.1.1", "1", "1")`#} + +{#op||split||{{sl1}} {{sl2}}||{{q}}|| +Splits {{sl1}} using separator {{sl2}} and returns the resulting strings within the quotation {{q}}. #} + +{#op||strip||{{sl}}||{{s}}|| +Returns {{s}}, which is set to {{sl}} with leading and trailing spaces removed.#} + +{#op||titleize||{{sl}}||{{s}}|| +Returns a copy of {{sl}} in which the first character of each word is capitalized.#} + +{#op||uppercase||{{sl1}}||{{sl2}}|| +Returns a copy of {{sl}} converted to uppercase.#} +
M site/contents/reference-sys.mdsite/contents/reference-sys.md

@@ -2,4 +2,113 @@ -----

content-type: "page" title: "sys Module" ----- -{@ _includes/_reference-sys.md || 1 @} +{@ _defs_.md || 0 @} + +{#sig||$||get-env#} + +{#alias||$||get-env#} + +{#sig||\!||system#} + +{#alias||\!||system#} + +{#sig||&||run#} + +{#alias||&||run#} + +{#op||.||{{null}}||{{s}}|| +Returns the full path to the current directory. #} + +{#op||..||{{null}}||{{s}}|| +Returns the full path to the parent directory. #} + +{#op||chmod||{{sl}} {{i}}||{{null}}|| +> Sets the permissions of file or directory {{sl}} to {{i}}. {{i}} is a three-digit representation of user, group and other permissions. See the [Unix Permissions Calculator](http://permissions-calculator.org/) for examples and conversions. +> +> > %sidebar% +> > Example +> > +> > The following program makes the file **/tmp/test.txt** readable, writable and executable by its owner, and readable and executable by users of the same group and all other users: +> > +> > `/tmp/test.txt 755 chmod`#} + +{#op||cd||{{sl}}||{{null}}|| +Change the current directory to {{{sl}}. #} + +{#op||cp||{{sl1}} {{sl2}}||{{null}}|| +Copies the file or directory {{sl1}} to {{sl2}}. #} + +{#op||cpu||{{null}}||{{s}}|| +Returns the host CPU. It can be one of the following strings i386, alpha, powerpc, powerpc64, powerpc64el, sparc, amd64, mips, mipsel, arm, arm64. #} + +{#op||env?||{{sl}}||{{b}}|| +Returns {{t}} if environment variable {{sl}} exists, {{f}} otherwise. #} + +{#op||dir?||{{sl}}||{{b}}|| +Returns {{t}} if the specified path {{sl}} exists and is a directory. #} + +{#op||dirname||{{sl}}||{{s}}|| +Returns the path of the directory containing path {{sl}}.#} + +{#op||exists?||{{sl}}||{{b}}|| +Returns {{t}} if the specified file or directory {{sl}} exists. #} + +{#op||file?||{{sl}}||{{b}}|| +Returns {{t}} if the specified path {{sl}} exists and is a file. #} + +{#op||filename||{{sl}}||{{s}}|| +Returns the file name of path {{sl}}.#} + +{#op||get-env||{{sl}}||{{s}}|| +Returns environment variable {{sl}}. #} + +{#op||hardlink||{{sl1}} {{sl2}}||{{null}}|| +Creates hardlink {{sl2}} for file or directory {{sl1}}. #} + +{#op||ls||{{sl}}||{{q}}|| +Returns a quotation {{q}} containing all children (files and directories) of the directory {{sl}}. #} + +{#op||ls-r||{{sl}}||{{q}}|| +Returns a quotation {{q}} containing all children (files and directories) of the directory {{sl}}, recursively. #} + +{#op||mkdir||{{sl}}||{{null}}|| +Creates the specified directory {{sl}}. #} + +{#op||mv||{{sl1}} {{sl2}}||{{null}}|| +Moves the file or directory {{sl1}} to {{sl2}}. #} + +{#op||os||{{null}}||{{s}}|| +Returns the host operating system. It can be one of the following strings: windows, macosx, linux, netbsd, freebsd, openbsd, solaris, aix, standalone. #} + +{#op||put-env||{{sl1}} {{sl2}}||{{s}}|| +Sets environment variable {{sl2}} to {{sl1}}. #} + +{#op||rm||{{sl}}||{{null}}|| +Deletes the specified file {{sl}}. #} + +{#op||rmdir||{{sl}}||{{null}}|| +Deletes the specified directory {{sl}} and all its subdirectories recursively. #} + +{#op||run||{{sl}}||{{d}}|| +Executes the external command {{sl}} in the current directory without displaying its output. Returns a dictionary containing the command output and return code (in keys **output** and **code** respectively). #} + +{#op||sleep||{{i}}||{{null}}|| +Halts program execution for {{i}} milliseconds.#} + +{#op||symlink||{{sl1}} {{sl2}}||{{null}}|| +Creates symlink {{sl2}} for file or directory {{sl1}}. #} + +{#op||symlink?||{{sl}}||{{b}}|| +Returns {{t}} if the specified path {{sl}} exists and is a symbolic link. #} + +{#op||system||{{sl}}||{{null}}|| +Executes the external command {{sl}} in the current directory. #} + +{#op||unzip||{{sl}}||{{null}}|| +Decompresses zip file {{sl}}.#} + +{#op||which||{{sl}}||{{s}}|| +Returns the full path to the directory containing executable {{sl}}, or an empty string if the executable is not found in **$PATH**. #} + +{#op||zip||{{sl}} {{q}}||{{null}}|| +Compresses files included in quotation {{q}} into zip file {{sl}}.#}
M site/contents/reference-time.mdsite/contents/reference-time.md

@@ -2,4 +2,28 @@ -----

content-type: "page" title: "time Module" ----- -{@ _includes/_reference-time.md || 1 @} +{@ _defs_.md || 0 @} + +{#op||now||{{null}}||{{flt}}|| +Returns the current time as Unix timestamp with microseconds. #} + +{#op||timestamp||{{null}}||{{i}}|| +Returns the current time as Unix timestamp. #} + +{#op||timeinfo||{{i}}||{{tinfo}}|| +Returns a timeinfo dictionary from timestamp {{i}}. #} + +{#op||to-timestamp||{{tinfo}}||{{i}}|| +Converts the timeinfo dictionary {{tinfo}} to the corresponding Unix timestamp. #} + +{#op||datetime||{{i}}||{{s}}|| +Returns an ISO 8601 string representing the combined date and time in UTC of timestamp {{i}}. #} + + +{#op||tformat||{{i}} {{s}}||{{s}}|| +> Formats timestamp {{i}} using string {{s}}. +> +> > %tip% +> > Tip +> > +> > For information on special characters in the format string, see the [format](https://nim-lang.org/docs/times.html#format,TimeInfo,string) nim method. #}
M site/contents/reference.mdsite/contents/reference.md

@@ -2,5 +2,107 @@ -----

content-type: "page" title: "Reference" ----- +{@ _defs_.md || 0 @} -{@ _includes/_reference.md || 0 @} +min includes a small but powerful standard library organized into the following _modules_: + +{#link-module||lang#} +: 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. +{#link-module||io#} +: Provides operators for reading and writing files as well as printing to STDOUT and reading from STDIN. +{#link-module||fs#} +: Provides operators for accessing file information and properties. +{#link-module||logic#} +: Provides comparison operators for all min data types and other boolean logic operators. +{#link-module||str#} +: Provides operators to perform operations on strings, use regular expressions, interpolation, etc.. +{#link-module||sys#} +: Provides operators to use as basic shell commands, access environment variables, and execute external commands. +{#link-module||num#} +: Provides operators to perform simple mathematical operations on integer and floating point numbers. +{#link-module||time#} +: Provides a few basic operators to manage dates, times, and timestamps. +{#link-module||crypto#} +: Provides operators to compute hashes (MD5, SHA1, SHA224, SHA256, SHA384, sha512), base64 encoding/decoding, and AES encryption/decryption. +{#link-module||math#} +: Provides many mathematical operators and constants such as trigonometric functions, square root, logarithms, etc. + +## Notation + +The following notation is used in the signature of all min operators: + +### Types and Values + +{{null}} +: No value. +{{any}} +: A value of any type. +{{b}} +: A boolean value +{{i}} +: An integer value. +{{flt}} +: A float value. +{{n}} +: A numeric (integer or float) value. +{{s}} +: A string value. +{{sl}} +: A string-like value (string or quoted symbol). +{{q}} +: A quotation (also expressed as parenthesis enclosing other values). +{{d}} +: A dictionary value. +{{tinfo}} +: A timeinfo dictionary: + <pre><code>( + ("year" 2017) + ("month" 7) + ("day" 8) + ("weekday" 6) + ("yearday" 188) + ("hour" 15) + ("minute" 16) + ("second" 25) + ("dst" true) + ("timezone" -3600) + ) + </code></pre> +{{e}} +: An error dictionary: + <pre><code>( + ("error" "MyError") + ("message" "An error occurred") + ("symbol" "symbol1") + ("filename" "dir1/file1.min") + ("line" 3) + ("column" 13) + ) + </code></pre> +{{t}} +: true (boolean type). +{{f}} +: false (boolean type) + +### Suffixes + +The following suffixes can be placed at the end of a value or type to indicate ordering or quantities. + +{{1}} +: The first value of the specified type. +{{2}} +: The second value of the specified type. +{{3}} +: The third value of the specified type. +{{4}} +: The fourth value of the specified type. +{{01}} +: Zero or one. +{{0p}} +: Zero or more. +{{1p}} +: One or more
M site/rules.minsite/rules.min

@@ -68,7 +68,7 @@ contents (

(dict) expect -> dup ( - ((/id "^_includes" match) ()) ;Ignore files starting with underscore. + ((/id "^_" match) ()) ;Ignore files starting with underscore. ((true) (process-content set-destination output-fwrite)) ) case ) foreach
M tests/logic.mintests/logic.min

@@ -141,5 +141,8 @@ (3 "a" == not) assert

(1 () != true) assert (3.3 'test == not) assert + ("a" :x (x number?) (x 6 <) dequote-and not) assert + (1 :x (x number?) (dsagasdgsg) dequote-or) assert + report clear-stack
M tests/seq.mintests/seq.min

@@ -71,5 +71,7 @@ ((2 3 () 4 (3 4) () () "test") harvest (2 3 4 (3 4) "test") ==) assert

((1 2 3 (4 5 6) 7 (8 9)) flatten (1 2 3 4 5 6 7 8 9) ==) assert + ((2 3 + 4 *) quote-map ('+ ==) find 2 ==) assert + report clear-stack