/** * Bounded, effect-intercepting evaluator used by the type checker's * constant-folding pass. * * Runs a subtree of AST with a fresh `ContextStack` seeded with literal * values, capped by a step budget. If the evaluator produces a `Perform` * step we stop immediately and report the effect name — we never dispatch * to handlers, because type-check time has none. Any other error or async * surface reports a generic failure and the caller falls back. * * Future optimizations (not in v1): * - Fast-path for trivial builtins (direct JS dispatch, no trampoline * setup) — shares the same builtin impl to avoid drift. * - Memoize `(calleeId, argValues)` across a single type-check pass. */ import type { AstNode } from '../parser/types'; import type { Any } from '../interface'; import type { ContextStack } from './ContextStack'; export type FoldResult = { ok: true; value: Any; } | { ok: false; reason: 'budget'; } | { ok: false; reason: 'effect'; effectName: string; } | { ok: false; reason: 'error'; }; /** Default step budget per fold attempt (decision #1 in the design doc). */ export declare const DEFAULT_FOLD_STEP_BUDGET = 10000; /** * Evaluate a single AST node for constant folding. Does NOT dispatch effects * to host handlers — if the evaluator surfaces a Perform step, we stop and * report the effect name so the caller can emit a warning. Any async surface * (unexpected in pure code) is treated as a generic failure. */ export declare function evaluateNodeForFold(node: AstNode, contextStack: ContextStack, maxSteps?: number): FoldResult;