From 9a3abdf1b6222c0e50c18a0a07e0a1208755d9ca Mon Sep 17 00:00:00 2001 From: Celestino Amoroso Date: Fri, 17 May 2024 15:46:56 +0200 Subject: [PATCH] Doc: more details on the syntax of the selector and variable default operators --- doc/Expr.adoc | 92 +++++++++++++++++++++---------------- doc/Expr.html | 123 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 137 insertions(+), 78 deletions(-) diff --git a/doc/Expr.adoc b/doc/Expr.adoc index 7f44809..09682fc 100644 --- a/doc/Expr.adoc +++ b/doc/Expr.adoc @@ -122,7 +122,7 @@ _Expr_ supports three type of numbers: . [blue]#Integers# . [blue]#Floats# -. [blue]#Factions# internally are stored as _pairs of_ Golang _int64_ values. +. [blue]#Factions# In mixed operations involving integers, fractions and floats, automatic type promotion to the largest type take place. @@ -183,7 +183,7 @@ _dec-seq_ = _see-integer-literal-syntax_ `>>>` [blue]`4.5E-3` + [green]`0.0045` + `>>>` [blue]`4.5E10` + -[green]`4.5e+10` + +[green]`4.5e+10` .Arithmetic operators @@ -207,7 +207,7 @@ _sign_ = "**+**" | "**-**" + _num-den-spec_ = _digit-seq_ "**|**" _digit-seq_ + _float-spec_ = _dec-seq_ "**.**" [_dec-seq_] "**(**" _dec-seq_ "**)**" + _dec-seq_ = _see-integer-literal-syntax_ + -_digit-seq_ = _see-integer-literal-syntax_ + +_digit-seq_ = _see-integer-literal-syntax_ ==== .Examples @@ -241,7 +241,7 @@ Fractions can be used together with integers and floats in expressions. `>>>` [blue]`4 - 1|2` + [green]`7|2` + `>>>` [blue]`1.0 + 1|2` + -[green]`1.5` + +[green]`1.5` @@ -289,7 +289,8 @@ _item_ = _string-expr_ "**.**" _integer-expr_ `>>>` [blue]`\#s` [gray]_number of chars_ + [gren]`3` + `>>>` [blue]`#"abc"` [gray]_number of chars_ + -[green]`3` + +[green]`3` + === Booleans Boolean data type has two values only: [blue]_true_ and [blue]_false_. Relational and boolean expressions result in boolean values. @@ -475,50 +476,65 @@ The assignment operator [blue]`=` is used to define variables in the evaluation The value on the left side of [blue]`=` must be an identifier. The value on the right side can be any expression and it becomes the result of the assignment operation. .Example -[source,go] ----- -a=15+1 // returns 16 ----- +`>>>` [blue]`a=15+1` +[green]`16` + === Selector operator [blue]`? : ::` The _selector operator_ is very similar to the _switch/case/default_ statement available in many programming languages. -.Syntax -[source,bnf] ----- - ::= "?" { ":" } ["::" ] - ::= [] - ::= "["{","}"]" - ::= ::= "{" "}" - ::= {";" } ----- +.Selector literal Syntax +_selector-operator_ = _select-expression_ "*?*" _selector-case_ { "*:*" _selector-case_ } ["*::*" _default-multi-expression_] + +_selector-case_ = [_match-list_] _case-value_ + +_match-list_ = "*[*" _item_ {"*,*" _items_} "*]*" + +_item_ = _expression_ + +_case-multi-expression_ = "*{*" _multi-expression_ "*}*" + +_multi-expression_ = _expression_ { "*;*" _expression_ } + +_default-multi-expression_ = _multi-expression_ -In other words, the selector operator evaluates the expression (``) on the left-hand side of the `?` symbol; it then compares the result obtained with the values listed in the ``'s. If the comparision finds a match with a value in a match-list, the associated `` is evaluted, and its result will be the final result of the selection operation. +In other words, the selector operator evaluates the _select-expression_ on the left-hand side of the [blue]`?` symbol; it then compares the result obtained with the values listed in the __match-list__'s, from left to right. If the comparision finds a match with a value in a _match-list_, the associated _case-multi-expression_ is evaluted, and its result will be the final result of the selection operation. -The match lists are optional. In that case, the position, from left to right, of the `` is used as match-list. Of course, that only works if the select-expression results in an integer. +The match lists are optional. In that case, the position, from left to right, of the _selector-case_ is used as _match-list_. Of course, that only works if the _select-expression_ results in an integer. -The `:` symbol (colon) is the separator of the selector-cases. Note that if the value of the select-expression does not match any match-list, an error will be issued. Therefore, it is strongly recommended to provide a default (multi-)expression introduced by the `::` symbol (double-colon). Also note that the default expression has no match-list. +The [blue]`:` symbol (colon) is the separator of the selector-cases. Note that if the value of the _select-expression_ does not match any _match-list_, an error will be issued. Therefore, it is strongly recommended to provide a default (multi-)expression introduced by the [blue]`::` symbol (double-colon). Also note that the default expression has no _match-list_. .Examples -[source,go] ----- -`>>>` [blue]`1 ? {"a"} : {"b"}` -[green]`b` -`>>>` [blue]`10 ? {"a"} : {"b"} :: {"c"}` -[green]`c' -[green]`>>>` [blue]`10 ? {"a"} :[true, 2+8] {"b"} :: {"c"}` -[green]`b` -`>>>` [blue]`10 ? {"a"} :[true, 2+8] {"b"} ::[10] {"c"}` -[red]`Parse Error: [1:34] case list in default clause` -[green]`>>>` [blue]`10 ? {"a"} :[10] {x="b" but x} :: {"c"}` -[green]`b` -`>>>` [blue]`10 ? {"a"} :[10] {x="b"; x} :: {"c"}` -[green]`b` -`>>>` [blue]`10 ? {"a"} : {"b"}` +`>>>` [blue]`1 ? {"a"} : {"b"}` + +[green]`b` + +`>>>` [blue]`10 ? {"a"} : {"b"} :: {"c"}` + +[green]`c' + +[green]`>>>` [blue]`10 ? {"a"} :[true, 2+8] {"b"} :: {"c"}` + +[green]`b` + +`>>>` [blue]`10 ? {"a"} :[true, 2+8] {"b"} ::[10] {"c"}` + +[red]`Parse Error: [1:34] case list in default clause` + +[green]`>>>` [blue]`10 ? {"a"} :[10] {x="b" but x} :: {"c"}` + +[green]`b` + +`>>>` [blue]`10 ? {"a"} :[10] {x="b"; x} :: {"c"}` + +[green]`b` + +`>>>` [blue]`10 ? {"a"} : {"b"}` + [red]`Eval Error: [1:3] no case catches the value (10) of the selection expression` ----- + +=== Variable default value [blue]`??` and [blue]`?=` +The left operand of these two operators must be a variable. The right operator can be any expression. They return the value of the variable if this is define; otherwise they return the value of the right expression. + +IMPORTANT: If the left variable is defined, the right expression is not evuated at all. + +The [blue]`??` do not change the status of the left variable. + +The [blue]`?=` assigns the calculated value of the right expression to the left variable. + +.Examples +`>>>` [blue]`var ?? (1+2)`' +[green]`3` + +`>>>` [blue]`var` + +[red]`Eval Error: undefined variable or function "var"` + +`>>>` [blue]`var ?= (1+2)` + +[green]`3` + +`>>>` [blue]`var` + +[green]`3` + +NOTE: These operators have a high priority, in particular higher than the operator [blue]`=`. == Priorities of operators The table below shows all supported operators by decreasing priorities. diff --git a/doc/Expr.html b/doc/Expr.html index 2083ed1..b581c5d 100644 --- a/doc/Expr.html +++ b/doc/Expr.html @@ -561,6 +561,7 @@ pre.rouge .ss {
  • 4.2. but operator
  • 4.3. Assignment operator =
  • 4.4. Selector operator ? : ::
  • +
  • 4.5. Variable default value ?? and ?=
  • 5. Priorities of operators
  • @@ -742,7 +743,7 @@ pre.rouge .ss {

    Floats

  • -

    Factions internally are stored as pairs of Golang int64 values.

    +

    Factions

  • @@ -854,7 +855,7 @@ pre.rouge .ss { >>> 4.5E-3
    0.0045
    >>> 4.5E10
    -4.5e+10

    +4.5e+10

    @@ -918,7 +919,7 @@ pre.rouge .ss { num-den-spec = digit-seq "|" digit-seq
    float-spec = dec-seq "." [dec-seq] "(" dec-seq ")"
    dec-seq = see-integer-literal-syntax
    -digit-seq = see-integer-literal-syntax

    +digit-seq = see-integer-literal-syntax

    @@ -953,7 +954,7 @@ pre.rouge .ss { >>>4 - 1|2
    7|2
    >>>1.0 + 1|2
    -1.5

    +1.5

    @@ -1031,7 +1032,7 @@ pre.rouge .ss { >>>#snumber of chars
    3
    >>>#"abc"number of chars
    -3

    +3

    @@ -1404,11 +1405,10 @@ Technically ; is not treated as a real operator. It ac

    The assignment operator = is used to define variables in the evaluation context or to change their value (see ExprContext). The value on the left side of = must be an identifier. The value on the right side can be any expression and it becomes the result of the assignment operation.

    -
    +
    Example
    -
    -
    a=15+1    // returns 16
    -
    +

    >>> a=15+1 +16

    @@ -1416,46 +1416,89 @@ The value on the left side of = must be an identifier.

    The selector operator is very similar to the switch/case/default statement available in many programming languages.

    -
    -
    Syntax
    -
    -
    <selector-operator> ::= <select-expression> "?" <selector-case> { ":" <selector-case> } ["::" <default-multi-expression>]
    -<selector-case> ::= [<match-list>] <case-value>
    -<match-list> ::= "["<item>{","<items>}"]"
    -<item> ::= <expression
    -<case-multi-expression> ::= "{" <multi-expression> "}"
    -<multi-expression> ::= <expression> {";" <expression>}
    -
    +
    +
    Selector literal Syntax
    +

    selector-operator = select-expression "?" selector-case { ":" selector-case } ["::" default-multi-expression]
    +selector-case = [match-list] case-value
    +match-list = "[" item {"," items} "]"
    +item = expression
    +case-multi-expression = "{" multi-expression "}"
    +multi-expression = expression { ";" expression }
    +default-multi-expression = multi-expression

    -

    In other words, the selector operator evaluates the expression (<select-expression>) on the left-hand side of the ? symbol; it then compares the result obtained with the values listed in the <match-list>’s. If the comparision finds a match with a value in a match-list, the associated `<case-multi-expression> is evaluted, and its result will be the final result of the selection operation.

    +

    In other words, the selector operator evaluates the select-expression on the left-hand side of the ? symbol; it then compares the result obtained with the values listed in the match-list's, from left to right. If the comparision finds a match with a value in a match-list, the associated case-multi-expression is evaluted, and its result will be the final result of the selection operation.

    -

    The match lists are optional. In that case, the position, from left to right, of the <selector-case> is used as match-list. Of course, that only works if the select-expression results in an integer.

    +

    The match lists are optional. In that case, the position, from left to right, of the selector-case is used as match-list. Of course, that only works if the select-expression results in an integer.

    -

    The : symbol (colon) is the separator of the selector-cases. Note that if the value of the select-expression does not match any match-list, an error will be issued. Therefore, it is strongly recommended to provide a default (multi-)expression introduced by the :: symbol (double-colon). Also note that the default expression has no match-list.

    +

    The : symbol (colon) is the separator of the selector-cases. Note that if the value of the select-expression does not match any match-list, an error will be issued. Therefore, it is strongly recommended to provide a default (multi-)expression introduced by the :: symbol (double-colon). Also note that the default expression has no match-list.

    -
    +
    Examples
    -
    -
    `>>>` [blue]`1 ? {"a"} : {"b"}`
    -[green]`b`
    -`>>>` [blue]`10 ? {"a"} : {"b"} :: {"c"}`
    -[green]`c'
    -[green]`>>>` [blue]`10 ? {"a"} :[true, 2+8] {"b"} :: {"c"}`
    -[green]`b`
    -`>>>` [blue]`10 ? {"a"} :[true, 2+8] {"b"} ::[10] {"c"}`
    -[red]`Parse Error: [1:34] case list in default clause`
    -[green]`>>>` [blue]`10 ? {"a"} :[10] {x="b" but x} :: {"c"}`
    -[green]`b`
    -`>>>` [blue]`10 ? {"a"} :[10] {x="b"; x} :: {"c"}`
    -[green]`b`
    -`>>>` [blue]`10 ? {"a"} : {"b"}`
    -[red]`Eval Error: [1:3] no case catches the value (10) of the selection expression`
    -
    +

    >>> 1 ? {"a"} : {"b"}
    +b
    +>>> 10 ? {"a"} : {"b"} :: {"c"}
    +c'
    +[green]
    >>>` 10 ? {"a"} :[true, 2+8] {"b"} :: {"c"}
    +b
    +>>> 10 ? {"a"} :[true, 2+8] {"b"} ::[10] {"c"}
    +Parse Error: [1:34] case list in default clause
    +>>> 10 ? {"a"} :[10] {x="b" but x} :: {"c"}
    +b
    +>>> 10 ? {"a"} :[10] {x="b"; x} :: {"c"}
    +b
    +>>> 10 ? {"a"} : {"b"}
    +Eval Error: [1:3] no case catches the value (10) of the selection expression

    +
    +

    4.5. Variable default value ?? and ?=

    +
    +

    The left operand of these two operators must be a variable. The right operator can be any expression. They return the value of the variable if this is define; otherwise they return the value of the right expression.

    +
    +
    +
    Table 2. Arithmetic operators
    + + + + +
    + + +If the left variable is defined, the right expression is not evuated at all. +
    + +
    +

    The ?? do not change the status of the left variable.

    +
    +
    +

    The ?= assigns the calculated value of the right expression to the left variable.

    +
    +
    +
    Examples
    +

    >>> var ?? (1+2)’ +[green]`3
    +>>> var
    +Eval Error: undefined variable or function "var"
    +>>> var ?= (1+2)
    +3
    +>>> var
    +3

    +
    +
    + + + + + +
    + + +These operators have a high priority, in particular higher than the operator =. +
    +
    @@ -1724,7 +1767,7 @@ The value on the left side of = must be an identifier.