Variable references belonging to the parent scope added ('@')

This commit is contained in:
2024-04-04 12:54:26 +02:00
parent 8c3254a8f2
commit d073d11ad3
8 changed files with 94 additions and 36 deletions
+17 -12
View File
@@ -6,7 +6,6 @@ package expr
import (
"errors"
"fmt"
)
// -------- function call term
@@ -24,7 +23,8 @@ func newFuncCallTerm(tk *Token, args []*term) *term {
}
// -------- eval func call
func evalFuncCall(ctx 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))
for i, tree := range self.children {
@@ -35,7 +35,12 @@ func evalFuncCall(ctx exprContext, self *term) (v any, err error) {
params[i] = param
}
if err == nil {
v, err = ctx.Call(name, params)
if v, err = ctx.Call(name, params); err == nil {
for _, refName := range ctx.EnumVars(func(name string) bool { return name[0] == '@' }) {
refValue, _ := ctx.GetVar(refName)
parentCtx.SetVar(refName[1:], refValue)
}
}
}
return
}
@@ -61,8 +66,7 @@ type funcDefFunctor struct {
expr Expr
}
func (functor *funcDefFunctor) Invoke(parentCtx exprContext, name string, args []any) (result any, err error) {
ctx := parentCtx.Clone()
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])
@@ -78,13 +82,14 @@ 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))
for i, param := range self.children {
if paramName, ok := param.value().(string); ok {
paramList = append(paramList, paramName)
} else {
err = fmt.Errorf("invalid function definition: formal param nr %d must be an identifiers", i+1)
break
}
for _, param := range self.children {
paramList = append(paramList, param.source())
// if paramName, ok := param.value().(string); ok {
// paramList = append(paramList, paramName)
// } else {
// err = fmt.Errorf("invalid function definition: formal param nr %d must be an identifier", i+1)
// break
// }
}
v = &funcDefFunctor{
params: paramList,