172 lines
5.5 KiB
Plaintext
172 lines
5.5 KiB
Plaintext
= Expr
|
|
Expressions calculator
|
|
:authors: Celestino Amoroso
|
|
:docinfo: shared
|
|
:encoding: utf-8
|
|
:toc: right
|
|
:toclevels: 4
|
|
//:toc-title: Indice Generale
|
|
:icons: font
|
|
:icon-set: fi
|
|
:numbered:
|
|
//:table-caption: Tabella
|
|
//:figure-caption: Diagramma
|
|
:docinfo1:
|
|
:sectlinks:
|
|
:sectanchors:
|
|
:source-highlighter: rouge
|
|
// :rouge-style: ThankfulEyes
|
|
:rouge-style: gruvbox
|
|
// :rouge-style: colorful
|
|
//:rouge-style: monokay
|
|
|
|
toc::[]
|
|
|
|
== Expr
|
|
_Expr_ is a GO package capable of analysing, interpreting and calculating expressions.
|
|
|
|
.Examples taken from parser_test.go
|
|
[source,go]
|
|
----
|
|
`1.0 / 2` // 0.5
|
|
`435 + 105 * 2 - 1` // 644
|
|
`4 == (3-1)*(10/5)` // true
|
|
`"uno" * (2+1)` // `unounouno`
|
|
`2+3 but 5*2` // 10 <1>
|
|
`add(add(1+4),3+2,5*(3-2))` // 15 <2>
|
|
`a=5; b=2; add(a, b*3)` // 11 <3>
|
|
`two=func(){2}; two()` // 2 <4>
|
|
`double=func(x){2*x}; a=4+1; two=func() {2}; (double(3+a) + 1) * two()` // 34
|
|
`import("./test-funcs.expr"); (double(3+a) + 1) * two()` // 34 <5>
|
|
`[1,2,"hello"]` // Mixed types list
|
|
`[1,2]+[3]` // append list, result: [1,2,3]
|
|
`add([1,[2,2],3,2])` // Deep list sum, result: 10 <2>
|
|
`[a=1,b=2,c=3] but a+b+c` // 6
|
|
----
|
|
|
|
<1> [blue]`but` operator.
|
|
<2> The _add()_ function definition may be changed in the future.
|
|
<3> Multiple expression. Only the last expression value will returned.
|
|
<4> Simple function definition: _two()_ returns 2.
|
|
<5> _import()_ function imports expressions from the specified files. See file _test-funcs.expr_.
|
|
|
|
|
|
=== Usage
|
|
|
|
|
|
[source,go]
|
|
----
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"git.portale-stac.it/go-pkg/expr"
|
|
)
|
|
|
|
func main() {
|
|
ctx := expr.NewSimpleVarStore()
|
|
ctx.SetValue("var", int64(4))
|
|
|
|
source := `(3-1)*(10/5) == var`
|
|
|
|
r := strings.NewReader(source)
|
|
scanner := expr.NewScanner(r, DefaultTranslations())
|
|
parser := expr.NewParser(ctx)
|
|
|
|
if ast, err := parser.parse(scanner); err == nil {
|
|
if result, err := ast.eval(ctx); err == nil {
|
|
fmt.Printf("%q -> %v [%T]\n", source, result, result)
|
|
} else {
|
|
fmt.Println("Error calculating the expression:", err)
|
|
}
|
|
} else {
|
|
fmt.Println("Error parsing the expression:", err)
|
|
}
|
|
}
|
|
----
|
|
The above program is equivalent to the following one.
|
|
|
|
[source,go]
|
|
----
|
|
import (
|
|
"fmt"
|
|
"git.portale-stac.it/go-pkg/expr"
|
|
)
|
|
|
|
func main() {
|
|
ctx := expr.NewSimpleVarStore()
|
|
ctx.SetValue("var", int64(4))
|
|
|
|
source := `(3-1)*(10/5) == var`
|
|
|
|
if result, err := expr.evalString(ctx, source); err == nil {
|
|
fmt.Printf("%q -> %v [%T]\n", source, result, result)
|
|
} else {
|
|
fmt.Println("Error calculating the expression:", err)
|
|
}
|
|
}
|
|
----
|
|
|
|
=== Data types
|
|
_Expr_ supports numerical, string, relational, boolean expressions, and mixed-type lists.
|
|
|
|
==== Numbers
|
|
Numbers can be integers (GO int64) and 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]_, [blue]`-(+2)` _[-2]_
|
|
|
|
| [blue]`+` | _sum_ | Add two values | [blue]`-1 + 2` _[1]_, [blue]`4 + 0.5` _[4.5]_
|
|
|
|
| [blue]`-` | _subtracion_ | Subtract the right value from the left one | [blue]`3 - 1` _[2]_, [blue]`4 - 0.5` _[3.5]_
|
|
|
|
| [blue]`*` | _product_ | Multiply two values | `-1 * 2` _[-2]_, [blue]`4 * 0.5` _[2.0]_
|
|
|
|
| [blue]`/` | _Division_ | Divide the left value by the right one | [blue]`-1 / 2` _[0]_, [blue]`1.0 / 2` _[0.5]_
|
|
|
|
| [blue]`./` | _Float division_ | Force float division | [blue]`-1 ./ 2` _[-0.5]_
|
|
|
|
| [blue]`%` | _Modulo_ | Remainder of the integer division | [blue]`5 % 2` _[1]_
|
|
|
|
|===
|
|
|
|
==== String
|
|
Strings are character sequences enclosed between two double quote [blue]`"`. Example: [blue]`"I'm a string"`.
|
|
|
|
Some arithmetic operators can also be used with strings.
|
|
|
|
|
|
==== Boolean
|
|
Boolean data type has two values only: _true_ and _false_. Relational and Boolean expressions produce a 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,6,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]_
|
|
|===
|