`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.
_Expr_ supports numerical, string, relational, boolean expressions, and mixed-type lists.
=== Numbers
Numbers can be integers (GO int64) or float (GO float64). In mixed operations involving integers and floats, integers are automatically promoted to floats.
.Arithmetic operators
[cols="^1,^2,6,4"]
|===
| Symbol | Operation | Description | Examples
| [blue]`+` / [blue]`-` | _change sign_ | Change the sign of values | [blue]`-1` _[-1]_ +
Boolean data type has two values only: _true_ and _false_. Relational and Boolean expressions produce Boolean values.
.Relational operators
[cols="^1,^2,6,4"]
|===
| Symbol | Operation | Description | Examples
| [blue]`==` | _Equal_ | True if the left value is equal to the right one | [blue]`5 == 2` _[false]_ +
[blue]`"a" == "a"` _[true]_
| [blue]`!=` | _Not Equal_ | True if the left value is NOT equal to the right one | [blue]`5 != 2` _[true]_ +
[blue]`"a" != "a"` _[false]_
| [blue]`<` | _Less_ | True if the left value is less than the right one | [blue]`5 < 2` _[false]_ +
[blue]`"a" < "b"` _[true]_
| [blue]`\<=` | _Less or Equal_ | True if the left value is less than or equal to the right one | [blue]`5 \<= 2` _[false]_ +
[blue]`"b" \<= "b"` _[true]_
| [blue]`>` | _Greater_ | True if the left value is greater than the right one | [blue]`5 > 2` _[true]_ +
[blue]`"a" < "b"` _[false]_
| [blue]`>=` | _Greater or Equal_ | True if the left value is greater than or equal to the right one | [blue]`5 >= 2` _[true]_ +
[blue]`"b" \<= "b"` _[true]_
|===
.Boolean operators
[cols="^2,^2,5,4"]
|===
| Symbol | Operation | Description | Examples
| [blue]`NOT` | _Not_ | True if the right value is false | [blue]`NOT true` _[false]_ +
[blue]`NOT (2 < 1)` _[true]_
| [blue]`AND` / [blue]`&&` | _And_ | True if both left and right values are true | [blue]`false && true` _[false]_ +
[blue]`"a" < "b" AND NOT (2 < 1)` _[true]_
| [blue]`OR` / [blue]`\|\|` | _Or_ | True if at least one of the left and right values integers true| [blue]`false or true` _[true]_ +
[blue]`"a" == "b" OR (2 == 1)` _[false]_
|===
[CAUTION]
====
Currently, boolean operations are evaluated using _short cut evaluation_. This means that, if the left expression of operators [blue]`and` and [blue]`or` is sufficient to establish the result of the whole operation, the right expression would not evaluated at all.
.Example
[source,go]
----
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_.
The _dictionary_ data-type is set of pairs _key/value_. It is also known as _map_ or _associative array_. Dictionary literals are sequences of pairs separated by comma `,`; sequences are enclosed between brace brackets.
.List examples
[source,go]
----
{1:"one", 2:"two"}
{"one":1, "two": 2}
{"sum":1+2+3, "prod":1*2*3}
----
WARNING: Support for dictionaries is still ongoing.
The semicolon operator [blue]`;` is an infixed pseudo-operator. It evaluates the left expression first and then the right expression. The latter is the final result.
[blue]`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: [blue]`5 but 2` returns 2, [blue]`x=2*3 but x-1` returns 5.
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
----
=== Selector operator [blue]`? : ::`
The _selector operator_ is very similar to the _switch/case/default_ statement available in many programming languages.
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.
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 [blue]`@` it is possibile to export local definition to the calling context.
=== Function calls
#TODO: function calls operations#
=== Function definitions
#TODO: function definitions operations#
== Builtins
#TODO: builtins#
=== Builtin functions
=== [blue]_import()_
[blue]_import([grey]#<source-file>#)_ loads the multi-expression contained in the specified source and returns its value.