@tom2012/cc-web 2026.5.18-a → 2026.5.18-c

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 (186) hide show
  1. package/README.md +1 -1
  2. package/backend/dist/index.d.ts.map +1 -1
  3. package/backend/dist/index.js +2 -21
  4. package/backend/dist/index.js.map +1 -1
  5. package/backend/dist/routes/global-tracks.d.ts +2 -5
  6. package/backend/dist/routes/global-tracks.d.ts.map +1 -1
  7. package/backend/dist/routes/global-tracks.js +2 -28
  8. package/backend/dist/routes/global-tracks.js.map +1 -1
  9. package/backend/dist/routes/tracks.d.ts +3 -9
  10. package/backend/dist/routes/tracks.d.ts.map +1 -1
  11. package/backend/dist/routes/tracks.js +3 -153
  12. package/backend/dist/routes/tracks.js.map +1 -1
  13. package/backend/dist/tracks/ask-user-bridge.d.ts +1 -6
  14. package/backend/dist/tracks/ask-user-bridge.d.ts.map +1 -1
  15. package/backend/dist/tracks/ask-user-bridge.js +0 -22
  16. package/backend/dist/tracks/ask-user-bridge.js.map +1 -1
  17. package/backend/dist/tracks/index.d.ts +1 -5
  18. package/backend/dist/tracks/index.d.ts.map +1 -1
  19. package/backend/dist/tracks/index.js +1 -10
  20. package/backend/dist/tracks/index.js.map +1 -1
  21. package/backend/package-lock.json +1 -64
  22. package/backend/package.json +1 -5
  23. package/frontend/dist/assets/{ChatOverlay-C-MIdZJm.js → ChatOverlay-i8gy2y-T.js} +1 -1
  24. package/frontend/dist/assets/{GraphPreview-D2qXaMDE.js → GraphPreview-CoOHeDk0.js} +2 -2
  25. package/frontend/dist/assets/{MobilePage-BolIAlON.js → MobilePage-ZYuVSqIu.js} +3 -3
  26. package/frontend/dist/assets/{OfficePreview-Bw5JlSpR.js → OfficePreview-BP_FVyDv.js} +2 -2
  27. package/frontend/dist/assets/{PdfPreview-DA96QUeL.js → PdfPreview-B_Is_82c.js} +1 -1
  28. package/frontend/dist/assets/{ProjectPage-CmbJ2g7j.js → ProjectPage-Bi7P0xvD.js} +5 -5
  29. package/frontend/dist/assets/{SettingsPage-_Cm-AVw4.js → SettingsPage-DlqnuIy1.js} +2 -2
  30. package/frontend/dist/assets/{SkillHubPage-By-ccKQj.js → SkillHubPage-FFefLcmN.js} +3 -3
  31. package/frontend/dist/assets/{chevron-down-DM_Mo17i.js → chevron-down-DqAoFpmS.js} +1 -1
  32. package/frontend/dist/assets/{index-DuGXgwGK.js → index-B5mDtgD1.js} +2 -2
  33. package/frontend/dist/assets/{index-ZXKKVcgm.js → index-Bj-uhUZY.js} +1 -1
  34. package/frontend/dist/assets/{index-B1ToZu3N.js → index-DzYZJMgp.js} +1 -1
  35. package/frontend/dist/assets/index-mxYmpvtf.css +1 -0
  36. package/frontend/dist/assets/{jszip.min-Bm8u3Q9Z.js → jszip.min-DW73pE0J.js} +1 -1
  37. package/frontend/dist/assets/{select-CF-2DxAz.js → select-HgZm25ew.js} +1 -1
  38. package/frontend/dist/assets/{user-mc2CAtZS.js → user-BOTyiGCj.js} +1 -1
  39. package/frontend/dist/index.html +2 -2
  40. package/package.json +1 -1
  41. package/backend/vendor/@tom2012/train-core/dist/ast-cache.d.ts +0 -74
  42. package/backend/vendor/@tom2012/train-core/dist/ast-cache.d.ts.map +0 -1
  43. package/backend/vendor/@tom2012/train-core/dist/ast-cache.js +0 -157
  44. package/backend/vendor/@tom2012/train-core/dist/ast-cache.js.map +0 -1
  45. package/backend/vendor/@tom2012/train-core/dist/ast.d.ts +0 -350
  46. package/backend/vendor/@tom2012/train-core/dist/ast.d.ts.map +0 -1
  47. package/backend/vendor/@tom2012/train-core/dist/ast.js +0 -15
  48. package/backend/vendor/@tom2012/train-core/dist/ast.js.map +0 -1
  49. package/backend/vendor/@tom2012/train-core/dist/builder.d.ts +0 -21
  50. package/backend/vendor/@tom2012/train-core/dist/builder.d.ts.map +0 -1
  51. package/backend/vendor/@tom2012/train-core/dist/builder.js +0 -1254
  52. package/backend/vendor/@tom2012/train-core/dist/builder.js.map +0 -1
  53. package/backend/vendor/@tom2012/train-core/dist/builtins.d.ts +0 -17
  54. package/backend/vendor/@tom2012/train-core/dist/builtins.d.ts.map +0 -1
  55. package/backend/vendor/@tom2012/train-core/dist/builtins.js +0 -500
  56. package/backend/vendor/@tom2012/train-core/dist/builtins.js.map +0 -1
  57. package/backend/vendor/@tom2012/train-core/dist/index.d.ts +0 -54
  58. package/backend/vendor/@tom2012/train-core/dist/index.d.ts.map +0 -1
  59. package/backend/vendor/@tom2012/train-core/dist/index.js +0 -66
  60. package/backend/vendor/@tom2012/train-core/dist/index.js.map +0 -1
  61. package/backend/vendor/@tom2012/train-core/dist/interpreter.d.ts +0 -110
  62. package/backend/vendor/@tom2012/train-core/dist/interpreter.d.ts.map +0 -1
  63. package/backend/vendor/@tom2012/train-core/dist/interpreter.js +0 -943
  64. package/backend/vendor/@tom2012/train-core/dist/interpreter.js.map +0 -1
  65. package/backend/vendor/@tom2012/train-core/dist/lexer.d.ts +0 -88
  66. package/backend/vendor/@tom2012/train-core/dist/lexer.d.ts.map +0 -1
  67. package/backend/vendor/@tom2012/train-core/dist/lexer.js +0 -243
  68. package/backend/vendor/@tom2012/train-core/dist/lexer.js.map +0 -1
  69. package/backend/vendor/@tom2012/train-core/dist/module-loader.d.ts +0 -74
  70. package/backend/vendor/@tom2012/train-core/dist/module-loader.d.ts.map +0 -1
  71. package/backend/vendor/@tom2012/train-core/dist/module-loader.js +0 -149
  72. package/backend/vendor/@tom2012/train-core/dist/module-loader.js.map +0 -1
  73. package/backend/vendor/@tom2012/train-core/dist/parser.d.ts +0 -138
  74. package/backend/vendor/@tom2012/train-core/dist/parser.d.ts.map +0 -1
  75. package/backend/vendor/@tom2012/train-core/dist/parser.js +0 -861
  76. package/backend/vendor/@tom2012/train-core/dist/parser.js.map +0 -1
  77. package/backend/vendor/@tom2012/train-core/dist/prompt-composer.d.ts +0 -49
  78. package/backend/vendor/@tom2012/train-core/dist/prompt-composer.d.ts.map +0 -1
  79. package/backend/vendor/@tom2012/train-core/dist/prompt-composer.js +0 -159
  80. package/backend/vendor/@tom2012/train-core/dist/prompt-composer.js.map +0 -1
  81. package/backend/vendor/@tom2012/train-core/dist/runtime.d.ts +0 -146
  82. package/backend/vendor/@tom2012/train-core/dist/runtime.d.ts.map +0 -1
  83. package/backend/vendor/@tom2012/train-core/dist/runtime.js +0 -156
  84. package/backend/vendor/@tom2012/train-core/dist/runtime.js.map +0 -1
  85. package/backend/vendor/@tom2012/train-core/dist/type-descriptor.d.ts +0 -18
  86. package/backend/vendor/@tom2012/train-core/dist/type-descriptor.d.ts.map +0 -1
  87. package/backend/vendor/@tom2012/train-core/dist/type-descriptor.js +0 -94
  88. package/backend/vendor/@tom2012/train-core/dist/type-descriptor.js.map +0 -1
  89. package/backend/vendor/@tom2012/train-core/dist/validation.d.ts +0 -44
  90. package/backend/vendor/@tom2012/train-core/dist/validation.d.ts.map +0 -1
  91. package/backend/vendor/@tom2012/train-core/dist/validation.js +0 -271
  92. package/backend/vendor/@tom2012/train-core/dist/validation.js.map +0 -1
  93. package/backend/vendor/@tom2012/train-core/package.json +0 -35
  94. package/frontend/dist/assets/TrackEditor-EL1VBAhT.js +0 -14
  95. package/frontend/dist/assets/TrackGraphEditor-BlSkKLI0.js +0 -2
  96. package/frontend/dist/assets/TrackGraphEditor-Fd0xVSp_.css +0 -1
  97. package/frontend/dist/assets/abap-LPLW346S.js +0 -7
  98. package/frontend/dist/assets/apex-Dk-jUCUV.js +0 -7
  99. package/frontend/dist/assets/azcli-DPUMmPlX.js +0 -7
  100. package/frontend/dist/assets/bat-C1Qbg1bV.js +0 -7
  101. package/frontend/dist/assets/bicep-D-e-VSJi.js +0 -7
  102. package/frontend/dist/assets/cameligo-CjUqTgqL.js +0 -7
  103. package/frontend/dist/assets/clojure-BWsu6Kju.js +0 -7
  104. package/frontend/dist/assets/codicon-DCmgc-ay.ttf +0 -0
  105. package/frontend/dist/assets/coffee-DeC36AK3.js +0 -7
  106. package/frontend/dist/assets/cpp-DcZnmBWT.js +0 -7
  107. package/frontend/dist/assets/csharp-DqBXBMf0.js +0 -7
  108. package/frontend/dist/assets/csp-CkO7y8ul.js +0 -7
  109. package/frontend/dist/assets/css-OAcfVtED.js +0 -7
  110. package/frontend/dist/assets/cssMode-CicA3AgL.js +0 -7
  111. package/frontend/dist/assets/cypher-40UGrUjD.js +0 -7
  112. package/frontend/dist/assets/dart-DmixyLor.js +0 -7
  113. package/frontend/dist/assets/dockerfile-CayO4nTA.js +0 -7
  114. package/frontend/dist/assets/ecl-DRrKCuVc.js +0 -7
  115. package/frontend/dist/assets/editor-B5EY1bb8.css +0 -1
  116. package/frontend/dist/assets/editor.main-DKkZVnWw.js +0 -37
  117. package/frontend/dist/assets/elixir-J3qpp9mX.js +0 -7
  118. package/frontend/dist/assets/flow9-DzW2c4Im.js +0 -7
  119. package/frontend/dist/assets/freemarker2-BAiKgR7W.js +0 -7
  120. package/frontend/dist/assets/fsharp-D00tn_6c.js +0 -7
  121. package/frontend/dist/assets/go-NnNmgWK_.js +0 -7
  122. package/frontend/dist/assets/graphql-C9_--VLF.js +0 -7
  123. package/frontend/dist/assets/handlebars-C65m36HJ.js +0 -7
  124. package/frontend/dist/assets/hcl-BhbOULbp.js +0 -7
  125. package/frontend/dist/assets/html-CQKNdpNj.js +0 -7
  126. package/frontend/dist/assets/htmlMode-lb8O19um.js +0 -7
  127. package/frontend/dist/assets/index-BzylQAjm.js +0 -1
  128. package/frontend/dist/assets/index-CI8kSYwX.css +0 -1
  129. package/frontend/dist/assets/ini-zR-_X5iG.js +0 -7
  130. package/frontend/dist/assets/java-CSTjsyoZ.js +0 -7
  131. package/frontend/dist/assets/javascript-FWRasi5r.js +0 -7
  132. package/frontend/dist/assets/jsonMode-D8aGj5qS.js +0 -7
  133. package/frontend/dist/assets/julia-DioMOKVu.js +0 -7
  134. package/frontend/dist/assets/kotlin-Dsb0PKmW.js +0 -7
  135. package/frontend/dist/assets/less-CZYLoAVD.js +0 -7
  136. package/frontend/dist/assets/lexon-d5JUiwNk.js +0 -7
  137. package/frontend/dist/assets/liquid-Bu7MHLsF.js +0 -7
  138. package/frontend/dist/assets/lua-1Al72GG8.js +0 -7
  139. package/frontend/dist/assets/m3-hx1xCPC3.js +0 -7
  140. package/frontend/dist/assets/markdown-DPGrH1xZ.js +0 -7
  141. package/frontend/dist/assets/mdx-C9KjBxd9.js +0 -7
  142. package/frontend/dist/assets/mips-CYbZjkIm.js +0 -7
  143. package/frontend/dist/assets/msdax-DAioKM5A.js +0 -7
  144. package/frontend/dist/assets/mysql-7e9GUebS.js +0 -7
  145. package/frontend/dist/assets/objective-c-BGf8QNjz.js +0 -7
  146. package/frontend/dist/assets/pascal-hEDRz3un.js +0 -7
  147. package/frontend/dist/assets/pascaligo-gqEhN6pG.js +0 -7
  148. package/frontend/dist/assets/perl-CN8Ht9Vk.js +0 -7
  149. package/frontend/dist/assets/pgsql-CRCqHQBx.js +0 -7
  150. package/frontend/dist/assets/php-DTZrlAwe.js +0 -7
  151. package/frontend/dist/assets/pla-CRmh4UcC.js +0 -7
  152. package/frontend/dist/assets/postiats-Car2G7g8.js +0 -7
  153. package/frontend/dist/assets/powerquery-BJKl8V3o.js +0 -7
  154. package/frontend/dist/assets/powershell-Du7a_J7r.js +0 -7
  155. package/frontend/dist/assets/protobuf-ChneWI0H.js +0 -7
  156. package/frontend/dist/assets/pug-BH6LSJaf.js +0 -7
  157. package/frontend/dist/assets/python-DnHhXfg2.js +0 -7
  158. package/frontend/dist/assets/qsharp-CU-Hxpxi.js +0 -7
  159. package/frontend/dist/assets/r-Bw-W15zh.js +0 -7
  160. package/frontend/dist/assets/razor-D4OpMyGk.js +0 -7
  161. package/frontend/dist/assets/redis-bY-X9-ol.js +0 -7
  162. package/frontend/dist/assets/redshift-CMu3ubbS.js +0 -7
  163. package/frontend/dist/assets/restructuredtext-KNkiWGNN.js +0 -7
  164. package/frontend/dist/assets/ruby-dQWMhU86.js +0 -7
  165. package/frontend/dist/assets/rust-BAcHhnEU.js +0 -7
  166. package/frontend/dist/assets/sb-Bidr5w2z.js +0 -7
  167. package/frontend/dist/assets/scala-imTtxsGY.js +0 -7
  168. package/frontend/dist/assets/scheme-BY-WHKiB.js +0 -7
  169. package/frontend/dist/assets/scss-NDoRP52C.js +0 -7
  170. package/frontend/dist/assets/shell-DrIjotnh.js +0 -7
  171. package/frontend/dist/assets/solidity-DTahNycF.js +0 -7
  172. package/frontend/dist/assets/sophia-DtyrjGkZ.js +0 -7
  173. package/frontend/dist/assets/sparql-CFuS5E3z.js +0 -7
  174. package/frontend/dist/assets/sql-BRxcnbRv.js +0 -7
  175. package/frontend/dist/assets/st-Dz4uh7MK.js +0 -7
  176. package/frontend/dist/assets/swift-Digsrw1G.js +0 -11
  177. package/frontend/dist/assets/systemverilog-7TDrkMau.js +0 -7
  178. package/frontend/dist/assets/tcl-BtaFcnDi.js +0 -7
  179. package/frontend/dist/assets/tsMode-RIZqtAps.js +0 -7
  180. package/frontend/dist/assets/twig-Deid_oBs.js +0 -7
  181. package/frontend/dist/assets/typescript-DJeBIxGF.js +0 -7
  182. package/frontend/dist/assets/typespec-zUaxhbG8.js +0 -7
  183. package/frontend/dist/assets/vb-DK0rKJzo.js +0 -7
  184. package/frontend/dist/assets/wgsl-B8fNVlOQ.js +0 -7
  185. package/frontend/dist/assets/xml-DuazQqBz.js +0 -7
  186. package/frontend/dist/assets/yaml-DsG3CKlY.js +0 -7
@@ -1,861 +0,0 @@
1
- /**
2
- * train language parser (CST-based)
3
- *
4
- * Built with chevrotain's CstParser. Produces a Concrete Syntax Tree;
5
- * a later transformer step (M1 end) converts CST → typed AST.
6
- *
7
- * Coverage as of this milestone:
8
- * - Top-level: import / const / var / func / fai / export / @runtime
9
- * - Annotations (@cache / @timeout / @adapter / ...) on func & fai decls
10
- * - Statements: let (with destructuring), assignment, if/else, for-in,
11
- * while, break, continue, return, try-catch, expression statement
12
- * - Expressions: full precedence chain (ternary / || / && / == != /
13
- * comparison / additive / multiplicative / unary / postfix /
14
- * array & object literals / identifiers / literals / parens)
15
- * - Types: leaf types with range/named constraints
16
- *
17
- * NOT yet implemented (TODO for later):
18
- * - Structural types: enum / array<T> / object{...}
19
- * - String template interpolation (${...}) — needs lexer modes
20
- */
21
- import { CstParser, EOF } from 'chevrotain';
22
- import * as t from './lexer.js';
23
- export class TrainParser extends CstParser {
24
- constructor() {
25
- super(t.allTokens, { recoveryEnabled: false });
26
- this.performSelfAnalysis();
27
- }
28
- // ─── Program ──────────────────────────────────────────────────────────
29
- program = this.RULE('program', () => {
30
- this.MANY(() => this.SUBRULE(this.topLevel));
31
- });
32
- /** Entry rule for parsing a bare expression (used by template string
33
- * interpolation: the builder hands `${ ... }` body to this rule
34
- * rather than re-implementing expression parsing). */
35
- exprEntry = this.RULE('exprEntry', () => {
36
- this.SUBRULE(this.expr);
37
- });
38
- topLevel = this.RULE('topLevel', () => {
39
- this.OR([
40
- { ALT: () => this.SUBRULE(this.importDecl) },
41
- { ALT: () => this.SUBRULE(this.constDecl) },
42
- { ALT: () => this.SUBRULE(this.varDecl) },
43
- // Annotation-prefixed forms — order matters: @runtime is its own
44
- // top-level statement; any other @<name> applied to func/fai must
45
- // route to annotatedDecl.
46
- {
47
- GATE: () => this.isRuntimeAnnotation(),
48
- ALT: () => this.SUBRULE(this.runtimeAnnotation),
49
- },
50
- {
51
- GATE: () => this.isAnnotatedFuncOrFai(),
52
- ALT: () => this.SUBRULE(this.annotatedDecl),
53
- },
54
- { ALT: () => this.SUBRULE(this.funcDecl) },
55
- { ALT: () => this.SUBRULE(this.faiDecl) },
56
- { ALT: () => this.SUBRULE(this.exportDecl) },
57
- ]);
58
- });
59
- /** @runtime(...) — distinguished from other annotations by literal name. */
60
- isRuntimeAnnotation() {
61
- const t1 = this.LA(1);
62
- return t1.tokenType === t.AtName && t1.image === '@runtime';
63
- }
64
- /** Look ahead: an AtName followed eventually by `func` or `fai`. */
65
- isAnnotatedFuncOrFai() {
66
- let i = 1;
67
- while (this.LA(i).tokenType === t.AtName) {
68
- i++;
69
- // Skip optional `(...)` arg list of annotation
70
- if (this.LA(i).tokenType === t.LParen) {
71
- let depth = 1;
72
- i++;
73
- while (depth > 0 && this.LA(i).tokenType !== EOF) {
74
- const tok = this.LA(i).tokenType;
75
- if (tok === t.LParen)
76
- depth++;
77
- else if (tok === t.RParen)
78
- depth--;
79
- i++;
80
- }
81
- }
82
- }
83
- const next = this.LA(i).tokenType;
84
- return next === t.Func || next === t.Fai;
85
- }
86
- // ─── Imports ──────────────────────────────────────────────────────────
87
- importDecl = this.RULE('importDecl', () => {
88
- this.CONSUME(t.Import);
89
- this.SUBRULE(this.importClause);
90
- this.CONSUME(t.From);
91
- this.CONSUME(t.StringLit);
92
- this.OPTION(() => this.CONSUME(t.AtName));
93
- });
94
- importClause = this.RULE('importClause', () => {
95
- this.OR([
96
- { ALT: () => this.SUBRULE(this.namedImports) },
97
- { ALT: () => this.SUBRULE(this.namespaceImport) },
98
- ]);
99
- });
100
- namedImports = this.RULE('namedImports', () => {
101
- this.CONSUME(t.LCurly);
102
- this.SUBRULE(this.importSpec);
103
- this.MANY(() => {
104
- this.CONSUME(t.Comma);
105
- this.SUBRULE2(this.importSpec);
106
- });
107
- this.OPTION(() => this.CONSUME2(t.Comma)); // trailing comma
108
- this.CONSUME(t.RCurly);
109
- });
110
- importSpec = this.RULE('importSpec', () => {
111
- this.CONSUME(t.Identifier);
112
- this.OPTION(() => {
113
- this.CONSUME(t.As);
114
- this.CONSUME2(t.Identifier);
115
- });
116
- });
117
- namespaceImport = this.RULE('namespaceImport', () => {
118
- this.CONSUME(t.Star);
119
- this.CONSUME(t.As);
120
- this.CONSUME(t.Identifier);
121
- });
122
- // ─── Annotations ──────────────────────────────────────────────────────
123
- /** Top-level `@runtime(adapter = "claude", ...)`. */
124
- runtimeAnnotation = this.RULE('runtimeAnnotation', () => {
125
- this.CONSUME(t.AtName); // must literally be "@runtime"; semantic layer enforces name
126
- this.OPTION(() => {
127
- this.CONSUME(t.LParen);
128
- this.OPTION2(() => this.SUBRULE(this.annoArgList));
129
- this.CONSUME(t.RParen);
130
- });
131
- });
132
- /** Decoration-style annotation attached to a func/fai/import declaration. */
133
- declAnnotation = this.RULE('declAnnotation', () => {
134
- this.CONSUME(t.AtName);
135
- this.OPTION(() => {
136
- this.CONSUME(t.LParen);
137
- this.OPTION2(() => this.SUBRULE(this.annoArgList));
138
- this.CONSUME(t.RParen);
139
- });
140
- });
141
- annoArgList = this.RULE('annoArgList', () => {
142
- this.SUBRULE(this.annoArg);
143
- this.MANY(() => {
144
- this.CONSUME(t.Comma);
145
- this.SUBRULE2(this.annoArg);
146
- });
147
- this.OPTION(() => this.CONSUME2(t.Comma));
148
- });
149
- annoArg = this.RULE('annoArg', () => {
150
- // Either `key = value` or bare `value`
151
- this.OR([
152
- {
153
- GATE: () => this.LA(1).tokenType === t.Identifier &&
154
- this.LA(2).tokenType === t.Equals,
155
- ALT: () => {
156
- this.CONSUME(t.Identifier);
157
- this.CONSUME(t.Equals);
158
- this.SUBRULE(this.literal);
159
- },
160
- },
161
- { ALT: () => this.SUBRULE2(this.literal) },
162
- ]);
163
- });
164
- /** Wrapper: zero-or-more decl annotations followed by func or fai decl. */
165
- annotatedDecl = this.RULE('annotatedDecl', () => {
166
- this.AT_LEAST_ONE(() => this.SUBRULE(this.declAnnotation));
167
- this.OR([
168
- { ALT: () => this.SUBRULE(this.funcDecl) },
169
- { ALT: () => this.SUBRULE(this.faiDecl) },
170
- ]);
171
- });
172
- // ─── Top-level declarations ───────────────────────────────────────────
173
- constDecl = this.RULE('constDecl', () => {
174
- this.CONSUME(t.Const);
175
- this.CONSUME(t.Identifier);
176
- this.CONSUME(t.Colon);
177
- this.SUBRULE(this.declTypeAnnot);
178
- this.CONSUME(t.Equals);
179
- this.SUBRULE(this.expr);
180
- });
181
- varDecl = this.RULE('varDecl', () => {
182
- this.CONSUME(t.Var);
183
- this.CONSUME(t.Identifier);
184
- this.CONSUME(t.Colon);
185
- this.SUBRULE(this.declTypeAnnot);
186
- this.OPTION(() => {
187
- this.CONSUME(t.Equals);
188
- this.SUBRULE(this.expr);
189
- });
190
- });
191
- funcDecl = this.RULE('funcDecl', () => {
192
- this.CONSUME(t.Func);
193
- this.CONSUME(t.Identifier);
194
- this.CONSUME(t.LParen);
195
- this.OPTION(() => this.SUBRULE(this.paramList));
196
- this.CONSUME(t.RParen);
197
- this.OPTION2(() => {
198
- this.CONSUME(t.Arrow);
199
- this.SUBRULE(this.typeAnnot);
200
- });
201
- this.SUBRULE(this.block);
202
- });
203
- faiDecl = this.RULE('faiDecl', () => {
204
- this.CONSUME(t.Fai);
205
- this.CONSUME(t.Identifier);
206
- this.CONSUME(t.LParen);
207
- this.OPTION(() => this.SUBRULE(this.faiParamList));
208
- this.CONSUME(t.RParen);
209
- this.CONSUME(t.Arrow);
210
- this.SUBRULE(this.faiOutputList);
211
- this.SUBRULE(this.block);
212
- });
213
- exportDecl = this.RULE('exportDecl', () => {
214
- this.CONSUME(t.Export);
215
- this.OR([
216
- { ALT: () => this.SUBRULE(this.exportNames) },
217
- { ALT: () => this.SUBRULE(this.funcDecl) },
218
- { ALT: () => this.SUBRULE(this.faiDecl) },
219
- ]);
220
- });
221
- exportNames = this.RULE('exportNames', () => {
222
- this.OR([
223
- {
224
- ALT: () => {
225
- // `export name [as alias]` or `export name`
226
- this.SUBRULE(this.exportSpec);
227
- },
228
- },
229
- {
230
- ALT: () => {
231
- this.CONSUME(t.LCurly);
232
- this.SUBRULE2(this.exportSpec);
233
- this.MANY(() => {
234
- this.CONSUME(t.Comma);
235
- this.SUBRULE3(this.exportSpec);
236
- });
237
- this.OPTION(() => this.CONSUME2(t.Comma));
238
- this.CONSUME(t.RCurly);
239
- },
240
- },
241
- ]);
242
- });
243
- exportSpec = this.RULE('exportSpec', () => {
244
- this.CONSUME(t.Identifier);
245
- this.OPTION(() => {
246
- this.CONSUME(t.As);
247
- this.CONSUME2(t.Identifier);
248
- });
249
- });
250
- // ─── Parameters / Outputs ─────────────────────────────────────────────
251
- paramList = this.RULE('paramList', () => {
252
- this.SUBRULE(this.param);
253
- this.MANY(() => {
254
- this.CONSUME(t.Comma);
255
- this.SUBRULE2(this.param);
256
- });
257
- this.OPTION(() => this.CONSUME2(t.Comma));
258
- });
259
- param = this.RULE('param', () => {
260
- this.CONSUME(t.Identifier);
261
- this.OPTION(() => {
262
- this.CONSUME(t.Colon);
263
- this.SUBRULE(this.typeAnnot);
264
- });
265
- });
266
- faiParamList = this.RULE('faiParamList', () => {
267
- this.SUBRULE(this.faiParam);
268
- this.MANY(() => {
269
- this.CONSUME(t.Comma);
270
- this.SUBRULE2(this.faiParam);
271
- });
272
- this.OPTION(() => this.CONSUME2(t.Comma));
273
- });
274
- faiParam = this.RULE('faiParam', () => {
275
- this.CONSUME(t.Identifier);
276
- this.CONSUME(t.Colon);
277
- this.SUBRULE(this.typeAnnot);
278
- });
279
- faiOutputList = this.RULE('faiOutputList', () => {
280
- this.SUBRULE(this.faiOutput);
281
- this.MANY(() => {
282
- this.CONSUME(t.Comma);
283
- this.SUBRULE2(this.faiOutput);
284
- });
285
- });
286
- faiOutput = this.RULE('faiOutput', () => {
287
- this.CONSUME(t.Identifier);
288
- this.CONSUME(t.Colon);
289
- this.SUBRULE(this.typeAnnot);
290
- });
291
- // ─── Type annotations ─────────────────────────────────────────────────
292
- typeAnnot = this.RULE('typeAnnot', () => {
293
- this.OR([
294
- { ALT: () => this.SUBRULE(this.enumType) },
295
- { ALT: () => this.SUBRULE(this.arrayType) },
296
- { ALT: () => this.SUBRULE(this.objectType) },
297
- { ALT: () => this.SUBRULE(this.scalarType) }, // catch-all leaf type
298
- ]);
299
- });
300
- // Variant of typeAnnot used by let/var/const declarations. These
301
- // forbid trailing named constraints (`int 0-10`, `maxLen=5`, etc.)
302
- // because the following statement (`x = 5`) would otherwise be
303
- // silently absorbed as a NamedConstraint, swallowing the assignment.
304
- // Constraints belong on fai outputs / func params where they're
305
- // contract-relevant, not on local bindings.
306
- declTypeAnnot = this.RULE('declTypeAnnot', () => {
307
- this.OR([
308
- { ALT: () => this.SUBRULE(this.enumType) },
309
- { ALT: () => this.SUBRULE(this.declArrayType) },
310
- { ALT: () => this.SUBRULE(this.objectType) },
311
- { ALT: () => this.SUBRULE(this.declScalarType) },
312
- ]);
313
- });
314
- declScalarType = this.RULE('declScalarType', () => {
315
- this.CONSUME(t.Identifier);
316
- });
317
- declArrayType = this.RULE('declArrayType', () => {
318
- this.CONSUME(t.KwArray);
319
- this.CONSUME(t.LAngle);
320
- this.SUBRULE(this.typeAnnot);
321
- this.CONSUME(t.RAngle);
322
- });
323
- scalarType = this.RULE('scalarType', () => {
324
- this.CONSUME(t.Identifier); // int / float / bool / string / prompt / any / etc.
325
- this.OPTION(() => this.SUBRULE(this.typeConstraint));
326
- });
327
- enumType = this.RULE('enumType', () => {
328
- this.CONSUME(t.KwEnum);
329
- this.CONSUME(t.Colon);
330
- this.CONSUME(t.Identifier); // first variant
331
- this.MANY(() => {
332
- this.CONSUME(t.Pipe);
333
- this.CONSUME2(t.Identifier);
334
- });
335
- });
336
- arrayType = this.RULE('arrayType', () => {
337
- this.CONSUME(t.KwArray);
338
- this.CONSUME(t.LAngle);
339
- this.SUBRULE(this.typeAnnot);
340
- this.CONSUME(t.RAngle);
341
- this.OPTION(() => this.SUBRULE(this.namedConstraint));
342
- });
343
- objectType = this.RULE('objectType', () => {
344
- this.CONSUME(t.KwObject);
345
- this.CONSUME(t.LCurly);
346
- this.SUBRULE(this.objectTypeField);
347
- this.MANY(() => {
348
- this.CONSUME(t.Comma);
349
- this.SUBRULE2(this.objectTypeField);
350
- });
351
- this.OPTION(() => this.CONSUME2(t.Comma));
352
- this.CONSUME(t.RCurly);
353
- });
354
- objectTypeField = this.RULE('objectTypeField', () => {
355
- this.CONSUME(t.Identifier);
356
- this.CONSUME(t.Colon);
357
- this.SUBRULE(this.typeAnnot);
358
- });
359
- typeConstraint = this.RULE('typeConstraint', () => {
360
- this.OR([
361
- {
362
- GATE: () => this.isRangeConstraint(),
363
- ALT: () => this.SUBRULE(this.rangeConstraint),
364
- },
365
- { ALT: () => this.SUBRULE(this.namedConstraint) },
366
- ]);
367
- });
368
- /** Range constraint starts with a numeric literal; named with identifier. */
369
- isRangeConstraint() {
370
- const t1 = this.LA(1).tokenType;
371
- return t1 === t.IntLit || t1 === t.FloatLit;
372
- }
373
- rangeConstraint = this.RULE('rangeConstraint', () => {
374
- this.SUBRULE(this.numberLit);
375
- this.CONSUME(t.Dash);
376
- this.SUBRULE2(this.numberLit);
377
- });
378
- namedConstraint = this.RULE('namedConstraint', () => {
379
- this.CONSUME(t.Identifier); // "maxLen", "minLen", "min", "max", "matches"
380
- this.CONSUME(t.Equals);
381
- this.OR([
382
- { ALT: () => this.SUBRULE(this.numberLit) },
383
- { ALT: () => this.CONSUME(t.StringLit) },
384
- ]);
385
- });
386
- numberLit = this.RULE('numberLit', () => {
387
- this.OR([
388
- { ALT: () => this.CONSUME(t.IntLit) },
389
- { ALT: () => this.CONSUME(t.FloatLit) },
390
- ]);
391
- });
392
- // ─── Block / Statements ───────────────────────────────────────────────
393
- block = this.RULE('block', () => {
394
- this.CONSUME(t.LCurly);
395
- this.MANY(() => this.SUBRULE(this.stmt));
396
- this.CONSUME(t.RCurly);
397
- });
398
- stmt = this.RULE('stmt', () => {
399
- this.OR([
400
- { ALT: () => this.SUBRULE(this.letDecl) },
401
- { ALT: () => this.SUBRULE(this.ifStmt) },
402
- { ALT: () => this.SUBRULE(this.forStmt) },
403
- { ALT: () => this.SUBRULE(this.whileStmt) },
404
- { ALT: () => this.SUBRULE(this.tryStmt) },
405
- { ALT: () => this.SUBRULE(this.breakStmt) },
406
- { ALT: () => this.SUBRULE(this.continueStmt) },
407
- { ALT: () => this.SUBRULE(this.returnStmt) },
408
- // Assignment vs expression-statement: both start with the same
409
- // primary tokens (Identifier mostly). Distinguish by lookahead.
410
- {
411
- GATE: () => this.isAssignment(),
412
- ALT: () => this.SUBRULE(this.assignment),
413
- },
414
- { ALT: () => this.SUBRULE(this.exprStmt) },
415
- ]);
416
- // Optional explicit semicolon terminator. Newlines are also treated
417
- // as terminators implicitly by chevrotain (which skips whitespace),
418
- // so most programs write one statement per line.
419
- this.OPTION(() => this.CONSUME(t.Semicolon));
420
- });
421
- /**
422
- * An assignment starts with an l-value (Identifier with optional . [ suffixes)
423
- * followed by an assignment operator. We scan ahead, skipping balanced
424
- * brackets, looking for one of the assignment ops at the same paren depth.
425
- */
426
- isAssignment() {
427
- if (this.LA(1).tokenType !== t.Identifier)
428
- return false;
429
- let i = 2;
430
- let depth = 0;
431
- while (true) {
432
- const tok = this.LA(i).tokenType;
433
- if (tok === EOF)
434
- return false;
435
- if (depth === 0) {
436
- if (tok === t.Equals ||
437
- tok === t.PlusEq ||
438
- tok === t.MinusEq ||
439
- tok === t.StarEq ||
440
- tok === t.SlashEq ||
441
- tok === t.PercentEq) {
442
- return true;
443
- }
444
- // boundaries that disqualify l-value parsing
445
- if (tok === t.Semicolon ||
446
- tok === t.RCurly ||
447
- tok === t.LCurly ||
448
- tok === t.Comma ||
449
- tok === t.RParen) {
450
- return false;
451
- }
452
- // valid l-value continuations
453
- if (tok === t.Dot || tok === t.Identifier) {
454
- i++;
455
- continue;
456
- }
457
- if (tok === t.LBracket || tok === t.LParen) {
458
- depth++;
459
- i++;
460
- continue;
461
- }
462
- // Any other token at depth 0 means this isn't a plain l-value chain
463
- return false;
464
- }
465
- else {
466
- // inside brackets: skip until balanced
467
- if (tok === t.LBracket || tok === t.LParen)
468
- depth++;
469
- else if (tok === t.RBracket || tok === t.RParen)
470
- depth--;
471
- i++;
472
- if (depth < 0)
473
- return false;
474
- }
475
- }
476
- }
477
- letDecl = this.RULE('letDecl', () => {
478
- this.CONSUME(t.Let);
479
- this.SUBRULE(this.letTarget);
480
- this.OPTION(() => {
481
- this.CONSUME(t.Colon);
482
- this.SUBRULE(this.declTypeAnnot);
483
- });
484
- this.OPTION2(() => {
485
- this.CONSUME(t.Equals);
486
- this.SUBRULE(this.expr);
487
- });
488
- });
489
- letTarget = this.RULE('letTarget', () => {
490
- this.OR([
491
- { ALT: () => this.CONSUME(t.Identifier) },
492
- { ALT: () => this.SUBRULE(this.objectDestruct) },
493
- { ALT: () => this.SUBRULE(this.arrayDestruct) },
494
- ]);
495
- });
496
- objectDestruct = this.RULE('objectDestruct', () => {
497
- this.CONSUME(t.LCurly);
498
- this.SUBRULE(this.destructField);
499
- this.MANY(() => {
500
- this.CONSUME(t.Comma);
501
- this.SUBRULE2(this.destructField);
502
- });
503
- this.OPTION(() => this.CONSUME2(t.Comma));
504
- this.CONSUME(t.RCurly);
505
- });
506
- destructField = this.RULE('destructField', () => {
507
- this.CONSUME(t.Identifier);
508
- this.OPTION(() => {
509
- this.CONSUME(t.Colon);
510
- this.CONSUME2(t.Identifier);
511
- });
512
- });
513
- arrayDestruct = this.RULE('arrayDestruct', () => {
514
- this.CONSUME(t.LBracket);
515
- this.CONSUME(t.Identifier);
516
- this.MANY(() => {
517
- this.CONSUME(t.Comma);
518
- this.CONSUME2(t.Identifier);
519
- });
520
- this.OPTION(() => this.CONSUME2(t.Comma));
521
- this.CONSUME(t.RBracket);
522
- });
523
- assignment = this.RULE('assignment', () => {
524
- this.SUBRULE(this.lvalue);
525
- this.SUBRULE(this.assignOp);
526
- this.SUBRULE(this.expr);
527
- });
528
- lvalue = this.RULE('lvalue', () => {
529
- this.CONSUME(t.Identifier);
530
- this.MANY(() => this.SUBRULE(this.lvalueSuffix));
531
- });
532
- lvalueSuffix = this.RULE('lvalueSuffix', () => {
533
- this.OR([
534
- {
535
- ALT: () => {
536
- this.CONSUME(t.Dot);
537
- this.CONSUME(t.Identifier);
538
- },
539
- },
540
- {
541
- ALT: () => {
542
- this.CONSUME(t.LBracket);
543
- this.SUBRULE(this.expr);
544
- this.CONSUME(t.RBracket);
545
- },
546
- },
547
- ]);
548
- });
549
- assignOp = this.RULE('assignOp', () => {
550
- this.OR([
551
- { ALT: () => this.CONSUME(t.Equals) },
552
- { ALT: () => this.CONSUME(t.PlusEq) },
553
- { ALT: () => this.CONSUME(t.MinusEq) },
554
- { ALT: () => this.CONSUME(t.StarEq) },
555
- { ALT: () => this.CONSUME(t.SlashEq) },
556
- { ALT: () => this.CONSUME(t.PercentEq) },
557
- ]);
558
- });
559
- ifStmt = this.RULE('ifStmt', () => {
560
- this.CONSUME(t.If);
561
- this.CONSUME(t.LParen);
562
- this.SUBRULE(this.expr);
563
- this.CONSUME(t.RParen);
564
- this.SUBRULE(this.block);
565
- this.MANY({
566
- GATE: () => this.LA(1).tokenType === t.Else && this.LA(2).tokenType === t.If,
567
- DEF: () => {
568
- this.CONSUME(t.Else);
569
- this.CONSUME2(t.If);
570
- this.CONSUME2(t.LParen);
571
- this.SUBRULE2(this.expr);
572
- this.CONSUME2(t.RParen);
573
- this.SUBRULE2(this.block);
574
- },
575
- });
576
- this.OPTION(() => {
577
- this.CONSUME3(t.Else);
578
- this.SUBRULE3(this.block);
579
- });
580
- });
581
- forStmt = this.RULE('forStmt', () => {
582
- this.CONSUME(t.For);
583
- this.CONSUME(t.Identifier);
584
- this.CONSUME(t.In);
585
- this.SUBRULE(this.expr);
586
- this.SUBRULE(this.block);
587
- });
588
- whileStmt = this.RULE('whileStmt', () => {
589
- this.CONSUME(t.While);
590
- this.CONSUME(t.LParen);
591
- this.SUBRULE(this.expr);
592
- this.CONSUME(t.RParen);
593
- this.SUBRULE(this.block);
594
- });
595
- tryStmt = this.RULE('tryStmt', () => {
596
- this.CONSUME(t.Try);
597
- this.SUBRULE(this.block);
598
- this.AT_LEAST_ONE(() => this.SUBRULE(this.catchClause));
599
- });
600
- catchClause = this.RULE('catchClause', () => {
601
- this.CONSUME(t.Catch);
602
- this.CONSUME(t.Identifier); // exception type name
603
- this.OPTION(() => {
604
- this.CONSUME(t.As);
605
- this.CONSUME2(t.Identifier); // bound variable
606
- });
607
- this.SUBRULE(this.block);
608
- });
609
- breakStmt = this.RULE('breakStmt', () => {
610
- this.CONSUME(t.Break);
611
- });
612
- continueStmt = this.RULE('continueStmt', () => {
613
- this.CONSUME(t.Continue);
614
- });
615
- returnStmt = this.RULE('returnStmt', () => {
616
- this.CONSUME(t.Return);
617
- this.OPTION({
618
- // Avoid eating tokens that begin the next statement.
619
- GATE: () => this.canStartExpression(),
620
- DEF: () => this.SUBRULE(this.expr),
621
- });
622
- });
623
- /** Heuristic: does the current lookahead token start an expression? */
624
- canStartExpression() {
625
- const tok = this.LA(1).tokenType;
626
- return (tok === t.IntLit ||
627
- tok === t.FloatLit ||
628
- tok === t.StringLit ||
629
- tok === t.True ||
630
- tok === t.False ||
631
- tok === t.Null ||
632
- tok === t.Identifier ||
633
- tok === t.LParen ||
634
- tok === t.LBracket ||
635
- tok === t.LCurly ||
636
- tok === t.Dash ||
637
- tok === t.Bang);
638
- }
639
- exprStmt = this.RULE('exprStmt', () => {
640
- this.SUBRULE(this.expr);
641
- });
642
- // ─── Expressions (precedence from LOW to HIGH) ────────────────────────
643
- expr = this.RULE('expr', () => {
644
- this.SUBRULE(this.ternaryExpr);
645
- });
646
- ternaryExpr = this.RULE('ternaryExpr', () => {
647
- this.SUBRULE(this.logicalOrExpr);
648
- this.OPTION(() => {
649
- this.CONSUME(t.Question);
650
- this.SUBRULE(this.expr);
651
- this.CONSUME(t.Colon);
652
- this.SUBRULE2(this.expr);
653
- });
654
- });
655
- logicalOrExpr = this.RULE('logicalOrExpr', () => {
656
- this.SUBRULE(this.logicalAndExpr);
657
- this.MANY(() => {
658
- this.CONSUME(t.OrOr);
659
- this.SUBRULE2(this.logicalAndExpr);
660
- });
661
- });
662
- logicalAndExpr = this.RULE('logicalAndExpr', () => {
663
- this.SUBRULE(this.equalityExpr);
664
- this.MANY(() => {
665
- this.CONSUME(t.AndAnd);
666
- this.SUBRULE2(this.equalityExpr);
667
- });
668
- });
669
- equalityExpr = this.RULE('equalityExpr', () => {
670
- this.SUBRULE(this.comparisonExpr);
671
- this.MANY(() => {
672
- this.OR([
673
- { ALT: () => this.CONSUME(t.EqEq) },
674
- { ALT: () => this.CONSUME(t.NotEq) },
675
- ]);
676
- this.SUBRULE2(this.comparisonExpr);
677
- });
678
- });
679
- comparisonExpr = this.RULE('comparisonExpr', () => {
680
- this.SUBRULE(this.additiveExpr);
681
- this.MANY(() => {
682
- this.OR([
683
- { ALT: () => this.CONSUME(t.LAngle) },
684
- { ALT: () => this.CONSUME(t.LtEq) },
685
- { ALT: () => this.CONSUME(t.RAngle) },
686
- { ALT: () => this.CONSUME(t.GtEq) },
687
- ]);
688
- this.SUBRULE2(this.additiveExpr);
689
- });
690
- });
691
- additiveExpr = this.RULE('additiveExpr', () => {
692
- this.SUBRULE(this.multiplicativeExpr);
693
- this.MANY(() => {
694
- this.OR([
695
- { ALT: () => this.CONSUME(t.Plus) },
696
- { ALT: () => this.CONSUME(t.Dash) },
697
- ]);
698
- this.SUBRULE2(this.multiplicativeExpr);
699
- });
700
- });
701
- multiplicativeExpr = this.RULE('multiplicativeExpr', () => {
702
- this.SUBRULE(this.unaryExpr);
703
- this.MANY(() => {
704
- this.OR([
705
- { ALT: () => this.CONSUME(t.Star) },
706
- { ALT: () => this.CONSUME(t.Slash) },
707
- { ALT: () => this.CONSUME(t.Percent) },
708
- ]);
709
- this.SUBRULE2(this.unaryExpr);
710
- });
711
- });
712
- unaryExpr = this.RULE('unaryExpr', () => {
713
- this.OPTION(() => {
714
- this.OR([
715
- { ALT: () => this.CONSUME(t.Dash) },
716
- { ALT: () => this.CONSUME(t.Bang) },
717
- ]);
718
- });
719
- this.SUBRULE(this.postfixExpr);
720
- });
721
- postfixExpr = this.RULE('postfixExpr', () => {
722
- this.SUBRULE(this.primaryExpr);
723
- this.MANY(() => this.SUBRULE(this.postfixSuffix));
724
- });
725
- postfixSuffix = this.RULE('postfixSuffix', () => {
726
- this.OR([
727
- {
728
- ALT: () => {
729
- this.CONSUME(t.Dot);
730
- this.CONSUME(t.Identifier);
731
- },
732
- },
733
- {
734
- ALT: () => {
735
- this.CONSUME(t.LBracket);
736
- this.SUBRULE(this.expr);
737
- this.CONSUME(t.RBracket);
738
- },
739
- },
740
- {
741
- ALT: () => {
742
- this.CONSUME(t.LParen);
743
- this.OPTION(() => this.SUBRULE(this.argList));
744
- this.CONSUME(t.RParen);
745
- },
746
- },
747
- ]);
748
- });
749
- argList = this.RULE('argList', () => {
750
- this.SUBRULE(this.expr);
751
- this.MANY(() => {
752
- this.CONSUME(t.Comma);
753
- this.SUBRULE2(this.expr);
754
- });
755
- this.OPTION(() => this.CONSUME2(t.Comma));
756
- });
757
- primaryExpr = this.RULE('primaryExpr', () => {
758
- this.OR([
759
- { ALT: () => this.SUBRULE(this.literal) },
760
- { ALT: () => this.CONSUME(t.Identifier) },
761
- { ALT: () => this.SUBRULE(this.arrayLit) },
762
- { ALT: () => this.SUBRULE(this.objectLit) },
763
- {
764
- ALT: () => {
765
- this.CONSUME(t.LParen);
766
- this.SUBRULE(this.expr);
767
- this.CONSUME(t.RParen);
768
- },
769
- },
770
- ]);
771
- });
772
- literal = this.RULE('literal', () => {
773
- this.OR([
774
- { ALT: () => this.CONSUME(t.IntLit) },
775
- { ALT: () => this.CONSUME(t.FloatLit) },
776
- { ALT: () => this.CONSUME(t.StringLit) },
777
- { ALT: () => this.CONSUME(t.True) },
778
- { ALT: () => this.CONSUME(t.False) },
779
- { ALT: () => this.CONSUME(t.Null) },
780
- ]);
781
- });
782
- arrayLit = this.RULE('arrayLit', () => {
783
- this.CONSUME(t.LBracket);
784
- this.OPTION(() => {
785
- this.SUBRULE(this.expr);
786
- this.MANY(() => {
787
- this.CONSUME(t.Comma);
788
- this.SUBRULE2(this.expr);
789
- });
790
- this.OPTION2(() => this.CONSUME2(t.Comma));
791
- });
792
- this.CONSUME(t.RBracket);
793
- });
794
- objectLit = this.RULE('objectLit', () => {
795
- this.CONSUME(t.LCurly);
796
- this.OPTION(() => {
797
- this.SUBRULE(this.objectLitField);
798
- this.MANY(() => {
799
- this.CONSUME(t.Comma);
800
- this.SUBRULE2(this.objectLitField);
801
- });
802
- this.OPTION2(() => this.CONSUME2(t.Comma));
803
- });
804
- this.CONSUME(t.RCurly);
805
- });
806
- objectLitField = this.RULE('objectLitField', () => {
807
- this.OR([
808
- {
809
- // `"key": value`
810
- GATE: () => this.LA(1).tokenType === t.StringLit,
811
- ALT: () => {
812
- this.CONSUME(t.StringLit);
813
- this.CONSUME(t.Colon);
814
- this.SUBRULE(this.expr);
815
- },
816
- },
817
- {
818
- // `key: value` or shorthand `key`
819
- ALT: () => {
820
- this.CONSUME(t.Identifier);
821
- this.OPTION(() => {
822
- this.CONSUME2(t.Colon);
823
- this.SUBRULE2(this.expr);
824
- });
825
- },
826
- },
827
- ]);
828
- });
829
- }
830
- // Singleton parser instance (chevrotain best practice — performSelfAnalysis is expensive)
831
- export const trainParser = new TrainParser();
832
- /**
833
- * Parse train source text. Returns CST + any errors (does not throw on parse errors,
834
- * to allow IDE-style error reporting).
835
- */
836
- export function parse(source) {
837
- const lexResult = t.trainLexer.tokenize(source);
838
- trainParser.input = lexResult.tokens;
839
- const cst = trainParser.program();
840
- return {
841
- cst,
842
- lexErrors: lexResult.errors,
843
- parseErrors: trainParser.errors,
844
- };
845
- }
846
- /**
847
- * Parse a single expression. Used internally by the template-string
848
- * interpolation builder. The source must be exactly an expression
849
- * (no surrounding statement/punctuation).
850
- */
851
- export function parseExpression(source) {
852
- const lexResult = t.trainLexer.tokenize(source);
853
- trainParser.input = lexResult.tokens;
854
- const cst = trainParser.exprEntry();
855
- return {
856
- cst,
857
- lexErrors: lexResult.errors,
858
- parseErrors: trainParser.errors,
859
- };
860
- }
861
- //# sourceMappingURL=parser.js.map