solve-engine 1.0.0-beta.7 → 1.0.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 (205) hide show
  1. package/dist/{BytecodeBuilder-3egMyuDi.d.cts → BytecodeBuilder-B0xskcv5.d.cts} +2 -1
  2. package/dist/{BytecodeBuilder-3egMyuDi.d.ts → BytecodeBuilder-B0xskcv5.d.ts} +2 -1
  3. package/dist/{Configuration-fVpd-HC-.d.cts → Configuration-B-G5gTRn.d.cts} +107 -29
  4. package/dist/{Configuration-fVpd-HC-.d.ts → Configuration-B-G5gTRn.d.ts} +107 -29
  5. package/dist/{EngineError-DvPSnhZi.d.cts → EngineError-LU7W7AgI.d.cts} +96 -16
  6. package/dist/{EngineError-DvPSnhZi.d.ts → EngineError-LU7W7AgI.d.ts} +96 -16
  7. package/dist/{Lexer-W9MBOP0V.d.ts → Lexer-BN5mt30n.d.ts} +16 -0
  8. package/dist/{Lexer-Cfm79Dak.d.cts → Lexer-D78E2yDW.d.cts} +16 -0
  9. package/dist/{PackageRegistry-CjDt-Jy_.d.ts → PackageRegistry-DFeINv2O.d.ts} +54 -13
  10. package/dist/{PackageRegistry-pHtKythi.d.cts → PackageRegistry-u2zdfFaj.d.cts} +54 -13
  11. package/dist/{Parselet-DEdF9I7n.d.ts → Parselet-BaySkMV3.d.ts} +37 -5
  12. package/dist/{Parselet-Cu0bLSis.d.cts → Parselet-DuI1Pjiq.d.cts} +37 -5
  13. package/dist/{ScopeManager-CKfQtl7l.d.cts → ScopeManager-B6GzdhVG.d.cts} +75 -6
  14. package/dist/{ScopeManager-B5k0nk05.d.ts → ScopeManager-udv4Twwq.d.ts} +75 -6
  15. package/dist/{VMCheckpoints-BmDwIXgK.d.ts → VMCheckpoints-BiaIlOOY.d.ts} +4 -4
  16. package/dist/{VMCheckpoints-CqFuLwrT.d.cts → VMCheckpoints-DwLjivM7.d.cts} +4 -4
  17. package/dist/{Value-KtAQNHur.d.cts → Value-CXJqDH9J.d.cts} +5 -2
  18. package/dist/{Value-KtAQNHur.d.ts → Value-CXJqDH9J.d.ts} +5 -2
  19. package/dist/{chunk-CSG5XVNJ.cjs → chunk-3AFRJYP4.cjs} +556 -414
  20. package/dist/chunk-3AFRJYP4.cjs.map +1 -0
  21. package/dist/chunk-3BOK2LDK.js +17 -0
  22. package/dist/chunk-3BOK2LDK.js.map +1 -0
  23. package/dist/{chunk-6RDSQURE.js → chunk-3D7V24DG.js} +57 -6
  24. package/dist/chunk-3D7V24DG.js.map +1 -0
  25. package/dist/{chunk-MEOHSQEH.js → chunk-3LAEG75D.js} +47 -15
  26. package/dist/chunk-3LAEG75D.js.map +1 -0
  27. package/dist/{chunk-P75775WC.js → chunk-3VNGREMU.js} +118 -41
  28. package/dist/chunk-3VNGREMU.js.map +1 -0
  29. package/dist/{chunk-4AVD7NZW.cjs → chunk-4B2CNWQU.cjs} +13 -7
  30. package/dist/chunk-4B2CNWQU.cjs.map +1 -0
  31. package/dist/{chunk-6GCKCWLB.js → chunk-526PMQOA.js} +126 -69
  32. package/dist/chunk-526PMQOA.js.map +1 -0
  33. package/dist/{chunk-2CS6OMZK.js → chunk-5F4C26RU.js} +8 -5
  34. package/dist/chunk-5F4C26RU.js.map +1 -0
  35. package/dist/{chunk-M4N5GA5Z.cjs → chunk-5KMIY374.cjs} +57 -6
  36. package/dist/chunk-5KMIY374.cjs.map +1 -0
  37. package/dist/{chunk-R24DI24X.cjs → chunk-5LI5EPGJ.cjs} +6 -5
  38. package/dist/chunk-5LI5EPGJ.cjs.map +1 -0
  39. package/dist/{chunk-BAMZT3GL.js → chunk-5WVP4YHP.js} +939 -134
  40. package/dist/chunk-5WVP4YHP.js.map +1 -0
  41. package/dist/{chunk-MZOVP3WI.cjs → chunk-6KFYJ6TD.cjs} +3 -2
  42. package/dist/chunk-6KFYJ6TD.cjs.map +1 -0
  43. package/dist/{chunk-BXKJLM5R.cjs → chunk-6WFMPTGB.cjs} +972 -636
  44. package/dist/chunk-6WFMPTGB.cjs.map +1 -0
  45. package/dist/{chunk-2MV4HBKC.cjs → chunk-A2N2GFCG.cjs} +10 -10
  46. package/dist/{chunk-2MV4HBKC.cjs.map → chunk-A2N2GFCG.cjs.map} +1 -1
  47. package/dist/chunk-ADBA3XBE.cjs +20 -0
  48. package/dist/chunk-ADBA3XBE.cjs.map +1 -0
  49. package/dist/{chunk-MBNQVDVC.cjs → chunk-AMOJYLG2.cjs} +16 -10
  50. package/dist/chunk-AMOJYLG2.cjs.map +1 -0
  51. package/dist/{chunk-CLVQBF5C.cjs → chunk-AQNHHJMJ.cjs} +5 -5
  52. package/dist/{chunk-CLVQBF5C.cjs.map → chunk-AQNHHJMJ.cjs.map} +1 -1
  53. package/dist/{chunk-AHCLWAM5.cjs → chunk-BHTNFEGZ.cjs} +13 -13
  54. package/dist/chunk-BHTNFEGZ.cjs.map +1 -0
  55. package/dist/{chunk-35IWNZPJ.cjs → chunk-E4NUZXVK.cjs} +58 -27
  56. package/dist/chunk-E4NUZXVK.cjs.map +1 -0
  57. package/dist/{chunk-P33SBYGG.js → chunk-GLG5ZMX7.js} +54 -23
  58. package/dist/chunk-GLG5ZMX7.js.map +1 -0
  59. package/dist/{chunk-BVAR5J2F.js → chunk-GQCOSXMG.js} +117 -6
  60. package/dist/chunk-GQCOSXMG.js.map +1 -0
  61. package/dist/{chunk-QDMPOAI7.cjs → chunk-HDP7VK3C.cjs} +1118 -313
  62. package/dist/chunk-HDP7VK3C.cjs.map +1 -0
  63. package/dist/{chunk-GVWHCL2N.js → chunk-HMOISHXR.js} +217 -75
  64. package/dist/chunk-HMOISHXR.js.map +1 -0
  65. package/dist/{chunk-MTX2KVU7.cjs → chunk-HVQFNJKE.cjs} +122 -90
  66. package/dist/chunk-HVQFNJKE.cjs.map +1 -0
  67. package/dist/{chunk-OC6LTXYS.cjs → chunk-JMXUNXQS.cjs} +126 -7
  68. package/dist/chunk-JMXUNXQS.cjs.map +1 -0
  69. package/dist/{chunk-WWOLFXTX.cjs → chunk-KBSXGXPM.cjs} +10 -7
  70. package/dist/chunk-KBSXGXPM.cjs.map +1 -0
  71. package/dist/{chunk-YU2CUNFO.js → chunk-KV7UW6T6.js} +11 -5
  72. package/dist/chunk-KV7UW6T6.js.map +1 -0
  73. package/dist/{chunk-CCJPSHGI.cjs → chunk-N7FNVFXW.cjs} +4 -12
  74. package/dist/chunk-N7FNVFXW.cjs.map +1 -0
  75. package/dist/{chunk-CYFK5SY2.js → chunk-O3ANBHSA.js} +169 -39
  76. package/dist/chunk-O3ANBHSA.js.map +1 -0
  77. package/dist/{chunk-NZFKROS7.cjs → chunk-PA4VC73I.cjs} +130 -72
  78. package/dist/chunk-PA4VC73I.cjs.map +1 -0
  79. package/dist/{chunk-NJTXJ5AG.cjs → chunk-PFUESQTW.cjs} +18 -18
  80. package/dist/{chunk-NJTXJ5AG.cjs.map → chunk-PFUESQTW.cjs.map} +1 -1
  81. package/dist/{chunk-SFQWJMKT.js → chunk-QY25VWBF.js} +51 -12
  82. package/dist/chunk-QY25VWBF.js.map +1 -0
  83. package/dist/{chunk-WC5FFSHB.js → chunk-R3PY4G7J.js} +3 -3
  84. package/dist/{chunk-WC5FFSHB.js.map → chunk-R3PY4G7J.js.map} +1 -1
  85. package/dist/{chunk-M5E34VG5.js → chunk-SBUFNJVE.js} +3 -3
  86. package/dist/{chunk-M5E34VG5.js.map → chunk-SBUFNJVE.js.map} +1 -1
  87. package/dist/{chunk-UKPGSAZW.js → chunk-TMA4RCEN.js} +3 -3
  88. package/dist/{chunk-UKPGSAZW.js.map → chunk-TMA4RCEN.js.map} +1 -1
  89. package/dist/{chunk-V6HA6JJZ.cjs → chunk-U5VAY32K.cjs} +215 -138
  90. package/dist/chunk-U5VAY32K.cjs.map +1 -0
  91. package/dist/{chunk-DUEZFTK2.js → chunk-UKQHXPGW.js} +4 -12
  92. package/dist/chunk-UKQHXPGW.js.map +1 -0
  93. package/dist/{chunk-4CVLFLOB.cjs → chunk-UM6BVY2S.cjs} +201 -69
  94. package/dist/chunk-UM6BVY2S.cjs.map +1 -0
  95. package/dist/{chunk-75JP4BZX.js → chunk-UQ3UIZJC.js} +3 -2
  96. package/dist/chunk-UQ3UIZJC.js.map +1 -0
  97. package/dist/{chunk-PCPX42KL.js → chunk-V4XG5QF6.js} +16 -10
  98. package/dist/chunk-V4XG5QF6.js.map +1 -0
  99. package/dist/{chunk-GPPLSM2Z.js → chunk-VB37OC6I.js} +6 -5
  100. package/dist/chunk-VB37OC6I.js.map +1 -0
  101. package/dist/{chunk-MVBEL57Q.js → chunk-Y7FT4IQT.js} +500 -170
  102. package/dist/chunk-Y7FT4IQT.js.map +1 -0
  103. package/dist/{chunk-OFXOTECC.js → chunk-YPPPYLSR.js} +7 -7
  104. package/dist/chunk-YPPPYLSR.js.map +1 -0
  105. package/dist/{chunk-M4F66R4O.cjs → chunk-YWQ6V4ZN.cjs} +121 -82
  106. package/dist/chunk-YWQ6V4ZN.cjs.map +1 -0
  107. package/dist/constants.cjs +5 -5
  108. package/dist/constants.d.cts +1 -1
  109. package/dist/constants.d.ts +1 -1
  110. package/dist/constants.js +2 -2
  111. package/dist/engine.cjs +31 -31
  112. package/dist/engine.d.cts +11 -11
  113. package/dist/engine.d.ts +11 -11
  114. package/dist/engine.js +21 -21
  115. package/dist/errors.cjs +19 -19
  116. package/dist/errors.d.cts +2 -2
  117. package/dist/errors.d.ts +2 -2
  118. package/dist/errors.js +1 -1
  119. package/dist/format.cjs +29 -22
  120. package/dist/format.cjs.map +1 -1
  121. package/dist/format.d.cts +1 -2
  122. package/dist/format.d.ts +1 -2
  123. package/dist/format.js +23 -16
  124. package/dist/format.js.map +1 -1
  125. package/dist/index.cjs +31 -31
  126. package/dist/index.d.cts +10 -10
  127. package/dist/index.d.ts +10 -10
  128. package/dist/index.js +22 -22
  129. package/dist/language.cjs +8 -8
  130. package/dist/language.cjs.map +1 -1
  131. package/dist/language.d.cts +10 -10
  132. package/dist/language.d.ts +10 -10
  133. package/dist/language.js +6 -6
  134. package/dist/language.js.map +1 -1
  135. package/dist/lexer.cjs +18 -18
  136. package/dist/lexer.d.cts +2 -2
  137. package/dist/lexer.d.ts +2 -2
  138. package/dist/lexer.js +6 -6
  139. package/dist/normalizer.cjs +12 -12
  140. package/dist/normalizer.js +6 -6
  141. package/dist/packages.cjs +39 -39
  142. package/dist/packages.d.cts +9 -9
  143. package/dist/packages.d.ts +9 -9
  144. package/dist/packages.js +16 -16
  145. package/dist/parser.cjs +15 -15
  146. package/dist/parser.d.cts +23 -9
  147. package/dist/parser.d.ts +23 -9
  148. package/dist/parser.js +5 -5
  149. package/dist/{pipeline-CrsRPmsv.d.ts → pipeline-B6k5lCB7.d.ts} +1 -1
  150. package/dist/{pipeline-DPUQt7yL.d.cts → pipeline-BEb3hujr.d.cts} +1 -1
  151. package/dist/resolvers.d.cts +2 -2
  152. package/dist/resolvers.d.ts +2 -2
  153. package/dist/uom.cjs +17 -17
  154. package/dist/uom.d.cts +2 -2
  155. package/dist/uom.d.ts +2 -2
  156. package/dist/uom.js +7 -7
  157. package/dist/utilities.cjs +8 -4
  158. package/dist/utilities.d.cts +19 -3
  159. package/dist/utilities.d.ts +19 -3
  160. package/dist/utilities.js +2 -2
  161. package/dist/vm.cjs +43 -31
  162. package/dist/vm.d.cts +105 -9
  163. package/dist/vm.d.ts +105 -9
  164. package/dist/vm.js +9 -9
  165. package/package.json +1 -1
  166. package/dist/chunk-2CS6OMZK.js.map +0 -1
  167. package/dist/chunk-35IWNZPJ.cjs.map +0 -1
  168. package/dist/chunk-4AVD7NZW.cjs.map +0 -1
  169. package/dist/chunk-4CVLFLOB.cjs.map +0 -1
  170. package/dist/chunk-6GCKCWLB.js.map +0 -1
  171. package/dist/chunk-6RDSQURE.js.map +0 -1
  172. package/dist/chunk-75JP4BZX.js.map +0 -1
  173. package/dist/chunk-AHCLWAM5.cjs.map +0 -1
  174. package/dist/chunk-BAMZT3GL.js.map +0 -1
  175. package/dist/chunk-BVAR5J2F.js.map +0 -1
  176. package/dist/chunk-BXKJLM5R.cjs.map +0 -1
  177. package/dist/chunk-CCJPSHGI.cjs.map +0 -1
  178. package/dist/chunk-CSG5XVNJ.cjs.map +0 -1
  179. package/dist/chunk-CYFK5SY2.js.map +0 -1
  180. package/dist/chunk-DUEZFTK2.js.map +0 -1
  181. package/dist/chunk-GPPLSM2Z.js.map +0 -1
  182. package/dist/chunk-GVWHCL2N.js.map +0 -1
  183. package/dist/chunk-M4F66R4O.cjs.map +0 -1
  184. package/dist/chunk-M4N5GA5Z.cjs.map +0 -1
  185. package/dist/chunk-MBNQVDVC.cjs.map +0 -1
  186. package/dist/chunk-MEOHSQEH.js.map +0 -1
  187. package/dist/chunk-MTX2KVU7.cjs.map +0 -1
  188. package/dist/chunk-MVBEL57Q.js.map +0 -1
  189. package/dist/chunk-MZOVP3WI.cjs.map +0 -1
  190. package/dist/chunk-N5YFR4UP.cjs +0 -10
  191. package/dist/chunk-N5YFR4UP.cjs.map +0 -1
  192. package/dist/chunk-NZFKROS7.cjs.map +0 -1
  193. package/dist/chunk-OC6LTXYS.cjs.map +0 -1
  194. package/dist/chunk-OFXOTECC.js.map +0 -1
  195. package/dist/chunk-P33SBYGG.js.map +0 -1
  196. package/dist/chunk-P75775WC.js.map +0 -1
  197. package/dist/chunk-PCPX42KL.js.map +0 -1
  198. package/dist/chunk-PFSDGGYL.js +0 -8
  199. package/dist/chunk-PFSDGGYL.js.map +0 -1
  200. package/dist/chunk-QDMPOAI7.cjs.map +0 -1
  201. package/dist/chunk-R24DI24X.cjs.map +0 -1
  202. package/dist/chunk-SFQWJMKT.js.map +0 -1
  203. package/dist/chunk-V6HA6JJZ.cjs.map +0 -1
  204. package/dist/chunk-WWOLFXTX.cjs.map +0 -1
  205. package/dist/chunk-YU2CUNFO.js.map +0 -1
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  var chunk47LRVGOT_cjs = require('./chunk-47LRVGOT.cjs');
4
- var chunkBXKJLM5R_cjs = require('./chunk-BXKJLM5R.cjs');
5
- var chunk2MV4HBKC_cjs = require('./chunk-2MV4HBKC.cjs');
6
- var chunkMZOVP3WI_cjs = require('./chunk-MZOVP3WI.cjs');
7
- var chunk4CVLFLOB_cjs = require('./chunk-4CVLFLOB.cjs');
8
- var chunkOC6LTXYS_cjs = require('./chunk-OC6LTXYS.cjs');
9
- var chunkNJTXJ5AG_cjs = require('./chunk-NJTXJ5AG.cjs');
10
- var chunkMBNQVDVC_cjs = require('./chunk-MBNQVDVC.cjs');
11
- var chunkM4N5GA5Z_cjs = require('./chunk-M4N5GA5Z.cjs');
4
+ var chunk6WFMPTGB_cjs = require('./chunk-6WFMPTGB.cjs');
5
+ var chunkA2N2GFCG_cjs = require('./chunk-A2N2GFCG.cjs');
6
+ var chunk6KFYJ6TD_cjs = require('./chunk-6KFYJ6TD.cjs');
7
+ var chunkUM6BVY2S_cjs = require('./chunk-UM6BVY2S.cjs');
8
+ var chunkJMXUNXQS_cjs = require('./chunk-JMXUNXQS.cjs');
9
+ var chunkPFUESQTW_cjs = require('./chunk-PFUESQTW.cjs');
10
+ var chunkAMOJYLG2_cjs = require('./chunk-AMOJYLG2.cjs');
11
+ var chunk5KMIY374_cjs = require('./chunk-5KMIY374.cjs');
12
12
 
13
13
  // src/vm/DependencyGraph.ts
14
14
  var DependencyGraph = class {
@@ -332,8 +332,139 @@ var ScopeManager = class {
332
332
  }
333
333
  };
334
334
 
335
+ // src/vm/VMBuiltinArity.ts
336
+ var BUILTIN_ARITY = {
337
+ 0: { name: "sqrt", min: 1, max: 1 },
338
+ 1: { name: "abs", min: 1, max: 1 },
339
+ 2: { name: "sin", min: 1, max: 1 },
340
+ 3: { name: "cos", min: 1, max: 1 },
341
+ 4: { name: "tan", min: 1, max: 1 },
342
+ 5: { name: "log", min: 1, max: 1 },
343
+ 6: { name: "ceil", min: 1, max: 1 },
344
+ 7: { name: "floor", min: 1, max: 1 },
345
+ 8: { name: "round", min: 1, max: 1 },
346
+ // min/max compare as many operands as they are given.
347
+ 9: { name: "min", min: 1, max: Infinity },
348
+ 10: { name: "max", min: 1, max: Infinity },
349
+ 11: { name: "asin", min: 1, max: 1 },
350
+ 12: { name: "acos", min: 1, max: 1 },
351
+ 13: { name: "atan", min: 1, max: 1 },
352
+ 14: { name: "atan2", min: 2, max: 2 },
353
+ 15: { name: "sinh", min: 1, max: 1 },
354
+ 16: { name: "cosh", min: 1, max: 1 },
355
+ 17: { name: "tanh", min: 1, max: 1 },
356
+ 18: { name: "asinh", min: 1, max: 1 },
357
+ 19: { name: "acosh", min: 1, max: 1 },
358
+ 20: { name: "atanh", min: 1, max: 1 },
359
+ 21: { name: "cbrt", min: 1, max: 1 },
360
+ 22: { name: "clz32", min: 1, max: 1 },
361
+ 23: { name: "expm1", min: 1, max: 1 },
362
+ 24: { name: "exp", min: 1, max: 1 },
363
+ 25: { name: "fround", min: 1, max: 1 },
364
+ // hypot is the length of a vector with as many components as it is given.
365
+ 26: { name: "hypot", min: 1, max: Infinity },
366
+ 27: { name: "imul", min: 2, max: 2 },
367
+ 28: { name: "log10", min: 1, max: 1 },
368
+ 29: { name: "log1p", min: 1, max: 1 },
369
+ 30: { name: "log2", min: 1, max: 1 },
370
+ 31: { name: "pow", min: 2, max: 2 },
371
+ 32: { name: "random", min: 0, max: 0 },
372
+ 33: { name: "sign", min: 1, max: 1 },
373
+ 34: { name: "trunc", min: 1, max: 1 },
374
+ 35: { name: "degtorad", min: 1, max: 1 },
375
+ 36: { name: "radtodeg", min: 1, max: 1 },
376
+ 37: { name: "roll", min: 2, max: 2 },
377
+ 38: { name: "gcd", min: 2, max: 2 },
378
+ 39: { name: "lcm", min: 2, max: 2 },
379
+ 40: { name: "permutation", min: 2, max: 2 },
380
+ 41: { name: "combination", min: 2, max: 2 },
381
+ // The aggregates back "average of X, Y, Z" and friends, so they take a
382
+ // list. Their implementations already answer for an empty list rather
383
+ // than indexing into it, and the phrase parselets can emit an empty one,
384
+ // so the minimum stays 0 here instead of being tightened on the way past.
385
+ 42: { name: "average", min: 0, max: Infinity },
386
+ 43: { name: "median", min: 0, max: Infinity },
387
+ 44: { name: "total", min: 0, max: Infinity },
388
+ 45: { name: "count", min: 0, max: Infinity },
389
+ 46: { name: "proportion", min: 3, max: 3 },
390
+ 47: { name: "clamp", min: 3, max: 3 },
391
+ 48: { name: "hex", min: 1, max: 1 },
392
+ 49: { name: "bin", min: 1, max: 1 },
393
+ 50: { name: "int", min: 1, max: 1 },
394
+ 51: { name: "compoundInterest", min: 3, max: 3 },
395
+ 52: { name: "interestEarned", min: 3, max: 3 },
396
+ 53: { name: "compoundInterestRate", min: 3, max: 3 },
397
+ 54: { name: "compoundInterestYears", min: 3, max: 3 },
398
+ 55: { name: "loanRepayment", min: 4, max: 4 },
399
+ 56: { name: "loanInterest", min: 4, max: 4 },
400
+ 57: { name: "monthlyPayment", min: 3, max: 3 },
401
+ 58: { name: "taxAdd", min: 2, max: 2 },
402
+ 59: { name: "taxRemove", min: 2, max: 2 },
403
+ 60: { name: "inflationAdjust", min: 3, max: 3 },
404
+ 61: { name: "root", min: 2, max: 2 },
405
+ 62: { name: "fact", min: 1, max: 1 },
406
+ 63: { name: "transpose", min: 1, max: 1 },
407
+ 64: { name: "det", min: 1, max: 1 },
408
+ 65: { name: "inv", min: 1, max: 1 },
409
+ 66: { name: "dot", min: 2, max: 2 },
410
+ 67: { name: "expand", min: 1, max: 1 },
411
+ 68: { name: "factor", min: 1, max: 1 },
412
+ // solve pushes the two sides of the equation and then the unknown's name.
413
+ 69: { name: "solve", min: 3, max: 3 },
414
+ // der's order of differentiation is optional and defaults to 1.
415
+ 70: { name: "der", min: 2, max: 3 },
416
+ 71: { name: "integral", min: 2, max: 2 },
417
+ 72: { name: "taylor", min: 4, max: 4 },
418
+ // jacobian differentiates however many functions it is handed.
419
+ 73: { name: "jacobian", min: 1, max: Infinity },
420
+ 74: { name: "imaginary", min: 1, max: 1 },
421
+ 75: { name: "conj", min: 1, max: 1 },
422
+ 76: { name: "re", min: 1, max: 1 },
423
+ 77: { name: "im", min: 1, max: 1 },
424
+ 78: { name: "cancel", min: 1, max: 1 },
425
+ 79: { name: "apart", min: 1, max: 1 },
426
+ 80: { name: "compoundInterestEvery", min: 4, max: 4 },
427
+ 81: { name: "compoundInterestEarnedEvery", min: 4, max: 4 },
428
+ 82: { name: "presentValue", min: 3, max: 3 },
429
+ 83: { name: "roi", min: 2, max: 2 },
430
+ 84: { name: "annualisedReturn", min: 3, max: 3 },
431
+ 85: { name: "taxIn", min: 2, max: 2 },
432
+ 86: { name: "taxOn", min: 2, max: 2 },
433
+ 87: { name: "sind", min: 1, max: 1 },
434
+ 88: { name: "cosd", min: 1, max: 1 },
435
+ 89: { name: "tand", min: 1, max: 1 },
436
+ 90: { name: "asind", min: 1, max: 1 },
437
+ 91: { name: "acosd", min: 1, max: 1 },
438
+ 92: { name: "atand", min: 1, max: 1 },
439
+ 93: { name: "daysCount", min: 1, max: 1 },
440
+ 94: { name: "asTwoUnits", min: 3, max: 3 },
441
+ 95: { name: "makeRate", min: 2, max: 2 },
442
+ 96: { name: "atRate", min: 2, max: 2 },
443
+ // Not reachable by name, only through `<value> to <n> dp`; see
444
+ // converters/parselets/RoundingParselets.ts.
445
+ 97: { name: "roundToPlaces", min: 2, max: 2 }
446
+ };
447
+ function plural(count) {
448
+ return count === 1 ? "1 argument" : `${count} arguments`;
449
+ }
450
+ function expectation(arity) {
451
+ if (arity.max === Infinity) return `at least ${plural(arity.min)}`;
452
+ if (arity.min === arity.max) return plural(arity.min);
453
+ return `${arity.min} to ${plural(arity.max)}`;
454
+ }
455
+ function builtinArityError(index, argCount) {
456
+ const arity = BUILTIN_ARITY[index];
457
+ if (arity === void 0) return void 0;
458
+ if (argCount >= arity.min && argCount <= arity.max) return void 0;
459
+ return chunk5KMIY374_cjs.ErrorFactory.execution(
460
+ "BUILTIN_ARITY_MISMATCH",
461
+ `${arity.name}() takes ${expectation(arity)}, but was given ${argCount === 0 ? "none" : plural(argCount)}`,
462
+ { functionName: arity.name, expectedMin: arity.min, expectedMax: arity.max, actual: argCount }
463
+ );
464
+ }
465
+
335
466
  // src/vm/VM.ts
336
- function createVM(registry, maxStackDepth = 200, maxInstructions = 5e4, maxFunctionRecursionDepth = 50, context = chunkBXKJLM5R_cjs.defaultEngineContext) {
467
+ function createVM(registry, maxStackDepth = 200, maxInstructions = 5e4, maxFunctionRecursionDepth = 50, maxCollectionSize = 1e5, maxAllocatedElements = 2e6, maxFunctionCalls = 1e4, maxDateOffsetYears = 100, minDateOffsetYears = -100, context = chunk6WFMPTGB_cjs.defaultEngineContext) {
337
468
  const stack = [];
338
469
  const variables = /* @__PURE__ */ new Map();
339
470
  let instructionCount = 0;
@@ -352,17 +483,51 @@ function createVM(registry, maxStackDepth = 200, maxInstructions = 5e4, maxFunct
352
483
  getMaxStackDepth() {
353
484
  return maxStackDepth;
354
485
  },
486
+ getMaxCollectionSize() {
487
+ return maxCollectionSize;
488
+ },
489
+ getMaxAllocatedElements() {
490
+ return maxAllocatedElements;
491
+ },
492
+ getMaxFunctionCalls() {
493
+ return maxFunctionCalls;
494
+ },
495
+ getMaxDateOffsetYears() {
496
+ return maxDateOffsetYears;
497
+ },
498
+ getMinDateOffsetYears() {
499
+ return minDateOffsetYears;
500
+ },
355
501
  pop() {
356
502
  if (stack.length === 0) {
357
- return chunkOC6LTXYS_cjs.numberValue(0);
503
+ return chunkJMXUNXQS_cjs.numberValue(0);
358
504
  }
359
505
  return stack.pop();
360
506
  },
507
+ /**
508
+ * Popped through `safePop()` for the same reason as `popString()` below.
509
+ * Only the underflow half applies here: `toNumber()` is a real method on
510
+ * every Value, so there was no cast to make a non-number look like one,
511
+ * and the `!` was the whole bug.
512
+ */
361
513
  popNumber() {
362
- return stack.pop().toNumber();
514
+ return safePop(stack).toNumber();
363
515
  },
516
+ /**
517
+ * Popped through the same two guards the dispatch loop below uses, and
518
+ * for the same reason: a package's opcode handler can disagree with its
519
+ * own bytecode exactly as this engine's compiler can disagree with
520
+ * hand-assembled input.
521
+ *
522
+ * This was `stack.pop()!.value as string`, which had neither guard. The
523
+ * `!` is compile-time only, so an empty stack reached `.value` and threw
524
+ * a raw TypeError; so is the cast, so any Value the stack happened to be
525
+ * holding was handed back as a "string" and threw in the handler's own
526
+ * code some lines later. Nothing in this repo calls this method, which is
527
+ * the only reason the fuzz corpus never found either.
528
+ */
364
529
  popString() {
365
- return stack.pop().value;
530
+ return stringOperand(safePop(stack), "VM.popString()");
366
531
  },
367
532
  peek() {
368
533
  return stack[stack.length - 1];
@@ -383,7 +548,7 @@ function createVM(registry, maxStackDepth = 200, maxInstructions = 5e4, maxFunct
383
548
  },
384
549
  pushCallFrame(frame) {
385
550
  if (callFrames.length >= maxFunctionRecursionDepth) {
386
- throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
551
+ throw chunk5KMIY374_cjs.ErrorFactory.execution(
387
552
  "FUNCTION_RECURSION_LIMIT_EXCEEDED",
388
553
  `Function call nesting exceeded maximum depth of ${maxFunctionRecursionDepth} (possible infinite recursion, e.g. f(x) = f(x))`,
389
554
  { maxFunctionRecursionDepth }
@@ -394,6 +559,9 @@ function createVM(registry, maxStackDepth = 200, maxInstructions = 5e4, maxFunct
394
559
  popCallFrame() {
395
560
  callFrames.pop();
396
561
  },
562
+ getCallFrame() {
563
+ return callFrames.length > 0 ? callFrames[callFrames.length - 1] : void 0;
564
+ },
397
565
  defineUserFunction(name, params, program) {
398
566
  userFunctions.set(name, { name, params, program });
399
567
  },
@@ -457,14 +625,25 @@ function createVM(registry, maxStackDepth = 200, maxInstructions = 5e4, maxFunct
457
625
  incrementInstructions(n) {
458
626
  instructionCount += n;
459
627
  if (instructionCount > maxInstructions) {
460
- throw chunkM4N5GA5Z_cjs.ErrorFactory.execution("INSTRUCTION_LIMIT_EXCEEDED", `Execution exceeded maximum of ${maxInstructions} instructions`);
628
+ throw chunk5KMIY374_cjs.ErrorFactory.execution("INSTRUCTION_LIMIT_EXCEEDED", `Execution exceeded maximum of ${maxInstructions} instructions`);
461
629
  }
462
630
  }
463
631
  };
464
632
  }
633
+ function matrixProductCells(l, r) {
634
+ if (l.rows === 1 && l.cols === 1) return r.data.length;
635
+ if (r.rows === 1 && r.cols === 1) return l.data.length;
636
+ if (l.cols !== r.rows) return 0;
637
+ return l.rows * r.cols;
638
+ }
639
+ function matrixPowerCells(m, exponent) {
640
+ if (!Number.isInteger(exponent) || exponent < 0) return 0;
641
+ const cells = m.rows * m.cols;
642
+ return cells * (1 + (exponent < 2 ? 1 : 2 * Math.floor(Math.log2(exponent))));
643
+ }
465
644
  function safePop(stack) {
466
645
  if (stack.length === 0) {
467
- throw chunkM4N5GA5Z_cjs.ErrorFactory.internal({
646
+ throw chunk5KMIY374_cjs.ErrorFactory.internal({
468
647
  code: "STACK_UNDERFLOW",
469
648
  message: "Stack underflow: an opcode expected a value on the stack but it was empty",
470
649
  expected: "at least one value on the VM stack",
@@ -474,6 +653,124 @@ function safePop(stack) {
474
653
  }
475
654
  return stack.pop();
476
655
  }
656
+ var MALFORMED_BYTECODE_SUGGESTION = "bytecode is caller input on this entry point: rebuild the program with the engine's compiler, or fix the hand-assembled stream";
657
+ function siteName(site) {
658
+ return typeof site === "number" ? chunk6KFYJ6TD_cjs.getOpCodeName(site) : site;
659
+ }
660
+ function malformedBytecode(code, site, problem, expected, found, context = {}) {
661
+ const name = siteName(site);
662
+ return chunk5KMIY374_cjs.ErrorFactory.validation({
663
+ code,
664
+ message: `Malformed bytecode: ${name} ${problem}`,
665
+ expected,
666
+ found,
667
+ suggestion: MALFORMED_BYTECODE_SUGGESTION,
668
+ // A named site reports under `site` rather than borrowing `opcodeName`,
669
+ // so a host reading `opcode`/`opcodeName` never gets a method name
670
+ // where it expects an opcode, and never has to tell a missing opcode
671
+ // apart from opcode 0.
672
+ context: typeof site === "number" ? { opcode: site, opcodeName: name, ...context } : { site: name, ...context }
673
+ });
674
+ }
675
+ function operandByte(opcodes, at, op, role) {
676
+ if (at >= opcodes.length) {
677
+ throw malformedBytecode(
678
+ "MALFORMED_BYTECODE_TRUNCATED",
679
+ op,
680
+ `is missing its ${role}: the program ends mid-instruction`,
681
+ `an operand byte at offset ${at}`,
682
+ `a program only ${opcodes.length} byte(s) long`,
683
+ { offset: at, length: opcodes.length, role }
684
+ );
685
+ }
686
+ return opcodes[at];
687
+ }
688
+ function poolIndex(opcodes, at, op, role, poolSize, poolName) {
689
+ const index = operandByte(opcodes, at, op, role);
690
+ if (index >= poolSize) {
691
+ throw malformedBytecode(
692
+ "MALFORMED_BYTECODE_CONSTANT_INDEX",
693
+ op,
694
+ `reads ${poolName} entry ${index}, which does not exist`,
695
+ `an index below ${poolSize}`,
696
+ `${index}`,
697
+ { index, poolSize, pool: poolName }
698
+ );
699
+ }
700
+ return index;
701
+ }
702
+ function poolString(opcodes, at, strings, op, role) {
703
+ return pooledString(strings, operandByte(opcodes, at, op, role), op);
704
+ }
705
+ function pooledString(strings, index, op) {
706
+ const text = strings[index];
707
+ if (typeof text !== "string") {
708
+ throw malformedBytecode(
709
+ "MALFORMED_BYTECODE_CONSTANT_INDEX",
710
+ op,
711
+ `reads string-pool entry ${index}, which is ${index >= strings.length ? "past the end of the pool" : "not a string"}`,
712
+ `an index below ${strings.length}, holding a string`,
713
+ index >= strings.length ? `${index}` : typeof text,
714
+ { index, poolSize: strings.length, pool: "string-pool" }
715
+ );
716
+ }
717
+ return text;
718
+ }
719
+ function stringOperand(value, site, role) {
720
+ if (typeof value.value !== "string") {
721
+ throw malformedBytecode(
722
+ "MALFORMED_BYTECODE_OPERAND_TYPE",
723
+ site,
724
+ `expected a ${role ?? "string"} on the stack`,
725
+ role ? `a string value holding the ${role}` : "a string value",
726
+ `a ${chunkJMXUNXQS_cjs.ValueType[value.type] ?? "unknown"} value`,
727
+ role ? { role, valueType: value.type } : { valueType: value.type }
728
+ );
729
+ }
730
+ return value.value;
731
+ }
732
+ function requireKnownBodyKind(kind, ref, op) {
733
+ if (kind !== 0 && kind !== 1 && kind !== 2) {
734
+ throw malformedBytecode(
735
+ "MALFORMED_BYTECODE_BODY_KIND",
736
+ op,
737
+ `has body kind ${kind}, which is not one this VM knows`,
738
+ "0 (inline body), 1 (builtin function) or 2 (user-defined function)",
739
+ `${kind}`,
740
+ { kind, ref }
741
+ );
742
+ }
743
+ }
744
+ function parseBigIntLiteral(text, op) {
745
+ try {
746
+ return BigInt(text);
747
+ } catch {
748
+ throw malformedBytecode(
749
+ "MALFORMED_BYTECODE_BIGINT_LITERAL",
750
+ op,
751
+ `cannot read "${text}" as a whole number`,
752
+ "a string holding an integer, with no decimal point or separators",
753
+ `"${text}"`,
754
+ { literal: text }
755
+ );
756
+ }
757
+ }
758
+ function unrunnableProgram(bytecode) {
759
+ if (bytecode === null || typeof bytecode !== "object") {
760
+ return `expected a bytecode program, got ${bytecode === null ? "null" : typeof bytecode}`;
761
+ }
762
+ const candidate = bytecode;
763
+ if (typeof candidate.opcodes?.length !== "number") {
764
+ return "the program has no `opcodes` array";
765
+ }
766
+ if (typeof candidate.numbers?.length !== "number") {
767
+ return "the program has no `numbers` pool";
768
+ }
769
+ if (typeof candidate.strings?.length !== "number") {
770
+ return "the program has no `strings` pool";
771
+ }
772
+ return null;
773
+ }
477
774
  function invokeFrameBody(params, program, args, vm, pipeline, expression, context, symbolicTolerant) {
478
775
  const frame = /* @__PURE__ */ new Map();
479
776
  for (let i = 0; i < params.length; i++) frame.set(params[i], args[i]);
@@ -485,7 +782,7 @@ function invokeFrameBody(params, program, args, vm, pipeline, expression, contex
485
782
  vm.popCallFrame();
486
783
  }
487
784
  if (bodyResult.type === "pending") {
488
- throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
785
+ throw chunk5KMIY374_cjs.ErrorFactory.execution(
489
786
  "MAP_REDUCE_ASYNC_UNSUPPORTED",
490
787
  `map/reduce transform bodies calling an async operation (weather, stocks, currency, ...) aren't supported`
491
788
  );
@@ -495,6 +792,27 @@ function invokeFrameBody(params, program, args, vm, pipeline, expression, contex
495
792
  }
496
793
  return bodyResult.value;
497
794
  }
795
+ function invokeWithBoundUnknown(name, program, vm, pipeline, expression, context, symbolicTolerant) {
796
+ const frame = new Map(vm.getCallFrame());
797
+ frame.set(name, chunkJMXUNXQS_cjs.symbolicValue(chunkUM6BVY2S_cjs.varNode(name)));
798
+ vm.pushCallFrame(frame);
799
+ let bodyResult;
800
+ try {
801
+ bodyResult = executeBytecode(program, vm, pipeline, expression, context, symbolicTolerant);
802
+ } finally {
803
+ vm.popCallFrame();
804
+ }
805
+ if (bodyResult.type === "pending") {
806
+ throw chunk5KMIY374_cjs.ErrorFactory.execution(
807
+ "SYMBOLIC_ASYNC_UNSUPPORTED",
808
+ `an algebra verb's expression cannot call an async operation (weather, stocks, currency, ...)`
809
+ );
810
+ }
811
+ if (bodyResult.type === "error") {
812
+ throw bodyResult.error;
813
+ }
814
+ return bodyResult.value;
815
+ }
498
816
  function unifyRatePeriods(l, r) {
499
817
  if (l.type !== 6 /* Uom */ || r.type !== 6 /* Uom */) return null;
500
818
  const leftUnit = l.unit;
@@ -504,8 +822,8 @@ function unifyRatePeriods(l, r) {
504
822
  const rightSlash = rightUnit.indexOf("/");
505
823
  if (leftSlash < 0 || rightSlash < 0) return null;
506
824
  if (leftUnit.slice(0, leftSlash) !== rightUnit.slice(0, rightSlash)) return null;
507
- const leftPeriod = chunkMBNQVDVC_cjs.UNIT_TABLE[leftUnit.slice(leftSlash + 1).toLowerCase()];
508
- const rightPeriod = chunkMBNQVDVC_cjs.UNIT_TABLE[rightUnit.slice(rightSlash + 1).toLowerCase()];
825
+ const leftPeriod = chunkAMOJYLG2_cjs.UNIT_TABLE[leftUnit.slice(leftSlash + 1).toLowerCase()];
826
+ const rightPeriod = chunkAMOJYLG2_cjs.UNIT_TABLE[rightUnit.slice(rightSlash + 1).toLowerCase()];
509
827
  if (leftPeriod === void 0 || rightPeriod === void 0) return null;
510
828
  if (leftPeriod[0] !== rightPeriod[0]) return null;
511
829
  return l.toNumber() * (rightPeriod[1] / leftPeriod[1]);
@@ -516,28 +834,31 @@ function moneyTimesQuantity(l, r) {
516
834
  const rightUnit = r.unit;
517
835
  if (leftUnit === void 0 || rightUnit === void 0) return null;
518
836
  if (leftUnit.includes("/") || rightUnit.includes("/")) return null;
519
- const leftIsMoney = chunk4CVLFLOB_cjs.CURRENCY_DISPLAY[leftUnit.toUpperCase()] !== void 0;
520
- const rightIsMoney = chunk4CVLFLOB_cjs.CURRENCY_DISPLAY[rightUnit.toUpperCase()] !== void 0;
837
+ const leftIsMoney = chunkUM6BVY2S_cjs.CURRENCY_DISPLAY[leftUnit.toUpperCase()] !== void 0;
838
+ const rightIsMoney = chunkUM6BVY2S_cjs.CURRENCY_DISPLAY[rightUnit.toUpperCase()] !== void 0;
521
839
  if (leftIsMoney === rightIsMoney) return null;
522
- return chunkOC6LTXYS_cjs.uomValue(l.toNumber() * r.toNumber(), leftIsMoney ? leftUnit : rightUnit);
840
+ return chunkJMXUNXQS_cjs.uomValue(l.toNumber() * r.toNumber(), leftIsMoney ? leftUnit : rightUnit);
523
841
  }
524
842
  function combinePercentage(l, r, sign) {
525
843
  if (l.type === 5 /* Percentage */) {
844
+ if (r.type === 6 /* Uom */ && r.unit !== void 0) {
845
+ return chunkJMXUNXQS_cjs.uomValue(r.toNumber() * (1 + sign * l.toNumber()), r.unit);
846
+ }
526
847
  if (r.type !== 5 /* Percentage */ && r.type !== 0 /* Number */) return null;
527
- return chunkOC6LTXYS_cjs.percentageValue(l.toNumber() + sign * r.toNumber());
848
+ return chunkJMXUNXQS_cjs.percentageValue(l.toNumber() + sign * r.toNumber());
528
849
  }
529
850
  if (r.type !== 5 /* Percentage */) return null;
530
851
  const factor = 1 + sign * r.toNumber();
531
- if (l.type === 0 /* Number */) return chunkOC6LTXYS_cjs.numberValue(l.toNumber() * factor);
532
- if (l.type === 6 /* Uom */ && l.unit !== void 0) return chunkOC6LTXYS_cjs.uomValue(l.toNumber() * factor, l.unit);
852
+ if (l.type === 0 /* Number */) return chunkJMXUNXQS_cjs.numberValue(l.toNumber() * factor);
853
+ if (l.type === 6 /* Uom */ && l.unit !== void 0) return chunkJMXUNXQS_cjs.uomValue(l.toNumber() * factor, l.unit);
533
854
  return null;
534
855
  }
535
856
  function extractDurationMs(value) {
536
857
  if (value.type === 6 /* Uom */) {
537
858
  const unit = value.unit;
538
- if (unit && chunkNJTXJ5AG_cjs.getMeasure(unit) === "time") {
859
+ if (unit && chunkPFUESQTW_cjs.getMeasure(unit) === "time") {
539
860
  try {
540
- return chunkNJTXJ5AG_cjs.convertUnit(value.toNumber(), unit, "ms");
861
+ return chunkPFUESQTW_cjs.convertUnit(value.toNumber(), unit, "ms");
541
862
  } catch {
542
863
  }
543
864
  }
@@ -545,10 +866,20 @@ function extractDurationMs(value) {
545
866
  }
546
867
  return value.toNumber();
547
868
  }
548
- function addBusinessDays(epochMs, n) {
549
- const date = new Date(epochMs);
869
+ var WORKDAYS_PER_YEAR = 260;
870
+ function addBusinessDays(epochMs, n, vm) {
550
871
  let remaining = Math.trunc(Math.abs(n));
551
872
  const direction = n >= 0 ? 1 : -1;
873
+ const limitYears = direction > 0 ? vm.getMaxDateOffsetYears() : -vm.getMinDateOffsetYears();
874
+ const limitWorkdays = Math.floor(limitYears * WORKDAYS_PER_YEAR);
875
+ if (remaining > limitWorkdays) {
876
+ throw chunk5KMIY374_cjs.ErrorFactory.execution(
877
+ "DATE_OFFSET_LIMIT_EXCEEDED",
878
+ `A date offset of ${remaining.toLocaleString("en-US")} workdays is about ${Math.round(remaining / WORKDAYS_PER_YEAR).toLocaleString("en-US")} years, past the limit of ${limitYears} years for a workday offset`,
879
+ { requestedWorkdays: remaining, limitYears, limitWorkdays }
880
+ );
881
+ }
882
+ const date = new Date(epochMs);
552
883
  while (remaining > 0) {
553
884
  date.setDate(date.getDate() + direction);
554
885
  const day = date.getDay();
@@ -556,44 +887,153 @@ function addBusinessDays(epochMs, n) {
556
887
  }
557
888
  return date.getTime();
558
889
  }
890
+ var MS_PER_DAY = 864e5;
891
+ var CALENDAR_MONTHS_PER_UNIT = {
892
+ month: 1,
893
+ months: 1,
894
+ mo: 1,
895
+ year: 12,
896
+ years: 12,
897
+ yr: 12,
898
+ y: 12,
899
+ a: 12,
900
+ decade: 120,
901
+ decades: 120,
902
+ dec: 120,
903
+ century: 1200,
904
+ centuries: 1200,
905
+ millennium: 12e3,
906
+ millennia: 12e3
907
+ };
908
+ function daysInMonth(year, monthIndex) {
909
+ return new Date(year, monthIndex + 1, 0).getDate();
910
+ }
911
+ function addCalendarDays(epochMs, days) {
912
+ const whole = Math.trunc(days);
913
+ const date = new Date(epochMs);
914
+ date.setDate(date.getDate() + whole);
915
+ const shifted = date.getTime();
916
+ if (Number.isNaN(shifted)) return epochMs + days * MS_PER_DAY;
917
+ return shifted + (days - whole) * MS_PER_DAY;
918
+ }
919
+ function addCalendarMonths(epochMs, months) {
920
+ const whole = Math.trunc(months);
921
+ const date = new Date(epochMs);
922
+ const dayOfMonth = date.getDate();
923
+ date.setDate(1);
924
+ date.setMonth(date.getMonth() + whole);
925
+ date.setDate(Math.min(dayOfMonth, daysInMonth(date.getFullYear(), date.getMonth())));
926
+ const shifted = date.getTime();
927
+ const monthMs = chunkPFUESQTW_cjs.convertUnit(1, "month", "ms");
928
+ if (Number.isNaN(shifted)) return epochMs + months * monthMs;
929
+ return shifted + (months - whole) * monthMs;
930
+ }
931
+ function shiftDatetime(epochMs, duration, sign, vm) {
932
+ if (duration.type === 6 /* Uom */ && duration.unit !== void 0) {
933
+ const unit = duration.unit;
934
+ const amount = sign * duration.toNumber();
935
+ if (chunkPFUESQTW_cjs.isWorkdayUnit(unit)) return addBusinessDays(epochMs, amount, vm);
936
+ const monthsPerUnit = CALENDAR_MONTHS_PER_UNIT[unit];
937
+ if (monthsPerUnit !== void 0) return addCalendarMonths(epochMs, amount * monthsPerUnit);
938
+ if (chunkPFUESQTW_cjs.getMeasure(unit) === "time") {
939
+ let daysPerUnit = 0;
940
+ try {
941
+ daysPerUnit = chunkPFUESQTW_cjs.convertUnit(1, unit, "day");
942
+ } catch {
943
+ }
944
+ if (Number.isInteger(daysPerUnit) && daysPerUnit >= 1) {
945
+ return addCalendarDays(epochMs, amount * daysPerUnit);
946
+ }
947
+ }
948
+ }
949
+ return epochMs + sign * extractDurationMs(duration);
950
+ }
559
951
  function combineTimecode(tc, r, sign) {
560
- const fps = chunkOC6LTXYS_cjs.timecodeFps(tc.unit);
561
- if (r.type === 6 /* Uom */ && chunkOC6LTXYS_cjs.isTimecodeUnit(r.unit)) {
562
- const rFps = chunkOC6LTXYS_cjs.timecodeFps(r.unit);
952
+ const fps = chunkJMXUNXQS_cjs.timecodeFps(tc.unit);
953
+ if (r.type === 6 /* Uom */ && chunkJMXUNXQS_cjs.isTimecodeUnit(r.unit)) {
954
+ const rFps = chunkJMXUNXQS_cjs.timecodeFps(r.unit);
563
955
  if (rFps !== fps) {
564
- return chunkOC6LTXYS_cjs.errorValue(
956
+ return chunkJMXUNXQS_cjs.errorValue(
565
957
  "TIMECODE_FPS_MISMATCH",
566
958
  `Cannot combine timecodes at different frame rates (${fps} fps vs ${rFps} fps)`
567
959
  );
568
960
  }
569
- return sign === 1 ? chunkOC6LTXYS_cjs.uomValue(tc.toNumber() + r.toNumber(), tc.unit) : chunkOC6LTXYS_cjs.uomValue(tc.toNumber() - r.toNumber(), "frames");
961
+ return sign === 1 ? chunkJMXUNXQS_cjs.uomValue(tc.toNumber() + r.toNumber(), tc.unit) : chunkJMXUNXQS_cjs.uomValue(tc.toNumber() - r.toNumber(), "frames");
570
962
  }
571
963
  if (r.type === 6 /* Uom */ && r.unit === "frames") {
572
- return chunkOC6LTXYS_cjs.uomValue(tc.toNumber() + sign * r.toNumber(), tc.unit);
964
+ return chunkJMXUNXQS_cjs.uomValue(tc.toNumber() + sign * r.toNumber(), tc.unit);
573
965
  }
574
- if (r.type === 6 /* Uom */ && r.unit && chunkNJTXJ5AG_cjs.getMeasure(r.unit) === "time") {
575
- const seconds = chunkNJTXJ5AG_cjs.convertUnit(r.toNumber(), r.unit, "s");
576
- return chunkOC6LTXYS_cjs.uomValue(tc.toNumber() + sign * seconds * fps, tc.unit);
966
+ if (r.type === 6 /* Uom */ && r.unit && chunkPFUESQTW_cjs.getMeasure(r.unit) === "time") {
967
+ const seconds = chunkPFUESQTW_cjs.convertUnit(r.toNumber(), r.unit, "s");
968
+ return chunkJMXUNXQS_cjs.uomValue(tc.toNumber() + sign * seconds * fps, tc.unit);
577
969
  }
578
- return chunkOC6LTXYS_cjs.uomValue(tc.toNumber() + sign * r.toNumber(), tc.unit);
970
+ return chunkJMXUNXQS_cjs.uomValue(tc.toNumber() + sign * r.toNumber(), tc.unit);
579
971
  }
580
972
  function isTruthy(value) {
581
973
  if (value.type === 10 /* Boolean */) return value.value;
582
974
  return value.toNumber() !== 0;
583
975
  }
976
+ function incompatibleConversionError(fromUnit, toUnit) {
977
+ return chunkJMXUNXQS_cjs.errorValue(
978
+ "INCOMPATIBLE_UNITS",
979
+ `Cannot convert ${fromUnit} to ${toUnit}: they do not measure the same thing`
980
+ );
981
+ }
982
+ var MAX_EXACT_POW_BITS = 65536;
983
+ function exactPowBits(base, exponent) {
984
+ if (!Number.isInteger(exponent) || exponent < 0) return null;
985
+ if (exponent === 0) return 1;
986
+ const magnitude = Math.abs(base.toNumber());
987
+ if (magnitude <= 1) return 1;
988
+ const baseBits = magnitude <= 2 ? 1 : Math.log2(magnitude);
989
+ return baseBits * exponent;
990
+ }
991
+ function bigIntPow(base, exponent) {
992
+ let result = 1n;
993
+ let factor = base;
994
+ let remaining = exponent;
995
+ while (remaining > 0n) {
996
+ if (remaining % 2n === 1n) result *= factor;
997
+ remaining /= 2n;
998
+ if (remaining > 0n) factor *= factor;
999
+ }
1000
+ return result;
1001
+ }
1002
+ var MAX_EXACT_SHIFT_BITS = MAX_EXACT_POW_BITS;
1003
+ function bigIntBitLength(value) {
1004
+ const magnitude = value < 0n ? -value : value;
1005
+ if (magnitude === 0n) return 0;
1006
+ const asDouble = Number(magnitude);
1007
+ if (Number.isFinite(asDouble)) return Math.floor(Math.log2(asDouble)) + 1;
1008
+ return magnitude.toString(16).length * 4;
1009
+ }
1010
+ function bigIntShift(l, r, direction) {
1011
+ const value = chunk6WFMPTGB_cjs.toBigIntOperand(l);
1012
+ const shift = chunk6WFMPTGB_cjs.toBigIntOperand(r);
1013
+ if (value === 0n) return chunkJMXUNXQS_cjs.bigIntValue(0n);
1014
+ const grownBits = direction * Number(shift);
1015
+ if (grownBits <= 0 || bigIntBitLength(value) + grownBits <= MAX_EXACT_SHIFT_BITS) {
1016
+ return chunkJMXUNXQS_cjs.bigIntValue(direction === 1 ? value << shift : value >> shift);
1017
+ }
1018
+ throw chunk5KMIY374_cjs.ErrorFactory.execution(
1019
+ "BIGINT_SHIFT_LIMIT_EXCEEDED",
1020
+ `Shifting by ${shift} would build an exact integer of about ${(bigIntBitLength(value) + grownBits).toLocaleString("en-US")} bits, past the limit of ${MAX_EXACT_SHIFT_BITS.toLocaleString("en-US")} bits`,
1021
+ { shift: String(shift), limitBits: MAX_EXACT_SHIFT_BITS }
1022
+ );
1023
+ }
584
1024
  function multiplyRateByMatchingUom(rate, multiplier) {
585
- const { numerator, denominator } = chunkOC6LTXYS_cjs.splitRateUnit(rate.unit);
586
- const rateMeasure = chunkNJTXJ5AG_cjs.getMeasure(denominator);
587
- const multiplierMeasure = chunkNJTXJ5AG_cjs.getMeasure(multiplier.unit);
1025
+ const { numerator, denominator } = chunkJMXUNXQS_cjs.splitRateUnit(rate.unit);
1026
+ const rateMeasure = chunkPFUESQTW_cjs.getMeasure(denominator);
1027
+ const multiplierMeasure = chunkPFUESQTW_cjs.getMeasure(multiplier.unit);
588
1028
  if (!rateMeasure || rateMeasure !== multiplierMeasure) {
589
- return chunkOC6LTXYS_cjs.errorValue(
1029
+ return chunkJMXUNXQS_cjs.errorValue(
590
1030
  "RATE_MUL_MEASURE_MISMATCH",
591
1031
  `Cannot multiply a "${denominator}"-denominated rate by "${multiplier.unit}" \u2014 different measures`
592
1032
  );
593
1033
  }
594
- const multiplierInDenominatorUnit = chunkNJTXJ5AG_cjs.convertUnit(multiplier.toNumber(), multiplier.unit, denominator);
1034
+ const multiplierInDenominatorUnit = chunkPFUESQTW_cjs.convertUnit(multiplier.toNumber(), multiplier.unit, denominator);
595
1035
  const total = rate.toNumber() * multiplierInDenominatorUnit;
596
- return numerator ? chunkOC6LTXYS_cjs.uomValue(total, numerator) : chunkOC6LTXYS_cjs.numberValue(total);
1036
+ return numerator ? chunkJMXUNXQS_cjs.uomValue(total, numerator) : chunkJMXUNXQS_cjs.numberValue(total);
597
1037
  }
598
1038
  function toFractionString(n) {
599
1039
  if (Number.isNaN(n)) return "NaN";
@@ -628,12 +1068,26 @@ function toMultiplierString(value) {
628
1068
  return `${Math.round(multiple * 1e6) / 1e6}x`;
629
1069
  }
630
1070
  function toScientificString(n) {
1071
+ if (!Number.isFinite(n)) return String(n);
631
1072
  if (n === 0) return "0e+0";
632
1073
  const [mantissa, exponent] = n.toExponential().split("e");
633
1074
  const trimmed = mantissa.includes(".") ? mantissa.replace(/0+$/, "").replace(/\.$/, "") : mantissa;
634
1075
  return `${trimmed}e${exponent}`;
635
1076
  }
636
1077
  function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTolerant) {
1078
+ const unrunnable = unrunnableProgram(bytecode);
1079
+ if (unrunnable) {
1080
+ return {
1081
+ type: "error",
1082
+ error: chunk5KMIY374_cjs.ErrorFactory.validation({
1083
+ code: "MALFORMED_BYTECODE_PROGRAM",
1084
+ message: `Malformed bytecode: ${unrunnable}`,
1085
+ expected: "a BytecodeProgram with opcodes, numbers and strings",
1086
+ found: unrunnable,
1087
+ suggestion: MALFORMED_BYTECODE_SUGGESTION
1088
+ })
1089
+ };
1090
+ }
637
1091
  const { opcodes, numbers, strings, userFunctionBodies, anonymousBodies } = bytecode;
638
1092
  let ip = 0;
639
1093
  let localInstructionCount = 0;
@@ -641,15 +1095,16 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
641
1095
  const maxStackDepth = vm.getMaxStackDepth();
642
1096
  const stack = vm.getStack();
643
1097
  const shouldTrace = pipeline?.hasCollectors ?? false;
644
- const hasArena = chunkOC6LTXYS_cjs.isArenaActive();
645
- if (opcodes.length === 0) return { type: "value", value: chunkOC6LTXYS_cjs.numberValue(0) };
1098
+ const hasArena = chunkJMXUNXQS_cjs.isArenaActive();
1099
+ if (opcodes.length === 0) return { type: "value", value: chunkJMXUNXQS_cjs.numberValue(0) };
1100
+ chunkJMXUNXQS_cjs.beginEvaluation(vm);
646
1101
  try {
647
1102
  while (ip < opcodes.length) {
648
1103
  if (++localInstructionCount > maxInstructions) {
649
- throw chunkM4N5GA5Z_cjs.ErrorFactory.execution("INSTRUCTION_LIMIT_EXCEEDED", `Execution exceeded maximum of ${maxInstructions} instructions`);
1104
+ throw chunk5KMIY374_cjs.ErrorFactory.execution("INSTRUCTION_LIMIT_EXCEEDED", `Execution exceeded maximum of ${maxInstructions} instructions`);
650
1105
  }
651
1106
  if (stack.length > maxStackDepth) {
652
- throw chunkM4N5GA5Z_cjs.ErrorFactory.execution("STACK_LIMIT_EXCEEDED", `Execution exceeded maximum stack depth of ${maxStackDepth}`);
1107
+ throw chunk5KMIY374_cjs.ErrorFactory.execution("STACK_LIMIT_EXCEEDED", `Execution exceeded maximum stack depth of ${maxStackDepth}`);
653
1108
  }
654
1109
  const op = opcodes[ip++];
655
1110
  if (shouldTrace) {
@@ -663,7 +1118,7 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
663
1118
  elapsedNs: 0,
664
1119
  expression: expression ?? "",
665
1120
  opcode: op,
666
- opcodeName: chunkMZOVP3WI_cjs.getOpCodeName(op),
1121
+ opcodeName: chunk6KFYJ6TD_cjs.getOpCodeName(op),
667
1122
  ip: ip - 1,
668
1123
  stackDepth: stack.length,
669
1124
  instructionNumber: localInstructionCount,
@@ -678,11 +1133,14 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
678
1133
  break;
679
1134
  case 1 /* HALT */: {
680
1135
  const result = safePop(stack);
681
- return { type: "value", value: hasArena ? chunkOC6LTXYS_cjs.persistentValue(result) : result };
1136
+ return { type: "value", value: hasArena ? chunkJMXUNXQS_cjs.persistentValue(result) : result };
682
1137
  }
683
- case 3 /* DUP */:
684
- stack.push(stack[stack.length - 1]);
1138
+ case 3 /* DUP */: {
1139
+ const top = safePop(stack);
1140
+ stack.push(top);
1141
+ stack.push(top);
685
1142
  break;
1143
+ }
686
1144
  case 2 /* SWAP */: {
687
1145
  const a = safePop(stack), b = safePop(stack);
688
1146
  stack.push(a);
@@ -692,20 +1150,25 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
692
1150
  // ═══════════════════════════════════════════════════════════════
693
1151
  // §2 Push literals (OpCode 10–15)
694
1152
  // ═══════════════════════════════════════════════════════════════
1153
+ // Every operand below goes through a checked read. An index past the
1154
+ // end of a pool used to yield `undefined` and be pushed as a Value,
1155
+ // which then failed somewhere else entirely: PUSH_BIGINT reached
1156
+ // `BigInt(undefined)`, and an undefined string sat on the stack until
1157
+ // a unit or converter name was read off it.
695
1158
  case 10 /* PUSH_NUMBER */:
696
- stack.push(chunkOC6LTXYS_cjs.numberValue(numbers[opcodes[ip++]]));
1159
+ stack.push(chunkJMXUNXQS_cjs.numberValue(numbers[poolIndex(opcodes, ip++, op, "constant-pool index", numbers.length, "number-pool")]));
697
1160
  break;
698
1161
  case 11 /* PUSH_BIGINT */:
699
- stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(strings[opcodes[ip++]])));
1162
+ stack.push(chunkJMXUNXQS_cjs.bigIntValue(parseBigIntLiteral(poolString(opcodes, ip++, strings, op, "constant-pool index"), op)));
700
1163
  break;
701
1164
  case 12 /* PUSH_HEX */:
702
- stack.push(chunkOC6LTXYS_cjs.hexValue(numbers[opcodes[ip++]]));
1165
+ stack.push(chunkJMXUNXQS_cjs.hexValue(numbers[poolIndex(opcodes, ip++, op, "constant-pool index", numbers.length, "number-pool")]));
703
1166
  break;
704
1167
  case 13 /* PUSH_STRING */:
705
- stack.push(chunkOC6LTXYS_cjs.stringValue(strings[opcodes[ip++]]));
1168
+ stack.push(chunkJMXUNXQS_cjs.stringValue(poolString(opcodes, ip++, strings, op, "constant-pool index")));
706
1169
  break;
707
1170
  case 14 /* PUSH_BOOLEAN */:
708
- stack.push(chunkOC6LTXYS_cjs.boolValue(opcodes[ip++] === 1));
1171
+ stack.push(chunkJMXUNXQS_cjs.boolValue(operandByte(opcodes, ip++, op, "boolean operand") === 1));
709
1172
  break;
710
1173
  // ═══════════════════════════════════════════════════════════════
711
1174
  // §3 Arithmetic (OpCode 20–27)
@@ -714,92 +1177,112 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
714
1177
  // ═══════════════════════════════════════════════════════════════
715
1178
  case 20 /* ADD */: {
716
1179
  const r = safePop(stack), l = safePop(stack);
1180
+ const addFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1181
+ if (addFault) {
1182
+ stack.push(addFault);
1183
+ break;
1184
+ }
717
1185
  const pctAdd = combinePercentage(l, r, 1);
718
1186
  const ratePeriodAdd = pctAdd === null ? unifyRatePeriods(l, r) : null;
719
1187
  if (pctAdd !== null) {
720
1188
  stack.push(pctAdd);
721
1189
  } else if (ratePeriodAdd !== null) {
722
- stack.push(chunkOC6LTXYS_cjs.uomValue(ratePeriodAdd + r.toNumber(), r.unit));
1190
+ stack.push(chunkJMXUNXQS_cjs.uomValue(ratePeriodAdd + r.toNumber(), r.unit));
723
1191
  } else if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
724
- stack.push(chunkOC6LTXYS_cjs.numberValue(l.value + r.value));
1192
+ stack.push(chunkJMXUNXQS_cjs.numberValue(l.value + r.value));
725
1193
  } else if (l.type === 10 /* Boolean */ && r.type === 10 /* Boolean */) {
726
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.value && r.value));
1194
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.value && r.value));
727
1195
  } else if (l.type === 4 /* Datetime */) {
728
1196
  if (r.type === 4 /* Datetime */) {
729
- stack.push(chunkOC6LTXYS_cjs.errorValue("INVALID_DATETIME_OP", "Cannot add two datetimes together"));
730
- } else if (r.type === 6 /* Uom */ && chunkNJTXJ5AG_cjs.isWorkdayUnit(r.unit)) {
731
- stack.push(chunkOC6LTXYS_cjs.datetimeValue(addBusinessDays(l.toNumber(), r.toNumber())));
1197
+ stack.push(chunkJMXUNXQS_cjs.errorValue("INVALID_DATETIME_OP", "Cannot add two datetimes together"));
732
1198
  } else {
733
- stack.push(chunkOC6LTXYS_cjs.datetimeValue(l.toNumber() + extractDurationMs(r)));
1199
+ stack.push(chunkJMXUNXQS_cjs.datetimeValue(shiftDatetime(l.toNumber(), r, 1, vm)));
734
1200
  }
735
- } else if (l.type === 6 /* Uom */ && chunkOC6LTXYS_cjs.isTimecodeUnit(l.unit)) {
1201
+ } else if (l.type === 6 /* Uom */ && chunkJMXUNXQS_cjs.isTimecodeUnit(l.unit)) {
736
1202
  stack.push(combineTimecode(l, r, 1));
1203
+ } else if (r.type === 4 /* Datetime */) {
1204
+ stack.push(chunkJMXUNXQS_cjs.datetimeValue(shiftDatetime(r.toNumber(), l, 1, vm)));
737
1205
  } else {
738
- stack.push(chunkBXKJLM5R_cjs.binaryOp(l, r, (a, b) => a + b, (a, b) => a + b, "add"));
1206
+ stack.push(chunk6WFMPTGB_cjs.binaryOp(l, r, (a, b) => a + b, (a, b) => a + b, "add"));
739
1207
  }
740
1208
  break;
741
1209
  }
742
1210
  case 21 /* SUB */: {
743
1211
  const r = safePop(stack), l = safePop(stack);
1212
+ const subFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1213
+ if (subFault) {
1214
+ stack.push(subFault);
1215
+ break;
1216
+ }
744
1217
  const pctSub = combinePercentage(l, r, -1);
745
1218
  const ratePeriodSub = pctSub === null ? unifyRatePeriods(l, r) : null;
746
1219
  if (pctSub !== null) {
747
1220
  stack.push(pctSub);
748
1221
  } else if (ratePeriodSub !== null) {
749
- stack.push(chunkOC6LTXYS_cjs.uomValue(ratePeriodSub - r.toNumber(), r.unit));
1222
+ stack.push(chunkJMXUNXQS_cjs.uomValue(ratePeriodSub - r.toNumber(), r.unit));
750
1223
  } else if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
751
- stack.push(chunkOC6LTXYS_cjs.numberValue(l.value - r.value));
1224
+ stack.push(chunkJMXUNXQS_cjs.numberValue(l.value - r.value));
752
1225
  } else if (l.type === 4 /* Datetime */) {
753
1226
  if (r.type === 4 /* Datetime */) {
754
- stack.push(chunkOC6LTXYS_cjs.uomValue(l.toNumber() - r.toNumber(), "ms"));
755
- } else if (r.type === 6 /* Uom */ && chunkNJTXJ5AG_cjs.isWorkdayUnit(r.unit)) {
756
- stack.push(chunkOC6LTXYS_cjs.datetimeValue(addBusinessDays(l.toNumber(), -r.toNumber())));
1227
+ stack.push(chunkJMXUNXQS_cjs.uomValue(l.toNumber() - r.toNumber(), "ms"));
757
1228
  } else {
758
- stack.push(chunkOC6LTXYS_cjs.datetimeValue(l.toNumber() - extractDurationMs(r)));
1229
+ stack.push(chunkJMXUNXQS_cjs.datetimeValue(shiftDatetime(l.toNumber(), r, -1, vm)));
759
1230
  }
760
- } else if (l.type === 6 /* Uom */ && chunkOC6LTXYS_cjs.isTimecodeUnit(l.unit)) {
1231
+ } else if (l.type === 6 /* Uom */ && chunkJMXUNXQS_cjs.isTimecodeUnit(l.unit)) {
761
1232
  stack.push(combineTimecode(l, r, -1));
1233
+ } else if (r.type === 4 /* Datetime */) {
1234
+ stack.push(chunkJMXUNXQS_cjs.errorValue(
1235
+ "INVALID_DATETIME_OP",
1236
+ "Cannot subtract a datetime from a value that is not a datetime"
1237
+ ));
762
1238
  } else {
763
- stack.push(chunkBXKJLM5R_cjs.binaryOp(l, r, (a, b) => a - b, (a, b) => a - b, "sub"));
1239
+ stack.push(chunk6WFMPTGB_cjs.binaryOp(l, r, (a, b) => a - b, (a, b) => a - b, "sub"));
764
1240
  }
765
1241
  break;
766
1242
  }
767
1243
  case 22 /* MUL */: {
768
1244
  const r = safePop(stack), l = safePop(stack);
769
1245
  if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
770
- stack.push(chunkOC6LTXYS_cjs.numberValue(l.value * r.value));
1246
+ stack.push(chunkJMXUNXQS_cjs.numberValue(l.value * r.value));
771
1247
  } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
772
- stack.push(chunk4CVLFLOB_cjs.matrixMultiply(l.value, r.value));
773
- } else if (l.type === 6 /* Uom */ && chunkOC6LTXYS_cjs.isRateUnit(l.unit) && r.type === 6 /* Uom */ && r.unit) {
1248
+ chunkJMXUNXQS_cjs.checkAllocation(matrixProductCells(l.value, r.value), "matrix cells");
1249
+ stack.push(chunkUM6BVY2S_cjs.matrixMultiply(l.value, r.value));
1250
+ } else if (l.type === 6 /* Uom */ && chunkJMXUNXQS_cjs.isRateUnit(l.unit) && r.type === 6 /* Uom */ && r.unit) {
774
1251
  stack.push(multiplyRateByMatchingUom(l, r));
775
- } else if (r.type === 6 /* Uom */ && chunkOC6LTXYS_cjs.isRateUnit(r.unit) && l.type === 6 /* Uom */ && l.unit) {
1252
+ } else if (r.type === 6 /* Uom */ && chunkJMXUNXQS_cjs.isRateUnit(r.unit) && l.type === 6 /* Uom */ && l.unit) {
776
1253
  stack.push(multiplyRateByMatchingUom(r, l));
777
1254
  } else if (moneyTimesQuantity(l, r) !== null) {
778
1255
  stack.push(moneyTimesQuantity(l, r));
779
1256
  } else {
780
- stack.push(chunkBXKJLM5R_cjs.binaryOp(l, r, (a, b) => a * b, (a, b) => a * b, "mul"));
1257
+ stack.push(chunk6WFMPTGB_cjs.binaryOp(l, r, (a, b) => a * b, (a, b) => a * b, "mul"));
781
1258
  }
782
1259
  break;
783
1260
  }
784
1261
  case 23 /* DIV */: {
785
1262
  const r = safePop(stack), l = safePop(stack);
786
1263
  if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
787
- const { lv, rv, sameMeasure } = chunkBXKJLM5R_cjs.unifyUom(l, r);
1264
+ const { lv, rv, sameMeasure } = chunk6WFMPTGB_cjs.unifyUom(l, r);
788
1265
  if (sameMeasure) {
789
- stack.push(chunkOC6LTXYS_cjs.numberValue(lv / rv));
790
- } else if (chunk2MV4HBKC_cjs.sharedCurrencyExchange.isCurrency(l.unit) && chunk2MV4HBKC_cjs.sharedCurrencyExchange.isCurrency(r.unit)) {
791
- stack.push(chunkOC6LTXYS_cjs.errorValue("INCOMPATIBLE_UNITS", `Cannot combine incompatible units: ${l.unit} and ${r.unit}`));
1266
+ stack.push(chunkJMXUNXQS_cjs.numberValue(lv / rv));
1267
+ } else if (chunkA2N2GFCG_cjs.sharedCurrencyExchange.isCurrency(l.unit) && chunkA2N2GFCG_cjs.sharedCurrencyExchange.isCurrency(r.unit)) {
1268
+ stack.push(chunkJMXUNXQS_cjs.errorValue("INCOMPATIBLE_UNITS", `Cannot combine incompatible units: ${l.unit} and ${r.unit}`));
792
1269
  } else {
793
- stack.push(chunkOC6LTXYS_cjs.rateValue(lv / rv, l.unit, r.unit));
1270
+ stack.push(chunkJMXUNXQS_cjs.rateValue(lv / rv, l.unit, r.unit));
794
1271
  }
795
1272
  } else {
796
- stack.push(chunkBXKJLM5R_cjs.binaryOp(l, r, (a, b) => a / b, (a, b) => a / b, "div"));
1273
+ stack.push(chunk6WFMPTGB_cjs.binaryOp(l, r, (a, b) => a / b, (a, b) => {
1274
+ if (b === 0n) throw chunk6WFMPTGB_cjs.bigIntDivisionByZero();
1275
+ return a / b;
1276
+ }, "div"));
797
1277
  }
798
1278
  break;
799
1279
  }
800
1280
  case 24 /* MOD */: {
801
1281
  const r = safePop(stack), l = safePop(stack);
802
- stack.push(chunkBXKJLM5R_cjs.binaryOp(l, r, (a, b) => a % b, (a, b) => a % b));
1282
+ stack.push(chunk6WFMPTGB_cjs.binaryOp(l, r, (a, b) => a % b, (a, b) => {
1283
+ if (b === 0n) throw chunk6WFMPTGB_cjs.bigIntDivisionByZero();
1284
+ return a % b;
1285
+ }));
803
1286
  break;
804
1287
  }
805
1288
  case 25 /* EXP */: {
@@ -821,183 +1304,367 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
821
1304
  break;
822
1305
  }
823
1306
  if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
824
- stack.push(chunkOC6LTXYS_cjs.numberValue(Math.pow(l.value, r.value)));
1307
+ stack.push(chunkJMXUNXQS_cjs.numberValue(chunk6WFMPTGB_cjs.power(l.value, r.value)));
1308
+ break;
1309
+ }
1310
+ if (l.type === 7 /* Matrix */ || r.type === 7 /* Matrix */) {
1311
+ if (l.type !== 7 /* Matrix */ || r.type !== 0 /* Number */) {
1312
+ stack.push(chunkJMXUNXQS_cjs.errorValue(
1313
+ "MATRIX_POWER_UNSUPPORTED",
1314
+ `^: a matrix may only be the base, raised to a whole number (as in "[1,2;3,4]^2"); "${chunkJMXUNXQS_cjs.ValueType[l.type]} ^ ${chunkJMXUNXQS_cjs.ValueType[r.type]}" has no matrix reading.`
1315
+ ));
1316
+ break;
1317
+ }
1318
+ chunkJMXUNXQS_cjs.checkAllocation(matrixPowerCells(l.value, r.value), "matrix cells");
1319
+ stack.push(chunkUM6BVY2S_cjs.matrixPower(l.value, r.value));
825
1320
  break;
826
1321
  }
827
1322
  if (l.type === 9 /* Symbolic */ || r.type === 9 /* Symbolic */) {
828
- stack.push(chunkBXKJLM5R_cjs.symbolicPow(l, r));
1323
+ stack.push(chunk6WFMPTGB_cjs.symbolicPow(l, r));
829
1324
  break;
830
1325
  }
831
- stack.push(chunkOC6LTXYS_cjs.numberValue(Math.pow(l.toNumber(), r.toNumber())));
1326
+ if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
1327
+ const powBits = exactPowBits(l, r.toNumber());
1328
+ if (powBits !== null) {
1329
+ if (powBits > MAX_EXACT_POW_BITS) {
1330
+ throw chunk5KMIY374_cjs.ErrorFactory.execution(
1331
+ "BIGINT_POW_LIMIT_EXCEEDED",
1332
+ `That power would build an exact integer of about ${Math.round(powBits).toLocaleString("en-US")} bits, past the limit of ${MAX_EXACT_POW_BITS.toLocaleString("en-US")} bits`,
1333
+ { limitBits: MAX_EXACT_POW_BITS }
1334
+ );
1335
+ }
1336
+ stack.push(chunkJMXUNXQS_cjs.bigIntValue(bigIntPow(chunk6WFMPTGB_cjs.toBigIntOperand(l), chunk6WFMPTGB_cjs.toBigIntOperand(r))));
1337
+ break;
1338
+ }
1339
+ }
1340
+ stack.push(chunkJMXUNXQS_cjs.numberValue(chunk6WFMPTGB_cjs.power(l.toNumber(), r.toNumber())));
832
1341
  break;
833
1342
  }
834
1343
  case 26 /* NEG */: {
835
1344
  const v = safePop(stack);
836
- if (v.type === 2 /* BigInt */) stack.push(chunkOC6LTXYS_cjs.bigIntValue(-v.value));
837
- else if (v.type === 6 /* Uom */) stack.push(chunkOC6LTXYS_cjs.uomValue(-v.toNumber(), v.unit));
838
- else if (v.type === 9 /* Symbolic */) stack.push(chunkBXKJLM5R_cjs.symbolicNeg(v));
839
- else stack.push(chunkOC6LTXYS_cjs.numberValue(-v.toNumber()));
1345
+ const negFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1346
+ if (negFault) {
1347
+ stack.push(negFault);
1348
+ break;
1349
+ }
1350
+ if (v.type === 2 /* BigInt */) stack.push(chunkJMXUNXQS_cjs.bigIntValue(-v.value));
1351
+ else if (v.type === 6 /* Uom */) stack.push(chunkJMXUNXQS_cjs.uomValue(-v.toNumber(), v.unit));
1352
+ else if (v.type === 5 /* Percentage */) stack.push(chunkJMXUNXQS_cjs.percentageValue(-v.toNumber()));
1353
+ else if (v.type === 9 /* Symbolic */) stack.push(chunk6WFMPTGB_cjs.symbolicNeg(v));
1354
+ else stack.push(chunkJMXUNXQS_cjs.numberValue(-v.toNumber()));
840
1355
  break;
841
1356
  }
842
1357
  case 27 /* POS */: {
843
1358
  const v = safePop(stack);
844
- if (v.type === 6 /* Uom */) stack.push(chunkOC6LTXYS_cjs.uomValue(v.toNumber(), v.unit));
845
- else stack.push(chunkOC6LTXYS_cjs.numberValue(v.toNumber()));
1359
+ const posFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1360
+ if (posFault) {
1361
+ stack.push(posFault);
1362
+ break;
1363
+ }
1364
+ if (v.type === 6 /* Uom */) stack.push(chunkJMXUNXQS_cjs.uomValue(v.toNumber(), v.unit));
1365
+ else if (v.type === 5 /* Percentage */) stack.push(chunkJMXUNXQS_cjs.percentageValue(v.toNumber()));
1366
+ else stack.push(chunkJMXUNXQS_cjs.numberValue(v.toNumber()));
846
1367
  break;
847
1368
  }
848
1369
  // ═══════════════════════════════════════════════════════════════
849
1370
  // §4 Bitwise (OpCode 30–36)
1371
+ // None of these routes through binaryOp(), so each one carries
1372
+ // its own faulted-operand check for the reason that function
1373
+ // documents: a bit pattern read off an Error or a Pending is the
1374
+ // bit pattern of zero, and `(5 kg to m) & 1` answered 0 with
1375
+ // nothing to say it had not been asked a real question.
850
1376
  // ═══════════════════════════════════════════════════════════════
851
1377
  case 30 /* LSHIFT */: {
852
1378
  const r = safePop(stack), l = safePop(stack);
1379
+ const shiftFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1380
+ if (shiftFault) {
1381
+ stack.push(shiftFault);
1382
+ break;
1383
+ }
853
1384
  if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
854
- stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(l.toNumber()) << BigInt(r.toNumber())));
1385
+ stack.push(bigIntShift(l, r, 1));
855
1386
  } else {
856
- stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() << r.toNumber()));
1387
+ stack.push(chunkJMXUNXQS_cjs.numberValue(l.toNumber() << r.toNumber()));
857
1388
  }
858
1389
  break;
859
1390
  }
860
1391
  case 31 /* RSHIFT */: {
861
1392
  const r = safePop(stack), l = safePop(stack);
1393
+ const rshiftFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1394
+ if (rshiftFault) {
1395
+ stack.push(rshiftFault);
1396
+ break;
1397
+ }
862
1398
  if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
863
- stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(l.toNumber()) >> BigInt(r.toNumber())));
1399
+ stack.push(bigIntShift(l, r, -1));
864
1400
  } else {
865
- stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() >> r.toNumber()));
1401
+ stack.push(chunkJMXUNXQS_cjs.numberValue(l.toNumber() >> r.toNumber()));
866
1402
  }
867
1403
  break;
868
1404
  }
869
1405
  case 32 /* URSHIFT */: {
870
1406
  const r = safePop(stack), l = safePop(stack);
871
- stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() >>> r.toNumber()));
1407
+ const urshiftFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1408
+ if (urshiftFault) {
1409
+ stack.push(urshiftFault);
1410
+ break;
1411
+ }
1412
+ stack.push(chunkJMXUNXQS_cjs.numberValue(l.toNumber() >>> r.toNumber()));
872
1413
  break;
873
1414
  }
874
1415
  case 33 /* BIT_AND */: {
875
1416
  const r = safePop(stack), l = safePop(stack);
1417
+ const andFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1418
+ if (andFault) {
1419
+ stack.push(andFault);
1420
+ break;
1421
+ }
876
1422
  if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
877
- stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(l.toNumber()) & BigInt(r.toNumber())));
1423
+ stack.push(chunkJMXUNXQS_cjs.bigIntValue(chunk6WFMPTGB_cjs.toBigIntOperand(l) & chunk6WFMPTGB_cjs.toBigIntOperand(r)));
878
1424
  } else {
879
- stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() & r.toNumber()));
1425
+ stack.push(chunkJMXUNXQS_cjs.numberValue(l.toNumber() & r.toNumber()));
880
1426
  }
881
1427
  break;
882
1428
  }
883
1429
  case 34 /* BIT_OR */: {
884
1430
  const r = safePop(stack), l = safePop(stack);
1431
+ const orFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1432
+ if (orFault) {
1433
+ stack.push(orFault);
1434
+ break;
1435
+ }
885
1436
  if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
886
- stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(l.toNumber()) | BigInt(r.toNumber())));
1437
+ stack.push(chunkJMXUNXQS_cjs.bigIntValue(chunk6WFMPTGB_cjs.toBigIntOperand(l) | chunk6WFMPTGB_cjs.toBigIntOperand(r)));
887
1438
  } else {
888
- stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() | r.toNumber()));
1439
+ stack.push(chunkJMXUNXQS_cjs.numberValue(l.toNumber() | r.toNumber()));
889
1440
  }
890
1441
  break;
891
1442
  }
892
1443
  case 35 /* BIT_XOR */: {
893
1444
  const r = safePop(stack), l = safePop(stack);
1445
+ const xorFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1446
+ if (xorFault) {
1447
+ stack.push(xorFault);
1448
+ break;
1449
+ }
894
1450
  if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
895
- stack.push(chunkOC6LTXYS_cjs.bigIntValue(BigInt(l.toNumber()) ^ BigInt(r.toNumber())));
1451
+ stack.push(chunkJMXUNXQS_cjs.bigIntValue(chunk6WFMPTGB_cjs.toBigIntOperand(l) ^ chunk6WFMPTGB_cjs.toBigIntOperand(r)));
896
1452
  } else {
897
- stack.push(chunkOC6LTXYS_cjs.numberValue(l.toNumber() ^ r.toNumber()));
1453
+ stack.push(chunkJMXUNXQS_cjs.numberValue(l.toNumber() ^ r.toNumber()));
898
1454
  }
899
1455
  break;
900
1456
  }
901
1457
  case 36 /* BIT_NOT */: {
902
1458
  const v = safePop(stack);
903
- if (v.type === 2 /* BigInt */) stack.push(chunkOC6LTXYS_cjs.bigIntValue(~v.value));
904
- else stack.push(chunkOC6LTXYS_cjs.numberValue(~v.toNumber()));
1459
+ const notFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1460
+ if (notFault) {
1461
+ stack.push(notFault);
1462
+ break;
1463
+ }
1464
+ if (v.type === 2 /* BigInt */) stack.push(chunkJMXUNXQS_cjs.bigIntValue(~v.value));
1465
+ else stack.push(chunkJMXUNXQS_cjs.numberValue(~v.toNumber()));
905
1466
  break;
906
1467
  }
907
1468
  // ═══════════════════════════════════════════════════════════════
908
1469
  // §4b Comparison (OpCode 40–45)
909
1470
  // Numeric fast path when both operands are Number;
910
- // EQ/NEQ support UoM unification for same-measure comparison.
1471
+ // all six unify UoM operands before comparing them.
1472
+ //
1473
+ // The four ordering opcodes used to skip that unification and
1474
+ // compare the bare magnitudes, so `1 km > 500 m` answered false
1475
+ // and `30 min < 1 hour` answered false as well. They now go
1476
+ // through compareUom() like EQ/NEQ, which also means they agree
1477
+ // with EQ about where the boundary between "less" and "equal"
1478
+ // falls: `equal` there is a tolerance rather than `===`, so a
1479
+ // pair EQ calls equal is one GT and LT both call false.
1480
+ //
1481
+ // Two units that share no measure cannot be ordered at all, so
1482
+ // the four ordering opcodes answer with an error rather than a
1483
+ // boolean. EQ and NEQ still answer with a boolean, because
1484
+ // "a kilogram is not a metre" is a true statement about a pair
1485
+ // that cannot be converted, whereas "a kilogram is less than a
1486
+ // metre" is not a statement at all.
1487
+ //
1488
+ // A faulted operand is the second case even for EQ and NEQ, and
1489
+ // all six propagate it. A kilogram is a quantity that is not a
1490
+ // metre; an Error is not a quantity, so there is nothing for it
1491
+ // to be equal to. Reading its number gave zero, which made
1492
+ // `(5 kg to m) == 0` answer true.
911
1493
  // ═══════════════════════════════════════════════════════════════
912
1494
  case 40 /* EQ */: {
913
1495
  const r = safePop(stack), l = safePop(stack);
1496
+ const eqFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1497
+ if (eqFault) {
1498
+ stack.push(eqFault);
1499
+ break;
1500
+ }
914
1501
  if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
915
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.value === r.value));
1502
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.value === r.value));
1503
+ } else if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
1504
+ const cmp = chunk6WFMPTGB_cjs.compareBigIntOperands(l, r);
1505
+ stack.push(chunkJMXUNXQS_cjs.boolValue(cmp === null ? l.toNumber() === r.toNumber() : cmp === 0));
1506
+ } else if (l.type === 3 /* String */ && r.type === 3 /* String */) {
1507
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.value === r.value));
916
1508
  } else if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
917
- const { lv, rv, sameMeasure } = chunkBXKJLM5R_cjs.unifyUom(l, r);
918
- stack.push(chunkOC6LTXYS_cjs.boolValue(sameMeasure && lv === rv));
1509
+ const { equal, sameMeasure } = chunk6WFMPTGB_cjs.compareUom(l, r);
1510
+ stack.push(chunkJMXUNXQS_cjs.boolValue(sameMeasure && equal));
919
1511
  } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
920
- stack.push(chunk4CVLFLOB_cjs.matrixCompare(l.value, r.value, (a, b) => a === b));
1512
+ stack.push(chunkUM6BVY2S_cjs.matrixCompare(l.value, r.value, (a, b) => a === b));
921
1513
  } else {
922
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() === r.toNumber()));
1514
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.toNumber() === r.toNumber()));
923
1515
  }
924
1516
  break;
925
1517
  }
926
1518
  case 41 /* NEQ */: {
927
1519
  const r = safePop(stack), l = safePop(stack);
1520
+ const neqFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1521
+ if (neqFault) {
1522
+ stack.push(neqFault);
1523
+ break;
1524
+ }
928
1525
  if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
929
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.value !== r.value));
1526
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.value !== r.value));
1527
+ } else if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
1528
+ const cmp = chunk6WFMPTGB_cjs.compareBigIntOperands(l, r);
1529
+ stack.push(chunkJMXUNXQS_cjs.boolValue(cmp === null ? l.toNumber() !== r.toNumber() : cmp !== 0));
1530
+ } else if (l.type === 3 /* String */ && r.type === 3 /* String */) {
1531
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.value !== r.value));
930
1532
  } else if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
931
- const { lv, rv, sameMeasure } = chunkBXKJLM5R_cjs.unifyUom(l, r);
932
- stack.push(chunkOC6LTXYS_cjs.boolValue(!sameMeasure || lv !== rv));
1533
+ const { equal, sameMeasure } = chunk6WFMPTGB_cjs.compareUom(l, r);
1534
+ stack.push(chunkJMXUNXQS_cjs.boolValue(!sameMeasure || !equal));
933
1535
  } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
934
- stack.push(chunk4CVLFLOB_cjs.matrixCompare(l.value, r.value, (a, b) => a !== b));
1536
+ stack.push(chunkUM6BVY2S_cjs.matrixCompare(l.value, r.value, (a, b) => a !== b));
935
1537
  } else {
936
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() !== r.toNumber()));
1538
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.toNumber() !== r.toNumber()));
937
1539
  }
938
1540
  break;
939
1541
  }
940
1542
  case 42 /* LT */: {
941
1543
  const r = safePop(stack), l = safePop(stack);
1544
+ const ltFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1545
+ if (ltFault) {
1546
+ stack.push(ltFault);
1547
+ break;
1548
+ }
942
1549
  if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
943
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.value < r.value));
1550
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.value < r.value));
1551
+ } else if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
1552
+ const cmp = chunk6WFMPTGB_cjs.compareBigIntOperands(l, r);
1553
+ stack.push(chunkJMXUNXQS_cjs.boolValue(cmp === null ? l.toNumber() < r.toNumber() : cmp < 0));
1554
+ } else if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
1555
+ const { lv, rv, equal, sameMeasure } = chunk6WFMPTGB_cjs.compareUom(l, r);
1556
+ stack.push(sameMeasure ? chunkJMXUNXQS_cjs.boolValue(!equal && lv < rv) : chunk6WFMPTGB_cjs.incomparableUnitsError(l, r));
944
1557
  } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
945
- stack.push(chunk4CVLFLOB_cjs.matrixCompare(l.value, r.value, (a, b) => a < b));
1558
+ stack.push(chunkUM6BVY2S_cjs.matrixCompare(l.value, r.value, (a, b) => a < b));
946
1559
  } else {
947
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() < r.toNumber()));
1560
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.toNumber() < r.toNumber()));
948
1561
  }
949
1562
  break;
950
1563
  }
951
1564
  case 43 /* LTE */: {
952
1565
  const r = safePop(stack), l = safePop(stack);
1566
+ const lteFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1567
+ if (lteFault) {
1568
+ stack.push(lteFault);
1569
+ break;
1570
+ }
953
1571
  if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
954
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.value <= r.value));
1572
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.value <= r.value));
1573
+ } else if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
1574
+ const cmp = chunk6WFMPTGB_cjs.compareBigIntOperands(l, r);
1575
+ stack.push(chunkJMXUNXQS_cjs.boolValue(cmp === null ? l.toNumber() <= r.toNumber() : cmp <= 0));
1576
+ } else if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
1577
+ const { lv, rv, equal, sameMeasure } = chunk6WFMPTGB_cjs.compareUom(l, r);
1578
+ stack.push(sameMeasure ? chunkJMXUNXQS_cjs.boolValue(equal || lv <= rv) : chunk6WFMPTGB_cjs.incomparableUnitsError(l, r));
955
1579
  } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
956
- stack.push(chunk4CVLFLOB_cjs.matrixCompare(l.value, r.value, (a, b) => a <= b));
1580
+ stack.push(chunkUM6BVY2S_cjs.matrixCompare(l.value, r.value, (a, b) => a <= b));
957
1581
  } else {
958
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() <= r.toNumber()));
1582
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.toNumber() <= r.toNumber()));
959
1583
  }
960
1584
  break;
961
1585
  }
962
1586
  case 44 /* GT */: {
963
1587
  const r = safePop(stack), l = safePop(stack);
1588
+ const gtFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1589
+ if (gtFault) {
1590
+ stack.push(gtFault);
1591
+ break;
1592
+ }
964
1593
  if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
965
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.value > r.value));
1594
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.value > r.value));
1595
+ } else if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
1596
+ const cmp = chunk6WFMPTGB_cjs.compareBigIntOperands(l, r);
1597
+ stack.push(chunkJMXUNXQS_cjs.boolValue(cmp === null ? l.toNumber() > r.toNumber() : cmp > 0));
1598
+ } else if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
1599
+ const { lv, rv, equal, sameMeasure } = chunk6WFMPTGB_cjs.compareUom(l, r);
1600
+ stack.push(sameMeasure ? chunkJMXUNXQS_cjs.boolValue(!equal && lv > rv) : chunk6WFMPTGB_cjs.incomparableUnitsError(l, r));
966
1601
  } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
967
- stack.push(chunk4CVLFLOB_cjs.matrixCompare(l.value, r.value, (a, b) => a > b));
1602
+ stack.push(chunkUM6BVY2S_cjs.matrixCompare(l.value, r.value, (a, b) => a > b));
968
1603
  } else {
969
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() > r.toNumber()));
1604
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.toNumber() > r.toNumber()));
970
1605
  }
971
1606
  break;
972
1607
  }
973
1608
  case 45 /* GTE */: {
974
1609
  const r = safePop(stack), l = safePop(stack);
1610
+ const gteFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1611
+ if (gteFault) {
1612
+ stack.push(gteFault);
1613
+ break;
1614
+ }
975
1615
  if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
976
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.value >= r.value));
1616
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.value >= r.value));
1617
+ } else if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
1618
+ const cmp = chunk6WFMPTGB_cjs.compareBigIntOperands(l, r);
1619
+ stack.push(chunkJMXUNXQS_cjs.boolValue(cmp === null ? l.toNumber() >= r.toNumber() : cmp >= 0));
1620
+ } else if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */) {
1621
+ const { lv, rv, equal, sameMeasure } = chunk6WFMPTGB_cjs.compareUom(l, r);
1622
+ stack.push(sameMeasure ? chunkJMXUNXQS_cjs.boolValue(equal || lv >= rv) : chunk6WFMPTGB_cjs.incomparableUnitsError(l, r));
977
1623
  } else if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
978
- stack.push(chunk4CVLFLOB_cjs.matrixCompare(l.value, r.value, (a, b) => a >= b));
1624
+ stack.push(chunkUM6BVY2S_cjs.matrixCompare(l.value, r.value, (a, b) => a >= b));
979
1625
  } else {
980
- stack.push(chunkOC6LTXYS_cjs.boolValue(l.toNumber() >= r.toNumber()));
1626
+ stack.push(chunkJMXUNXQS_cjs.boolValue(l.toNumber() >= r.toNumber()));
981
1627
  }
982
1628
  break;
983
1629
  }
984
1630
  // ═══════════════════════════════════════════════════════════════
985
1631
  // §4c Logical / conditional select (OpCode 130–132)
1632
+ //
1633
+ // Truthiness is read through isTruthy(), which reads a number,
1634
+ // which is zero for a fault, so a failed operand used to be
1635
+ // quietly false. Both operands are already evaluated by the time
1636
+ // either opcode runs (this VM has no branch opcodes), so there is
1637
+ // no short-circuit to preserve by ignoring the right-hand one.
986
1638
  // ═══════════════════════════════════════════════════════════════
987
1639
  case 130 /* LOGICAL_AND */: {
988
1640
  const r = safePop(stack), l = safePop(stack);
989
- stack.push(chunkOC6LTXYS_cjs.boolValue(isTruthy(l) && isTruthy(r)));
1641
+ const andLogicFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1642
+ if (andLogicFault) {
1643
+ stack.push(andLogicFault);
1644
+ break;
1645
+ }
1646
+ stack.push(chunkJMXUNXQS_cjs.boolValue(isTruthy(l) && isTruthy(r)));
990
1647
  break;
991
1648
  }
992
1649
  case 131 /* LOGICAL_OR */: {
993
1650
  const r = safePop(stack), l = safePop(stack);
994
- stack.push(chunkOC6LTXYS_cjs.boolValue(isTruthy(l) || isTruthy(r)));
1651
+ const orLogicFault = chunkJMXUNXQS_cjs.faultedOperand(l, r);
1652
+ if (orLogicFault) {
1653
+ stack.push(orLogicFault);
1654
+ break;
1655
+ }
1656
+ stack.push(chunkJMXUNXQS_cjs.boolValue(isTruthy(l) || isTruthy(r)));
995
1657
  break;
996
1658
  }
997
1659
  case 132 /* SELECT */: {
998
1660
  const elseVal = safePop(stack);
999
1661
  const thenVal = safePop(stack);
1000
1662
  const condition = safePop(stack);
1663
+ const conditionFault = chunkJMXUNXQS_cjs.faultedOperand(condition);
1664
+ if (conditionFault) {
1665
+ stack.push(conditionFault);
1666
+ break;
1667
+ }
1001
1668
  stack.push(isTruthy(condition) ? thenVal : elseVal);
1002
1669
  break;
1003
1670
  }
@@ -1005,14 +1672,17 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1005
1672
  // §5 Functions (OpCode 50–52)
1006
1673
  // ═══════════════════════════════════════════════════════════════
1007
1674
  case 50 /* CALL_PLUGIN */: {
1008
- const fnIdx = opcodes[ip++];
1009
- const argCount = opcodes[ip++];
1675
+ const fnIdx = operandByte(opcodes, ip++, op, "plugin-function index");
1676
+ const argCount = operandByte(opcodes, ip++, op, "argument count");
1010
1677
  const args = [];
1011
1678
  for (let i = 0; i < argCount; i++) args.push(safePop(stack));
1012
1679
  args.reverse();
1013
1680
  const fn = vm.context.pluginFunctions[fnIdx];
1014
- if (!fn) {
1015
- stack.push(chunkOC6LTXYS_cjs.numberValue(0));
1681
+ const pluginArgFault = chunkJMXUNXQS_cjs.faultedIn(args);
1682
+ if (pluginArgFault) {
1683
+ stack.push(pluginArgFault);
1684
+ } else if (!fn) {
1685
+ stack.push(chunkJMXUNXQS_cjs.numberValue(0));
1016
1686
  } else {
1017
1687
  const result = fn(args, context);
1018
1688
  if (result instanceof Promise) {
@@ -1026,8 +1696,10 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1026
1696
  break;
1027
1697
  }
1028
1698
  case 51 /* CALL_BUILTIN */: {
1029
- const fnIdx = opcodes[ip++];
1030
- const argCount = opcodes[ip++];
1699
+ const fnIdx = operandByte(opcodes, ip++, op, "builtin-function index");
1700
+ const argCount = operandByte(opcodes, ip++, op, "argument count");
1701
+ const arityError = builtinArityError(fnIdx, argCount);
1702
+ if (arityError) throw arityError;
1031
1703
  const args = [];
1032
1704
  let sawSymbolic = false;
1033
1705
  for (let i = 0; i < argCount; i++) {
@@ -1035,19 +1707,24 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1035
1707
  if (arg.type === 9 /* Symbolic */) sawSymbolic = true;
1036
1708
  args.push(arg);
1037
1709
  }
1038
- const fn = chunkBXKJLM5R_cjs.builtinFunctions[fnIdx];
1710
+ const builtinArgFault = chunkJMXUNXQS_cjs.faultedIn(args);
1711
+ if (builtinArgFault) {
1712
+ stack.push(builtinArgFault);
1713
+ break;
1714
+ }
1715
+ const fn = chunk6WFMPTGB_cjs.builtinFunctions[fnIdx];
1039
1716
  if (fn) {
1040
1717
  const ordered = args.reverse();
1041
- const routeSymbolically = sawSymbolic && !chunkBXKJLM5R_cjs.SYMBOLIC_NATIVE_BUILTINS.has(fnIdx);
1042
- stack.push(routeSymbolically ? chunkBXKJLM5R_cjs.symbolicBuiltin(fnIdx, ordered) : fn(ordered));
1718
+ const routeSymbolically = sawSymbolic && !chunk6WFMPTGB_cjs.SYMBOLIC_NATIVE_BUILTINS.has(fnIdx);
1719
+ stack.push(routeSymbolically ? chunk6WFMPTGB_cjs.symbolicBuiltin(fnIdx, ordered) : fn(ordered));
1043
1720
  }
1044
1721
  break;
1045
1722
  }
1046
1723
  case 150 /* DEFINE_USER_FUNCTION */: {
1047
- const bodyIdx = opcodes[ip++];
1724
+ const bodyIdx = operandByte(opcodes, ip++, op, "function-body index");
1048
1725
  const def = userFunctionBodies?.[bodyIdx];
1049
1726
  if (!def) {
1050
- throw chunkM4N5GA5Z_cjs.ErrorFactory.internal(
1727
+ throw chunk5KMIY374_cjs.ErrorFactory.internal(
1051
1728
  "INTERNAL_MISSING_FUNCTION_BODY",
1052
1729
  `Internal error: DEFINE_USER_FUNCTION referenced missing body index ${bodyIdx}`,
1053
1730
  { bodyIdx }
@@ -1057,18 +1734,17 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1057
1734
  break;
1058
1735
  }
1059
1736
  case 151 /* CALL_USER_FUNCTION */: {
1060
- const nameIdx = opcodes[ip++];
1061
- const argCount = opcodes[ip++];
1062
- const name = strings[nameIdx];
1737
+ const name = poolString(opcodes, ip++, strings, op, "function-name index");
1738
+ const argCount = operandByte(opcodes, ip++, op, "argument count");
1063
1739
  const args = [];
1064
1740
  for (let i = 0; i < argCount; i++) args.push(safePop(stack));
1065
1741
  args.reverse();
1066
1742
  const fn = vm.getUserFunction(name);
1067
1743
  if (!fn) {
1068
- throw chunkM4N5GA5Z_cjs.ErrorFactory.execution("UNDEFINED_FUNCTION", `Undefined function: ${name}`, { name });
1744
+ throw chunk5KMIY374_cjs.ErrorFactory.execution("UNDEFINED_FUNCTION", `Undefined function: ${name}`, { name });
1069
1745
  }
1070
1746
  if (argCount !== fn.params.length) {
1071
- throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
1747
+ throw chunk5KMIY374_cjs.ErrorFactory.execution(
1072
1748
  "FUNCTION_ARITY_MISMATCH",
1073
1749
  `${name} expects ${fn.params.length} argument(s) but got ${argCount}`,
1074
1750
  { name, expected: fn.params.length, actual: argCount }
@@ -1076,6 +1752,7 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1076
1752
  }
1077
1753
  const frame = /* @__PURE__ */ new Map();
1078
1754
  for (let i = 0; i < fn.params.length; i++) frame.set(fn.params[i], args[i]);
1755
+ chunkJMXUNXQS_cjs.chargeFunctionCall();
1079
1756
  vm.pushCallFrame(frame);
1080
1757
  let bodyResult;
1081
1758
  try {
@@ -1084,7 +1761,7 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1084
1761
  vm.popCallFrame();
1085
1762
  }
1086
1763
  if (bodyResult.type === "pending") {
1087
- throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
1764
+ throw chunk5KMIY374_cjs.ErrorFactory.execution(
1088
1765
  "USER_FUNCTION_ASYNC_UNSUPPORTED",
1089
1766
  `${name}: user-defined functions with async bodies (weather, stocks, currency, ...) aren't supported`,
1090
1767
  { name }
@@ -1100,14 +1777,14 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1100
1777
  // §6 Variables (OpCode 60–63)
1101
1778
  // ═══════════════════════════════════════════════════════════════
1102
1779
  case 60 /* LOAD_VAR */: {
1103
- const varName = strings[opcodes[ip++]];
1780
+ const varName = poolString(opcodes, ip++, strings, op, "variable-name index");
1104
1781
  const val = vm.getVar(varName);
1105
1782
  if (val !== void 0) {
1106
1783
  stack.push(val);
1107
1784
  } else if (symbolicTolerant) {
1108
- stack.push(chunkOC6LTXYS_cjs.symbolicValue(chunk4CVLFLOB_cjs.varNode(varName)));
1785
+ stack.push(chunkJMXUNXQS_cjs.symbolicValue(chunkUM6BVY2S_cjs.varNode(varName)));
1109
1786
  } else {
1110
- throw chunkM4N5GA5Z_cjs.ErrorFactory.execution(
1787
+ throw chunk5KMIY374_cjs.ErrorFactory.execution(
1111
1788
  "UNDEFINED_VARIABLE",
1112
1789
  `Undefined variable: ${varName}`,
1113
1790
  { varName }
@@ -1117,16 +1794,16 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1117
1794
  }
1118
1795
  case 61 /* STORE_VAR */: {
1119
1796
  const val = safePop(stack);
1120
- const varName = strings[opcodes[ip++]];
1121
- vm.setVar(varName, hasArena ? chunkOC6LTXYS_cjs.persistentValue(val) : val);
1797
+ const varName = poolString(opcodes, ip++, strings, op, "variable-name index");
1798
+ vm.setVar(varName, hasArena ? chunkJMXUNXQS_cjs.persistentValue(val) : val);
1122
1799
  stack.push(val);
1123
1800
  break;
1124
1801
  }
1125
1802
  case 62 /* LOAD_GLOBAL_VAR */: {
1126
- const varName = strings[opcodes[ip++]];
1127
- const globalValue = chunkBXKJLM5R_cjs.sharedGlobalVariableStore.get(varName);
1803
+ const varName = poolString(opcodes, ip++, strings, op, "variable-name index");
1804
+ const globalValue = chunk6WFMPTGB_cjs.sharedGlobalVariableStore.get(varName);
1128
1805
  if (globalValue === void 0) {
1129
- throw chunkM4N5GA5Z_cjs.ErrorFactory.internal({
1806
+ throw chunk5KMIY374_cjs.ErrorFactory.internal({
1130
1807
  code: "GLOBAL_VARIABLE_NOT_RESOLVED",
1131
1808
  message: `Global variable "${varName}" was read before it resolved`,
1132
1809
  expected: `global variable "${varName}" to already be resolved (async preflight should guarantee this)`,
@@ -1139,62 +1816,111 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1139
1816
  }
1140
1817
  case 63 /* STORE_GLOBAL_VAR */: {
1141
1818
  const val = safePop(stack);
1142
- const varName = strings[opcodes[ip++]];
1143
- chunkBXKJLM5R_cjs.sharedGlobalVariableStore.set(varName, hasArena ? chunkOC6LTXYS_cjs.persistentValue(val) : val);
1819
+ const varName = poolString(opcodes, ip++, strings, op, "variable-name index");
1820
+ chunk6WFMPTGB_cjs.sharedGlobalVariableStore.set(varName, hasArena ? chunkJMXUNXQS_cjs.persistentValue(val) : val);
1144
1821
  stack.push(val);
1145
1822
  break;
1146
1823
  }
1147
1824
  // ═══════════════════════════════════════════════════════════════
1148
1825
  // §7 Type conversions (OpCode 70–74, 140–145)
1826
+ // Every one of these restates a number in another notation, so a
1827
+ // faulted operand has nothing to restate and each propagates it
1828
+ // rather than converting the zero toNumber() reports. Without it
1829
+ // "(5 kg to m) as hex" answered 0x0 and "as binary" answered 0b0.
1149
1830
  // ═══════════════════════════════════════════════════════════════
1150
1831
  case 70 /* TO_NUMBER */: {
1151
1832
  const v = safePop(stack);
1152
- stack.push(chunkOC6LTXYS_cjs.numberValue(v.toNumber()));
1833
+ const toNumberFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1834
+ if (toNumberFault) {
1835
+ stack.push(toNumberFault);
1836
+ break;
1837
+ }
1838
+ stack.push(chunkJMXUNXQS_cjs.numberValue(v.toNumber()));
1153
1839
  break;
1154
1840
  }
1155
1841
  case 71 /* TO_HEX */: {
1156
1842
  const v = safePop(stack);
1157
- stack.push(chunkOC6LTXYS_cjs.hexValue(v.toNumber()));
1843
+ const toHexFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1844
+ if (toHexFault) {
1845
+ stack.push(toHexFault);
1846
+ break;
1847
+ }
1848
+ stack.push(chunkJMXUNXQS_cjs.hexValue(v.type === 2 /* BigInt */ ? v.value : v.toNumber()));
1158
1849
  break;
1159
1850
  }
1160
1851
  case 74 /* TO_PERCENTAGE */: {
1161
1852
  const v = safePop(stack);
1162
- stack.push(chunkOC6LTXYS_cjs.percentageValue(v.toNumber()));
1853
+ const toPercentageFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1854
+ if (toPercentageFault) {
1855
+ stack.push(toPercentageFault);
1856
+ break;
1857
+ }
1858
+ stack.push(chunkJMXUNXQS_cjs.percentageValue(v.toNumber()));
1163
1859
  break;
1164
1860
  }
1165
1861
  case 140 /* TO_FRACTION */: {
1166
1862
  const v = safePop(stack);
1167
- stack.push(chunkOC6LTXYS_cjs.stringValue(toFractionString(v.toNumber())));
1863
+ const toFractionFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1864
+ if (toFractionFault) {
1865
+ stack.push(toFractionFault);
1866
+ break;
1867
+ }
1868
+ stack.push(chunkJMXUNXQS_cjs.stringValue(toFractionString(v.toNumber())));
1168
1869
  break;
1169
1870
  }
1170
1871
  case 141 /* TO_MULTIPLIER */: {
1171
1872
  const v = safePop(stack);
1172
- stack.push(chunkOC6LTXYS_cjs.stringValue(toMultiplierString(v)));
1873
+ const toMultiplierFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1874
+ if (toMultiplierFault) {
1875
+ stack.push(toMultiplierFault);
1876
+ break;
1877
+ }
1878
+ stack.push(chunkJMXUNXQS_cjs.stringValue(toMultiplierString(v)));
1173
1879
  break;
1174
1880
  }
1175
1881
  case 142 /* TO_SCI */: {
1176
1882
  const v = safePop(stack);
1177
- stack.push(chunkOC6LTXYS_cjs.stringValue(toScientificString(v.toNumber())));
1883
+ const toSciFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1884
+ if (toSciFault) {
1885
+ stack.push(toSciFault);
1886
+ break;
1887
+ }
1888
+ stack.push(chunkJMXUNXQS_cjs.stringValue(toScientificString(v.toNumber())));
1178
1889
  break;
1179
1890
  }
1180
1891
  // Numeric, like TO_HEX above. A base is a way of writing a number, so
1181
1892
  // `(255 as binary) + 1` has to be 256; as a string it was 1.
1182
1893
  case 143 /* TO_BINARY */: {
1183
1894
  const v = safePop(stack);
1184
- stack.push(chunkOC6LTXYS_cjs.hexValue(v.toNumber(), "bin"));
1895
+ const toBinaryFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1896
+ if (toBinaryFault) {
1897
+ stack.push(toBinaryFault);
1898
+ break;
1899
+ }
1900
+ stack.push(chunkJMXUNXQS_cjs.hexValue(v.type === 2 /* BigInt */ ? v.value : v.toNumber(), "bin"));
1185
1901
  break;
1186
1902
  }
1187
1903
  case 144 /* TO_OCTAL */: {
1188
1904
  const v = safePop(stack);
1189
- stack.push(chunkOC6LTXYS_cjs.hexValue(v.toNumber(), "oct"));
1905
+ const toOctalFault = chunkJMXUNXQS_cjs.faultedOperand(v);
1906
+ if (toOctalFault) {
1907
+ stack.push(toOctalFault);
1908
+ break;
1909
+ }
1910
+ stack.push(chunkJMXUNXQS_cjs.hexValue(v.type === 2 /* BigInt */ ? v.value : v.toNumber(), "oct"));
1190
1911
  break;
1191
1912
  }
1192
1913
  case 145 /* CALL_AS_CONVERTER */: {
1193
- const name = safePop(stack).value.toLowerCase();
1914
+ const name = stringOperand(safePop(stack), op, "converter name").toLowerCase();
1194
1915
  const value = safePop(stack);
1195
- const converter = chunkBXKJLM5R_cjs.asConverterRegistry.get(name);
1916
+ const converterFault = chunkJMXUNXQS_cjs.faultedOperand(value);
1917
+ if (converterFault) {
1918
+ stack.push(converterFault);
1919
+ break;
1920
+ }
1921
+ const converter = chunk6WFMPTGB_cjs.asConverterRegistry.get(name);
1196
1922
  if (!converter) {
1197
- stack.push(chunkOC6LTXYS_cjs.errorValue("UNKNOWN_AS_CONVERTER", `Unknown converter "as ${name}"`));
1923
+ stack.push(chunkJMXUNXQS_cjs.errorValue("UNKNOWN_AS_CONVERTER", `Unknown converter "as ${name}"`));
1198
1924
  } else {
1199
1925
  stack.push(converter(value));
1200
1926
  }
@@ -1204,72 +1930,98 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1204
1930
  // §8 UoM (OpCode 80–84)
1205
1931
  // ═══════════════════════════════════════════════════════════════
1206
1932
  case 80 /* UOM_CONVERT */: {
1207
- const unit = safePop(stack).value;
1208
- const val = safePop(stack).toNumber();
1209
- stack.push(chunkOC6LTXYS_cjs.uomValue(val, unit));
1933
+ const unit = stringOperand(safePop(stack), op, "unit name");
1934
+ const operand = safePop(stack);
1935
+ const faulted = chunkJMXUNXQS_cjs.faultedOperand(operand);
1936
+ if (faulted) {
1937
+ stack.push(faulted);
1938
+ break;
1939
+ }
1940
+ stack.push(chunkJMXUNXQS_cjs.uomValue(operand.toNumber(), unit));
1210
1941
  break;
1211
1942
  }
1212
1943
  case 81 /* UOM_CONVERT_TO */: {
1213
- const toUnit = safePop(stack).value;
1214
- const fromUnit = safePop(stack).value;
1215
- const val = safePop(stack).toNumber();
1216
- const measure = chunkNJTXJ5AG_cjs.getMeasure(fromUnit);
1217
- const isCurrency = chunk2MV4HBKC_cjs.sharedCurrencyExchange.isCurrency(fromUnit) && chunk2MV4HBKC_cjs.sharedCurrencyExchange.isCurrency(toUnit);
1218
- if (measure && chunkNJTXJ5AG_cjs.getMeasure(toUnit) === measure) {
1219
- stack.push(chunkOC6LTXYS_cjs.uomValue(chunkNJTXJ5AG_cjs.convertUnit(val, fromUnit, toUnit), toUnit));
1944
+ const toUnit = stringOperand(safePop(stack), op, "target unit name");
1945
+ const fromUnit = stringOperand(safePop(stack), op, "source unit name");
1946
+ const operand = safePop(stack);
1947
+ const faulted = chunkJMXUNXQS_cjs.faultedOperand(operand);
1948
+ if (faulted) {
1949
+ stack.push(faulted);
1950
+ break;
1951
+ }
1952
+ const val = operand.toNumber();
1953
+ const measure = chunkPFUESQTW_cjs.getMeasure(fromUnit);
1954
+ const isCurrency = chunkA2N2GFCG_cjs.sharedCurrencyExchange.isCurrency(fromUnit) && chunkA2N2GFCG_cjs.sharedCurrencyExchange.isCurrency(toUnit);
1955
+ if (measure && chunkPFUESQTW_cjs.getMeasure(toUnit) === measure) {
1956
+ stack.push(chunkJMXUNXQS_cjs.uomValue(chunkPFUESQTW_cjs.convertUnit(val, fromUnit, toUnit), toUnit));
1220
1957
  } else if (isCurrency) {
1221
- const converted = chunk2MV4HBKC_cjs.sharedCurrencyExchange.convertSync(val, fromUnit, toUnit);
1958
+ const converted = chunkA2N2GFCG_cjs.sharedCurrencyExchange.convertSync(val, fromUnit, toUnit);
1222
1959
  if (converted !== null) {
1223
- stack.push(chunkOC6LTXYS_cjs.uomValue(converted, toUnit));
1960
+ stack.push(chunkJMXUNXQS_cjs.uomValue(converted, toUnit));
1224
1961
  } else {
1225
- stack.push(chunkOC6LTXYS_cjs.errorValue("CURRENCY_RATE_UNAVAILABLE", `No exchange rate available for ${fromUnit} to ${toUnit}`));
1962
+ stack.push(chunkJMXUNXQS_cjs.errorValue("CURRENCY_RATE_UNAVAILABLE", `No exchange rate available for ${fromUnit} to ${toUnit}`));
1226
1963
  }
1227
1964
  } else {
1228
- stack.push(chunkOC6LTXYS_cjs.uomValue(val, fromUnit));
1965
+ stack.push(incompatibleConversionError(fromUnit, toUnit));
1229
1966
  }
1230
1967
  break;
1231
1968
  }
1232
1969
  case 85 /* UOM_POSSIBILITIES */: {
1233
- const unit = safePop(stack).value;
1234
- const possibilities = chunkNJTXJ5AG_cjs.getConvertiblePossibilities(unit);
1235
- stack.push(chunkOC6LTXYS_cjs.stringValue(possibilities.length > 0 ? possibilities.join(", ") : `No known units for "${unit}"`));
1970
+ const unit = stringOperand(safePop(stack), op, "unit name");
1971
+ const possibilities = chunkPFUESQTW_cjs.getConvertiblePossibilities(unit);
1972
+ stack.push(chunkJMXUNXQS_cjs.stringValue(possibilities.length > 0 ? possibilities.join(", ") : `No known units for "${unit}"`));
1236
1973
  break;
1237
1974
  }
1238
1975
  case 83 /* UOM_BEST */: {
1239
- const unit = safePop(stack).value;
1240
- const val = safePop(stack).toNumber();
1241
- const { value, unit: bestUnit } = chunkNJTXJ5AG_cjs.getBestUnit(val, unit);
1242
- stack.push(chunkOC6LTXYS_cjs.uomValue(value, bestUnit));
1976
+ const unit = stringOperand(safePop(stack), op, "unit name");
1977
+ const operand = safePop(stack);
1978
+ const faulted = chunkJMXUNXQS_cjs.faultedOperand(operand);
1979
+ if (faulted) {
1980
+ stack.push(faulted);
1981
+ break;
1982
+ }
1983
+ const { value, unit: bestUnit } = chunkPFUESQTW_cjs.getBestUnit(operand.toNumber(), unit);
1984
+ stack.push(chunkJMXUNXQS_cjs.uomValue(value, bestUnit));
1243
1985
  break;
1244
1986
  }
1245
1987
  case 84 /* UOM_CONVERT_IN */: {
1246
- const toUnit = safePop(stack).value;
1988
+ const toUnit = stringOperand(safePop(stack), op, "target unit name");
1247
1989
  const left = safePop(stack);
1990
+ const faulted = chunkJMXUNXQS_cjs.faultedOperand(left);
1991
+ if (faulted) {
1992
+ stack.push(faulted);
1993
+ break;
1994
+ }
1248
1995
  if (left.type === 6 /* Uom */) {
1249
1996
  const fromUnit = left.unit;
1250
1997
  const val = left.toNumber();
1251
- const measure = chunkNJTXJ5AG_cjs.getMeasure(fromUnit);
1252
- const isCurrency = chunk2MV4HBKC_cjs.sharedCurrencyExchange.isCurrency(fromUnit) && chunk2MV4HBKC_cjs.sharedCurrencyExchange.isCurrency(toUnit);
1253
- if (measure && chunkNJTXJ5AG_cjs.getMeasure(toUnit) === measure) {
1254
- stack.push(chunkOC6LTXYS_cjs.uomValue(chunkNJTXJ5AG_cjs.convertUnit(val, fromUnit, toUnit), toUnit));
1998
+ const measure = chunkPFUESQTW_cjs.getMeasure(fromUnit);
1999
+ const isCurrency = chunkA2N2GFCG_cjs.sharedCurrencyExchange.isCurrency(fromUnit) && chunkA2N2GFCG_cjs.sharedCurrencyExchange.isCurrency(toUnit);
2000
+ if (measure && chunkPFUESQTW_cjs.getMeasure(toUnit) === measure) {
2001
+ stack.push(chunkJMXUNXQS_cjs.uomValue(chunkPFUESQTW_cjs.convertUnit(val, fromUnit, toUnit), toUnit));
1255
2002
  } else if (isCurrency) {
1256
- const converted = chunk2MV4HBKC_cjs.sharedCurrencyExchange.convertSync(val, fromUnit, toUnit);
2003
+ const converted = chunkA2N2GFCG_cjs.sharedCurrencyExchange.convertSync(val, fromUnit, toUnit);
1257
2004
  if (converted !== null) {
1258
- stack.push(chunkOC6LTXYS_cjs.uomValue(converted, toUnit));
2005
+ stack.push(chunkJMXUNXQS_cjs.uomValue(converted, toUnit));
1259
2006
  } else {
1260
- stack.push(chunkOC6LTXYS_cjs.errorValue("CURRENCY_RATE_UNAVAILABLE", `No exchange rate available for ${fromUnit} to ${toUnit}`));
2007
+ stack.push(chunkJMXUNXQS_cjs.errorValue("CURRENCY_RATE_UNAVAILABLE", `No exchange rate available for ${fromUnit} to ${toUnit}`));
1261
2008
  }
1262
2009
  } else {
1263
- stack.push(left);
2010
+ stack.push(incompatibleConversionError(fromUnit, toUnit));
1264
2011
  }
1265
2012
  } else {
1266
- stack.push(chunkOC6LTXYS_cjs.uomValue(left.toNumber(), toUnit));
2013
+ stack.push(chunkJMXUNXQS_cjs.uomValue(left.toNumber(), toUnit));
1267
2014
  }
1268
2015
  break;
1269
2016
  }
1270
2017
  case 82 /* UOM_GET_VALUE */: {
1271
2018
  const v = safePop(stack);
1272
- stack.push(chunkOC6LTXYS_cjs.numberValue(v.toNumber()));
2019
+ const getValueFault = chunkJMXUNXQS_cjs.faultedOperand(v);
2020
+ if (getValueFault) {
2021
+ stack.push(getValueFault);
2022
+ break;
2023
+ }
2024
+ stack.push(chunkJMXUNXQS_cjs.numberValue(v.toNumber()));
1273
2025
  break;
1274
2026
  }
1275
2027
  // ═══════════════════════════════════════════════════════════════
@@ -1279,89 +2031,125 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1279
2031
  case 110 /* RATE_DIV */: {
1280
2032
  const denominatorVal = safePop(stack);
1281
2033
  const numeratorVal = safePop(stack);
2034
+ const rateDivFault = chunkJMXUNXQS_cjs.faultedOperand(numeratorVal, denominatorVal);
2035
+ if (rateDivFault) {
2036
+ stack.push(rateDivFault);
2037
+ break;
2038
+ }
1282
2039
  if (denominatorVal.type !== 6 /* Uom */ || !denominatorVal.unit) {
1283
- stack.push(chunkOC6LTXYS_cjs.errorValue("RATE_MISSING_DENOMINATOR_UNIT", 'Cannot build a rate: the right-hand side of "/" has no unit'));
2040
+ stack.push(chunkJMXUNXQS_cjs.errorValue("RATE_MISSING_DENOMINATOR_UNIT", 'Cannot build a rate: the right-hand side of "/" has no unit'));
1284
2041
  break;
1285
2042
  }
1286
2043
  const numeratorUnit = numeratorVal.type === 6 /* Uom */ ? numeratorVal.unit ?? "" : "";
1287
- stack.push(chunkOC6LTXYS_cjs.rateValue(numeratorVal.toNumber() / denominatorVal.toNumber(), numeratorUnit, denominatorVal.unit));
2044
+ stack.push(chunkJMXUNXQS_cjs.rateValue(numeratorVal.toNumber() / denominatorVal.toNumber(), numeratorUnit, denominatorVal.unit));
1288
2045
  break;
1289
2046
  }
1290
2047
  case 111 /* RATE_MUL */: {
1291
2048
  const multiplier = safePop(stack);
1292
2049
  const rate = safePop(stack);
1293
- if (rate.type !== 6 /* Uom */ || !chunkOC6LTXYS_cjs.isRateUnit(rate.unit)) {
1294
- stack.push(chunkOC6LTXYS_cjs.errorValue("RATE_MUL_LEFT_NOT_A_RATE", 'Left-hand side of a rate multiplication must be a rate (e.g. "$50/week")'));
2050
+ const rateMulFault = chunkJMXUNXQS_cjs.faultedOperand(rate, multiplier);
2051
+ if (rateMulFault) {
2052
+ stack.push(rateMulFault);
2053
+ break;
2054
+ }
2055
+ if (rate.type !== 6 /* Uom */ || !chunkJMXUNXQS_cjs.isRateUnit(rate.unit)) {
2056
+ stack.push(chunkJMXUNXQS_cjs.errorValue("RATE_MUL_LEFT_NOT_A_RATE", 'Left-hand side of a rate multiplication must be a rate (e.g. "$50/week")'));
1295
2057
  break;
1296
2058
  }
1297
2059
  if (multiplier.type !== 6 /* Uom */ || !multiplier.unit) {
1298
- stack.push(chunkOC6LTXYS_cjs.errorValue("RATE_MUL_RIGHT_MISSING_UNIT", "Right-hand side of a rate multiplication must have a unit matching the rate's denominator"));
2060
+ stack.push(chunkJMXUNXQS_cjs.errorValue("RATE_MUL_RIGHT_MISSING_UNIT", "Right-hand side of a rate multiplication must have a unit matching the rate's denominator"));
1299
2061
  break;
1300
2062
  }
1301
2063
  stack.push(multiplyRateByMatchingUom(rate, multiplier));
1302
2064
  break;
1303
2065
  }
1304
2066
  case 112 /* RATE_CONVERT */: {
1305
- const newDenominatorUnit = safePop(stack).value;
2067
+ const newDenominatorUnit = stringOperand(safePop(stack), op, "denominator unit name");
1306
2068
  const rate = safePop(stack);
1307
- if (rate.type !== 6 /* Uom */ || !chunkOC6LTXYS_cjs.isRateUnit(rate.unit)) {
1308
- stack.push(chunkOC6LTXYS_cjs.errorValue("RATE_CONVERT_NOT_A_RATE", "Cannot convert a non-rate value's denominator"));
2069
+ const rateConvertFault = chunkJMXUNXQS_cjs.faultedOperand(rate);
2070
+ if (rateConvertFault) {
2071
+ stack.push(rateConvertFault);
1309
2072
  break;
1310
2073
  }
1311
- const { numerator, denominator } = chunkOC6LTXYS_cjs.splitRateUnit(rate.unit);
1312
- const rateMeasure = chunkNJTXJ5AG_cjs.getMeasure(denominator);
1313
- const targetMeasure = chunkNJTXJ5AG_cjs.getMeasure(newDenominatorUnit);
2074
+ if (rate.type !== 6 /* Uom */ || !chunkJMXUNXQS_cjs.isRateUnit(rate.unit)) {
2075
+ stack.push(chunkJMXUNXQS_cjs.errorValue("RATE_CONVERT_NOT_A_RATE", "Cannot convert a non-rate value's denominator"));
2076
+ break;
2077
+ }
2078
+ const { numerator, denominator } = chunkJMXUNXQS_cjs.splitRateUnit(rate.unit);
2079
+ const rateMeasure = chunkPFUESQTW_cjs.getMeasure(denominator);
2080
+ const targetMeasure = chunkPFUESQTW_cjs.getMeasure(newDenominatorUnit);
1314
2081
  if (!rateMeasure || rateMeasure !== targetMeasure) {
1315
- stack.push(chunkOC6LTXYS_cjs.errorValue(
2082
+ stack.push(chunkJMXUNXQS_cjs.errorValue(
1316
2083
  "RATE_CONVERT_MEASURE_MISMATCH",
1317
2084
  `Cannot convert a "${denominator}"-denominated rate to "${newDenominatorUnit}" \u2014 different measures`
1318
2085
  ));
1319
2086
  break;
1320
2087
  }
1321
- const factor = chunkNJTXJ5AG_cjs.convertUnit(1, newDenominatorUnit, denominator);
1322
- stack.push(chunkOC6LTXYS_cjs.rateValue(rate.toNumber() * factor, numerator, newDenominatorUnit));
2088
+ const factor = chunkPFUESQTW_cjs.convertUnit(1, newDenominatorUnit, denominator);
2089
+ stack.push(chunkJMXUNXQS_cjs.rateValue(rate.toNumber() * factor, numerator, newDenominatorUnit));
1323
2090
  break;
1324
2091
  }
1325
2092
  // ═══════════════════════════════════════════════════════════════
1326
2093
  // §8.7 Time, clock-time-of-day (OpCode 120)
1327
2094
  // ═══════════════════════════════════════════════════════════════
1328
2095
  case 120 /* CLOCK_TIME_TODAY */: {
1329
- const totalMinutes = safePop(stack).toNumber();
2096
+ const minutesValue = safePop(stack);
2097
+ const clockFault = chunkJMXUNXQS_cjs.faultedOperand(minutesValue);
2098
+ if (clockFault) {
2099
+ stack.push(clockFault);
2100
+ break;
2101
+ }
2102
+ const totalMinutes = minutesValue.toNumber();
1330
2103
  const now = /* @__PURE__ */ new Date();
1331
2104
  const anchored = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);
1332
2105
  anchored.setMinutes(totalMinutes);
1333
- stack.push(chunkOC6LTXYS_cjs.datetimeValue(anchored.getTime()));
2106
+ stack.push(chunkJMXUNXQS_cjs.datetimeValue(anchored.getTime()));
1334
2107
  break;
1335
2108
  }
1336
2109
  // ═══════════════════════════════════════════════════════════════
1337
2110
  // §9 Datetime (OpCode 90–93)
1338
2111
  // ═══════════════════════════════════════════════════════════════
1339
2112
  case 90 /* DATE_NOW */:
1340
- stack.push(chunkOC6LTXYS_cjs.datetimeValue(Date.now()));
2113
+ stack.push(chunkJMXUNXQS_cjs.datetimeValue(Date.now()));
1341
2114
  break;
1342
2115
  case 95 /* DATE_LITERAL */:
1343
- stack.push(chunkOC6LTXYS_cjs.datetimeValue(numbers[opcodes[ip++]]));
2116
+ stack.push(chunkJMXUNXQS_cjs.datetimeValue(numbers[poolIndex(opcodes, ip++, op, "constant-pool index", numbers.length, "number-pool")]));
1344
2117
  break;
1345
2118
  case 91 /* DATE_ADD */: {
1346
2119
  const durValue = safePop(stack), dtValue = safePop(stack);
1347
- stack.push(chunkOC6LTXYS_cjs.datetimeValue(dtValue.toNumber() + extractDurationMs(durValue)));
2120
+ const dateAddFault = chunkJMXUNXQS_cjs.faultedOperand(dtValue, durValue);
2121
+ if (dateAddFault) {
2122
+ stack.push(dateAddFault);
2123
+ break;
2124
+ }
2125
+ stack.push(chunkJMXUNXQS_cjs.datetimeValue(shiftDatetime(dtValue.toNumber(), durValue, 1, vm)));
1348
2126
  break;
1349
2127
  }
1350
2128
  case 92 /* DATE_SUB */: {
1351
2129
  const durValue = safePop(stack), dtValue = safePop(stack);
1352
- stack.push(chunkOC6LTXYS_cjs.datetimeValue(dtValue.toNumber() - extractDurationMs(durValue)));
2130
+ const dateSubFault = chunkJMXUNXQS_cjs.faultedOperand(dtValue, durValue);
2131
+ if (dateSubFault) {
2132
+ stack.push(dateSubFault);
2133
+ break;
2134
+ }
2135
+ stack.push(chunkJMXUNXQS_cjs.datetimeValue(shiftDatetime(dtValue.toNumber(), durValue, -1, vm)));
1353
2136
  break;
1354
2137
  }
1355
2138
  case 93 /* DATE_NEXT_WEEKDAY */:
1356
2139
  case 94 /* DATE_LAST_WEEKDAY */: {
1357
- const targetDay = safePop(stack).toNumber();
2140
+ const targetDayValue = safePop(stack);
1358
2141
  const nowValue = safePop(stack);
2142
+ const weekdayFault = chunkJMXUNXQS_cjs.faultedOperand(nowValue, targetDayValue);
2143
+ if (weekdayFault) {
2144
+ stack.push(weekdayFault);
2145
+ break;
2146
+ }
2147
+ const targetDay = targetDayValue.toNumber();
1359
2148
  const now = nowValue.toNumber();
1360
2149
  const currentDay = new Date(now).getDay();
1361
2150
  let diffDays = op === 93 /* DATE_NEXT_WEEKDAY */ ? (targetDay - currentDay + 7) % 7 : (currentDay - targetDay + 7) % 7;
1362
2151
  if (diffDays === 0) diffDays = 7;
1363
- const offsetMs = diffDays * 24 * 60 * 60 * 1e3;
1364
- stack.push(chunkOC6LTXYS_cjs.datetimeValue(op === 93 /* DATE_NEXT_WEEKDAY */ ? now + offsetMs : now - offsetMs));
2152
+ stack.push(chunkJMXUNXQS_cjs.datetimeValue(addCalendarDays(now, op === 93 /* DATE_NEXT_WEEKDAY */ ? diffDays : -diffDays)));
1365
2153
  break;
1366
2154
  }
1367
2155
  // ═══════════════════════════════════════════════════════════════
@@ -1373,133 +2161,119 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1373
2161
  // column-major storage helpers.
1374
2162
  // ═══════════════════════════════════════════════════════════════
1375
2163
  case 152 /* MAT_NEW */: {
1376
- const rows = opcodes[ip++];
1377
- const cols = opcodes[ip++];
2164
+ const rows = operandByte(opcodes, ip++, op, "row count");
2165
+ const cols = operandByte(opcodes, ip++, op, "column count");
1378
2166
  const count = rows * cols;
1379
- const rowMajor = new Array(count);
2167
+ const rowMajor = chunkJMXUNXQS_cjs.checkedArray(count, "matrix cells");
2168
+ let cellFault = null;
1380
2169
  for (let i = count - 1; i >= 0; i--) {
1381
2170
  const cellVal = safePop(stack);
2171
+ if (cellFault === null) cellFault = chunkJMXUNXQS_cjs.faultedOperand(cellVal);
1382
2172
  rowMajor[i] = cellVal.type === 10 /* Boolean */ ? cellVal.value : cellVal.type === 9 /* Symbolic */ ? cellVal.value : cellVal.toNumber();
1383
2173
  }
1384
- stack.push(chunkOC6LTXYS_cjs.matrixValue(rows, cols, chunk4CVLFLOB_cjs.rowMajorToColumnMajor(rows, cols, rowMajor)));
2174
+ if (cellFault) {
2175
+ stack.push(cellFault);
2176
+ break;
2177
+ }
2178
+ stack.push(chunkJMXUNXQS_cjs.matrixValue(rows, cols, chunkUM6BVY2S_cjs.rowMajorToColumnMajor(rows, cols, rowMajor)));
1385
2179
  break;
1386
2180
  }
1387
2181
  case 153 /* MAT_INDEX1 */: {
1388
2182
  const indexVal = safePop(stack), matrixVal = safePop(stack);
1389
- if (matrixVal.type === 13 /* Error */) {
1390
- stack.push(matrixVal);
1391
- break;
1392
- }
1393
- if (indexVal.type === 13 /* Error */) {
1394
- stack.push(indexVal);
2183
+ const index1Fault = chunkJMXUNXQS_cjs.faultedOperand(matrixVal, indexVal);
2184
+ if (index1Fault) {
2185
+ stack.push(index1Fault);
1395
2186
  break;
1396
2187
  }
1397
2188
  if (matrixVal.type !== 7 /* Matrix */) {
1398
- stack.push(chunkOC6LTXYS_cjs.errorValue("MATRIX_INDEX_NOT_A_MATRIX", `Cannot index a non-matrix value with "[...]".`));
2189
+ stack.push(chunkJMXUNXQS_cjs.errorValue("MATRIX_INDEX_NOT_A_MATRIX", `Cannot index a non-matrix value with "[...]".`));
1399
2190
  break;
1400
2191
  }
1401
2192
  const m = matrixVal.value;
1402
2193
  const index = Math.trunc(indexVal.toNumber());
1403
2194
  if (index < 0 || index >= m.data.length) {
1404
- stack.push(chunkOC6LTXYS_cjs.errorValue(
2195
+ stack.push(chunkJMXUNXQS_cjs.errorValue(
1405
2196
  "MATRIX_INDEX_OUT_OF_BOUNDS",
1406
2197
  `Index ${index} is out of bounds for a ${m.rows}x${m.cols} matrix (valid range: 0-${m.data.length - 1}).`
1407
2198
  ));
1408
2199
  break;
1409
2200
  }
1410
- const cell = chunk4CVLFLOB_cjs.matIndex(m, index);
1411
- stack.push(chunk4CVLFLOB_cjs.matrixEntryToValue(cell));
2201
+ const cell = chunkUM6BVY2S_cjs.matIndex(m, index);
2202
+ stack.push(chunkUM6BVY2S_cjs.matrixEntryToValue(cell));
1412
2203
  break;
1413
2204
  }
1414
2205
  case 154 /* MAT_INDEX2 */: {
1415
2206
  const colVal = safePop(stack), rowVal = safePop(stack), matrixVal = safePop(stack);
1416
- if (matrixVal.type === 13 /* Error */) {
1417
- stack.push(matrixVal);
1418
- break;
1419
- }
1420
- if (rowVal.type === 13 /* Error */) {
1421
- stack.push(rowVal);
1422
- break;
1423
- }
1424
- if (colVal.type === 13 /* Error */) {
1425
- stack.push(colVal);
2207
+ const index2Fault = chunkJMXUNXQS_cjs.faultedOperand(matrixVal, rowVal, colVal);
2208
+ if (index2Fault) {
2209
+ stack.push(index2Fault);
1426
2210
  break;
1427
2211
  }
1428
2212
  if (matrixVal.type !== 7 /* Matrix */) {
1429
- stack.push(chunkOC6LTXYS_cjs.errorValue("MATRIX_INDEX_NOT_A_MATRIX", `Cannot index a non-matrix value with "[...]".`));
2213
+ stack.push(chunkJMXUNXQS_cjs.errorValue("MATRIX_INDEX_NOT_A_MATRIX", `Cannot index a non-matrix value with "[...]".`));
1430
2214
  break;
1431
2215
  }
1432
2216
  const m = matrixVal.value;
1433
2217
  const row = Math.trunc(rowVal.toNumber());
1434
2218
  const col = Math.trunc(colVal.toNumber());
1435
- if (!chunk4CVLFLOB_cjs.inBounds(m, row, col)) {
1436
- stack.push(chunkOC6LTXYS_cjs.errorValue(
2219
+ if (!chunkUM6BVY2S_cjs.inBounds(m, row, col)) {
2220
+ stack.push(chunkJMXUNXQS_cjs.errorValue(
1437
2221
  "MATRIX_INDEX_OUT_OF_BOUNDS",
1438
2222
  `[${row}, ${col}] is out of bounds for a ${m.rows}x${m.cols} matrix.`
1439
2223
  ));
1440
2224
  break;
1441
2225
  }
1442
- const cell = chunk4CVLFLOB_cjs.matAt(m, row, col);
1443
- stack.push(chunk4CVLFLOB_cjs.matrixEntryToValue(cell));
2226
+ const cell = chunkUM6BVY2S_cjs.matAt(m, row, col);
2227
+ stack.push(chunkUM6BVY2S_cjs.matrixEntryToValue(cell));
1444
2228
  break;
1445
2229
  }
1446
2230
  case 156 /* RANGE_NEW */: {
1447
2231
  const maxVal = safePop(stack), minVal = safePop(stack);
1448
- if (minVal.type === 13 /* Error */) {
1449
- stack.push(minVal);
1450
- break;
1451
- }
1452
- if (maxVal.type === 13 /* Error */) {
1453
- stack.push(maxVal);
2232
+ const rangeFault = chunkJMXUNXQS_cjs.faultedOperand(minVal, maxVal);
2233
+ if (rangeFault) {
2234
+ stack.push(rangeFault);
1454
2235
  break;
1455
2236
  }
1456
2237
  if (minVal.type !== 0 /* Number */ || maxVal.type !== 0 /* Number */) {
1457
- stack.push(chunkOC6LTXYS_cjs.errorValue("INVALID_RANGE_BOUND", `A range's bounds must be plain numbers (e.g. "0:3").`));
2238
+ stack.push(chunkJMXUNXQS_cjs.errorValue("INVALID_RANGE_BOUND", `A range's bounds must be plain numbers (e.g. "0:3").`));
1458
2239
  break;
1459
2240
  }
1460
2241
  const min = minVal.value;
1461
2242
  const max = maxVal.value;
1462
2243
  if (!Number.isInteger(min) || !Number.isInteger(max)) {
1463
- stack.push(chunkOC6LTXYS_cjs.errorValue("NON_INTEGER_RANGE_BOUND", `A range's bounds must be whole numbers, got "${min}:${max}".`));
2244
+ stack.push(chunkJMXUNXQS_cjs.errorValue("NON_INTEGER_RANGE_BOUND", `A range's bounds must be whole numbers, got "${min}:${max}".`));
1464
2245
  break;
1465
2246
  }
1466
2247
  if (min > max) {
1467
- stack.push(chunkOC6LTXYS_cjs.errorValue(
2248
+ stack.push(chunkJMXUNXQS_cjs.errorValue(
1468
2249
  "DESCENDING_RANGE",
1469
2250
  `A range's min (${min}) cannot be greater than its max (${max}) \u2014 did you mean "${max}:${min}"?`
1470
2251
  ));
1471
2252
  break;
1472
2253
  }
1473
- stack.push(chunkOC6LTXYS_cjs.rangeValue(min, max));
2254
+ stack.push(chunkJMXUNXQS_cjs.rangeValue(min, max));
1474
2255
  break;
1475
2256
  }
1476
2257
  case 155 /* MAT_SLICE */: {
1477
2258
  const colRangeVal = safePop(stack), rowRangeVal = safePop(stack), matrixVal = safePop(stack);
1478
- if (matrixVal.type === 13 /* Error */) {
1479
- stack.push(matrixVal);
1480
- break;
1481
- }
1482
- if (rowRangeVal.type === 13 /* Error */) {
1483
- stack.push(rowRangeVal);
1484
- break;
1485
- }
1486
- if (colRangeVal.type === 13 /* Error */) {
1487
- stack.push(colRangeVal);
2259
+ const sliceFault = chunkJMXUNXQS_cjs.faultedOperand(matrixVal, rowRangeVal, colRangeVal);
2260
+ if (sliceFault) {
2261
+ stack.push(sliceFault);
1488
2262
  break;
1489
2263
  }
1490
2264
  if (matrixVal.type !== 7 /* Matrix */) {
1491
- stack.push(chunkOC6LTXYS_cjs.errorValue("MATRIX_INDEX_NOT_A_MATRIX", `Cannot slice a non-matrix value with "[...]".`));
2265
+ stack.push(chunkJMXUNXQS_cjs.errorValue("MATRIX_INDEX_NOT_A_MATRIX", `Cannot slice a non-matrix value with "[...]".`));
1492
2266
  break;
1493
2267
  }
1494
2268
  if (rowRangeVal.type !== 8 /* Range */ || colRangeVal.type !== 8 /* Range */) {
1495
- stack.push(chunkOC6LTXYS_cjs.errorValue("INVALID_MATRIX_SLICE_BOUND", `Matrix slicing needs range bounds (e.g. "a[0:1, 1:2]").`));
2269
+ stack.push(chunkJMXUNXQS_cjs.errorValue("INVALID_MATRIX_SLICE_BOUND", `Matrix slicing needs range bounds (e.g. "a[0:1, 1:2]").`));
1496
2270
  break;
1497
2271
  }
1498
2272
  const m = matrixVal.value;
1499
2273
  const rowRange = rowRangeVal.value;
1500
2274
  const colRange = colRangeVal.value;
1501
2275
  if (rowRange.min < 0 || rowRange.max >= m.rows || colRange.min < 0 || colRange.max >= m.cols) {
1502
- stack.push(chunkOC6LTXYS_cjs.errorValue(
2276
+ stack.push(chunkJMXUNXQS_cjs.errorValue(
1503
2277
  "MATRIX_INDEX_OUT_OF_BOUNDS",
1504
2278
  `Slice [${rowRange.min}:${rowRange.max}, ${colRange.min}:${colRange.max}] is out of bounds for a ${m.rows}x${m.cols} matrix.`
1505
2279
  ));
@@ -1507,13 +2281,13 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1507
2281
  }
1508
2282
  const newRows = rowRange.max - rowRange.min + 1;
1509
2283
  const newCols = colRange.max - colRange.min + 1;
1510
- const data = new Array(newRows * newCols);
2284
+ const data = chunkJMXUNXQS_cjs.checkedArray(newRows * newCols, "matrix cells");
1511
2285
  for (let r = 0; r < newRows; r++) {
1512
2286
  for (let c = 0; c < newCols; c++) {
1513
- data[r + c * newRows] = chunk4CVLFLOB_cjs.matAt(m, rowRange.min + r, colRange.min + c);
2287
+ data[r + c * newRows] = chunkUM6BVY2S_cjs.matAt(m, rowRange.min + r, colRange.min + c);
1514
2288
  }
1515
2289
  }
1516
- stack.push(chunkOC6LTXYS_cjs.matrixValue(newRows, newCols, data));
2290
+ stack.push(chunkJMXUNXQS_cjs.matrixValue(newRows, newCols, data));
1517
2291
  break;
1518
2292
  }
1519
2293
  // ═══════════════════════════════════════════════════════════════
@@ -1525,9 +2299,10 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1525
2299
  // kind-0 bodies are a SEPARATE side-table from userFunctionBodies.
1526
2300
  // ═══════════════════════════════════════════════════════════════
1527
2301
  case 157 /* MAP_INVOKE */: {
1528
- const kind = opcodes[ip++];
1529
- const ref = opcodes[ip++];
1530
- const collectionCount = opcodes[ip++];
2302
+ const kind = operandByte(opcodes, ip++, op, "body kind");
2303
+ const ref = operandByte(opcodes, ip++, op, "body reference");
2304
+ const collectionCount = operandByte(opcodes, ip++, op, "collection count");
2305
+ requireKnownBodyKind(kind, ref, op);
1531
2306
  const rawCollections = new Array(collectionCount);
1532
2307
  for (let i = collectionCount - 1; i >= 0; i--) rawCollections[i] = safePop(stack);
1533
2308
  let paramNames = [];
@@ -1535,7 +2310,7 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1535
2310
  if (kind === 0) {
1536
2311
  const def = anonymousBodies?.[ref];
1537
2312
  if (!def) {
1538
- throw chunkM4N5GA5Z_cjs.ErrorFactory.internal(
2313
+ throw chunk5KMIY374_cjs.ErrorFactory.internal(
1539
2314
  "INTERNAL_MISSING_ANONYMOUS_BODY",
1540
2315
  `Internal error: MAP_INVOKE referenced missing anonymous body index ${ref}`,
1541
2316
  { ref }
@@ -1544,14 +2319,14 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1544
2319
  paramNames = def.params;
1545
2320
  program = def.program;
1546
2321
  } else if (kind === 2) {
1547
- const name = strings[ref];
2322
+ const name = pooledString(strings, ref, op);
1548
2323
  const fn = vm.getUserFunction(name);
1549
2324
  if (!fn) {
1550
- stack.push(chunkOC6LTXYS_cjs.errorValue("UNDEFINED_FUNCTION", `map: undefined function "${name}"`));
2325
+ stack.push(chunkJMXUNXQS_cjs.errorValue("UNDEFINED_FUNCTION", `map: undefined function "${name}"`));
1551
2326
  break;
1552
2327
  }
1553
2328
  if (fn.params.length !== collectionCount) {
1554
- stack.push(chunkOC6LTXYS_cjs.errorValue(
2329
+ stack.push(chunkJMXUNXQS_cjs.errorValue(
1555
2330
  "FUNCTION_ARITY_MISMATCH",
1556
2331
  `map: "${name}" expects ${fn.params.length} argument(s) but ${collectionCount} collection(s) were given`
1557
2332
  ));
@@ -1564,15 +2339,16 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1564
2339
  const cellArrays = new Array(collectionCount);
1565
2340
  let mapEarlyError;
1566
2341
  for (let i = 0; i < collectionCount; i++) {
1567
- const resolved = chunk4CVLFLOB_cjs.collectionToValues(rawCollections[i]);
2342
+ const resolved = chunkUM6BVY2S_cjs.collectionToValues(rawCollections[i], vm.getMaxCollectionSize());
1568
2343
  if (!Array.isArray(resolved)) {
1569
2344
  mapEarlyError = resolved;
1570
2345
  break;
1571
2346
  }
2347
+ chunkJMXUNXQS_cjs.chargeAllocation(resolved.length, "collection elements");
1572
2348
  if (collectionLength === -1) {
1573
2349
  collectionLength = resolved.length;
1574
2350
  } else if (resolved.length !== collectionLength) {
1575
- mapEarlyError = chunkOC6LTXYS_cjs.errorValue(
2351
+ mapEarlyError = chunkJMXUNXQS_cjs.errorValue(
1576
2352
  "MAP_COLLECTION_LENGTH_MISMATCH",
1577
2353
  `map: all collections must have the same length (got ${collectionLength} and ${resolved.length}).`
1578
2354
  );
@@ -1584,14 +2360,15 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1584
2360
  stack.push(mapEarlyError);
1585
2361
  break;
1586
2362
  }
1587
- const resultData = new Array(collectionLength);
2363
+ const resultData = chunkJMXUNXQS_cjs.checkedArray(collectionLength, "matrix cells");
1588
2364
  let mapError;
1589
2365
  for (let i = 0; i < collectionLength; i++) {
1590
2366
  const args = new Array(collectionCount);
1591
2367
  for (let j = 0; j < collectionCount; j++) args[j] = cellArrays[j][i];
1592
- const resultVal = kind === 1 ? chunkBXKJLM5R_cjs.builtinFunctions[ref]?.(args) ?? chunkOC6LTXYS_cjs.errorValue("UNKNOWN_BUILTIN_FUNCTION", `map: unknown builtin function index ${ref}`) : invokeFrameBody(paramNames, program, args, vm, pipeline, expression, context, !!symbolicTolerant);
1593
- if (resultVal.type === 13 /* Error */) {
1594
- mapError = resultVal;
2368
+ const resultVal = kind === 1 ? chunk6WFMPTGB_cjs.builtinFunctions[ref]?.(args) ?? chunkJMXUNXQS_cjs.errorValue("UNKNOWN_BUILTIN_FUNCTION", `map: unknown builtin function index ${ref}`) : invokeFrameBody(paramNames, program, args, vm, pipeline, expression, context, !!symbolicTolerant);
2369
+ const resultFault = chunkJMXUNXQS_cjs.faultedOperand(resultVal);
2370
+ if (resultFault) {
2371
+ mapError = resultFault;
1595
2372
  break;
1596
2373
  }
1597
2374
  resultData[i] = resultVal.type === 10 /* Boolean */ ? resultVal.value : resultVal.type === 9 /* Symbolic */ ? resultVal.value : resultVal.toNumber();
@@ -1600,13 +2377,20 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1600
2377
  stack.push(mapError);
1601
2378
  break;
1602
2379
  }
1603
- stack.push(chunkOC6LTXYS_cjs.matrixValue(1, collectionLength, resultData));
2380
+ const firstCollection = rawCollections[0];
2381
+ const sourceShape = firstCollection?.type === 7 /* Matrix */ ? firstCollection.value : void 0;
2382
+ if (sourceShape && sourceShape.rows * sourceShape.cols === collectionLength) {
2383
+ stack.push(chunkJMXUNXQS_cjs.matrixValue(sourceShape.rows, sourceShape.cols, resultData));
2384
+ } else {
2385
+ stack.push(chunkJMXUNXQS_cjs.matrixValue(1, collectionLength, resultData));
2386
+ }
1604
2387
  break;
1605
2388
  }
1606
2389
  case 158 /* REDUCE_INVOKE */: {
1607
- const kind = opcodes[ip++];
1608
- const ref = opcodes[ip++];
1609
- const hasInitial = opcodes[ip++];
2390
+ const kind = operandByte(opcodes, ip++, op, "body kind");
2391
+ const ref = operandByte(opcodes, ip++, op, "body reference");
2392
+ const hasInitial = operandByte(opcodes, ip++, op, "initial-value flag");
2393
+ requireKnownBodyKind(kind, ref, op);
1610
2394
  const initialVal = hasInitial ? safePop(stack) : void 0;
1611
2395
  const collectionVal = safePop(stack);
1612
2396
  let paramNames = [];
@@ -1614,7 +2398,7 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1614
2398
  if (kind === 0) {
1615
2399
  const def = anonymousBodies?.[ref];
1616
2400
  if (!def) {
1617
- throw chunkM4N5GA5Z_cjs.ErrorFactory.internal(
2401
+ throw chunk5KMIY374_cjs.ErrorFactory.internal(
1618
2402
  "INTERNAL_MISSING_ANONYMOUS_BODY",
1619
2403
  `Internal error: REDUCE_INVOKE referenced missing anonymous body index ${ref}`,
1620
2404
  { ref }
@@ -1623,14 +2407,14 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1623
2407
  paramNames = def.params;
1624
2408
  program = def.program;
1625
2409
  } else if (kind === 2) {
1626
- const name = strings[ref];
2410
+ const name = pooledString(strings, ref, op);
1627
2411
  const fn = vm.getUserFunction(name);
1628
2412
  if (!fn) {
1629
- stack.push(chunkOC6LTXYS_cjs.errorValue("UNDEFINED_FUNCTION", `reduce: undefined function "${name}"`));
2413
+ stack.push(chunkJMXUNXQS_cjs.errorValue("UNDEFINED_FUNCTION", `reduce: undefined function "${name}"`));
1630
2414
  break;
1631
2415
  }
1632
2416
  if (fn.params.length !== 2) {
1633
- stack.push(chunkOC6LTXYS_cjs.errorValue(
2417
+ stack.push(chunkJMXUNXQS_cjs.errorValue(
1634
2418
  "FUNCTION_ARITY_MISMATCH",
1635
2419
  `reduce: "${name}" must take exactly 2 arguments (accumulator, element), got ${fn.params.length}`
1636
2420
  ));
@@ -1639,23 +2423,25 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1639
2423
  paramNames = fn.params;
1640
2424
  program = fn.program;
1641
2425
  }
1642
- const cells = chunk4CVLFLOB_cjs.collectionToValues(collectionVal);
2426
+ const cells = chunkUM6BVY2S_cjs.collectionToValues(collectionVal, vm.getMaxCollectionSize());
1643
2427
  if (!Array.isArray(cells)) {
1644
2428
  stack.push(cells);
1645
2429
  break;
1646
2430
  }
2431
+ chunkJMXUNXQS_cjs.chargeAllocation(cells.length, "collection elements");
1647
2432
  let acc;
1648
2433
  let startIdx;
1649
2434
  if (initialVal !== void 0) {
1650
- if (initialVal.type === 13 /* Error */) {
1651
- stack.push(initialVal);
2435
+ const initialFault = chunkJMXUNXQS_cjs.faultedOperand(initialVal);
2436
+ if (initialFault) {
2437
+ stack.push(initialFault);
1652
2438
  break;
1653
2439
  }
1654
2440
  acc = initialVal;
1655
2441
  startIdx = 0;
1656
2442
  } else {
1657
2443
  if (cells.length === 0) {
1658
- stack.push(chunkOC6LTXYS_cjs.errorValue("REDUCE_EMPTY_COLLECTION", `reduce: cannot reduce an empty collection without an initial value.`));
2444
+ stack.push(chunkJMXUNXQS_cjs.errorValue("REDUCE_EMPTY_COLLECTION", `reduce: cannot reduce an empty collection without an initial value.`));
1659
2445
  break;
1660
2446
  }
1661
2447
  acc = cells[0];
@@ -1664,9 +2450,10 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1664
2450
  let reduceError;
1665
2451
  for (let i = startIdx; i < cells.length; i++) {
1666
2452
  const args = [acc, cells[i]];
1667
- const resultVal = kind === 1 ? chunkBXKJLM5R_cjs.builtinFunctions[ref]?.(args) ?? chunkOC6LTXYS_cjs.errorValue("UNKNOWN_BUILTIN_FUNCTION", `reduce: unknown builtin function index ${ref}`) : invokeFrameBody(paramNames, program, args, vm, pipeline, expression, context, !!symbolicTolerant);
1668
- if (resultVal.type === 13 /* Error */) {
1669
- reduceError = resultVal;
2453
+ const resultVal = kind === 1 ? chunk6WFMPTGB_cjs.builtinFunctions[ref]?.(args) ?? chunkJMXUNXQS_cjs.errorValue("UNKNOWN_BUILTIN_FUNCTION", `reduce: unknown builtin function index ${ref}`) : invokeFrameBody(paramNames, program, args, vm, pipeline, expression, context, !!symbolicTolerant);
2454
+ const stepFault = chunkJMXUNXQS_cjs.faultedOperand(resultVal);
2455
+ if (stepFault) {
2456
+ reduceError = stepFault;
1670
2457
  break;
1671
2458
  }
1672
2459
  acc = resultVal;
@@ -1678,12 +2465,30 @@ function executeBytecode(bytecode, vm, pipeline, expression, context, symbolicTo
1678
2465
  stack.push(acc);
1679
2466
  break;
1680
2467
  }
2468
+ // ═══════════════════════════════════════════════════════════════
2469
+ // §12 Algebra verbs' bound unknown (OpCode 159)
2470
+ // ═══════════════════════════════════════════════════════════════
2471
+ case 159 /* BIND_UNKNOWN */: {
2472
+ const ref = operandByte(opcodes, ip++, op, "body reference");
2473
+ const def = anonymousBodies?.[ref];
2474
+ if (!def) {
2475
+ throw chunk5KMIY374_cjs.ErrorFactory.internal(
2476
+ "INTERNAL_MISSING_ANONYMOUS_BODY",
2477
+ `Internal error: BIND_UNKNOWN referenced missing anonymous body index ${ref}`,
2478
+ { ref }
2479
+ );
2480
+ }
2481
+ stack.push(invokeWithBoundUnknown(def.params[0], def.program, vm, pipeline, expression, context, !!symbolicTolerant));
2482
+ break;
2483
+ }
1681
2484
  }
1682
2485
  }
1683
2486
  const fallback = safePop(stack);
1684
- return { type: "value", value: hasArena ? chunkOC6LTXYS_cjs.persistentValue(fallback) : fallback };
2487
+ return { type: "value", value: hasArena ? chunkJMXUNXQS_cjs.persistentValue(fallback) : fallback };
1685
2488
  } catch (e) {
1686
- return { type: "error", error: chunkM4N5GA5Z_cjs.normalizeUnknownError(e) };
2489
+ return { type: "error", error: chunk5KMIY374_cjs.normalizeUnknownError(e) };
2490
+ } finally {
2491
+ chunkJMXUNXQS_cjs.endEvaluation();
1687
2492
  }
1688
2493
  }
1689
2494
 
@@ -1691,5 +2496,5 @@ exports.DependencyGraph = DependencyGraph;
1691
2496
  exports.ScopeManager = ScopeManager;
1692
2497
  exports.createVM = createVM;
1693
2498
  exports.executeBytecode = executeBytecode;
1694
- //# sourceMappingURL=chunk-QDMPOAI7.cjs.map
1695
- //# sourceMappingURL=chunk-QDMPOAI7.cjs.map
2499
+ //# sourceMappingURL=chunk-HDP7VK3C.cjs.map
2500
+ //# sourceMappingURL=chunk-HDP7VK3C.cjs.map