expr/doc/Expr.html

84 KiB
Raw Blame History

<html lang="en"> <head> </head>

TODO: Work in progress (last update on 2024/05/07, 07:15 am)

1. Expr

Expr is a GO package capable of analysing, interpreting and calculating expressions.

1.1. dev-expr test tool

dev-expr is a simple program that can be used to evaluate expressions interactively. As its name suggests, it was created for testing purpose. In fact, beyond in additon to the automatic test suite based on the Go test framework, dev-expr provides an important aid for quickly testing of new features during their development.

It cat work as a REPL, *R*ead-*E*xecute-*P*rint-*L*oop, or it can process expression acquired from files or standard input.

The program in located in the tools directory. Here are some examples of execution.

Run dev-expr in REPL mode and ask for help
# Assume the expr source directory. Type 'exit' or Ctrl+D to quit the program.

[user]$ tools/expr -- Expressions calculator v1.6.1,2024/05/06 (celestino.amoroso@portale-stac.it)
	Type help to get the list of command.
	See also https://git.portale-stac.it/go-pkg/expr/src/branch/main/README.adoc

>>> help
--- REPL commands:
        help -- Show command list
          ml -- Enable/Disable multi-line output
        mods -- List builtin modules
         tty -- Enable/Disable ansi output (1)
        exit -- Exit the program

--- Command line options:
    -b <builtin>       Import builtin modules.
                       <builtin> can be a list of module names or a glob-pattern.
                       Use the special value 'all' or the pattern '*' to import all modules.
    -e <expression>    Evaluate <expression> instead of standard-input
    -i                 Force REPL operation when all -e occurences have been processed
    -h, --help, help   Show this help menu
    -m, --modules      List all builtin modules
    -p                 Print prefix form
    -t                 Print tree form (2)
1 Only available for single fraction values
2 Work in progress
REPL examples
[user]$ tools/expr -- Expressions calculator v1.6.1,2024/05/06 (celestino.amoroso@portale-stac.it)
        Type help to get the list of command.
        See also https://git.portale-stac.it/go-pkg/expr/src/branch/main/README.adoc
>>> 2+3
5
>>> 2+3*(4-1.5)
9.5
>>> 0xFD + 0b1 + 0o1 (1)
255
>>> 1|2 + 2|3 (2)
7|6
>>> ml (3)
>>> 1|2 + 2|3
7
-
6
>>> 1+2 but 5|2+0.5 (4)
3
>>> 1+2; 5|2+0.5 (5)
3
>>>
1 Number bases: 0x = hexadecimal, 0o = octal, 0b = binary.
2 Fractions: numerator | denominator.
3 Activate multi-line output of fractions.
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.

2. Data types

Expr supports numerical, string, relational, boolean expressions, and mixed-type lists.

2.1. Numbers

Numbers can be integers (GO int64) or float (GO float64). In mixed operations involving integers and floats, integers are automatically promoted to floats.

Table 1. Arithmetic operators
Symbol Operation Description Examples

+ / -

change sign

Change the sign of values

-1 [-1]
-(+2) [-2]

+

sum

Add two values

-1 + 2 [1]
4 + 0.5 [4.5]

-

subtraction

Subtract the right value from the left one

3 - 1 [2]
4 - 0.5 [3.5]

*

product

Multiply two values

-1 * 2 [-2]
4 * 0.5 [2.0]

/

Division

Divide the left value by the right one

-1 / 2 [0]
1.0 / 2 [0.5]

./

Float division

Force float division

-1 ./ 2 [-0.5]

%

Modulo

Remainder of the integer division

5 % 2 [1]

2.2. String

Strings are character sequences enclosed between two double quote ". Example: "Im a string".

Some arithmetic operators can also be used with strings.

Table 2. String operators
Symbol Operation Description Examples

+

concatenation

Join two strings or two stringable values

"one" + "two" ["onetwo"]
"one" + 2 ["one2"]

*

repeat

Make n copy of a string

"one" * 2 ["oneone"]

2.3. Boolean

Boolean data type has two values only: true and false. Relational and Boolean expressions produce Boolean values.

Table 3. Relational operators
Symbol Operation Description Examples

==

Equal

True if the left value is equal to the right one

5 == 2 [false]
"a" == "a" [true]

!=

Not Equal

True if the left value is NOT equal to the right one

5 != 2 [true]
"a" != "a" [false]

<

Less

True if the left value is less than the right one

5 < 2 [false]
"a" < "b" [true]

<=

Less or Equal

True if the left value is less than or equal to the right one

5 <= 2 [false]
"b" <= "b" [true]

>

Greater

True if the left value is greater than the right one

5 > 2 [true]
"a" < "b" [false]

>=

Greater or Equal

True if the left value is greater than or equal to the right one

5 >= 2 [true]
"b" <= "b" [true]

Table 4. Boolean operators
Symbol Operation Description Examples

NOT

Not

True if the right value is false

NOT true [false]
NOT (2 < 1) [true]

AND / &&

And

True if both left and right values are true

false && true [false]
"a" < "b" AND NOT (2 < 1) [true]

OR / ||

Or

True if at least one of the left and right values integers true

false or true [true]
"a" == "b" OR (2 == 1) [false]

Currently, boolean operations are evaluated using short cut evaluation. This means that, if the left expression of operators and and or is sufficient to establish the result of the whole operation, the right expression would not evaluated at all.

Example
2 > (a=1) or (a=8) > 0; a (1)
1 This multi-expression returns 1 because in the first expression the left value of or is true and as a conseguence its right value is not computed. Therefore the a variable only receives the integer 1.

2.4. List

Expr supports list of mixed-type values, also specified by normal expressions.

List examples
[1, 2, 3]                   // List of integers
["one", "two", "three"]     // List of strings
["one", 2, false, 4.1]      // List of mixed-types
["one"+1, 2.0*(9-2)]        // List of expressions
[ [1,"one"], [2,"two"]]     // List of lists
Table 5. List operators
Symbol Operation Description Examples

+

Join

Joins two lists

[1,2] + [3] [ [1,2,3] ]

-

Difference

Left list without elements in the right list

[1,2,3] - [2] [ [1,3] ]

3. Variables

A variable is an identifier with an assigned value. Variables are stored in the object that implements the ExprContext interface.

Examples
a=1
x = 5.2 * (9-3)
x = 1; y = 2*x

4. Other operations

4.1. ; operator

The semicolon operator ; is an infixed pseudo-operator. It evaluates the left expression first and then the right expression. The latter is the final result.

Technically ; is not treated as a real operator. It acts as a separator in lists of expressions.
; can be used to set some variables before the final calculation.
Example
a=1; b=2; c=3; a+b+c    // returns 6

4.2. but operator

but is an infixed operator. Its operands can be expressions of any type. It evaluates the left expression first, then the right expression. The value of the right expression is the final result. Examples: 5 but 2 returns 2, x=2*3 but x-1 returns 5.

but is very similar to ;. The only difference is that ; cant be used inside parenthesis ( and ).

4.3. Assignment operator =

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

4.4. Selector operator ? : ::

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>}

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 find 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 : 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
1 ? {"a"} : {"b"}                           // returns "b"
10 ? {"a"} : {"b"} :: {"c"}                 // returns "c"
10 ? {"a"} :[true, 2+8] {"b"} :: {"c"}      // returns "b"
10 ? {"a"} :[true, 2+8] {"b"} ::[10] {"c"}  // error:  "... case list in default clause"
10 ? {"a"} :[10] {x="b" but x} :: {"c"}     // returns "b"
10 ? {"a"} :[10] {x="b"; x} :: {"c"}        // returns "b"
10 ? {"a"} : {"b"}                          // error:  "... no case catches the value (10) of the selection expression

5. Priorities of operators

The table below shows all supported operators by decreasing priorities.

Table 6. Operators priorities
Priority Operators Position Operation Operands and results

ITEM

.

Infix

Item

collection "." keyany

INC

++

Postfix

Post increment

integer-variable "++"integer

++

Postfix

Next item

iterator "++"any

FACT

!

Postfix

Factorial

integer "!"integer

SIGN

+, -

Prefix

Change-sign

("+“|”-") numbernumber

#

Prefix

Lenght-of

"#" collectioninteger

#

Prefix

Size-of

"#" iteratorinteger

PROD

*

Infix

Product

number "*" numbernumber

*

Infix

String-repeat

string "*" integerstring

/

Infix

Division

number "/" numbernumber

./

Infix

Float-division

number "./" numberfloat

%

Infix

Integer-remainder

integer "%" integerinteger

SUM

+

Infix

Sum

number "+" numbernumber

+

Infix

String-concat

(string|number) "+" (string|number) → string

+

Infix

List-join

list "+" listlist

-

Infix

Subtraction

number "-" numbernumber

-

Infix

List-difference

list "-" listlist

RELATION

<

Infix

less

comparable "<" comparableboolean

<=

Infix

less-equal

comparable "<=" comparableboolean

>

Infix

greater

comparable ">" comparableboolean

>=

Infix

greater-equal

comparable ">=" comparableboolean

==

Infix

equal

comparable "==" comparableboolean

!=

Infix

not-equal

comparable "!=" comparableboolean

NOT

not

Prefix

not

"not" booleanboolean

AND

and

Infix

and

boolean "and" booleanboolean

&&

Infix

and

boolean "&&" booleanboolean

OR

or

Infix

or

boolean "or" booleanboolean

||

Infix

or

boolean "||" booleanboolean

ASSIGN

=

Infix

assignment

identifier "=" anyany

BUT

but

Infix

but

any "but" anyany

6. Functions

Functions in Expr are very similar to functions in many programming languages.

In Expr functions compute values in a local context (scope) that do not make effects on the calling context. This is the normal behavior. Using the reference operator @ it is possibile to export local definition to the calling context.

6.1. Function calls

TODO: function calls operations

6.2. Function definitions

TODO: function definitions operations

7. Builtins

TODO: builtins

7.2. import()

import(<source-file>) loads the multi-expression contained in the specified source and returns its value.

</html>