func (v *evalConcat) Eval(s ast.Scope, stack *ast.Stack) (interface{}, ast.Type, error) { // The expressions should all be on the stack in reverse // order. So pop them off, reverse their order, and concatenate. nodes := make([]*ast.LiteralNode, 0, len(v.Exprs)) for range v.Exprs { nodes = append(nodes, stack.Pop().(*ast.LiteralNode)) } var buf bytes.Buffer for i := len(nodes) - 1; i >= 0; i-- { buf.WriteString(nodes[i].Value.(string)) } return buf.String(), ast.TypeString, nil }
func (v *evalCall) Eval(s ast.Scope, stack *ast.Stack) (interface{}, ast.Type, error) { // Look up the function in the map function, ok := s.LookupFunc(v.Func) if !ok { return nil, ast.TypeInvalid, fmt.Errorf( "unknown function called: %s", v.Func) } // The arguments are on the stack in reverse order, so pop them off. args := make([]interface{}, len(v.Args)) for i, _ := range v.Args { node := stack.Pop().(*ast.LiteralNode) args[len(v.Args)-1-i] = node.Value } // Call the function result, err := function.Callback(args) if err != nil { return nil, ast.TypeInvalid, fmt.Errorf("%s: %s", v.Func, err) } return result, function.ReturnType, nil }