Documentation
¶
Index ¶
- Variables
- func CallLambda(ctx context.Context, val any, args []any, start time.Time, depth int) (any, error)
- func NewDebugContext(ctx context.Context) (context.Context, *[]DebugEntry)deprecated
- func ToBool(v any) bool
- func ToFloat(v any) float64
- func ToInt(v any) int64
- func ToString(v any) string
- type BuiltinFunc
- type CompiledFunction
- type DebugEntry
- type ExecConfig
- type Executor
- func (ex *Executor) Execute(ctx context.Context, fn *CompiledFunction, args map[string]any) (any, error)
- func (ex *Executor) ExecuteExpr(ctx context.Context, expr ast.ExprNode, vars map[string]any) (any, error)
- func (ex *Executor) ExecuteInto(ctx context.Context, fn *CompiledFunction, args map[string]any, ...) (any, error)
- func (ex *Executor) ExecuteWithDebug(ctx context.Context, fn *CompiledFunction, args map[string]any) (any, []DebugEntry, error)
- func (ex *Executor) RegisterBuiltin(name string, bf *BuiltinFunc)
- type FunctionLookup
Constants ¶
This section is empty.
Variables ¶
var ( ErrTimeout = errors.New("execution timeout exceeded") ErrMaxDepth = errors.New("maximum call depth exceeded") ErrDivZero = errors.New("division by zero") )
Errors returned by the executor.
var ErrUserRaise = errors.New("raise")
ErrUserRaise is returned when a DTL function executes a raise statement.
Functions ¶
func CallLambda ¶
CallLambda invokes a lambda closure. Used by stdlib collection functions.
func NewDebugContext
deprecated
func NewDebugContext(ctx context.Context) (context.Context, *[]DebugEntry)
NewDebugContext returns a context with an attached debug buffer.
Deprecated: ExecuteWithDebug collects the same entries without allocating a buffer and a context value on every call, whether or not the function ever calls debug(). This remains for callers driving the executor directly, and appendDebug still honours it.
Types ¶
type BuiltinFunc ¶
type BuiltinFunc struct {
Name string
MinArgs int
MaxArgs int // -1 for variadic
Fn func(args []any) (any, error)
// CtxFn is an optional context-aware alternative to Fn.
// When set, the executor passes the evaluation context so the function
// can access platform services (schema, query, pipeline, etc.).
// If CtxFn is set, Fn is ignored.
CtxFn func(ctx context.Context, args []any) (any, error)
// Doc is a one-line signature and description, surfaced by the language
// server as hover text and completion detail. The conventional shape is
// "name(args) -> type -- what it does". Host-registered builtins may set
// it to document themselves; an empty Doc simply yields no hover text.
Doc string
}
BuiltinFunc is a Go-implemented function callable from DTL.
type CompiledFunction ¶
CompiledFunction is a parsed+compiled user-defined function ready for execution.
type DebugEntry ¶
type DebugEntry struct {
Timestamp time.Time `json:"timestamp"`
Label string `json:"label,omitempty"`
Values []any `json:"values"`
}
DebugEntry represents a single debug/print output line.
type ExecConfig ¶
type ExecConfig struct {
// Timeout bounds wall-clock time per execution. Zero means unbounded.
Timeout time.Duration
// MaxDepth bounds nested user-function calls. Zero means unbounded.
MaxDepth int
}
ExecConfig holds execution limits.
Both fields use zero to mean "unbounded", which is the right primitive at this layer but the wrong default for a host: unbounded depth ends in `fatal error: stack overflow`, which no recover() can catch. Callers that build an Executor directly own that choice. Anything constructed through registry.New gets registry.DefaultMaxCallDepth instead.
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor evaluates compiled DTL AST nodes via tree-walking.
func New ¶
func New(builtins map[string]*BuiltinFunc, lookup FunctionLookup, config ExecConfig) *Executor
New creates an executor with the given built-ins and function resolver.
builtins is not copied and must not be mutated afterwards; use RegisterBuiltin to add to this executor without touching a shared table.
func (*Executor) Execute ¶
func (ex *Executor) Execute(ctx context.Context, fn *CompiledFunction, args map[string]any) (any, error)
Execute runs a compiled function with the given arguments.
func (*Executor) ExecuteExpr ¶
func (ex *Executor) ExecuteExpr(ctx context.Context, expr ast.ExprNode, vars map[string]any) (any, error)
ExecuteExpr evaluates a standalone expression with the given variable bindings.
func (*Executor) ExecuteInto ¶ added in v1.5.2
func (ex *Executor) ExecuteInto(ctx context.Context, fn *CompiledFunction, args map[string]any, logs *[]DebugEntry) (any, error)
ExecuteInto runs a compiled function, appending any debug() or print() output to *logs. Pass nil to discard it.
This exists so a caller that already has somewhere to put the entries can hand that address over — registry.Execute points it at the ExecuteResult it was going to allocate regardless. Owning the destination is what keeps the executor's own per-call state off the heap: a sink pointing into evalCtx would force evalCtx itself to escape, trading one allocation for another.
func (*Executor) ExecuteWithDebug ¶ added in v1.5.2
func (ex *Executor) ExecuteWithDebug(ctx context.Context, fn *CompiledFunction, args map[string]any) (any, []DebugEntry, error)
ExecuteWithDebug runs a compiled function and returns whatever debug() and print() emitted, without the per-call buffer and context value that NewDebugContext costs. The returned slice is nil unless something was emitted, so the common case allocates nothing for it.
func (*Executor) RegisterBuiltin ¶ added in v1.5.3
func (ex *Executor) RegisterBuiltin(name string, bf *BuiltinFunc)
RegisterBuiltin adds a builtin visible only to this executor, shadowing any same-named entry in the base table.
Not safe against concurrent execution: call it during setup, before the executor is used. That was already the contract when the builtin table was written directly.
type FunctionLookup ¶
type FunctionLookup interface {
GetCompiled(ctx context.Context, name string) (*CompiledFunction, bool)
}
FunctionLookup resolves function names to compiled user functions.