solve-engine 1.0.0-beta.0 → 1.0.0-beta.2

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 (253) hide show
  1. package/dist/BytecodeBuilder-3egMyuDi.d.cts +274 -0
  2. package/dist/BytecodeBuilder-3egMyuDi.d.ts +274 -0
  3. package/dist/Configuration-fVpd-HC-.d.cts +228 -0
  4. package/dist/Configuration-fVpd-HC-.d.ts +228 -0
  5. package/dist/EngineError-DvPSnhZi.d.cts +304 -0
  6. package/dist/EngineError-DvPSnhZi.d.ts +304 -0
  7. package/dist/Lexer-BJdhlnej.d.cts +531 -0
  8. package/dist/Lexer-D9l4Yrk2.d.ts +531 -0
  9. package/dist/NormalizerRule-BrVoVjmP.d.cts +163 -0
  10. package/dist/NormalizerRule-CEjf1FyD.d.ts +163 -0
  11. package/dist/PackageRegistry-D-Tv_7ca.d.cts +2572 -0
  12. package/dist/PackageRegistry-DaH4aIKP.d.ts +2572 -0
  13. package/dist/Parselet-CK8cQu2a.d.cts +299 -0
  14. package/dist/Parselet-ConOIdRO.d.ts +299 -0
  15. package/dist/ScopeManager-B5k0nk05.d.ts +559 -0
  16. package/dist/ScopeManager-CKfQtl7l.d.cts +559 -0
  17. package/dist/Token-0jpvUdPY.d.cts +245 -0
  18. package/dist/Token-0jpvUdPY.d.ts +245 -0
  19. package/dist/VMCheckpoints-BmDwIXgK.d.ts +171 -0
  20. package/dist/VMCheckpoints-CqFuLwrT.d.cts +171 -0
  21. package/dist/Value-KtAQNHur.d.cts +295 -0
  22. package/dist/Value-KtAQNHur.d.ts +295 -0
  23. package/dist/chunk-2RWAXT6O.js +3 -0
  24. package/dist/chunk-2RWAXT6O.js.map +1 -0
  25. package/dist/chunk-34RRD7PC.js +1492 -0
  26. package/dist/chunk-34RRD7PC.js.map +1 -0
  27. package/dist/chunk-3PPFLFH4.js +5097 -0
  28. package/dist/chunk-3PPFLFH4.js.map +1 -0
  29. package/dist/chunk-3VGDNEE3.js +84 -0
  30. package/dist/chunk-3VGDNEE3.js.map +1 -0
  31. package/dist/chunk-3YNVWKR2.cjs +370 -0
  32. package/dist/chunk-3YNVWKR2.cjs.map +1 -0
  33. package/dist/chunk-47LRVGOT.cjs +316 -0
  34. package/dist/chunk-47LRVGOT.cjs.map +1 -0
  35. package/dist/chunk-4MG4XKO2.js +1644 -0
  36. package/dist/chunk-4MG4XKO2.js.map +1 -0
  37. package/dist/chunk-4QADQTWS.js +2392 -0
  38. package/dist/chunk-4QADQTWS.js.map +1 -0
  39. package/dist/chunk-53B6KDDJ.cjs +1651 -0
  40. package/dist/chunk-53B6KDDJ.cjs.map +1 -0
  41. package/dist/chunk-5X2PTP6F.cjs +104 -0
  42. package/dist/chunk-5X2PTP6F.cjs.map +1 -0
  43. package/dist/chunk-5YEMOYSE.js +264 -0
  44. package/dist/chunk-5YEMOYSE.js.map +1 -0
  45. package/dist/chunk-64W6GLLZ.js +481 -0
  46. package/dist/chunk-64W6GLLZ.js.map +1 -0
  47. package/dist/chunk-6BKTCEUP.cjs +233 -0
  48. package/dist/chunk-6BKTCEUP.cjs.map +1 -0
  49. package/dist/chunk-6NTVRDQV.cjs +1642 -0
  50. package/dist/chunk-6NTVRDQV.cjs.map +1 -0
  51. package/dist/chunk-6RDSQURE.js +290 -0
  52. package/dist/chunk-6RDSQURE.js.map +1 -0
  53. package/dist/chunk-75JP4BZX.js +93 -0
  54. package/dist/chunk-75JP4BZX.js.map +1 -0
  55. package/dist/chunk-B7LXJ6LC.cjs +36 -0
  56. package/dist/chunk-B7LXJ6LC.cjs.map +1 -0
  57. package/dist/chunk-BVAR5J2F.js +257 -0
  58. package/dist/chunk-BVAR5J2F.js.map +1 -0
  59. package/dist/chunk-C4XZV6E7.cjs +269 -0
  60. package/dist/chunk-C4XZV6E7.cjs.map +1 -0
  61. package/dist/chunk-CCJPSHGI.cjs +40 -0
  62. package/dist/chunk-CCJPSHGI.cjs.map +1 -0
  63. package/dist/chunk-CLL7RUQV.cjs +316 -0
  64. package/dist/chunk-CLL7RUQV.cjs.map +1 -0
  65. package/dist/chunk-DM3LMRBC.js +329 -0
  66. package/dist/chunk-DM3LMRBC.js.map +1 -0
  67. package/dist/chunk-DUEZFTK2.js +38 -0
  68. package/dist/chunk-DUEZFTK2.js.map +1 -0
  69. package/dist/chunk-EBSPLUW4.cjs +489 -0
  70. package/dist/chunk-EBSPLUW4.cjs.map +1 -0
  71. package/dist/chunk-EHAHVROS.cjs +261 -0
  72. package/dist/chunk-EHAHVROS.cjs.map +1 -0
  73. package/dist/chunk-EIGTWK5N.js +167 -0
  74. package/dist/chunk-EIGTWK5N.js.map +1 -0
  75. package/dist/chunk-EPOXXJBK.js +96 -0
  76. package/dist/chunk-EPOXXJBK.js.map +1 -0
  77. package/dist/chunk-FEAIOR7N.cjs +91 -0
  78. package/dist/chunk-FEAIOR7N.cjs.map +1 -0
  79. package/dist/chunk-G535KJEG.js +312 -0
  80. package/dist/chunk-G535KJEG.js.map +1 -0
  81. package/dist/chunk-GCM5JHMX.js +88 -0
  82. package/dist/chunk-GCM5JHMX.js.map +1 -0
  83. package/dist/chunk-GOLDJNMZ.js +368 -0
  84. package/dist/chunk-GOLDJNMZ.js.map +1 -0
  85. package/dist/chunk-GW32KPCU.cjs +360 -0
  86. package/dist/chunk-GW32KPCU.cjs.map +1 -0
  87. package/dist/chunk-HTXVVJRA.cjs +1549 -0
  88. package/dist/chunk-HTXVVJRA.cjs.map +1 -0
  89. package/dist/chunk-HWSZJQCI.js +311 -0
  90. package/dist/chunk-HWSZJQCI.js.map +1 -0
  91. package/dist/chunk-IF532O7C.js +101 -0
  92. package/dist/chunk-IF532O7C.js.map +1 -0
  93. package/dist/chunk-J73SJHR3.cjs +2415 -0
  94. package/dist/chunk-J73SJHR3.cjs.map +1 -0
  95. package/dist/chunk-JBSYC7BB.cjs +7473 -0
  96. package/dist/chunk-JBSYC7BB.cjs.map +1 -0
  97. package/dist/chunk-KVILKGMS.js +228 -0
  98. package/dist/chunk-KVILKGMS.js.map +1 -0
  99. package/dist/chunk-LIPPNDBE.js +258 -0
  100. package/dist/chunk-LIPPNDBE.js.map +1 -0
  101. package/dist/chunk-LR7YASZF.cjs +172 -0
  102. package/dist/chunk-LR7YASZF.cjs.map +1 -0
  103. package/dist/chunk-M4N5GA5Z.cjs +309 -0
  104. package/dist/chunk-M4N5GA5Z.cjs.map +1 -0
  105. package/dist/chunk-M5LX5AOO.js +7459 -0
  106. package/dist/chunk-M5LX5AOO.js.map +1 -0
  107. package/dist/chunk-MZOVP3WI.cjs +96 -0
  108. package/dist/chunk-MZOVP3WI.cjs.map +1 -0
  109. package/dist/chunk-N5YFR4UP.cjs +10 -0
  110. package/dist/chunk-N5YFR4UP.cjs.map +1 -0
  111. package/dist/chunk-NGBBNL4K.cjs +4 -0
  112. package/dist/chunk-NGBBNL4K.cjs.map +1 -0
  113. package/dist/chunk-NH2O2AUR.js +146 -0
  114. package/dist/chunk-NH2O2AUR.js.map +1 -0
  115. package/dist/chunk-NLNDMWZC.js +31 -0
  116. package/dist/chunk-NLNDMWZC.js.map +1 -0
  117. package/dist/chunk-NMCRQP3Z.cjs +778 -0
  118. package/dist/chunk-NMCRQP3Z.cjs.map +1 -0
  119. package/dist/chunk-NMD5VRN4.cjs +1327 -0
  120. package/dist/chunk-NMD5VRN4.cjs.map +1 -0
  121. package/dist/chunk-OC6LTXYS.cjs +286 -0
  122. package/dist/chunk-OC6LTXYS.cjs.map +1 -0
  123. package/dist/chunk-OT6OJY7C.cjs +114 -0
  124. package/dist/chunk-OT6OJY7C.cjs.map +1 -0
  125. package/dist/chunk-PFSDGGYL.js +8 -0
  126. package/dist/chunk-PFSDGGYL.js.map +1 -0
  127. package/dist/chunk-QNJ4ACRT.cjs +155 -0
  128. package/dist/chunk-QNJ4ACRT.cjs.map +1 -0
  129. package/dist/chunk-QWY3VEZN.js +1637 -0
  130. package/dist/chunk-QWY3VEZN.js.map +1 -0
  131. package/dist/chunk-RFYD5TJE.js +111 -0
  132. package/dist/chunk-RFYD5TJE.js.map +1 -0
  133. package/dist/chunk-RIN643A3.js +354 -0
  134. package/dist/chunk-RIN643A3.js.map +1 -0
  135. package/dist/chunk-RZCWSXTA.cjs +5122 -0
  136. package/dist/chunk-RZCWSXTA.cjs.map +1 -0
  137. package/dist/chunk-SDGRK7EP.js +774 -0
  138. package/dist/chunk-SDGRK7EP.js.map +1 -0
  139. package/dist/chunk-VEKIWQ3F.cjs +39 -0
  140. package/dist/chunk-VEKIWQ3F.cjs.map +1 -0
  141. package/dist/chunk-WQTTOGXC.cjs +99 -0
  142. package/dist/chunk-WQTTOGXC.cjs.map +1 -0
  143. package/dist/chunk-X6K3HUOY.cjs +86 -0
  144. package/dist/chunk-X6K3HUOY.cjs.map +1 -0
  145. package/dist/chunk-XJCMXB2E.cjs +333 -0
  146. package/dist/chunk-XJCMXB2E.cjs.map +1 -0
  147. package/dist/chunk-XVWCOTR6.js +1324 -0
  148. package/dist/chunk-XVWCOTR6.js.map +1 -0
  149. package/dist/chunk-YLJ4XMA6.js +33 -0
  150. package/dist/chunk-YLJ4XMA6.js.map +1 -0
  151. package/dist/chunk-Z2XP767T.cjs +35 -0
  152. package/dist/chunk-Z2XP767T.cjs.map +1 -0
  153. package/dist/chunk-Z4X2RWOF.js +37 -0
  154. package/dist/chunk-Z4X2RWOF.js.map +1 -0
  155. package/dist/constants.cjs +22 -0
  156. package/dist/constants.cjs.map +1 -0
  157. package/dist/constants.d.cts +12 -0
  158. package/dist/constants.d.ts +12 -0
  159. package/dist/constants.js +5 -0
  160. package/dist/constants.js.map +1 -0
  161. package/dist/engine.cjs +79 -0
  162. package/dist/engine.cjs.map +1 -0
  163. package/dist/engine.d.cts +587 -0
  164. package/dist/engine.d.ts +587 -0
  165. package/dist/engine.js +34 -0
  166. package/dist/engine.js.map +1 -0
  167. package/dist/errors.cjs +81 -0
  168. package/dist/errors.cjs.map +1 -0
  169. package/dist/errors.d.cts +95 -0
  170. package/dist/errors.d.ts +95 -0
  171. package/dist/errors.js +4 -0
  172. package/dist/errors.js.map +1 -0
  173. package/dist/format.cjs +171 -0
  174. package/dist/format.cjs.map +1 -0
  175. package/dist/format.d.cts +51 -0
  176. package/dist/format.d.ts +51 -0
  177. package/dist/format.js +168 -0
  178. package/dist/format.js.map +1 -0
  179. package/dist/index.cjs +97 -0
  180. package/dist/index.cjs.map +1 -0
  181. package/dist/index.d.cts +152 -0
  182. package/dist/index.d.ts +152 -0
  183. package/dist/index.js +75 -0
  184. package/dist/index.js.map +1 -0
  185. package/dist/language.cjs +308 -0
  186. package/dist/language.cjs.map +1 -0
  187. package/dist/language.d.cts +110 -0
  188. package/dist/language.d.ts +110 -0
  189. package/dist/language.js +287 -0
  190. package/dist/language.js.map +1 -0
  191. package/dist/lexer.cjs +64 -0
  192. package/dist/lexer.cjs.map +1 -0
  193. package/dist/lexer.d.cts +56 -0
  194. package/dist/lexer.d.ts +56 -0
  195. package/dist/lexer.js +11 -0
  196. package/dist/lexer.js.map +1 -0
  197. package/dist/normalizer.cjs +40 -0
  198. package/dist/normalizer.cjs.map +1 -0
  199. package/dist/normalizer.d.cts +364 -0
  200. package/dist/normalizer.d.ts +364 -0
  201. package/dist/normalizer.js +11 -0
  202. package/dist/normalizer.js.map +1 -0
  203. package/dist/packages.cjs +121 -0
  204. package/dist/packages.cjs.map +1 -0
  205. package/dist/packages.d.cts +691 -0
  206. package/dist/packages.d.ts +691 -0
  207. package/dist/packages.js +24 -0
  208. package/dist/packages.js.map +1 -0
  209. package/dist/parser.cjs +55 -0
  210. package/dist/parser.cjs.map +1 -0
  211. package/dist/parser.d.cts +46 -0
  212. package/dist/parser.d.ts +46 -0
  213. package/dist/parser.js +10 -0
  214. package/dist/parser.js.map +1 -0
  215. package/dist/pipeline-CrsRPmsv.d.ts +285 -0
  216. package/dist/pipeline-DPUQt7yL.d.cts +285 -0
  217. package/dist/resolvers.cjs +13 -0
  218. package/dist/resolvers.cjs.map +1 -0
  219. package/dist/resolvers.d.cts +111 -0
  220. package/dist/resolvers.d.ts +111 -0
  221. package/dist/resolvers.js +4 -0
  222. package/dist/resolvers.js.map +1 -0
  223. package/dist/services.cjs +21 -0
  224. package/dist/services.cjs.map +1 -0
  225. package/dist/services.d.cts +30 -0
  226. package/dist/services.d.ts +30 -0
  227. package/dist/services.js +4 -0
  228. package/dist/services.js.map +1 -0
  229. package/dist/uom.cjs +56 -0
  230. package/dist/uom.cjs.map +1 -0
  231. package/dist/uom.d.cts +224 -0
  232. package/dist/uom.d.ts +224 -0
  233. package/dist/uom.js +11 -0
  234. package/dist/uom.js.map +1 -0
  235. package/dist/utilities.cjs +32 -0
  236. package/dist/utilities.cjs.map +1 -0
  237. package/dist/utilities.d.cts +113 -0
  238. package/dist/utilities.d.ts +113 -0
  239. package/dist/utilities.js +7 -0
  240. package/dist/utilities.js.map +1 -0
  241. package/dist/variables.cjs +17 -0
  242. package/dist/variables.cjs.map +1 -0
  243. package/dist/variables.d.cts +87 -0
  244. package/dist/variables.d.ts +87 -0
  245. package/dist/variables.js +4 -0
  246. package/dist/variables.js.map +1 -0
  247. package/dist/vm.cjs +284 -0
  248. package/dist/vm.cjs.map +1 -0
  249. package/dist/vm.d.cts +68 -0
  250. package/dist/vm.d.ts +68 -0
  251. package/dist/vm.js +194 -0
  252. package/dist/vm.js.map +1 -0
  253. package/package.json +4 -4
@@ -0,0 +1,360 @@
1
+ 'use strict';
2
+
3
+ // src/lexer/Token.ts
4
+ var TokenTypes = {
5
+ NUMBER: "NUMBER",
6
+ BIGINT: "BIGINT",
7
+ STRING: "STRING",
8
+ IDENT: "IDENT",
9
+ PLUS: "PLUS",
10
+ MINUS: "MINUS",
11
+ STAR: "STAR",
12
+ SLASH: "SLASH",
13
+ CARET: "CARET",
14
+ PERCENT: "PERCENT",
15
+ LSHIFT: "LSHIFT",
16
+ RSHIFT: "RSHIFT",
17
+ URSHIFT: "URSHIFT",
18
+ LPAREN: "LPAREN",
19
+ RPAREN: "RPAREN",
20
+ LBRACKET: "LBRACKET",
21
+ RBRACKET: "RBRACKET",
22
+ LBRACE: "LBRACE",
23
+ RBRACE: "RBRACE",
24
+ COMMA: "COMMA",
25
+ DOT: "DOT",
26
+ COLON: "COLON",
27
+ SEMICOLON: "SEMICOLON",
28
+ EQUALS: "EQUALS",
29
+ DOLLAR: "DOLLAR",
30
+ POUND: "POUND",
31
+ EURO: "EURO",
32
+ YEN: "YEN",
33
+ RUBLE: "RUBLE",
34
+ WON: "WON",
35
+ QUESTION: "QUESTION",
36
+ BANG: "BANG",
37
+ BIT_AND: "BIT_AND",
38
+ BIT_OR: "BIT_OR",
39
+ BIT_NOT: "BIT_NOT",
40
+ KEYWORD: "KEYWORD",
41
+ EOF: "EOF",
42
+ ERROR: "ERROR",
43
+ WS: "WS",
44
+ NEWLINE: "NEWLINE",
45
+ DATETIME_LITERAL: "DATETIME_LITERAL",
46
+ DURATION: "DURATION",
47
+ UNIT: "UNIT",
48
+ ROLL: "ROLL",
49
+ PI: "PI",
50
+ E: "E",
51
+ MOD: "MOD",
52
+ OF: "OF",
53
+ INCREASE_BY: "INCREASE_BY",
54
+ DECREASE_BY: "DECREASE_BY",
55
+ // Percentage solve-for-unknown (packages/percentage/), "N% of what is
56
+ // X" solves N% * base = X for base. Fused as a full 3-word phrase (see
57
+ // PercentagePackage.ts's `phrases` field) rather than a bare "what"
58
+ // keyword, "what" is common enough as a variable name to be worth the
59
+ // same phrase-fusion treatment this codebase gives "total"/"average"/etc.
60
+ OF_WHAT_IS: "OF_WHAT_IS",
61
+ // Sibling solve-for-unknown forms accounting for a +/-1 offset, "N% on
62
+ // what is X" (increase) / "N% off what is X" (decrease). Same
63
+ // phrase-fusion reasoning as OF_WHAT_IS above.
64
+ ON_WHAT_IS: "ON_WHAT_IS",
65
+ OFF_WHAT_IS: "OFF_WHAT_IS",
66
+ NOW: "NOW",
67
+ TODAY: "TODAY",
68
+ TOMORROW: "TOMORROW",
69
+ YESTERDAY: "YESTERDAY",
70
+ DURATION_DAY: "DURATION_DAY",
71
+ DURATION_WEEK: "DURATION_WEEK",
72
+ DURATION_MONTH: "DURATION_MONTH",
73
+ DURATION_YEAR: "DURATION_YEAR",
74
+ DURATION_HOUR: "DURATION_HOUR",
75
+ DURATION_MINUTE: "DURATION_MINUTE",
76
+ DURATION_SECOND: "DURATION_SECOND",
77
+ FUNC: "FUNC",
78
+ CONVERT: "CONVERT",
79
+ TO: "TO",
80
+ BEST: "BEST",
81
+ NEXT: "NEXT",
82
+ LAST: "LAST",
83
+ UNTIL: "UNTIL",
84
+ SINCE: "SINCE",
85
+ BETWEEN: "BETWEEN",
86
+ FROM: "FROM",
87
+ INCREASE: "INCREASE",
88
+ DECREASE: "DECREASE",
89
+ UNICODE_MATH: "UNICODE_MATH",
90
+ TIMES_BY: "TIMES_BY",
91
+ MULTIPLY_BY: "MULTIPLY_BY",
92
+ DIVIDE_BY: "DIVIDE_BY",
93
+ NEQ: "NEQ",
94
+ IN: "IN",
95
+ BIT_XOR: "BIT_XOR",
96
+ EQUALITY: "EQUALITY",
97
+ GTE: "GTE",
98
+ LTE: "LTE",
99
+ LT: "LT",
100
+ GT: "GT",
101
+ LOGICAL_AND: "LOGICAL_AND",
102
+ LOGICAL_OR: "LOGICAL_OR",
103
+ OR: "OR",
104
+ TRUE: "TRUE",
105
+ FALSE: "FALSE",
106
+ IF: "IF",
107
+ THEN: "THEN",
108
+ ELSE: "ELSE",
109
+ AS: "AS",
110
+ CONVERTER_NAME: "CONVERTER_NAME",
111
+ // Fused two-word phrase tokens (see MathPhrasesPackage.ts's `phrases`
112
+ // field), deliberately NOT bare single-word keywords: "average"
113
+ // "total", "count", etc. are common variable names, and this codebase
114
+ // has a tested policy that colon-prefixed variable names can't be
115
+ // keyword-shaped words (see VariableParselet.ts's doc comment). Fusing
116
+ // the full "<word> of"/"<word> between" phrase means the bare word
117
+ // itself never becomes its own token type, so ":total = ..." keeps
118
+ // working exactly as before.
119
+ AVERAGE_OF: "AVERAGE_OF",
120
+ MEDIAN_OF: "MEDIAN_OF",
121
+ TOTAL_OF: "TOTAL_OF",
122
+ COUNT_OF: "COUNT_OF",
123
+ LARGER_OF: "LARGER_OF",
124
+ SMALLER_OF: "SMALLER_OF",
125
+ HALF_OF: "HALF_OF",
126
+ MIDPOINT_BETWEEN: "MIDPOINT_BETWEEN",
127
+ RANDOM_NUMBER: "RANDOM_NUMBER",
128
+ IS_TO: "IS_TO",
129
+ // CLAMP stays a bare single-word keyword: "clamp X between Y and Z" has
130
+ // the value X between the trigger and "between", so it can't be
131
+ // phrase-fused like the others above (same structural reason
132
+ // ClampParselet.ts is hand-written instead of PhrasePattern-based).
133
+ // Matches this codebase's existing accepted risk for "between"/"from"/
134
+ // "next"/"last"/"best", also bare, also can't be used as `:name`.
135
+ CLAMP: "CLAMP",
136
+ // map/reduce/sum/prod (packages/mapreduce/), bare single-word keywords
137
+ // each with its own dedicated parselet (custom argument grammar: a bare
138
+ // builtin/user-function name, an inline transform expression, or
139
+ // `name=collection` zipped pairs, none of which fit the ordinary
140
+ // FunctionCallParselet path, so these can't just reuse the generic FUNC
141
+ // token type the way sqrt/abs/... do).
142
+ MAP: "MAP",
143
+ REDUCE: "REDUCE",
144
+ SUM_FN: "SUM_FN",
145
+ PROD_FN: "PROD_FN",
146
+ // The algebra verbs (packages/symbolic/), fused from an ordinary IDENT only
147
+ // when immediately followed by `(`, so `factor`/`solve`/`expand` stay usable
148
+ // as variable names. Declared here rather than left to be minted on first use
149
+ // by `tokenTypeId()`, which is what {@link registerAllTokenTypes} exists for:
150
+ // a lazily-minted id depends on what else happened to be minted before it, so
151
+ // in a single-process run the id a normalizer rule produces can stop matching
152
+ // the id the parselet was registered under. Every token type a built-in
153
+ // package relies on belongs in this table.
154
+ EXPAND_FN: "EXPAND_FN",
155
+ FACTOR_FN: "FACTOR_FN",
156
+ SOLVE_FN: "SOLVE_FN",
157
+ DER_FN: "DER_FN",
158
+ INTEGRAL_FN: "INTEGRAL_FN",
159
+ TAYLOR_FN: "TAYLOR_FN",
160
+ JACOBIAN_FN: "JACOBIAN_FN",
161
+ CONJ_FN: "CONJ_FN",
162
+ RE_FN: "RE_FN",
163
+ IM_FN: "IM_FN",
164
+ CANCEL_FN: "CANCEL_FN",
165
+ APART_FN: "APART_FN",
166
+ // The imaginary-literal suffix, fused from a number followed immediately by
167
+ // `i`. Same registration reasoning as the verbs above.
168
+ IMAGINARY: "IMAGINARY",
169
+ // `=>`, "therefore"/solve operator. The algebra itself lives in symbolic/;
170
+ // packages/symbolic/ carries the grammar surface for the named operations.
171
+ // A genuine 2-char lexer token (ExpressionLexer.ts's TWO_CHAR_OPS table),
172
+ // same mechanism as ==/!=/>=/<=, not a normalizer-level fusion, "=" then
173
+ // ">" is the opposite char order from GTE's ">=", so there's no collision.
174
+ THEREFORE: "THEREFORE",
175
+ // Timezone query phrases (see TimePackage.ts's `phrases` field). Same
176
+ // phrase-fusion reasoning as above: "time"/"date"/"difference" are
177
+ // common variable names, so the fused trigger is the full phrase.
178
+ // CITY_NAME is the fused-token type for multi-word city/country names
179
+ // (e.g. "new york"). See timezones/CityZones.ts's MULTI_WORD_CITY_ZONES.
180
+ TIME_IN: "TIME_IN",
181
+ DATE_IN: "DATE_IN",
182
+ TIME_DIFFERENCE_BETWEEN: "TIME_DIFFERENCE_BETWEEN",
183
+ CITY_NAME: "CITY_NAME",
184
+ BACKTICK_OPEN: "BACKTICK_OPEN",
185
+ INLINE_SOLVE_START: "INLINE_SOLVE_START",
186
+ // Comment marker, `#` or `//` to end of line. Emitted by
187
+ // ExpressionLexer.tokenizeComment()/tokenizeOperator() but never reaches
188
+ // a parselet: ExpressionEngine.prepareExpression() filters COMMENT
189
+ // tokens out of the stream before normalization/parsing (see
190
+ // ExpressionEngine.ts's "Filter COMMENT tokens" comments). Listed here
191
+ // for discoverability even though tokenTypeId() would lazily register
192
+ // it anyway on first use.
193
+ COMMENT: "COMMENT",
194
+ // Vector types (referenced in locale keywordMap as vec2→VEC2, etc.)
195
+ VEC2: "VEC2",
196
+ VEC3: "VEC3",
197
+ VEC4: "VEC4",
198
+ FLOAT: "FLOAT",
199
+ GLOBAL: "GLOBAL",
200
+ // ── Finance (packages/finance/) ──
201
+ // OVER/RATE_AT are bare single-word keywords (not phrase-fused): both are
202
+ // prepositions with near-zero plausibility as a variable name (nobody
203
+ // writes ":over = 5" or ":at = 3"), the same accepted-risk category as
204
+ // this codebase's existing bare "between"/"from"/"next"/"last"/"best"
205
+ // keywords (see VariableParselet.ts's doc comment). RATE_AT is deliberately
206
+ // NOT named "AT", that name is already reserved (dormant) for a future
207
+ // "@" symbol token in TokenNormalizer.NON_WORD_NAMES; reusing it here would
208
+ // create an unintended coupling if "@" is ever wired up.
209
+ OVER: "OVER",
210
+ RATE_AT: "RATE_AT",
211
+ // Fused phrase tokens (see FinancePackage.ts's `phrases` field)
212
+ // deliberately NOT bare single-word keywords: "interest", "tax", "vat",
213
+ // "repayment", "principal" etc. are all common, plausible variable names
214
+ // (a shipped playground example uses ":total = :subtotal + :tax". See
215
+ // MathPhrasesPackage.ts's doc comment for the regression this caused
216
+ // once already). Fusing the full "<word> on"/"<word> off" phrase means
217
+ // the bare leading word itself never becomes its own token type, so
218
+ // ":tax = ..." keeps working exactly as before.
219
+ COMPOUND_INTEREST_ON: "COMPOUND_INTEREST_ON",
220
+ INTEREST_ON: "INTEREST_ON",
221
+ DAILY_REPAYMENT_ON: "DAILY_REPAYMENT_ON",
222
+ MONTHLY_REPAYMENT_ON: "MONTHLY_REPAYMENT_ON",
223
+ ANNUAL_REPAYMENT_ON: "ANNUAL_REPAYMENT_ON",
224
+ TOTAL_REPAYMENT_ON: "TOTAL_REPAYMENT_ON",
225
+ DAILY_LOAN_INTEREST_ON: "DAILY_LOAN_INTEREST_ON",
226
+ MONTHLY_LOAN_INTEREST_ON: "MONTHLY_LOAN_INTEREST_ON",
227
+ ANNUAL_LOAN_INTEREST_ON: "ANNUAL_LOAN_INTEREST_ON",
228
+ TOTAL_LOAN_INTEREST_ON: "TOTAL_LOAN_INTEREST_ON",
229
+ TAX_ON: "TAX_ON",
230
+ TAX_OFF: "TAX_OFF",
231
+ // Inflation-adjusted value (packages/finance/) -- fused phrase
232
+ // tokens (see FinancePackage.ts's `phrases` field), same reasoning
233
+ // as the tax/interest phrases above: "what"/"was"/"value"/"worth"
234
+ // are all plausible variable names, so only the full phrases are
235
+ // ever claimed as keywords, never the bare leading word.
236
+ WHAT_IS: "WHAT_IS",
237
+ WHAT_WAS: "WHAT_WAS",
238
+ VALUE_OF: "VALUE_OF",
239
+ WORTH_IN: "WORTH_IN",
240
+ // Bare single-word keyword (not phrase-fused) -- "assuming" has
241
+ // near-zero plausibility as a variable name, the same accepted-risk
242
+ // category as this codebase's existing bare "over"/"at" keywords
243
+ // (see the OVER/RATE_AT comment above). Registered so its bare word
244
+ // is a recognized phrase-starter (`canStartPhrase`), which suppresses
245
+ // implicit-multiply insertion between the futureYear NUMBER and this
246
+ // word in "value of $X in <year> assuming N% inflation" -- without
247
+ // this, "<year> assuming" was silently rewritten to "<year> *
248
+ // assuming" before parsing ever ran.
249
+ ASSUMING: "ASSUMING",
250
+ // Fused by a custom NormalizerRule (not `phrases`), carrying the
251
+ // year as its value -- see
252
+ // finance/normalizer/InYearDollarsNormalizerRule.ts.
253
+ IN_YEAR_DOLLARS: "IN_YEAR_DOLLARS",
254
+ // Cooking/UoM (packages/uom/) -- fused ingredient name (single- or
255
+ // multi-word, e.g. "butter"/"olive oil") carrying the matched name
256
+ // as its value. NOT a bare-word phrase-trie keyword -- see
257
+ // uom/normalizer/IngredientNameNormalizerRule.ts's doc comment for
258
+ // why this is a context-sensitive NormalizerRule instead (so a bare
259
+ // `:butter = 5` variable definition is completely unaffected).
260
+ INGREDIENT_NAME: "INGREDIENT_NAME",
261
+ // ── Datetime, workdays/weekdays/timestamps (packages/datetime/) ──
262
+ // Fused phrase tokens (see DatetimePackage.ts's `phrases` field)
263
+ // deliberately NOT bare single-word keywords: "workdays"/"weekday"/
264
+ // "timestamp"/"date" are all plausible variable names, same
265
+ // reasoning/regression risk as MathPhrasesPackage.ts's "total" note and
266
+ // FinancePackage.ts's "tax" note above. Fusing the full phrase means the
267
+ // bare leading word itself never becomes its own token type, so e.g.
268
+ // ":timestamp = 5" keeps working.
269
+ WORKDAYS_IN: "WORKDAYS_IN",
270
+ WEEKDAY_ON: "WEEKDAY_ON",
271
+ CURRENT_TIMESTAMP: "CURRENT_TIMESTAMP",
272
+ TO_DATE: "TO_DATE",
273
+ TO_TIMESTAMP: "TO_TIMESTAMP",
274
+ // Natural-question forms over the same date fields, "what day is it in
275
+ // 30 days", "what month is it on 25/12/2026", "what week is it". Each is
276
+ // a fully-fused phrase for the same reason as WEEKDAY_ON above: claiming
277
+ // bare "day"/"month"/"week" as keywords would break ":day = 5" and
278
+ // collide with the UNIT tokens of the same name.
279
+ WEEKDAY_IN: "WEEKDAY_IN",
280
+ MONTH_ON: "MONTH_ON",
281
+ MONTH_IN: "MONTH_IN",
282
+ WEEK_ON: "WEEK_ON",
283
+ WEEK_IN: "WEEK_IN",
284
+ // `<unit> between <date> and <date>`, fused UNIT+BETWEEN, exactly like
285
+ // UNTIL_UNIT/SINCE_UNIT above.
286
+ BETWEEN_UNIT: "BETWEEN_UNIT",
287
+ // Postfix day-type predicates, "<date> is a weekend" / "is a workday".
288
+ IS_WEEKEND: "IS_WEEKEND",
289
+ IS_WORKDAY: "IS_WORKDAY",
290
+ // ── Time, video timecode (packages/time/) ──
291
+ // Fused from a raw `HH:MM:SS:FF` token sequence (see
292
+ // packages/time/normalizer/VideoTimecodeNormalizerRule.ts) and from
293
+ // `NUMBER frames` (see FrameCountNormalizerRule.ts), not a bare-keyword
294
+ // collision risk the way the datetime tokens above are, since neither
295
+ // fusion claims a plain English word as its own token type.
296
+ VIDEO_TIMECODE: "VIDEO_TIMECODE",
297
+ FRAME_COUNT: "FRAME_COUNT",
298
+ // "@". See ExpressionLexer.ts's OP_MAP entry for why this was
299
+ // previously dormant/unproduced despite being anticipated by name here
300
+ // and in TokenNormalizer.ts's NON_WORD_NAMES.
301
+ AT: "AT",
302
+ // Generic token for every currency symbol added AFTER the original
303
+ // DOLLAR/POUND/EURO/YEN/RUBLE/WON set (each of which kept its own
304
+ // specific token type for backward compatibility). See
305
+ // uom/CurrencyAliases.ts's CURRENCY_SYMBOL_ALIASES and
306
+ // ExpressionLexer.ts's dispatch for the full symbol list. One shared
307
+ // type avoids needing a new TokenTypes entry + TokenCategoryMap entry +
308
+ // CurrencyPackage.ts prefixParselets entry per additional symbol.
309
+ CURRENCY_SYMBOL: "CURRENCY_SYMBOL",
310
+ // ── Cross-line data access (packages/lines/) ──
311
+ // "prev" -- bare keyword (nothing to phrase-fuse against, same shape as
312
+ // CLAMP -- accepted collision risk per that package's own precedent).
313
+ PREV: "PREV",
314
+ // "line1" / "line 1" / "l1" -- fused by LineRefNormalizerRule (never a
315
+ // bare lexer keyword, so ":line = 5"/":l = 5" stay untouched). Carries
316
+ // the parsed line number as its .value.
317
+ LINE_REF: "LINE_REF",
318
+ // "sum(" / "total(" -- fused ONLY when immediately followed by LPAREN
319
+ // (see LineRefNormalizerRule's lookahead guard), so ":sum = 100" and
320
+ // MathPhrases' "total of X, Y" (no paren after "of") are unaffected.
321
+ SUM_RANGE_CALL: "SUM_RANGE_CALL",
322
+ AVERAGE_RANGE_CALL: "AVERAGE_RANGE_CALL",
323
+ // "total above" / "sum above" / "average above" -- phrase-fused (see
324
+ // LinesPackage.ts's `phrases` field), a deliberate departure from
325
+ // Numi/Numbr's bare "total"/"sum" wording to avoid the exact bare-
326
+ // keyword collision this codebase already regressed on once.
327
+ TOTAL_ABOVE: "TOTAL_ABOVE",
328
+ SUM_ABOVE: "SUM_ABOVE",
329
+ AVERAGE_ABOVE: "AVERAGE_ABOVE"
330
+ };
331
+ var _nextTokenTypeId = 0;
332
+ var _tokenTypeNameToId = /* @__PURE__ */ new Map();
333
+ var _tokenTypeIdToName = /* @__PURE__ */ new Map();
334
+ function registerTokenType(name) {
335
+ const existing = _tokenTypeNameToId.get(name);
336
+ if (existing !== void 0) return existing;
337
+ const id = _nextTokenTypeId++;
338
+ _tokenTypeNameToId.set(name, id);
339
+ _tokenTypeIdToName.set(id, name);
340
+ return id;
341
+ }
342
+ function tokenTypeId(name) {
343
+ return registerTokenType(name);
344
+ }
345
+ function tokenTypeName(id) {
346
+ return _tokenTypeIdToName.get(id) ?? `UNKNOWN_${id}`;
347
+ }
348
+ function registerAllTokenTypes() {
349
+ for (const name of Object.values(TokenTypes)) {
350
+ registerTokenType(name);
351
+ }
352
+ }
353
+
354
+ exports.TokenTypes = TokenTypes;
355
+ exports.registerAllTokenTypes = registerAllTokenTypes;
356
+ exports.registerTokenType = registerTokenType;
357
+ exports.tokenTypeId = tokenTypeId;
358
+ exports.tokenTypeName = tokenTypeName;
359
+ //# sourceMappingURL=chunk-GW32KPCU.cjs.map
360
+ //# sourceMappingURL=chunk-GW32KPCU.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lexer/Token.ts"],"names":[],"mappings":"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","file":"chunk-GW32KPCU.cjs","sourcesContent":["/**\n * Lexer token produced by {@link ExpressionLexer} and consumed by parsers.\n *\n * Each token carries:\n * - `type`: string name (e.g. \"NUMBER\", \"PLUS\") for diagnostics and parselet lookup\n * - `typeId`: integer ID for O(1) comparison in parser hot paths\n * - `value`/`text`: the token's semantic value and raw source text\n * - `offset`/`line`/`col`: source position for error messages and highlighting\n */\nexport interface Token {\n\t/** String token type (e.g., \"NUMBER\", \"PLUS\", \"IDENT\"). Used by ParseletRegistry string-keyed maps and error messages. */\n\ttype: string;\n\t/** Integer token type ID for fast comparison in Parser hot path.\n\t * Populated by the Lexer via registerTokenType(). Use tokenTypeId(type) to get a type's ID. */\n\ttypeId: number;\n\tvalue: string;\n\ttext: string;\n\toffset: number;\n\tlineBreaks: number;\n\tline: number;\n\tcol: number;\n}\n\n/**\n * Canonical token type name constants.\n * All token types used by the lexer, parser, and VM are defined here.\n * Custom/plugin token types should be registered via {@link registerTokenType}.\n */\nexport const TokenTypes = {\n NUMBER: \"NUMBER\",\n BIGINT: \"BIGINT\",\n STRING: \"STRING\",\n IDENT: \"IDENT\",\n PLUS: \"PLUS\",\n MINUS: \"MINUS\",\n STAR: \"STAR\",\n SLASH: \"SLASH\",\n CARET: \"CARET\",\n PERCENT: \"PERCENT\",\n LSHIFT: \"LSHIFT\",\n RSHIFT: \"RSHIFT\",\n URSHIFT: \"URSHIFT\",\n LPAREN: \"LPAREN\",\n RPAREN: \"RPAREN\",\n LBRACKET: \"LBRACKET\",\n RBRACKET: \"RBRACKET\",\n LBRACE: \"LBRACE\",\n RBRACE: \"RBRACE\",\n COMMA: \"COMMA\",\n DOT: \"DOT\",\n COLON: \"COLON\",\n SEMICOLON: \"SEMICOLON\",\n EQUALS: \"EQUALS\",\n DOLLAR: \"DOLLAR\",\n POUND: \"POUND\",\n EURO: \"EURO\",\n YEN: \"YEN\",\n RUBLE: \"RUBLE\",\n WON: \"WON\",\n QUESTION: \"QUESTION\",\n BANG: \"BANG\",\n BIT_AND: \"BIT_AND\",\n BIT_OR: \"BIT_OR\",\n BIT_NOT: \"BIT_NOT\",\n KEYWORD: \"KEYWORD\",\n EOF: \"EOF\",\n ERROR: \"ERROR\",\n WS: \"WS\",\n NEWLINE: \"NEWLINE\",\n DATETIME_LITERAL: \"DATETIME_LITERAL\",\n DURATION: \"DURATION\",\n UNIT: \"UNIT\",\n ROLL: \"ROLL\",\n PI: \"PI\",\n E: \"E\",\n MOD: \"MOD\",\n OF: \"OF\",\n INCREASE_BY: \"INCREASE_BY\",\n DECREASE_BY: \"DECREASE_BY\",\n // Percentage solve-for-unknown (packages/percentage/), \"N% of what is\n // X\" solves N% * base = X for base. Fused as a full 3-word phrase (see\n // PercentagePackage.ts's `phrases` field) rather than a bare \"what\"\n // keyword, \"what\" is common enough as a variable name to be worth the\n // same phrase-fusion treatment this codebase gives \"total\"/\"average\"/etc.\n OF_WHAT_IS: \"OF_WHAT_IS\",\n // Sibling solve-for-unknown forms accounting for a +/-1 offset, \"N% on\n // what is X\" (increase) / \"N% off what is X\" (decrease). Same\n // phrase-fusion reasoning as OF_WHAT_IS above.\n ON_WHAT_IS: \"ON_WHAT_IS\",\n OFF_WHAT_IS: \"OFF_WHAT_IS\",\n NOW: \"NOW\",\n TODAY: \"TODAY\",\n TOMORROW: \"TOMORROW\",\n YESTERDAY: \"YESTERDAY\",\n DURATION_DAY: \"DURATION_DAY\",\n DURATION_WEEK: \"DURATION_WEEK\",\n DURATION_MONTH: \"DURATION_MONTH\",\n DURATION_YEAR: \"DURATION_YEAR\",\n DURATION_HOUR: \"DURATION_HOUR\",\n DURATION_MINUTE: \"DURATION_MINUTE\",\n DURATION_SECOND: \"DURATION_SECOND\",\n FUNC: \"FUNC\",\n CONVERT: \"CONVERT\",\n TO: \"TO\",\n BEST: \"BEST\",\n NEXT: \"NEXT\",\n LAST: \"LAST\",\n UNTIL: \"UNTIL\",\n SINCE: \"SINCE\",\n BETWEEN: \"BETWEEN\",\n FROM: \"FROM\",\n INCREASE: \"INCREASE\",\n DECREASE: \"DECREASE\",\n UNICODE_MATH: \"UNICODE_MATH\",\n TIMES_BY: \"TIMES_BY\",\n MULTIPLY_BY: \"MULTIPLY_BY\",\n DIVIDE_BY: \"DIVIDE_BY\",\n NEQ: \"NEQ\",\n IN: \"IN\",\n BIT_XOR: \"BIT_XOR\",\n EQUALITY: \"EQUALITY\",\n GTE: \"GTE\",\n LTE: \"LTE\",\n LT: \"LT\",\n GT: \"GT\",\n LOGICAL_AND: \"LOGICAL_AND\",\n LOGICAL_OR: \"LOGICAL_OR\",\n OR: \"OR\",\n TRUE: \"TRUE\",\n FALSE: \"FALSE\",\n IF: \"IF\",\n THEN: \"THEN\",\n ELSE: \"ELSE\",\n AS: \"AS\",\n CONVERTER_NAME: \"CONVERTER_NAME\",\n // Fused two-word phrase tokens (see MathPhrasesPackage.ts's `phrases`\n // field), deliberately NOT bare single-word keywords: \"average\"\n // \"total\", \"count\", etc. are common variable names, and this codebase\n // has a tested policy that colon-prefixed variable names can't be\n // keyword-shaped words (see VariableParselet.ts's doc comment). Fusing\n // the full \"<word> of\"/\"<word> between\" phrase means the bare word\n // itself never becomes its own token type, so \":total = ...\" keeps\n // working exactly as before.\n AVERAGE_OF: \"AVERAGE_OF\",\n MEDIAN_OF: \"MEDIAN_OF\",\n TOTAL_OF: \"TOTAL_OF\",\n COUNT_OF: \"COUNT_OF\",\n LARGER_OF: \"LARGER_OF\",\n SMALLER_OF: \"SMALLER_OF\",\n HALF_OF: \"HALF_OF\",\n MIDPOINT_BETWEEN: \"MIDPOINT_BETWEEN\",\n RANDOM_NUMBER: \"RANDOM_NUMBER\",\n IS_TO: \"IS_TO\",\n // CLAMP stays a bare single-word keyword: \"clamp X between Y and Z\" has\n // the value X between the trigger and \"between\", so it can't be\n // phrase-fused like the others above (same structural reason\n // ClampParselet.ts is hand-written instead of PhrasePattern-based).\n // Matches this codebase's existing accepted risk for \"between\"/\"from\"/\n // \"next\"/\"last\"/\"best\", also bare, also can't be used as `:name`.\n CLAMP: \"CLAMP\",\n // map/reduce/sum/prod (packages/mapreduce/), bare single-word keywords\n // each with its own dedicated parselet (custom argument grammar: a bare\n // builtin/user-function name, an inline transform expression, or\n // `name=collection` zipped pairs, none of which fit the ordinary\n // FunctionCallParselet path, so these can't just reuse the generic FUNC\n // token type the way sqrt/abs/... do).\n MAP: \"MAP\",\n REDUCE: \"REDUCE\",\n SUM_FN: \"SUM_FN\",\n PROD_FN: \"PROD_FN\",\n // The algebra verbs (packages/symbolic/), fused from an ordinary IDENT only\n // when immediately followed by `(`, so `factor`/`solve`/`expand` stay usable\n // as variable names. Declared here rather than left to be minted on first use\n // by `tokenTypeId()`, which is what {@link registerAllTokenTypes} exists for:\n // a lazily-minted id depends on what else happened to be minted before it, so\n // in a single-process run the id a normalizer rule produces can stop matching\n // the id the parselet was registered under. Every token type a built-in\n // package relies on belongs in this table.\n EXPAND_FN: \"EXPAND_FN\",\n FACTOR_FN: \"FACTOR_FN\",\n SOLVE_FN: \"SOLVE_FN\",\n DER_FN: \"DER_FN\",\n INTEGRAL_FN: \"INTEGRAL_FN\",\n TAYLOR_FN: \"TAYLOR_FN\",\n JACOBIAN_FN: \"JACOBIAN_FN\",\n CONJ_FN: \"CONJ_FN\",\n RE_FN: \"RE_FN\",\n IM_FN: \"IM_FN\",\n CANCEL_FN: \"CANCEL_FN\",\n APART_FN: \"APART_FN\",\n // The imaginary-literal suffix, fused from a number followed immediately by\n // `i`. Same registration reasoning as the verbs above.\n IMAGINARY: \"IMAGINARY\",\n // `=>`, \"therefore\"/solve operator. The algebra itself lives in symbolic/;\n // packages/symbolic/ carries the grammar surface for the named operations.\n // A genuine 2-char lexer token (ExpressionLexer.ts's TWO_CHAR_OPS table),\n // same mechanism as ==/!=/>=/<=, not a normalizer-level fusion, \"=\" then\n // \">\" is the opposite char order from GTE's \">=\", so there's no collision.\n THEREFORE: \"THEREFORE\",\n // Timezone query phrases (see TimePackage.ts's `phrases` field). Same\n // phrase-fusion reasoning as above: \"time\"/\"date\"/\"difference\" are\n // common variable names, so the fused trigger is the full phrase.\n // CITY_NAME is the fused-token type for multi-word city/country names\n // (e.g. \"new york\"). See timezones/CityZones.ts's MULTI_WORD_CITY_ZONES.\n TIME_IN: \"TIME_IN\",\n DATE_IN: \"DATE_IN\",\n TIME_DIFFERENCE_BETWEEN: \"TIME_DIFFERENCE_BETWEEN\",\n CITY_NAME: \"CITY_NAME\",\n BACKTICK_OPEN: \"BACKTICK_OPEN\",\n INLINE_SOLVE_START: \"INLINE_SOLVE_START\",\n // Comment marker, `#` or `//` to end of line. Emitted by\n // ExpressionLexer.tokenizeComment()/tokenizeOperator() but never reaches\n // a parselet: ExpressionEngine.prepareExpression() filters COMMENT\n // tokens out of the stream before normalization/parsing (see\n // ExpressionEngine.ts's \"Filter COMMENT tokens\" comments). Listed here\n // for discoverability even though tokenTypeId() would lazily register\n // it anyway on first use.\n COMMENT: \"COMMENT\",\n // Vector types (referenced in locale keywordMap as vec2→VEC2, etc.)\n VEC2: \"VEC2\",\n VEC3: \"VEC3\",\n VEC4: \"VEC4\",\n FLOAT: \"FLOAT\",\n GLOBAL: \"GLOBAL\",\n // ── Finance (packages/finance/) ──\n // OVER/RATE_AT are bare single-word keywords (not phrase-fused): both are\n // prepositions with near-zero plausibility as a variable name (nobody\n // writes \":over = 5\" or \":at = 3\"), the same accepted-risk category as\n // this codebase's existing bare \"between\"/\"from\"/\"next\"/\"last\"/\"best\"\n // keywords (see VariableParselet.ts's doc comment). RATE_AT is deliberately\n // NOT named \"AT\", that name is already reserved (dormant) for a future\n // \"@\" symbol token in TokenNormalizer.NON_WORD_NAMES; reusing it here would\n // create an unintended coupling if \"@\" is ever wired up.\n OVER: \"OVER\",\n RATE_AT: \"RATE_AT\",\n // Fused phrase tokens (see FinancePackage.ts's `phrases` field)\n // deliberately NOT bare single-word keywords: \"interest\", \"tax\", \"vat\",\n // \"repayment\", \"principal\" etc. are all common, plausible variable names\n // (a shipped playground example uses \":total = :subtotal + :tax\". See\n // MathPhrasesPackage.ts's doc comment for the regression this caused\n // once already). Fusing the full \"<word> on\"/\"<word> off\" phrase means\n // the bare leading word itself never becomes its own token type, so\n // \":tax = ...\" keeps working exactly as before.\n COMPOUND_INTEREST_ON: \"COMPOUND_INTEREST_ON\",\n INTEREST_ON: \"INTEREST_ON\",\n DAILY_REPAYMENT_ON: \"DAILY_REPAYMENT_ON\",\n MONTHLY_REPAYMENT_ON: \"MONTHLY_REPAYMENT_ON\",\n ANNUAL_REPAYMENT_ON: \"ANNUAL_REPAYMENT_ON\",\n TOTAL_REPAYMENT_ON: \"TOTAL_REPAYMENT_ON\",\n DAILY_LOAN_INTEREST_ON: \"DAILY_LOAN_INTEREST_ON\",\n MONTHLY_LOAN_INTEREST_ON: \"MONTHLY_LOAN_INTEREST_ON\",\n ANNUAL_LOAN_INTEREST_ON: \"ANNUAL_LOAN_INTEREST_ON\",\n TOTAL_LOAN_INTEREST_ON: \"TOTAL_LOAN_INTEREST_ON\",\n TAX_ON: \"TAX_ON\",\n TAX_OFF: \"TAX_OFF\",\n // Inflation-adjusted value (packages/finance/) -- fused phrase\n // tokens (see FinancePackage.ts's `phrases` field), same reasoning\n // as the tax/interest phrases above: \"what\"/\"was\"/\"value\"/\"worth\"\n // are all plausible variable names, so only the full phrases are\n // ever claimed as keywords, never the bare leading word.\n WHAT_IS: \"WHAT_IS\",\n WHAT_WAS: \"WHAT_WAS\",\n VALUE_OF: \"VALUE_OF\",\n WORTH_IN: \"WORTH_IN\",\n // Bare single-word keyword (not phrase-fused) -- \"assuming\" has\n // near-zero plausibility as a variable name, the same accepted-risk\n // category as this codebase's existing bare \"over\"/\"at\" keywords\n // (see the OVER/RATE_AT comment above). Registered so its bare word\n // is a recognized phrase-starter (`canStartPhrase`), which suppresses\n // implicit-multiply insertion between the futureYear NUMBER and this\n // word in \"value of $X in <year> assuming N% inflation\" -- without\n // this, \"<year> assuming\" was silently rewritten to \"<year> *\n // assuming\" before parsing ever ran.\n ASSUMING: \"ASSUMING\",\n // Fused by a custom NormalizerRule (not `phrases`), carrying the\n // year as its value -- see\n // finance/normalizer/InYearDollarsNormalizerRule.ts.\n IN_YEAR_DOLLARS: \"IN_YEAR_DOLLARS\",\n // Cooking/UoM (packages/uom/) -- fused ingredient name (single- or\n // multi-word, e.g. \"butter\"/\"olive oil\") carrying the matched name\n // as its value. NOT a bare-word phrase-trie keyword -- see\n // uom/normalizer/IngredientNameNormalizerRule.ts's doc comment for\n // why this is a context-sensitive NormalizerRule instead (so a bare\n // `:butter = 5` variable definition is completely unaffected).\n INGREDIENT_NAME: \"INGREDIENT_NAME\",\n // ── Datetime, workdays/weekdays/timestamps (packages/datetime/) ──\n // Fused phrase tokens (see DatetimePackage.ts's `phrases` field)\n // deliberately NOT bare single-word keywords: \"workdays\"/\"weekday\"/\n // \"timestamp\"/\"date\" are all plausible variable names, same\n // reasoning/regression risk as MathPhrasesPackage.ts's \"total\" note and\n // FinancePackage.ts's \"tax\" note above. Fusing the full phrase means the\n // bare leading word itself never becomes its own token type, so e.g.\n // \":timestamp = 5\" keeps working.\n WORKDAYS_IN: \"WORKDAYS_IN\",\n WEEKDAY_ON: \"WEEKDAY_ON\",\n CURRENT_TIMESTAMP: \"CURRENT_TIMESTAMP\",\n TO_DATE: \"TO_DATE\",\n TO_TIMESTAMP: \"TO_TIMESTAMP\",\n // Natural-question forms over the same date fields, \"what day is it in\n // 30 days\", \"what month is it on 25/12/2026\", \"what week is it\". Each is\n // a fully-fused phrase for the same reason as WEEKDAY_ON above: claiming\n // bare \"day\"/\"month\"/\"week\" as keywords would break \":day = 5\" and\n // collide with the UNIT tokens of the same name.\n WEEKDAY_IN: \"WEEKDAY_IN\",\n MONTH_ON: \"MONTH_ON\",\n MONTH_IN: \"MONTH_IN\",\n WEEK_ON: \"WEEK_ON\",\n WEEK_IN: \"WEEK_IN\",\n // `<unit> between <date> and <date>`, fused UNIT+BETWEEN, exactly like\n // UNTIL_UNIT/SINCE_UNIT above.\n BETWEEN_UNIT: \"BETWEEN_UNIT\",\n // Postfix day-type predicates, \"<date> is a weekend\" / \"is a workday\".\n IS_WEEKEND: \"IS_WEEKEND\",\n IS_WORKDAY: \"IS_WORKDAY\",\n // ── Time, video timecode (packages/time/) ──\n // Fused from a raw `HH:MM:SS:FF` token sequence (see\n // packages/time/normalizer/VideoTimecodeNormalizerRule.ts) and from\n // `NUMBER frames` (see FrameCountNormalizerRule.ts), not a bare-keyword\n // collision risk the way the datetime tokens above are, since neither\n // fusion claims a plain English word as its own token type.\n VIDEO_TIMECODE: \"VIDEO_TIMECODE\",\n FRAME_COUNT: \"FRAME_COUNT\",\n // \"@\". See ExpressionLexer.ts's OP_MAP entry for why this was\n // previously dormant/unproduced despite being anticipated by name here\n // and in TokenNormalizer.ts's NON_WORD_NAMES.\n AT: \"AT\",\n // Generic token for every currency symbol added AFTER the original\n // DOLLAR/POUND/EURO/YEN/RUBLE/WON set (each of which kept its own\n // specific token type for backward compatibility). See\n // uom/CurrencyAliases.ts's CURRENCY_SYMBOL_ALIASES and\n // ExpressionLexer.ts's dispatch for the full symbol list. One shared\n // type avoids needing a new TokenTypes entry + TokenCategoryMap entry +\n // CurrencyPackage.ts prefixParselets entry per additional symbol.\n CURRENCY_SYMBOL: \"CURRENCY_SYMBOL\",\n // ── Cross-line data access (packages/lines/) ──\n // \"prev\" -- bare keyword (nothing to phrase-fuse against, same shape as\n // CLAMP -- accepted collision risk per that package's own precedent).\n PREV: \"PREV\",\n // \"line1\" / \"line 1\" / \"l1\" -- fused by LineRefNormalizerRule (never a\n // bare lexer keyword, so \":line = 5\"/\":l = 5\" stay untouched). Carries\n // the parsed line number as its .value.\n LINE_REF: \"LINE_REF\",\n // \"sum(\" / \"total(\" -- fused ONLY when immediately followed by LPAREN\n // (see LineRefNormalizerRule's lookahead guard), so \":sum = 100\" and\n // MathPhrases' \"total of X, Y\" (no paren after \"of\") are unaffected.\n SUM_RANGE_CALL: \"SUM_RANGE_CALL\",\n AVERAGE_RANGE_CALL: \"AVERAGE_RANGE_CALL\",\n // \"total above\" / \"sum above\" / \"average above\" -- phrase-fused (see\n // LinesPackage.ts's `phrases` field), a deliberate departure from\n // Numi/Numbr's bare \"total\"/\"sum\" wording to avoid the exact bare-\n // keyword collision this codebase already regressed on once.\n TOTAL_ABOVE: \"TOTAL_ABOVE\",\n SUM_ABOVE: \"SUM_ABOVE\",\n AVERAGE_ABOVE: \"AVERAGE_ABOVE\",\n} as const;\n\n/**\n * A token's kind, as a string.\n *\n * Deliberately open rather than an enum: a package registers its own token\n * types at runtime, and a closed set would make that impossible.\n */\nexport type TokenType = (typeof TokenTypes)[keyof typeof TokenTypes];\n\n// ── Integer Token Type ID System ──────────────────────────────────────────────\n// Enables O(1) integer comparison in Parser hot path instead of string hashing.\n\n/** Auto-incrementing integer ID for each token type. */\nlet _nextTokenTypeId = 0;\n\n/** String → integer ID lookup. Populated lazily via registerTokenType(). */\nconst _tokenTypeNameToId = new Map<string, number>();\n\n/** Integer ID → string lookup. For debug/error messages. */\nconst _tokenTypeIdToName = new Map<number, string>();\n\n/**\n * Register a token type name and get back its integer ID.\n * Idempotent, returns existing ID if already registered.\n * Call once per token type at module initialization time.\n */\nexport function registerTokenType(name: string): number {\n\tconst existing = _tokenTypeNameToId.get(name);\n\tif (existing !== undefined) return existing;\n\tconst id = _nextTokenTypeId++;\n\t_tokenTypeNameToId.set(name, id);\n\t_tokenTypeIdToName.set(id, name);\n\treturn id;\n}\n\n/**\n * Get the integer ID for a token type name.\n * Lazily registers unknown token types on first access, enabling plugin providers\n * to define custom token types (VEC2, VEC3, etc.) without pre-registration.\n * All built-in TokenTypes are pre-registered via registerAllTokenTypes().\n */\nexport function tokenTypeId(name: string): number {\n\treturn registerTokenType(name); // registerTokenType is idempotent\n}\n\n/**\n * Get the string name for a token type ID (for error messages and debugging).\n * Returns `UNKNOWN_${id}` if the ID is not registered.\n */\nexport function tokenTypeName(id: number): string {\n\treturn _tokenTypeIdToName.get(id) ?? `UNKNOWN_${id}`;\n}\n\n/**\n * Bootstrap all known token types from TokenTypes at module load.\n * Call this once after TokenTypes is defined.\n */\nexport function registerAllTokenTypes(): void {\n\tfor (const name of Object.values(TokenTypes)) {\n\t\tregisterTokenType(name);\n\t}\n}\n"]}