@rcrsr/rill 0.1.0
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/LICENSE +21 -0
- package/README.md +187 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +69 -0
- package/dist/cli.js.map +1 -0
- package/dist/demo.d.ts +6 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/demo.js +121 -0
- package/dist/demo.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/lexer/errors.d.ts +9 -0
- package/dist/lexer/errors.d.ts.map +1 -0
- package/dist/lexer/errors.js +12 -0
- package/dist/lexer/errors.js.map +1 -0
- package/dist/lexer/helpers.d.ts +14 -0
- package/dist/lexer/helpers.d.ts.map +1 -0
- package/dist/lexer/helpers.js +30 -0
- package/dist/lexer/helpers.js.map +1 -0
- package/dist/lexer/index.d.ts +8 -0
- package/dist/lexer/index.d.ts.map +1 -0
- package/dist/lexer/index.js +8 -0
- package/dist/lexer/index.js.map +1 -0
- package/dist/lexer/operators.d.ts +11 -0
- package/dist/lexer/operators.d.ts.map +1 -0
- package/dist/lexer/operators.js +58 -0
- package/dist/lexer/operators.js.map +1 -0
- package/dist/lexer/readers.d.ts +12 -0
- package/dist/lexer/readers.d.ts.map +1 -0
- package/dist/lexer/readers.js +144 -0
- package/dist/lexer/readers.js.map +1 -0
- package/dist/lexer/state.d.ts +18 -0
- package/dist/lexer/state.d.ts.map +1 -0
- package/dist/lexer/state.js +37 -0
- package/dist/lexer/state.js.map +1 -0
- package/dist/lexer/tokenizer.d.ts +9 -0
- package/dist/lexer/tokenizer.d.ts.map +1 -0
- package/dist/lexer/tokenizer.js +100 -0
- package/dist/lexer/tokenizer.js.map +1 -0
- package/dist/lexer.d.ts +19 -0
- package/dist/lexer.d.ts.map +1 -0
- package/dist/lexer.js +344 -0
- package/dist/lexer.js.map +1 -0
- package/dist/parser/arithmetic.d.ts +16 -0
- package/dist/parser/arithmetic.d.ts.map +1 -0
- package/dist/parser/arithmetic.js +128 -0
- package/dist/parser/arithmetic.js.map +1 -0
- package/dist/parser/boolean.d.ts +15 -0
- package/dist/parser/boolean.d.ts.map +1 -0
- package/dist/parser/boolean.js +20 -0
- package/dist/parser/boolean.js.map +1 -0
- package/dist/parser/control-flow.d.ts +56 -0
- package/dist/parser/control-flow.d.ts.map +1 -0
- package/dist/parser/control-flow.js +167 -0
- package/dist/parser/control-flow.js.map +1 -0
- package/dist/parser/expressions.d.ts +23 -0
- package/dist/parser/expressions.d.ts.map +1 -0
- package/dist/parser/expressions.js +950 -0
- package/dist/parser/expressions.js.map +1 -0
- package/dist/parser/extraction.d.ts +48 -0
- package/dist/parser/extraction.d.ts.map +1 -0
- package/dist/parser/extraction.js +279 -0
- package/dist/parser/extraction.js.map +1 -0
- package/dist/parser/functions.d.ts +20 -0
- package/dist/parser/functions.d.ts.map +1 -0
- package/dist/parser/functions.js +96 -0
- package/dist/parser/functions.js.map +1 -0
- package/dist/parser/helpers.d.ts +94 -0
- package/dist/parser/helpers.d.ts.map +1 -0
- package/dist/parser/helpers.js +225 -0
- package/dist/parser/helpers.js.map +1 -0
- package/dist/parser/index.d.ts +49 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +73 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/literals.d.ts +37 -0
- package/dist/parser/literals.d.ts.map +1 -0
- package/dist/parser/literals.js +373 -0
- package/dist/parser/literals.js.map +1 -0
- package/dist/parser/parser-collect.d.ts +16 -0
- package/dist/parser/parser-collect.d.ts.map +1 -0
- package/dist/parser/parser-collect.js +125 -0
- package/dist/parser/parser-collect.js.map +1 -0
- package/dist/parser/parser-control.d.ts +20 -0
- package/dist/parser/parser-control.d.ts.map +1 -0
- package/dist/parser/parser-control.js +120 -0
- package/dist/parser/parser-control.js.map +1 -0
- package/dist/parser/parser-expr.d.ts +37 -0
- package/dist/parser/parser-expr.d.ts.map +1 -0
- package/dist/parser/parser-expr.js +639 -0
- package/dist/parser/parser-expr.js.map +1 -0
- package/dist/parser/parser-extract.d.ts +17 -0
- package/dist/parser/parser-extract.d.ts.map +1 -0
- package/dist/parser/parser-extract.js +222 -0
- package/dist/parser/parser-extract.js.map +1 -0
- package/dist/parser/parser-functions.d.ts +21 -0
- package/dist/parser/parser-functions.d.ts.map +1 -0
- package/dist/parser/parser-functions.js +155 -0
- package/dist/parser/parser-functions.js.map +1 -0
- package/dist/parser/parser-literals.d.ts +22 -0
- package/dist/parser/parser-literals.d.ts.map +1 -0
- package/dist/parser/parser-literals.js +288 -0
- package/dist/parser/parser-literals.js.map +1 -0
- package/dist/parser/parser-script.d.ts +21 -0
- package/dist/parser/parser-script.d.ts.map +1 -0
- package/dist/parser/parser-script.js +174 -0
- package/dist/parser/parser-script.js.map +1 -0
- package/dist/parser/parser-variables.d.ts +20 -0
- package/dist/parser/parser-variables.d.ts.map +1 -0
- package/dist/parser/parser-variables.js +146 -0
- package/dist/parser/parser-variables.js.map +1 -0
- package/dist/parser/parser.d.ts +49 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/parser/parser.js +54 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/parser/script.d.ts +14 -0
- package/dist/parser/script.d.ts.map +1 -0
- package/dist/parser/script.js +196 -0
- package/dist/parser/script.js.map +1 -0
- package/dist/parser/state.d.ts +40 -0
- package/dist/parser/state.d.ts.map +1 -0
- package/dist/parser/state.js +129 -0
- package/dist/parser/state.js.map +1 -0
- package/dist/parser/variables.d.ts +10 -0
- package/dist/parser/variables.d.ts.map +1 -0
- package/dist/parser/variables.js +215 -0
- package/dist/parser/variables.js.map +1 -0
- package/dist/runtime/ast-equals.d.ts +13 -0
- package/dist/runtime/ast-equals.d.ts.map +1 -0
- package/dist/runtime/ast-equals.js +447 -0
- package/dist/runtime/ast-equals.js.map +1 -0
- package/dist/runtime/builtins.d.ts +13 -0
- package/dist/runtime/builtins.d.ts.map +1 -0
- package/dist/runtime/builtins.js +180 -0
- package/dist/runtime/builtins.js.map +1 -0
- package/dist/runtime/callable.d.ts +88 -0
- package/dist/runtime/callable.d.ts.map +1 -0
- package/dist/runtime/callable.js +98 -0
- package/dist/runtime/callable.js.map +1 -0
- package/dist/runtime/context.d.ts +13 -0
- package/dist/runtime/context.d.ts.map +1 -0
- package/dist/runtime/context.js +73 -0
- package/dist/runtime/context.js.map +1 -0
- package/dist/runtime/core/callable.d.ts +171 -0
- package/dist/runtime/core/callable.d.ts.map +1 -0
- package/dist/runtime/core/callable.js +246 -0
- package/dist/runtime/core/callable.js.map +1 -0
- package/dist/runtime/core/context.d.ts +29 -0
- package/dist/runtime/core/context.d.ts.map +1 -0
- package/dist/runtime/core/context.js +154 -0
- package/dist/runtime/core/context.js.map +1 -0
- package/dist/runtime/core/equals.d.ts +9 -0
- package/dist/runtime/core/equals.d.ts.map +1 -0
- package/dist/runtime/core/equals.js +381 -0
- package/dist/runtime/core/equals.js.map +1 -0
- package/dist/runtime/core/eval/base.d.ts +65 -0
- package/dist/runtime/core/eval/base.d.ts.map +1 -0
- package/dist/runtime/core/eval/base.js +112 -0
- package/dist/runtime/core/eval/base.js.map +1 -0
- package/dist/runtime/core/eval/evaluator.d.ts +47 -0
- package/dist/runtime/core/eval/evaluator.d.ts.map +1 -0
- package/dist/runtime/core/eval/evaluator.js +73 -0
- package/dist/runtime/core/eval/evaluator.js.map +1 -0
- package/dist/runtime/core/eval/index.d.ts +57 -0
- package/dist/runtime/core/eval/index.d.ts.map +1 -0
- package/dist/runtime/core/eval/index.js +95 -0
- package/dist/runtime/core/eval/index.js.map +1 -0
- package/dist/runtime/core/eval/mixins/annotations.d.ts +19 -0
- package/dist/runtime/core/eval/mixins/annotations.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/annotations.js +146 -0
- package/dist/runtime/core/eval/mixins/annotations.js.map +1 -0
- package/dist/runtime/core/eval/mixins/closures.d.ts +49 -0
- package/dist/runtime/core/eval/mixins/closures.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/closures.js +479 -0
- package/dist/runtime/core/eval/mixins/closures.js.map +1 -0
- package/dist/runtime/core/eval/mixins/collections.d.ts +24 -0
- package/dist/runtime/core/eval/mixins/collections.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/collections.js +466 -0
- package/dist/runtime/core/eval/mixins/collections.js.map +1 -0
- package/dist/runtime/core/eval/mixins/control-flow.d.ts +27 -0
- package/dist/runtime/core/eval/mixins/control-flow.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/control-flow.js +369 -0
- package/dist/runtime/core/eval/mixins/control-flow.js.map +1 -0
- package/dist/runtime/core/eval/mixins/core.d.ts +24 -0
- package/dist/runtime/core/eval/mixins/core.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/core.js +335 -0
- package/dist/runtime/core/eval/mixins/core.js.map +1 -0
- package/dist/runtime/core/eval/mixins/expressions.d.ts +19 -0
- package/dist/runtime/core/eval/mixins/expressions.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/expressions.js +202 -0
- package/dist/runtime/core/eval/mixins/expressions.js.map +1 -0
- package/dist/runtime/core/eval/mixins/extraction.d.ts +10 -0
- package/dist/runtime/core/eval/mixins/extraction.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/extraction.js +250 -0
- package/dist/runtime/core/eval/mixins/extraction.js.map +1 -0
- package/dist/runtime/core/eval/mixins/literals.d.ts +23 -0
- package/dist/runtime/core/eval/mixins/literals.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/literals.js +180 -0
- package/dist/runtime/core/eval/mixins/literals.js.map +1 -0
- package/dist/runtime/core/eval/mixins/types.d.ts +20 -0
- package/dist/runtime/core/eval/mixins/types.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/types.js +109 -0
- package/dist/runtime/core/eval/mixins/types.js.map +1 -0
- package/dist/runtime/core/eval/mixins/variables.d.ts +34 -0
- package/dist/runtime/core/eval/mixins/variables.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/variables.js +247 -0
- package/dist/runtime/core/eval/mixins/variables.js.map +1 -0
- package/dist/runtime/core/eval/types.d.ts +41 -0
- package/dist/runtime/core/eval/types.d.ts.map +1 -0
- package/dist/runtime/core/eval/types.js +10 -0
- package/dist/runtime/core/eval/types.js.map +1 -0
- package/dist/runtime/core/evaluate.d.ts +42 -0
- package/dist/runtime/core/evaluate.d.ts.map +1 -0
- package/dist/runtime/core/evaluate.debug.js +1251 -0
- package/dist/runtime/core/evaluate.js +1913 -0
- package/dist/runtime/core/evaluate.js.map +1 -0
- package/dist/runtime/core/execute.d.ts +26 -0
- package/dist/runtime/core/execute.d.ts.map +1 -0
- package/dist/runtime/core/execute.js +177 -0
- package/dist/runtime/core/execute.js.map +1 -0
- package/dist/runtime/core/signals.d.ts +19 -0
- package/dist/runtime/core/signals.d.ts.map +1 -0
- package/dist/runtime/core/signals.js +26 -0
- package/dist/runtime/core/signals.js.map +1 -0
- package/dist/runtime/core/types.d.ts +177 -0
- package/dist/runtime/core/types.d.ts.map +1 -0
- package/dist/runtime/core/types.js +50 -0
- package/dist/runtime/core/types.js.map +1 -0
- package/dist/runtime/core/values.d.ts +66 -0
- package/dist/runtime/core/values.d.ts.map +1 -0
- package/dist/runtime/core/values.js +240 -0
- package/dist/runtime/core/values.js.map +1 -0
- package/dist/runtime/evaluate.d.ts +32 -0
- package/dist/runtime/evaluate.d.ts.map +1 -0
- package/dist/runtime/evaluate.js +1111 -0
- package/dist/runtime/evaluate.js.map +1 -0
- package/dist/runtime/execute.d.ts +26 -0
- package/dist/runtime/execute.d.ts.map +1 -0
- package/dist/runtime/execute.js +121 -0
- package/dist/runtime/execute.js.map +1 -0
- package/dist/runtime/ext/builtins.d.ts +16 -0
- package/dist/runtime/ext/builtins.d.ts.map +1 -0
- package/dist/runtime/ext/builtins.js +528 -0
- package/dist/runtime/ext/builtins.js.map +1 -0
- package/dist/runtime/ext/content-parser.d.ts +83 -0
- package/dist/runtime/ext/content-parser.d.ts.map +1 -0
- package/dist/runtime/ext/content-parser.js +536 -0
- package/dist/runtime/ext/content-parser.js.map +1 -0
- package/dist/runtime/index.d.ts +28 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +34 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/signals.d.ts +19 -0
- package/dist/runtime/signals.d.ts.map +1 -0
- package/dist/runtime/signals.js +26 -0
- package/dist/runtime/signals.js.map +1 -0
- package/dist/runtime/types.d.ts +169 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +50 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/runtime/values.d.ts +50 -0
- package/dist/runtime/values.d.ts.map +1 -0
- package/dist/runtime/values.js +209 -0
- package/dist/runtime/values.js.map +1 -0
- package/dist/runtime.d.ts +254 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +2014 -0
- package/dist/runtime.js.map +1 -0
- package/dist/types.d.ts +752 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +189 -0
- package/dist/types.js.map +1 -0
- package/docs/00_INDEX.md +65 -0
- package/docs/01_guide.md +390 -0
- package/docs/02_types.md +399 -0
- package/docs/03_variables.md +314 -0
- package/docs/04_operators.md +551 -0
- package/docs/05_control-flow.md +350 -0
- package/docs/06_closures.md +353 -0
- package/docs/07_collections.md +686 -0
- package/docs/08_iterators.md +330 -0
- package/docs/09_strings.md +205 -0
- package/docs/10_parsing.md +366 -0
- package/docs/11_reference.md +350 -0
- package/docs/12_examples.md +771 -0
- package/docs/13_modules.md +519 -0
- package/docs/14_host-integration.md +826 -0
- package/docs/15_grammar.ebnf +693 -0
- package/docs/16_conventions.md +696 -0
- package/docs/99_llm-reference.txt +300 -0
- package/docs/assets/logo.png +0 -0
- package/package.json +70 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser Extension: Variable Parsing
|
|
3
|
+
* Variables and access chains
|
|
4
|
+
*/
|
|
5
|
+
import { Parser } from './parser.js';
|
|
6
|
+
import { TOKEN_TYPES } from '../types.js';
|
|
7
|
+
import { check, advance, expect, makeSpan } from './state.js';
|
|
8
|
+
import { isMethodCallWithArgs, VALID_TYPE_NAMES, parseTypeName, } from './helpers.js';
|
|
9
|
+
// ============================================================
|
|
10
|
+
// VARIABLE PARSING
|
|
11
|
+
// ============================================================
|
|
12
|
+
Parser.prototype.parseVariable = function () {
|
|
13
|
+
const start = this.state.tokens[this.state.pos].span.start;
|
|
14
|
+
if (check(this.state, TOKEN_TYPES.PIPE_VAR)) {
|
|
15
|
+
advance(this.state);
|
|
16
|
+
return this.makeVariableWithAccess(null, true, start);
|
|
17
|
+
}
|
|
18
|
+
const dollarToken = expect(this.state, TOKEN_TYPES.DOLLAR, 'Expected $');
|
|
19
|
+
if (dollarToken.value === '$@') {
|
|
20
|
+
return this.makeVariableWithAccess('@', false, start);
|
|
21
|
+
}
|
|
22
|
+
// Handle $ followed by access chain (no name): $[0], $.field
|
|
23
|
+
if (check(this.state, TOKEN_TYPES.LBRACKET) ||
|
|
24
|
+
check(this.state, TOKEN_TYPES.DOT) ||
|
|
25
|
+
check(this.state, TOKEN_TYPES.DOT_QUESTION)) {
|
|
26
|
+
return this.makeVariableWithAccess(null, true, start);
|
|
27
|
+
}
|
|
28
|
+
const nameToken = expect(this.state, TOKEN_TYPES.IDENTIFIER, 'Expected variable name');
|
|
29
|
+
return this.makeVariableWithAccess(nameToken.value, false, start);
|
|
30
|
+
};
|
|
31
|
+
Parser.prototype.makeVariableWithAccess = function (name, isPipeVar, start) {
|
|
32
|
+
const { accessChain, existenceCheck } = this.parseAccessChain();
|
|
33
|
+
let defaultValue = null;
|
|
34
|
+
if (check(this.state, TOKEN_TYPES.NULLISH_COALESCE) && !existenceCheck) {
|
|
35
|
+
advance(this.state);
|
|
36
|
+
defaultValue = this.parseDefaultValue();
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
type: 'Variable',
|
|
40
|
+
name,
|
|
41
|
+
isPipeVar,
|
|
42
|
+
accessChain,
|
|
43
|
+
defaultValue,
|
|
44
|
+
existenceCheck,
|
|
45
|
+
span: makeSpan(start, start),
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
Parser.prototype.parseAccessChain = function () {
|
|
49
|
+
const accessChain = [];
|
|
50
|
+
let existenceCheck = null;
|
|
51
|
+
while (check(this.state, TOKEN_TYPES.DOT, TOKEN_TYPES.DOT_QUESTION, TOKEN_TYPES.LBRACKET)) {
|
|
52
|
+
if (check(this.state, TOKEN_TYPES.DOT) &&
|
|
53
|
+
isMethodCallWithArgs(this.state)) {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
if (check(this.state, TOKEN_TYPES.LBRACKET)) {
|
|
57
|
+
advance(this.state);
|
|
58
|
+
const expression = this.parsePipeChain();
|
|
59
|
+
expect(this.state, TOKEN_TYPES.RBRACKET, 'Expected ] after index expression');
|
|
60
|
+
accessChain.push({ accessKind: 'bracket', expression });
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (check(this.state, TOKEN_TYPES.DOT_QUESTION)) {
|
|
64
|
+
advance(this.state);
|
|
65
|
+
const finalAccess = this.parseFieldAccessElement();
|
|
66
|
+
if (!finalAccess) {
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
let typeName = null;
|
|
70
|
+
if (check(this.state, TOKEN_TYPES.AMPERSAND)) {
|
|
71
|
+
advance(this.state);
|
|
72
|
+
typeName = parseTypeName(this.state, VALID_TYPE_NAMES);
|
|
73
|
+
}
|
|
74
|
+
existenceCheck = { finalAccess, typeName };
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
advance(this.state);
|
|
78
|
+
const access = this.parseFieldAccessElement();
|
|
79
|
+
if (!access) {
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
accessChain.push(access);
|
|
83
|
+
}
|
|
84
|
+
return { accessChain, existenceCheck };
|
|
85
|
+
};
|
|
86
|
+
Parser.prototype.parseFieldAccessElement = function () {
|
|
87
|
+
if (check(this.state, TOKEN_TYPES.DOLLAR)) {
|
|
88
|
+
advance(this.state);
|
|
89
|
+
const nameToken = expect(this.state, TOKEN_TYPES.IDENTIFIER, 'Expected variable name after .$');
|
|
90
|
+
return { kind: 'variable', variableName: nameToken.value };
|
|
91
|
+
}
|
|
92
|
+
if (check(this.state, TOKEN_TYPES.LPAREN)) {
|
|
93
|
+
return this.parseComputedOrAlternatives();
|
|
94
|
+
}
|
|
95
|
+
if (check(this.state, TOKEN_TYPES.LBRACE)) {
|
|
96
|
+
const block = this.parseBlock();
|
|
97
|
+
return { kind: 'block', block };
|
|
98
|
+
}
|
|
99
|
+
if (check(this.state, TOKEN_TYPES.IDENTIFIER)) {
|
|
100
|
+
return { kind: 'literal', field: advance(this.state).value };
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
};
|
|
104
|
+
Parser.prototype.parseComputedOrAlternatives = function () {
|
|
105
|
+
advance(this.state);
|
|
106
|
+
const alternatives = this.tryParseAlternatives();
|
|
107
|
+
if (alternatives) {
|
|
108
|
+
expect(this.state, TOKEN_TYPES.RPAREN, 'Expected ) after alternatives');
|
|
109
|
+
return { kind: 'alternatives', alternatives };
|
|
110
|
+
}
|
|
111
|
+
const expression = this.parsePipeChain();
|
|
112
|
+
expect(this.state, TOKEN_TYPES.RPAREN, 'Expected ) after expression');
|
|
113
|
+
return { kind: 'computed', expression };
|
|
114
|
+
};
|
|
115
|
+
Parser.prototype.tryParseAlternatives = function () {
|
|
116
|
+
const savedPos = this.state.pos;
|
|
117
|
+
const alternatives = [];
|
|
118
|
+
if (!check(this.state, TOKEN_TYPES.IDENTIFIER)) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
alternatives.push(advance(this.state).value);
|
|
122
|
+
if (!check(this.state, TOKEN_TYPES.OR)) {
|
|
123
|
+
this.state.pos = savedPos;
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
while (check(this.state, TOKEN_TYPES.OR)) {
|
|
127
|
+
advance(this.state);
|
|
128
|
+
if (!check(this.state, TOKEN_TYPES.IDENTIFIER)) {
|
|
129
|
+
this.state.pos = savedPos;
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
alternatives.push(advance(this.state).value);
|
|
133
|
+
}
|
|
134
|
+
if (!check(this.state, TOKEN_TYPES.RPAREN)) {
|
|
135
|
+
this.state.pos = savedPos;
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
return alternatives;
|
|
139
|
+
};
|
|
140
|
+
Parser.prototype.parseDefaultValue = function () {
|
|
141
|
+
if (check(this.state, TOKEN_TYPES.LBRACE)) {
|
|
142
|
+
return this.parseBlock();
|
|
143
|
+
}
|
|
144
|
+
return this.parsePipeChain();
|
|
145
|
+
};
|
|
146
|
+
//# sourceMappingURL=parser-variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser-variables.js","sourceRoot":"","sources":["../../src/parser/parser-variables.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser Class - Core
|
|
3
|
+
*
|
|
4
|
+
* Defines the Parser class structure. Methods are added via prototype
|
|
5
|
+
* extension from separate modules, using TypeScript declaration merging
|
|
6
|
+
* for type safety.
|
|
7
|
+
*
|
|
8
|
+
* This architecture eliminates circular dependencies while keeping
|
|
9
|
+
* the codebase modular and organized by concern.
|
|
10
|
+
*/
|
|
11
|
+
import type { ScriptNode, Token } from '../types.js';
|
|
12
|
+
import { ParseError } from '../types.js';
|
|
13
|
+
import { type ParserState } from './state.js';
|
|
14
|
+
/**
|
|
15
|
+
* Parser class that converts tokens into an AST.
|
|
16
|
+
*
|
|
17
|
+
* Methods are organized across multiple files:
|
|
18
|
+
* - parser-script.ts: Script, statement, annotation parsing
|
|
19
|
+
* - parser-expr.ts: Expressions, precedence chain, pipe targets
|
|
20
|
+
* - parser-literals.ts: Literals, strings, tuples, dicts, closures
|
|
21
|
+
* - parser-variables.ts: Variables, access chains
|
|
22
|
+
* - parser-control.ts: Conditionals, loops, blocks
|
|
23
|
+
* - parser-functions.ts: Function calls, methods, type operations
|
|
24
|
+
* - parser-collect.ts: Collection operators (each, map, fold, filter)
|
|
25
|
+
* - parser-extract.ts: Extraction operators (destructure, slice, spread)
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const parser = new Parser(tokens, { recoveryMode: false });
|
|
30
|
+
* const ast = parser.parse();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class Parser {
|
|
34
|
+
/** Parser state including tokens, position, and error collection */
|
|
35
|
+
state: ParserState;
|
|
36
|
+
constructor(tokens: Token[], options?: {
|
|
37
|
+
recoveryMode?: boolean;
|
|
38
|
+
source?: string;
|
|
39
|
+
});
|
|
40
|
+
/**
|
|
41
|
+
* Parse tokens into a complete AST.
|
|
42
|
+
*/
|
|
43
|
+
parse(): ScriptNode;
|
|
44
|
+
/**
|
|
45
|
+
* Get collected errors (for recovery mode).
|
|
46
|
+
*/
|
|
47
|
+
get errors(): ParseError[];
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,YAAY,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,MAAM;IACjB,oEAAoE;IACpE,KAAK,EAAE,WAAW,CAAC;gBAGjB,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAQvD;;OAEG;IACH,KAAK,IAAI,UAAU;IAInB;;OAEG;IACH,IAAI,MAAM,IAAI,UAAU,EAAE,CAEzB;CACF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser Class - Core
|
|
3
|
+
*
|
|
4
|
+
* Defines the Parser class structure. Methods are added via prototype
|
|
5
|
+
* extension from separate modules, using TypeScript declaration merging
|
|
6
|
+
* for type safety.
|
|
7
|
+
*
|
|
8
|
+
* This architecture eliminates circular dependencies while keeping
|
|
9
|
+
* the codebase modular and organized by concern.
|
|
10
|
+
*/
|
|
11
|
+
import { ParseError } from '../types.js';
|
|
12
|
+
import { createParserState } from './state.js';
|
|
13
|
+
/**
|
|
14
|
+
* Parser class that converts tokens into an AST.
|
|
15
|
+
*
|
|
16
|
+
* Methods are organized across multiple files:
|
|
17
|
+
* - parser-script.ts: Script, statement, annotation parsing
|
|
18
|
+
* - parser-expr.ts: Expressions, precedence chain, pipe targets
|
|
19
|
+
* - parser-literals.ts: Literals, strings, tuples, dicts, closures
|
|
20
|
+
* - parser-variables.ts: Variables, access chains
|
|
21
|
+
* - parser-control.ts: Conditionals, loops, blocks
|
|
22
|
+
* - parser-functions.ts: Function calls, methods, type operations
|
|
23
|
+
* - parser-collect.ts: Collection operators (each, map, fold, filter)
|
|
24
|
+
* - parser-extract.ts: Extraction operators (destructure, slice, spread)
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const parser = new Parser(tokens, { recoveryMode: false });
|
|
29
|
+
* const ast = parser.parse();
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export class Parser {
|
|
33
|
+
/** Parser state including tokens, position, and error collection */
|
|
34
|
+
state;
|
|
35
|
+
constructor(tokens, options) {
|
|
36
|
+
this.state = createParserState(tokens, {
|
|
37
|
+
recoveryMode: options?.recoveryMode ?? false,
|
|
38
|
+
source: options?.source ?? '',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parse tokens into a complete AST.
|
|
43
|
+
*/
|
|
44
|
+
parse() {
|
|
45
|
+
return this.parseScript();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get collected errors (for recovery mode).
|
|
49
|
+
*/
|
|
50
|
+
get errors() {
|
|
51
|
+
return this.state.errors;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAoB,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,MAAM;IACjB,oEAAoE;IACpE,KAAK,CAAc;IAEnB,YACE,MAAe,EACf,OAAqD;QAErD,IAAI,CAAC,KAAK,GAAG,iBAAiB,CAAC,MAAM,EAAE;YACrC,YAAY,EAAE,OAAO,EAAE,YAAY,IAAI,KAAK;YAC5C,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;SAC9B,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Script Structure Parsing
|
|
3
|
+
* Script, frontmatter, statements, and annotations
|
|
4
|
+
*/
|
|
5
|
+
import type { AnnotatedStatementNode, ScriptNode, StatementNode } from '../types.js';
|
|
6
|
+
import { type ParserState } from './state.js';
|
|
7
|
+
export declare function parseScript(state: ParserState): ScriptNode;
|
|
8
|
+
/**
|
|
9
|
+
* Parse a statement: optionally annotated pipe chain expression.
|
|
10
|
+
* Annotations prefix statements with ^(key: value, ...) syntax.
|
|
11
|
+
* Termination (capture/break/return) is now part of PipeChainNode.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseStatement(state: ParserState): StatementNode | AnnotatedStatementNode;
|
|
14
|
+
//# sourceMappingURL=script.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"script.d.ts","sourceRoot":"","sources":["../../src/parser/script.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,sBAAsB,EAKtB,UAAU,EAEV,aAAa,EACd,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,KAAK,WAAW,EAQjB,MAAM,YAAY,CAAC;AAQpB,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,CAiD1D;AA6DD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,GACjB,aAAa,GAAG,sBAAsB,CAexC"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Script Structure Parsing
|
|
3
|
+
* Script, frontmatter, statements, and annotations
|
|
4
|
+
*/
|
|
5
|
+
import { ParseError, TOKEN_TYPES } from '../types.js';
|
|
6
|
+
import { check, advance, expect, current, isAtEnd, skipNewlines, makeSpan, } from './state.js';
|
|
7
|
+
import { parseExpression } from './expressions.js';
|
|
8
|
+
import { setParseStatement } from './control-flow.js';
|
|
9
|
+
// ============================================================
|
|
10
|
+
// SCRIPT PARSING
|
|
11
|
+
// ============================================================
|
|
12
|
+
export function parseScript(state) {
|
|
13
|
+
const start = current(state).span.start;
|
|
14
|
+
skipNewlines(state);
|
|
15
|
+
// Optional frontmatter
|
|
16
|
+
let frontmatter = null;
|
|
17
|
+
if (check(state, TOKEN_TYPES.FRONTMATTER_DELIM)) {
|
|
18
|
+
frontmatter = parseFrontmatter(state);
|
|
19
|
+
}
|
|
20
|
+
skipNewlines(state);
|
|
21
|
+
// Statements
|
|
22
|
+
const statements = [];
|
|
23
|
+
while (!isAtEnd(state)) {
|
|
24
|
+
skipNewlines(state);
|
|
25
|
+
if (isAtEnd(state))
|
|
26
|
+
break;
|
|
27
|
+
if (state.recoveryMode) {
|
|
28
|
+
// Recovery mode: catch errors and create ErrorNode
|
|
29
|
+
const stmtStart = current(state).span.start;
|
|
30
|
+
try {
|
|
31
|
+
statements.push(parseStatement(state));
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
if (err instanceof ParseError) {
|
|
35
|
+
state.errors.push(err);
|
|
36
|
+
// Create ErrorNode and skip to next statement boundary
|
|
37
|
+
const errorNode = recoverToNextStatement(state, stmtStart, err.message);
|
|
38
|
+
statements.push(errorNode);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
throw err; // Re-throw non-parse errors
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Normal mode: let errors propagate
|
|
47
|
+
statements.push(parseStatement(state));
|
|
48
|
+
}
|
|
49
|
+
skipNewlines(state);
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
type: 'Script',
|
|
53
|
+
frontmatter,
|
|
54
|
+
statements,
|
|
55
|
+
span: makeSpan(start, current(state).span.end),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Recovery helper: skip tokens until we find a likely statement boundary.
|
|
60
|
+
* Returns an ErrorNode containing the skipped content.
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
function recoverToNextStatement(state, startLocation, message) {
|
|
64
|
+
const startOffset = startLocation.offset;
|
|
65
|
+
let endOffset = startOffset;
|
|
66
|
+
// Skip tokens until we hit a newline or EOF (statement boundary)
|
|
67
|
+
while (!isAtEnd(state) && !check(state, TOKEN_TYPES.NEWLINE)) {
|
|
68
|
+
endOffset = current(state).span.end.offset;
|
|
69
|
+
advance(state);
|
|
70
|
+
}
|
|
71
|
+
// Extract the skipped text from source
|
|
72
|
+
const text = state.source.slice(startOffset, endOffset);
|
|
73
|
+
return {
|
|
74
|
+
type: 'Error',
|
|
75
|
+
message,
|
|
76
|
+
text,
|
|
77
|
+
span: makeSpan(startLocation, current(state).span.start),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// ============================================================
|
|
81
|
+
// FRONTMATTER PARSING
|
|
82
|
+
// ============================================================
|
|
83
|
+
function parseFrontmatter(state) {
|
|
84
|
+
const start = current(state).span.start;
|
|
85
|
+
expect(state, TOKEN_TYPES.FRONTMATTER_DELIM, 'Expected ---');
|
|
86
|
+
skipNewlines(state);
|
|
87
|
+
// Collect all content until next ---
|
|
88
|
+
let content = '';
|
|
89
|
+
while (!check(state, TOKEN_TYPES.FRONTMATTER_DELIM) && !isAtEnd(state)) {
|
|
90
|
+
const token = advance(state);
|
|
91
|
+
content += token.value;
|
|
92
|
+
}
|
|
93
|
+
expect(state, TOKEN_TYPES.FRONTMATTER_DELIM, 'Expected closing ---');
|
|
94
|
+
return {
|
|
95
|
+
type: 'Frontmatter',
|
|
96
|
+
content: content.trim(),
|
|
97
|
+
span: makeSpan(start, current(state).span.end),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
// ============================================================
|
|
101
|
+
// STATEMENT PARSING
|
|
102
|
+
// ============================================================
|
|
103
|
+
/**
|
|
104
|
+
* Parse a statement: optionally annotated pipe chain expression.
|
|
105
|
+
* Annotations prefix statements with ^(key: value, ...) syntax.
|
|
106
|
+
* Termination (capture/break/return) is now part of PipeChainNode.
|
|
107
|
+
*/
|
|
108
|
+
export function parseStatement(state) {
|
|
109
|
+
const start = current(state).span.start;
|
|
110
|
+
// Check for annotation prefix: ^(...)
|
|
111
|
+
if (check(state, TOKEN_TYPES.CARET)) {
|
|
112
|
+
return parseAnnotatedStatement(state);
|
|
113
|
+
}
|
|
114
|
+
const expression = parseExpression(state);
|
|
115
|
+
return {
|
|
116
|
+
type: 'Statement',
|
|
117
|
+
expression,
|
|
118
|
+
span: makeSpan(start, current(state).span.end),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
// ============================================================
|
|
122
|
+
// ANNOTATION PARSING
|
|
123
|
+
// ============================================================
|
|
124
|
+
/**
|
|
125
|
+
* Parse an annotated statement: ^(key: value, ...) statement
|
|
126
|
+
* Annotations modify operational parameters for statements.
|
|
127
|
+
*/
|
|
128
|
+
function parseAnnotatedStatement(state) {
|
|
129
|
+
const start = current(state).span.start;
|
|
130
|
+
expect(state, TOKEN_TYPES.CARET, 'Expected ^');
|
|
131
|
+
expect(state, TOKEN_TYPES.LPAREN, 'Expected (');
|
|
132
|
+
const annotations = parseAnnotationArgs(state);
|
|
133
|
+
expect(state, TOKEN_TYPES.RPAREN, 'Expected )');
|
|
134
|
+
// Parse the inner statement (which could also be annotated)
|
|
135
|
+
const statement = parseStatement(state);
|
|
136
|
+
// If inner is annotated, wrap it; otherwise use directly
|
|
137
|
+
const innerStatement = statement.type === 'AnnotatedStatement'
|
|
138
|
+
? {
|
|
139
|
+
type: 'Statement',
|
|
140
|
+
expression: statement.statement.expression,
|
|
141
|
+
span: statement.span,
|
|
142
|
+
}
|
|
143
|
+
: statement;
|
|
144
|
+
return {
|
|
145
|
+
type: 'AnnotatedStatement',
|
|
146
|
+
annotations,
|
|
147
|
+
statement: innerStatement,
|
|
148
|
+
span: makeSpan(start, current(state).span.end),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Parse annotation arguments: key: value, *spread, ...
|
|
153
|
+
*/
|
|
154
|
+
function parseAnnotationArgs(state) {
|
|
155
|
+
const args = [];
|
|
156
|
+
if (check(state, TOKEN_TYPES.RPAREN)) {
|
|
157
|
+
return args; // Empty annotation list
|
|
158
|
+
}
|
|
159
|
+
args.push(parseAnnotationArg(state));
|
|
160
|
+
while (check(state, TOKEN_TYPES.COMMA)) {
|
|
161
|
+
advance(state); // consume comma
|
|
162
|
+
if (check(state, TOKEN_TYPES.RPAREN))
|
|
163
|
+
break; // trailing comma
|
|
164
|
+
args.push(parseAnnotationArg(state));
|
|
165
|
+
}
|
|
166
|
+
return args;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Parse a single annotation argument: named (key: value) or spread (*expr)
|
|
170
|
+
*/
|
|
171
|
+
function parseAnnotationArg(state) {
|
|
172
|
+
const start = current(state).span.start;
|
|
173
|
+
// Spread argument: *expr
|
|
174
|
+
if (check(state, TOKEN_TYPES.STAR)) {
|
|
175
|
+
advance(state); // consume *
|
|
176
|
+
const expression = parseExpression(state);
|
|
177
|
+
return {
|
|
178
|
+
type: 'SpreadArg',
|
|
179
|
+
expression,
|
|
180
|
+
span: makeSpan(start, current(state).span.end),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// Named argument: key: value
|
|
184
|
+
const nameToken = expect(state, TOKEN_TYPES.IDENTIFIER, 'Expected annotation name');
|
|
185
|
+
expect(state, TOKEN_TYPES.COLON, 'Expected :');
|
|
186
|
+
const value = parseExpression(state);
|
|
187
|
+
return {
|
|
188
|
+
type: 'NamedArg',
|
|
189
|
+
name: nameToken.value,
|
|
190
|
+
value,
|
|
191
|
+
span: makeSpan(start, current(state).span.end),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
// Wire up the circular dependency
|
|
195
|
+
setParseStatement(parseStatement);
|
|
196
|
+
//# sourceMappingURL=script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"script.js","sourceRoot":"","sources":["../../src/parser/script.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAEL,KAAK,EACL,OAAO,EACP,MAAM,EACN,OAAO,EACP,OAAO,EACP,YAAY,EACZ,QAAQ,GACT,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,+DAA+D;AAC/D,iBAAiB;AACjB,+DAA+D;AAE/D,MAAM,UAAU,WAAW,CAAC,KAAkB;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IACxC,YAAY,CAAC,KAAK,CAAC,CAAC;IAEpB,uBAAuB;IACvB,IAAI,WAAW,GAA2B,IAAI,CAAC;IAC/C,IAAI,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAChD,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IACD,YAAY,CAAC,KAAK,CAAC,CAAC;IAEpB,aAAa;IACb,MAAM,UAAU,GAA2D,EAAE,CAAC;IAC9E,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,IAAI,OAAO,CAAC,KAAK,CAAC;YAAE,MAAM;QAE1B,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACvB,mDAAmD;YACnD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YAC5C,IAAI,CAAC;gBACH,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,UAAU,EAAE,CAAC;oBAC9B,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACvB,uDAAuD;oBACvD,MAAM,SAAS,GAAG,sBAAsB,CACtC,KAAK,EACL,SAAS,EACT,GAAG,CAAC,OAAO,CACZ,CAAC;oBACF,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,CAAC,CAAC,4BAA4B;gBACzC,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,oCAAoC;YACpC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,WAAW;QACX,UAAU;QACV,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAC7B,KAAkB,EAClB,aAA+D,EAC/D,OAAe;IAEf,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IACzC,IAAI,SAAS,GAAG,WAAW,CAAC;IAE5B,iEAAiE;IACjE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7D,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;QAC3C,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;IAED,uCAAuC;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAExD,OAAO;QACL,IAAI,EAAE,OAAO;QACb,OAAO;QACP,IAAI;QACJ,IAAI,EAAE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;KACzD,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,sBAAsB;AACtB,+DAA+D;AAE/D,SAAS,gBAAgB,CAAC,KAAkB;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IACxC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;IAC7D,YAAY,CAAC,KAAK,CAAC,CAAC;IAEpB,qCAAqC;IACrC,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,iBAAiB,EAAE,sBAAsB,CAAC,CAAC;IAErE,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;QACvB,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,oBAAoB;AACpB,+DAA+D;AAE/D;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAkB;IAElB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IAExC,sCAAsC;IACtC,IAAI,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,uBAAuB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAE1C,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,UAAU;QACV,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,qBAAqB;AACrB,+DAA+D;AAE/D;;;GAGG;AACH,SAAS,uBAAuB,CAAC,KAAkB;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IACxC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC/C,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAEhD,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAE/C,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAEhD,4DAA4D;IAC5D,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAExC,yDAAyD;IACzD,MAAM,cAAc,GAClB,SAAS,CAAC,IAAI,KAAK,oBAAoB;QACrC,CAAC,CAAC;YACE,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,SAAS,CAAC,SAAS,CAAC,UAAU;YAC1C,IAAI,EAAE,SAAS,CAAC,IAAI;SACrB;QACH,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,IAAI,EAAE,oBAAoB;QAC1B,WAAW;QACX,SAAS,EAAE,cAAc;QACzB,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,KAAkB;IAC7C,MAAM,IAAI,GAAoB,EAAE,CAAC;IAEjC,IAAI,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,CAAC,wBAAwB;IACvC,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IAErC,OAAO,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB;QAChC,IAAI,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;YAAE,MAAM,CAAC,iBAAiB;QAC9D,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,KAAkB;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IAExC,yBAAyB;IACzB,IAAI,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY;QAC5B,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,UAAU;YACV,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;SACvB,CAAC;IAC5B,CAAC;IAED,6BAA6B;IAC7B,MAAM,SAAS,GAAG,MAAM,CACtB,KAAK,EACL,WAAW,CAAC,UAAU,EACtB,0BAA0B,CAC3B,CAAC;IACF,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAErC,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,SAAS,CAAC,KAAK;QACrB,KAAK;QACL,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;KACxB,CAAC;AAC3B,CAAC;AAED,kCAAkC;AAClC,iBAAiB,CAAC,cAAc,CAAC,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser State
|
|
3
|
+
* Core state management and token navigation utilities
|
|
4
|
+
*/
|
|
5
|
+
import type { SourceLocation, SourceSpan, Token } from '../types.js';
|
|
6
|
+
import { ParseError } from '../types.js';
|
|
7
|
+
export interface ParserState {
|
|
8
|
+
readonly tokens: Token[];
|
|
9
|
+
pos: number;
|
|
10
|
+
/** Recovery mode: collect errors instead of throwing */
|
|
11
|
+
readonly recoveryMode: boolean;
|
|
12
|
+
/** Errors collected during recovery mode parsing */
|
|
13
|
+
readonly errors: ParseError[];
|
|
14
|
+
/** Original source text (for error recovery) */
|
|
15
|
+
readonly source: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ParserStateOptions {
|
|
18
|
+
/** Enable recovery mode for IDE/tooling scenarios */
|
|
19
|
+
recoveryMode?: boolean;
|
|
20
|
+
/** Original source text (required for recovery mode) */
|
|
21
|
+
source?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function createParserState(tokens: Token[], options?: ParserStateOptions): ParserState;
|
|
24
|
+
/** @internal */
|
|
25
|
+
export declare function current(state: ParserState): Token;
|
|
26
|
+
/** @internal */
|
|
27
|
+
export declare function peek(state: ParserState, offset?: number): Token;
|
|
28
|
+
/** @internal */
|
|
29
|
+
export declare function isAtEnd(state: ParserState): boolean;
|
|
30
|
+
/** @internal */
|
|
31
|
+
export declare function check(state: ParserState, ...types: string[]): boolean;
|
|
32
|
+
/** @internal */
|
|
33
|
+
export declare function advance(state: ParserState): Token;
|
|
34
|
+
/** @internal */
|
|
35
|
+
export declare function expect(state: ParserState, type: string, message: string): Token;
|
|
36
|
+
/** @internal */
|
|
37
|
+
export declare function skipNewlines(state: ParserState): void;
|
|
38
|
+
/** @internal */
|
|
39
|
+
export declare function makeSpan(start: SourceLocation, end: SourceLocation): SourceSpan;
|
|
40
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/parser/state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,UAAU,EAAe,MAAM,aAAa,CAAC;AAMtD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;IAC9B,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAQb;AAMD,gBAAgB;AAChB,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,CAMjD;AAED,gBAAgB;AAChB,wBAAgB,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,SAAI,GAAG,KAAK,CAO1D;AAED,gBAAgB;AAChB,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAEnD;AAED,gBAAgB;AAChB,wBAAgB,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAErE;AAED,gBAAgB;AAChB,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,CAIjD;AAED,gBAAgB;AAChB,wBAAgB,MAAM,CACpB,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,KAAK,CAMP;AAED,gBAAgB;AAChB,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAErD;AAqED,gBAAgB;AAChB,wBAAgB,QAAQ,CACtB,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,cAAc,GAClB,UAAU,CAEZ"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser State
|
|
3
|
+
* Core state management and token navigation utilities
|
|
4
|
+
*/
|
|
5
|
+
import { ParseError, TOKEN_TYPES } from '../types.js';
|
|
6
|
+
export function createParserState(tokens, options = {}) {
|
|
7
|
+
return {
|
|
8
|
+
tokens,
|
|
9
|
+
pos: 0,
|
|
10
|
+
recoveryMode: options.recoveryMode ?? false,
|
|
11
|
+
errors: [],
|
|
12
|
+
source: options.source ?? '',
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
// ============================================================
|
|
16
|
+
// TOKEN NAVIGATION
|
|
17
|
+
// ============================================================
|
|
18
|
+
/** @internal */
|
|
19
|
+
export function current(state) {
|
|
20
|
+
const token = state.tokens[state.pos];
|
|
21
|
+
if (token)
|
|
22
|
+
return token;
|
|
23
|
+
const last = state.tokens[state.tokens.length - 1];
|
|
24
|
+
if (last)
|
|
25
|
+
return last;
|
|
26
|
+
throw new Error('No tokens available');
|
|
27
|
+
}
|
|
28
|
+
/** @internal */
|
|
29
|
+
export function peek(state, offset = 0) {
|
|
30
|
+
const idx = state.pos + offset;
|
|
31
|
+
const token = state.tokens[idx];
|
|
32
|
+
if (token)
|
|
33
|
+
return token;
|
|
34
|
+
const last = state.tokens[state.tokens.length - 1];
|
|
35
|
+
if (last)
|
|
36
|
+
return last;
|
|
37
|
+
throw new Error('No tokens available');
|
|
38
|
+
}
|
|
39
|
+
/** @internal */
|
|
40
|
+
export function isAtEnd(state) {
|
|
41
|
+
return current(state).type === TOKEN_TYPES.EOF;
|
|
42
|
+
}
|
|
43
|
+
/** @internal */
|
|
44
|
+
export function check(state, ...types) {
|
|
45
|
+
return types.includes(current(state).type);
|
|
46
|
+
}
|
|
47
|
+
/** @internal */
|
|
48
|
+
export function advance(state) {
|
|
49
|
+
const token = current(state);
|
|
50
|
+
if (!isAtEnd(state))
|
|
51
|
+
state.pos++;
|
|
52
|
+
return token;
|
|
53
|
+
}
|
|
54
|
+
/** @internal */
|
|
55
|
+
export function expect(state, type, message) {
|
|
56
|
+
if (check(state, type))
|
|
57
|
+
return advance(state);
|
|
58
|
+
const token = current(state);
|
|
59
|
+
const hint = generateHint(type, token);
|
|
60
|
+
const fullMessage = hint ? `${message}. ${hint}` : message;
|
|
61
|
+
throw new ParseError(fullMessage, token.span.start);
|
|
62
|
+
}
|
|
63
|
+
/** @internal */
|
|
64
|
+
export function skipNewlines(state) {
|
|
65
|
+
while (check(state, TOKEN_TYPES.NEWLINE))
|
|
66
|
+
advance(state);
|
|
67
|
+
}
|
|
68
|
+
// ============================================================
|
|
69
|
+
// ERROR HINTS
|
|
70
|
+
// ============================================================
|
|
71
|
+
/**
|
|
72
|
+
* Generate contextual hints for common parse errors.
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
function generateHint(expectedType, actualToken) {
|
|
76
|
+
const actual = actualToken.type;
|
|
77
|
+
const value = actualToken.value;
|
|
78
|
+
// Hint for unclosed brackets/braces/parens
|
|
79
|
+
if (expectedType === TOKEN_TYPES.RPAREN && actual === TOKEN_TYPES.EOF) {
|
|
80
|
+
return 'Hint: Check for unclosed parenthesis';
|
|
81
|
+
}
|
|
82
|
+
if (expectedType === TOKEN_TYPES.RBRACE && actual === TOKEN_TYPES.EOF) {
|
|
83
|
+
return 'Hint: Check for unclosed brace';
|
|
84
|
+
}
|
|
85
|
+
if (expectedType === TOKEN_TYPES.RBRACKET && actual === TOKEN_TYPES.EOF) {
|
|
86
|
+
return 'Hint: Check for unclosed bracket';
|
|
87
|
+
}
|
|
88
|
+
// Hint for keyword typos
|
|
89
|
+
if (actual === TOKEN_TYPES.IDENTIFIER) {
|
|
90
|
+
const typoHints = {
|
|
91
|
+
tru: 'true',
|
|
92
|
+
fals: 'false',
|
|
93
|
+
flase: 'false',
|
|
94
|
+
ture: 'true',
|
|
95
|
+
retrn: 'return',
|
|
96
|
+
retrun: 'return',
|
|
97
|
+
brek: 'break',
|
|
98
|
+
braek: 'break',
|
|
99
|
+
eahc: 'each',
|
|
100
|
+
ech: 'each',
|
|
101
|
+
fitler: 'filter',
|
|
102
|
+
fliter: 'filter',
|
|
103
|
+
fild: 'fold',
|
|
104
|
+
mp: 'map',
|
|
105
|
+
};
|
|
106
|
+
const suggestion = typoHints[value.toLowerCase()];
|
|
107
|
+
if (suggestion) {
|
|
108
|
+
return `Hint: Did you mean '${suggestion}'?`;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Hint for missing arrow
|
|
112
|
+
if (expectedType === TOKEN_TYPES.ARROW &&
|
|
113
|
+
(actual === TOKEN_TYPES.IDENTIFIER || actual === TOKEN_TYPES.DOLLAR)) {
|
|
114
|
+
return "Hint: Missing '->' before pipe target";
|
|
115
|
+
}
|
|
116
|
+
// Hint for using = instead of ->
|
|
117
|
+
if (expectedType === TOKEN_TYPES.ARROW && actual === TOKEN_TYPES.ASSIGN) {
|
|
118
|
+
return "Hint: Use '->' for assignment, not '='";
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
// ============================================================
|
|
123
|
+
// SPAN UTILITIES
|
|
124
|
+
// ============================================================
|
|
125
|
+
/** @internal */
|
|
126
|
+
export function makeSpan(start, end) {
|
|
127
|
+
return { start, end };
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=state.js.map
|