/** * String, Tuple, Dict, Closure, and Pass Evaluation * * Handles evaluation of literal values including: * - Pass keyword (returns current pipe value) * - String literals with interpolation * - Tuple literals * - Dict literals with callable binding * - Closure creation with late binding * - Block-closure creation for expression-position blocks * * Interface requirements (from spec): * - evaluatePass(node) -> Promise * - evaluateString(node) -> Promise<{ value: string; interpolated: boolean }> * - evaluateDict(node) -> Promise> * - createClosure(node) -> Promise * - createBlockClosure(node) -> ScriptCallable * * Error Handling: * - Pass throws RUNTIME_UNDEFINED_VARIABLE if $ not bound * - String interpolation errors propagate from evaluateExpression() * - Dict/tuple evaluation errors propagate from nested expressions * * @internal */ import type { StringLiteralNode, DictNode, ClosureNode, BlockNode, ExpressionNode, BodyNode, SourceLocation, AnnotationArg, PassNode, PassBlockNode } from '../../../../types.js'; import type { RillValue } from '../../types/structures.js'; import { type ScriptCallable } from '../../callable.js'; import type { EvalState } from '../state.js'; /** * Evaluate annotation arguments to a dict of key-value pairs. * Handles both named arguments and spread arguments. * * @param annotations - Annotation arguments from AST * @param evalExpr - Expression evaluator function * @returns Record of annotation key-value pairs * * @internal */ export declare function evaluateAnnotations(annotations: AnnotationArg[], evalExpr: (expr: ExpressionNode) => Promise): Promise>; /** * Evaluate pass node - returns current pipe value unchanged. * * Pass returns ctx.pipeValue. If $ not bound (pipeValue is null), * throws RUNTIME_UNDEFINED_VARIABLE error. * * @param s - Evaluator state * @param node - PassNode from AST * @returns Current pipe value * @throws RuntimeError with RUNTIME_UNDEFINED_VARIABLE if $ not bound */ export declare function evaluatePass(s: EvalState, node: PassNode): Promise; /** * Evaluate pass block node — non-halting side-effect. * * Runs `body` in the current context. Reads `on_error` from `options`; * when it equals `#IGNORE`, catchable halts from the body are suppressed * and the original pipe value is returned unchanged. * * When `async: true` is present in options, the body is dispatched via * `trackInflight` without awaiting (fire-and-forget). The pipe-entry value * flows downstream immediately; the body return value is discarded. * `on_error: #IGNORE` composes with `async: true`: the registered promise * suppresses catchable body halts when both options are set. * * Without `on_error: #IGNORE`, a body halt in the async path is not * awaited by any caller, so it is tagged (`markDeferredHalt`) before it * reaches `trackInflight` and surfaces at `dispose()` time via the log * callbacks rather than being swallowed. Non-catchable `error`/`assert` * halts always surface this way. * * Non-catchable halts (`catchable: false`) and `ControlSignal` instances * are always re-thrown. * * @param s - Evaluator state * @param node - PassBlockNode from AST * @returns Original pipe value (ctx.pipeValue at entry), unchanged */ export declare function evaluatePassBlock(s: EvalState, node: PassBlockNode): Promise; /** * Evaluate string literal with interpolation. * Interpolation expressions are evaluated with the current pipe value preserved. * * String parts are concatenated with interpolated values formatted via formatValue(). * Errors from interpolation expression evaluation propagate to caller. * * Returns `{ value, interpolated }` where `interpolated` is `true` iff at least one * part is a non-literal (interpolation expression). This flag enables callers such as * `evaluateError` to decide whether to wrap frames with the original literal text. */ export declare function evaluateString(s: EvalState, node: StringLiteralNode): Promise<{ value: string; interpolated: boolean; }>; /** * Reject dict keys that collide with reserved method names (len, first, * empty, eq, ne, keys, values, entries) or reserved brand keys used * internally to discriminate runtime value shapes (__type, __rill_atom, * __rill_tuple, etc.). Halts catchably when the key is unusable; a no-op * otherwise. */ export declare function assertUsableDictKey(s: EvalState, stringKey: string, span: { readonly start: SourceLocation; }): void; /** * Evaluate dict literal. * All callables in the dict are bound to the containing dict via boundDict property. * * Reserved method names (len, first, empty, eq, ne, keys, values, entries) * cannot be used as dict keys. * Multi-key entries (tuple keys) expand to multiple entries with shared value. * Errors from value evaluation propagate to caller. */ export declare function evaluateDict(s: EvalState, node: DictNode): Promise>; /** * Evaluate dict as dispatch table when piped. * * Searches dict entries for key matching piped value using type-aware deep equality. * Returns matched value. Auto-invokes if matched value is closure. * * Type-aware matching ensures: * - Number key 1 matches only number input 1, not string "1" * - Boolean key true matches only boolean input true, not string "true" * * Multi-key support: [["k1", "k2"]: value] syntax allows multiple keys * to map to the same value. Key tuple is evaluated to get list of candidates. * * @param s - Evaluator state * @param node - DictNode representing dispatch table * @param input - Piped value to use as lookup key * @returns Matched value (auto-invoked if closure) * @throws RuntimeError with RUNTIME_PROPERTY_NOT_FOUND if no match and no default */ export declare function evaluateDictDispatch(s: EvalState, node: DictNode, input: RillValue): Promise; /** * Runtime dict dispatch for variables: search dict for matching key. * Supports multi-key entries, auto-invokes closures, handles default values. * * @param s - Evaluator state * @param dict - Runtime dict value * @param input - Key to search for * @param defaultValue - Optional default value expression node * @param location - Source location for error reporting * @returns Matched value or default */ export declare function dispatchToDict(s: EvalState, dict: Record, input: RillValue, defaultValue: BodyNode | null, location: { span?: { start: SourceLocation; end: SourceLocation; }; }, skipClosureResolution?: boolean): Promise; /** * Runtime list dispatch for variables: return element at numeric index. * Supports negative indices, auto-invokes closures, handles default values. * * @param s - Evaluator state * @param list - Runtime list value * @param input - Index value (must be number) * @param defaultValue - Optional default value expression node * @param location - Source location for error reporting * @returns Element at index or default */ export declare function dispatchToList(s: EvalState, list: RillValue[], input: RillValue, defaultValue: BodyNode | null, location: { span?: { start: SourceLocation; end: SourceLocation; }; }, skipClosureResolution?: boolean): Promise; /** * Create a script callable from a closure node. * Closures use late binding - variables are resolved in definingScope when invoked. * * Default parameter values are evaluated immediately in the current context. * Property-style callables (zero params) are auto-invoked on dict access. */ export declare function createClosure(s: EvalState, node: ClosureNode): Promise; /** * Create a script callable from a block node in expression position. * Block-closures have a single implicit $ parameter representing the piped value. * * No default parameter evaluation since the implicit $ has no default. * isProperty is always false (block-closures require $). */ export declare function createBlockClosure(s: EvalState, node: BlockNode): ScriptCallable;