2024-04-14 08:16:01 +02:00
|
|
|
= README
|
|
|
|
README about the Expressions calculator
|
2024-03-26 07:36:12 +01:00
|
|
|
: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.
|
|
|
|
|
2024-04-08 23:14:25 +02:00
|
|
|
A few examples to get started.
|
|
|
|
|
2024-04-02 08:18:34 +02:00
|
|
|
.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_.
|
|
|
|
|
|
|
|
|
2024-03-27 08:44:47 +01:00
|
|
|
=== Usage
|
|
|
|
|
|
|
|
|
|
|
|
[source,go]
|
|
|
|
----
|
2024-04-09 05:42:50 +02:00
|
|
|
package main
|
|
|
|
|
2024-03-27 08:44:47 +01:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
"git.portale-stac.it/go-pkg/expr"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
ctx := expr.NewSimpleVarStore()
|
2024-04-09 07:09:23 +02:00
|
|
|
ctx.SetVar("var", 4)
|
2024-03-27 08:44:47 +01:00
|
|
|
|
|
|
|
source := `(3-1)*(10/5) == var`
|
|
|
|
|
2024-04-09 06:29:44 +02:00
|
|
|
r := strings.NewReader(source)
|
|
|
|
scanner := expr.NewScanner(r, expr.DefaultTranslations())
|
2024-03-27 08:44:47 +01:00
|
|
|
parser := expr.NewParser(ctx)
|
|
|
|
|
2024-04-08 23:14:25 +02:00
|
|
|
if ast, err := parser.Parse(scanner); err == nil {
|
|
|
|
if result, err := ast.Eval(ctx); err == nil {
|
2024-04-09 06:29:44 +02:00
|
|
|
fmt.Printf("%q -> %v [%T]\n", source, result, result)
|
|
|
|
} else {
|
|
|
|
fmt.Println("Error calculating the expression:", err)
|
|
|
|
}
|
2024-03-27 08:44:47 +01:00
|
|
|
} else {
|
2024-04-09 06:29:44 +02:00
|
|
|
fmt.Println("Error parsing the expression:", err)
|
|
|
|
}
|
2024-03-27 08:44:47 +01:00
|
|
|
}
|
|
|
|
----
|
2024-04-09 06:29:44 +02:00
|
|
|
|
2024-03-27 08:44:47 +01:00
|
|
|
The above program is equivalent to the following one.
|
|
|
|
|
|
|
|
[source,go]
|
|
|
|
----
|
2024-04-09 06:29:44 +02:00
|
|
|
package main
|
|
|
|
|
2024-03-27 08:44:47 +01:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"git.portale-stac.it/go-pkg/expr"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
ctx := expr.NewSimpleVarStore()
|
2024-04-09 07:09:23 +02:00
|
|
|
ctx.SetVar("var", 4)
|
2024-03-27 08:44:47 +01:00
|
|
|
|
|
|
|
source := `(3-1)*(10/5) == var`
|
|
|
|
|
2024-04-09 06:29:44 +02:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
|
|
|
Here is another equivalent version.
|
|
|
|
|
|
|
|
[source,go]
|
|
|
|
----
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"git.portale-stac.it/go-pkg/expr"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
source := `(3-1)*(10/5) == var`
|
|
|
|
|
2024-04-09 07:09:23 +02:00
|
|
|
if result, err := expr.EvalStringA(source, expr.Arg{"var", 4}); err == nil {
|
2024-04-09 06:29:44 +02:00
|
|
|
fmt.Printf("%q -> %v [%T]\n", source, result, result)
|
|
|
|
} else {
|
|
|
|
fmt.Println("Error calculating the expression:", err)
|
|
|
|
}
|
2024-03-27 08:44:47 +01:00
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2024-04-14 08:16:01 +02:00
|
|
|
== Context of evaluation
|
|
|
|
Unless helpers functions like _expr.EvalStringA()_ are used, a _context_ is required to compute an expession.
|
2024-04-09 09:11:47 +02:00
|
|
|
|
2024-04-14 08:16:01 +02:00
|
|
|
A context is an object that implements the _expr.ExprContext_ interface. This interface specifies a set of function to handle variables and functions.
|
2024-04-09 09:11:47 +02:00
|
|
|
|
2024-04-14 08:16:01 +02:00
|
|
|
Variables and functions can be added to a context both programmatically and ad an effect of the expression computation.
|
2024-04-03 06:23:45 +02:00
|
|
|
|
2024-04-14 08:16:01 +02:00
|
|
|
== Expressions syntax
|
2024-04-03 06:23:45 +02:00
|
|
|
|
2024-04-14 08:16:01 +02:00
|
|
|
See #TODO link to doc/Expr.html#
|