Compare commits

...

3 Commits

Author SHA1 Message Date
camoroso a9b143d012 README.adoc: example programs updated 2024-04-09 06:29:44 +02:00
camoroso 024ff42be0 Arg struct members are now exported 2024-04-09 06:28:57 +02:00
camoroso 8ab2c28343 EvalArg -> Arg 2024-04-09 06:13:12 +02:00
3 changed files with 60 additions and 35 deletions
+41 -16
View File
@@ -63,35 +63,37 @@ package main
import ( import (
"fmt" "fmt"
"strings" "strings"
"git.portale-stac.it/go-pkg/expr" "git.portale-stac.it/go-pkg/expr"
) )
func main() { func main() {
ctx := expr.NewSimpleVarStore() ctx := expr.NewSimpleVarStore()
ctx.SetValue("var", int64(4)) ctx.SetVar("var", int64(4))
source := `(3-1)*(10/5) == var` source := `(3-1)*(10/5) == var`
r := strings.NewReader(source) r := strings.NewReader(source)
scanner := expr.NewScanner(r, DefaultTranslations()) scanner := expr.NewScanner(r, expr.DefaultTranslations())
parser := expr.NewParser(ctx) parser := expr.NewParser(ctx)
if ast, err := parser.Parse(scanner); err == nil { if ast, err := parser.Parse(scanner); err == nil {
if result, err := ast.Eval(ctx); err == nil { if result, err := ast.Eval(ctx); err == nil {
fmt.Printf("%q -> %v [%T]\n", source, result, result) fmt.Printf("%q -> %v [%T]\n", source, result, result)
} else { } else {
fmt.Println("Error calculating the expression:", err) fmt.Println("Error calculating the expression:", err)
} }
} else { } else {
fmt.Println("Error parsing the expression:", err) fmt.Println("Error parsing the expression:", err)
} }
} }
---- ----
The above program is equivalent to the following one. The above program is equivalent to the following one.
[source,go] [source,go]
---- ----
package main
import ( import (
"fmt" "fmt"
"git.portale-stac.it/go-pkg/expr" "git.portale-stac.it/go-pkg/expr"
@@ -99,15 +101,38 @@ import (
func main() { func main() {
ctx := expr.NewSimpleVarStore() ctx := expr.NewSimpleVarStore()
ctx.SetValue("var", int64(4)) ctx.SetVar("var", int64(4))
source := `(3-1)*(10/5) == var` source := `(3-1)*(10/5) == var`
if result, err := expr.EvalString(ctx, source); err == nil { if result, err := expr.EvalString(ctx, source); err == nil {
fmt.Printf("%q -> %v [%T]\n", source, result, result) fmt.Printf("%q -> %v [%T]\n", source, result, result)
} else { } else {
fmt.Println("Error calculating the expression:", err) 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`
if result, err := expr.EvalStringA(source, expr.Arg{"var", int64(4)}); err == nil {
fmt.Printf("%q -> %v [%T]\n", source, result, result)
} else {
fmt.Println("Error calculating the expression:", err)
}
} }
---- ----
+18 -18
View File
@@ -19,35 +19,35 @@ func EvalString(ctx ExprContext, source string) (result any, err error) {
return return
} }
type EvalArg struct { type Arg struct {
name string Name string
value any Value any
} }
func EvalStringA(source string, args ...EvalArg) (result any, err error) { func EvalStringA(source string, args ...Arg) (result any, err error) {
return EvalStringV(source, args) return EvalStringV(source, args)
} }
func EvalStringV(source string, args []EvalArg) (result any, err error) { func EvalStringV(source string, args []Arg) (result any, err error) {
ctx := NewSimpleFuncStore() ctx := NewSimpleFuncStore()
for _, arg := range args { for _, arg := range args {
if isFunc(arg.value) { if isFunc(arg.Value) {
if f, ok := arg.value.(FuncTemplate); ok { if f, ok := arg.Value.(FuncTemplate); ok {
functor := &simpleFunctor{f: f} functor := &simpleFunctor{f: f}
ctx.RegisterFunc(arg.name, functor, 0, -1) ctx.RegisterFunc(arg.Name, functor, 0, -1)
} else { } else {
err = fmt.Errorf("invalid function specification: %q", arg.name) err = fmt.Errorf("invalid function specification: %q", arg.Name)
} }
} else if integer, ok := anyInteger(arg.value); ok { } else if integer, ok := anyInteger(arg.Value); ok {
ctx.SetVar(arg.name, integer) ctx.SetVar(arg.Name, integer)
} else if float, ok := anyFloat(arg.value); ok { } else if float, ok := anyFloat(arg.Value); ok {
ctx.SetVar(arg.name, float) ctx.SetVar(arg.Name, float)
} else if _, ok := arg.value.(string); ok { } else if _, ok := arg.Value.(string); ok {
ctx.SetVar(arg.name, arg.value) ctx.SetVar(arg.Name, arg.Value)
} else if _, ok := arg.value.(bool); ok { } else if _, ok := arg.Value.(bool); ok {
ctx.SetVar(arg.name, arg.value) ctx.SetVar(arg.Name, arg.Value)
} else { } else {
err = fmt.Errorf("unsupported type %T specified for item %q", arg.value, arg.name) err = fmt.Errorf("unsupported type %T specified for item %q", arg.Value, arg.Name)
} }
} }
+1 -1
View File
@@ -24,7 +24,7 @@ func subtract(ctx ExprContext, name string, args []any) (result any, err error)
func TestEvalStringA(t *testing.T) { func TestEvalStringA(t *testing.T) {
source := `a + b * subtract(4,2)` source := `a + b * subtract(4,2)`
args := []EvalArg{ args := []Arg{
{"a", uint8(1)}, {"a", uint8(1)},
{"b", int8(2)}, {"b", int8(2)},
{"subtract", FuncTemplate(subtract)}, {"subtract", FuncTemplate(subtract)},