Expr.doc, a lot of fixes

This commit is contained in:
Celestino Amoroso 2026-04-15 18:17:27 +02:00
parent 037565c41e
commit 3ba8194ddb
2 changed files with 70 additions and 60 deletions

View File

@ -20,15 +20,15 @@ Expressions calculator
:rouge-style: gruvbox :rouge-style: gruvbox
// :rouge-style: colorful // :rouge-style: colorful
//:rouge-style: monokay //:rouge-style: monokay
// Work around to manage double-column in back-tick quotes // Workaround to manage double-column in back-tick quotes
:2c: :: :2c: ::
toc::[] toc::[]
#TODO: Work in progress (last update on 2024/06/21, 05:40 a.m.)# #TODO: Work in progress (last update on 2026/04/15, 6:02 p.m.)#
== Expr == Expr
_Expr_ is a GO package capable of analysing, interpreting and calculating expressions. _Expr_ is a GO package that can analyze, interpret and calculate expressions.
=== Concepts and terminology === Concepts and terminology
@ -42,7 +42,7 @@ Expressions are texts containing sequences of operations represented by a syntax
image::expression-diagram.png[] image::expression-diagram.png[]
==== Variables ==== Variables
_Expr_ supports variables. The result of an expression can be stored in a variable and reused in other espressions simply specifying the name of the variable as an operand. _Expr_ supports variables. The result of an expression can be stored in a variable and reused in other espressions by simply specifying the name of the variable as an operand.
==== Multi-expression ==== Multi-expression
An input text valid for _Expr_ can contain more than an expression. Expressions are separated by [blue]`;` (semicolon). When an input contains two or more expressions it is called _multi-expression_. An input text valid for _Expr_ can contain more than an expression. Expressions are separated by [blue]`;` (semicolon). When an input contains two or more expressions it is called _multi-expression_.
@ -58,9 +58,9 @@ The expression context is analogous to the stack-frame of other programming lang
Function contexts are created by cloning the calling context. More details on this topic are given later in this document. Function contexts are created by cloning the calling context. More details on this topic are given later in this document.
_Expr_ creates and keeps a inner _global context_ where it stores imported functions, either from builtin or plugin modules. To perform calculations, the user program must provide its own context; this is the _main context_. All calculations take place in this context. As mentioned eralier, when a function is called, a new context is created by cloning the calling context. The created context can be called _function context_. _Expr_ creates and keeps a inner _global context_ where it stores imported functions, either from builtin or plugin modules. To perform calculations, the user program must provide its own context; this is the _main context_. All calculations take place in this context. As mentioned earlier, when a function is called, a new context is created by cloning the calling context. The created context can be called _function context_.
Imported functions are registerd in the _global context_. When an expression first calls an imported function, that function is linked to the current context; this can be the _main context_ or a _function context_. Imported functions are registered in the _global context_. When an expression first calls an imported function, that function is linked to the current context; this can be the _main context_ or a _function context_.
=== `dev-expr` test tool === `dev-expr` test tool
Before we begin to describe the syntax of _Expr_, it is worth introducing _dev-expr_ because it will be used to show many examples of expressions. Before we begin to describe the syntax of _Expr_, it is worth introducing _dev-expr_ because it will be used to show many examples of expressions.
@ -145,7 +145,7 @@ dev-expr -- Expressions calculator v1.10.0(build 14),2024/06/17 (celestino.amoro
<2> Fractions: _numerator_ : _denominator_. <2> Fractions: _numerator_ : _denominator_.
<3> Activate multi-line output of fractions. <3> Activate multi-line output of fractions.
<4> But operator, see <<_but_operator>>. <4> But operator, see <<_but_operator>>.
<5> Multi-expression: the same result of the previous single expression but this it is obtained with two separated calculations. <5> Multi-expression: the same result as the previous single expression, but this time it is obtained with two separate calculations.
== Data types == Data types
_Expr_ has its type system which is a subset of Golang's type system. It supports numerical, string, relational, boolean expressions, and mixed-type lists and maps. _Expr_ has its type system which is a subset of Golang's type system. It supports numerical, string, relational, boolean expressions, and mixed-type lists and maps.
@ -240,10 +240,11 @@ _Expr_ also supports fractions. Fraction literals are made with two integers sep
.Fraction literal syntax .Fraction literal syntax
==== ====
*_fraction_* = [__sign__] (_num-den-spec_ "**:**" _float-spec_) + *_fraction_* = [__sign__] (_num-den-spec_ | _float-spec_) +
_sign_ = "**+**" | "**-**" + _sign_ = "**+**" | "**-**" +
_num-den-spec_ = _digit-seq_ "**|**" _digit-seq_ + _num-den-spec_ = _digit-seq_ "**:**" _digit-seq_ +
_float-spec_ = _dec-seq_ "**.**" [_dec-seq_] "**(**" _dec-seq_ "**)**" + _float-spec_ = _dec-seq_ "**.**" [_dec-seq_] "**(**" _repetend_ "**)**" +
_repetend_ = _dec-seq_ +
_dec-seq_ = _see-integer-literal-syntax_ + _dec-seq_ = _see-integer-literal-syntax_ +
_digit-seq_ = _see-integer-literal-syntax_ _digit-seq_ = _see-integer-literal-syntax_
==== ====
@ -276,6 +277,8 @@ _digit-seq_ = _see-integer-literal-syntax_
`>>>` [blue]`1:(-2)` + `>>>` [blue]`1:(-2)` +
[green]`-1:2` [green]`-1:2`
`>>>` [blue]`1.(3)` // 1.33333... +
[green]`4:3`
Fractions can be used together with integers and floats in expressions. Fractions can be used together with integers and floats in expressions.
@ -395,12 +398,13 @@ Boolean data type has two values only: [blue]_true_ and [blue]_false_. Relationa
[CAUTION] [CAUTION]
==== ====
Currently, boolean operations are evaluated using _short cut evaluation_. This means that, if the left expression of the [blue]`and` and [blue]`or` operators is sufficient to establish the result of the whole operation, the right expression would not be evaluated at all. Currently, boolean operations are evaluated using _short cut evaluation_. This means that, if the left expression of the [blue]`and` and [blue]`or` operators is sufficient to establish the result of the whole operation, the right expression would not be evaluated at all.
.Example .Example
[source,go] [source,go]
---- ----
2 > (a=1) or (a=8) > 0; a // <1> 2 > (a=1) or (a=8) > 0; a // <1>
---- ----
<1> This multi-expression returns _1_ because in the first expression the left value of [blue]`or` is _true_ and as a conseguence its right value is not computed. Therefore the _a_ variable only receives the integer _1_. <1> This multi-expression returns _1_ because in the first expression the left value of [blue]`or` is _true_ and, as a conseguence, its right value is not computed. Therefore the _a_ variable only receives the integer _1_.
TIP: `dev-expr` provides the _ctrl()_ function that allows to change this behaviour. TIP: `dev-expr` provides the _ctrl()_ function that allows to change this behaviour.
@ -492,10 +496,10 @@ Array's items can be accessed using the index `[]` operator.
[green]`3` [green]`3`
.Examples: Element insertion .Examples: Element insertion
`>>>` [blue]`"first" >> list` + `>>>` [blue]`"first" +> list` +
[green]`["first", "one", "six", "three"]` [green]`["first", "one", "six", "three"]`
`>>>` [blue]`list << "last"` + `>>>` [blue]`list <+ "last"` +
[green]`["first", "one", "six", "three", "last"]` [green]`["first", "one", "six", "three", "last"]`
.Examples: Element in list .Examples: Element in list
@ -509,7 +513,7 @@ Array's items can be accessed using the index `[]` operator.
`>>>` [blue]`[1,2,3] + ["one", "two", "three"]` + `>>>` [blue]`[1,2,3] + ["one", "two", "three"]` +
[green]`[1, 2, 3, "one", "two", "three"]` [green]`[1, 2, 3, "one", "two", "three"]`
`>>>` [blue]`[1,2,3,4] - [2,4]` + `>>>` [blue]`[1,2,3,2,4] - [2,4]` +
[green]`[1, 3]` [green]`[1, 3]`
@ -570,7 +574,7 @@ _Expr_, like most programming languages, supports variables. A variable is an id
.Variable literal syntax .Variable literal syntax
==== ====
*_variable_* = _identifier_ "*=*" _any-value_ + *_variable_* = _identifier_ "*=*" _any-value_ +
_identifier_ = _alpha_ {(_alpha_)|_dec-digit_|"*_*"} + _identifier_ = _alpha_ {_alpha_|_dec-digit_|"*_*"} +
__alpha__ = "*a*"|"*b*"|..."*z*"|"*A*"|"*B*"|..."*Z*" __alpha__ = "*a*"|"*b*"|..."*z*"|"*A*"|"*B*"|..."*Z*"
==== ====
@ -695,7 +699,7 @@ The [blue]`:` symbol (colon) is the separator of the selector-cases. Note that i
=== Variable default value [blue]`??`, [blue]`?=`, and [blue]`?!` === Variable default value [blue]`??`, [blue]`?=`, and [blue]`?!`
The left operand of first two operators, [blue]`??` and [blue]`?=`, must be a variable. The right operator can be any expression. They return the value of the variable if this is defined; otherwise they return the value of the right expression. The left operand of the first two operators, [blue]`??` and [blue]`?=`, must be a variable. The right operator can be any expression. They return the value of the variable if this is defined; otherwise they return the value of the right expression.
IMPORTANT: If the left variable is defined, the right expression is not evaluated at all. IMPORTANT: If the left variable is defined, the right expression is not evaluated at all.
@ -841,12 +845,12 @@ Functions in _Expr_ are very similar to functions available in many programming
=== _Expr_ function definition === _Expr_ function definition
A function is identified and referenced by its name. It can have zero or more parameter. _Expr_ functions also support optional parameters and passing paramters by name. An expr-function is identified and referenced by its name. It can have zero or more parameter. expr-functions also support optional parameters and passing paramters by name.
.Expr's function definition syntax .Expr's function definition syntax
==== ====
*_function-definition_* = _identifier_ "**=**" "**func(**" [_formal-param-list_] "**)**" "**{**" _multi-expression_ "**}**" + *_function-definition_* = _identifier_ "**=**" "**func(**" [_formal-param-list_] "**)**" "**{**" _multi-expression_ "**}**" +
_formal-param_list_ = _required-param-list_ [ "**,**" _optional-param-list_ ] + _formal-param-list_ = _required-param-list_ [ "**,**" _optional-param-list_ ] +
_required-param-list_ = _identifier_ { "**,**" _identifier_ } + _required-param-list_ = _identifier_ { "**,**" _identifier_ } +
_optional-param-list_ = _optional-parm_ { "**,**" _optional-param_ } + _optional-param-list_ = _optional-parm_ { "**,**" _optional-param_ } +
_optional-param_ = _param-name_ "**=**" _any-expr_ + _optional-param_ = _param-name_ "**=**" _any-expr_ +
@ -858,7 +862,7 @@ _param-name_ = _identifier_
`>>>` [blue]`sum = func(a, b){ a + b }` + `>>>` [blue]`sum = func(a, b){ a + b }` +
[green]`sum(a, b):any{}` [green]`sum(a, b):any{}`
^(\*)^ Since the plus, *+*, operator is defined for multiple data-types, the _sum()_ function can be used for any pair of that types. ^(*)^ Since the plus, **+**, operator is defined for multiple data-types, the _sum()_ function can be used for any pair of that types.
`>>>` [gray]_// A more complex example: recursive calculation of the n-th value of Fibonacci's sequence_ + `>>>` [gray]_// A more complex example: recursive calculation of the n-th value of Fibonacci's sequence_ +
`>>>` [blue]`fib = func(n){ n ? [0] {0}: [1] {1} :: {fib(n-1)+fib(n-2)} }` + `>>>` [blue]`fib = func(n){ n ? [0] {0}: [1] {1} :: {fib(n-1)+fib(n-2)} }` +
@ -959,9 +963,9 @@ _param-name_ = _identifier_
=== Function context === Function context
Functions compute values in a local context (scope) that do not make effects on the calling context. This is the normal behavior. Using the _clone_ modifier [blue]`@` it is possibile to export local definition to the calling context. The clone modifier must be used as prefix to variable names and it is part of the name. E.g. [blue]`@x` is not the same as [blue]`x`; they are two different and un related variables. Functions compute values in a local context (scope) that do not make effects on the calling context. This is the normal behavior. Using the _clone_ modifier [blue]`@` it is possibile to export local definition to the calling context. The clone modifier must be used as prefix to variable names and it is part of the name. E.g. [blue]`@x` is not the same as [blue]`x`; they are two different and unrelated variables.
Clone variables are normal local variables. The only diffence will appear when the defining function terminate, just before the destruction of its local context. At that point, all local clone variables are cloned in the calling context with the same names but the [blue]`@` symbol. Clone variables are normal local variables. The only diffence will appear when the defining function ends, just before the destruction of its local context. At that point, all local clone variables are cloned in the calling context with the same names but the [blue]`@` symbol.
.Example .Example
`>>>` [blue]`f = func() { @x = 3; x = 5 }` [gray]_// f() declares two *different* local variables: ``@x`` and ``x``_ + `>>>` [blue]`f = func() { @x = 3; x = 5 }` [gray]_// f() declares two *different* local variables: ``@x`` and ``x``_ +
@ -978,12 +982,12 @@ NOTE: The clone modifier [blue]`@` does not make a variable a reference variable
The clone modifier can also be used to declare the formal parameters of functions, because they are local variables too. The clone modifier can also be used to declare the formal parameters of functions, because they are local variables too.
.Example .Example
`>>>` [blue]`g = func(@p) {2+@p}` `>>>` [blue]`g = func(@p) {2+@p}` +
g(@p):any{}` [green]`g(@p):any{}` +
`>>>` [blue]`g(9)` `>>>` [blue]`g(9)` +
11` [green]`11` +
`>>>` [blue]`p `>>>` [blue]`p` +
9 [green]`9`
==== ====
== Iterators == Iterators

View File

@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.20"> <meta name="generator" content="Asciidoctor 2.0.26">
<meta name="author" content="Celestino Amoroso"> <meta name="author" content="Celestino Amoroso">
<title>Expr</title> <title>Expr</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
@ -117,7 +117,6 @@ h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title str
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed} :not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed} pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit} pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal} pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal} em em{font-style:normal}
strong strong{font-weight:400} strong strong{font-weight:400}
@ -141,7 +140,7 @@ p a>code:hover{color:rgba(0,0,0,.9)}
#content::before{content:none} #content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf} #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px} #header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap} #header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em} #header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)} #header .details span.email a{color:rgba(0,0,0,.85)}
@ -163,6 +162,7 @@ p a>code:hover{color:rgba(0,0,0,.9)}
#toctitle{color:#7a2518;font-size:1.2em} #toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em} @media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0} body.toc2{padding-left:15em;padding-right:0}
body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} #toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0} #toc.toc2>ul{font-size:.9em;margin-bottom:0}
@ -219,6 +219,7 @@ table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8} .literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)} .literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative} .listingblock>.content{position:relative}
.listingblock pre>code{display:block}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5} .listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block} .listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5} .listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
@ -328,7 +329,7 @@ a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none} a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super} sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none} sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline} sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0} #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em} #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
@ -605,7 +606,7 @@ pre.rouge .ss {
<div class="sectionbody"> <div class="sectionbody">
<!-- toc disabled --> <!-- toc disabled -->
<div class="paragraph"> <div class="paragraph">
<p><mark>TODO: Work in progress (last update on 2024/06/21, 05:40 a.m.)</mark></p> <p><mark>TODO: Work in progress (last update on 2026/04/15, 6:02 p.m.)</mark></p>
</div> </div>
</div> </div>
</div> </div>
@ -613,7 +614,7 @@ pre.rouge .ss {
<h2 id="_expr"><a class="anchor" href="#_expr"></a><a class="link" href="#_expr">1. Expr</a></h2> <h2 id="_expr"><a class="anchor" href="#_expr"></a><a class="link" href="#_expr">1. Expr</a></h2>
<div class="sectionbody"> <div class="sectionbody">
<div class="paragraph"> <div class="paragraph">
<p><em>Expr</em> is a GO package capable of analysing, interpreting and calculating expressions.</p> <p><em>Expr</em> is a GO package that can analyze, interpret and calculate expressions.</p>
</div> </div>
<div class="sect2"> <div class="sect2">
<h3 id="_concepts_and_terminology"><a class="anchor" href="#_concepts_and_terminology"></a><a class="link" href="#_concepts_and_terminology">1.1. Concepts and terminology</a></h3> <h3 id="_concepts_and_terminology"><a class="anchor" href="#_concepts_and_terminology"></a><a class="link" href="#_concepts_and_terminology">1.1. Concepts and terminology</a></h3>
@ -641,7 +642,7 @@ pre.rouge .ss {
<div class="sect3"> <div class="sect3">
<h4 id="_variables"><a class="anchor" href="#_variables"></a><a class="link" href="#_variables">1.1.1. Variables</a></h4> <h4 id="_variables"><a class="anchor" href="#_variables"></a><a class="link" href="#_variables">1.1.1. Variables</a></h4>
<div class="paragraph"> <div class="paragraph">
<p><em>Expr</em> supports variables. The result of an expression can be stored in a variable and reused in other espressions simply specifying the name of the variable as an operand.</p> <p><em>Expr</em> supports variables. The result of an expression can be stored in a variable and reused in other espressions by simply specifying the name of the variable as an operand.</p>
</div> </div>
</div> </div>
<div class="sect3"> <div class="sect3">
@ -668,10 +669,10 @@ pre.rouge .ss {
<p>Function contexts are created by cloning the calling context. More details on this topic are given later in this document.</p> <p>Function contexts are created by cloning the calling context. More details on this topic are given later in this document.</p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p><em>Expr</em> creates and keeps a inner <em>global context</em> where it stores imported functions, either from builtin or plugin modules. To perform calculations, the user program must provide its own context; this is the <em>main context</em>. All calculations take place in this context. As mentioned eralier, when a function is called, a new context is created by cloning the calling context. The created context can be called <em>function context</em>.</p> <p><em>Expr</em> creates and keeps a inner <em>global context</em> where it stores imported functions, either from builtin or plugin modules. To perform calculations, the user program must provide its own context; this is the <em>main context</em>. All calculations take place in this context. As mentioned earlier, when a function is called, a new context is created by cloning the calling context. The created context can be called <em>function context</em>.</p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p>Imported functions are registerd in the <em>global context</em>. When an expression first calls an imported function, that function is linked to the current context; this can be the <em>main context</em> or a <em>function context</em>.</p> <p>Imported functions are registered in the <em>global context</em>. When an expression first calls an imported function, that function is linked to the current context; this can be the <em>main context</em> or a <em>function context</em>.</p>
</div> </div>
</div> </div>
</div> </div>
@ -789,7 +790,7 @@ dev-expr <span class="nt">--</span> Expressions calculator v1.10.0<span class="o
</tr> </tr>
<tr> <tr>
<td><i class="conum" data-value="5"></i><b>5</b></td> <td><i class="conum" data-value="5"></i><b>5</b></td>
<td>Multi-expression: the same result of the previous single expression but this it is obtained with two separated calculations.</td> <td>Multi-expression: the same result as the previous single expression, but this time it is obtained with two separate calculations.</td>
</tr> </tr>
</table> </table>
</div> </div>
@ -997,10 +998,11 @@ dev-expr <span class="nt">--</span> Expressions calculator v1.10.0<span class="o
<div class="title">Example 3. Fraction literal syntax</div> <div class="title">Example 3. Fraction literal syntax</div>
<div class="content"> <div class="content">
<div class="paragraph"> <div class="paragraph">
<p><strong><em>fraction</em></strong> = [<em>sign</em>] (<em>num-den-spec</em> "<strong>:</strong>" <em>float-spec</em>)<br> <p><strong><em>fraction</em></strong> = [<em>sign</em>] (<em>num-den-spec</em> | <em>float-spec</em>)<br>
<em>sign</em> = "<strong>+</strong>" | "<strong>-</strong>"<br> <em>sign</em> = "<strong>+</strong>" | "<strong>-</strong>"<br>
<em>num-den-spec</em> = <em>digit-seq</em> "<strong>|</strong>" <em>digit-seq</em><br> <em>num-den-spec</em> = <em>digit-seq</em> "<strong>:</strong>" <em>digit-seq</em><br>
<em>float-spec</em> = <em>dec-seq</em> "<strong>.</strong>" [<em>dec-seq</em>] "<strong>(</strong>" <em>dec-seq</em> "<strong>)</strong>"<br> <em>float-spec</em> = <em>dec-seq</em> "<strong>.</strong>" [<em>dec-seq</em>] "<strong>(</strong>" <em>repetend</em> "<strong>)</strong>"<br>
<em>repetend</em> = <em>dec-seq</em><br>
<em>dec-seq</em> = <em>see-integer-literal-syntax</em><br> <em>dec-seq</em> = <em>see-integer-literal-syntax</em><br>
<em>digit-seq</em> = <em>see-integer-literal-syntax</em></p> <em>digit-seq</em> = <em>see-integer-literal-syntax</em></p>
</div> </div>
@ -1044,6 +1046,10 @@ dev-expr <span class="nt">--</span> Expressions calculator v1.10.0<span class="o
<code class="green">-1:2</code></p> <code class="green">-1:2</code></p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p><code>&gt;&gt;&gt;</code> <code class="blue">1.(3)</code> // 1.33333&#8230;&#8203;<br>
<code class="green">4:3</code></p>
</div>
<div class="paragraph">
<p>Fractions can be used together with integers and floats in expressions.</p> <p>Fractions can be used together with integers and floats in expressions.</p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
@ -1281,10 +1287,10 @@ dev-expr <span class="nt">--</span> Expressions calculator v1.10.0<span class="o
</td> </td>
<td class="content"> <td class="content">
<div class="paragraph"> <div class="paragraph">
<p>Currently, boolean operations are evaluated using <em>short cut evaluation</em>. This means that, if the left expression of the <code class="blue">and</code> and <code class="blue">or</code> operators is sufficient to establish the result of the whole operation, the right expression would not be evaluated at all. <p>Currently, boolean operations are evaluated using <em>short cut evaluation</em>. This means that, if the left expression of the <code class="blue">and</code> and <code class="blue">or</code> operators is sufficient to establish the result of the whole operation, the right expression would not be evaluated at all.</p>
.Example</p>
</div> </div>
<div class="listingblock"> <div class="listingblock">
<div class="title">Example</div>
<div class="content"> <div class="content">
<pre class="rouge highlight"><code data-lang="go"><span class="m">2</span> <span class="o">&gt;</span> <span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="m">1</span><span class="p">)</span> <span class="n">or</span> <span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="m">8</span><span class="p">)</span> <span class="o">&gt;</span> <span class="m">0</span><span class="p">;</span> <span class="n">a</span> <i class="conum" data-value="1"></i><b>(1)</b></code></pre> <pre class="rouge highlight"><code data-lang="go"><span class="m">2</span> <span class="o">&gt;</span> <span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="m">1</span><span class="p">)</span> <span class="n">or</span> <span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="m">8</span><span class="p">)</span> <span class="o">&gt;</span> <span class="m">0</span><span class="p">;</span> <span class="n">a</span> <i class="conum" data-value="1"></i><b>(1)</b></code></pre>
</div> </div>
@ -1293,7 +1299,7 @@ dev-expr <span class="nt">--</span> Expressions calculator v1.10.0<span class="o
<table> <table>
<tr> <tr>
<td><i class="conum" data-value="1"></i><b>1</b></td> <td><i class="conum" data-value="1"></i><b>1</b></td>
<td>This multi-expression returns <em>1</em> because in the first expression the left value of <code class="blue">or</code> is <em>true</em> and as a conseguence its right value is not computed. Therefore the <em>a</em> variable only receives the integer <em>1</em>.</td> <td>This multi-expression returns <em>1</em> because in the first expression the left value of <code class="blue">or</code> is <em>true</em> and, as a conseguence, its right value is not computed. Therefore the <em>a</em> variable only receives the integer <em>1</em>.</td>
</tr> </tr>
</table> </table>
</div> </div>
@ -1475,11 +1481,11 @@ dev-expr <span class="nt">--</span> Expressions calculator v1.10.0<span class="o
</div> </div>
<div class="paragraph"> <div class="paragraph">
<div class="title">Examples: Element insertion</div> <div class="title">Examples: Element insertion</div>
<p><code>&gt;&gt;&gt;</code> <code class="blue">"first" &gt;&gt; list</code><br> <p><code>&gt;&gt;&gt;</code> <code class="blue">"first" +&gt; list</code><br>
<code class="green">["first", "one", "six", "three"]</code></p> <code class="green">["first", "one", "six", "three"]</code></p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p><code>&gt;&gt;&gt;</code> <code class="blue">list &lt;&lt; "last"</code><br> <p><code>&gt;&gt;&gt;</code> <code class="blue">list &lt;+ "last"</code><br>
<code class="green">["first", "one", "six", "three", "last"]</code></p> <code class="green">["first", "one", "six", "three", "last"]</code></p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
@ -1497,7 +1503,7 @@ dev-expr <span class="nt">--</span> Expressions calculator v1.10.0<span class="o
<code class="green">[1, 2, 3, "one", "two", "three"]</code></p> <code class="green">[1, 2, 3, "one", "two", "three"]</code></p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p><code>&gt;&gt;&gt;</code> <code class="blue">[1,2,3,4] - [2,4]</code><br> <p><code>&gt;&gt;&gt;</code> <code class="blue">[1,2,3,2,4] - [2,4]</code><br>
<code class="green">[1, 3]</code></p> <code class="green">[1, 3]</code></p>
</div> </div>
</div> </div>
@ -1610,7 +1616,7 @@ dev-expr <span class="nt">--</span> Expressions calculator v1.10.0<span class="o
<div class="content"> <div class="content">
<div class="paragraph"> <div class="paragraph">
<p><strong><em>variable</em></strong> = <em>identifier</em> "<strong>=</strong>" <em>any-value</em><br> <p><strong><em>variable</em></strong> = <em>identifier</em> "<strong>=</strong>" <em>any-value</em><br>
<em>identifier</em> = <em>alpha</em> {(<em>alpha</em>)|<em>dec-digit</em>|"<strong>_</strong>"}<br> <em>identifier</em> = <em>alpha</em> {<em>alpha</em>|<em>dec-digit</em>|"<strong>_</strong>"}<br>
<em>alpha</em> = "<strong>a</strong>"|"<strong>b</strong>"|&#8230;&#8203;"<strong>z</strong>"|"<strong>A</strong>"|"<strong>B</strong>"|&#8230;&#8203;"<strong>Z</strong>"</p> <em>alpha</em> = "<strong>a</strong>"|"<strong>b</strong>"|&#8230;&#8203;"<strong>z</strong>"|"<strong>A</strong>"|"<strong>B</strong>"|&#8230;&#8203;"<strong>Z</strong>"</p>
</div> </div>
</div> </div>
@ -1812,7 +1818,7 @@ Technically <code class="blue">;</code> is not treated as a real operator. It ac
<div class="sect2"> <div class="sect2">
<h3 id="_variable_default_value_and"><a class="anchor" href="#_variable_default_value_and"></a><a class="link" href="#_variable_default_value_and">4.5. Variable default value <code class="blue">??</code>, <code class="blue">?=</code>, and <code class="blue">?!</code></a></h3> <h3 id="_variable_default_value_and"><a class="anchor" href="#_variable_default_value_and"></a><a class="link" href="#_variable_default_value_and">4.5. Variable default value <code class="blue">??</code>, <code class="blue">?=</code>, and <code class="blue">?!</code></a></h3>
<div class="paragraph"> <div class="paragraph">
<p>The left operand of first two operators, <code class="blue">??</code> and <code class="blue">?=</code>, must be a variable. The right operator can be any expression. They return the value of the variable if this is defined; otherwise they return the value of the right expression.</p> <p>The left operand of the first two operators, <code class="blue">??</code> and <code class="blue">?=</code>, must be a variable. The right operator can be any expression. They return the value of the variable if this is defined; otherwise they return the value of the right expression.</p>
</div> </div>
<div class="admonitionblock important"> <div class="admonitionblock important">
<table> <table>
@ -2370,14 +2376,14 @@ short for<br>
<div class="sect2"> <div class="sect2">
<h3 id="_expr_function_definition"><a class="anchor" href="#_expr_function_definition"></a><a class="link" href="#_expr_function_definition">6.1. <em>Expr</em> function definition</a></h3> <h3 id="_expr_function_definition"><a class="anchor" href="#_expr_function_definition"></a><a class="link" href="#_expr_function_definition">6.1. <em>Expr</em> function definition</a></h3>
<div class="paragraph"> <div class="paragraph">
<p>A function is identified and referenced by its name. It can have zero or more parameter. <em>Expr</em> functions also support optional parameters and passing paramters by name.</p> <p>An expr-function is identified and referenced by its name. It can have zero or more parameter. expr-functions also support optional parameters and passing paramters by name.</p>
</div> </div>
<div class="exampleblock"> <div class="exampleblock">
<div class="title">Example 14. Expr&#8217;s function definition syntax</div> <div class="title">Example 14. Expr&#8217;s function definition syntax</div>
<div class="content"> <div class="content">
<div class="paragraph"> <div class="paragraph">
<p><strong><em>function-definition</em></strong> = <em>identifier</em> "<strong>=</strong>" "<strong>func(</strong>" [<em>formal-param-list</em>] "<strong>)</strong>" "<strong>{</strong>" <em>multi-expression</em> "<strong>}</strong>"<br> <p><strong><em>function-definition</em></strong> = <em>identifier</em> "<strong>=</strong>" "<strong>func(</strong>" [<em>formal-param-list</em>] "<strong>)</strong>" "<strong>{</strong>" <em>multi-expression</em> "<strong>}</strong>"<br>
<em>formal-param_list</em> = <em>required-param-list</em> [ "<strong>,</strong>" <em>optional-param-list</em> ]<br> <em>formal-param-list</em> = <em>required-param-list</em> [ "<strong>,</strong>" <em>optional-param-list</em> ]<br>
<em>required-param-list</em> = <em>identifier</em> { "<strong>,</strong>" <em>identifier</em> }<br> <em>required-param-list</em> = <em>identifier</em> { "<strong>,</strong>" <em>identifier</em> }<br>
<em>optional-param-list</em> = <em>optional-parm</em> { "<strong>,</strong>" <em>optional-param</em> }<br> <em>optional-param-list</em> = <em>optional-parm</em> { "<strong>,</strong>" <em>optional-param</em> }<br>
<em>optional-param</em> = <em>param-name</em> "<strong>=</strong>" <em>any-expr</em><br> <em>optional-param</em> = <em>param-name</em> "<strong>=</strong>" <em>any-expr</em><br>
@ -2392,7 +2398,7 @@ short for<br>
<code class="green">sum(a, b):any{}</code></p> <code class="green">sum(a, b):any{}</code></p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p><sup>(*)</sup> Since the plus, *+*, operator is defined for multiple data-types, the <em>sum()</em> function can be used for any pair of that types.</p> <p><sup>(*)</sup> Since the plus, <strong>+</strong>, operator is defined for multiple data-types, the <em>sum()</em> function can be used for any pair of that types.</p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p><code>&gt;&gt;&gt;</code> <em class="gray">// A more complex example: recursive calculation of the n-th value of Fibonacci&#8217;s sequence</em><br> <p><code>&gt;&gt;&gt;</code> <em class="gray">// A more complex example: recursive calculation of the n-th value of Fibonacci&#8217;s sequence</em><br>
@ -2510,10 +2516,10 @@ short for<br>
<div class="sect2"> <div class="sect2">
<h3 id="_function_context"><a class="anchor" href="#_function_context"></a><a class="link" href="#_function_context">6.4. Function context</a></h3> <h3 id="_function_context"><a class="anchor" href="#_function_context"></a><a class="link" href="#_function_context">6.4. Function context</a></h3>
<div class="paragraph"> <div class="paragraph">
<p>Functions compute values in a local context (scope) that do not make effects on the calling context. This is the normal behavior. Using the <em>clone</em> modifier <code class="blue">@</code> it is possibile to export local definition to the calling context. The clone modifier must be used as prefix to variable names and it is part of the name. E.g. <code class="blue">@x</code> is not the same as <code class="blue">x</code>; they are two different and un related variables.</p> <p>Functions compute values in a local context (scope) that do not make effects on the calling context. This is the normal behavior. Using the <em>clone</em> modifier <code class="blue">@</code> it is possibile to export local definition to the calling context. The clone modifier must be used as prefix to variable names and it is part of the name. E.g. <code class="blue">@x</code> is not the same as <code class="blue">x</code>; they are two different and unrelated variables.</p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p>Clone variables are normal local variables. The only diffence will appear when the defining function terminate, just before the destruction of its local context. At that point, all local clone variables are cloned in the calling context with the same names but the <code class="blue">@</code> symbol.</p> <p>Clone variables are normal local variables. The only diffence will appear when the defining function ends, just before the destruction of its local context. At that point, all local clone variables are cloned in the calling context with the same names but the <code class="blue">@</code> symbol.</p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<div class="title">Example</div> <div class="title">Example</div>
@ -2548,12 +2554,12 @@ The clone modifier <code class="blue">@</code> does not make a variable a refere
</div> </div>
<div class="paragraph"> <div class="paragraph">
<div class="title">Example</div> <div class="title">Example</div>
<p><code>&gt;&gt;&gt;</code> <code class="blue">g = func(@p) {2+@p}</code> <p><code>&gt;&gt;&gt;</code> <code class="blue">g = func(@p) {2+@p}</code><br>
g(@p):any{}` <code class="green">g(@p):any{}</code><br>
<code>&gt;&gt;&gt;</code> <code class="blue">g(9)</code> <code>&gt;&gt;&gt;</code> <code class="blue">g(9)</code><br>
11` <code class="green">11</code><br>
<code>&gt;&gt;&gt;</code> [blue]`p <code>&gt;&gt;&gt;</code> <code class="blue">p</code><br>
9</p> <code class="green">9</code></p>
</div> </div>
</td> </td>
</tr> </tr>
@ -2599,7 +2605,7 @@ g(@p):any{}`
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2025-01-05 12:15:58 +0100 Last updated 2026-04-15 18:14:50 +0200
</div> </div>
</div> </div>
</body> </body>