made some interfaces exportable and fixed/enhaaced some selector operator versions
This commit is contained in:
parent
aa195b9a68
commit
9ac88bf446
18
ast.go
18
ast.go
@ -10,7 +10,8 @@ import (
|
||||
)
|
||||
|
||||
type Expr interface {
|
||||
Eval(ctx exprContext, preset bool) (result any, err error)
|
||||
Eval(ctx ExprContext) (result any, err error)
|
||||
eval(ctx ExprContext, preset bool) (result any, err error)
|
||||
}
|
||||
|
||||
//-------- ast
|
||||
@ -58,15 +59,6 @@ func (self *ast) addToken(tk *Token) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// func (self *ast) addToken(tk *Token) (err error) {
|
||||
// if t := newTerm(tk, nil); t != nil {
|
||||
// err = self.addTerm(t)
|
||||
// } else {
|
||||
// err = tk.Errorf("No term constructor for token %q", tk.String())
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
|
||||
func (self *ast) addToken2(tk *Token) (t *term, err error) {
|
||||
if t = newTerm(tk, nil); t != nil {
|
||||
err = self.addTerm(t)
|
||||
@ -112,7 +104,11 @@ func (self *ast) Finish() {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *ast) Eval(ctx exprContext, preset bool) (result any, err error) {
|
||||
func (self *ast) Eval(ctx ExprContext) (result any, err error) {
|
||||
return self.eval(ctx, true)
|
||||
}
|
||||
|
||||
func (self *ast) eval(ctx ExprContext, preset bool) (result any, err error) {
|
||||
self.Finish()
|
||||
|
||||
if self.root != nil {
|
||||
|
14
context.go
14
context.go
@ -5,23 +5,23 @@
|
||||
package expr
|
||||
|
||||
// ---- Function template
|
||||
type FuncTemplate func(ctx exprContext, name string, args []any) (result any, err error)
|
||||
type FuncTemplate func(ctx ExprContext, name string, args []any) (result any, err error)
|
||||
|
||||
// ---- Functor interface
|
||||
type Functor interface {
|
||||
Invoke(ctx exprContext, name string, args []any) (result any, err error)
|
||||
Invoke(ctx ExprContext, name string, args []any) (result any, err error)
|
||||
}
|
||||
|
||||
type simpleFunctor struct {
|
||||
f FuncTemplate
|
||||
}
|
||||
|
||||
func (functor *simpleFunctor) Invoke(ctx exprContext, name string, args []any) (result any, err error) {
|
||||
func (functor *simpleFunctor) Invoke(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||
return functor.f(ctx, name, args)
|
||||
}
|
||||
|
||||
// ---- Function Info
|
||||
type exprFunc interface {
|
||||
type ExprFunc interface {
|
||||
Name() string
|
||||
MinArgs() int
|
||||
MaxArgs() int
|
||||
@ -29,13 +29,13 @@ type exprFunc interface {
|
||||
}
|
||||
|
||||
// ----Expression Context
|
||||
type exprContext interface {
|
||||
Clone() exprContext
|
||||
type ExprContext interface {
|
||||
Clone() ExprContext
|
||||
GetVar(varName string) (value any, exists bool)
|
||||
SetVar(varName string, value any)
|
||||
EnumVars(func(name string) (accept bool)) (varNames []string)
|
||||
EnumFuncs(func(name string) (accept bool)) (funcNames []string)
|
||||
GetFuncInfo(name string) exprFunc
|
||||
GetFuncInfo(name string) ExprFunc
|
||||
Call(name string, args []any) (result any, err error)
|
||||
RegisterFunc(name string, f Functor, minArgs, maxArgs int)
|
||||
}
|
||||
|
10
control.go
10
control.go
@ -20,12 +20,12 @@ const (
|
||||
init_import_path = "~/.local/lib/go-pkg/expr:/usr/local/lib/go-pkg/expr:/usr/lib/go-pkg/expr"
|
||||
)
|
||||
|
||||
func initDefaultVars(ctx exprContext) {
|
||||
func initDefaultVars(ctx ExprContext) {
|
||||
ctx.SetVar(control_bool_shortcut, true)
|
||||
ctx.SetVar(control_import_path, init_import_path)
|
||||
}
|
||||
|
||||
func enable(ctx exprContext, name string) {
|
||||
func enable(ctx ExprContext, name string) {
|
||||
if strings.HasPrefix(name, "_") {
|
||||
ctx.SetVar(name, true)
|
||||
} else {
|
||||
@ -33,7 +33,7 @@ func enable(ctx exprContext, name string) {
|
||||
}
|
||||
}
|
||||
|
||||
func disable(ctx exprContext, name string) {
|
||||
func disable(ctx ExprContext, name string) {
|
||||
if strings.HasPrefix(name, "_") {
|
||||
ctx.SetVar(name, false)
|
||||
} else {
|
||||
@ -41,7 +41,7 @@ func disable(ctx exprContext, name string) {
|
||||
}
|
||||
}
|
||||
|
||||
func isEnabled(ctx exprContext, name string) (status bool) {
|
||||
func isEnabled(ctx ExprContext, name string) (status bool) {
|
||||
if v, exists := ctx.GetVar(name); exists {
|
||||
if b, ok := v.(bool); ok {
|
||||
status = b
|
||||
@ -50,7 +50,7 @@ func isEnabled(ctx exprContext, name string) (status bool) {
|
||||
return
|
||||
}
|
||||
|
||||
func getControlString(ctx exprContext, name string) (s string, exists bool) {
|
||||
func getControlString(ctx ExprContext, name string) (s string, exists bool) {
|
||||
var v any
|
||||
if v, exists = ctx.GetVar(name); exists {
|
||||
s, exists = v.(string)
|
||||
|
@ -13,16 +13,16 @@ import (
|
||||
|
||||
const ENV_EXPR_PATH = "EXPR_PATH"
|
||||
|
||||
func importFunc(ctx exprContext, name string, args []any) (result any, err error) {
|
||||
func importFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||
return importGeneral(ctx, name, args)
|
||||
}
|
||||
|
||||
func includeFunc(ctx exprContext, name string, args []any) (result any, err error) {
|
||||
func includeFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||
enable(ctx, control_export_all)
|
||||
return importGeneral(ctx, name, args)
|
||||
}
|
||||
|
||||
func importGeneral(ctx exprContext, name string, args []any) (result any, err error) {
|
||||
func importGeneral(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||
var dirList []string
|
||||
|
||||
dirList = addEnvImportDirs(dirList)
|
||||
@ -50,7 +50,7 @@ func addEnvImportDirs(dirList []string) []string {
|
||||
return dirList
|
||||
}
|
||||
|
||||
func addPresetImportDirs(ctx exprContext, dirList []string) []string {
|
||||
func addPresetImportDirs(ctx ExprContext, dirList []string) []string {
|
||||
if dirSpec, exists := getControlString(ctx, control_import_path); exists {
|
||||
dirs := strings.Split(dirSpec, ":")
|
||||
if dirList == nil {
|
||||
@ -96,7 +96,7 @@ func makeFilepath(filename string, dirList []string) (filePath string, err error
|
||||
return
|
||||
}
|
||||
|
||||
func doImport(ctx exprContext, name string, dirList []string, it Iterator) (result any, err error) {
|
||||
func doImport(ctx ExprContext, name string, dirList []string, it Iterator) (result any, err error) {
|
||||
var v any
|
||||
var sourceFilepath string
|
||||
|
||||
@ -114,7 +114,7 @@ func doImport(ctx exprContext, name string, dirList []string, it Iterator) (resu
|
||||
scanner := NewScanner(file, DefaultTranslations())
|
||||
parser := NewParser(ctx)
|
||||
if expr, err = parser.parseGeneral(scanner, true, true); err == nil {
|
||||
result, err = expr.Eval(ctx, false)
|
||||
result, err = expr.eval(ctx, false)
|
||||
}
|
||||
if err != nil {
|
||||
break
|
||||
@ -133,7 +133,7 @@ func doImport(ctx exprContext, name string, dirList []string, it Iterator) (resu
|
||||
return
|
||||
}
|
||||
|
||||
func importImportFunc(ctx exprContext) {
|
||||
func importImportFunc(ctx ExprContext) {
|
||||
ctx.RegisterFunc("import", &simpleFunctor{f: importFunc}, 1, -1)
|
||||
ctx.RegisterFunc("include", &simpleFunctor{f: includeFunc}, 1, -1)
|
||||
}
|
||||
|
10
func-math.go
10
func-math.go
@ -13,7 +13,7 @@ func checkNumberParamExpected(funcName string, paramValue any, paramPos int) (er
|
||||
return
|
||||
}
|
||||
|
||||
func doAdd(ctx exprContext, name string, it Iterator) (result any, err error) {
|
||||
func doAdd(ctx ExprContext, name string, it Iterator) (result any, err error) {
|
||||
var sumAsFloat = false
|
||||
var floatSum float64 = 0.0
|
||||
var intSum int64 = 0
|
||||
@ -52,12 +52,12 @@ func doAdd(ctx exprContext, name string, it Iterator) (result any, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func addFunc(ctx exprContext, name string, args []any) (result any, err error) {
|
||||
func addFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||
result, err = doAdd(ctx, name, NewFlatArrayIterator(args))
|
||||
return
|
||||
}
|
||||
|
||||
func doMul(ctx exprContext, name string, it Iterator) (result any, err error) {
|
||||
func doMul(ctx ExprContext, name string, it Iterator) (result any, err error) {
|
||||
var mulAsFloat = false
|
||||
var floatProd float64 = 1.0
|
||||
var intProd int64 = 1
|
||||
@ -96,12 +96,12 @@ func doMul(ctx exprContext, name string, it Iterator) (result any, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func mulFunc(ctx exprContext, name string, args []any) (result any, err error) {
|
||||
func mulFunc(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||
result, err = doMul(ctx, name, NewFlatArrayIterator(args))
|
||||
return
|
||||
}
|
||||
|
||||
func importMathFuncs(ctx exprContext) {
|
||||
func importMathFuncs(ctx ExprContext) {
|
||||
ctx.RegisterFunc("add", &simpleFunctor{f: addFunc}, 0, -1)
|
||||
ctx.RegisterFunc("mul", &simpleFunctor{f: mulFunc}, 0, -1)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func EvalString(ctx exprContext, source string) (result any, err error) {
|
||||
func EvalString(ctx ExprContext, source string) (result any, err error) {
|
||||
var tree *ast
|
||||
|
||||
r := strings.NewReader(source)
|
||||
@ -14,7 +14,7 @@ func EvalString(ctx exprContext, source string) (result any, err error) {
|
||||
parser := NewParser(ctx)
|
||||
|
||||
if tree, err = parser.Parse(scanner); err == nil {
|
||||
result, err = tree.Eval(ctx, true)
|
||||
result, err = tree.eval(ctx, true)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func subtract(ctx exprContext, name string, args []any) (result any, err error) {
|
||||
func subtract(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||
if len(args) != 2 {
|
||||
err = fmt.Errorf("%s(): requires exactly two arguments", name)
|
||||
return
|
||||
|
@ -61,7 +61,7 @@ func newStringTerm(tk *Token) *term {
|
||||
}
|
||||
|
||||
// -------- eval func
|
||||
func evalConst(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalConst(ctx ExprContext, self *term) (v any, err error) {
|
||||
v = self.tk.Value
|
||||
return
|
||||
}
|
||||
|
@ -21,9 +21,9 @@ func newExprTerm(tk *Token) *term {
|
||||
}
|
||||
|
||||
// -------- eval expr
|
||||
func evalExpr(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalExpr(ctx ExprContext, self *term) (v any, err error) {
|
||||
if expr, ok := self.value().(Expr); ok {
|
||||
v, err = expr.Eval(ctx, false)
|
||||
v, err = expr.eval(ctx, false)
|
||||
} else {
|
||||
err = fmt.Errorf("expression expected, got %T", self.value())
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ func newFuncCallTerm(tk *Token, args []*term) *term {
|
||||
}
|
||||
|
||||
// -------- eval func call
|
||||
func evalFuncCall(parentCtx exprContext, self *term) (v any, err error) {
|
||||
func evalFuncCall(parentCtx ExprContext, self *term) (v any, err error) {
|
||||
ctx := parentCtx.Clone()
|
||||
name, _ := self.tk.Value.(string)
|
||||
params := make([]any, len(self.children))
|
||||
@ -53,14 +53,14 @@ func evalFuncCall(parentCtx exprContext, self *term) (v any, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func exportVar(ctx exprContext, name string, value any) {
|
||||
func exportVar(ctx ExprContext, name string, value any) {
|
||||
if name[0] == '@' {
|
||||
name = name[1:]
|
||||
}
|
||||
ctx.SetVar(name, value)
|
||||
}
|
||||
|
||||
func exportFunc(ctx exprContext, name string, info exprFunc) {
|
||||
func exportFunc(ctx ExprContext, name string, info ExprFunc) {
|
||||
if name[0] == '@' {
|
||||
name = name[1:]
|
||||
}
|
||||
@ -88,7 +88,7 @@ type funcDefFunctor struct {
|
||||
expr Expr
|
||||
}
|
||||
|
||||
func (functor *funcDefFunctor) Invoke(ctx exprContext, name string, args []any) (result any, err error) {
|
||||
func (functor *funcDefFunctor) Invoke(ctx ExprContext, name string, args []any) (result any, err error) {
|
||||
for i, p := range functor.params {
|
||||
if i < len(args) {
|
||||
ctx.SetVar(p, args[i])
|
||||
@ -96,11 +96,11 @@ func (functor *funcDefFunctor) Invoke(ctx exprContext, name string, args []any)
|
||||
ctx.SetVar(p, nil)
|
||||
}
|
||||
}
|
||||
result, err = functor.expr.Eval(ctx, false)
|
||||
result, err = functor.expr.eval(ctx, false)
|
||||
return
|
||||
}
|
||||
|
||||
func evalFuncDef(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalFuncDef(ctx ExprContext, self *term) (v any, err error) {
|
||||
bodySpec := self.value()
|
||||
if expr, ok := bodySpec.(*ast); ok {
|
||||
paramList := make([]string, 0, len(self.children))
|
||||
|
@ -19,7 +19,7 @@ func newListTerm(args []*term) *term {
|
||||
}
|
||||
|
||||
// -------- list func
|
||||
func evalList(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalList(ctx ExprContext, self *term) (v any, err error) {
|
||||
items := make([]any, len(self.children))
|
||||
for i, tree := range self.children {
|
||||
var param any
|
||||
|
@ -28,7 +28,7 @@ func newSelectorCaseTerm(row, col int, filterList *term, caseExpr Expr) *term {
|
||||
}
|
||||
|
||||
// -------- eval selector case
|
||||
func evalSelectorCase(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalSelectorCase(ctx ExprContext, self *term) (v any, err error) {
|
||||
var ok bool
|
||||
if v, ok = self.value().(*selectorCase); !ok {
|
||||
err = fmt.Errorf("selector-case expected, got %T", self.value())
|
||||
|
@ -21,7 +21,7 @@ func newVarTerm(tk *Token) *term {
|
||||
}
|
||||
|
||||
// -------- eval func
|
||||
func evalVar(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalVar(ctx ExprContext, self *term) (v any, err error) {
|
||||
var exists bool
|
||||
if v, exists = ctx.GetVar(self.tk.source); !exists {
|
||||
err = fmt.Errorf("undefined variable %q", self.tk.source)
|
||||
|
@ -18,7 +18,7 @@ func newAssignTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalAssign(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalAssign(ctx ExprContext, self *term) (v any, err error) {
|
||||
if err = self.checkOperands(); err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ func newNotTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalNot(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalNot(ctx ExprContext, self *term) (v any, err error) {
|
||||
var rightValue any
|
||||
|
||||
if rightValue, err = self.evalPrefix(ctx); err != nil {
|
||||
@ -49,7 +49,7 @@ func newAndTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalAnd(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalAnd(ctx ExprContext, self *term) (v any, err error) {
|
||||
if isEnabled(ctx, control_bool_shortcut) {
|
||||
v, err = evalAndWithShortcut(ctx, self)
|
||||
} else {
|
||||
@ -58,7 +58,7 @@ func evalAnd(ctx exprContext, self *term) (v any, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func evalAndWithoutShortcut(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalAndWithoutShortcut(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
var leftBool, rightBool bool
|
||||
var lok, rok bool
|
||||
@ -78,7 +78,7 @@ func evalAndWithoutShortcut(ctx exprContext, self *term) (v any, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func evalAndWithShortcut(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalAndWithShortcut(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if err = self.checkOperands(); err != nil {
|
||||
@ -118,7 +118,7 @@ func newOrTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalOr(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalOr(ctx ExprContext, self *term) (v any, err error) {
|
||||
if isEnabled(ctx, control_bool_shortcut) {
|
||||
v, err = evalOrWithShortcut(ctx, self)
|
||||
} else {
|
||||
@ -127,7 +127,7 @@ func evalOr(ctx exprContext, self *term) (v any, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func evalOrWithoutShortcut(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalOrWithoutShortcut(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
var leftBool, rightBool bool
|
||||
var lok, rok bool
|
||||
@ -147,7 +147,7 @@ func evalOrWithoutShortcut(ctx exprContext, self *term) (v any, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func evalOrWithShortcut(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalOrWithShortcut(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if err = self.checkOperands(); err != nil {
|
||||
|
@ -18,7 +18,7 @@ func newButTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalBut(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalBut(ctx ExprContext, self *term) (v any, err error) {
|
||||
_, v, err = self.evalInfix(ctx)
|
||||
return
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ func newNullCoalesceTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalNullCoalesce(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalNullCoalesce(ctx ExprContext, self *term) (v any, err error) {
|
||||
var rightValue any
|
||||
|
||||
if err = self.checkOperands(); err != nil {
|
||||
@ -57,7 +57,7 @@ func newCoalesceAssignTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalAssignCoalesce(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalAssignCoalesce(ctx ExprContext, self *term) (v any, err error) {
|
||||
var rightValue any
|
||||
|
||||
if err = self.checkOperands(); err != nil {
|
||||
|
@ -18,7 +18,7 @@ func newExportAllTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalExportAll(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalExportAll(ctx ExprContext, self *term) (v any, err error) {
|
||||
enable(ctx, control_export_all)
|
||||
return
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ func newFactTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalFact(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalFact(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue any
|
||||
|
||||
if leftValue, err = self.evalPrefix(ctx); err != nil {
|
||||
|
@ -23,7 +23,7 @@ func newMultiplyTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalMultiply(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalMultiply(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
||||
@ -62,7 +62,7 @@ func newDivideTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalDivide(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalDivide(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
||||
@ -105,7 +105,7 @@ func newDivideAsFloatTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalDivideAsFloat(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalDivideAsFloat(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
||||
@ -139,7 +139,7 @@ func newReminderTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalReminder(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalReminder(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
||||
|
@ -18,7 +18,7 @@ func newEqualTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalEqual(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalEqual(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
||||
@ -57,7 +57,7 @@ func newNotEqualTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalNotEqual(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalNotEqual(ctx ExprContext, self *term) (v any, err error) {
|
||||
if v, err = evalEqual(ctx, self); err == nil {
|
||||
b, _ := toBool(v)
|
||||
v = !b
|
||||
@ -104,7 +104,7 @@ func newLessTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalLess(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalLess(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
||||
@ -143,7 +143,7 @@ func newLessEqualTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalLessEqual(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalLessEqual(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
||||
@ -182,7 +182,7 @@ func newGreaterTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalGreater(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalGreater(ctx ExprContext, self *term) (v any, err error) {
|
||||
if v, err = evalLessEqual(ctx, self); err == nil {
|
||||
b, _ := toBool(v)
|
||||
v = !b
|
||||
@ -204,7 +204,7 @@ func newGreaterEqualTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalGreaterEqual(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalGreaterEqual(ctx ExprContext, self *term) (v any, err error) {
|
||||
if v, err = evalLess(ctx, self); err == nil {
|
||||
b, _ := toBool(v)
|
||||
v = !b
|
||||
|
@ -18,19 +18,19 @@ func newSelectorTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func isSelectorCase(ctx exprContext, exprValue, caseSel any, caseIndex int) (selectedValue any, err error) {
|
||||
func isSelectorCase(ctx ExprContext, exprValue, caseSel any, caseIndex int) (selectedValue any, err error) {
|
||||
caseData, _ := caseSel.(*selectorCase)
|
||||
if caseData.filterList == nil {
|
||||
selectedValue, err = caseData.caseExpr.Eval(ctx, false)
|
||||
selectedValue, err = caseData.caseExpr.eval(ctx, false)
|
||||
} else {
|
||||
filterList := caseData.filterList.children
|
||||
if len(filterList) == 0 && exprValue == int64(caseIndex) {
|
||||
selectedValue, err = caseData.caseExpr.Eval(ctx, false)
|
||||
selectedValue, err = caseData.caseExpr.eval(ctx, false)
|
||||
} else {
|
||||
var caseValue any
|
||||
for _, caseTerm := range filterList {
|
||||
if caseValue, err = caseTerm.compute(ctx); err != nil || caseValue == exprValue {
|
||||
selectedValue, err = caseData.caseExpr.Eval(ctx, false)
|
||||
selectedValue, err = caseData.caseExpr.eval(ctx, false)
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -39,7 +39,7 @@ func isSelectorCase(ctx exprContext, exprValue, caseSel any, caseIndex int) (sel
|
||||
return
|
||||
}
|
||||
|
||||
func evalSelector(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalSelector(ctx ExprContext, self *term) (v any, err error) {
|
||||
var exprValue any
|
||||
// var caseList []*term
|
||||
|
||||
|
@ -30,7 +30,7 @@ func newMinusSignTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalSign(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalSign(ctx ExprContext, self *term) (v any, err error) {
|
||||
var rightValue any
|
||||
|
||||
if rightValue, err = self.evalPrefix(ctx); err != nil {
|
||||
|
@ -23,7 +23,7 @@ func newPlusTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalPlus(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalPlus(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
||||
@ -77,7 +77,7 @@ func newMinusTerm(tk *Token) (inst *term) {
|
||||
}
|
||||
}
|
||||
|
||||
func evalMinus(ctx exprContext, self *term) (v any, err error) {
|
||||
func evalMinus(ctx ExprContext, self *term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
||||
|
11
parser.go
11
parser.go
@ -12,10 +12,10 @@ import (
|
||||
//-------- parser
|
||||
|
||||
type parser struct {
|
||||
ctx exprContext
|
||||
ctx ExprContext
|
||||
}
|
||||
|
||||
func NewParser(ctx exprContext) (p *parser) {
|
||||
func NewParser(ctx ExprContext) (p *parser) {
|
||||
p = &parser{
|
||||
ctx: ctx,
|
||||
}
|
||||
@ -246,9 +246,9 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
|
||||
currentTerm, err = tree.addToken2(tk)
|
||||
}
|
||||
case SymQuestion:
|
||||
if selectorTerm != nil {
|
||||
/*if selectorTerm != nil {
|
||||
err = tk.Errorf("nested selectors must be enclosed in parentheses")
|
||||
} else if selectorTerm, err = self.parseSelector(scanner, tree, allowVarRef); err == nil {
|
||||
} else*/if selectorTerm, err = self.parseSelector(scanner, tree, allowVarRef); err == nil {
|
||||
currentTerm = selectorTerm
|
||||
}
|
||||
case SymColon, SymDoubleColon:
|
||||
@ -259,6 +259,9 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
|
||||
selectorTerm.children = append(selectorTerm.children, caseTerm)
|
||||
caseTerm.parent = selectorTerm
|
||||
currentTerm = caseTerm
|
||||
if tk.Sym == SymDoubleColon {
|
||||
selectorTerm = nil
|
||||
}
|
||||
}
|
||||
//resetSelector = tk.Sym == SymDoubleColon
|
||||
default:
|
||||
|
@ -153,6 +153,8 @@ func TestParser(t *testing.T) {
|
||||
/* 132 */ {`10 ? {"a"} :[10] {x="b" but x} :: {"c"}`, "b", nil},
|
||||
/* 133 */ {`10 ? {"a"} :[10] {x="b"; x} :: {"c"}`, "b", nil},
|
||||
/* 134 */ {`10 ? {"a"} : {"b"}`, nil, errors.New(`[1:3] no case catches the value (10) of the selection expression`)},
|
||||
/* 135 */ {`10 ? {"a"} :: {"b"} : {"c"}`, nil, errors.New(`[1:22] selector-case outside of a selector context`)},
|
||||
/* 136 */ {`1 ? {"a"} : {"b"} ? ["a"] {"A"} :["b"] {"B"}`, "B", nil},
|
||||
}
|
||||
check_env_expr_path := 113
|
||||
|
||||
@ -160,11 +162,11 @@ func TestParser(t *testing.T) {
|
||||
failed := 0
|
||||
|
||||
// inputs1 := []inputType{
|
||||
// {`1 ? {"a"} : {"b"}`, "b", nil},
|
||||
// {`1 ? {"a"} : {"b"} ? ["a"] {"A"} :["b"] {"B"}`, "B", nil},
|
||||
// }
|
||||
|
||||
for i, input := range inputs {
|
||||
var expr *ast
|
||||
var expr Expr
|
||||
var gotResult any
|
||||
var gotErr error
|
||||
|
||||
@ -182,7 +184,7 @@ func TestParser(t *testing.T) {
|
||||
|
||||
good := true
|
||||
if expr, gotErr = parser.Parse(scanner); gotErr == nil {
|
||||
gotResult, gotErr = expr.Eval(ctx, true)
|
||||
gotResult, gotErr = expr.Eval(ctx)
|
||||
}
|
||||
|
||||
if gotResult != input.wantResult {
|
||||
@ -209,7 +211,7 @@ func TestParser(t *testing.T) {
|
||||
t.Log(fmt.Sprintf("test count: %d, succeeded count: %d, failed count: %d", len(inputs), succeeded, failed))
|
||||
}
|
||||
|
||||
func NoTestListParser(t *testing.T) {
|
||||
func TestListParser(t *testing.T) {
|
||||
type inputType struct {
|
||||
source string
|
||||
wantResult any
|
||||
@ -257,7 +259,7 @@ func NoTestListParser(t *testing.T) {
|
||||
|
||||
good := true
|
||||
if expr, gotErr = parser.Parse(scanner); gotErr == nil {
|
||||
gotResult, gotErr = expr.Eval(ctx, true)
|
||||
gotResult, gotErr = expr.Eval(ctx)
|
||||
}
|
||||
|
||||
if (gotResult == nil && input.wantResult != nil) || (gotResult != nil && input.wantResult == nil) {
|
||||
|
@ -38,14 +38,14 @@ func NewSimpleFuncStore() *SimpleFuncStore {
|
||||
}
|
||||
}
|
||||
|
||||
func (ctx *SimpleFuncStore) Clone() exprContext {
|
||||
func (ctx *SimpleFuncStore) Clone() ExprContext {
|
||||
return &SimpleFuncStore{
|
||||
SimpleVarStore: SimpleVarStore{varStore: CloneMap(ctx.varStore)},
|
||||
funcStore: CloneMap(ctx.funcStore),
|
||||
}
|
||||
}
|
||||
|
||||
func (ctx *SimpleFuncStore) GetFuncInfo(name string) (info exprFunc) {
|
||||
func (ctx *SimpleFuncStore) GetFuncInfo(name string) (info ExprFunc) {
|
||||
info, _ = ctx.funcStore[name]
|
||||
return
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ func NewSimpleVarStore() *SimpleVarStore {
|
||||
}
|
||||
}
|
||||
|
||||
func (ctx *SimpleVarStore) Clone() (clone exprContext) {
|
||||
func (ctx *SimpleVarStore) Clone() (clone ExprContext) {
|
||||
clone = &SimpleVarStore{
|
||||
varStore: CloneMap(ctx.varStore),
|
||||
}
|
||||
@ -41,7 +41,7 @@ func (ctx *SimpleVarStore) EnumVars(acceptor func(name string) (accept bool)) (v
|
||||
return
|
||||
}
|
||||
|
||||
func (ctx *SimpleVarStore) GetFuncInfo(name string) (f exprFunc) {
|
||||
func (ctx *SimpleVarStore) GetFuncInfo(name string) (f ExprFunc) {
|
||||
return
|
||||
}
|
||||
|
||||
|
8
term.go
8
term.go
@ -58,7 +58,7 @@ const (
|
||||
posMultifix
|
||||
)
|
||||
|
||||
type evalFuncType func(ctx exprContext, self *term) (v any, err error)
|
||||
type evalFuncType func(ctx ExprContext, self *term) (v any, err error)
|
||||
|
||||
// type iterm interface {
|
||||
// getClass() termClass
|
||||
@ -167,7 +167,7 @@ func (self *term) value() any {
|
||||
return self.tk.Value
|
||||
}
|
||||
|
||||
func (self *term) compute(ctx exprContext) (v any, err error) {
|
||||
func (self *term) compute(ctx ExprContext) (v any, err error) {
|
||||
if self.evalFunc == nil {
|
||||
err = self.tk.Errorf("undefined eval-func for %v term type", self.kind)
|
||||
} else {
|
||||
@ -225,7 +225,7 @@ func (self *term) anyChildrenNil() bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func (self *term) evalInfix(ctx exprContext) (leftValue, rightValue any, err error) {
|
||||
func (self *term) evalInfix(ctx ExprContext) (leftValue, rightValue any, err error) {
|
||||
if err = self.checkOperands(); err == nil {
|
||||
if leftValue, err = self.children[0].compute(ctx); err == nil {
|
||||
rightValue, err = self.children[1].compute(ctx)
|
||||
@ -234,7 +234,7 @@ func (self *term) evalInfix(ctx exprContext) (leftValue, rightValue any, err err
|
||||
return
|
||||
}
|
||||
|
||||
func (self *term) evalPrefix(ctx exprContext) (rightValue any, err error) {
|
||||
func (self *term) evalPrefix(ctx ExprContext) (rightValue any, err error) {
|
||||
if err = self.checkOperands(); err == nil {
|
||||
rightValue, err = self.children[0].compute(ctx)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user