stringent 0.0.1 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -0
- package/dist/context.d.ts +45 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +14 -0
- package/dist/context.js.map +1 -0
- package/dist/createParser.d.ts +159 -0
- package/dist/createParser.d.ts.map +1 -0
- package/dist/createParser.js +118 -0
- package/dist/createParser.js.map +1 -0
- package/dist/errors.d.ts +121 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +186 -0
- package/dist/errors.js.map +1 -0
- package/dist/grammar/index.d.ts +48 -0
- package/dist/grammar/index.d.ts.map +1 -0
- package/dist/grammar/index.js +13 -0
- package/dist/grammar/index.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/parse/index.d.ts +211 -0
- package/dist/parse/index.d.ts.map +1 -0
- package/dist/parse/index.js +16 -0
- package/dist/parse/index.js.map +1 -0
- package/dist/performance.bench.d.ts +10 -0
- package/dist/performance.bench.d.ts.map +1 -0
- package/dist/performance.bench.js +379 -0
- package/dist/performance.bench.js.map +1 -0
- package/dist/primitive/index.d.ts +96 -0
- package/dist/primitive/index.d.ts.map +1 -0
- package/dist/primitive/index.js +102 -0
- package/dist/primitive/index.js.map +1 -0
- package/dist/runtime/eval.d.ts +157 -0
- package/dist/runtime/eval.d.ts.map +1 -0
- package/dist/runtime/eval.js +206 -0
- package/dist/runtime/eval.js.map +1 -0
- package/dist/runtime/infer.d.ts +27 -0
- package/dist/runtime/infer.d.ts.map +1 -0
- package/dist/runtime/infer.js +35 -0
- package/dist/runtime/infer.js.map +1 -0
- package/dist/runtime/parser.d.ts +115 -0
- package/dist/runtime/parser.d.ts.map +1 -0
- package/dist/runtime/parser.js +746 -0
- package/dist/runtime/parser.js.map +1 -0
- package/dist/schema/index.d.ts +476 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +137 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/static/infer.d.ts +27 -0
- package/dist/static/infer.d.ts.map +1 -0
- package/dist/static/infer.js +10 -0
- package/dist/static/infer.js.map +1 -0
- package/package.json +62 -8
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Expression Evaluation
|
|
3
|
+
*
|
|
4
|
+
* Evaluates parsed AST nodes to produce runtime values.
|
|
5
|
+
* Uses the eval functions defined in NodeSchema to compute results.
|
|
6
|
+
*
|
|
7
|
+
* The evaluator:
|
|
8
|
+
* 1. Recursively evaluates child nodes first
|
|
9
|
+
* 2. Passes evaluated values to the node's eval function
|
|
10
|
+
* 3. Returns the computed result
|
|
11
|
+
* 4. Validates values against arktype constraints at runtime
|
|
12
|
+
*/
|
|
13
|
+
import type { NodeSchema, SchemaToType } from '../schema/index.js';
|
|
14
|
+
/**
|
|
15
|
+
* Extract the outputSchema from an AST node type.
|
|
16
|
+
* Returns the literal schema string if present, otherwise 'unknown'.
|
|
17
|
+
*/
|
|
18
|
+
type ExtractOutputSchema<T> = T extends {
|
|
19
|
+
outputSchema: infer S extends string;
|
|
20
|
+
} ? S : 'unknown';
|
|
21
|
+
/**
|
|
22
|
+
* A type that represents any AST node with an outputSchema field.
|
|
23
|
+
* This is used as a constraint for the evaluate() function.
|
|
24
|
+
*/
|
|
25
|
+
export type ASTNodeWithSchema<TSchema extends string = string> = {
|
|
26
|
+
readonly node: string;
|
|
27
|
+
readonly outputSchema: TSchema;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Recursively extract all identifier nodes from an AST.
|
|
31
|
+
* Returns a union of { name: string, outputSchema: string } tuples.
|
|
32
|
+
*
|
|
33
|
+
* This is used to determine what variables are used in an expression
|
|
34
|
+
* and what types they expect.
|
|
35
|
+
*/
|
|
36
|
+
type ExtractIdentifiers<T> = T extends {
|
|
37
|
+
node: 'identifier';
|
|
38
|
+
name: infer N;
|
|
39
|
+
outputSchema: infer S;
|
|
40
|
+
} ? {
|
|
41
|
+
name: N;
|
|
42
|
+
outputSchema: S;
|
|
43
|
+
} : T extends object ? {
|
|
44
|
+
[K in keyof T]: ExtractIdentifiers<T[K]>;
|
|
45
|
+
}[keyof T] : never;
|
|
46
|
+
/**
|
|
47
|
+
* Convert a union of identifier tuples to a data object type.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* type Ids = { name: 'x'; outputSchema: 'number' } | { name: 'y'; outputSchema: 'string' };
|
|
51
|
+
* type Data = IdentifiersToData<Ids>;
|
|
52
|
+
* // { x: number; y: string }
|
|
53
|
+
*/
|
|
54
|
+
type IdentifiersToData<T> = T extends {
|
|
55
|
+
name: infer N extends string;
|
|
56
|
+
outputSchema: infer S;
|
|
57
|
+
} ? {
|
|
58
|
+
[K in N]: SchemaToType<S>;
|
|
59
|
+
} : never;
|
|
60
|
+
/**
|
|
61
|
+
* Merge a union of single-key objects into a single object type.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* type Union = { x: number } | { y: string };
|
|
65
|
+
* type Merged = UnionToIntersection<Union>;
|
|
66
|
+
* // { x: number } & { y: string }
|
|
67
|
+
*/
|
|
68
|
+
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
69
|
+
/**
|
|
70
|
+
* Extract required data types from an AST based on its identifier nodes.
|
|
71
|
+
* Returns Record<string, never> if no identifiers are found (empty object is allowed).
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* type AST = { node: 'add'; left: { node: 'identifier'; name: 'x'; outputSchema: 'number' }; ... };
|
|
75
|
+
* type Data = ExtractRequiredData<AST>;
|
|
76
|
+
* // { x: number }
|
|
77
|
+
*/
|
|
78
|
+
export type ExtractRequiredData<T> = ExtractIdentifiers<T> extends never ? Record<string, never> : UnionToIntersection<IdentifiersToData<ExtractIdentifiers<T>>>;
|
|
79
|
+
/**
|
|
80
|
+
* Evaluation context that includes both the parse context and node schemas.
|
|
81
|
+
* When AST type is provided, the data is type-checked against the AST's variables.
|
|
82
|
+
*/
|
|
83
|
+
export interface EvalContext<TData = Record<string, unknown>> {
|
|
84
|
+
/** The data context (variable name → value mapping) */
|
|
85
|
+
data: TData;
|
|
86
|
+
/** The node schemas (for looking up eval functions) */
|
|
87
|
+
nodes: readonly NodeSchema[];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Evaluate an AST node to produce a runtime value.
|
|
91
|
+
*
|
|
92
|
+
* The return type is inferred from the AST node's `outputSchema` field:
|
|
93
|
+
* - `outputSchema: "number"` → returns `number`
|
|
94
|
+
* - `outputSchema: "string"` → returns `string`
|
|
95
|
+
* - `outputSchema: "boolean"` → returns `boolean`
|
|
96
|
+
* - `outputSchema: "null"` → returns `null`
|
|
97
|
+
* - `outputSchema: "undefined"` → returns `undefined`
|
|
98
|
+
* - Other/unknown → returns `unknown`
|
|
99
|
+
*
|
|
100
|
+
* @param ast - The parsed AST node to evaluate
|
|
101
|
+
* @param ctx - The evaluation context containing variable values and node schemas
|
|
102
|
+
* @returns The evaluated value with the type derived from the AST's outputSchema
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* import { createParser, defineNode, lhs, rhs, constVal } from "stringent";
|
|
107
|
+
* import { evaluate } from "stringent/runtime/eval";
|
|
108
|
+
*
|
|
109
|
+
* const add = defineNode({
|
|
110
|
+
* name: "add",
|
|
111
|
+
* pattern: [lhs("number").as("left"), constVal("+"), rhs("number").as("right")],
|
|
112
|
+
* precedence: 1,
|
|
113
|
+
* resultType: "number",
|
|
114
|
+
* eval: ({ left, right }) => left + right,
|
|
115
|
+
* });
|
|
116
|
+
*
|
|
117
|
+
* const parser = createParser([add] as const);
|
|
118
|
+
* const result = parser.parse("1+2", {});
|
|
119
|
+
*
|
|
120
|
+
* if (result.length === 2) {
|
|
121
|
+
* const value = evaluate(result[0], { data: {}, nodes: [add] });
|
|
122
|
+
* // value has type: number (not unknown!)
|
|
123
|
+
* // value === 3
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export declare function evaluate<T, TData extends ExtractRequiredData<T>>(ast: T, ctx: EvalContext<TData>): SchemaToType<ExtractOutputSchema<T>>;
|
|
128
|
+
/**
|
|
129
|
+
* Create a bound evaluator function for a specific set of node schemas.
|
|
130
|
+
*
|
|
131
|
+
* This is a convenience function that pre-binds the node schemas,
|
|
132
|
+
* so you only need to pass the AST and variable values when evaluating.
|
|
133
|
+
*
|
|
134
|
+
* The returned evaluator function preserves type inference:
|
|
135
|
+
* - The return type is derived from the AST's `outputSchema` field
|
|
136
|
+
* - `outputSchema: "number"` → returns `number`
|
|
137
|
+
* - `outputSchema: "string"` → returns `string`
|
|
138
|
+
* - etc.
|
|
139
|
+
*
|
|
140
|
+
* @param nodes - The node schemas with eval functions
|
|
141
|
+
* @returns An evaluator function with type inference
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* const evaluator = createEvaluator([add, mul]);
|
|
146
|
+
*
|
|
147
|
+
* const result = parser.parse("1+2*3", {});
|
|
148
|
+
* if (result.length === 2) {
|
|
149
|
+
* const value = evaluator(result[0], {});
|
|
150
|
+
* // value has type: number (inferred from AST's outputSchema)
|
|
151
|
+
* // value === 7
|
|
152
|
+
* }
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export declare function createEvaluator(nodes: readonly NodeSchema[]): <T, TData extends ExtractRequiredData<T>>(ast: T, data: TData) => SchemaToType<ExtractOutputSchema<T>>;
|
|
156
|
+
export {};
|
|
157
|
+
//# sourceMappingURL=eval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/runtime/eval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMnE;;;GAGG;AACH,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,YAAY,EAAE,MAAM,CAAC,SAAS,MAAM,CAAA;CAAE,GAAG,CAAC,GAAG,SAAS,CAAC;AAEjG;;;GAGG;AACH,MAAM,MAAM,iBAAiB,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM,IAAI;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAChC,CAAC;AAMF;;;;;;GAMG;AACH,KAAK,kBAAkB,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC,CAAA;CAAE,GAC/F;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,YAAY,EAAE,CAAC,CAAA;CAAE,GAC5B,CAAC,SAAS,MAAM,GACd;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC,MAAM,CAAC,CAAC,GACrD,KAAK,CAAC;AAEZ;;;;;;;GAOG;AACH,KAAK,iBAAiB,CAAC,CAAC,IAAI,CAAC,SAAS;IACpC,IAAI,EAAE,MAAM,CAAC,SAAS,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC,CAAC;CACvB,GACG;KAAG,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;CAAE,GAC7B,KAAK,CAAC;AAEV;;;;;;;GAOG;AACH,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,KAAK,CAAC,SAAS,CACjF,CAAC,EAAE,MAAM,CAAC,KACP,IAAI,GACL,CAAC,GACD,KAAK,CAAC;AAEV;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAC/B,kBAAkB,CAAC,CAAC,CAAC,SAAS,KAAK,GAC/B,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GACrB,mBAAmB,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE;;;GAGG;AACH,MAAM,WAAW,WAAW,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1D,uDAAuD;IACvD,IAAI,EAAE,KAAK,CAAC;IACZ,uDAAuD;IACvD,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;CAC9B;AA0DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,SAAS,mBAAmB,CAAC,CAAC,CAAC,EAC9D,GAAG,EAAE,CAAC,EACN,GAAG,EAAE,WAAW,CAAC,KAAK,CAAC,GACtB,YAAY,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAgGtC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,IAChC,CAAC,EAAE,KAAK,SAAS,mBAAmB,CAAC,CAAC,CAAC,EAC/D,KAAK,CAAC,EACN,MAAM,KAAK,KACV,YAAY,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAGxC"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Expression Evaluation
|
|
3
|
+
*
|
|
4
|
+
* Evaluates parsed AST nodes to produce runtime values.
|
|
5
|
+
* Uses the eval functions defined in NodeSchema to compute results.
|
|
6
|
+
*
|
|
7
|
+
* The evaluator:
|
|
8
|
+
* 1. Recursively evaluates child nodes first
|
|
9
|
+
* 2. Passes evaluated values to the node's eval function
|
|
10
|
+
* 3. Returns the computed result
|
|
11
|
+
* 4. Validates values against arktype constraints at runtime
|
|
12
|
+
*/
|
|
13
|
+
import { type } from 'arktype';
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// Runtime ArkType Validation
|
|
16
|
+
// =============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Cache for arktype validators to avoid re-creating them for each evaluation.
|
|
19
|
+
* Maps schema strings to their compiled validators.
|
|
20
|
+
*/
|
|
21
|
+
const validatorCache = new Map();
|
|
22
|
+
/**
|
|
23
|
+
* Get or create an arktype validator for a given schema string.
|
|
24
|
+
* Uses a cache to avoid re-creating validators for frequently used schemas.
|
|
25
|
+
*
|
|
26
|
+
* @param schema - The arktype schema string (e.g., 'number >= 0', 'string.email')
|
|
27
|
+
* @returns The compiled arktype validator
|
|
28
|
+
*/
|
|
29
|
+
function getValidator(schema) {
|
|
30
|
+
let validator = validatorCache.get(schema);
|
|
31
|
+
if (!validator) {
|
|
32
|
+
// Create and cache the validator
|
|
33
|
+
// Note: Invalid schemas will cause arktype to throw at compile time
|
|
34
|
+
// At runtime, we trust the schema was validated at parse time
|
|
35
|
+
validator = type(schema);
|
|
36
|
+
validatorCache.set(schema, validator);
|
|
37
|
+
}
|
|
38
|
+
return validator;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Validate a value against an arktype schema at runtime.
|
|
42
|
+
* Throws an error if the value doesn't match the schema constraints.
|
|
43
|
+
*
|
|
44
|
+
* @param value - The value to validate
|
|
45
|
+
* @param schema - The arktype schema string (e.g., 'number >= 0', 'string.email')
|
|
46
|
+
* @param variableName - The name of the variable (for error messages)
|
|
47
|
+
* @throws Error if the value doesn't match the schema constraints
|
|
48
|
+
*/
|
|
49
|
+
function validateValue(value, schema, variableName) {
|
|
50
|
+
// Skip validation for generic schemas that don't have runtime constraints
|
|
51
|
+
// These basic types are handled by TypeScript's compile-time checking
|
|
52
|
+
if (schema === 'unknown' || schema === 'never') {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const validator = getValidator(schema);
|
|
56
|
+
const result = validator(value);
|
|
57
|
+
// arktype returns the value if valid, or an ArkErrors object if invalid
|
|
58
|
+
if (result instanceof type.errors) {
|
|
59
|
+
throw new Error(`Variable '${variableName}' failed validation for schema '${schema}': ${result.summary}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Evaluate an AST node to produce a runtime value.
|
|
64
|
+
*
|
|
65
|
+
* The return type is inferred from the AST node's `outputSchema` field:
|
|
66
|
+
* - `outputSchema: "number"` → returns `number`
|
|
67
|
+
* - `outputSchema: "string"` → returns `string`
|
|
68
|
+
* - `outputSchema: "boolean"` → returns `boolean`
|
|
69
|
+
* - `outputSchema: "null"` → returns `null`
|
|
70
|
+
* - `outputSchema: "undefined"` → returns `undefined`
|
|
71
|
+
* - Other/unknown → returns `unknown`
|
|
72
|
+
*
|
|
73
|
+
* @param ast - The parsed AST node to evaluate
|
|
74
|
+
* @param ctx - The evaluation context containing variable values and node schemas
|
|
75
|
+
* @returns The evaluated value with the type derived from the AST's outputSchema
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* import { createParser, defineNode, lhs, rhs, constVal } from "stringent";
|
|
80
|
+
* import { evaluate } from "stringent/runtime/eval";
|
|
81
|
+
*
|
|
82
|
+
* const add = defineNode({
|
|
83
|
+
* name: "add",
|
|
84
|
+
* pattern: [lhs("number").as("left"), constVal("+"), rhs("number").as("right")],
|
|
85
|
+
* precedence: 1,
|
|
86
|
+
* resultType: "number",
|
|
87
|
+
* eval: ({ left, right }) => left + right,
|
|
88
|
+
* });
|
|
89
|
+
*
|
|
90
|
+
* const parser = createParser([add] as const);
|
|
91
|
+
* const result = parser.parse("1+2", {});
|
|
92
|
+
*
|
|
93
|
+
* if (result.length === 2) {
|
|
94
|
+
* const value = evaluate(result[0], { data: {}, nodes: [add] });
|
|
95
|
+
* // value has type: number (not unknown!)
|
|
96
|
+
* // value === 3
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export function evaluate(ast, ctx) {
|
|
101
|
+
if (typeof ast !== 'object' || ast === null) {
|
|
102
|
+
throw new Error(`Invalid AST node: expected object, got ${typeof ast}`);
|
|
103
|
+
}
|
|
104
|
+
const node = ast;
|
|
105
|
+
// Check for the 'node' property that indicates the node type
|
|
106
|
+
if (!('node' in node) || typeof node.node !== 'string') {
|
|
107
|
+
throw new Error(`Invalid AST node: missing 'node' property`);
|
|
108
|
+
}
|
|
109
|
+
const nodeType = node.node;
|
|
110
|
+
// Handle literal nodes (number, string, boolean, null, undefined)
|
|
111
|
+
if (nodeType === 'literal') {
|
|
112
|
+
if ('value' in node) {
|
|
113
|
+
return node.value;
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`Literal node missing 'value' property`);
|
|
116
|
+
}
|
|
117
|
+
// Internal eval context for recursive calls (typed at runtime level)
|
|
118
|
+
const internalCtx = ctx;
|
|
119
|
+
// Handle identifier nodes - look up value in context and validate against schema
|
|
120
|
+
if (nodeType === 'identifier') {
|
|
121
|
+
if (!('name' in node) || typeof node.name !== 'string') {
|
|
122
|
+
throw new Error(`Identifier node missing 'name' property`);
|
|
123
|
+
}
|
|
124
|
+
const name = node.name;
|
|
125
|
+
if (!(name in internalCtx.data)) {
|
|
126
|
+
throw new Error(`Undefined variable: ${name}`);
|
|
127
|
+
}
|
|
128
|
+
const value = internalCtx.data[name];
|
|
129
|
+
// Validate value against arktype schema at runtime
|
|
130
|
+
if ('outputSchema' in node && typeof node.outputSchema === 'string') {
|
|
131
|
+
validateValue(value, node.outputSchema, name);
|
|
132
|
+
}
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
// Handle const nodes (operators, keywords) - these shouldn't be evaluated directly
|
|
136
|
+
if (nodeType === 'const') {
|
|
137
|
+
throw new Error(`Cannot evaluate const node directly`);
|
|
138
|
+
}
|
|
139
|
+
// Handle parentheses - just evaluate the inner expression
|
|
140
|
+
if (nodeType === 'parentheses') {
|
|
141
|
+
if (!('inner' in node)) {
|
|
142
|
+
throw new Error(`Parentheses node missing 'inner' property`);
|
|
143
|
+
}
|
|
144
|
+
// Use type assertion for recursive call (data constraint already validated at entry)
|
|
145
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
146
|
+
return evaluate(node.inner, internalCtx);
|
|
147
|
+
}
|
|
148
|
+
// Look up the node schema for this node type
|
|
149
|
+
const nodeSchema = internalCtx.nodes.find((n) => n.name === nodeType);
|
|
150
|
+
if (!nodeSchema) {
|
|
151
|
+
throw new Error(`Unknown node type: ${nodeType}. Make sure to pass all node schemas to evaluate().`);
|
|
152
|
+
}
|
|
153
|
+
if (!nodeSchema.eval) {
|
|
154
|
+
throw new Error(`Node type '${nodeType}' has no eval function defined`);
|
|
155
|
+
}
|
|
156
|
+
// Extract and evaluate all named bindings from the node
|
|
157
|
+
const evaluatedBindings = {};
|
|
158
|
+
// Get the pattern to determine which fields are named bindings
|
|
159
|
+
for (const element of nodeSchema.pattern) {
|
|
160
|
+
// Check if this is a named schema (has __named and name)
|
|
161
|
+
if ('__named' in element && element.__named === true && 'name' in element) {
|
|
162
|
+
const bindingName = element.name;
|
|
163
|
+
if (bindingName in node) {
|
|
164
|
+
// Recursively evaluate the child node
|
|
165
|
+
// Use type assertion for recursive call (data constraint already validated at entry)
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
167
|
+
evaluatedBindings[bindingName] = evaluate(node[bindingName], internalCtx);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Call the eval function with evaluated bindings
|
|
172
|
+
return nodeSchema.eval(evaluatedBindings, internalCtx.data);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Create a bound evaluator function for a specific set of node schemas.
|
|
176
|
+
*
|
|
177
|
+
* This is a convenience function that pre-binds the node schemas,
|
|
178
|
+
* so you only need to pass the AST and variable values when evaluating.
|
|
179
|
+
*
|
|
180
|
+
* The returned evaluator function preserves type inference:
|
|
181
|
+
* - The return type is derived from the AST's `outputSchema` field
|
|
182
|
+
* - `outputSchema: "number"` → returns `number`
|
|
183
|
+
* - `outputSchema: "string"` → returns `string`
|
|
184
|
+
* - etc.
|
|
185
|
+
*
|
|
186
|
+
* @param nodes - The node schemas with eval functions
|
|
187
|
+
* @returns An evaluator function with type inference
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* const evaluator = createEvaluator([add, mul]);
|
|
192
|
+
*
|
|
193
|
+
* const result = parser.parse("1+2*3", {});
|
|
194
|
+
* if (result.length === 2) {
|
|
195
|
+
* const value = evaluator(result[0], {});
|
|
196
|
+
* // value has type: number (inferred from AST's outputSchema)
|
|
197
|
+
* // value === 7
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
export function createEvaluator(nodes) {
|
|
202
|
+
return function evaluator(ast, data) {
|
|
203
|
+
return evaluate(ast, { data, nodes });
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=eval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval.js","sourceRoot":"","sources":["../../src/runtime/eval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Type Inference
|
|
3
|
+
*
|
|
4
|
+
* Infers the result type of a parsed AST at runtime.
|
|
5
|
+
*
|
|
6
|
+
* With the new architecture, nodes carry their outputSchema directly,
|
|
7
|
+
* so inference is simpler - just extract the outputSchema field.
|
|
8
|
+
*/
|
|
9
|
+
import type { Context } from '../context.js';
|
|
10
|
+
export type InferredType = string;
|
|
11
|
+
/**
|
|
12
|
+
* Runtime inference - extracts outputSchema from parsed AST nodes.
|
|
13
|
+
*
|
|
14
|
+
* @param ast - The parsed AST node
|
|
15
|
+
* @param context - Parse context (unused, kept for API compatibility)
|
|
16
|
+
* @returns The result type of the AST node
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const result = parser.parse("1+2", {});
|
|
21
|
+
* if (result.length === 2) {
|
|
22
|
+
* const type = infer(result[0], {}); // "number"
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function infer(ast: unknown, _context: Context): InferredType;
|
|
27
|
+
//# sourceMappingURL=infer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"infer.d.ts","sourceRoot":"","sources":["../../src/runtime/infer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,YAAY,CAanE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Type Inference
|
|
3
|
+
*
|
|
4
|
+
* Infers the result type of a parsed AST at runtime.
|
|
5
|
+
*
|
|
6
|
+
* With the new architecture, nodes carry their outputSchema directly,
|
|
7
|
+
* so inference is simpler - just extract the outputSchema field.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Runtime inference - extracts outputSchema from parsed AST nodes.
|
|
11
|
+
*
|
|
12
|
+
* @param ast - The parsed AST node
|
|
13
|
+
* @param context - Parse context (unused, kept for API compatibility)
|
|
14
|
+
* @returns The result type of the AST node
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const result = parser.parse("1+2", {});
|
|
19
|
+
* if (result.length === 2) {
|
|
20
|
+
* const type = infer(result[0], {}); // "number"
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function infer(ast, _context) {
|
|
25
|
+
if (typeof ast !== 'object' || ast === null) {
|
|
26
|
+
throw new Error(`Invalid AST node: ${ast}`);
|
|
27
|
+
}
|
|
28
|
+
const node = ast;
|
|
29
|
+
// Nodes with outputSchema (new architecture)
|
|
30
|
+
if ('outputSchema' in node && typeof node.outputSchema === 'string') {
|
|
31
|
+
return node.outputSchema;
|
|
32
|
+
}
|
|
33
|
+
throw new Error(`AST node has no outputSchema: ${JSON.stringify(ast)}`);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=infer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"infer.js","sourceRoot":"","sources":["../../src/runtime/infer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,QAAiB;IACnD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,IAAI,GAAG,GAA8B,CAAC;IAE5C,6CAA6C;IAC7C,IAAI,cAAc,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;QACpE,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Parser
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the type-level Parse<Grammar, Input, Context> at runtime.
|
|
5
|
+
* Uses the same precedence-based parsing strategy:
|
|
6
|
+
* 1. Try operators at current level (lowest precedence first)
|
|
7
|
+
* 2. Fall back to next level (higher precedence)
|
|
8
|
+
* 3. Base case: try atoms (last level)
|
|
9
|
+
*/
|
|
10
|
+
import type { Context } from '../context.js';
|
|
11
|
+
import type { ComputeGrammar, Grammar } from '../grammar/index.js';
|
|
12
|
+
import type { Parse } from '../parse/index.js';
|
|
13
|
+
import type { NodeSchema, StringSchema, ConstSchema, ExprSchema } from '../schema/index.js';
|
|
14
|
+
import { ASTNode } from '../primitive/index.js';
|
|
15
|
+
/** All built-in atoms, used as the last level of the grammar */
|
|
16
|
+
export declare const BUILT_IN_ATOMS: readonly [NodeSchema<"numberLiteral", readonly [import("../schema/index.js").NumberSchema & {
|
|
17
|
+
as<TName extends string>(name: TName): import("../schema/index.js").NamedSchema<import("../schema/index.js").NumberSchema, TName>;
|
|
18
|
+
}], 0, "number">, NodeSchema<"stringLiteral", readonly [StringSchema<readonly ["\"", "'"]> & {
|
|
19
|
+
as<TName extends string>(name: TName): import("../schema/index.js").NamedSchema<StringSchema<readonly ["\"", "'"]>, TName>;
|
|
20
|
+
}], 0, "string">, NodeSchema<"nullLiteral", readonly [import("../schema/index.js").NullSchema & {
|
|
21
|
+
as<TName extends string>(name: TName): import("../schema/index.js").NamedSchema<import("../schema/index.js").NullSchema, TName>;
|
|
22
|
+
}], 0, "null">, NodeSchema<"booleanLiteral", readonly [import("../schema/index.js").BooleanSchema & {
|
|
23
|
+
as<TName extends string>(name: TName): import("../schema/index.js").NamedSchema<import("../schema/index.js").BooleanSchema, TName>;
|
|
24
|
+
}], 0, "boolean">, NodeSchema<"undefinedLiteral", readonly [import("../schema/index.js").UndefinedSchema & {
|
|
25
|
+
as<TName extends string>(name: TName): import("../schema/index.js").NamedSchema<import("../schema/index.js").UndefinedSchema, TName>;
|
|
26
|
+
}], 0, "undefined">, NodeSchema<"identifier", readonly [import("../schema/index.js").IdentSchema & {
|
|
27
|
+
as<TName extends string>(name: TName): import("../schema/index.js").NamedSchema<import("../schema/index.js").IdentSchema, TName>;
|
|
28
|
+
}], 0, "unknown">, NodeSchema<"parentheses", readonly [ConstSchema<"("> & {
|
|
29
|
+
as<TName extends string>(name: TName): import("../schema/index.js").NamedSchema<ConstSchema<"(">, TName>;
|
|
30
|
+
}, import("../schema/index.js").NamedSchema<ExprSchema<string, "expr">, "inner">, ConstSchema<")"> & {
|
|
31
|
+
as<TName extends string>(name: TName): import("../schema/index.js").NamedSchema<ConstSchema<")">, TName>;
|
|
32
|
+
}], 0, "unknown">];
|
|
33
|
+
/** Parse result: empty = no match, [node, rest] = matched */
|
|
34
|
+
export type ParseResult<T extends ASTNode<string, unknown> = ASTNode<string, unknown>> = [] | [T & {}, string];
|
|
35
|
+
/**
|
|
36
|
+
* Process escape sequences in a string.
|
|
37
|
+
* Supports: \n, \t, \r, \\, \", \', \0, \b, \f, \v, \xHH, \uHHHH
|
|
38
|
+
*
|
|
39
|
+
* @param str - The raw string with escape sequences
|
|
40
|
+
* @returns The processed string with escape sequences converted
|
|
41
|
+
*/
|
|
42
|
+
export declare function processEscapeSequences(str: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Build runtime grammar from operator schemas.
|
|
45
|
+
*
|
|
46
|
+
* Returns a flat tuple of levels:
|
|
47
|
+
* [[ops@prec1], [ops@prec2], ..., [builtInAtoms]]
|
|
48
|
+
*
|
|
49
|
+
* Operators are sorted by precedence ascending (lowest first).
|
|
50
|
+
* Built-in atoms are always appended as the last level.
|
|
51
|
+
*/
|
|
52
|
+
export declare function buildGrammar(operators: readonly NodeSchema[]): Grammar;
|
|
53
|
+
/**
|
|
54
|
+
* Parse input string using node schemas.
|
|
55
|
+
*
|
|
56
|
+
* The return type is computed from the input types using the type-level
|
|
57
|
+
* Parse<Grammar, Input, Context> type, ensuring runtime and type-level
|
|
58
|
+
* parsing stay in sync.
|
|
59
|
+
*/
|
|
60
|
+
export declare function parse<const TNodes extends readonly NodeSchema[], const TInput extends string, const TContext extends Context>(nodes: TNodes, input: TInput, context: TContext): Parse<ComputeGrammar<TNodes>, TInput, TContext>;
|
|
61
|
+
import { type RichParseError, type ParseResultWithErrors } from '../errors.js';
|
|
62
|
+
export type { RichParseError, ParseResultWithErrors };
|
|
63
|
+
/**
|
|
64
|
+
* Result from parseWithErrors - includes rich error information on failure.
|
|
65
|
+
*/
|
|
66
|
+
export interface ParseWithErrorsResult<T extends ASTNode<string, unknown> = ASTNode<string, unknown>> {
|
|
67
|
+
/** Whether parsing was successful */
|
|
68
|
+
readonly success: boolean;
|
|
69
|
+
/** The parsed AST node (only present if success is true) */
|
|
70
|
+
readonly ast?: T;
|
|
71
|
+
/** Remaining unparsed input (only present if success is true) */
|
|
72
|
+
readonly remaining?: string;
|
|
73
|
+
/** Parse error information (only present if success is false) */
|
|
74
|
+
readonly error?: RichParseError;
|
|
75
|
+
/** Original input string */
|
|
76
|
+
readonly input: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Parse input with rich error information.
|
|
80
|
+
*
|
|
81
|
+
* Unlike `parse()` which returns an empty array on failure, this function
|
|
82
|
+
* returns detailed error information including:
|
|
83
|
+
* - Position (line, column, offset)
|
|
84
|
+
* - Error message
|
|
85
|
+
* - Source snippet showing where the error occurred
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* const result = parseWithErrors([add], "1 + ", context);
|
|
90
|
+
* if (!result.success) {
|
|
91
|
+
* console.log(result.error.message);
|
|
92
|
+
* // "No grammar rule matched at position 1:5: """
|
|
93
|
+
* console.log(result.error.snippet);
|
|
94
|
+
* // "1 + →"
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export declare function parseWithErrors<const TNodes extends readonly NodeSchema[], const TInput extends string, const TContext extends Context>(nodes: TNodes, input: TInput, context: TContext): ParseWithErrorsResult;
|
|
99
|
+
/**
|
|
100
|
+
* Format a parse error for display.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const result = parseWithErrors([add], "1 + ", context);
|
|
105
|
+
* if (!result.success) {
|
|
106
|
+
* console.log(formatParseError(result.error));
|
|
107
|
+
* // Error at line 1, column 5:
|
|
108
|
+
* // No grammar rule matched at position 1:5: ""
|
|
109
|
+
* //
|
|
110
|
+
* // 1 + →
|
|
111
|
+
* }
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare function formatParseError(error: RichParseError): string;
|
|
115
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/runtime/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EACV,UAAU,EAEV,YAAY,EACZ,WAAW,EACX,UAAU,EAEX,MAAM,oBAAoB,CAAC;AAa5B,OAAO,EACL,OAAO,EAOR,MAAM,uBAAuB,CAAC;AA2E/B,gEAAgE;AAGhE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;kBAQjB,CAAC;AAEX,6DAA6D;AAC7D,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IACjF,EAAE,GACF,CAAC,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;AAoBrB;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA+F1D;AA6KD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,UAAU,EAAE,GAAG,OAAO,CAuBtE;AA4TD;;;;;;GAMG;AACH,wBAAgB,KAAK,CACnB,KAAK,CAAC,MAAM,SAAS,SAAS,UAAU,EAAE,EAC1C,KAAK,CAAC,MAAM,SAAS,MAAM,EAC3B,KAAK,CAAC,QAAQ,SAAS,OAAO,EAE9B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,QAAQ,GAChB,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAOjD;AAMD,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAG3B,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,qBAAqB,CACpC,CAAC,SAAS,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;IAE7D,qCAAqC;IACrC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjB,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAChC,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAC7B,KAAK,CAAC,MAAM,SAAS,SAAS,UAAU,EAAE,EAC1C,KAAK,CAAC,MAAM,SAAS,MAAM,EAC3B,KAAK,CAAC,QAAQ,SAAS,OAAO,EAC9B,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,qBAAqB,CA+BxE;AAsCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAmB9D"}
|