@ascent-lang/dev 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.
Files changed (111) hide show
  1. package/README.md +68 -0
  2. package/dist/errors/index.d.ts +4 -0
  3. package/dist/errors/index.d.ts.map +1 -0
  4. package/dist/errors/index.js +35 -0
  5. package/dist/errors/index.js.map +1 -0
  6. package/dist/errors/types.d.ts +9 -0
  7. package/dist/errors/types.d.ts.map +1 -0
  8. package/dist/errors/types.js +5 -0
  9. package/dist/errors/types.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +200 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/interpreter.d.ts +35 -0
  15. package/dist/interpreter.d.ts.map +1 -0
  16. package/dist/interpreter.js +305 -0
  17. package/dist/interpreter.js.map +1 -0
  18. package/dist/lexer/chars.d.ts +6 -0
  19. package/dist/lexer/chars.d.ts.map +1 -0
  20. package/dist/lexer/chars.js +6 -0
  21. package/dist/lexer/chars.js.map +1 -0
  22. package/dist/lexer/cursor.d.ts +16 -0
  23. package/dist/lexer/cursor.d.ts.map +1 -0
  24. package/dist/lexer/cursor.js +43 -0
  25. package/dist/lexer/cursor.js.map +1 -0
  26. package/dist/lexer/index.d.ts +21 -0
  27. package/dist/lexer/index.d.ts.map +1 -0
  28. package/dist/lexer/index.js +163 -0
  29. package/dist/lexer/index.js.map +1 -0
  30. package/dist/lexer/keywords.d.ts +5 -0
  31. package/dist/lexer/keywords.d.ts.map +1 -0
  32. package/dist/lexer/keywords.js +39 -0
  33. package/dist/lexer/keywords.js.map +1 -0
  34. package/dist/lexer/token.d.ts +20 -0
  35. package/dist/lexer/token.d.ts.map +1 -0
  36. package/dist/lexer/token.js +2 -0
  37. package/dist/lexer/token.js.map +1 -0
  38. package/dist/lib.d.ts +14 -0
  39. package/dist/lib.d.ts.map +1 -0
  40. package/dist/lib.js +17 -0
  41. package/dist/lib.js.map +1 -0
  42. package/dist/parser/ast.d.ts +128 -0
  43. package/dist/parser/ast.d.ts.map +1 -0
  44. package/dist/parser/ast.js +2 -0
  45. package/dist/parser/ast.js.map +1 -0
  46. package/dist/parser/expr.d.ts +4 -0
  47. package/dist/parser/expr.d.ts.map +1 -0
  48. package/dist/parser/expr.js +277 -0
  49. package/dist/parser/expr.js.map +1 -0
  50. package/dist/parser/index.d.ts +12 -0
  51. package/dist/parser/index.d.ts.map +1 -0
  52. package/dist/parser/index.js +40 -0
  53. package/dist/parser/index.js.map +1 -0
  54. package/dist/parser/printer.d.ts +7 -0
  55. package/dist/parser/printer.d.ts.map +1 -0
  56. package/dist/parser/printer.js +130 -0
  57. package/dist/parser/printer.js.map +1 -0
  58. package/dist/parser/stmt.d.ts +7 -0
  59. package/dist/parser/stmt.d.ts.map +1 -0
  60. package/dist/parser/stmt.js +153 -0
  61. package/dist/parser/stmt.js.map +1 -0
  62. package/dist/parser/token-stream.d.ts +19 -0
  63. package/dist/parser/token-stream.d.ts.map +1 -0
  64. package/dist/parser/token-stream.js +111 -0
  65. package/dist/parser/token-stream.js.map +1 -0
  66. package/dist/parser/type-expr.d.ts +5 -0
  67. package/dist/parser/type-expr.d.ts.map +1 -0
  68. package/dist/parser/type-expr.js +54 -0
  69. package/dist/parser/type-expr.js.map +1 -0
  70. package/dist/parser/typechecker.d.ts +9 -0
  71. package/dist/parser/typechecker.d.ts.map +1 -0
  72. package/dist/parser/typechecker.js +446 -0
  73. package/dist/parser/typechecker.js.map +1 -0
  74. package/dist/parser/typed-ast.d.ts +130 -0
  75. package/dist/parser/typed-ast.d.ts.map +1 -0
  76. package/dist/parser/typed-ast.js +2 -0
  77. package/dist/parser/typed-ast.js.map +1 -0
  78. package/dist/parser/typed-printer.d.ts +3 -0
  79. package/dist/parser/typed-printer.d.ts.map +1 -0
  80. package/dist/parser/typed-printer.js +91 -0
  81. package/dist/parser/typed-printer.js.map +1 -0
  82. package/dist/types/types.d.ts +28 -0
  83. package/dist/types/types.d.ts.map +1 -0
  84. package/dist/types/types.js +48 -0
  85. package/dist/types/types.js.map +1 -0
  86. package/package.json +70 -0
  87. package/src/errors/index.ts +38 -0
  88. package/src/errors/lexical.yml +16 -0
  89. package/src/errors/name.yml +11 -0
  90. package/src/errors/syntactic.yml +66 -0
  91. package/src/errors/typechecker.yml +61 -0
  92. package/src/errors/types.ts +13 -0
  93. package/src/index.ts +213 -0
  94. package/src/interpreter.ts +332 -0
  95. package/src/lexer/chars.ts +12 -0
  96. package/src/lexer/cursor.ts +51 -0
  97. package/src/lexer/index.ts +174 -0
  98. package/src/lexer/keywords.ts +43 -0
  99. package/src/lexer/token.ts +62 -0
  100. package/src/lib.ts +33 -0
  101. package/src/parser/ast.ts +64 -0
  102. package/src/parser/expr.ts +313 -0
  103. package/src/parser/index.ts +50 -0
  104. package/src/parser/printer.ts +146 -0
  105. package/src/parser/stmt.ts +176 -0
  106. package/src/parser/token-stream.ts +121 -0
  107. package/src/parser/type-expr.ts +63 -0
  108. package/src/parser/typechecker.ts +406 -0
  109. package/src/parser/typed-ast.ts +63 -0
  110. package/src/parser/typed-printer.ts +105 -0
  111. package/src/types/types.ts +65 -0
@@ -0,0 +1,39 @@
1
+ export const KEYWORDS = {
2
+ div: 'KW_DIV',
3
+ mod: 'KW_MOD',
4
+ fix: 'KW_FIX',
5
+ mut: 'KW_MUT',
6
+ if: 'KW_IF',
7
+ else: 'KW_ELSE',
8
+ while: 'KW_WHILE',
9
+ args: 'KW_ARGS',
10
+ };
11
+ // Built-in constructors: uppercase names that are part of the language
12
+ // core but are not keywords — they are non-shadowable constructor names
13
+ // (True, False, None) that happen to be built in rather than user-defined.
14
+ export const CONSTRUCTORS = {
15
+ True: 'BOOL_LIT',
16
+ False: 'BOOL_LIT',
17
+ None: 'NONE_LIT',
18
+ Done: 'DONE_LIT',
19
+ };
20
+ // Built-in type names: recognised as TYPE_NAME tokens so the parser can
21
+ // use them in type annotations (e.g. args declarations). Other uppercase
22
+ // names that are neither constructors nor type names are still L0001.
23
+ const BUILTIN_TYPES = {
24
+ Int: 'TYPE_NAME',
25
+ Float: 'TYPE_NAME',
26
+ Bool: 'TYPE_NAME',
27
+ String: 'TYPE_NAME',
28
+ List: 'TYPE_NAME',
29
+ };
30
+ // Returns the token kind for a scanned word, or null for an unrecognised
31
+ // uppercase name (the caller must emit L0001). Lowercase words that are not
32
+ // keywords resolve to SLOT rather than null.
33
+ export function resolveWord(value, firstCh) {
34
+ if (firstCh >= 'A' && firstCh <= 'Z') {
35
+ return CONSTRUCTORS[value] ?? BUILTIN_TYPES[value] ?? null;
36
+ }
37
+ return KEYWORDS[value] ?? 'SLOT';
38
+ }
39
+ //# sourceMappingURL=keywords.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keywords.js","sourceRoot":"","sources":["../../src/lexer/keywords.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAA8B;IACjD,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,EAAE,EAAE,OAAO;IACX,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,SAAS;CAChB,CAAC;AAEF,uEAAuE;AACvE,wEAAwE;AACxE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,YAAY,GAA8B;IACrD,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;CACjB,CAAC;AAEF,wEAAwE;AACxE,yEAAyE;AACzE,sEAAsE;AACtE,MAAM,aAAa,GAA8B;IAC/C,GAAG,EAAE,WAAW;IAChB,KAAK,EAAE,WAAW;IAClB,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,WAAW;IACnB,IAAI,EAAE,WAAW;CAClB,CAAC;AAEF,yEAAyE;AACzE,4EAA4E;AAC5E,6CAA6C;AAC7C,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,OAAe;IACxD,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,IAAI,GAAG,EAAE,CAAC;QACrC,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IAC7D,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC;AACnC,CAAC"}
@@ -0,0 +1,20 @@
1
+ export type TokenKind = 'INT_LIT' | 'FLOAT_LIT' | 'STR_LIT' | 'BOOL_LIT' | 'NONE_LIT' | 'DONE_LIT' | 'SLOT' | 'PLUS' | 'MINUS' | 'STAR' | 'SLASH' | 'KW_DIV' | 'KW_MOD' | 'KW_FIX' | 'KW_MUT' | 'KW_IF' | 'KW_ELSE' | 'KW_WHILE' | 'KW_ARGS' | 'TYPE_NAME' | 'COLON' | 'EQUALS' | 'EQ_EQ' | 'BANG_EQ' | 'LT' | 'LT_EQ' | 'GT' | 'GT_EQ' | 'DOT' | 'COMMA' | 'SEMICOLON' | 'LPAREN' | 'RPAREN' | 'LBRACE' | 'RBRACE' | 'LBRACKET' | 'RBRACKET' | 'ERROR' | 'EOF';
2
+ export interface Position {
3
+ offset: number;
4
+ line: number;
5
+ column: number;
6
+ }
7
+ export interface Span {
8
+ start: Position;
9
+ end: Position;
10
+ }
11
+ export interface Marker {
12
+ code: string;
13
+ span: Span;
14
+ }
15
+ export interface Token {
16
+ kind: TokenKind;
17
+ value: string;
18
+ span: Span;
19
+ }
20
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/lexer/token.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,WAAW,GACX,SAAS,GACT,UAAU,GACV,UAAU,GACV,UAAU,GACV,MAAM,GACN,MAAM,GACN,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,SAAS,GACT,UAAU,GACV,SAAS,GACT,WAAW,GACX,OAAO,GACP,QAAQ,GACR,OAAO,GACP,SAAS,GACT,IAAI,GACJ,OAAO,GACP,IAAI,GACJ,OAAO,GACP,KAAK,GACL,OAAO,GACP,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,UAAU,GACV,OAAO,GACP,KAAK,CAAC;AAEV,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,QAAQ,CAAC;IAChB,GAAG,EAAE,QAAQ,CAAC;CACf;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;CACZ"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/lexer/token.ts"],"names":[],"mappings":""}
package/dist/lib.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export { Lexer } from './lexer/index.js';
2
+ export type { LexResult } from './lexer/index.js';
3
+ export { Parser } from './parser/index.js';
4
+ export type { ParseResult } from './parser/index.js';
5
+ export { typecheck } from './parser/typechecker.js';
6
+ export type { TypeCheckResult } from './parser/typechecker.js';
7
+ export { Environment, evaluateExpr, executeStmt, executeProgram, } from './interpreter.js';
8
+ export type { RuntimeValue, AssignResult } from './interpreter.js';
9
+ export { formatExpr, formatStmt, formatValue } from './parser/printer.js';
10
+ export { formatTypedStmt } from './parser/typed-printer.js';
11
+ export * from './types/types.js';
12
+ export { ERRORS, byCode } from './errors/index.js';
13
+ export type { ErrorEntry, Category } from './errors/types.js';
14
+ //# sourceMappingURL=lib.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/lib.js ADDED
@@ -0,0 +1,17 @@
1
+ // Public programmatic API for the Ascent language toolchain.
2
+ // The `ascent` CLI (see index.ts) is the primary entry point, but the
3
+ // individual stages are re-exported here so tools can embed the pipeline:
4
+ //
5
+ // const { tokens, errorMarkers } = new Lexer(src).tokenize();
6
+ // const { program } = new Parser(tokens).parse();
7
+ // const { typedProgram } = typecheck(program!);
8
+ // const result = executeProgram(typedProgram!, new Environment());
9
+ export { Lexer } from './lexer/index.js';
10
+ export { Parser } from './parser/index.js';
11
+ export { typecheck } from './parser/typechecker.js';
12
+ export { Environment, evaluateExpr, executeStmt, executeProgram, } from './interpreter.js';
13
+ export { formatExpr, formatStmt, formatValue } from './parser/printer.js';
14
+ export { formatTypedStmt } from './parser/typed-printer.js';
15
+ export * from './types/types.js';
16
+ export { ERRORS, byCode } from './errors/index.js';
17
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,sEAAsE;AACtE,0EAA0E;AAC1E,EAAE;AACF,gEAAgE;AAChE,oDAAoD;AACpD,kDAAkD;AAClD,qEAAqE;AAErE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGpD,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,128 @@
1
+ import type { Span } from '../lexer/token.js';
2
+ export type TypeExpr = {
3
+ kind: 'TypeName';
4
+ name: 'Int' | 'Float' | 'Bool' | 'String';
5
+ span: Span;
6
+ } | {
7
+ kind: 'ListType';
8
+ elem: TypeExpr;
9
+ span: Span;
10
+ };
11
+ export type Literal = ({
12
+ kind: 'literal';
13
+ valueType: 'Int';
14
+ value: bigint;
15
+ span: Span;
16
+ } | {
17
+ kind: 'literal';
18
+ valueType: 'Float';
19
+ value: number;
20
+ span: Span;
21
+ } | {
22
+ kind: 'literal';
23
+ valueType: 'Bool';
24
+ value: boolean;
25
+ span: Span;
26
+ } | {
27
+ kind: 'literal';
28
+ valueType: 'String';
29
+ value: string;
30
+ span: Span;
31
+ } | {
32
+ kind: 'literal';
33
+ valueType: 'None';
34
+ span: Span;
35
+ } | {
36
+ kind: 'literal';
37
+ valueType: 'Done';
38
+ span: Span;
39
+ });
40
+ export type UnaryOp = '-';
41
+ export type ArithmeticOp = '+' | '-' | '*' | '/' | 'div' | 'mod';
42
+ export type ComparisonOp = '==' | '!=' | '<' | '<=' | '>' | '>=';
43
+ export type BinaryOp = ArithmeticOp | ComparisonOp;
44
+ export type Block = {
45
+ kind: 'block';
46
+ stmts: Statement[];
47
+ span: Span;
48
+ };
49
+ export type If = {
50
+ kind: 'if';
51
+ cond: Expr;
52
+ then: Block;
53
+ else: Block | If | null;
54
+ span: Span;
55
+ };
56
+ export type Expr = (Literal | {
57
+ kind: 'slot';
58
+ name: string;
59
+ span: Span;
60
+ } | {
61
+ kind: 'call';
62
+ callee: string;
63
+ args: Expr[];
64
+ span: Span;
65
+ } | {
66
+ kind: 'methodCall';
67
+ receiver: Expr;
68
+ method: string;
69
+ args: Expr[];
70
+ span: Span;
71
+ } | {
72
+ kind: 'list';
73
+ elements: Expr[];
74
+ span: Span;
75
+ } | {
76
+ kind: 'index';
77
+ list: Expr;
78
+ index: Expr;
79
+ span: Span;
80
+ } | {
81
+ kind: 'unary';
82
+ op: UnaryOp;
83
+ operand: Expr;
84
+ span: Span;
85
+ } | {
86
+ kind: 'binary';
87
+ op: BinaryOp;
88
+ left: Expr;
89
+ right: Expr;
90
+ span: Span;
91
+ } | Block | If);
92
+ export type Statement = ({
93
+ kind: 'fix';
94
+ name: string;
95
+ typeAnnotation: TypeExpr | null;
96
+ init: Expr;
97
+ span: Span;
98
+ } | {
99
+ kind: 'mut';
100
+ name: string;
101
+ typeAnnotation: TypeExpr | null;
102
+ init: Expr;
103
+ span: Span;
104
+ } | {
105
+ kind: 'assign';
106
+ name: string;
107
+ value: Expr;
108
+ span: Span;
109
+ } | {
110
+ kind: 'expr';
111
+ expr: Expr;
112
+ span: Span;
113
+ } | {
114
+ kind: 'while';
115
+ cond: Expr;
116
+ body: Block;
117
+ span: Span;
118
+ });
119
+ export type ArgType = 'Int' | 'Float' | 'Bool' | 'String';
120
+ export type ArgDef = {
121
+ name: string;
122
+ type: ArgType;
123
+ };
124
+ export type Program = {
125
+ args: ArgDef[];
126
+ stmts: Statement[];
127
+ };
128
+ //# sourceMappingURL=ast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { Expr } from './ast.js';
2
+ import type { TokenStream } from './token-stream.js';
3
+ export declare function parseExpr(ts: TokenStream, minBp?: number): Expr | null;
4
+ //# sourceMappingURL=expr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expr.d.ts","sourceRoot":"","sources":["../../src/parser/expr.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAqB,MAAM,UAAU,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA0ErD,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,SAAI,GAAG,IAAI,GAAG,IAAI,CA+DjE"}
@@ -0,0 +1,277 @@
1
+ import { parseBlock, parseIf } from './stmt.js';
2
+ // ---- Pratt parsing ----------------------------------------------------
3
+ //
4
+ // A Pratt parser recognises an expression as an atom (a "nud" — null
5
+ // denotation, a value that doesn't look left at anything) optionally
6
+ // followed by a chain of infix or postfix operators (each a "led" —
7
+ // left denotation, because it combines the value already parsed with
8
+ // whatever comes after it).
9
+ //
10
+ // Every operator — prefix, infix, or postfix — has a binding power: a
11
+ // number saying how tightly it grabs its operands. Higher binds
12
+ // tighter — that's what encodes precedence: '*' outbinds '+', so
13
+ // `1 + 2 * 3` parses as `1 + (2 * 3)`, not `(1 + 2) * 3`. The parsing
14
+ // loop only accepts an operator when its binding power is at least
15
+ // `minBp` — the "how tight does the *caller* need things bound"
16
+ // threshold passed down on each recursive call.
17
+ //
18
+ // This ladder is the single source of truth for what binds tighter
19
+ // than what: postfix (`.method()`, `[index]`) binds tightest, then
20
+ // unary '-', then '*'/'/'/'div'/'mod', then '+'/'-', then the
21
+ // comparisons, loosest. Every table below is keyed off these numbers
22
+ // instead of inlining its own.
23
+ const BP = {
24
+ COMPARISON: 1,
25
+ ADDITIVE: 2,
26
+ MULTIPLICATIVE: 3,
27
+ UNARY: 4,
28
+ POSTFIX: 4,
29
+ };
30
+ // Every binary operator this parser knows about has one row in this
31
+ // table. Adding the next one means adding a row, never touching the
32
+ // loop below. '*', '/', 'div' and 'mod' all share a binding power —
33
+ // they're the same precedence tier — so all four outbind '+', which
34
+ // in turn outbinds the comparisons — `1 + 2 < 3 * 4` groups as
35
+ // `(1 + 2) < (3 * 4)`. Comparisons are also marked `assoc: 'none'`:
36
+ // unlike '+' or '*', two of them can never sit side by side
37
+ // (`a < b < c` is rejected, not silently grouped one way or the other).
38
+ const INFIX_OPS = {
39
+ EQ_EQ: { op: '==', bp: BP.COMPARISON, assoc: 'none' },
40
+ BANG_EQ: { op: '!=', bp: BP.COMPARISON, assoc: 'none' },
41
+ LT: { op: '<', bp: BP.COMPARISON, assoc: 'none' },
42
+ LT_EQ: { op: '<=', bp: BP.COMPARISON, assoc: 'none' },
43
+ GT: { op: '>', bp: BP.COMPARISON, assoc: 'none' },
44
+ GT_EQ: { op: '>=', bp: BP.COMPARISON, assoc: 'none' },
45
+ PLUS: { op: '+', bp: BP.ADDITIVE, assoc: 'left' },
46
+ MINUS: { op: '-', bp: BP.ADDITIVE, assoc: 'left' },
47
+ STAR: { op: '*', bp: BP.MULTIPLICATIVE, assoc: 'left' },
48
+ SLASH: { op: '/', bp: BP.MULTIPLICATIVE, assoc: 'left' },
49
+ KW_DIV: { op: 'div', bp: BP.MULTIPLICATIVE, assoc: 'left' },
50
+ KW_MOD: { op: 'mod', bp: BP.MULTIPLICATIVE, assoc: 'left' },
51
+ };
52
+ // Postfix table — dot-calls and indexing are "led" operators exactly
53
+ // like the binary ones above (they look left at the value already
54
+ // parsed), so they're declared here and dispatched on in the loop
55
+ // below instead of being special-cased ahead of the INFIX_OPS lookup.
56
+ // Both bind at POSTFIX — tighter than unary or any binary operator —
57
+ // which is why `-a.b()[0]` parses as `-(a.b()[0])`.
58
+ const POSTFIX_OPS = {
59
+ DOT: { bp: BP.POSTFIX },
60
+ LBRACKET: { bp: BP.POSTFIX },
61
+ };
62
+ // Prefix table — unary '-' is the Pratt parser's other operator kind
63
+ // (a "nud" that still takes an operand, parsed in parseAtom below).
64
+ // Only one entry today, but its binding power is declared here rather
65
+ // than inlined at the call site.
66
+ const PREFIX_OPS = {
67
+ MINUS: { op: '-', bp: BP.UNARY },
68
+ };
69
+ export function parseExpr(ts, minBp = 0) {
70
+ let left = parseAtom(ts);
71
+ if (left === null) {
72
+ return null;
73
+ }
74
+ // Tracks whether a non-associative (comparison-tier) operator has
75
+ // already been consumed at this call's level — a second one directly
76
+ // beside it (`a < b < c`) is a chain, not a grouping choice, so it's
77
+ // rejected here rather than silently parsed left- or right-first.
78
+ let chained = false;
79
+ while (true) {
80
+ const kind = ts.peek().kind;
81
+ // Postfix: expr.method(args) or expr[index] — dispatched by table
82
+ // rather than special-cased ahead of the INFIX_OPS lookup below.
83
+ const postfix = POSTFIX_OPS[kind];
84
+ if (postfix !== undefined) {
85
+ if (postfix.bp < minBp)
86
+ break;
87
+ left = kind === 'DOT' ? parseMethodCall(ts, left) : parseIndex(ts, left);
88
+ if (left === null)
89
+ return null;
90
+ continue;
91
+ }
92
+ const infix = INFIX_OPS[kind];
93
+ if (infix === undefined || infix.bp < minBp) {
94
+ break;
95
+ }
96
+ if (infix.assoc === 'none') {
97
+ if (chained) {
98
+ ts.report('S0008', ts.peek().span);
99
+ return null;
100
+ }
101
+ chained = true;
102
+ }
103
+ ts.advance(); // consume the operator
104
+ // Left-associativity — `1 + 2 + 3` must parse as `(1 + 2) + 3`,
105
+ // not `1 + (2 + 3)`. Parsing the right-hand side with `bp + 1`
106
+ // (instead of `bp`) is what enforces that: it stops a second '+'
107
+ // from being absorbed into the *right* operand, forcing it to
108
+ // instead be picked up by the loop one level up. Non-associative
109
+ // operators reuse the same `bp + 1` call — it still keeps looser
110
+ // operators out of the right operand, and the `chained` check
111
+ // above is what stops them from reappearing at this level.
112
+ const right = parseExpr(ts, infix.bp + 1);
113
+ if (right === null) {
114
+ return null;
115
+ }
116
+ left = {
117
+ kind: 'binary',
118
+ op: infix.op,
119
+ left,
120
+ right,
121
+ span: { start: left.span.start, end: right.span.end }
122
+ };
123
+ }
124
+ return left;
125
+ }
126
+ // 'receiver.method(args)' — DOT already confirmed on lookahead by the
127
+ // Pratt loop; this consumes it through the closing ')'.
128
+ function parseMethodCall(ts, receiver) {
129
+ ts.advance(); // consume '.'
130
+ const methodTok = ts.peek();
131
+ if (methodTok.kind !== 'SLOT') {
132
+ ts.report('S0012', methodTok.span);
133
+ return null;
134
+ }
135
+ ts.advance(); // consume method name
136
+ if (ts.peek().kind !== 'LPAREN') {
137
+ ts.report('S0001', ts.peek().span);
138
+ return null;
139
+ }
140
+ ts.advance(); // consume '('
141
+ const parsed = ts.parseSeparated(() => parseExpr(ts), 'COMMA', 'RPAREN', 'S0001');
142
+ if (parsed === null)
143
+ return null;
144
+ return {
145
+ kind: 'methodCall',
146
+ receiver,
147
+ method: methodTok.value,
148
+ args: parsed.items,
149
+ span: { start: receiver.span.start, end: parsed.close.span.end },
150
+ };
151
+ }
152
+ // 'list[index]' — LBRACKET already confirmed on lookahead by the Pratt loop.
153
+ function parseIndex(ts, list) {
154
+ ts.advance(); // consume '['
155
+ const index = parseExpr(ts);
156
+ if (index === null)
157
+ return null;
158
+ const rbracket = ts.expect('RBRACKET', 'S0013');
159
+ if (rbracket === null)
160
+ return null;
161
+ return {
162
+ kind: 'index',
163
+ list,
164
+ index,
165
+ span: { start: list.span.start, end: rbracket.span.end },
166
+ };
167
+ }
168
+ // parseAtom parses the smallest possible expression: a single literal
169
+ // that doesn't depend on any operator. This is the Pratt parser's nud —
170
+ // every future one (parenthesized groups, unary '-', identifiers) is
171
+ // just another case added here, never a change to the loop above.
172
+ function parseAtom(ts) {
173
+ const tok = ts.peek();
174
+ if (tok.kind === 'INT_LIT') {
175
+ ts.advance();
176
+ return {
177
+ kind: 'literal',
178
+ valueType: 'Int',
179
+ value: BigInt(tok.value),
180
+ span: tok.span
181
+ };
182
+ }
183
+ if (tok.kind === 'FLOAT_LIT') {
184
+ ts.advance();
185
+ return {
186
+ kind: 'literal',
187
+ valueType: 'Float',
188
+ value: parseFloat(tok.value),
189
+ span: tok.span
190
+ };
191
+ }
192
+ if (tok.kind === 'STR_LIT') {
193
+ ts.advance();
194
+ return { kind: 'literal', valueType: 'String', value: tok.value, span: tok.span };
195
+ }
196
+ if (tok.kind === 'BOOL_LIT') {
197
+ ts.advance();
198
+ return {
199
+ kind: 'literal',
200
+ valueType: 'Bool',
201
+ value: tok.value === 'True',
202
+ span: tok.span
203
+ };
204
+ }
205
+ if (tok.kind === 'NONE_LIT') {
206
+ ts.advance();
207
+ return { kind: 'literal', valueType: 'None', span: tok.span };
208
+ }
209
+ if (tok.kind === 'DONE_LIT') {
210
+ ts.advance();
211
+ return { kind: 'literal', valueType: 'Done', span: tok.span };
212
+ }
213
+ if (tok.kind === 'SLOT') {
214
+ ts.advance();
215
+ if (ts.peek().kind === 'LPAREN') {
216
+ return parseCall(ts, tok);
217
+ }
218
+ return { kind: 'slot', name: tok.value, span: tok.span };
219
+ }
220
+ if (tok.kind === 'LPAREN') {
221
+ ts.advance();
222
+ const inner = parseExpr(ts);
223
+ if (inner === null) {
224
+ return null;
225
+ }
226
+ const closing = ts.peek();
227
+ if (closing.kind !== 'RPAREN') {
228
+ ts.report('S0001', closing.span);
229
+ return null;
230
+ }
231
+ ts.advance(); // consume ')'
232
+ return inner;
233
+ }
234
+ const prefix = PREFIX_OPS[tok.kind];
235
+ if (prefix !== undefined) {
236
+ const start = tok.span.start;
237
+ ts.advance();
238
+ const operand = parseExpr(ts, prefix.bp);
239
+ if (operand === null) {
240
+ return null;
241
+ }
242
+ return { kind: 'unary', op: prefix.op, operand, span: { start, end: operand.span.end } };
243
+ }
244
+ if (tok.kind === 'LBRACKET') {
245
+ return parseList(ts);
246
+ }
247
+ if (tok.kind === 'LBRACE') {
248
+ return parseBlock(ts);
249
+ }
250
+ if (tok.kind === 'KW_IF') {
251
+ return parseIf(ts);
252
+ }
253
+ ts.report('S0002', tok.span);
254
+ return null;
255
+ }
256
+ // 'name(arg, arg, …)' — callee token already consumed by parseAtom.
257
+ function parseCall(ts, callee) {
258
+ ts.advance(); // consume '('
259
+ const parsed = ts.parseSeparated(() => parseExpr(ts), 'COMMA', 'RPAREN', 'S0001');
260
+ if (parsed === null)
261
+ return null;
262
+ return {
263
+ kind: 'call',
264
+ callee: callee.value,
265
+ args: parsed.items,
266
+ span: { start: callee.span.start, end: parsed.close.span.end },
267
+ };
268
+ }
269
+ // '[' expr, expr, … ']' — list literal. Already peeked '[' in parseAtom.
270
+ function parseList(ts) {
271
+ const openTok = ts.advance(); // consume '['
272
+ const parsed = ts.parseSeparated(() => parseExpr(ts), 'COMMA', 'RBRACKET', 'S0013');
273
+ if (parsed === null)
274
+ return null;
275
+ return { kind: 'list', elements: parsed.items, span: { start: openTok.span.start, end: parsed.close.span.end } };
276
+ }
277
+ //# sourceMappingURL=expr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expr.js","sourceRoot":"","sources":["../../src/parser/expr.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEhD,0EAA0E;AAC1E,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,oEAAoE;AACpE,qEAAqE;AACrE,4BAA4B;AAC5B,EAAE;AACF,sEAAsE;AACtE,gEAAgE;AAChE,iEAAiE;AACjE,sEAAsE;AACtE,mEAAmE;AACnE,gEAAgE;AAChE,gDAAgD;AAChD,EAAE;AACF,mEAAmE;AACnE,mEAAmE;AACnE,8DAA8D;AAC9D,qEAAqE;AACrE,+BAA+B;AAC/B,MAAM,EAAE,GAAG;IACT,UAAU,EAAE,CAAC;IACb,QAAQ,EAAE,CAAC;IACX,cAAc,EAAE,CAAC;IACjB,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;CACF,CAAC;AAEX,oEAAoE;AACpE,oEAAoE;AACpE,oEAAoE;AACpE,oEAAoE;AACpE,+DAA+D;AAC/D,oEAAoE;AACpE,4DAA4D;AAC5D,wEAAwE;AACxE,MAAM,SAAS,GAAqF;IAClG,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE;IACrD,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE;IACvD,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE;IACjD,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE;IACrD,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE;IACjD,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE;IACrD,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE;IACjD,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE;IAClD,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE;IACvD,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE;IACxD,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE;IAC3D,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE;CAC5D,CAAC;AAEF,qEAAqE;AACrE,kEAAkE;AAClE,kEAAkE;AAClE,sEAAsE;AACtE,qEAAqE;AACrE,oDAAoD;AACpD,MAAM,WAAW,GAA+C;IAC9D,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE;IACvB,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE;CAC7B,CAAC;AAEF,qEAAqE;AACrE,oEAAoE;AACpE,sEAAsE;AACtE,iCAAiC;AACjC,MAAM,UAAU,GAA4D;IAC1E,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE;CACjC,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,EAAe,EAAE,KAAK,GAAG,CAAC;IAClD,IAAI,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IACzB,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kEAAkE;IAClE,qEAAqE;IACrE,qEAAqE;IACrE,kEAAkE;IAClE,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC;QAE5B,kEAAkE;QAClE,iEAAiE;QACjE,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,OAAO,CAAC,EAAE,GAAG,KAAK;gBAAE,MAAM;YAC9B,IAAI,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACzE,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;YAC5C,MAAM;QACR,CAAC;QAED,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC3B,IAAI,OAAO,EAAE,CAAC;gBACZ,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;gBACnC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QAED,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,uBAAuB;QAErC,gEAAgE;QAChE,+DAA+D;QAC/D,iEAAiE;QACjE,8DAA8D;QAC9D,iEAAiE;QACjE,iEAAiE;QACjE,8DAA8D;QAC9D,2DAA2D;QAC3D,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC1C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,GAAG;YACL,IAAI,EAAE,QAAQ;YACd,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI;YACJ,KAAK;YACL,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;SACtD,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sEAAsE;AACtE,wDAAwD;AACxD,SAAS,eAAe,CAAC,EAAe,EAAE,QAAc;IACtD,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,cAAc;IAE5B,MAAM,SAAS,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC9B,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,sBAAsB;IAEpC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAChC,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,cAAc;IAE5B,MAAM,MAAM,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClF,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,QAAQ;QACR,MAAM,EAAE,SAAS,CAAC,KAAK;QACvB,IAAI,EAAE,MAAM,CAAC,KAAK;QAClB,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;KACjE,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,SAAS,UAAU,CAAC,EAAe,EAAE,IAAU;IAC7C,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,cAAc;IAE5B,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IAC5B,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEhC,MAAM,QAAQ,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEnC,OAAO;QACL,IAAI,EAAE,OAAO;QACb,IAAI;QACJ,KAAK;QACL,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE;KACzD,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,wEAAwE;AACxE,qEAAqE;AACrE,kEAAkE;AAClE,SAAS,SAAS,CAAC,EAAe;IAChC,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;IAEtB,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3B,EAAE,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;YACxB,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC7B,EAAE,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,OAAO;YAClB,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;YAC5B,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3B,EAAE,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;IACpF,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC5B,EAAE,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,MAAM;YACjB,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,MAAM;YAC3B,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC5B,EAAE,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;IAChE,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC5B,EAAE,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;IAChE,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACxB,EAAE,CAAC,OAAO,EAAE,CAAC;QACb,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3D,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,EAAE,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,cAAc;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;QAC7B,EAAE,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACzC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC3F,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;IAED,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oEAAoE;AACpE,SAAS,SAAS,CAAC,EAAe,EAAE,MAAa;IAC/C,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,cAAc;IAC5B,MAAM,MAAM,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClF,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,MAAM,CAAC,KAAK;QACpB,IAAI,EAAE,MAAM,CAAC,KAAK;QAClB,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;KAC/D,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,SAAS,SAAS,CAAC,EAAe;IAChC,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,cAAc;IAC5C,MAAM,MAAM,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IACpF,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AACnH,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Token, Marker } from '../lexer/token.js';
2
+ import type { Program } from './ast.js';
3
+ export interface ParseResult {
4
+ program: Program | null;
5
+ errorMarkers: Marker[];
6
+ }
7
+ export declare class Parser {
8
+ private readonly tokens;
9
+ constructor(tokens: Token[]);
10
+ parse(): ParseResult;
11
+ }
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAU,OAAO,EAAE,MAAM,UAAU,CAAC;AAKhD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AA4BD,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;gBAEd,MAAM,EAAE,KAAK,EAAE;IAI3B,KAAK,IAAI,WAAW;CAK5B"}
@@ -0,0 +1,40 @@
1
+ import { TokenStream } from './token-stream.js';
2
+ import { parseStmt } from './stmt.js';
3
+ import { parseArgs } from './type-expr.js';
4
+ // The program is an optional 'args (…);' header followed by a
5
+ // semicolon-separated run of statements up to EOF — the same
6
+ // "item (sep item)* close" shape as a block, with EOF standing in for
7
+ // the closing brace. `recover` is on, so a malformed statement is
8
+ // synchronized past rather than aborting the whole parse.
9
+ function parseProgram(ts) {
10
+ let args = [];
11
+ if (ts.peek().kind === 'KW_ARGS') {
12
+ const result = parseArgs(ts);
13
+ if (result === null)
14
+ return null;
15
+ args = result;
16
+ if (ts.expect('SEMICOLON', 'S0011') === null)
17
+ return null;
18
+ }
19
+ const parsed = ts.parseSeparated(() => parseStmt(ts), 'SEMICOLON', 'EOF', 'S0011', true);
20
+ if (parsed === null)
21
+ return null;
22
+ return { args, stmts: parsed.items };
23
+ }
24
+ // The parser's public entry point. Phase 5 moved the grammar into
25
+ // free functions over a TokenStream (token-stream.ts, expr.ts, stmt.ts,
26
+ // type-expr.ts); this class is the thin wiring that owns the stream for
27
+ // one parse and exposes the same `new Parser(tokens).parse()` API the
28
+ // rest of the toolchain calls.
29
+ export class Parser {
30
+ tokens;
31
+ constructor(tokens) {
32
+ this.tokens = tokens;
33
+ }
34
+ parse() {
35
+ const ts = new TokenStream(this.tokens);
36
+ const program = parseProgram(ts);
37
+ return { program, errorMarkers: ts.errors };
38
+ }
39
+ }
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAO3C,8DAA8D;AAC9D,6DAA6D;AAC7D,sEAAsE;AACtE,kEAAkE;AAClE,0DAA0D;AAC1D,SAAS,YAAY,CAAC,EAAe;IACnC,IAAI,IAAI,GAAa,EAAE,CAAC;IACxB,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;QAC7B,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACjC,IAAI,GAAG,MAAM,CAAC;QAEd,IAAI,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;IAC5D,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACzF,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;AACvC,CAAC;AAED,kEAAkE;AAClE,wEAAwE;AACxE,wEAAwE;AACxE,sEAAsE;AACtE,+BAA+B;AAC/B,MAAM,OAAO,MAAM;IACA,MAAM,CAAU;IAEjC,YAAmB,MAAe;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEM,KAAK;QACV,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QACjC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC;IAC9C,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { Expr, Statement } from './ast.js';
2
+ import type { RuntimeValue } from '../interpreter.js';
3
+ export declare const branch: (lines: string[], isLast: boolean) => string[];
4
+ export declare const formatExpr: (expr: Expr) => string;
5
+ export declare const formatStmt: (stmt: Statement) => string;
6
+ export declare const formatValue: (value: RuntimeValue) => string;
7
+ //# sourceMappingURL=printer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"printer.d.ts","sourceRoot":"","sources":["../../src/parser/printer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAY,MAAM,UAAU,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAsFtD,eAAO,MAAM,MAAM,GAAI,OAAO,MAAM,EAAE,EAAE,QAAQ,OAAO,KAAG,MAAM,EAI/D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,MAAM,IAAI,KAAG,MAEvC,CAAC;AA2BF,eAAO,MAAM,UAAU,GAAI,MAAM,SAAS,KAAG,MAAoC,CAAC;AAElF,eAAO,MAAM,WAAW,GAAI,OAAO,YAAY,KAAG,MAoBjD,CAAC"}