solve-engine 1.2.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (385) hide show
  1. package/README.md +12 -17
  2. package/dist/{BytecodeBuilder-Bp9xeTmX.d.cts → BytecodeBuilder-DGGeByAP.d.cts} +18 -0
  3. package/dist/{BytecodeBuilder-Bp9xeTmX.d.ts → BytecodeBuilder-DGGeByAP.d.ts} +18 -0
  4. package/dist/{Configuration-C9W8tJv_.d.cts → Configuration-B6W0-T67.d.cts} +17 -4
  5. package/dist/{Configuration-C9W8tJv_.d.ts → Configuration-B6W0-T67.d.ts} +17 -4
  6. package/dist/{EngineError-CNA_rHY-.d.cts → EngineError-Ce1lPkjZ.d.cts} +2 -0
  7. package/dist/{EngineError-CNA_rHY-.d.ts → EngineError-Ce1lPkjZ.d.ts} +2 -0
  8. package/dist/{PackageCompatibility-B6NX9IaN.d.cts → PackageCompatibility-Bn5jnBtA.d.cts} +2 -2
  9. package/dist/{PackageCompatibility-Ceg5XdAp.d.ts → PackageCompatibility-CIvq2MP5.d.ts} +2 -2
  10. package/dist/{PackageRegistry-DrCPQNyy.d.ts → PackageRegistry-DzeiWcv4.d.ts} +93 -172
  11. package/dist/{PackageRegistry-DnJYVw9G.d.cts → PackageRegistry-dpdurBVO.d.cts} +93 -172
  12. package/dist/{Parselet-Bhf7d0_W.d.ts → Parselet-B-zoPrTa.d.ts} +8 -5
  13. package/dist/{Parselet-Cv7S7KRt.d.cts → Parselet-C4Wu055_.d.cts} +8 -5
  14. package/dist/{ScopeManager-Bzq87GfA.d.ts → ScopeManager-C2LDOrDx.d.ts} +7 -16
  15. package/dist/{ScopeManager-DRDBVfan.d.cts → ScopeManager-D7uMXbhS.d.cts} +7 -16
  16. package/dist/{VMCheckpoints-C6c17Hbo.d.ts → VMCheckpoints-CGyFhivM.d.ts} +3 -3
  17. package/dist/{VMCheckpoints-dZxSMGHG.d.cts → VMCheckpoints-I9jg3jWR.d.cts} +3 -3
  18. package/dist/{Value-DZNQ_PU7.d.cts → Value-CCi_Eecs.d.cts} +40 -0
  19. package/dist/{Value-DZNQ_PU7.d.ts → Value-CCi_Eecs.d.ts} +40 -0
  20. package/dist/{WorkerError-Djd7GGGa.d.cts → WorkerError-B4p6PNfx.d.cts} +1 -1
  21. package/dist/{WorkerError-B7t7R2-m.d.ts → WorkerError-Dhj9BQ_A.d.ts} +1 -1
  22. package/dist/chunk-2JMFUQZH.js +2 -0
  23. package/dist/chunk-2JMFUQZH.js.map +1 -0
  24. package/dist/chunk-2LFLR3VZ.cjs +2 -0
  25. package/dist/chunk-2LFLR3VZ.cjs.map +1 -0
  26. package/dist/chunk-2RWAXT6O.js +0 -1
  27. package/dist/chunk-32GC2FHC.cjs +2 -0
  28. package/dist/chunk-32GC2FHC.cjs.map +1 -0
  29. package/dist/chunk-4BZIYU7S.cjs +3 -0
  30. package/dist/chunk-4BZIYU7S.cjs.map +1 -0
  31. package/dist/chunk-4E4YVQKK.js +5 -0
  32. package/dist/chunk-4E4YVQKK.js.map +1 -0
  33. package/dist/chunk-4QVBSG6B.cjs +2 -0
  34. package/dist/chunk-4QVBSG6B.cjs.map +1 -0
  35. package/dist/chunk-5FO4PDIG.js +2 -0
  36. package/dist/chunk-5FO4PDIG.js.map +1 -0
  37. package/dist/chunk-5IJD5L3O.cjs +2 -0
  38. package/dist/chunk-5IJD5L3O.cjs.map +1 -0
  39. package/dist/chunk-62LMTO4F.js +2 -0
  40. package/dist/chunk-62LMTO4F.js.map +1 -0
  41. package/dist/chunk-6G3PMEPA.js +2 -0
  42. package/dist/chunk-6G3PMEPA.js.map +1 -0
  43. package/dist/chunk-6INX773F.cjs +2 -0
  44. package/dist/chunk-6INX773F.cjs.map +1 -0
  45. package/dist/chunk-76F3LCIL.js +4 -0
  46. package/dist/chunk-76F3LCIL.js.map +1 -0
  47. package/dist/chunk-7BXPCWKM.cjs +2 -0
  48. package/dist/chunk-7BXPCWKM.cjs.map +1 -0
  49. package/dist/chunk-7GK3XEZF.js +2 -0
  50. package/dist/chunk-7GK3XEZF.js.map +1 -0
  51. package/dist/chunk-AXMQG5TS.cjs +2 -0
  52. package/dist/chunk-AXMQG5TS.cjs.map +1 -0
  53. package/dist/chunk-CIQOK7Q4.cjs +2 -0
  54. package/dist/chunk-CIQOK7Q4.cjs.map +1 -0
  55. package/dist/chunk-E2Q3PQ2G.js +3 -0
  56. package/dist/chunk-E2Q3PQ2G.js.map +1 -0
  57. package/dist/chunk-E6Z4NQAS.js +2 -0
  58. package/dist/chunk-E6Z4NQAS.js.map +1 -0
  59. package/dist/chunk-EFJCC6FJ.cjs +2 -0
  60. package/dist/chunk-EFJCC6FJ.cjs.map +1 -0
  61. package/dist/chunk-ESUN2THE.cjs +2 -0
  62. package/dist/chunk-ESUN2THE.cjs.map +1 -0
  63. package/dist/chunk-EVAOPEO4.js +2 -0
  64. package/dist/chunk-EVAOPEO4.js.map +1 -0
  65. package/dist/chunk-EVI6OHQH.cjs +2 -0
  66. package/dist/chunk-EVI6OHQH.cjs.map +1 -0
  67. package/dist/chunk-FDE5HWDI.cjs +2 -0
  68. package/dist/chunk-FDE5HWDI.cjs.map +1 -0
  69. package/dist/chunk-FWW3M36J.cjs +2 -0
  70. package/dist/chunk-FWW3M36J.cjs.map +1 -0
  71. package/dist/chunk-G7TBEQRQ.js +2 -0
  72. package/dist/chunk-G7TBEQRQ.js.map +1 -0
  73. package/dist/chunk-GK2OHWRF.cjs +5 -0
  74. package/dist/chunk-GK2OHWRF.cjs.map +1 -0
  75. package/dist/chunk-HFKDWQUL.js +2 -0
  76. package/dist/chunk-HFKDWQUL.js.map +1 -0
  77. package/dist/chunk-HLBYHXQD.cjs +3 -0
  78. package/dist/chunk-HLBYHXQD.cjs.map +1 -0
  79. package/dist/chunk-I52MYCVI.js +3 -0
  80. package/dist/chunk-I52MYCVI.js.map +1 -0
  81. package/dist/chunk-IANAMBJQ.cjs +2 -0
  82. package/dist/chunk-IANAMBJQ.cjs.map +1 -0
  83. package/dist/chunk-IJMNVBIS.js +2 -0
  84. package/dist/chunk-IJMNVBIS.js.map +1 -0
  85. package/dist/chunk-J4LZD4ZY.js +3 -0
  86. package/dist/chunk-J4LZD4ZY.js.map +1 -0
  87. package/dist/chunk-JAK3RAFA.cjs +2 -0
  88. package/dist/chunk-JAK3RAFA.cjs.map +1 -0
  89. package/dist/chunk-JFAJN3C2.cjs +2 -0
  90. package/dist/chunk-JFAJN3C2.cjs.map +1 -0
  91. package/dist/chunk-JPFCXLJV.js +2 -0
  92. package/dist/chunk-JPFCXLJV.js.map +1 -0
  93. package/dist/chunk-JUIJ6NRD.cjs +3 -0
  94. package/dist/chunk-JUIJ6NRD.cjs.map +1 -0
  95. package/dist/chunk-MIQBJGGR.js +2 -0
  96. package/dist/chunk-MIQBJGGR.js.map +1 -0
  97. package/dist/chunk-MPB7KUN5.js +3 -0
  98. package/dist/chunk-MPB7KUN5.js.map +1 -0
  99. package/dist/chunk-MSYX32PF.cjs +2 -0
  100. package/dist/chunk-MSYX32PF.cjs.map +1 -0
  101. package/dist/chunk-MVZUTETT.js +2 -0
  102. package/dist/chunk-MVZUTETT.js.map +1 -0
  103. package/dist/chunk-N7N7MPMK.cjs +2 -0
  104. package/dist/chunk-N7N7MPMK.cjs.map +1 -0
  105. package/dist/chunk-NGBBNL4K.cjs +1 -3
  106. package/dist/chunk-OVKDDTXO.cjs +3 -0
  107. package/dist/chunk-OVKDDTXO.cjs.map +1 -0
  108. package/dist/chunk-P6WPEUAJ.cjs +2 -0
  109. package/dist/chunk-P6WPEUAJ.cjs.map +1 -0
  110. package/dist/chunk-PS272DZJ.cjs +2 -0
  111. package/dist/chunk-PS272DZJ.cjs.map +1 -0
  112. package/dist/chunk-R2ENWQ76.js +2 -0
  113. package/dist/chunk-R2ENWQ76.js.map +1 -0
  114. package/dist/chunk-R2SZFJTT.cjs +2 -0
  115. package/dist/chunk-R2SZFJTT.cjs.map +1 -0
  116. package/dist/chunk-RAF57WYO.js +2 -0
  117. package/dist/chunk-RAF57WYO.js.map +1 -0
  118. package/dist/chunk-RSF25YSJ.js +2 -0
  119. package/dist/chunk-RSF25YSJ.js.map +1 -0
  120. package/dist/chunk-SOMGSIO4.cjs +3 -0
  121. package/dist/chunk-SOMGSIO4.cjs.map +1 -0
  122. package/dist/chunk-SYYE3QAX.cjs +2 -0
  123. package/dist/chunk-SYYE3QAX.cjs.map +1 -0
  124. package/dist/chunk-TCZSPH4A.js +2 -0
  125. package/dist/chunk-TCZSPH4A.js.map +1 -0
  126. package/dist/chunk-TLG7VZRX.cjs +2 -0
  127. package/dist/chunk-TLG7VZRX.cjs.map +1 -0
  128. package/dist/chunk-TN5E6JU6.js +2 -0
  129. package/dist/chunk-TN5E6JU6.js.map +1 -0
  130. package/dist/chunk-TRBXW6HW.js +2 -0
  131. package/dist/{chunk-AQNHHJMJ.cjs.map → chunk-TRBXW6HW.js.map} +1 -1
  132. package/dist/chunk-TTFO4YDP.cjs +2 -0
  133. package/dist/chunk-TTFO4YDP.cjs.map +1 -0
  134. package/dist/chunk-TWC7K3ZX.js +2 -0
  135. package/dist/chunk-TWC7K3ZX.js.map +1 -0
  136. package/dist/chunk-U4AEVL5Z.js +2 -0
  137. package/dist/chunk-U4AEVL5Z.js.map +1 -0
  138. package/dist/chunk-UURM7P3P.cjs +4 -0
  139. package/dist/chunk-UURM7P3P.cjs.map +1 -0
  140. package/dist/chunk-VAGS5JS7.cjs +2 -0
  141. package/dist/chunk-VAGS5JS7.cjs.map +1 -0
  142. package/dist/chunk-W2JAR233.js +2 -0
  143. package/dist/chunk-W2JAR233.js.map +1 -0
  144. package/dist/chunk-WGZ3FNHI.js +2 -0
  145. package/dist/chunk-WGZ3FNHI.js.map +1 -0
  146. package/dist/chunk-XEIDV5JP.js +2 -0
  147. package/dist/chunk-XEIDV5JP.js.map +1 -0
  148. package/dist/chunk-XNIWQHXY.js +2 -0
  149. package/dist/chunk-XNIWQHXY.js.map +1 -0
  150. package/dist/chunk-Y7O4D3BJ.cjs +2 -0
  151. package/dist/chunk-Y7O4D3BJ.cjs.map +1 -0
  152. package/dist/chunk-YAHGSBMC.js +2 -0
  153. package/dist/chunk-YAHGSBMC.js.map +1 -0
  154. package/dist/chunk-YAYBVVG2.js +3 -0
  155. package/dist/chunk-YAYBVVG2.js.map +1 -0
  156. package/dist/chunk-YJ2OPULK.js +2 -0
  157. package/dist/chunk-YJ2OPULK.js.map +1 -0
  158. package/dist/chunk-YVKHEAFT.js +2 -0
  159. package/dist/chunk-YVKHEAFT.js.map +1 -0
  160. package/dist/chunk-ZCNBT44X.cjs +2 -0
  161. package/dist/chunk-ZCNBT44X.cjs.map +1 -0
  162. package/dist/chunk-ZLRJ7TDP.cjs +2 -0
  163. package/dist/chunk-ZLRJ7TDP.cjs.map +1 -0
  164. package/dist/constants.cjs +1 -21
  165. package/dist/constants.d.cts +1 -1
  166. package/dist/constants.d.ts +1 -1
  167. package/dist/constants.js +1 -4
  168. package/dist/engine.cjs +1 -94
  169. package/dist/engine.d.cts +10 -11
  170. package/dist/engine.d.ts +10 -11
  171. package/dist/engine.js +1 -37
  172. package/dist/errors.cjs +1 -105
  173. package/dist/errors.d.cts +3 -3
  174. package/dist/errors.d.ts +3 -3
  175. package/dist/errors.js +1 -4
  176. package/dist/format.cjs +1 -26
  177. package/dist/format.d.cts +2 -2
  178. package/dist/format.d.ts +2 -2
  179. package/dist/format.js +1 -9
  180. package/dist/index.cjs +1 -314
  181. package/dist/index.cjs.map +1 -1
  182. package/dist/index.d.cts +52 -20
  183. package/dist/index.d.ts +52 -20
  184. package/dist/index.js +1 -278
  185. package/dist/index.js.map +1 -1
  186. package/dist/language.cjs +1 -369
  187. package/dist/language.cjs.map +1 -1
  188. package/dist/language.d.cts +9 -10
  189. package/dist/language.d.ts +9 -10
  190. package/dist/language.js +1 -348
  191. package/dist/language.js.map +1 -1
  192. package/dist/lexer.cjs +1 -63
  193. package/dist/lexer.js +1 -10
  194. package/dist/normalizer.cjs +1 -39
  195. package/dist/normalizer.js +1 -10
  196. package/dist/packages.cjs +1 -132
  197. package/dist/packages.d.cts +8 -9
  198. package/dist/packages.d.ts +8 -9
  199. package/dist/packages.js +1 -23
  200. package/dist/parser.cjs +1 -54
  201. package/dist/parser.d.cts +8 -8
  202. package/dist/parser.d.ts +8 -8
  203. package/dist/parser.js +1 -9
  204. package/dist/{pipeline-D-PS9gVw.d.ts → pipeline-72QmQlGx.d.ts} +1 -1
  205. package/dist/{pipeline-DtSBJ8TS.d.cts → pipeline-DCQicwWX.d.cts} +1 -1
  206. package/dist/resolvers.cjs +1 -12
  207. package/dist/resolvers.d.cts +2 -2
  208. package/dist/resolvers.d.ts +2 -2
  209. package/dist/resolvers.js +1 -3
  210. package/dist/services.cjs +1 -20
  211. package/dist/services.js +1 -3
  212. package/dist/testing.cjs +3 -477
  213. package/dist/testing.cjs.map +1 -1
  214. package/dist/testing.d.cts +9 -10
  215. package/dist/testing.d.ts +9 -10
  216. package/dist/testing.js +3 -469
  217. package/dist/testing.js.map +1 -1
  218. package/dist/uom.cjs +1 -55
  219. package/dist/uom.d.cts +2 -2
  220. package/dist/uom.d.ts +2 -2
  221. package/dist/uom.js +1 -10
  222. package/dist/utilities.cjs +1 -36
  223. package/dist/utilities.js +1 -7
  224. package/dist/vm.cjs +1 -295
  225. package/dist/vm.cjs.map +1 -1
  226. package/dist/vm.d.cts +22 -10
  227. package/dist/vm.d.ts +22 -10
  228. package/dist/vm.js +1 -193
  229. package/dist/vm.js.map +1 -1
  230. package/dist/worker.cjs +2 -492
  231. package/dist/worker.cjs.map +1 -1
  232. package/dist/worker.d.cts +16 -17
  233. package/dist/worker.d.ts +16 -17
  234. package/dist/worker.js +2 -483
  235. package/dist/worker.js.map +1 -1
  236. package/package.json +1 -13
  237. package/dist/chunk-3BOK2LDK.js +0 -17
  238. package/dist/chunk-3BOK2LDK.js.map +0 -1
  239. package/dist/chunk-3VGDNEE3.js +0 -84
  240. package/dist/chunk-3VGDNEE3.js.map +0 -1
  241. package/dist/chunk-4K5W7EH2.cjs +0 -112
  242. package/dist/chunk-4K5W7EH2.cjs.map +0 -1
  243. package/dist/chunk-5EFKSKMA.js +0 -413
  244. package/dist/chunk-5EFKSKMA.js.map +0 -1
  245. package/dist/chunk-5HRB36DK.js +0 -405
  246. package/dist/chunk-5HRB36DK.js.map +0 -1
  247. package/dist/chunk-5ON7PUAZ.js +0 -12
  248. package/dist/chunk-5ON7PUAZ.js.map +0 -1
  249. package/dist/chunk-7AXJNQMF.cjs +0 -297
  250. package/dist/chunk-7AXJNQMF.cjs.map +0 -1
  251. package/dist/chunk-7JM3F4KL.js +0 -1795
  252. package/dist/chunk-7JM3F4KL.js.map +0 -1
  253. package/dist/chunk-7USV76HV.cjs +0 -341
  254. package/dist/chunk-7USV76HV.cjs.map +0 -1
  255. package/dist/chunk-A2DZ5BEJ.cjs +0 -1930
  256. package/dist/chunk-A2DZ5BEJ.cjs.map +0 -1
  257. package/dist/chunk-ADBA3XBE.cjs +0 -20
  258. package/dist/chunk-ADBA3XBE.cjs.map +0 -1
  259. package/dist/chunk-AKNGX4TZ.cjs +0 -236
  260. package/dist/chunk-AKNGX4TZ.cjs.map +0 -1
  261. package/dist/chunk-ALYRJ72W.cjs +0 -434
  262. package/dist/chunk-ALYRJ72W.cjs.map +0 -1
  263. package/dist/chunk-AMOJYLG2.cjs +0 -1692
  264. package/dist/chunk-AMOJYLG2.cjs.map +0 -1
  265. package/dist/chunk-AOH6UR2L.js +0 -825
  266. package/dist/chunk-AOH6UR2L.js.map +0 -1
  267. package/dist/chunk-AQNHHJMJ.cjs +0 -261
  268. package/dist/chunk-B7LXJ6LC.cjs +0 -36
  269. package/dist/chunk-B7LXJ6LC.cjs.map +0 -1
  270. package/dist/chunk-BESTLPRK.cjs +0 -6919
  271. package/dist/chunk-BESTLPRK.cjs.map +0 -1
  272. package/dist/chunk-BLI4NIQY.js +0 -98
  273. package/dist/chunk-BLI4NIQY.js.map +0 -1
  274. package/dist/chunk-BSPXMGIS.js +0 -455
  275. package/dist/chunk-BSPXMGIS.js.map +0 -1
  276. package/dist/chunk-C2OMO3WN.cjs +0 -2806
  277. package/dist/chunk-C2OMO3WN.cjs.map +0 -1
  278. package/dist/chunk-CSDQMDU2.js +0 -204
  279. package/dist/chunk-CSDQMDU2.js.map +0 -1
  280. package/dist/chunk-EJ3ILXX6.cjs +0 -223
  281. package/dist/chunk-EJ3ILXX6.cjs.map +0 -1
  282. package/dist/chunk-ENRIK36Q.cjs +0 -94
  283. package/dist/chunk-ENRIK36Q.cjs.map +0 -1
  284. package/dist/chunk-F4UB4XIL.js +0 -109
  285. package/dist/chunk-F4UB4XIL.js.map +0 -1
  286. package/dist/chunk-FD5ZZHEU.js +0 -92
  287. package/dist/chunk-FD5ZZHEU.js.map +0 -1
  288. package/dist/chunk-FE4RC37D.js +0 -2801
  289. package/dist/chunk-FE4RC37D.js.map +0 -1
  290. package/dist/chunk-FEAIOR7N.cjs +0 -91
  291. package/dist/chunk-FEAIOR7N.cjs.map +0 -1
  292. package/dist/chunk-FR7RNOPT.cjs +0 -3303
  293. package/dist/chunk-FR7RNOPT.cjs.map +0 -1
  294. package/dist/chunk-G2YPPLGX.cjs +0 -484
  295. package/dist/chunk-G2YPPLGX.cjs.map +0 -1
  296. package/dist/chunk-GCM5JHMX.js +0 -88
  297. package/dist/chunk-GCM5JHMX.js.map +0 -1
  298. package/dist/chunk-GDEU72RG.cjs +0 -829
  299. package/dist/chunk-GDEU72RG.cjs.map +0 -1
  300. package/dist/chunk-HKTQCQ4Z.cjs +0 -8383
  301. package/dist/chunk-HKTQCQ4Z.cjs.map +0 -1
  302. package/dist/chunk-HWHU642X.cjs +0 -316
  303. package/dist/chunk-HWHU642X.cjs.map +0 -1
  304. package/dist/chunk-ICEKS6YC.cjs +0 -507
  305. package/dist/chunk-ICEKS6YC.cjs.map +0 -1
  306. package/dist/chunk-IJGOFP2J.js +0 -6904
  307. package/dist/chunk-IJGOFP2J.js.map +0 -1
  308. package/dist/chunk-IQJGDZOP.js +0 -333
  309. package/dist/chunk-IQJGDZOP.js.map +0 -1
  310. package/dist/chunk-IT74O4BE.cjs +0 -456
  311. package/dist/chunk-IT74O4BE.cjs.map +0 -1
  312. package/dist/chunk-KXDQKVNX.cjs +0 -459
  313. package/dist/chunk-KXDQKVNX.cjs.map +0 -1
  314. package/dist/chunk-L2TE7PMO.cjs +0 -14
  315. package/dist/chunk-L2TE7PMO.cjs.map +0 -1
  316. package/dist/chunk-L5YHV6BQ.js +0 -499
  317. package/dist/chunk-L5YHV6BQ.js.map +0 -1
  318. package/dist/chunk-LO7HU5WB.cjs +0 -209
  319. package/dist/chunk-LO7HU5WB.cjs.map +0 -1
  320. package/dist/chunk-LSALB3IN.js +0 -292
  321. package/dist/chunk-LSALB3IN.js.map +0 -1
  322. package/dist/chunk-MI7OTUHL.cjs +0 -339
  323. package/dist/chunk-MI7OTUHL.cjs.map +0 -1
  324. package/dist/chunk-MIGXCBXT.cjs +0 -381
  325. package/dist/chunk-MIGXCBXT.cjs.map +0 -1
  326. package/dist/chunk-MVTOCRV2.js +0 -213
  327. package/dist/chunk-MVTOCRV2.js.map +0 -1
  328. package/dist/chunk-N7FNVFXW.cjs +0 -32
  329. package/dist/chunk-N7FNVFXW.cjs.map +0 -1
  330. package/dist/chunk-N7OA4WPJ.js +0 -362
  331. package/dist/chunk-N7OA4WPJ.js.map +0 -1
  332. package/dist/chunk-NAWZATKT.js +0 -478
  333. package/dist/chunk-NAWZATKT.js.map +0 -1
  334. package/dist/chunk-NLNDMWZC.js +0 -31
  335. package/dist/chunk-NLNDMWZC.js.map +0 -1
  336. package/dist/chunk-ORM7CHYZ.js +0 -1531
  337. package/dist/chunk-ORM7CHYZ.js.map +0 -1
  338. package/dist/chunk-OUHT5Z36.cjs +0 -393
  339. package/dist/chunk-OUHT5Z36.cjs.map +0 -1
  340. package/dist/chunk-PCZVMMWU.cjs +0 -74
  341. package/dist/chunk-PCZVMMWU.cjs.map +0 -1
  342. package/dist/chunk-RNKDIXDV.js +0 -336
  343. package/dist/chunk-RNKDIXDV.js.map +0 -1
  344. package/dist/chunk-SBUFNJVE.js +0 -258
  345. package/dist/chunk-SBUFNJVE.js.map +0 -1
  346. package/dist/chunk-TC6BTUSU.cjs +0 -1799
  347. package/dist/chunk-TC6BTUSU.cjs.map +0 -1
  348. package/dist/chunk-TPOK3UNI.js +0 -8355
  349. package/dist/chunk-TPOK3UNI.js.map +0 -1
  350. package/dist/chunk-UF6JG5SG.js +0 -312
  351. package/dist/chunk-UF6JG5SG.js.map +0 -1
  352. package/dist/chunk-UKQHXPGW.js +0 -30
  353. package/dist/chunk-UKQHXPGW.js.map +0 -1
  354. package/dist/chunk-V4XG5QF6.js +0 -1685
  355. package/dist/chunk-V4XG5QF6.js.map +0 -1
  356. package/dist/chunk-VEKIWQ3F.cjs +0 -39
  357. package/dist/chunk-VEKIWQ3F.cjs.map +0 -1
  358. package/dist/chunk-WMQRJTAO.js +0 -3266
  359. package/dist/chunk-WMQRJTAO.js.map +0 -1
  360. package/dist/chunk-X6K3HUOY.cjs +0 -86
  361. package/dist/chunk-X6K3HUOY.cjs.map +0 -1
  362. package/dist/chunk-XBTEO4OB.js +0 -391
  363. package/dist/chunk-XBTEO4OB.js.map +0 -1
  364. package/dist/chunk-XIYYHA65.cjs +0 -101
  365. package/dist/chunk-XIYYHA65.cjs.map +0 -1
  366. package/dist/chunk-YJHY7CMN.cjs +0 -1534
  367. package/dist/chunk-YJHY7CMN.cjs.map +0 -1
  368. package/dist/chunk-YLJ4XMA6.js +0 -33
  369. package/dist/chunk-YLJ4XMA6.js.map +0 -1
  370. package/dist/chunk-YNIWOYW6.js +0 -232
  371. package/dist/chunk-YNIWOYW6.js.map +0 -1
  372. package/dist/chunk-Z2XP767T.cjs +0 -35
  373. package/dist/chunk-Z2XP767T.cjs.map +0 -1
  374. package/dist/chunk-Z4X2RWOF.js +0 -37
  375. package/dist/chunk-Z4X2RWOF.js.map +0 -1
  376. package/dist/chunk-ZN6YYPIW.js +0 -67
  377. package/dist/chunk-ZN6YYPIW.js.map +0 -1
  378. package/dist/chunk-ZNFFTYWH.js +0 -1854
  379. package/dist/chunk-ZNFFTYWH.js.map +0 -1
  380. package/dist/variables.cjs +0 -17
  381. package/dist/variables.cjs.map +0 -1
  382. package/dist/variables.d.cts +0 -87
  383. package/dist/variables.d.ts +0 -87
  384. package/dist/variables.js +0 -4
  385. package/dist/variables.js.map +0 -1
@@ -1,1534 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkG2YPPLGX_cjs = require('./chunk-G2YPPLGX.cjs');
4
- var chunkOUHT5Z36_cjs = require('./chunk-OUHT5Z36.cjs');
5
- var chunkAQNHHJMJ_cjs = require('./chunk-AQNHHJMJ.cjs');
6
- var chunkMIGXCBXT_cjs = require('./chunk-MIGXCBXT.cjs');
7
-
8
- // src/lexer/ExpressionLexer.ts
9
- chunkG2YPPLGX_cjs.registerAllTokenTypes();
10
- function buildCharClassTable() {
11
- const table = new Uint8Array(128);
12
- for (let i = 48; i <= 57; i++) table[i] = 2 /* DIGIT */;
13
- for (let i = 65; i <= 90; i++) table[i] = 3 /* ALPHA */;
14
- for (let i = 97; i <= 122; i++) table[i] = 3 /* ALPHA */;
15
- table[95] = 3 /* ALPHA */;
16
- table[46] = 4 /* DOT */;
17
- table[32] = 1 /* WHITESPACE */;
18
- table[9] = 1 /* WHITESPACE */;
19
- table[10] = 1 /* WHITESPACE */;
20
- table[13] = 1 /* WHITESPACE */;
21
- table[33] = 5 /* OPERATOR */;
22
- table[37] = 5 /* OPERATOR */;
23
- table[38] = 5 /* OPERATOR */;
24
- table[40] = 5 /* OPERATOR */;
25
- table[41] = 5 /* OPERATOR */;
26
- table[42] = 5 /* OPERATOR */;
27
- table[43] = 5 /* OPERATOR */;
28
- table[44] = 5 /* OPERATOR */;
29
- table[45] = 5 /* OPERATOR */;
30
- table[47] = 5 /* OPERATOR */;
31
- table[58] = 5 /* OPERATOR */;
32
- table[59] = 5 /* OPERATOR */;
33
- table[60] = 5 /* OPERATOR */;
34
- table[61] = 5 /* OPERATOR */;
35
- table[62] = 5 /* OPERATOR */;
36
- table[63] = 5 /* OPERATOR */;
37
- table[91] = 5 /* OPERATOR */;
38
- table[93] = 5 /* OPERATOR */;
39
- table[94] = 5 /* OPERATOR */;
40
- table[123] = 5 /* OPERATOR */;
41
- table[124] = 5 /* OPERATOR */;
42
- table[125] = 5 /* OPERATOR */;
43
- table[126] = 5 /* OPERATOR */;
44
- table[64] = 5 /* OPERATOR */;
45
- table[34] = 6 /* QUOTE */;
46
- table[35] = 7 /* HASH */;
47
- table[36] = 8 /* DOLLAR */;
48
- table[96] = 11 /* BACKTICK */;
49
- return table;
50
- }
51
- function isUnicodeSpace(cc) {
52
- return cc === 133 || // NEL, next line
53
- cc === 160 || // no-break space
54
- cc === 5760 || // ogham space mark
55
- cc >= 8192 && cc <= 8202 || // en quad through hair space, incl. figure/thin space
56
- cc === 8203 || // zero-width space
57
- cc === 8232 || // line separator
58
- cc === 8233 || // paragraph separator
59
- cc === 8239 || // narrow no-break space
60
- cc === 8287 || // medium mathematical space
61
- cc === 12288 || // ideographic space
62
- cc === 65279;
63
- }
64
- var LexerToken = class {
65
- constructor(type, typeId, value, text, offset, lineBreaks, line, col, sourceEnd) {
66
- this.type = type;
67
- this.typeId = typeId;
68
- this.value = value;
69
- this.text = text;
70
- this.offset = offset;
71
- this.lineBreaks = lineBreaks;
72
- this.line = line;
73
- this.col = col;
74
- this.sourceEnd = sourceEnd;
75
- }
76
- };
77
- var TWO_CHAR_OPS = {
78
- 61: { 61: "EQUALITY", 62: "THEREFORE" },
79
- // ==, => (opposite char order from >='s GTE below — no collision)
80
- 33: { 61: "NEQ" },
81
- // !=
82
- 62: { 61: "GTE" },
83
- // >=
84
- 60: { 61: "LTE" },
85
- // <=
86
- 38: { 38: "LOGICAL_AND" },
87
- // &&
88
- 124: { 124: "LOGICAL_OR" },
89
- // ||
90
- 43: { 61: "PLUS_EQUALS" },
91
- // += (compound assignment, running totals)
92
- 45: { 61: "MINUS_EQUALS" }
93
- // -= (neither + nor - had a two-char op before)
94
- // Note: ** is NOT a single token, the existing moo lexer emits two
95
- // separate STAR tokens, and the parser consumes them that way.
96
- // 42: { 42: 'EXPONENT' }, // **, disabled for moo compatibility
97
- };
98
- var OP_MAP = {
99
- 43: "PLUS",
100
- // +
101
- 45: "MINUS",
102
- // -
103
- 42: "STAR",
104
- // *
105
- 47: "SLASH",
106
- // /
107
- 94: "CARET",
108
- // ^
109
- 37: "PERCENT",
110
- // %
111
- 40: "LPAREN",
112
- // (
113
- 41: "RPAREN",
114
- // )
115
- 91: "LBRACKET",
116
- // [
117
- 93: "RBRACKET",
118
- // ]
119
- 123: "LBRACE",
120
- // {
121
- 125: "RBRACE",
122
- // }
123
- 44: "COMMA",
124
- // ,
125
- 58: "COLON",
126
- // :
127
- 59: "SEMICOLON",
128
- // ;
129
- 61: "EQUALS",
130
- // =
131
- 63: "QUESTION",
132
- // ?
133
- 33: "BANG",
134
- // !
135
- 38: "BIT_AND",
136
- // &
137
- 124: "BIT_OR",
138
- // |
139
- 60: "LT",
140
- // <
141
- 62: "GT",
142
- // >
143
- 126: "BIT_NOT",
144
- // ~
145
- // "@", activates the token type name already dormant-reserved for this
146
- // exact purpose (see Token.ts's OVER/RATE_AT doc comment and
147
- // normalizer/TokenNormalizer.ts's NON_WORD_NAMES, both of which already
148
- // anticipated "AT" as a future "@" symbol token before this addition).
149
- // Backs the time package's video-timecode literal's alternate fps
150
- // separator (`01:02:03:04 @ 30fps`, equivalent to `... at 30fps`). See
151
- // packages/time/parselets/VideoTimecodeParselet.ts.
152
- 64: "AT"
153
- // @
154
- };
155
- var EXPRESSION_INDICATOR_CODES = (() => {
156
- const set = /* @__PURE__ */ new Set();
157
- for (let i = 48; i <= 57; i++) set.add(i);
158
- const opCodes = [43, 45, 42, 47, 94, 37, 40, 41, 91, 93, 123, 125, 61, 60, 62, 33, 38, 124, 126, 59, 63];
159
- for (const c of opCodes) set.add(c);
160
- set.add(36);
161
- set.add(163);
162
- set.add(8364);
163
- set.add(165);
164
- set.add(8381);
165
- set.add(8361);
166
- set.add(96);
167
- set.add(46);
168
- set.add(35);
169
- return set;
170
- })();
171
- var _ExpressionLexer = class _ExpressionLexer {
172
- constructor(localeCode = "en", lookup) {
173
- /**
174
- * Configured TokenLookup from TokenClassRegistry. When set, replaces
175
- * the internal keyword map and unit set with registry-built equivalents.
176
- * Enables data-driven keyword/unit registration across locale keywords,
177
- * provider keywords, and plugins.
178
- *
179
- * Set at construction time via the constructor parameter. Plugin-registered
180
- * keywords/units (via registerVocabulary()) are checked alongside
181
- * the configuredLookup, neither source is bypassed.
182
- */
183
- this.configuredLookup = null;
184
- // Instance state
185
- this.input = "";
186
- this.pos = 0;
187
- this.len = 0;
188
- // Line / column tracking (1-indexed)
189
- this.line = 1;
190
- this.lineStartPos = 0;
191
- // Open-bracket context stack for the current line, one entry per unclosed
192
- // `(`/`[`, `true` when a comma inside it is a separator rather than a
193
- // thousands group. A `[` (vector/matrix) and a CALL `(` (`rgb(255,255,255)`,
194
- // preceded by an identifier) are separator contexts; a bare GROUPING `(`
195
- // (`(1,000)`, preceded by an operator or the line start) is not, so a
196
- // parenthesised thousands number still reads as one scalar. The number scanner
197
- // consults the innermost entry. Tracked here because the flat token stream
198
- // carries no nesting otherwise; reset per line, so an unbalanced bracket
199
- // cannot bleed the decision into the next.
200
- this.groupingStack = [];
201
- // Plugin-extensible keyword map (merged with locale keywordMap)
202
- this.pluginKeywordMap = /* @__PURE__ */ new Map();
203
- // Plugin-extensible two-char operators: firstChar → (secondChar → tokenType)
204
- this.pluginOperators = /* @__PURE__ */ new Map();
205
- // Plugin-extensible units (merged with knownUnits)
206
- this.pluginUnits = /* @__PURE__ */ new Set();
207
- // Fast-path guards: skip plugin lookups entirely when no plugins registered
208
- this.hasPluginOps = false;
209
- /**
210
- * Inline solve spans collected during the most recent tokenization pass.
211
- * Populated by [Symbol.iterator]() and consumed by scanDocument().
212
- */
213
- this._inlineSolveSpans = [];
214
- // Plugin-extensible raw-line patterns. See LexerVocabulary.rawLinePatterns.
215
- this.pluginRawLinePatterns = [];
216
- /**
217
- * If a `rawLinePatterns` rule matches the FULL text most recently passed
218
- * to {@link reset}, this holds the single synthetic token that
219
- * {@link tokenizeAll} should return instead of running the
220
- * character-by-character scanner. Cleared (re-evaluated) on every
221
- * {@link reset} call. `null` when no plugin registered any raw-line
222
- * patterns, or none matched, the overwhelmingly common case, checked
223
- * with a `length === 0` guard before ever touching this field so a
224
- * plugin-free lexer pays zero cost for the feature.
225
- */
226
- this.pendingRawLineToken = null;
227
- this.localeCode = localeCode;
228
- this.locale = chunkOUHT5Z36_cjs.getLocale(localeCode);
229
- this.configuredLookup = lookup ?? null;
230
- this.keywordMap = /* @__PURE__ */ new Map();
231
- for (const [k, v] of Object.entries(this.locale.keywordMap)) {
232
- this.keywordMap.set(k.toLowerCase(), v);
233
- }
234
- this.mergedKeywords = new Map(this.keywordMap);
235
- this.mergedUnits = new Set(chunkAQNHHJMJ_cjs.knownUnits);
236
- }
237
- /**
238
- * Test `text` against every registered `rawLinePatterns` rule, in
239
- * registration order. Returns a synthetic token for the first rule
240
- * whose `pattern` matches AND whose capture group 1 is non-empty after
241
- * trimming; returns `null` if no rule matches (the normal
242
- * character-by-character scanner should run instead).
243
- */
244
- matchRawLine(text) {
245
- for (const rule of this.pluginRawLinePatterns) {
246
- const m = rule.pattern.exec(text);
247
- if (m && typeof m[1] === "string") {
248
- const value = m[1].trim();
249
- if (value.length > 0) {
250
- return new LexerToken(rule.tokenType, chunkG2YPPLGX_cjs.tokenTypeId(rule.tokenType), value, value, 0, 0, this.line, 1);
251
- }
252
- }
253
- }
254
- return null;
255
- }
256
- /** Rebuild merged keyword and unit collections after plugin registration. */
257
- rebuildMergedCollections() {
258
- this.mergedKeywords = new Map([...this.keywordMap, ...this.pluginKeywordMap]);
259
- this.mergedUnits = /* @__PURE__ */ new Set([...chunkAQNHHJMJ_cjs.knownUnits, ...this.pluginUnits]);
260
- }
261
- /**
262
- * Register a plugin to extend the lexer with custom tokens.
263
- *
264
- * All registrations are additive, built-in patterns still work.
265
- * Keywords, operators, and units from the plugin are merged
266
- * with existing ones. Calling multiple times adds more entries.
267
- *
268
- * Note: multi-word phrases are now handled by the TokenNormalizer
269
- * (see `IEnginePackage.normalizerRules`), not the lexer.
270
- *
271
- * Built-in tokens CANNOT be overridden. Throws a EngineError if the
272
- * plugin attempts to register a keyword, operator, or unit
273
- * that conflicts with a built-in one.
274
- */
275
- registerVocabulary(plugin) {
276
- if (plugin.keywords) {
277
- for (const [keyword, tokenType] of Object.entries(plugin.keywords)) {
278
- const lower = keyword.toLowerCase();
279
- if (this.keywordMap.has(lower)) {
280
- throw chunkMIGXCBXT_cjs.ErrorFactory.config(
281
- "PLUGIN_KEYWORD_COLLISION",
282
- `Plugin keyword "${keyword}" conflicts with built-in keyword (type: ${this.keywordMap.get(lower)}). Built-in keywords cannot be overridden.`,
283
- { keyword, builtinType: this.keywordMap.get(lower) }
284
- );
285
- }
286
- this.pluginKeywordMap.set(lower, tokenType);
287
- }
288
- this.rebuildMergedCollections();
289
- }
290
- if (plugin.operators) {
291
- this.hasPluginOps = true;
292
- for (const [chars, tokenType] of Object.entries(plugin.operators)) {
293
- if (chars.length === 2) {
294
- const first = chars.charCodeAt(0);
295
- const second = chars.charCodeAt(1);
296
- const builtInSecondMap = TWO_CHAR_OPS[first];
297
- if (builtInSecondMap && builtInSecondMap[second] !== void 0) {
298
- throw chunkMIGXCBXT_cjs.ErrorFactory.config(
299
- "PLUGIN_OPERATOR_COLLISION",
300
- `Plugin operator "${chars}" conflicts with built-in operator (type: ${builtInSecondMap[second]}). Built-in operators cannot be overridden.`,
301
- { operator: chars, builtinType: builtInSecondMap[second] }
302
- );
303
- }
304
- if (first === 60 && second === 60) {
305
- throw chunkMIGXCBXT_cjs.ErrorFactory.config(
306
- "PLUGIN_OPERATOR_COLLISION",
307
- `Plugin operator "${chars}" conflicts with built-in operator (type: LSHIFT). Built-in operators cannot be overridden.`,
308
- { operator: chars, builtinType: "LSHIFT" }
309
- );
310
- }
311
- if (first === 62 && second === 62) {
312
- throw chunkMIGXCBXT_cjs.ErrorFactory.config(
313
- "PLUGIN_OPERATOR_COLLISION",
314
- `Plugin operator "${chars}" conflicts with built-in operator (type: RSHIFT). Built-in operators cannot be overridden.`,
315
- { operator: chars, builtinType: "RSHIFT" }
316
- );
317
- }
318
- if (first === 47 && second === 47) {
319
- throw chunkMIGXCBXT_cjs.ErrorFactory.config(
320
- "PLUGIN_OPERATOR_COLLISION",
321
- `Plugin operator "${chars}" conflicts with built-in comment sequence. Comment sequences cannot be overridden.`,
322
- { operator: chars, builtinType: "COMMENT" }
323
- );
324
- }
325
- let inner = this.pluginOperators.get(first);
326
- if (!inner) {
327
- inner = /* @__PURE__ */ new Map();
328
- this.pluginOperators.set(first, inner);
329
- }
330
- inner.set(second, tokenType);
331
- }
332
- }
333
- }
334
- if (plugin.units) {
335
- for (const unit of plugin.units) {
336
- if (chunkAQNHHJMJ_cjs.knownUnits.has(unit)) {
337
- throw chunkMIGXCBXT_cjs.ErrorFactory.config(
338
- "PLUGIN_UNIT_COLLISION",
339
- `Plugin unit "${unit}" conflicts with a built-in unit. Built-in units cannot be overridden.`,
340
- { unit }
341
- );
342
- }
343
- this.pluginUnits.add(unit);
344
- }
345
- this.rebuildMergedCollections();
346
- }
347
- if (plugin.rawLinePatterns) {
348
- this.pluginRawLinePatterns.push(...plugin.rawLinePatterns);
349
- }
350
- }
351
- /**
352
- * Unregister a plugin, removing its custom tokens from the lexer.
353
- *
354
- * This is the inverse of registerVocabulary(). All keywords, operators,
355
- * and units registered by the plugin are removed. After
356
- * unregistration, those tokens will revert to their default behavior
357
- * (e.g., keywords become IDENT, operators become ERROR).
358
- *
359
- * Calling unregisterVocabulary with a plugin that was never registered
360
- * is safe, it simply has no effect.
361
- */
362
- unregisterVocabulary(plugin) {
363
- if (plugin.keywords) {
364
- for (const keyword of Object.keys(plugin.keywords)) {
365
- this.pluginKeywordMap.delete(keyword.toLowerCase());
366
- }
367
- this.rebuildMergedCollections();
368
- }
369
- if (plugin.operators) {
370
- for (const chars of Object.keys(plugin.operators)) {
371
- if (chars.length === 2) {
372
- const first = chars.charCodeAt(0);
373
- const second = chars.charCodeAt(1);
374
- const inner = this.pluginOperators.get(first);
375
- if (inner) {
376
- inner.delete(second);
377
- if (inner.size === 0) {
378
- this.pluginOperators.delete(first);
379
- }
380
- }
381
- }
382
- }
383
- this.hasPluginOps = this.pluginOperators.size > 0;
384
- }
385
- if (plugin.units) {
386
- for (const unit of plugin.units) {
387
- this.pluginUnits.delete(unit);
388
- }
389
- this.rebuildMergedCollections();
390
- }
391
- if (plugin.rawLinePatterns) {
392
- const toRemove = new Set(plugin.rawLinePatterns);
393
- this.pluginRawLinePatterns = this.pluginRawLinePatterns.filter((r) => !toRemove.has(r));
394
- }
395
- }
396
- reset(input) {
397
- this.input = input;
398
- this.pos = 0;
399
- this.len = input.length;
400
- this.line = 1;
401
- this.lineStartPos = 0;
402
- this.pendingRawLineToken = this.pluginRawLinePatterns.length > 0 ? this.matchRawLine(input) : null;
403
- }
404
- /**
405
- * Scan a full document text in a single pass, classifying each line and
406
- * tokenizing non-skipped lines.
407
- *
408
- * Replaces the separate classifyLine() + findInlineSolves() + per-line
409
- * reset() + tokenizeAll() pattern with a single character-by-character
410
- * walk through the entire document. Key benefits:
411
- *
412
- * - **Single reset()**: `this.pos`, `this.len`, `this.line`, and
413
- * `this.lineStartPos` are set once for the whole document, not per-line.
414
- * - **Single classification**: classifyLine() runs once per line inline;
415
- * skipped lines are jumped over without tokenization.
416
- * - **Shared tokenization**: Non-skipped lines are tokenized using the
417
- * existing state machine, yielding Token[] without per-line reset().
418
- * - **Inline solve detection**: findInlineSolves() is called only for
419
- * lines that classifyLine() marks as having inline solves.
420
- *
421
- * Tokenization is scoped to each line by temporarily restricting
422
- * `this.len` to the line end position, so the [Symbol.iterator]
423
- * generator naturally stops at the line boundary. After tokenization,
424
- * `this.len` is restored and `this.pos` advances past the newline.
425
- *
426
- * @param text The full document text (with newlines).
427
- * @returns Array of ScanLineResult, one per line, in document order.
428
- */
429
- scanDocument(text) {
430
- this.input = text;
431
- this.pos = 0;
432
- this.len = text.length;
433
- this.line = 1;
434
- this.lineStartPos = 0;
435
- const results = [];
436
- const input = this.input;
437
- const docLen = this.len;
438
- while (this.pos < docLen) {
439
- const lineStart = this.pos;
440
- let lineEnd = this.pos;
441
- while (lineEnd < docLen) {
442
- const cc = input.charCodeAt(lineEnd);
443
- if (cc === 10 || cc === 13) break;
444
- lineEnd++;
445
- }
446
- const lineNumber = this.line;
447
- const classification = this.classifyFromPositions(lineStart, lineEnd);
448
- const lineText = input.slice(lineStart, lineEnd);
449
- let tokens = [];
450
- if (!classification.skip) {
451
- const rawToken = this.pluginRawLinePatterns.length > 0 ? this.matchRawLine(lineText) : null;
452
- if (rawToken) {
453
- tokens = [rawToken];
454
- } else {
455
- const savedLen = this.len;
456
- this.len = lineEnd;
457
- if (classification.contentOffset !== void 0) this.pos = classification.contentOffset;
458
- tokens = Array.from(this);
459
- this.len = savedLen;
460
- }
461
- }
462
- let inlineSolves = [];
463
- if (classification.hasInlineSolve) {
464
- if (!classification.skip && tokens.length > 0) {
465
- const charSpans = this.findInlineSolves(lineText);
466
- inlineSolves = this._inlineSolveSpans.map((span, i) => ({
467
- start: charSpans[i]?.start ?? 0,
468
- end: charSpans[i]?.end ?? 0,
469
- expression: charSpans[i]?.expression ?? "",
470
- columnNumber: charSpans[i]?.columnNumber ?? span.columnNumber,
471
- startTokenIndex: span.startTokenIndex,
472
- endTokenIndex: span.endTokenIndex
473
- }));
474
- } else {
475
- inlineSolves = this.findInlineSolves(lineText);
476
- }
477
- }
478
- results.push({
479
- text: lineText,
480
- lineNumber,
481
- startOffset: lineStart,
482
- endOffset: lineEnd,
483
- classification,
484
- tokens,
485
- inlineSolves
486
- });
487
- this.pos = lineEnd;
488
- if (this.pos < docLen) {
489
- const nlChar = input.charCodeAt(this.pos);
490
- if (nlChar === 13) {
491
- this.pos++;
492
- if (this.pos < docLen && input.charCodeAt(this.pos) === 10) {
493
- this.pos++;
494
- }
495
- } else if (nlChar === 10) {
496
- this.pos++;
497
- }
498
- }
499
- this.line++;
500
- this.lineStartPos = this.pos;
501
- }
502
- return results;
503
- }
504
- /**
505
- * Tokenize an expression string into an array of Tokens.
506
- *
507
- * Delegates to the lazy [Symbol.iterator]() generator and collects all
508
- * yielded tokens via Array.from(). For memory-sensitive use cases, prefer
509
- * iterating the lexer directly with for...of to avoid array allocation.
510
- *
511
- * Optimizations:
512
- * - CHAR_CLASS jump table (Uint8Array) → switch on small integers
513
- * - Direct character-code dispatch (c0 cached pattern)
514
- * - Mathematical digit parsing (integer math, not slice+parseFloat)
515
- * - Inline operator tokenizer with two-char peek-ahead
516
- * - Whitespace eliminated in-lexer (never emitted)
517
- * - 0-char and 1-char fast paths
518
- */
519
- tokenizeAll() {
520
- if (this.pendingRawLineToken) {
521
- this._inlineSolveSpans = [];
522
- return [this.pendingRawLineToken];
523
- }
524
- return Array.from(this);
525
- }
526
- // ── Lazy iterator ─────────────────────────────────────────────────────
527
- /**
528
- * Lazy token-by-token generator. Yields each token without allocating an
529
- * intermediate Token[] array. Supports for...of and spread usage.
530
- *
531
- * Usage:
532
- * for (const t of lexer) { ... } // lazy, no array allocation
533
- * const tokens = [...lexer]; // materializes via spread
534
- * const tokens = lexer.tokenizeAll(); // materializes via Array.from()
535
- *
536
- * IMPORTANT: This generator captures `this.len` ONCE at creation time
537
- * (const len = this.len). `scanDocument()` relies on this behavior to
538
- * scope tokenization to a single line by temporarily restricting
539
- * `this.len` to the line end position before creating the iterator.
540
- * Do NOT refactor to re-read `this.len` mid-loop without also updating
541
- * `scanDocument()`.
542
- */
543
- *[Symbol.iterator]() {
544
- const len = this.len;
545
- if (len === 0) {
546
- this._inlineSolveSpans = [];
547
- return;
548
- }
549
- let tokenIndex = 0;
550
- let openSpan = null;
551
- const collectedSpans = [];
552
- if (len === 1) {
553
- const c0 = this.input.charCodeAt(0);
554
- const cc = _ExpressionLexer.CHAR_CLASS[c0] ?? 0 /* SKIP */;
555
- switch (cc) {
556
- case 2 /* DIGIT */:
557
- case 4 /* DOT */:
558
- yield new LexerToken("NUMBER", chunkG2YPPLGX_cjs.tokenTypeId("NUMBER"), this.input, this.input, 0, 0, 1, 1);
559
- tokenIndex++;
560
- break;
561
- case 3 /* ALPHA */: {
562
- const input2 = this.input;
563
- const identLower = input2.toLowerCase();
564
- if (this.mergedUnits.has(input2)) {
565
- yield new LexerToken("UNIT", chunkG2YPPLGX_cjs.tokenTypeId("UNIT"), input2, input2, 0, 0, 1, 1);
566
- } else {
567
- const kwType = this.mergedKeywords.get(identLower);
568
- if (kwType) {
569
- yield new LexerToken(kwType, chunkG2YPPLGX_cjs.tokenTypeId(kwType), input2, input2, 0, 0, 1, 1);
570
- } else {
571
- yield new LexerToken("IDENT", chunkG2YPPLGX_cjs.tokenTypeId("IDENT"), input2, input2, 0, 0, 1, 1);
572
- }
573
- }
574
- tokenIndex++;
575
- break;
576
- }
577
- case 5 /* OPERATOR */: {
578
- const opType = OP_MAP[c0];
579
- if (opType) {
580
- yield new LexerToken(opType, chunkG2YPPLGX_cjs.tokenTypeId(opType), this.input, this.input, 0, 0, 1, 1);
581
- tokenIndex++;
582
- }
583
- break;
584
- }
585
- case 6 /* QUOTE */:
586
- this.pos = 0;
587
- yield this.tokenizeString();
588
- tokenIndex++;
589
- break;
590
- case 7 /* HASH */:
591
- this.pos = 0;
592
- yield this.tokenizeComment();
593
- tokenIndex++;
594
- break;
595
- case 8 /* DOLLAR */:
596
- yield new LexerToken("DOLLAR", chunkG2YPPLGX_cjs.tokenTypeId("DOLLAR"), "$", "$", 0, 0, 1, 1);
597
- tokenIndex++;
598
- break;
599
- case 11 /* BACKTICK */:
600
- yield new LexerToken("BACKTICK_OPEN", chunkG2YPPLGX_cjs.tokenTypeId("BACKTICK_OPEN"), "`", "`", 0, 0, 1, 1);
601
- tokenIndex++;
602
- break;
603
- default: {
604
- if (isUnicodeSpace(c0)) ; else if (c0 === 215) {
605
- yield new LexerToken("STAR", chunkG2YPPLGX_cjs.tokenTypeId("STAR"), "\xD7", "\xD7", 0, 0, 1, 1);
606
- tokenIndex++;
607
- } else if (c0 === 247) {
608
- yield new LexerToken("SLASH", chunkG2YPPLGX_cjs.tokenTypeId("SLASH"), "\xF7", "\xF7", 0, 0, 1, 1);
609
- tokenIndex++;
610
- } else if (c0 === 177) {
611
- yield new LexerToken("PLUS_MINUS", chunkG2YPPLGX_cjs.tokenTypeId("PLUS_MINUS"), "\xB1", "\xB1", 0, 0, 1, 1);
612
- tokenIndex++;
613
- } else if (c0 === 8800) {
614
- yield new LexerToken("NEQ", chunkG2YPPLGX_cjs.tokenTypeId("NEQ"), "\u2260", "\u2260", 0, 0, 1, 1);
615
- tokenIndex++;
616
- } else if (c0 === 163) {
617
- yield new LexerToken("POUND", chunkG2YPPLGX_cjs.tokenTypeId("POUND"), "\xA3", "\xA3", 0, 0, 1, 1);
618
- tokenIndex++;
619
- } else if (c0 === 8364) {
620
- yield new LexerToken("EURO", chunkG2YPPLGX_cjs.tokenTypeId("EURO"), "\u20AC", "\u20AC", 0, 0, 1, 1);
621
- tokenIndex++;
622
- } else if (c0 === 165) {
623
- yield new LexerToken("YEN", chunkG2YPPLGX_cjs.tokenTypeId("YEN"), "\xA5", "\xA5", 0, 0, 1, 1);
624
- tokenIndex++;
625
- } else if (c0 === 8381) {
626
- yield new LexerToken("RUBLE", chunkG2YPPLGX_cjs.tokenTypeId("RUBLE"), "\u20BD", "\u20BD", 0, 0, 1, 1);
627
- tokenIndex++;
628
- } else if (c0 === 8361) {
629
- yield new LexerToken("WON", chunkG2YPPLGX_cjs.tokenTypeId("WON"), "\u20A9", "\u20A9", 0, 0, 1, 1);
630
- tokenIndex++;
631
- } else if (c0 === 8377) {
632
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B9", "\u20B9", 0, 0, 1, 1);
633
- tokenIndex++;
634
- } else if (c0 === 8378) {
635
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20BA", "\u20BA", 0, 0, 1, 1);
636
- tokenIndex++;
637
- } else if (c0 === 8372) {
638
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B4", "\u20B4", 0, 0, 1, 1);
639
- tokenIndex++;
640
- } else if (c0 === 8362) {
641
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AA", "\u20AA", 0, 0, 1, 1);
642
- tokenIndex++;
643
- } else if (c0 === 8363) {
644
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AB", "\u20AB", 0, 0, 1, 1);
645
- tokenIndex++;
646
- } else if (c0 === 8358) {
647
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20A6", "\u20A6", 0, 0, 1, 1);
648
- tokenIndex++;
649
- } else if (c0 === 8369) {
650
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B1", "\u20B1", 0, 0, 1, 1);
651
- tokenIndex++;
652
- } else if (c0 >= 128) {
653
- yield new LexerToken("IDENT", chunkG2YPPLGX_cjs.tokenTypeId("IDENT"), this.input, this.input, 0, 0, 1, 1);
654
- tokenIndex++;
655
- }
656
- break;
657
- }
658
- }
659
- this._inlineSolveSpans = collectedSpans;
660
- return;
661
- }
662
- const input = this.input;
663
- this.groupingStack.length = 0;
664
- while (this.pos < len) {
665
- const c0 = input.charCodeAt(this.pos);
666
- const cc = _ExpressionLexer.CHAR_CLASS[c0] ?? 0 /* SKIP */;
667
- if (openSpan && c0 === 92 && this.pos + 1 < len && input.charCodeAt(this.pos + 1) === 96) {
668
- this.pos += 2;
669
- continue;
670
- }
671
- switch (cc) {
672
- // ── Whitespace, skip entirely, track newlines ────────────────
673
- case 1 /* WHITESPACE */:
674
- this.pos++;
675
- if (c0 === 10) {
676
- this.line++;
677
- this.lineStartPos = this.pos;
678
- this.groupingStack.length = 0;
679
- } else if (c0 === 13) {
680
- this.line++;
681
- if (this.pos < len && input.charCodeAt(this.pos) === 10) {
682
- this.pos++;
683
- }
684
- this.lineStartPos = this.pos;
685
- this.groupingStack.length = 0;
686
- }
687
- break;
688
- // ── Digit, inline number tokenizer ───────────────────────────
689
- case 2 /* DIGIT */:
690
- yield this.tokenizeNumber();
691
- tokenIndex++;
692
- break;
693
- // ── Alpha / underscore, identifier or keyword ────────────────
694
- case 3 /* ALPHA */: {
695
- const token = this.tokenizeIdentifier();
696
- if (token.type === "INLINE_SOLVE_START") {
697
- openSpan = { startTokenIndex: tokenIndex, startColumn: token.col };
698
- }
699
- yield token;
700
- tokenIndex++;
701
- break;
702
- }
703
- // ── Dot, could be decimal (.5) or DOT token ─────────────────
704
- case 4 /* DOT */:
705
- if (this.pos + 1 < len) {
706
- const nextCc = _ExpressionLexer.CHAR_CLASS[input.charCodeAt(this.pos + 1)] ?? 0 /* SKIP */;
707
- if (nextCc === 2 /* DIGIT */) {
708
- yield this.tokenizeNumber();
709
- } else {
710
- const col = this.pos - this.lineStartPos + 1;
711
- yield new LexerToken("DOT", chunkG2YPPLGX_cjs.tokenTypeId("DOT"), ".", ".", this.pos, 0, this.line, col);
712
- this.pos++;
713
- }
714
- } else {
715
- const col = this.pos - this.lineStartPos + 1;
716
- yield new LexerToken("DOT", chunkG2YPPLGX_cjs.tokenTypeId("DOT"), ".", ".", this.pos, 0, this.line, col);
717
- this.pos++;
718
- }
719
- tokenIndex++;
720
- break;
721
- // ── Operator / punctuation ────────────────────────────────────
722
- case 5 /* OPERATOR */:
723
- yield this.tokenizeOperator();
724
- tokenIndex++;
725
- break;
726
- // ── String literal ────────────────────────────────────────────
727
- case 6 /* QUOTE */:
728
- yield this.tokenizeString();
729
- tokenIndex++;
730
- break;
731
- // ── Comment (# or //) ─────────────────────────────────────────
732
- case 7 /* HASH */:
733
- yield this.tokenizeComment();
734
- tokenIndex++;
735
- break;
736
- // ── Dollar sign $ ─────────────────────────────────────────────
737
- case 8 /* DOLLAR */: {
738
- const col = this.pos - this.lineStartPos + 1;
739
- yield new LexerToken("DOLLAR", chunkG2YPPLGX_cjs.tokenTypeId("DOLLAR"), "$", "$", this.pos, 0, this.line, col);
740
- this.pos++;
741
- tokenIndex++;
742
- break;
743
- }
744
- // ── Backtick ` ───────────────────────────────────────────────
745
- case 11 /* BACKTICK */: {
746
- const col = this.pos - this.lineStartPos + 1;
747
- yield new LexerToken("BACKTICK_OPEN", chunkG2YPPLGX_cjs.tokenTypeId("BACKTICK_OPEN"), "`", "`", this.pos, 0, this.line, col);
748
- this.pos++;
749
- if (openSpan) {
750
- const span = openSpan;
751
- collectedSpans.push({
752
- start: 0,
753
- end: 0,
754
- expression: "",
755
- columnNumber: span.startColumn,
756
- startTokenIndex: span.startTokenIndex,
757
- endTokenIndex: tokenIndex
758
- });
759
- openSpan = null;
760
- }
761
- tokenIndex++;
762
- break;
763
- }
764
- // ── Non-ASCII characters ─────────────────────────────────────
765
- default: {
766
- const col = this.pos - this.lineStartPos + 1;
767
- if (isUnicodeSpace(c0)) {
768
- this.pos++;
769
- if (c0 === 8232 || c0 === 8233 || c0 === 133) {
770
- this.line++;
771
- this.lineStartPos = this.pos;
772
- }
773
- } else if (c0 === 215) {
774
- yield new LexerToken("STAR", chunkG2YPPLGX_cjs.tokenTypeId("STAR"), "\xD7", "\xD7", this.pos, 0, this.line, col);
775
- this.pos++;
776
- tokenIndex++;
777
- } else if (c0 === 247) {
778
- yield new LexerToken("SLASH", chunkG2YPPLGX_cjs.tokenTypeId("SLASH"), "\xF7", "\xF7", this.pos, 0, this.line, col);
779
- this.pos++;
780
- tokenIndex++;
781
- } else if (c0 === 177) {
782
- yield new LexerToken("PLUS_MINUS", chunkG2YPPLGX_cjs.tokenTypeId("PLUS_MINUS"), "\xB1", "\xB1", this.pos, 0, this.line, col);
783
- this.pos++;
784
- tokenIndex++;
785
- } else if (c0 === 8800) {
786
- yield new LexerToken("NEQ", chunkG2YPPLGX_cjs.tokenTypeId("NEQ"), "\u2260", "\u2260", this.pos, 0, this.line, col);
787
- this.pos++;
788
- tokenIndex++;
789
- } else if (c0 === 163) {
790
- yield new LexerToken("POUND", chunkG2YPPLGX_cjs.tokenTypeId("POUND"), "\xA3", "\xA3", this.pos, 0, this.line, col);
791
- this.pos++;
792
- tokenIndex++;
793
- } else if (c0 === 8364) {
794
- yield new LexerToken("EURO", chunkG2YPPLGX_cjs.tokenTypeId("EURO"), "\u20AC", "\u20AC", this.pos, 0, this.line, col);
795
- this.pos++;
796
- tokenIndex++;
797
- } else if (c0 === 165) {
798
- yield new LexerToken("YEN", chunkG2YPPLGX_cjs.tokenTypeId("YEN"), "\xA5", "\xA5", this.pos, 0, this.line, col);
799
- this.pos++;
800
- tokenIndex++;
801
- } else if (c0 === 8381) {
802
- yield new LexerToken("RUBLE", chunkG2YPPLGX_cjs.tokenTypeId("RUBLE"), "\u20BD", "\u20BD", this.pos, 0, this.line, col);
803
- this.pos++;
804
- tokenIndex++;
805
- } else if (c0 === 8361) {
806
- yield new LexerToken("WON", chunkG2YPPLGX_cjs.tokenTypeId("WON"), "\u20A9", "\u20A9", this.pos, 0, this.line, col);
807
- this.pos++;
808
- tokenIndex++;
809
- } else if (c0 === 8377) {
810
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B9", "\u20B9", this.pos, 0, this.line, col);
811
- this.pos++;
812
- tokenIndex++;
813
- } else if (c0 === 8378) {
814
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20BA", "\u20BA", this.pos, 0, this.line, col);
815
- this.pos++;
816
- tokenIndex++;
817
- } else if (c0 === 8372) {
818
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B4", "\u20B4", this.pos, 0, this.line, col);
819
- this.pos++;
820
- tokenIndex++;
821
- } else if (c0 === 8362) {
822
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AA", "\u20AA", this.pos, 0, this.line, col);
823
- this.pos++;
824
- tokenIndex++;
825
- } else if (c0 === 8363) {
826
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20AB", "\u20AB", this.pos, 0, this.line, col);
827
- this.pos++;
828
- tokenIndex++;
829
- } else if (c0 === 8358) {
830
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20A6", "\u20A6", this.pos, 0, this.line, col);
831
- this.pos++;
832
- tokenIndex++;
833
- } else if (c0 === 8369) {
834
- yield new LexerToken("CURRENCY_SYMBOL", chunkG2YPPLGX_cjs.tokenTypeId("CURRENCY_SYMBOL"), "\u20B1", "\u20B1", this.pos, 0, this.line, col);
835
- this.pos++;
836
- tokenIndex++;
837
- } else if (c0 >= 128) {
838
- yield this.tokenizeIdentifier();
839
- tokenIndex++;
840
- } else {
841
- this.pos++;
842
- }
843
- break;
844
- }
845
- }
846
- }
847
- this._inlineSolveSpans = collectedSpans;
848
- }
849
- // ── Inline number tokenizer ────────────────────────────────────────────
850
- /**
851
- * Character-by-character number parsing.
852
- *
853
- * Supports: integers, floats, scientific notation (1.5e10, 1.5e-10),
854
- * hex (0xFF), binary (0b1010), octal (0o17), BigInt suffix (123n),
855
- * thousands separators (1,234 or 1.234.567).
856
- *
857
- * Returns a LexerToken and advances `this.pos` past the number.
858
- */
859
- tokenizeNumber() {
860
- const input = this.input;
861
- const len = this.len;
862
- let pos = this.pos;
863
- const start = pos;
864
- const startCol = pos - this.lineStartPos + 1;
865
- let cc;
866
- if (input.charCodeAt(pos) === 48 && pos + 1 < len) {
867
- const next = input.charCodeAt(pos + 1);
868
- if (next === 120 || next === 88) {
869
- pos += 2;
870
- while (pos < len && (cc = input.charCodeAt(pos), cc >= 48 && cc <= 57 || cc >= 65 && cc <= 70 || cc >= 97 && cc <= 102)) {
871
- pos++;
872
- }
873
- const text2 = input.slice(start, pos);
874
- this.pos = pos;
875
- return new LexerToken("NUMBER", chunkG2YPPLGX_cjs.tokenTypeId("NUMBER"), text2, text2, start, 0, this.line, startCol);
876
- }
877
- if (next === 98 || next === 66) {
878
- pos += 2;
879
- while (pos < len && (cc = input.charCodeAt(pos), cc === 48 || cc === 49)) {
880
- pos++;
881
- }
882
- const text2 = input.slice(start, pos);
883
- this.pos = pos;
884
- return new LexerToken("NUMBER", chunkG2YPPLGX_cjs.tokenTypeId("NUMBER"), text2, text2, start, 0, this.line, startCol);
885
- }
886
- if (next === 111 || next === 79) {
887
- pos += 2;
888
- while (pos < len && (cc = input.charCodeAt(pos), cc >= 48 && cc <= 55)) {
889
- pos++;
890
- }
891
- const text2 = input.slice(start, pos);
892
- this.pos = pos;
893
- return new LexerToken("NUMBER", chunkG2YPPLGX_cjs.tokenTypeId("NUMBER"), text2, text2, start, 0, this.line, startCol);
894
- }
895
- }
896
- let hasIntPart = false;
897
- while (pos < len && (cc = input.charCodeAt(pos), cc >= 48 && cc <= 57)) {
898
- hasIntPart = true;
899
- pos++;
900
- }
901
- while (hasIntPart && pos < len && (input.charCodeAt(pos) === 44 || input.charCodeAt(pos) === 46)) {
902
- if (input.charCodeAt(pos) === 44 && this.groupingStack.length > 0 && this.groupingStack[this.groupingStack.length - 1]) {
903
- break;
904
- }
905
- if (pos + 4 <= len) {
906
- const d1 = input.charCodeAt(pos + 1);
907
- const d2 = input.charCodeAt(pos + 2);
908
- const d3 = input.charCodeAt(pos + 3);
909
- const d4 = pos + 4 < len ? input.charCodeAt(pos + 4) : -1;
910
- const isGroupOfExactlyThree = !(d4 >= 48 && d4 <= 57);
911
- if (d1 >= 48 && d1 <= 57 && d2 >= 48 && d2 <= 57 && d3 >= 48 && d3 <= 57 && isGroupOfExactlyThree) {
912
- pos += 4;
913
- hasIntPart = true;
914
- continue;
915
- }
916
- }
917
- break;
918
- }
919
- let hasDecimal = false;
920
- if (pos < len && input.charCodeAt(pos) === 46) {
921
- if (pos + 1 < len) {
922
- const nextCc = input.charCodeAt(pos + 1);
923
- if (nextCc >= 48 && nextCc <= 57) {
924
- hasDecimal = true;
925
- pos++;
926
- while (pos < len && (cc = input.charCodeAt(pos), cc >= 48 && cc <= 57)) {
927
- pos++;
928
- }
929
- }
930
- }
931
- }
932
- let hasExponent = false;
933
- if (pos < len) {
934
- const ec = input.charCodeAt(pos);
935
- if (ec === 101 || ec === 69) {
936
- if (pos + 1 < len) {
937
- const next = input.charCodeAt(pos + 1);
938
- if (next >= 48 && next <= 57 || next === 43 || next === 45) {
939
- hasExponent = true;
940
- pos++;
941
- if (next === 43 || next === 45) pos++;
942
- while (pos < len && (cc = input.charCodeAt(pos), cc >= 48 && cc <= 57)) {
943
- pos++;
944
- }
945
- }
946
- }
947
- }
948
- }
949
- if (pos < len && input.charCodeAt(pos) === 110) {
950
- if (hasIntPart && !hasDecimal && !hasExponent) {
951
- pos++;
952
- const text2 = input.slice(start, pos);
953
- this.pos = pos;
954
- return new LexerToken("BIGINT", chunkG2YPPLGX_cjs.tokenTypeId("BIGINT"), text2, text2, start, 0, this.line, startCol);
955
- }
956
- }
957
- const text = input.slice(start, pos);
958
- this.pos = pos;
959
- return new LexerToken("NUMBER", chunkG2YPPLGX_cjs.tokenTypeId("NUMBER"), text, text, start, 0, this.line, startCol);
960
- }
961
- // ── Inline identifier / keyword tokenizer ──────────────────────────────
962
- /**
963
- * Reads [a-zA-Z_][a-zA-Z0-9_]* and resolves to:
964
- * - A unit type (via knownUnits, case-sensitive)
965
- * - A keyword type (via locale keywordMap, case-insensitive)
966
- * - IDENT if none of the above
967
- *
968
- * Multi-word phrases (e.g., "to the power of") are handled by the
969
- * TokenNormalizer post-lexer pass, not the lexer.
970
- */
971
- tokenizeIdentifier() {
972
- const input = this.input;
973
- const len = this.len;
974
- let pos = this.pos;
975
- const start = pos;
976
- const startCol = pos - this.lineStartPos + 1;
977
- let cc;
978
- while (pos < len && (cc = input.charCodeAt(pos), cc >= 48 && cc <= 57 || // 0-9
979
- cc >= 65 && cc <= 90 || // A-Z
980
- cc >= 97 && cc <= 122 || // a-z
981
- cc === 95 || // _
982
- cc >= 128 && !isUnicodeSpace(cc))) {
983
- pos++;
984
- }
985
- const identText = input.slice(start, pos);
986
- const identLower = identText.toLowerCase();
987
- if (identLower === "s" && pos < len && input.charCodeAt(pos) === 96) {
988
- pos++;
989
- this.pos = pos;
990
- const fullText = input.slice(start, pos);
991
- return new LexerToken("INLINE_SOLVE_START", chunkG2YPPLGX_cjs.tokenTypeId("INLINE_SOLVE_START"), fullText, fullText, start, 0, this.line, startCol);
992
- }
993
- const isKnownUnit = this.mergedUnits.has(identText);
994
- if (isKnownUnit) {
995
- if (!this.isFollowedByLParen(pos)) {
996
- this.pos = pos;
997
- return new LexerToken("UNIT", chunkG2YPPLGX_cjs.tokenTypeId("UNIT"), identText, identText, start, 0, this.line, startCol);
998
- }
999
- }
1000
- const localeKwType = this.mergedKeywords.get(identLower);
1001
- if (localeKwType) {
1002
- this.pos = pos;
1003
- return new LexerToken(localeKwType, chunkG2YPPLGX_cjs.tokenTypeId(localeKwType), identText, identText, start, 0, this.line, startCol);
1004
- }
1005
- this.pos = pos;
1006
- return new LexerToken("IDENT", chunkG2YPPLGX_cjs.tokenTypeId("IDENT"), identText, identText, start, 0, this.line, startCol);
1007
- }
1008
- /**
1009
- * Peek past in-expression whitespace (space, tab) from `pos` to check
1010
- * if the next significant character is '('.
1011
- */
1012
- isFollowedByLParen(pos) {
1013
- const len = this.len;
1014
- let lookPos = pos;
1015
- while (lookPos < len) {
1016
- const cc = this.input.charCodeAt(lookPos);
1017
- if (cc === 40) return true;
1018
- if (cc !== 32 && cc !== 9) break;
1019
- lookPos++;
1020
- }
1021
- return false;
1022
- }
1023
- // ── Inline operator tokenizer ─────────────────────────────────────────
1024
- /**
1025
- * Whether the `(` at `parenPos` opens a function call rather than a bare
1026
- * grouping, deciding whether a comma inside it is a separator or a thousands
1027
- * group (see {@link groupingStack}).
1028
- *
1029
- * It is a call when the nearest non-whitespace character before it belongs to
1030
- * the value the call applies to: a closing `)`/`]` (a call on a result), or an
1031
- * IDENTIFIER (`rgb(`, `vec2(`). A run of digits alone is a number, not an
1032
- * identifier, so `2(1,000)` is implicit multiplication over the grouping
1033
- * `(1,000)`, not a call, while `vec2(` and `atan2(` (identifiers that end in a
1034
- * digit) are calls. A `(` after an operator, a comma, or the line start is a
1035
- * grouping.
1036
- */
1037
- precededByCallTarget(parenPos) {
1038
- const input = this.input;
1039
- const start = this.lineStartPos;
1040
- let i = parenPos - 1;
1041
- while (i >= start && (input.charCodeAt(i) === 32 || input.charCodeAt(i) === 9)) i--;
1042
- if (i < start) return false;
1043
- const c = input.charCodeAt(i);
1044
- const isWord = (ch) => ch >= 48 && ch <= 57 || ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch === 95;
1045
- const isAlpha = (ch) => ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch === 95;
1046
- if (!isWord(c)) return false;
1047
- const wordEnd = i + 1;
1048
- let hasAlpha = false;
1049
- while (i >= start) {
1050
- const ch = input.charCodeAt(i);
1051
- if (!isWord(ch)) break;
1052
- if (isAlpha(ch)) hasAlpha = true;
1053
- i--;
1054
- }
1055
- if (!hasAlpha) return false;
1056
- const word = input.slice(i + 1, wordEnd).toLowerCase();
1057
- const keywordType = this.mergedKeywords.get(word);
1058
- return keywordType === void 0 || keywordType === "FUNC";
1059
- }
1060
- /**
1061
- * Reads an operator/punctuation token.
1062
- * Handles two-char operators (==, !=, >=, <=, **) and the special
1063
- * cases << (LSHIFT) and >> (RSHIFT).
1064
- */
1065
- tokenizeOperator() {
1066
- const input = this.input;
1067
- const pos = this.pos;
1068
- const col = pos - this.lineStartPos + 1;
1069
- const c0 = input.charCodeAt(pos);
1070
- const len = this.len;
1071
- if (pos + 1 < len) {
1072
- const c1 = input.charCodeAt(pos + 1);
1073
- const secondMap = TWO_CHAR_OPS[c0];
1074
- if (secondMap) {
1075
- const twoCharType = secondMap[c1];
1076
- if (twoCharType) {
1077
- const text2 = input.slice(pos, pos + 2);
1078
- this.pos = pos + 2;
1079
- return new LexerToken(twoCharType, chunkG2YPPLGX_cjs.tokenTypeId(twoCharType), text2, text2, pos, 0, this.line, col);
1080
- }
1081
- }
1082
- if (c0 === 47 && c1 === 47) {
1083
- let commentPos = pos + 2;
1084
- while (commentPos < len) {
1085
- const cc = input.charCodeAt(commentPos);
1086
- if (cc === 10 || cc === 13) break;
1087
- commentPos++;
1088
- }
1089
- const text2 = input.slice(pos, commentPos);
1090
- this.pos = commentPos;
1091
- return new LexerToken("COMMENT", chunkG2YPPLGX_cjs.tokenTypeId("COMMENT"), text2, text2, pos, 0, this.line, col);
1092
- }
1093
- if (c0 === 60 && c1 === 60) {
1094
- this.pos = pos + 2;
1095
- return new LexerToken("LSHIFT", chunkG2YPPLGX_cjs.tokenTypeId("LSHIFT"), "<<", "<<", pos, 0, this.line, col);
1096
- }
1097
- if (c0 === 62 && c1 === 62) {
1098
- if (input.charCodeAt(pos + 2) === 62) {
1099
- this.pos = pos + 3;
1100
- return new LexerToken("URSHIFT", chunkG2YPPLGX_cjs.tokenTypeId("URSHIFT"), ">>>", ">>>", pos, 0, this.line, col);
1101
- }
1102
- this.pos = pos + 2;
1103
- return new LexerToken("RSHIFT", chunkG2YPPLGX_cjs.tokenTypeId("RSHIFT"), ">>", ">>", pos, 0, this.line, col);
1104
- }
1105
- if (this.hasPluginOps) {
1106
- const pluginInner = this.pluginOperators.get(c0);
1107
- if (pluginInner) {
1108
- const pluginType = pluginInner.get(c1);
1109
- if (pluginType) {
1110
- const text2 = input.slice(pos, pos + 2);
1111
- this.pos = pos + 2;
1112
- return new LexerToken(pluginType, chunkG2YPPLGX_cjs.tokenTypeId(pluginType), text2, text2, pos, 0, this.line, col);
1113
- }
1114
- }
1115
- }
1116
- }
1117
- this.pos = pos + 1;
1118
- if (c0 === 91) {
1119
- this.groupingStack.push(true);
1120
- } else if (c0 === 40) {
1121
- this.groupingStack.push(this.precededByCallTarget(pos));
1122
- } else if (c0 === 41 || c0 === 93) {
1123
- if (this.groupingStack.length > 0) this.groupingStack.pop();
1124
- }
1125
- const opType = OP_MAP[c0];
1126
- const text = input.charAt(pos);
1127
- return new LexerToken(opType || "ERROR", chunkG2YPPLGX_cjs.tokenTypeId(opType || "ERROR"), text, text, pos, 0, this.line, col);
1128
- }
1129
- // ── String literal tokenizer ──────────────────────────────────────────
1130
- /**
1131
- * Reads a double-quoted string literal. Supports backslash escapes.
1132
- *
1133
- * `text` is the raw source slice, quotes included, because that is what
1134
- * `offset` + `text.length` has to span for a host to underline the literal.
1135
- * `value` is the PAYLOAD, quotes excluded, because that is what
1136
- * `PUSH_STRING` puts into the Value.
1137
- *
1138
- * The two used to be the same string. `"abc"` carried the five characters
1139
- * `"abc"` as its value, which was invisible on screen (the formatter prints
1140
- * the payload raw and the retained quotes landed where a display would have
1141
- * put them back) and not invisible anywhere else: `parseFloat('"5"')` is NaN
1142
- * whatever the digits say, so `"5" + 5` answered 5.
1143
- *
1144
- * An unterminated literal is an error rather than a string that happens to
1145
- * reach the end of the line. It used to return what it had, so `"abc` and
1146
- * `"abc"` were indistinguishable by payload once the quotes were stripped,
1147
- * which is the other half of why they are stripped here rather than later.
1148
- */
1149
- tokenizeString() {
1150
- const input = this.input;
1151
- const len = this.len;
1152
- const start = this.pos;
1153
- const startCol = start - this.lineStartPos + 1;
1154
- let pos = start + 1;
1155
- let lineBreaks = 0;
1156
- while (pos < len) {
1157
- const c0 = input.charCodeAt(pos);
1158
- if (c0 === 34) {
1159
- pos++;
1160
- const text = input.slice(start, pos);
1161
- const value = input.slice(start + 1, pos - 1);
1162
- this.pos = pos;
1163
- return new LexerToken("STRING", chunkG2YPPLGX_cjs.tokenTypeId("STRING"), value, text, start, lineBreaks, this.line, startCol);
1164
- }
1165
- if (c0 === 92 && pos + 1 < len) {
1166
- pos += 2;
1167
- continue;
1168
- }
1169
- if (c0 === 10) {
1170
- this.line++;
1171
- this.lineStartPos = pos + 1;
1172
- lineBreaks++;
1173
- }
1174
- pos++;
1175
- }
1176
- this.pos = pos;
1177
- throw chunkMIGXCBXT_cjs.ErrorFactory.parsing(
1178
- "UNTERMINATED_STRING",
1179
- `Unterminated string literal: ${input.slice(start, pos)}`,
1180
- { literal: input.slice(start, pos), offset: start }
1181
- );
1182
- }
1183
- // ── Markdown line scanner (Phase B) ───────────────────────────────────
1184
- /**
1185
- * L1 expression gating: quickly determine if a line contains any
1186
- * characters that indicate an expression (digits, operators, currency,
1187
- * backticks, parentheses, etc.).
1188
- *
1189
- * Pure prose lines (e.g., "The quick brown fox jumps over the lazy dog")
1190
- * return false and can be skipped without full tokenization (L2).
1191
- *
1192
- * This is a fast character-by-character scan that stops at the first
1193
- * expression indicator. Called once per line in classifyFromPositions().
1194
- */
1195
- static hasExpressionIndicators(input, start, end) {
1196
- const indicatorCodes = EXPRESSION_INDICATOR_CODES;
1197
- for (let i = start; i < end; i++) {
1198
- const cc = input.charCodeAt(i);
1199
- if (indicatorCodes.has(cc)) return true;
1200
- if (cc >= 128) {
1201
- if (cc === 215 || cc === 247 || cc === 8800 || cc === 163 || cc === 8364 || cc === 165 || cc === 8381 || cc === 8361) {
1202
- return true;
1203
- }
1204
- }
1205
- }
1206
- return false;
1207
- }
1208
- /**
1209
- * Classify a line by its character positions within this.input.
1210
- * Reads directly from this.input using start/end boundaries.
1211
- * DOES NOT modify this.pos, purely a read-only classifier.
1212
- */
1213
- /**
1214
- * Advance past the whitespace after a list marker, and past a task-item
1215
- * checkbox if one follows.
1216
- *
1217
- * The checkbox is included because it is markup by the same argument the
1218
- * marker is, and because leaving it stopped the line dead: `- [ ] 100 + 20`
1219
- * lexed `[ ]` as a matrix literal and reported that a matrix cannot be
1220
- * empty, which tells a user writing a to-do list nothing they can act on.
1221
- *
1222
- * @param from - Offset just past the marker character.
1223
- * @param end - Line end, never read past.
1224
- * @returns Offset of the first evaluable character.
1225
- */
1226
- skipMarkerGap(from, end) {
1227
- const input = this.input;
1228
- let pos = from;
1229
- while (pos < end && (input.charCodeAt(pos) === 32 || input.charCodeAt(pos) === 9)) pos++;
1230
- if (pos + 2 < end && input.charCodeAt(pos) === 91 && input.charCodeAt(pos + 2) === 93) {
1231
- let after = pos + 3;
1232
- while (after < end && (input.charCodeAt(after) === 32 || input.charCodeAt(after) === 9)) after++;
1233
- if (after > pos + 3) return after;
1234
- }
1235
- return pos;
1236
- }
1237
- /**
1238
- * The end offset (exclusive) of a `#hex` colour literal starting at `hashPos`,
1239
- * or -1 if the run there is not one. A colour is `#` followed by EXACTLY 3, 4,
1240
- * 6 or 8 hex digits (the CSS forms `#rgb`/`#rgba`/`#rrggbb`/`#rrggbbaa`) and
1241
- * then a boundary, not a longer word or number. This is the one predicate that
1242
- * carves colours out of the two things `#` otherwise means, a markdown heading
1243
- * at line start and a comment mid-line, and it is pure character logic so line
1244
- * classification stays vocabulary-independent. Examples: `#f00`, `#ff0000`,
1245
- * `#deadbeef` match; `# Heading` (space), `#tag`/`#todo` (non-hex letter),
1246
- * `#12345` (length 5), `#ff0000zz` (trailing word) do not.
1247
- */
1248
- matchHexColourEnd(hashPos, end) {
1249
- const input = this.input;
1250
- let p = hashPos + 1;
1251
- let n = 0;
1252
- while (p < end) {
1253
- const c = input.charCodeAt(p);
1254
- const isHex = c >= 48 && c <= 57 || c >= 65 && c <= 70 || c >= 97 && c <= 102;
1255
- if (!isHex) break;
1256
- n++;
1257
- p++;
1258
- }
1259
- if (n !== 3 && n !== 4 && n !== 6 && n !== 8) return -1;
1260
- if (p < end) {
1261
- const c = input.charCodeAt(p);
1262
- const isWord = c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95;
1263
- if (isWord) return -1;
1264
- }
1265
- return p;
1266
- }
1267
- classifyFromPositions(start, end) {
1268
- const len = end;
1269
- if (start >= len) {
1270
- return { type: "empty", skip: true, hasInlineSolve: false };
1271
- }
1272
- const input = this.input;
1273
- let pos = start;
1274
- while (pos < len) {
1275
- const cc = input.charCodeAt(pos);
1276
- if (cc !== 32 && cc !== 9) break;
1277
- pos++;
1278
- }
1279
- if (pos >= len) {
1280
- return { type: "empty", skip: true, hasInlineSolve: false };
1281
- }
1282
- const c0 = input.charCodeAt(pos);
1283
- let hasInline;
1284
- if (c0 === 35) {
1285
- if (this.matchHexColourEnd(pos, len) !== -1) {
1286
- if (hasInline === void 0) {
1287
- const idx = input.indexOf("s`", pos);
1288
- hasInline = idx !== -1 && idx < len;
1289
- }
1290
- return { type: "expression", skip: false, hasInlineSolve: hasInline };
1291
- }
1292
- let hashCount = 1;
1293
- while (pos + hashCount < len && input.charCodeAt(pos + hashCount) === 35) {
1294
- hashCount++;
1295
- }
1296
- if (hashCount <= 6 && pos + hashCount < len && input.charCodeAt(pos + hashCount) === 32) {
1297
- return { type: "heading", skip: true, hasInlineSolve: false };
1298
- }
1299
- return { type: "heading", skip: true, hasInlineSolve: false };
1300
- }
1301
- if (c0 === 62) {
1302
- if (pos + 1 < len && input.charCodeAt(pos + 1) === 32) {
1303
- return { type: "blockquote", skip: true, hasInlineSolve: false };
1304
- }
1305
- }
1306
- if (c0 === 96 && pos + 2 < len && input.charCodeAt(pos + 1) === 96 && input.charCodeAt(pos + 2) === 96) {
1307
- return { type: "code_fence", skip: true, hasInlineSolve: false };
1308
- }
1309
- if (c0 === 126 && pos + 2 < len && input.charCodeAt(pos + 1) === 126 && input.charCodeAt(pos + 2) === 126) {
1310
- return { type: "code_fence", skip: true, hasInlineSolve: false };
1311
- }
1312
- if (c0 === 36 && pos + 1 < len && input.charCodeAt(pos + 1) === 36) {
1313
- return { type: "math_fence", skip: true, hasInlineSolve: false };
1314
- }
1315
- if (c0 === 45 || c0 === 42 || c0 === 95) {
1316
- let count = 1;
1317
- while (pos + count < len && input.charCodeAt(pos + count) === c0) {
1318
- count++;
1319
- }
1320
- if (count >= 3) {
1321
- let trailPos = pos + count;
1322
- while (trailPos < len && (input.charCodeAt(trailPos) === 32 || input.charCodeAt(trailPos) === 9)) {
1323
- trailPos++;
1324
- }
1325
- if (trailPos >= len) {
1326
- return { type: "hr", skip: true, hasInlineSolve: false };
1327
- }
1328
- }
1329
- }
1330
- if ((c0 === 45 || c0 === 42 || c0 === 43) && pos + 1 < len && input.charCodeAt(pos + 1) === 32) {
1331
- if (hasInline === void 0) {
1332
- const idx = input.indexOf("s`", pos);
1333
- hasInline = idx !== -1 && idx < len;
1334
- }
1335
- return { type: "list", skip: false, hasInlineSolve: hasInline, contentOffset: this.skipMarkerGap(pos + 1, len) };
1336
- }
1337
- if (c0 >= 48 && c0 <= 57) {
1338
- let digitPos = pos;
1339
- while (digitPos < len && input.charCodeAt(digitPos) >= 48 && input.charCodeAt(digitPos) <= 57) {
1340
- digitPos++;
1341
- }
1342
- if (digitPos < len && input.charCodeAt(digitPos) === 46) {
1343
- if (digitPos + 1 < len && input.charCodeAt(digitPos + 1) === 32) {
1344
- if (hasInline === void 0) {
1345
- const idx = input.indexOf("s`", pos);
1346
- hasInline = idx !== -1 && idx < len;
1347
- }
1348
- return { type: "list", skip: false, hasInlineSolve: hasInline, contentOffset: this.skipMarkerGap(digitPos + 1, len) };
1349
- }
1350
- }
1351
- }
1352
- if (c0 === 124) {
1353
- let tPos = pos + 1;
1354
- while (tPos < len) {
1355
- const tc = input.charCodeAt(tPos);
1356
- if (tc !== 45 && tc !== 58 && tc !== 124 && tc !== 32 && tc !== 9 && tc !== 13) break;
1357
- tPos++;
1358
- }
1359
- if (tPos >= len) {
1360
- return { type: "table_separator", skip: true, hasInlineSolve: false };
1361
- }
1362
- }
1363
- if (c0 === 91 && pos + 1 < len && input.charCodeAt(pos + 1) === 91) {
1364
- const closePos = input.indexOf("]]", pos + 2);
1365
- if (closePos !== -1 && closePos < len) {
1366
- let trailPos = closePos + 2;
1367
- while (trailPos < len && (input.charCodeAt(trailPos) === 32 || input.charCodeAt(trailPos) === 9)) {
1368
- trailPos++;
1369
- }
1370
- if (trailPos >= len) {
1371
- return { type: "wikilink", skip: true, hasInlineSolve: false };
1372
- }
1373
- }
1374
- }
1375
- if (c0 === 33 && pos + 2 < len && input.charCodeAt(pos + 1) === 91 && input.charCodeAt(pos + 2) === 91) {
1376
- const closePos = input.indexOf("]]", pos + 3);
1377
- if (closePos !== -1 && closePos < len) {
1378
- let trailPos = closePos + 2;
1379
- while (trailPos < len && (input.charCodeAt(trailPos) === 32 || input.charCodeAt(trailPos) === 9)) {
1380
- trailPos++;
1381
- }
1382
- if (trailPos >= len) {
1383
- return { type: "wikilink", skip: true, hasInlineSolve: false };
1384
- }
1385
- }
1386
- }
1387
- if (c0 === 47 && pos + 1 < len && input.charCodeAt(pos + 1) === 47) {
1388
- return { type: "comment", skip: true, hasInlineSolve: false };
1389
- }
1390
- if (c0 === 62) {
1391
- let trail = pos + 1;
1392
- while (trail < len && (input.charCodeAt(trail) === 32 || input.charCodeAt(trail) === 9)) trail++;
1393
- if (trail >= len) return { type: "blockquote", skip: true, hasInlineSolve: false };
1394
- }
1395
- if (c0 === 45 || c0 === 42 || c0 === 43) {
1396
- let trail = pos + 1;
1397
- while (trail < len && (input.charCodeAt(trail) === 32 || input.charCodeAt(trail) === 9)) trail++;
1398
- if (trail >= len) return { type: "list", skip: false, hasInlineSolve: false };
1399
- }
1400
- if (hasInline === void 0) {
1401
- const idx = input.indexOf("s`", pos);
1402
- hasInline = idx !== -1 && idx < len;
1403
- }
1404
- if (!hasInline) {
1405
- let onlySkippable = true;
1406
- for (let i = pos; i < len; i++) {
1407
- const code = input.charCodeAt(i);
1408
- if (code >= 128 || _ExpressionLexer.CHAR_CLASS[code] > 1 /* WHITESPACE */) {
1409
- onlySkippable = false;
1410
- break;
1411
- }
1412
- }
1413
- if (onlySkippable) {
1414
- return { type: "empty", skip: true, hasInlineSolve: false };
1415
- }
1416
- }
1417
- return { type: "expression", skip: false, hasInlineSolve: hasInline };
1418
- }
1419
- /**
1420
- * Classify a single line of markdown text.
1421
- */
1422
- classifyLine(lineText) {
1423
- const savedInput = this.input;
1424
- const savedLen = this.len;
1425
- const savedPos = this.pos;
1426
- this.input = lineText;
1427
- this.len = lineText.length;
1428
- this.pos = 0;
1429
- const result = this.classifyFromPositions(0, lineText.length);
1430
- this.input = savedInput;
1431
- this.len = savedLen;
1432
- this.pos = savedPos;
1433
- return result;
1434
- }
1435
- /**
1436
- * Every keyword this lexer currently recognizes, locale keywords
1437
- * (`pi`, `sqrt`, `convert`, ...) merged with any plugin-contributed ones
1438
- * from `registerVocabulary()` (e.g. a package's custom keywords), mapped to
1439
- * the token type they lex to. A snapshot copy, not a live reference
1440
- * mutating the return value has no effect on the lexer.
1441
- */
1442
- getKeywords() {
1443
- return Object.fromEntries(this.mergedKeywords);
1444
- }
1445
- /**
1446
- * Find all inline solve markers in a line with precise coordinate mapping.
1447
- */
1448
- findInlineSolves(lineText) {
1449
- const results = [];
1450
- const len = lineText.length;
1451
- let pos = 0;
1452
- while (pos < len) {
1453
- const sPos = lineText.indexOf("s`", pos);
1454
- if (sPos === -1) break;
1455
- const exprStart = sPos + 2;
1456
- let exprEnd = exprStart;
1457
- while (exprEnd < len) {
1458
- const cc = lineText.charCodeAt(exprEnd);
1459
- if (cc === 92 && exprEnd + 1 < len) {
1460
- exprEnd += 2;
1461
- continue;
1462
- }
1463
- if (cc === 96) break;
1464
- exprEnd++;
1465
- }
1466
- if (exprEnd >= len) {
1467
- exprEnd = len;
1468
- }
1469
- const expression = lineText.slice(exprStart, exprEnd);
1470
- const end = exprEnd < len ? exprEnd + 1 : exprEnd;
1471
- results.push({
1472
- start: sPos,
1473
- end,
1474
- expression,
1475
- columnNumber: sPos + 1
1476
- });
1477
- pos = end;
1478
- }
1479
- return results;
1480
- }
1481
- // ── Comment tokenizer ─────────────────────────────────────────────────
1482
- /**
1483
- * Reads a comment: # to end of line, or // to end of line.
1484
- */
1485
- tokenizeComment() {
1486
- const input = this.input;
1487
- const len = this.len;
1488
- const start = this.pos;
1489
- const startCol = start - this.lineStartPos + 1;
1490
- if (input.charCodeAt(start) === 35) {
1491
- const hexEnd = this.matchHexColourEnd(start, len);
1492
- if (hexEnd !== -1) {
1493
- const text2 = input.slice(start, hexEnd);
1494
- this.pos = hexEnd;
1495
- return new LexerToken("HEX_COLOUR", chunkG2YPPLGX_cjs.tokenTypeId("HEX_COLOUR"), text2, text2, start, 0, this.line, startCol);
1496
- }
1497
- const first = input.charCodeAt(start + 1);
1498
- const isLetter = first >= 65 && first <= 90 || first >= 97 && first <= 122;
1499
- if (isLetter) {
1500
- let tagEnd = start + 2;
1501
- while (tagEnd < len) {
1502
- const c = input.charCodeAt(tagEnd);
1503
- const isTagChar = c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95 || c === 45;
1504
- if (!isTagChar) break;
1505
- tagEnd++;
1506
- }
1507
- const name = input.slice(start + 1, tagEnd);
1508
- this.pos = tagEnd;
1509
- return new LexerToken("TAG", chunkG2YPPLGX_cjs.tokenTypeId("TAG"), name, name, start, 0, this.line, startCol);
1510
- }
1511
- }
1512
- let pos = this.pos;
1513
- if (pos + 1 < len && input.charCodeAt(pos + 1) === 47) {
1514
- pos += 2;
1515
- } else {
1516
- pos++;
1517
- }
1518
- while (pos < len) {
1519
- const c0 = input.charCodeAt(pos);
1520
- if (c0 === 10 || c0 === 13) break;
1521
- pos++;
1522
- }
1523
- const text = input.slice(start, pos);
1524
- this.pos = pos;
1525
- return new LexerToken("COMMENT", chunkG2YPPLGX_cjs.tokenTypeId("COMMENT"), text, text, start, 0, this.line, startCol);
1526
- }
1527
- };
1528
- _ExpressionLexer.CHAR_CLASS = buildCharClassTable();
1529
- var ExpressionLexer = _ExpressionLexer;
1530
-
1531
- exports.ExpressionLexer = ExpressionLexer;
1532
- exports.LexerToken = LexerToken;
1533
- //# sourceMappingURL=chunk-YJHY7CMN.cjs.map
1534
- //# sourceMappingURL=chunk-YJHY7CMN.cjs.map