@tom2012/cc-web 2026.5.14-b → 2026.5.15-a

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 (236) hide show
  1. package/README.md +1 -1
  2. package/backend/dist/index.d.ts.map +1 -1
  3. package/backend/dist/index.js +51 -0
  4. package/backend/dist/index.js.map +1 -1
  5. package/backend/dist/routes/flows.d.ts.map +1 -1
  6. package/backend/dist/routes/flows.js +10 -0
  7. package/backend/dist/routes/flows.js.map +1 -1
  8. package/backend/dist/routes/global-tracks.d.ts +11 -0
  9. package/backend/dist/routes/global-tracks.d.ts.map +1 -0
  10. package/backend/dist/routes/global-tracks.js +86 -0
  11. package/backend/dist/routes/global-tracks.js.map +1 -0
  12. package/backend/dist/routes/tracks.d.ts +14 -0
  13. package/backend/dist/routes/tracks.d.ts.map +1 -0
  14. package/backend/dist/routes/tracks.js +184 -0
  15. package/backend/dist/routes/tracks.js.map +1 -0
  16. package/backend/dist/tracks/__tests__/verify-track-t1.d.ts +11 -0
  17. package/backend/dist/tracks/__tests__/verify-track-t1.d.ts.map +1 -0
  18. package/backend/dist/tracks/__tests__/verify-track-t1.js +293 -0
  19. package/backend/dist/tracks/__tests__/verify-track-t1.js.map +1 -0
  20. package/backend/dist/tracks/__tests__/verify-track.d.ts +20 -0
  21. package/backend/dist/tracks/__tests__/verify-track.d.ts.map +1 -0
  22. package/backend/dist/tracks/__tests__/verify-track.js +187 -0
  23. package/backend/dist/tracks/__tests__/verify-track.js.map +1 -0
  24. package/backend/dist/tracks/ask-user-bridge.d.ts +59 -0
  25. package/backend/dist/tracks/ask-user-bridge.d.ts.map +1 -0
  26. package/backend/dist/tracks/ask-user-bridge.js +186 -0
  27. package/backend/dist/tracks/ask-user-bridge.js.map +1 -0
  28. package/backend/dist/tracks/ccweb-train-adapter.d.ts +40 -0
  29. package/backend/dist/tracks/ccweb-train-adapter.d.ts.map +1 -0
  30. package/backend/dist/tracks/ccweb-train-adapter.js +111 -0
  31. package/backend/dist/tracks/ccweb-train-adapter.js.map +1 -0
  32. package/backend/dist/tracks/cross-lock.d.ts +30 -0
  33. package/backend/dist/tracks/cross-lock.d.ts.map +1 -0
  34. package/backend/dist/tracks/cross-lock.js +44 -0
  35. package/backend/dist/tracks/cross-lock.js.map +1 -0
  36. package/backend/dist/tracks/index.d.ts +20 -0
  37. package/backend/dist/tracks/index.d.ts.map +1 -0
  38. package/backend/dist/tracks/index.js +42 -0
  39. package/backend/dist/tracks/index.js.map +1 -0
  40. package/backend/dist/tracks/registry.d.ts +56 -0
  41. package/backend/dist/tracks/registry.d.ts.map +1 -0
  42. package/backend/dist/tracks/registry.js +161 -0
  43. package/backend/dist/tracks/registry.js.map +1 -0
  44. package/backend/dist/tracks/store.d.ts +37 -0
  45. package/backend/dist/tracks/store.d.ts.map +1 -0
  46. package/backend/dist/tracks/store.js +254 -0
  47. package/backend/dist/tracks/store.js.map +1 -0
  48. package/backend/dist/tracks/track-runner.d.ts +62 -0
  49. package/backend/dist/tracks/track-runner.d.ts.map +1 -0
  50. package/backend/dist/tracks/track-runner.js +134 -0
  51. package/backend/dist/tracks/track-runner.js.map +1 -0
  52. package/backend/dist/tracks/train-loader.d.ts +44 -0
  53. package/backend/dist/tracks/train-loader.d.ts.map +1 -0
  54. package/backend/dist/tracks/train-loader.js +32 -0
  55. package/backend/dist/tracks/train-loader.js.map +1 -0
  56. package/backend/dist/tracks/types-train.d.ts +12 -0
  57. package/backend/dist/tracks/types-train.d.ts.map +1 -0
  58. package/backend/dist/tracks/types-train.js +13 -0
  59. package/backend/dist/tracks/types-train.js.map +1 -0
  60. package/backend/dist/tracks/types.d.ts +66 -0
  61. package/backend/dist/tracks/types.d.ts.map +1 -0
  62. package/backend/dist/tracks/types.js +12 -0
  63. package/backend/dist/tracks/types.js.map +1 -0
  64. package/backend/dist/tracks/workflow-data-watcher.d.ts +47 -0
  65. package/backend/dist/tracks/workflow-data-watcher.d.ts.map +1 -0
  66. package/backend/dist/tracks/workflow-data-watcher.js +166 -0
  67. package/backend/dist/tracks/workflow-data-watcher.js.map +1 -0
  68. package/backend/package-lock.json +107 -0
  69. package/backend/package.json +6 -1
  70. package/backend/vendor/@train-lang/adapter-spec/dist/index.d.ts +164 -0
  71. package/backend/vendor/@train-lang/adapter-spec/dist/index.d.ts.map +1 -0
  72. package/backend/vendor/@train-lang/adapter-spec/dist/index.js +13 -0
  73. package/backend/vendor/@train-lang/adapter-spec/dist/index.js.map +1 -0
  74. package/backend/vendor/@train-lang/adapter-spec/package.json +15 -0
  75. package/backend/vendor/@train-lang/core/dist/ast-cache.d.ts +74 -0
  76. package/backend/vendor/@train-lang/core/dist/ast-cache.d.ts.map +1 -0
  77. package/backend/vendor/@train-lang/core/dist/ast-cache.js +157 -0
  78. package/backend/vendor/@train-lang/core/dist/ast-cache.js.map +1 -0
  79. package/backend/vendor/@train-lang/core/dist/ast.d.ts +350 -0
  80. package/backend/vendor/@train-lang/core/dist/ast.d.ts.map +1 -0
  81. package/backend/vendor/@train-lang/core/dist/ast.js +15 -0
  82. package/backend/vendor/@train-lang/core/dist/ast.js.map +1 -0
  83. package/backend/vendor/@train-lang/core/dist/builder.d.ts +21 -0
  84. package/backend/vendor/@train-lang/core/dist/builder.d.ts.map +1 -0
  85. package/backend/vendor/@train-lang/core/dist/builder.js +1221 -0
  86. package/backend/vendor/@train-lang/core/dist/builder.js.map +1 -0
  87. package/backend/vendor/@train-lang/core/dist/builtins.d.ts +17 -0
  88. package/backend/vendor/@train-lang/core/dist/builtins.d.ts.map +1 -0
  89. package/backend/vendor/@train-lang/core/dist/builtins.js +488 -0
  90. package/backend/vendor/@train-lang/core/dist/builtins.js.map +1 -0
  91. package/backend/vendor/@train-lang/core/dist/index.d.ts +54 -0
  92. package/backend/vendor/@train-lang/core/dist/index.d.ts.map +1 -0
  93. package/backend/vendor/@train-lang/core/dist/index.js +66 -0
  94. package/backend/vendor/@train-lang/core/dist/index.js.map +1 -0
  95. package/backend/vendor/@train-lang/core/dist/interpreter.d.ts +110 -0
  96. package/backend/vendor/@train-lang/core/dist/interpreter.d.ts.map +1 -0
  97. package/backend/vendor/@train-lang/core/dist/interpreter.js +894 -0
  98. package/backend/vendor/@train-lang/core/dist/interpreter.js.map +1 -0
  99. package/backend/vendor/@train-lang/core/dist/lexer.d.ts +88 -0
  100. package/backend/vendor/@train-lang/core/dist/lexer.d.ts.map +1 -0
  101. package/backend/vendor/@train-lang/core/dist/lexer.js +243 -0
  102. package/backend/vendor/@train-lang/core/dist/lexer.js.map +1 -0
  103. package/backend/vendor/@train-lang/core/dist/module-loader.d.ts +74 -0
  104. package/backend/vendor/@train-lang/core/dist/module-loader.d.ts.map +1 -0
  105. package/backend/vendor/@train-lang/core/dist/module-loader.js +134 -0
  106. package/backend/vendor/@train-lang/core/dist/module-loader.js.map +1 -0
  107. package/backend/vendor/@train-lang/core/dist/parser.d.ts +135 -0
  108. package/backend/vendor/@train-lang/core/dist/parser.d.ts.map +1 -0
  109. package/backend/vendor/@train-lang/core/dist/parser.js +838 -0
  110. package/backend/vendor/@train-lang/core/dist/parser.js.map +1 -0
  111. package/backend/vendor/@train-lang/core/dist/prompt-composer.d.ts +49 -0
  112. package/backend/vendor/@train-lang/core/dist/prompt-composer.d.ts.map +1 -0
  113. package/backend/vendor/@train-lang/core/dist/prompt-composer.js +159 -0
  114. package/backend/vendor/@train-lang/core/dist/prompt-composer.js.map +1 -0
  115. package/backend/vendor/@train-lang/core/dist/runtime.d.ts +146 -0
  116. package/backend/vendor/@train-lang/core/dist/runtime.d.ts.map +1 -0
  117. package/backend/vendor/@train-lang/core/dist/runtime.js +156 -0
  118. package/backend/vendor/@train-lang/core/dist/runtime.js.map +1 -0
  119. package/backend/vendor/@train-lang/core/dist/type-descriptor.d.ts +18 -0
  120. package/backend/vendor/@train-lang/core/dist/type-descriptor.d.ts.map +1 -0
  121. package/backend/vendor/@train-lang/core/dist/type-descriptor.js +94 -0
  122. package/backend/vendor/@train-lang/core/dist/type-descriptor.js.map +1 -0
  123. package/backend/vendor/@train-lang/core/dist/validation.d.ts +44 -0
  124. package/backend/vendor/@train-lang/core/dist/validation.d.ts.map +1 -0
  125. package/backend/vendor/@train-lang/core/dist/validation.js +271 -0
  126. package/backend/vendor/@train-lang/core/dist/validation.js.map +1 -0
  127. package/backend/vendor/@train-lang/core/package.json +35 -0
  128. package/frontend/dist/assets/{ChatOverlay-B4bHclb4.js → ChatOverlay-D0AFod2I.js} +1 -1
  129. package/frontend/dist/assets/{GraphPreview-CBR4uFHb.js → GraphPreview-BTnlkocf.js} +2 -2
  130. package/frontend/dist/assets/{MobilePage-B7u9HJ1Y.js → MobilePage-CnjdRqIt.js} +3 -3
  131. package/frontend/dist/assets/{OfficePreview-V-X3ON2u.js → OfficePreview-nTZKPD9R.js} +2 -2
  132. package/frontend/dist/assets/{PdfPreview-NktKOUdL.js → PdfPreview-DlB-s5M8.js} +1 -1
  133. package/frontend/dist/assets/{ProjectPage-DAU6cEkl.js → ProjectPage-C_3_sZbd.js} +5 -5
  134. package/frontend/dist/assets/{SettingsPage-CtBCvofK.js → SettingsPage-BYSCQKoh.js} +2 -2
  135. package/frontend/dist/assets/{SkillHubPage-CHvWwI8j.js → SkillHubPage-CUgZXyeE.js} +3 -3
  136. package/frontend/dist/assets/TrackEditor-R2lmPugZ.js +14 -0
  137. package/frontend/dist/assets/abap-LPLW346S.js +7 -0
  138. package/frontend/dist/assets/apex-Dk-jUCUV.js +7 -0
  139. package/frontend/dist/assets/azcli-DPUMmPlX.js +7 -0
  140. package/frontend/dist/assets/bat-C1Qbg1bV.js +7 -0
  141. package/frontend/dist/assets/bicep-D-e-VSJi.js +7 -0
  142. package/frontend/dist/assets/cameligo-CjUqTgqL.js +7 -0
  143. package/frontend/dist/assets/{chevron-down-COdWD3xd.js → chevron-down-Bc6Xpnnk.js} +1 -1
  144. package/frontend/dist/assets/clojure-BWsu6Kju.js +7 -0
  145. package/frontend/dist/assets/codicon-DCmgc-ay.ttf +0 -0
  146. package/frontend/dist/assets/coffee-DeC36AK3.js +7 -0
  147. package/frontend/dist/assets/cpp-DcZnmBWT.js +7 -0
  148. package/frontend/dist/assets/csharp-DqBXBMf0.js +7 -0
  149. package/frontend/dist/assets/csp-CkO7y8ul.js +7 -0
  150. package/frontend/dist/assets/css-OAcfVtED.js +7 -0
  151. package/frontend/dist/assets/cssMode-oT-78_Ke.js +7 -0
  152. package/frontend/dist/assets/cypher-40UGrUjD.js +7 -0
  153. package/frontend/dist/assets/dart-DmixyLor.js +7 -0
  154. package/frontend/dist/assets/dockerfile-CayO4nTA.js +7 -0
  155. package/frontend/dist/assets/ecl-DRrKCuVc.js +7 -0
  156. package/frontend/dist/assets/editor-B5EY1bb8.css +1 -0
  157. package/frontend/dist/assets/editor.main-CKHkO4rf.js +37 -0
  158. package/frontend/dist/assets/elixir-J3qpp9mX.js +7 -0
  159. package/frontend/dist/assets/flow9-DzW2c4Im.js +7 -0
  160. package/frontend/dist/assets/freemarker2-gLqtlSdW.js +7 -0
  161. package/frontend/dist/assets/fsharp-D00tn_6c.js +7 -0
  162. package/frontend/dist/assets/go-NnNmgWK_.js +7 -0
  163. package/frontend/dist/assets/graphql-C9_--VLF.js +7 -0
  164. package/frontend/dist/assets/handlebars-CMR-cKzv.js +7 -0
  165. package/frontend/dist/assets/hcl-BhbOULbp.js +7 -0
  166. package/frontend/dist/assets/html-er6LXl7Q.js +7 -0
  167. package/frontend/dist/assets/htmlMode-BY7CWp3G.js +7 -0
  168. package/frontend/dist/assets/index-BmPb0Wl1.css +1 -0
  169. package/frontend/dist/assets/{index-CRhUXLfj.js → index-C6JmYBh3.js} +1 -1
  170. package/frontend/dist/assets/{index-CZ4PAGPA.js → index-C7QaGdFu.js} +2 -2
  171. package/frontend/dist/assets/{index-CaO8S0F7.js → index-CuoDBJ4_.js} +1 -1
  172. package/frontend/dist/assets/index-LxjrLxfp.js +1 -0
  173. package/frontend/dist/assets/ini-zR-_X5iG.js +7 -0
  174. package/frontend/dist/assets/java-CSTjsyoZ.js +7 -0
  175. package/frontend/dist/assets/javascript-R0QZ7Rw2.js +7 -0
  176. package/frontend/dist/assets/jsonMode-dh6Js0Qv.js +7 -0
  177. package/frontend/dist/assets/{jszip.min-CP_BBUld.js → jszip.min-D7W3wEX7.js} +1 -1
  178. package/frontend/dist/assets/julia-DioMOKVu.js +7 -0
  179. package/frontend/dist/assets/kotlin-Dsb0PKmW.js +7 -0
  180. package/frontend/dist/assets/less-CZYLoAVD.js +7 -0
  181. package/frontend/dist/assets/lexon-d5JUiwNk.js +7 -0
  182. package/frontend/dist/assets/liquid-ggFR895M.js +7 -0
  183. package/frontend/dist/assets/lua-1Al72GG8.js +7 -0
  184. package/frontend/dist/assets/m3-hx1xCPC3.js +7 -0
  185. package/frontend/dist/assets/markdown-DPGrH1xZ.js +7 -0
  186. package/frontend/dist/assets/mdx-B4WBy0Yh.js +7 -0
  187. package/frontend/dist/assets/mips-CYbZjkIm.js +7 -0
  188. package/frontend/dist/assets/msdax-DAioKM5A.js +7 -0
  189. package/frontend/dist/assets/mysql-7e9GUebS.js +7 -0
  190. package/frontend/dist/assets/objective-c-BGf8QNjz.js +7 -0
  191. package/frontend/dist/assets/pascal-hEDRz3un.js +7 -0
  192. package/frontend/dist/assets/pascaligo-gqEhN6pG.js +7 -0
  193. package/frontend/dist/assets/perl-CN8Ht9Vk.js +7 -0
  194. package/frontend/dist/assets/pgsql-CRCqHQBx.js +7 -0
  195. package/frontend/dist/assets/php-DTZrlAwe.js +7 -0
  196. package/frontend/dist/assets/pla-CRmh4UcC.js +7 -0
  197. package/frontend/dist/assets/postiats-Car2G7g8.js +7 -0
  198. package/frontend/dist/assets/powerquery-BJKl8V3o.js +7 -0
  199. package/frontend/dist/assets/powershell-Du7a_J7r.js +7 -0
  200. package/frontend/dist/assets/protobuf-ChneWI0H.js +7 -0
  201. package/frontend/dist/assets/pug-BH6LSJaf.js +7 -0
  202. package/frontend/dist/assets/python-AIGmVleM.js +7 -0
  203. package/frontend/dist/assets/qsharp-CU-Hxpxi.js +7 -0
  204. package/frontend/dist/assets/r-Bw-W15zh.js +7 -0
  205. package/frontend/dist/assets/razor-BGAZW957.js +7 -0
  206. package/frontend/dist/assets/redis-bY-X9-ol.js +7 -0
  207. package/frontend/dist/assets/redshift-CMu3ubbS.js +7 -0
  208. package/frontend/dist/assets/restructuredtext-KNkiWGNN.js +7 -0
  209. package/frontend/dist/assets/ruby-dQWMhU86.js +7 -0
  210. package/frontend/dist/assets/rust-BAcHhnEU.js +7 -0
  211. package/frontend/dist/assets/sb-Bidr5w2z.js +7 -0
  212. package/frontend/dist/assets/scala-imTtxsGY.js +7 -0
  213. package/frontend/dist/assets/scheme-BY-WHKiB.js +7 -0
  214. package/frontend/dist/assets/scss-NDoRP52C.js +7 -0
  215. package/frontend/dist/assets/{select-Cf6Q2O8Z.js → select-B9gOzVx5.js} +1 -1
  216. package/frontend/dist/assets/shell-DrIjotnh.js +7 -0
  217. package/frontend/dist/assets/solidity-DTahNycF.js +7 -0
  218. package/frontend/dist/assets/sophia-DtyrjGkZ.js +7 -0
  219. package/frontend/dist/assets/sparql-CFuS5E3z.js +7 -0
  220. package/frontend/dist/assets/sql-BRxcnbRv.js +7 -0
  221. package/frontend/dist/assets/st-Dz4uh7MK.js +7 -0
  222. package/frontend/dist/assets/swift-Digsrw1G.js +11 -0
  223. package/frontend/dist/assets/systemverilog-7TDrkMau.js +7 -0
  224. package/frontend/dist/assets/tcl-BtaFcnDi.js +7 -0
  225. package/frontend/dist/assets/tsMode-UrEEwBkN.js +7 -0
  226. package/frontend/dist/assets/twig-Deid_oBs.js +7 -0
  227. package/frontend/dist/assets/typescript-BTfMCp5C.js +7 -0
  228. package/frontend/dist/assets/typespec-zUaxhbG8.js +7 -0
  229. package/frontend/dist/assets/{user-B4YUPhU8.js → user-BG-Xqf8M.js} +1 -1
  230. package/frontend/dist/assets/vb-DK0rKJzo.js +7 -0
  231. package/frontend/dist/assets/wgsl-B8fNVlOQ.js +7 -0
  232. package/frontend/dist/assets/xml-BCL5DPdB.js +7 -0
  233. package/frontend/dist/assets/yaml-B__nW1c2.js +7 -0
  234. package/frontend/dist/index.html +2 -2
  235. package/package.json +2 -1
  236. package/frontend/dist/assets/index-BkQ6KI1l.css +0 -1
@@ -0,0 +1,838 @@
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.typeAnnot);
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.typeAnnot);
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
+ scalarType = this.RULE('scalarType', () => {
301
+ this.CONSUME(t.Identifier); // int / float / bool / string / prompt / any / etc.
302
+ this.OPTION(() => this.SUBRULE(this.typeConstraint));
303
+ });
304
+ enumType = this.RULE('enumType', () => {
305
+ this.CONSUME(t.KwEnum);
306
+ this.CONSUME(t.Colon);
307
+ this.CONSUME(t.Identifier); // first variant
308
+ this.MANY(() => {
309
+ this.CONSUME(t.Pipe);
310
+ this.CONSUME2(t.Identifier);
311
+ });
312
+ });
313
+ arrayType = this.RULE('arrayType', () => {
314
+ this.CONSUME(t.KwArray);
315
+ this.CONSUME(t.LAngle);
316
+ this.SUBRULE(this.typeAnnot);
317
+ this.CONSUME(t.RAngle);
318
+ this.OPTION(() => this.SUBRULE(this.namedConstraint));
319
+ });
320
+ objectType = this.RULE('objectType', () => {
321
+ this.CONSUME(t.KwObject);
322
+ this.CONSUME(t.LCurly);
323
+ this.SUBRULE(this.objectTypeField);
324
+ this.MANY(() => {
325
+ this.CONSUME(t.Comma);
326
+ this.SUBRULE2(this.objectTypeField);
327
+ });
328
+ this.OPTION(() => this.CONSUME2(t.Comma));
329
+ this.CONSUME(t.RCurly);
330
+ });
331
+ objectTypeField = this.RULE('objectTypeField', () => {
332
+ this.CONSUME(t.Identifier);
333
+ this.CONSUME(t.Colon);
334
+ this.SUBRULE(this.typeAnnot);
335
+ });
336
+ typeConstraint = this.RULE('typeConstraint', () => {
337
+ this.OR([
338
+ {
339
+ GATE: () => this.isRangeConstraint(),
340
+ ALT: () => this.SUBRULE(this.rangeConstraint),
341
+ },
342
+ { ALT: () => this.SUBRULE(this.namedConstraint) },
343
+ ]);
344
+ });
345
+ /** Range constraint starts with a numeric literal; named with identifier. */
346
+ isRangeConstraint() {
347
+ const t1 = this.LA(1).tokenType;
348
+ return t1 === t.IntLit || t1 === t.FloatLit;
349
+ }
350
+ rangeConstraint = this.RULE('rangeConstraint', () => {
351
+ this.SUBRULE(this.numberLit);
352
+ this.CONSUME(t.Dash);
353
+ this.SUBRULE2(this.numberLit);
354
+ });
355
+ namedConstraint = this.RULE('namedConstraint', () => {
356
+ this.CONSUME(t.Identifier); // "maxLen", "minLen", "min", "max", "matches"
357
+ this.CONSUME(t.Equals);
358
+ this.OR([
359
+ { ALT: () => this.SUBRULE(this.numberLit) },
360
+ { ALT: () => this.CONSUME(t.StringLit) },
361
+ ]);
362
+ });
363
+ numberLit = this.RULE('numberLit', () => {
364
+ this.OR([
365
+ { ALT: () => this.CONSUME(t.IntLit) },
366
+ { ALT: () => this.CONSUME(t.FloatLit) },
367
+ ]);
368
+ });
369
+ // ─── Block / Statements ───────────────────────────────────────────────
370
+ block = this.RULE('block', () => {
371
+ this.CONSUME(t.LCurly);
372
+ this.MANY(() => this.SUBRULE(this.stmt));
373
+ this.CONSUME(t.RCurly);
374
+ });
375
+ stmt = this.RULE('stmt', () => {
376
+ this.OR([
377
+ { ALT: () => this.SUBRULE(this.letDecl) },
378
+ { ALT: () => this.SUBRULE(this.ifStmt) },
379
+ { ALT: () => this.SUBRULE(this.forStmt) },
380
+ { ALT: () => this.SUBRULE(this.whileStmt) },
381
+ { ALT: () => this.SUBRULE(this.tryStmt) },
382
+ { ALT: () => this.SUBRULE(this.breakStmt) },
383
+ { ALT: () => this.SUBRULE(this.continueStmt) },
384
+ { ALT: () => this.SUBRULE(this.returnStmt) },
385
+ // Assignment vs expression-statement: both start with the same
386
+ // primary tokens (Identifier mostly). Distinguish by lookahead.
387
+ {
388
+ GATE: () => this.isAssignment(),
389
+ ALT: () => this.SUBRULE(this.assignment),
390
+ },
391
+ { ALT: () => this.SUBRULE(this.exprStmt) },
392
+ ]);
393
+ // Optional explicit semicolon terminator. Newlines are also treated
394
+ // as terminators implicitly by chevrotain (which skips whitespace),
395
+ // so most programs write one statement per line.
396
+ this.OPTION(() => this.CONSUME(t.Semicolon));
397
+ });
398
+ /**
399
+ * An assignment starts with an l-value (Identifier with optional . [ suffixes)
400
+ * followed by an assignment operator. We scan ahead, skipping balanced
401
+ * brackets, looking for one of the assignment ops at the same paren depth.
402
+ */
403
+ isAssignment() {
404
+ if (this.LA(1).tokenType !== t.Identifier)
405
+ return false;
406
+ let i = 2;
407
+ let depth = 0;
408
+ while (true) {
409
+ const tok = this.LA(i).tokenType;
410
+ if (tok === EOF)
411
+ return false;
412
+ if (depth === 0) {
413
+ if (tok === t.Equals ||
414
+ tok === t.PlusEq ||
415
+ tok === t.MinusEq ||
416
+ tok === t.StarEq ||
417
+ tok === t.SlashEq ||
418
+ tok === t.PercentEq) {
419
+ return true;
420
+ }
421
+ // boundaries that disqualify l-value parsing
422
+ if (tok === t.Semicolon ||
423
+ tok === t.RCurly ||
424
+ tok === t.LCurly ||
425
+ tok === t.Comma ||
426
+ tok === t.RParen) {
427
+ return false;
428
+ }
429
+ // valid l-value continuations
430
+ if (tok === t.Dot || tok === t.Identifier) {
431
+ i++;
432
+ continue;
433
+ }
434
+ if (tok === t.LBracket || tok === t.LParen) {
435
+ depth++;
436
+ i++;
437
+ continue;
438
+ }
439
+ // Any other token at depth 0 means this isn't a plain l-value chain
440
+ return false;
441
+ }
442
+ else {
443
+ // inside brackets: skip until balanced
444
+ if (tok === t.LBracket || tok === t.LParen)
445
+ depth++;
446
+ else if (tok === t.RBracket || tok === t.RParen)
447
+ depth--;
448
+ i++;
449
+ if (depth < 0)
450
+ return false;
451
+ }
452
+ }
453
+ }
454
+ letDecl = this.RULE('letDecl', () => {
455
+ this.CONSUME(t.Let);
456
+ this.SUBRULE(this.letTarget);
457
+ this.OPTION(() => {
458
+ this.CONSUME(t.Colon);
459
+ this.SUBRULE(this.typeAnnot);
460
+ });
461
+ this.OPTION2(() => {
462
+ this.CONSUME(t.Equals);
463
+ this.SUBRULE(this.expr);
464
+ });
465
+ });
466
+ letTarget = this.RULE('letTarget', () => {
467
+ this.OR([
468
+ { ALT: () => this.CONSUME(t.Identifier) },
469
+ { ALT: () => this.SUBRULE(this.objectDestruct) },
470
+ { ALT: () => this.SUBRULE(this.arrayDestruct) },
471
+ ]);
472
+ });
473
+ objectDestruct = this.RULE('objectDestruct', () => {
474
+ this.CONSUME(t.LCurly);
475
+ this.SUBRULE(this.destructField);
476
+ this.MANY(() => {
477
+ this.CONSUME(t.Comma);
478
+ this.SUBRULE2(this.destructField);
479
+ });
480
+ this.OPTION(() => this.CONSUME2(t.Comma));
481
+ this.CONSUME(t.RCurly);
482
+ });
483
+ destructField = this.RULE('destructField', () => {
484
+ this.CONSUME(t.Identifier);
485
+ this.OPTION(() => {
486
+ this.CONSUME(t.Colon);
487
+ this.CONSUME2(t.Identifier);
488
+ });
489
+ });
490
+ arrayDestruct = this.RULE('arrayDestruct', () => {
491
+ this.CONSUME(t.LBracket);
492
+ this.CONSUME(t.Identifier);
493
+ this.MANY(() => {
494
+ this.CONSUME(t.Comma);
495
+ this.CONSUME2(t.Identifier);
496
+ });
497
+ this.OPTION(() => this.CONSUME2(t.Comma));
498
+ this.CONSUME(t.RBracket);
499
+ });
500
+ assignment = this.RULE('assignment', () => {
501
+ this.SUBRULE(this.lvalue);
502
+ this.SUBRULE(this.assignOp);
503
+ this.SUBRULE(this.expr);
504
+ });
505
+ lvalue = this.RULE('lvalue', () => {
506
+ this.CONSUME(t.Identifier);
507
+ this.MANY(() => this.SUBRULE(this.lvalueSuffix));
508
+ });
509
+ lvalueSuffix = this.RULE('lvalueSuffix', () => {
510
+ this.OR([
511
+ {
512
+ ALT: () => {
513
+ this.CONSUME(t.Dot);
514
+ this.CONSUME(t.Identifier);
515
+ },
516
+ },
517
+ {
518
+ ALT: () => {
519
+ this.CONSUME(t.LBracket);
520
+ this.SUBRULE(this.expr);
521
+ this.CONSUME(t.RBracket);
522
+ },
523
+ },
524
+ ]);
525
+ });
526
+ assignOp = this.RULE('assignOp', () => {
527
+ this.OR([
528
+ { ALT: () => this.CONSUME(t.Equals) },
529
+ { ALT: () => this.CONSUME(t.PlusEq) },
530
+ { ALT: () => this.CONSUME(t.MinusEq) },
531
+ { ALT: () => this.CONSUME(t.StarEq) },
532
+ { ALT: () => this.CONSUME(t.SlashEq) },
533
+ { ALT: () => this.CONSUME(t.PercentEq) },
534
+ ]);
535
+ });
536
+ ifStmt = this.RULE('ifStmt', () => {
537
+ this.CONSUME(t.If);
538
+ this.CONSUME(t.LParen);
539
+ this.SUBRULE(this.expr);
540
+ this.CONSUME(t.RParen);
541
+ this.SUBRULE(this.block);
542
+ this.MANY({
543
+ GATE: () => this.LA(1).tokenType === t.Else && this.LA(2).tokenType === t.If,
544
+ DEF: () => {
545
+ this.CONSUME(t.Else);
546
+ this.CONSUME2(t.If);
547
+ this.CONSUME2(t.LParen);
548
+ this.SUBRULE2(this.expr);
549
+ this.CONSUME2(t.RParen);
550
+ this.SUBRULE2(this.block);
551
+ },
552
+ });
553
+ this.OPTION(() => {
554
+ this.CONSUME3(t.Else);
555
+ this.SUBRULE3(this.block);
556
+ });
557
+ });
558
+ forStmt = this.RULE('forStmt', () => {
559
+ this.CONSUME(t.For);
560
+ this.CONSUME(t.Identifier);
561
+ this.CONSUME(t.In);
562
+ this.SUBRULE(this.expr);
563
+ this.SUBRULE(this.block);
564
+ });
565
+ whileStmt = this.RULE('whileStmt', () => {
566
+ this.CONSUME(t.While);
567
+ this.CONSUME(t.LParen);
568
+ this.SUBRULE(this.expr);
569
+ this.CONSUME(t.RParen);
570
+ this.SUBRULE(this.block);
571
+ });
572
+ tryStmt = this.RULE('tryStmt', () => {
573
+ this.CONSUME(t.Try);
574
+ this.SUBRULE(this.block);
575
+ this.AT_LEAST_ONE(() => this.SUBRULE(this.catchClause));
576
+ });
577
+ catchClause = this.RULE('catchClause', () => {
578
+ this.CONSUME(t.Catch);
579
+ this.CONSUME(t.Identifier); // exception type name
580
+ this.OPTION(() => {
581
+ this.CONSUME(t.As);
582
+ this.CONSUME2(t.Identifier); // bound variable
583
+ });
584
+ this.SUBRULE(this.block);
585
+ });
586
+ breakStmt = this.RULE('breakStmt', () => {
587
+ this.CONSUME(t.Break);
588
+ });
589
+ continueStmt = this.RULE('continueStmt', () => {
590
+ this.CONSUME(t.Continue);
591
+ });
592
+ returnStmt = this.RULE('returnStmt', () => {
593
+ this.CONSUME(t.Return);
594
+ this.OPTION({
595
+ // Avoid eating tokens that begin the next statement.
596
+ GATE: () => this.canStartExpression(),
597
+ DEF: () => this.SUBRULE(this.expr),
598
+ });
599
+ });
600
+ /** Heuristic: does the current lookahead token start an expression? */
601
+ canStartExpression() {
602
+ const tok = this.LA(1).tokenType;
603
+ return (tok === t.IntLit ||
604
+ tok === t.FloatLit ||
605
+ tok === t.StringLit ||
606
+ tok === t.True ||
607
+ tok === t.False ||
608
+ tok === t.Null ||
609
+ tok === t.Identifier ||
610
+ tok === t.LParen ||
611
+ tok === t.LBracket ||
612
+ tok === t.LCurly ||
613
+ tok === t.Dash ||
614
+ tok === t.Bang);
615
+ }
616
+ exprStmt = this.RULE('exprStmt', () => {
617
+ this.SUBRULE(this.expr);
618
+ });
619
+ // ─── Expressions (precedence from LOW to HIGH) ────────────────────────
620
+ expr = this.RULE('expr', () => {
621
+ this.SUBRULE(this.ternaryExpr);
622
+ });
623
+ ternaryExpr = this.RULE('ternaryExpr', () => {
624
+ this.SUBRULE(this.logicalOrExpr);
625
+ this.OPTION(() => {
626
+ this.CONSUME(t.Question);
627
+ this.SUBRULE(this.expr);
628
+ this.CONSUME(t.Colon);
629
+ this.SUBRULE2(this.expr);
630
+ });
631
+ });
632
+ logicalOrExpr = this.RULE('logicalOrExpr', () => {
633
+ this.SUBRULE(this.logicalAndExpr);
634
+ this.MANY(() => {
635
+ this.CONSUME(t.OrOr);
636
+ this.SUBRULE2(this.logicalAndExpr);
637
+ });
638
+ });
639
+ logicalAndExpr = this.RULE('logicalAndExpr', () => {
640
+ this.SUBRULE(this.equalityExpr);
641
+ this.MANY(() => {
642
+ this.CONSUME(t.AndAnd);
643
+ this.SUBRULE2(this.equalityExpr);
644
+ });
645
+ });
646
+ equalityExpr = this.RULE('equalityExpr', () => {
647
+ this.SUBRULE(this.comparisonExpr);
648
+ this.MANY(() => {
649
+ this.OR([
650
+ { ALT: () => this.CONSUME(t.EqEq) },
651
+ { ALT: () => this.CONSUME(t.NotEq) },
652
+ ]);
653
+ this.SUBRULE2(this.comparisonExpr);
654
+ });
655
+ });
656
+ comparisonExpr = this.RULE('comparisonExpr', () => {
657
+ this.SUBRULE(this.additiveExpr);
658
+ this.MANY(() => {
659
+ this.OR([
660
+ { ALT: () => this.CONSUME(t.LAngle) },
661
+ { ALT: () => this.CONSUME(t.LtEq) },
662
+ { ALT: () => this.CONSUME(t.RAngle) },
663
+ { ALT: () => this.CONSUME(t.GtEq) },
664
+ ]);
665
+ this.SUBRULE2(this.additiveExpr);
666
+ });
667
+ });
668
+ additiveExpr = this.RULE('additiveExpr', () => {
669
+ this.SUBRULE(this.multiplicativeExpr);
670
+ this.MANY(() => {
671
+ this.OR([
672
+ { ALT: () => this.CONSUME(t.Plus) },
673
+ { ALT: () => this.CONSUME(t.Dash) },
674
+ ]);
675
+ this.SUBRULE2(this.multiplicativeExpr);
676
+ });
677
+ });
678
+ multiplicativeExpr = this.RULE('multiplicativeExpr', () => {
679
+ this.SUBRULE(this.unaryExpr);
680
+ this.MANY(() => {
681
+ this.OR([
682
+ { ALT: () => this.CONSUME(t.Star) },
683
+ { ALT: () => this.CONSUME(t.Slash) },
684
+ { ALT: () => this.CONSUME(t.Percent) },
685
+ ]);
686
+ this.SUBRULE2(this.unaryExpr);
687
+ });
688
+ });
689
+ unaryExpr = this.RULE('unaryExpr', () => {
690
+ this.OPTION(() => {
691
+ this.OR([
692
+ { ALT: () => this.CONSUME(t.Dash) },
693
+ { ALT: () => this.CONSUME(t.Bang) },
694
+ ]);
695
+ });
696
+ this.SUBRULE(this.postfixExpr);
697
+ });
698
+ postfixExpr = this.RULE('postfixExpr', () => {
699
+ this.SUBRULE(this.primaryExpr);
700
+ this.MANY(() => this.SUBRULE(this.postfixSuffix));
701
+ });
702
+ postfixSuffix = this.RULE('postfixSuffix', () => {
703
+ this.OR([
704
+ {
705
+ ALT: () => {
706
+ this.CONSUME(t.Dot);
707
+ this.CONSUME(t.Identifier);
708
+ },
709
+ },
710
+ {
711
+ ALT: () => {
712
+ this.CONSUME(t.LBracket);
713
+ this.SUBRULE(this.expr);
714
+ this.CONSUME(t.RBracket);
715
+ },
716
+ },
717
+ {
718
+ ALT: () => {
719
+ this.CONSUME(t.LParen);
720
+ this.OPTION(() => this.SUBRULE(this.argList));
721
+ this.CONSUME(t.RParen);
722
+ },
723
+ },
724
+ ]);
725
+ });
726
+ argList = this.RULE('argList', () => {
727
+ this.SUBRULE(this.expr);
728
+ this.MANY(() => {
729
+ this.CONSUME(t.Comma);
730
+ this.SUBRULE2(this.expr);
731
+ });
732
+ this.OPTION(() => this.CONSUME2(t.Comma));
733
+ });
734
+ primaryExpr = this.RULE('primaryExpr', () => {
735
+ this.OR([
736
+ { ALT: () => this.SUBRULE(this.literal) },
737
+ { ALT: () => this.CONSUME(t.Identifier) },
738
+ { ALT: () => this.SUBRULE(this.arrayLit) },
739
+ { ALT: () => this.SUBRULE(this.objectLit) },
740
+ {
741
+ ALT: () => {
742
+ this.CONSUME(t.LParen);
743
+ this.SUBRULE(this.expr);
744
+ this.CONSUME(t.RParen);
745
+ },
746
+ },
747
+ ]);
748
+ });
749
+ literal = this.RULE('literal', () => {
750
+ this.OR([
751
+ { ALT: () => this.CONSUME(t.IntLit) },
752
+ { ALT: () => this.CONSUME(t.FloatLit) },
753
+ { ALT: () => this.CONSUME(t.StringLit) },
754
+ { ALT: () => this.CONSUME(t.True) },
755
+ { ALT: () => this.CONSUME(t.False) },
756
+ { ALT: () => this.CONSUME(t.Null) },
757
+ ]);
758
+ });
759
+ arrayLit = this.RULE('arrayLit', () => {
760
+ this.CONSUME(t.LBracket);
761
+ this.OPTION(() => {
762
+ this.SUBRULE(this.expr);
763
+ this.MANY(() => {
764
+ this.CONSUME(t.Comma);
765
+ this.SUBRULE2(this.expr);
766
+ });
767
+ this.OPTION2(() => this.CONSUME2(t.Comma));
768
+ });
769
+ this.CONSUME(t.RBracket);
770
+ });
771
+ objectLit = this.RULE('objectLit', () => {
772
+ this.CONSUME(t.LCurly);
773
+ this.OPTION(() => {
774
+ this.SUBRULE(this.objectLitField);
775
+ this.MANY(() => {
776
+ this.CONSUME(t.Comma);
777
+ this.SUBRULE2(this.objectLitField);
778
+ });
779
+ this.OPTION2(() => this.CONSUME2(t.Comma));
780
+ });
781
+ this.CONSUME(t.RCurly);
782
+ });
783
+ objectLitField = this.RULE('objectLitField', () => {
784
+ this.OR([
785
+ {
786
+ // `"key": value`
787
+ GATE: () => this.LA(1).tokenType === t.StringLit,
788
+ ALT: () => {
789
+ this.CONSUME(t.StringLit);
790
+ this.CONSUME(t.Colon);
791
+ this.SUBRULE(this.expr);
792
+ },
793
+ },
794
+ {
795
+ // `key: value` or shorthand `key`
796
+ ALT: () => {
797
+ this.CONSUME(t.Identifier);
798
+ this.OPTION(() => {
799
+ this.CONSUME2(t.Colon);
800
+ this.SUBRULE2(this.expr);
801
+ });
802
+ },
803
+ },
804
+ ]);
805
+ });
806
+ }
807
+ // Singleton parser instance (chevrotain best practice — performSelfAnalysis is expensive)
808
+ export const trainParser = new TrainParser();
809
+ /**
810
+ * Parse train source text. Returns CST + any errors (does not throw on parse errors,
811
+ * to allow IDE-style error reporting).
812
+ */
813
+ export function parse(source) {
814
+ const lexResult = t.trainLexer.tokenize(source);
815
+ trainParser.input = lexResult.tokens;
816
+ const cst = trainParser.program();
817
+ return {
818
+ cst,
819
+ lexErrors: lexResult.errors,
820
+ parseErrors: trainParser.errors,
821
+ };
822
+ }
823
+ /**
824
+ * Parse a single expression. Used internally by the template-string
825
+ * interpolation builder. The source must be exactly an expression
826
+ * (no surrounding statement/punctuation).
827
+ */
828
+ export function parseExpression(source) {
829
+ const lexResult = t.trainLexer.tokenize(source);
830
+ trainParser.input = lexResult.tokens;
831
+ const cst = trainParser.exprEntry();
832
+ return {
833
+ cst,
834
+ lexErrors: lexResult.errors,
835
+ parseErrors: trainParser.errors,
836
+ };
837
+ }
838
+ //# sourceMappingURL=parser.js.map