expr/operand-func.go

88 lines
2.1 KiB
Go

// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// operand-func.go
package expr
import (
"errors"
"git.portale-stac.it/go-pkg/expr/kern"
)
// -------- function call term
func newFuncCallTerm(tk *Token, args []*term) *term {
var pos termPosition = posLeaf
if len(args) > 0 {
pos = posMultifix
}
return &term{
tk: *tk,
parent: nil,
children: args,
position: pos,
priority: priValue,
evalFunc: evalFuncCall,
}
}
// -------- eval func call
// func _evalFuncCall(ctx ExprContext, opTerm *term) (v any, err error) {
// name, _ := opTerm.tk.Value.(string)
// params := make([]any, len(opTerm.children), len(opTerm.children)+5)
// for i, tree := range opTerm.children {
// var param any
// if param, err = tree.compute(ctx); err != nil {
// break
// }
// params[i] = param
// }
// if err == nil {
// v, err = CallFunction(ctx, name, params)
// }
// return
// }
func evalFuncCall(ctx kern.ExprContext, opTerm *term) (v any, err error) {
name, _ := opTerm.tk.Value.(string)
v, err = kern.CallFunctionByTerm(ctx, name, opTerm)
return
}
// -------- function definition term
func newFuncDefTerm(tk *Token, args []*term) *term {
return &term{
tk: *tk, // value is the expression body
parent: nil,
children: args, // function params
position: posLeaf,
priority: priValue,
evalFunc: evalFuncDef,
}
}
// -------- eval func def
func evalFuncDef(ctx kern.ExprContext, opTerm *term) (v any, err error) {
bodySpec := opTerm.value()
if ast, ok := bodySpec.(*ast); ok {
paramList := make([]kern.ExprFuncParam, 0, len(opTerm.children))
for _, param := range opTerm.children {
var defValue any
flags := paramFlags(0)
if len(param.children) > 0 {
flags |= PfDefault
if defValue, err = param.children[0].Compute(ctx); err != nil {
return
}
}
info := NewFuncParamFlagDef(param.Source(), flags, defValue)
paramList = append(paramList, info)
}
v = newExprFunctor(ast, paramList, ctx)
} else {
err = errors.New("invalid function definition: the body specification must be an expression")
}
return
}