11import type { Expr , Span } from "./ast/mod.ts" ;
22import { parseExpression } from "./parse.ts" ;
33
4+ /** Primitive runtime values supported by the evaluator. */
45export type RuntimePrimitive = undefined | null | boolean | number | string ;
56
7+ /** A function callable from expressions (must accept/return `RuntimeValue`). */
68export type RuntimeFunction = ( ...args : RuntimeValue [ ] ) => RuntimeValue ;
79
10+ /** A `RuntimeValue` array. */
811export interface RuntimeArray extends Array < RuntimeValue > { }
912
13+ /** A plain object mapping string keys to `RuntimeValue`. */
1014export interface RuntimeObject {
15+ /** Own enumerable properties (prototype is ignored by the evaluator). */
1116 [ key : string ] : RuntimeValue ;
1217}
1318
19+ /**
20+ * Allowed runtime data model for evaluation.
21+ *
22+ * Values are validated at runtime when present in `env`, and function return
23+ * values are also validated.
24+ */
1425export type RuntimeValue =
1526 | RuntimePrimitive
1627 | RuntimeArray
1728 | RuntimeObject
1829 | RuntimeFunction ;
1930
31+ /** Options for `evaluateAst` and `evaluateExpression`. */
2032export type EvalOptions = Readonly < {
2133 /**
2234 * Identifier bindings available to the expression.
@@ -50,6 +62,12 @@ export type EvalOptions = Readonly<{
5062 throwOnError ?: boolean ;
5163} > ;
5264
65+ /**
66+ * An evaluation failure.
67+ *
68+ * - `span` is present for errors tied to a specific AST node.
69+ * - `index` is present when evaluation failed because parsing failed.
70+ */
5371export type EvalError = Readonly < {
5472 message : string ;
5573 span ?: Span ;
@@ -58,11 +76,20 @@ export type EvalError = Readonly<{
5876 index ?: number ;
5977} > ;
6078
79+ /**
80+ * Thrown evaluation error (default mode).
81+ *
82+ * Carries either `span` (eval failures) and/or `index` (parse failures).
83+ */
6184export class ExpEvalError extends Error {
85+ /** AST span for eval errors tied to a node. */
6286 readonly span ?: Span ;
87+ /** Step counter at the time of failure (useful with budgets). */
6388 readonly steps ?: number ;
89+ /** Byte index into input when the failure originated from parsing. */
6490 readonly index ?: number ;
6591
92+ /** Create an `ExpEvalError` from an `EvalError` payload. */
6693 constructor ( error : EvalError ) {
6794 super ( error . message ) ;
6895 this . name = "ExpEvalError" ;
@@ -72,6 +99,7 @@ export class ExpEvalError extends Error {
7299 }
73100}
74101
102+ /** Result returned by `evaluateAst` / `evaluateExpression` in non-throwing mode. */
75103export type EvalResult =
76104 | Readonly < { success : true ; value : RuntimeValue } >
77105 | Readonly < { success : false ; error : EvalError } > ;
@@ -416,6 +444,7 @@ const evalExpr = (expr: Expr, ctx: Ctx): EvalResult => {
416444 }
417445} ;
418446
447+ /** Evaluate a pre-parsed AST. */
419448export function evaluateAst ( expr : Expr , opts : EvalOptions = { } ) : EvalResult {
420449 const throwOnError = opts . throwOnError ?? true ;
421450
@@ -442,14 +471,20 @@ export function evaluateAst(expr: Expr, opts: EvalOptions = {}): EvalResult {
442471 return res ;
443472}
444473
474+ /** Options for `evaluateExpression` (includes all `EvalOptions`). */
445475export type EvaluateExpressionOptions =
446476 & EvalOptions
447477 & Readonly < {
448478 /** When true, throw on parse failure. Default: true */
449479 throwOnParseError ?: boolean ;
450480 } > ;
451481
452- /** Parse + evaluate a single expression. */
482+ /**
483+ * Parse + evaluate a single expression.
484+ *
485+ * If `throwOnParseError: false`, parse failures return an `EvalError` that
486+ * includes `index` so callers can render diagnostics.
487+ */
453488export function evaluateExpression (
454489 input : string ,
455490 opts : EvaluateExpressionOptions = { } ,
0 commit comments