GO package for analysis and calculation of expressions
This feature is implemented by expansion, not by dedicated operators, e.g. a*=2+x is exapanded as a=a*(2+x) |
||
---|---|---|
doc | ||
test-resources | ||
tools | ||
ast.go | ||
bind-expr-functions.go | ||
bind-go-functions.go | ||
builtin-base.go | ||
builtin-fmt.go | ||
builtin-import.go | ||
builtin-iterator.go | ||
builtin-math-arith.go | ||
builtin-os-file.go | ||
builtin-string.go | ||
builtins-register.go | ||
byte-slider.go | ||
common-errors.go | ||
common-params.go | ||
common-type-names.go | ||
context-helpers.go | ||
control.go | ||
data-cursor.go | ||
dict-type.go | ||
expr-context.go | ||
expr-function.go | ||
expr.go | ||
formatter.go | ||
fraction-type.go | ||
function.go | ||
global-context.go | ||
go.mod | ||
graph.go | ||
helpers.go | ||
import-utils.go | ||
it-range.go.unused | ||
iterator.go | ||
list-iterator.go | ||
list-type.go | ||
operand-dict.go | ||
operand-expr.go | ||
operand-func.go | ||
operand-iterator.go | ||
operand-list.go | ||
operand-literal.go | ||
operand-selector-case.go | ||
operand-var.go | ||
operator-assign.go | ||
operator-bool.go | ||
operator-builtin.go | ||
operator-but.go | ||
operator-context.go | ||
operator-ctrl.go | ||
operator-default.go | ||
operator-dot.go | ||
operator-fact.go | ||
operator-fraction.go | ||
operator-in.go | ||
operator-include.go | ||
operator-index.go | ||
operator-insert.go | ||
operator-iter-value.go | ||
operator-length.go | ||
operator-plugin.go | ||
operator-post-inc.go | ||
operator-prod.go | ||
operator-range.go | ||
operator-rel.go | ||
operator-selector.go | ||
operator-sign.go | ||
operator-sum.go | ||
operator-unset.go | ||
parser.go | ||
plugins.go | ||
README.adoc | ||
scanner.go | ||
simple-store.go | ||
symbol.go | ||
t_ast_test.go | ||
t_bool_test.go | ||
t_builtin-base_test.go | ||
t_builtin-fmt_test.go | ||
t_builtin-import_test.go | ||
t_builtin-iterator_test.go | ||
t_builtin-math-arith_test.go | ||
t_builtin-os-file_test.go | ||
t_builtin-string_test.go | ||
t_common_test.go | ||
t_dict_test.go | ||
t_expr_test.go | ||
t_fractions_test.go | ||
t_funcs_test.go | ||
t_graph_test.go | ||
t_helpers_test.go | ||
t_index_test.go | ||
t_iter-list_test.go | ||
t_iterator_test.go | ||
t_list_test.go | ||
t_module-register_test.go | ||
t_operator_test.go | ||
t_parser_test.go | ||
t_plugin_test.go | ||
t_relational_test.go | ||
t_scanner_test.go | ||
t_strings_test.go | ||
t_template_test.go | ||
t_term_test.go | ||
t_token_test.go | ||
t_utils_test.go | ||
term-constuctor-registry.go | ||
term.go | ||
test-file.txt | ||
token.go | ||
utils.go |
README
Table of Contents
1. Expr
Expr is a GO package capable of analysing, interpreting and calculating expressions.
A few examples to get started.
Examples taken from parser_test.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 | 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. |
1.1. Usage
package main
import (
"fmt"
"strings"
"git.portale-stac.it/go-pkg/expr"
)
func main() {
ctx := expr.NewSimpleVarStore()
ctx.SetVar("var", 4)
source := `(3-1)*(10/5) == var`
r := strings.NewReader(source)
scanner := expr.NewScanner(r, expr.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.
package main
import (
"fmt"
"git.portale-stac.it/go-pkg/expr"
)
func main() {
ctx := expr.NewSimpleVarStore()
ctx.SetVar("var", 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)
}
}
Here is another equivalent version.
package main
import (
"fmt"
"git.portale-stac.it/go-pkg/expr"
)
func main() {
source := `(3-1)*(10/5) == var`
if result, err := expr.EvalStringA(source, expr.Arg{"var", 4}); err == nil {
fmt.Printf("%q -> %v [%T]\n", source, result, result)
} else {
fmt.Println("Error calculating the expression:", err)
}
}
2. Context of evaluation
Unless helpers functions like expr.EvalStringA() are used, a context is required to compute an expession.
A context is an object that implements the expr.ExprContext interface. This interface specifies a set of function to handle variables and functions.
Variables and functions can be added to a context both programmatically and ad an effect of the expression computation.
3. Expressions syntax
See TODO link to doc/Expr.html