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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/dist/BytecodeBuilder-3egMyuDi.d.cts +274 -0
  2. package/dist/BytecodeBuilder-3egMyuDi.d.ts +274 -0
  3. package/dist/Configuration-fVpd-HC-.d.cts +228 -0
  4. package/dist/Configuration-fVpd-HC-.d.ts +228 -0
  5. package/dist/EngineError-DvPSnhZi.d.cts +304 -0
  6. package/dist/EngineError-DvPSnhZi.d.ts +304 -0
  7. package/dist/Lexer-BJdhlnej.d.cts +531 -0
  8. package/dist/Lexer-D9l4Yrk2.d.ts +531 -0
  9. package/dist/NormalizerRule-BrVoVjmP.d.cts +163 -0
  10. package/dist/NormalizerRule-CEjf1FyD.d.ts +163 -0
  11. package/dist/PackageRegistry-D-Tv_7ca.d.cts +2572 -0
  12. package/dist/PackageRegistry-DaH4aIKP.d.ts +2572 -0
  13. package/dist/Parselet-CK8cQu2a.d.cts +299 -0
  14. package/dist/Parselet-ConOIdRO.d.ts +299 -0
  15. package/dist/ScopeManager-B5k0nk05.d.ts +559 -0
  16. package/dist/ScopeManager-CKfQtl7l.d.cts +559 -0
  17. package/dist/Token-0jpvUdPY.d.cts +245 -0
  18. package/dist/Token-0jpvUdPY.d.ts +245 -0
  19. package/dist/VMCheckpoints-BmDwIXgK.d.ts +171 -0
  20. package/dist/VMCheckpoints-CqFuLwrT.d.cts +171 -0
  21. package/dist/Value-KtAQNHur.d.cts +295 -0
  22. package/dist/Value-KtAQNHur.d.ts +295 -0
  23. package/dist/chunk-2RWAXT6O.js +3 -0
  24. package/dist/chunk-2RWAXT6O.js.map +1 -0
  25. package/dist/chunk-34RRD7PC.js +1492 -0
  26. package/dist/chunk-34RRD7PC.js.map +1 -0
  27. package/dist/chunk-3PPFLFH4.js +5097 -0
  28. package/dist/chunk-3PPFLFH4.js.map +1 -0
  29. package/dist/chunk-3VGDNEE3.js +84 -0
  30. package/dist/chunk-3VGDNEE3.js.map +1 -0
  31. package/dist/chunk-3YNVWKR2.cjs +370 -0
  32. package/dist/chunk-3YNVWKR2.cjs.map +1 -0
  33. package/dist/chunk-47LRVGOT.cjs +316 -0
  34. package/dist/chunk-47LRVGOT.cjs.map +1 -0
  35. package/dist/chunk-4MG4XKO2.js +1644 -0
  36. package/dist/chunk-4MG4XKO2.js.map +1 -0
  37. package/dist/chunk-4QADQTWS.js +2392 -0
  38. package/dist/chunk-4QADQTWS.js.map +1 -0
  39. package/dist/chunk-53B6KDDJ.cjs +1651 -0
  40. package/dist/chunk-53B6KDDJ.cjs.map +1 -0
  41. package/dist/chunk-5X2PTP6F.cjs +104 -0
  42. package/dist/chunk-5X2PTP6F.cjs.map +1 -0
  43. package/dist/chunk-5YEMOYSE.js +264 -0
  44. package/dist/chunk-5YEMOYSE.js.map +1 -0
  45. package/dist/chunk-64W6GLLZ.js +481 -0
  46. package/dist/chunk-64W6GLLZ.js.map +1 -0
  47. package/dist/chunk-6BKTCEUP.cjs +233 -0
  48. package/dist/chunk-6BKTCEUP.cjs.map +1 -0
  49. package/dist/chunk-6NTVRDQV.cjs +1642 -0
  50. package/dist/chunk-6NTVRDQV.cjs.map +1 -0
  51. package/dist/chunk-6RDSQURE.js +290 -0
  52. package/dist/chunk-6RDSQURE.js.map +1 -0
  53. package/dist/chunk-75JP4BZX.js +93 -0
  54. package/dist/chunk-75JP4BZX.js.map +1 -0
  55. package/dist/chunk-B7LXJ6LC.cjs +36 -0
  56. package/dist/chunk-B7LXJ6LC.cjs.map +1 -0
  57. package/dist/chunk-BVAR5J2F.js +257 -0
  58. package/dist/chunk-BVAR5J2F.js.map +1 -0
  59. package/dist/chunk-C4XZV6E7.cjs +269 -0
  60. package/dist/chunk-C4XZV6E7.cjs.map +1 -0
  61. package/dist/chunk-CCJPSHGI.cjs +40 -0
  62. package/dist/chunk-CCJPSHGI.cjs.map +1 -0
  63. package/dist/chunk-CLL7RUQV.cjs +316 -0
  64. package/dist/chunk-CLL7RUQV.cjs.map +1 -0
  65. package/dist/chunk-DM3LMRBC.js +329 -0
  66. package/dist/chunk-DM3LMRBC.js.map +1 -0
  67. package/dist/chunk-DUEZFTK2.js +38 -0
  68. package/dist/chunk-DUEZFTK2.js.map +1 -0
  69. package/dist/chunk-EBSPLUW4.cjs +489 -0
  70. package/dist/chunk-EBSPLUW4.cjs.map +1 -0
  71. package/dist/chunk-EHAHVROS.cjs +261 -0
  72. package/dist/chunk-EHAHVROS.cjs.map +1 -0
  73. package/dist/chunk-EIGTWK5N.js +167 -0
  74. package/dist/chunk-EIGTWK5N.js.map +1 -0
  75. package/dist/chunk-EPOXXJBK.js +96 -0
  76. package/dist/chunk-EPOXXJBK.js.map +1 -0
  77. package/dist/chunk-FEAIOR7N.cjs +91 -0
  78. package/dist/chunk-FEAIOR7N.cjs.map +1 -0
  79. package/dist/chunk-G535KJEG.js +312 -0
  80. package/dist/chunk-G535KJEG.js.map +1 -0
  81. package/dist/chunk-GCM5JHMX.js +88 -0
  82. package/dist/chunk-GCM5JHMX.js.map +1 -0
  83. package/dist/chunk-GOLDJNMZ.js +368 -0
  84. package/dist/chunk-GOLDJNMZ.js.map +1 -0
  85. package/dist/chunk-GW32KPCU.cjs +360 -0
  86. package/dist/chunk-GW32KPCU.cjs.map +1 -0
  87. package/dist/chunk-HTXVVJRA.cjs +1549 -0
  88. package/dist/chunk-HTXVVJRA.cjs.map +1 -0
  89. package/dist/chunk-HWSZJQCI.js +311 -0
  90. package/dist/chunk-HWSZJQCI.js.map +1 -0
  91. package/dist/chunk-IF532O7C.js +101 -0
  92. package/dist/chunk-IF532O7C.js.map +1 -0
  93. package/dist/chunk-J73SJHR3.cjs +2415 -0
  94. package/dist/chunk-J73SJHR3.cjs.map +1 -0
  95. package/dist/chunk-JBSYC7BB.cjs +7473 -0
  96. package/dist/chunk-JBSYC7BB.cjs.map +1 -0
  97. package/dist/chunk-KVILKGMS.js +228 -0
  98. package/dist/chunk-KVILKGMS.js.map +1 -0
  99. package/dist/chunk-LIPPNDBE.js +258 -0
  100. package/dist/chunk-LIPPNDBE.js.map +1 -0
  101. package/dist/chunk-LR7YASZF.cjs +172 -0
  102. package/dist/chunk-LR7YASZF.cjs.map +1 -0
  103. package/dist/chunk-M4N5GA5Z.cjs +309 -0
  104. package/dist/chunk-M4N5GA5Z.cjs.map +1 -0
  105. package/dist/chunk-M5LX5AOO.js +7459 -0
  106. package/dist/chunk-M5LX5AOO.js.map +1 -0
  107. package/dist/chunk-MZOVP3WI.cjs +96 -0
  108. package/dist/chunk-MZOVP3WI.cjs.map +1 -0
  109. package/dist/chunk-N5YFR4UP.cjs +10 -0
  110. package/dist/chunk-N5YFR4UP.cjs.map +1 -0
  111. package/dist/chunk-NGBBNL4K.cjs +4 -0
  112. package/dist/chunk-NGBBNL4K.cjs.map +1 -0
  113. package/dist/chunk-NH2O2AUR.js +146 -0
  114. package/dist/chunk-NH2O2AUR.js.map +1 -0
  115. package/dist/chunk-NLNDMWZC.js +31 -0
  116. package/dist/chunk-NLNDMWZC.js.map +1 -0
  117. package/dist/chunk-NMCRQP3Z.cjs +778 -0
  118. package/dist/chunk-NMCRQP3Z.cjs.map +1 -0
  119. package/dist/chunk-NMD5VRN4.cjs +1327 -0
  120. package/dist/chunk-NMD5VRN4.cjs.map +1 -0
  121. package/dist/chunk-OC6LTXYS.cjs +286 -0
  122. package/dist/chunk-OC6LTXYS.cjs.map +1 -0
  123. package/dist/chunk-OT6OJY7C.cjs +114 -0
  124. package/dist/chunk-OT6OJY7C.cjs.map +1 -0
  125. package/dist/chunk-PFSDGGYL.js +8 -0
  126. package/dist/chunk-PFSDGGYL.js.map +1 -0
  127. package/dist/chunk-QNJ4ACRT.cjs +155 -0
  128. package/dist/chunk-QNJ4ACRT.cjs.map +1 -0
  129. package/dist/chunk-QWY3VEZN.js +1637 -0
  130. package/dist/chunk-QWY3VEZN.js.map +1 -0
  131. package/dist/chunk-RFYD5TJE.js +111 -0
  132. package/dist/chunk-RFYD5TJE.js.map +1 -0
  133. package/dist/chunk-RIN643A3.js +354 -0
  134. package/dist/chunk-RIN643A3.js.map +1 -0
  135. package/dist/chunk-RZCWSXTA.cjs +5122 -0
  136. package/dist/chunk-RZCWSXTA.cjs.map +1 -0
  137. package/dist/chunk-SDGRK7EP.js +774 -0
  138. package/dist/chunk-SDGRK7EP.js.map +1 -0
  139. package/dist/chunk-VEKIWQ3F.cjs +39 -0
  140. package/dist/chunk-VEKIWQ3F.cjs.map +1 -0
  141. package/dist/chunk-WQTTOGXC.cjs +99 -0
  142. package/dist/chunk-WQTTOGXC.cjs.map +1 -0
  143. package/dist/chunk-X6K3HUOY.cjs +86 -0
  144. package/dist/chunk-X6K3HUOY.cjs.map +1 -0
  145. package/dist/chunk-XJCMXB2E.cjs +333 -0
  146. package/dist/chunk-XJCMXB2E.cjs.map +1 -0
  147. package/dist/chunk-XVWCOTR6.js +1324 -0
  148. package/dist/chunk-XVWCOTR6.js.map +1 -0
  149. package/dist/chunk-YLJ4XMA6.js +33 -0
  150. package/dist/chunk-YLJ4XMA6.js.map +1 -0
  151. package/dist/chunk-Z2XP767T.cjs +35 -0
  152. package/dist/chunk-Z2XP767T.cjs.map +1 -0
  153. package/dist/chunk-Z4X2RWOF.js +37 -0
  154. package/dist/chunk-Z4X2RWOF.js.map +1 -0
  155. package/dist/constants.cjs +22 -0
  156. package/dist/constants.cjs.map +1 -0
  157. package/dist/constants.d.cts +12 -0
  158. package/dist/constants.d.ts +12 -0
  159. package/dist/constants.js +5 -0
  160. package/dist/constants.js.map +1 -0
  161. package/dist/engine.cjs +79 -0
  162. package/dist/engine.cjs.map +1 -0
  163. package/dist/engine.d.cts +587 -0
  164. package/dist/engine.d.ts +587 -0
  165. package/dist/engine.js +34 -0
  166. package/dist/engine.js.map +1 -0
  167. package/dist/errors.cjs +81 -0
  168. package/dist/errors.cjs.map +1 -0
  169. package/dist/errors.d.cts +95 -0
  170. package/dist/errors.d.ts +95 -0
  171. package/dist/errors.js +4 -0
  172. package/dist/errors.js.map +1 -0
  173. package/dist/format.cjs +171 -0
  174. package/dist/format.cjs.map +1 -0
  175. package/dist/format.d.cts +51 -0
  176. package/dist/format.d.ts +51 -0
  177. package/dist/format.js +168 -0
  178. package/dist/format.js.map +1 -0
  179. package/dist/index.cjs +97 -0
  180. package/dist/index.cjs.map +1 -0
  181. package/dist/index.d.cts +152 -0
  182. package/dist/index.d.ts +152 -0
  183. package/dist/index.js +75 -0
  184. package/dist/index.js.map +1 -0
  185. package/dist/language.cjs +308 -0
  186. package/dist/language.cjs.map +1 -0
  187. package/dist/language.d.cts +110 -0
  188. package/dist/language.d.ts +110 -0
  189. package/dist/language.js +287 -0
  190. package/dist/language.js.map +1 -0
  191. package/dist/lexer.cjs +64 -0
  192. package/dist/lexer.cjs.map +1 -0
  193. package/dist/lexer.d.cts +56 -0
  194. package/dist/lexer.d.ts +56 -0
  195. package/dist/lexer.js +11 -0
  196. package/dist/lexer.js.map +1 -0
  197. package/dist/normalizer.cjs +40 -0
  198. package/dist/normalizer.cjs.map +1 -0
  199. package/dist/normalizer.d.cts +364 -0
  200. package/dist/normalizer.d.ts +364 -0
  201. package/dist/normalizer.js +11 -0
  202. package/dist/normalizer.js.map +1 -0
  203. package/dist/packages.cjs +121 -0
  204. package/dist/packages.cjs.map +1 -0
  205. package/dist/packages.d.cts +691 -0
  206. package/dist/packages.d.ts +691 -0
  207. package/dist/packages.js +24 -0
  208. package/dist/packages.js.map +1 -0
  209. package/dist/parser.cjs +55 -0
  210. package/dist/parser.cjs.map +1 -0
  211. package/dist/parser.d.cts +46 -0
  212. package/dist/parser.d.ts +46 -0
  213. package/dist/parser.js +10 -0
  214. package/dist/parser.js.map +1 -0
  215. package/dist/pipeline-CrsRPmsv.d.ts +285 -0
  216. package/dist/pipeline-DPUQt7yL.d.cts +285 -0
  217. package/dist/resolvers.cjs +13 -0
  218. package/dist/resolvers.cjs.map +1 -0
  219. package/dist/resolvers.d.cts +111 -0
  220. package/dist/resolvers.d.ts +111 -0
  221. package/dist/resolvers.js +4 -0
  222. package/dist/resolvers.js.map +1 -0
  223. package/dist/services.cjs +21 -0
  224. package/dist/services.cjs.map +1 -0
  225. package/dist/services.d.cts +30 -0
  226. package/dist/services.d.ts +30 -0
  227. package/dist/services.js +4 -0
  228. package/dist/services.js.map +1 -0
  229. package/dist/uom.cjs +56 -0
  230. package/dist/uom.cjs.map +1 -0
  231. package/dist/uom.d.cts +224 -0
  232. package/dist/uom.d.ts +224 -0
  233. package/dist/uom.js +11 -0
  234. package/dist/uom.js.map +1 -0
  235. package/dist/utilities.cjs +32 -0
  236. package/dist/utilities.cjs.map +1 -0
  237. package/dist/utilities.d.cts +113 -0
  238. package/dist/utilities.d.ts +113 -0
  239. package/dist/utilities.js +7 -0
  240. package/dist/utilities.js.map +1 -0
  241. package/dist/variables.cjs +17 -0
  242. package/dist/variables.cjs.map +1 -0
  243. package/dist/variables.d.cts +87 -0
  244. package/dist/variables.d.ts +87 -0
  245. package/dist/variables.js +4 -0
  246. package/dist/variables.js.map +1 -0
  247. package/dist/vm.cjs +284 -0
  248. package/dist/vm.cjs.map +1 -0
  249. package/dist/vm.d.cts +68 -0
  250. package/dist/vm.d.ts +68 -0
  251. package/dist/vm.js +194 -0
  252. package/dist/vm.js.map +1 -0
  253. package/package.json +4 -4
@@ -0,0 +1,274 @@
1
+ /**
2
+ * The VM's bytecode instruction set.
3
+ *
4
+ * Emitted by parselets (via {@link BytecodeBuilder}) during parsing and
5
+ * consumed by the VM's dispatch loop during execution. Values are grouped
6
+ * into numeric bands by category (0-9 stack ops, 10-19 push-literal, 20-29
7
+ * arithmetic, ...) purely for readability, the VM dispatches on the exact
8
+ * numeric value, not the band.
9
+ *
10
+ * Third-party packages emit `CALL_PLUGIN` (with a plugin-function index
11
+ * from {@link allocatePluginFunctionIndex}) to invoke their own logic
12
+ * see `IEnginePackage.pluginFunctions`. The other opcodes are used
13
+ * internally by the built-in packages' parselets.
14
+ */
15
+ declare enum OpCode {
16
+ NOP = 0,
17
+ HALT = 1,
18
+ SWAP = 2,
19
+ DUP = 3,
20
+ PUSH_NUMBER = 10,
21
+ PUSH_BIGINT = 11,
22
+ PUSH_HEX = 12,
23
+ PUSH_STRING = 13,
24
+ PUSH_BOOLEAN = 14,
25
+ PUSH_VARIABLE = 15,
26
+ ADD = 20,
27
+ SUB = 21,
28
+ MUL = 22,
29
+ DIV = 23,
30
+ MOD = 24,
31
+ EXP = 25,
32
+ NEG = 26,
33
+ POS = 27,
34
+ LSHIFT = 30,
35
+ RSHIFT = 31,
36
+ URSHIFT = 32,
37
+ BIT_AND = 33,
38
+ BIT_OR = 34,
39
+ BIT_XOR = 35,
40
+ BIT_NOT = 36,
41
+ EQ = 40,
42
+ NEQ = 41,
43
+ LT = 42,
44
+ LTE = 43,
45
+ GT = 44,
46
+ GTE = 45,
47
+ CALL_PLUGIN = 50,// Plugin-registered functions (may be async — pre-resolved by orchestrator)
48
+ CALL_BUILTIN = 51,// Sync built-in functions (sqrt, sin, diceRoll, matmul)
49
+ RETURN = 52,// Reserved for future user-defined functions
50
+ LOAD_VAR = 60,
51
+ STORE_VAR = 61,
52
+ LOAD_GLOBAL_VAR = 62,// Reads from the process-wide GlobalVariableStore, not the VM's local scope
53
+ STORE_GLOBAL_VAR = 63,// Writes to the process-wide GlobalVariableStore, visible to every document
54
+ TO_NUMBER = 70,
55
+ TO_HEX = 71,
56
+ TO_PERCENTAGE = 74,
57
+ UOM_CONVERT = 80,
58
+ UOM_CONVERT_TO = 81,
59
+ UOM_GET_VALUE = 82,
60
+ UOM_BEST = 83,
61
+ UOM_CONVERT_IN = 84,
62
+ UOM_POSSIBILITIES = 85,// "sourceUnit to ?" — list units convertible from sourceUnit
63
+ DATE_NOW = 90,
64
+ DATE_ADD = 91,
65
+ DATE_SUB = 92,
66
+ DATE_NEXT_WEEKDAY = 93,// "next <Weekday>" — the next occurrence strictly after now
67
+ DATE_LAST_WEEKDAY = 94,// "last <Weekday>" — the previous occurrence strictly before now
68
+ DATE_LITERAL = 95,// Push a datetime literal whose epoch-ms was already resolved at parse time (see DateLiteralParselet)
69
+ RATE_DIV = 110,// Uom ÷ Uom (different measures) -> Rate — the construction op
70
+ RATE_MUL = 111,// Rate × Uom (same measure as denominator) -> plain Uom (denominator cancels)
71
+ RATE_CONVERT = 112,// Rate -> Rate with a rescaled denominator unit (keeps the same real-world rate)
72
+ CLOCK_TIME_TODAY = 120,// minutes-since-midnight -> Datetime anchored to today's calendar date
73
+ LOGICAL_AND = 130,// Boolean && Boolean -> Boolean
74
+ LOGICAL_OR = 131,// Boolean || Boolean -> Boolean
75
+ SELECT = 132,// (thenVal, elseVal, condition) -> thenVal if condition else elseVal — EAGER (both
76
+ TO_FRACTION = 140,// Number -> String, simplified fraction ("0.5" -> "1/2")
77
+ TO_MULTIPLIER = 141,// Number -> String, "1 + n" growth multiplier ("0.5" -> "1.5x")
78
+ TO_SCI = 142,// Number -> String, scientific notation ("1500000" -> "1.5e+6")
79
+ TO_BINARY = 143,// Number -> String, base-2 display ("10" -> "0b1010")
80
+ TO_OCTAL = 144,// Number -> String, base-8 display ("10" -> "0o12")
81
+ CALL_AS_CONVERTER = 145,// (value, name) -> runtime asConverterRegistry lookup + call
82
+ DEFINE_USER_FUNCTION = 150,// (operand = index into bytecode.userFunctionBodies) -> register name/params/program into vm.userFunctions. Registration happens at VM-EXECUTION time, not parse time, so a diagnostic/lookahead parse that compiles but never executes a definition line has no side effect on the shared registry.
83
+ CALL_USER_FUNCTION = 151,// (N arg values already on stack) -> pop N args, bind by NAME into a new call frame, execute the named function's stored body (reentrant executeBytecode), push its result
84
+ MAT_NEW = 152,// (rows, cols operands; rows*cols values already on stack, ROW-MAJOR push order) -> pop rows*cols values, transpose to column-major, push a Matrix
85
+ MAT_INDEX1 = 153,// (matrix, index already on stack) -> column-major single-index read `a[i]`
86
+ MAT_INDEX2 = 154,// (matrix, row, col already on stack) -> `a[row, col]` read
87
+ MAT_SLICE = 155,// (matrix, rowRange, colRange already on stack) -> sub-matrix via two Range values
88
+ RANGE_NEW = 156,// (min, max already on stack) -> push a Range value `min:max`
89
+ MAP_INVOKE = 157,// map(...) — see parser/BytecodeBuilder.ts's `anonymousBodies` side-table
90
+ REDUCE_INVOKE = 158
91
+ }
92
+ /**
93
+ * Gets the name of an OpCode as a string.
94
+ * @param op The OpCode value
95
+ * @returns The enum name as a string, or "UNKNOWN_<value>" if not found
96
+ */
97
+ declare function getOpCodeName(op: number): string;
98
+
99
+ /**
100
+ * Compiled bytecode program produced by {@link BytecodeBuilder}.
101
+ * Ready for consumption by {@link executeBytecode} without further processing.
102
+ */
103
+ interface BytecodeProgram {
104
+ opcodes: Uint8Array;
105
+ numbers: Float64Array;
106
+ strings: string[];
107
+ constants?: Map<number, number>;
108
+ /**
109
+ * Whether the program contains any async opcodes (CALL_PLUGIN, etc.).
110
+ * Set during compilation by the BytecodeBuilder. Allows the engine
111
+ * to skip the O(n) resolver preflight check in O(1) for purely
112
+ * synchronous expressions like `2 + 2`.
113
+ */
114
+ hasAsync: boolean;
115
+ /**
116
+ * User-defined-function bodies compiled alongside this program (one
117
+ * entry per `name(params) = body` definition on this line). See
118
+ * {@link BytecodeBuilder.emitUserFunctionBody}. `OpCode.DEFINE_USER_FUNCTION`'s
119
+ * operand is an index into this array, resolved at VM-execution time
120
+ * (not parse time) so a diagnostic/lookahead parse that never actually
121
+ * executes the definition line has no side effect on `vm.userFunctions`.
122
+ */
123
+ userFunctionBodies?: UserFunctionDef[];
124
+ /**
125
+ * Anonymous function bodies compiled alongside this program, one entry
126
+ * per `map`/`reduce` inline transform expression (e.g. the `10*x` in
127
+ * `map(10*x, [0,1,500])`). See {@link BytecodeBuilder.emitAnonymousBody}.
128
+ * Deliberately a SEPARATE side-table from `userFunctionBodies`, not
129
+ * routed through `vm.userFunctions` at all: an inline body has no name
130
+ * and must never leak into the persistent name-keyed registry the way
131
+ * a real `f(x) = ...` definition does.
132
+ */
133
+ anonymousBodies?: AnonymousBodyDef[];
134
+ }
135
+ /**
136
+ * An anonymous transform body for `map`/`reduce`'s inline-expression form
137
+ * (e.g. `10*x` in `map(10*x, [0,1,500])`, or `acc+x` in `reduce(acc+x,
138
+ * [1,2,3])`). Structurally identical to {@link UserFunctionDef} minus the
139
+ * `name`. See `OpCode.MAP_INVOKE`/`REDUCE_INVOKE` and
140
+ * `vm/VM.ts`'s handlers, which build a call frame from `params`/`args`
141
+ * exactly like `CALL_USER_FUNCTION` does, just without ever registering
142
+ * the body in `vm.userFunctions`.
143
+ */
144
+ interface AnonymousBodyDef {
145
+ params: string[];
146
+ program: BytecodeProgram;
147
+ }
148
+ /**
149
+ * A user-defined, parameterized, reusable function's compiled form
150
+ * (`f(x) = 2*x + 1`). See `OpCode.DEFINE_USER_FUNCTION`/`CALL_USER_FUNCTION`
151
+ * and `vm/VM.ts`'s `VM.defineUserFunction`/`getUserFunction`.
152
+ *
153
+ * `program` is the body compiled to its OWN independent `BytecodeProgram`,
154
+ * not a fragment of the definition line's own bytecode. Parameter names
155
+ * inside the body compile to ORDINARY `LOAD_VAR <name>` opcodes, no
156
+ * parse-time rewriting, because parameter resolution happens dynamically
157
+ * at the VM level: `CALL_USER_FUNCTION` pushes a name-keyed call frame
158
+ * (`Map<string, Value>`) before re-executing `program`, and `VM.getVar()`
159
+ * checks the innermost call frame before falling back to the flat
160
+ * document-variable store. This is why a `UNIT`-collision parameter name
161
+ * (e.g. `h` in `area(w, h) = w * h`, which lexes as the "hour" unit) needs
162
+ * no special handling anywhere, it's just another `LOAD_VAR "h"`, resolved
163
+ * the same way as any other name.
164
+ */
165
+ interface UserFunctionDef {
166
+ name: string;
167
+ params: string[];
168
+ program: BytecodeProgram;
169
+ }
170
+ /**
171
+ * Direct-to-bytecode compiler for the Pratt parser.
172
+ *
173
+ * Accumulates opcodes, numeric constants, and string references during parsing,
174
+ * then produces a {@link BytecodeProgram} for VM execution. Supports:
175
+ * - Standard build via {@link build}
176
+ * - Zero-copy build into pre-allocated buffers via {@link buildInto}
177
+ * - In-place reset for reuse without reallocation
178
+ */
179
+ declare class BytecodeBuilder {
180
+ private opcodes;
181
+ private numbers;
182
+ private strings;
183
+ private stringIndex;
184
+ private _hasAsync;
185
+ private userFunctionBodies;
186
+ private anonymousBodies;
187
+ /** Emit an {@link OpCode} instruction. */
188
+ emitOpcode(op: OpCode): void;
189
+ /**
190
+ * Emit a numeric literal: appends `n` to the program's constant pool and
191
+ * writes its index into the opcode stream (read back by the VM as e.g.
192
+ * `PUSH_NUMBER <idx>`).
193
+ *
194
+ * Numeric constants are NOT deduplicated (unlike {@link emitString})
195
+ * every call appends a new entry, so an expression with more than
196
+ * {@link MAX_CONSTANT_POOL_INDEX}+1 distinct numeric-literal occurrences
197
+ * throws rather than silently wrapping the index (see
198
+ * `MAX_CONSTANT_POOL_INDEX`'s doc for what that would otherwise do).
199
+ *
200
+ * @throws If the constant pool would exceed 256 entries.
201
+ */
202
+ emitNumber(n: number): void;
203
+ /**
204
+ * Emit a string literal: interns `s` into the program's string pool
205
+ * (deduplicated via `stringIndex`) and writes its index into the opcode
206
+ * stream. Subject to the same constant-pool bound as {@link emitNumber},
207
+ * but since strings ARE deduplicated, only distinct string values count
208
+ * against the limit.
209
+ *
210
+ * @throws If the string pool would exceed 256 distinct entries.
211
+ */
212
+ emitString(s: string): void;
213
+ /**
214
+ * Emit a raw numeric operand (0-255) following an opcode, e.g. a
215
+ * plugin-function index for `CALL_PLUGIN`, or an argument count. Unlike
216
+ * {@link emitOpcode}, this does not go through the `OpCode` enum, so
217
+ * package authors use this (not an unsafe cast to `OpCode`) to push
218
+ * operands their own opcode handler expects to read positionally.
219
+ */
220
+ emitIndex(idx: number): void;
221
+ /** Emit a raw byte (0-255), used for fixed small operands like argument counts. */
222
+ emitByte(b: number): void;
223
+ /** Number of opcodes/operands emitted so far, used to compute jump targets before {@link patchJump}. */
224
+ get currentLength(): number;
225
+ /**
226
+ * Register a compiled user-defined-function body, returning its index
227
+ * into this program's `userFunctionBodies` side-table, the caller emits
228
+ * that index as `DEFINE_USER_FUNCTION`'s operand via {@link emitIndex}.
229
+ * Subject to the same {@link MAX_CONSTANT_POOL_INDEX} bound as
230
+ * {@link emitNumber}/{@link emitString} (the index itself is a single
231
+ * opcode-stream byte), in practice a single line defines at most a
232
+ * handful of functions, so this limit is never realistically reached.
233
+ *
234
+ * @throws If more than 256 function bodies are registered on one program.
235
+ */
236
+ emitUserFunctionBody(name: string, params: string[], program: BytecodeProgram): number;
237
+ /**
238
+ * Register a compiled `map`/`reduce` anonymous transform body, returning
239
+ * its index into this program's `anonymousBodies` side-table, the
240
+ * caller emits that index as `MAP_INVOKE`/`REDUCE_INVOKE`'s operand via
241
+ * {@link emitIndex}. Same {@link MAX_CONSTANT_POOL_INDEX} bound as
242
+ * {@link emitUserFunctionBody}.
243
+ *
244
+ * @throws If more than 256 anonymous bodies are registered on one program.
245
+ */
246
+ emitAnonymousBody(params: string[], program: BytecodeProgram): number;
247
+ /** Overwrite a previously-emitted placeholder operand at `position` with the real jump `target`, once known. */
248
+ patchJump(position: number, target: number): void;
249
+ /**
250
+ * Build the accumulated opcodes/numbers/strings into a BytecodeProgram.
251
+ * Creates new TypedArrays, the builder can be reused after this call.
252
+ */
253
+ build(): BytecodeProgram;
254
+ /**
255
+ * Build directly into a pre-allocated buffer for zero-copy VM consumption.
256
+ *
257
+ * When `buf` is provided and large enough, writes into it and returns
258
+ * subarray **views** (not copies), the returned TypedArrays share the
259
+ * buffer's underlying ArrayBuffer. The caller MUST NOT mutate the buffer
260
+ * until the returned BytecodeProgram is no longer needed.
261
+ *
262
+ * If the caller intends to cache the result, they must copy the TypedArrays
263
+ * (e.g. `new Uint8Array(program.opcodes)`) before reusing the buffer pool.
264
+ *
265
+ * When `buf` is omitted or too small, allocates fresh TypedArrays.
266
+ */
267
+ buildInto(buf?: {
268
+ opcodes: Uint8Array;
269
+ numbers: Float64Array;
270
+ }): BytecodeProgram;
271
+ reset(): void;
272
+ }
273
+
274
+ export { type AnonymousBodyDef as A, BytecodeBuilder as B, OpCode as O, type UserFunctionDef as U, type BytecodeProgram as a, getOpCodeName as g };
@@ -0,0 +1,274 @@
1
+ /**
2
+ * The VM's bytecode instruction set.
3
+ *
4
+ * Emitted by parselets (via {@link BytecodeBuilder}) during parsing and
5
+ * consumed by the VM's dispatch loop during execution. Values are grouped
6
+ * into numeric bands by category (0-9 stack ops, 10-19 push-literal, 20-29
7
+ * arithmetic, ...) purely for readability, the VM dispatches on the exact
8
+ * numeric value, not the band.
9
+ *
10
+ * Third-party packages emit `CALL_PLUGIN` (with a plugin-function index
11
+ * from {@link allocatePluginFunctionIndex}) to invoke their own logic
12
+ * see `IEnginePackage.pluginFunctions`. The other opcodes are used
13
+ * internally by the built-in packages' parselets.
14
+ */
15
+ declare enum OpCode {
16
+ NOP = 0,
17
+ HALT = 1,
18
+ SWAP = 2,
19
+ DUP = 3,
20
+ PUSH_NUMBER = 10,
21
+ PUSH_BIGINT = 11,
22
+ PUSH_HEX = 12,
23
+ PUSH_STRING = 13,
24
+ PUSH_BOOLEAN = 14,
25
+ PUSH_VARIABLE = 15,
26
+ ADD = 20,
27
+ SUB = 21,
28
+ MUL = 22,
29
+ DIV = 23,
30
+ MOD = 24,
31
+ EXP = 25,
32
+ NEG = 26,
33
+ POS = 27,
34
+ LSHIFT = 30,
35
+ RSHIFT = 31,
36
+ URSHIFT = 32,
37
+ BIT_AND = 33,
38
+ BIT_OR = 34,
39
+ BIT_XOR = 35,
40
+ BIT_NOT = 36,
41
+ EQ = 40,
42
+ NEQ = 41,
43
+ LT = 42,
44
+ LTE = 43,
45
+ GT = 44,
46
+ GTE = 45,
47
+ CALL_PLUGIN = 50,// Plugin-registered functions (may be async — pre-resolved by orchestrator)
48
+ CALL_BUILTIN = 51,// Sync built-in functions (sqrt, sin, diceRoll, matmul)
49
+ RETURN = 52,// Reserved for future user-defined functions
50
+ LOAD_VAR = 60,
51
+ STORE_VAR = 61,
52
+ LOAD_GLOBAL_VAR = 62,// Reads from the process-wide GlobalVariableStore, not the VM's local scope
53
+ STORE_GLOBAL_VAR = 63,// Writes to the process-wide GlobalVariableStore, visible to every document
54
+ TO_NUMBER = 70,
55
+ TO_HEX = 71,
56
+ TO_PERCENTAGE = 74,
57
+ UOM_CONVERT = 80,
58
+ UOM_CONVERT_TO = 81,
59
+ UOM_GET_VALUE = 82,
60
+ UOM_BEST = 83,
61
+ UOM_CONVERT_IN = 84,
62
+ UOM_POSSIBILITIES = 85,// "sourceUnit to ?" — list units convertible from sourceUnit
63
+ DATE_NOW = 90,
64
+ DATE_ADD = 91,
65
+ DATE_SUB = 92,
66
+ DATE_NEXT_WEEKDAY = 93,// "next <Weekday>" — the next occurrence strictly after now
67
+ DATE_LAST_WEEKDAY = 94,// "last <Weekday>" — the previous occurrence strictly before now
68
+ DATE_LITERAL = 95,// Push a datetime literal whose epoch-ms was already resolved at parse time (see DateLiteralParselet)
69
+ RATE_DIV = 110,// Uom ÷ Uom (different measures) -> Rate — the construction op
70
+ RATE_MUL = 111,// Rate × Uom (same measure as denominator) -> plain Uom (denominator cancels)
71
+ RATE_CONVERT = 112,// Rate -> Rate with a rescaled denominator unit (keeps the same real-world rate)
72
+ CLOCK_TIME_TODAY = 120,// minutes-since-midnight -> Datetime anchored to today's calendar date
73
+ LOGICAL_AND = 130,// Boolean && Boolean -> Boolean
74
+ LOGICAL_OR = 131,// Boolean || Boolean -> Boolean
75
+ SELECT = 132,// (thenVal, elseVal, condition) -> thenVal if condition else elseVal — EAGER (both
76
+ TO_FRACTION = 140,// Number -> String, simplified fraction ("0.5" -> "1/2")
77
+ TO_MULTIPLIER = 141,// Number -> String, "1 + n" growth multiplier ("0.5" -> "1.5x")
78
+ TO_SCI = 142,// Number -> String, scientific notation ("1500000" -> "1.5e+6")
79
+ TO_BINARY = 143,// Number -> String, base-2 display ("10" -> "0b1010")
80
+ TO_OCTAL = 144,// Number -> String, base-8 display ("10" -> "0o12")
81
+ CALL_AS_CONVERTER = 145,// (value, name) -> runtime asConverterRegistry lookup + call
82
+ DEFINE_USER_FUNCTION = 150,// (operand = index into bytecode.userFunctionBodies) -> register name/params/program into vm.userFunctions. Registration happens at VM-EXECUTION time, not parse time, so a diagnostic/lookahead parse that compiles but never executes a definition line has no side effect on the shared registry.
83
+ CALL_USER_FUNCTION = 151,// (N arg values already on stack) -> pop N args, bind by NAME into a new call frame, execute the named function's stored body (reentrant executeBytecode), push its result
84
+ MAT_NEW = 152,// (rows, cols operands; rows*cols values already on stack, ROW-MAJOR push order) -> pop rows*cols values, transpose to column-major, push a Matrix
85
+ MAT_INDEX1 = 153,// (matrix, index already on stack) -> column-major single-index read `a[i]`
86
+ MAT_INDEX2 = 154,// (matrix, row, col already on stack) -> `a[row, col]` read
87
+ MAT_SLICE = 155,// (matrix, rowRange, colRange already on stack) -> sub-matrix via two Range values
88
+ RANGE_NEW = 156,// (min, max already on stack) -> push a Range value `min:max`
89
+ MAP_INVOKE = 157,// map(...) — see parser/BytecodeBuilder.ts's `anonymousBodies` side-table
90
+ REDUCE_INVOKE = 158
91
+ }
92
+ /**
93
+ * Gets the name of an OpCode as a string.
94
+ * @param op The OpCode value
95
+ * @returns The enum name as a string, or "UNKNOWN_<value>" if not found
96
+ */
97
+ declare function getOpCodeName(op: number): string;
98
+
99
+ /**
100
+ * Compiled bytecode program produced by {@link BytecodeBuilder}.
101
+ * Ready for consumption by {@link executeBytecode} without further processing.
102
+ */
103
+ interface BytecodeProgram {
104
+ opcodes: Uint8Array;
105
+ numbers: Float64Array;
106
+ strings: string[];
107
+ constants?: Map<number, number>;
108
+ /**
109
+ * Whether the program contains any async opcodes (CALL_PLUGIN, etc.).
110
+ * Set during compilation by the BytecodeBuilder. Allows the engine
111
+ * to skip the O(n) resolver preflight check in O(1) for purely
112
+ * synchronous expressions like `2 + 2`.
113
+ */
114
+ hasAsync: boolean;
115
+ /**
116
+ * User-defined-function bodies compiled alongside this program (one
117
+ * entry per `name(params) = body` definition on this line). See
118
+ * {@link BytecodeBuilder.emitUserFunctionBody}. `OpCode.DEFINE_USER_FUNCTION`'s
119
+ * operand is an index into this array, resolved at VM-execution time
120
+ * (not parse time) so a diagnostic/lookahead parse that never actually
121
+ * executes the definition line has no side effect on `vm.userFunctions`.
122
+ */
123
+ userFunctionBodies?: UserFunctionDef[];
124
+ /**
125
+ * Anonymous function bodies compiled alongside this program, one entry
126
+ * per `map`/`reduce` inline transform expression (e.g. the `10*x` in
127
+ * `map(10*x, [0,1,500])`). See {@link BytecodeBuilder.emitAnonymousBody}.
128
+ * Deliberately a SEPARATE side-table from `userFunctionBodies`, not
129
+ * routed through `vm.userFunctions` at all: an inline body has no name
130
+ * and must never leak into the persistent name-keyed registry the way
131
+ * a real `f(x) = ...` definition does.
132
+ */
133
+ anonymousBodies?: AnonymousBodyDef[];
134
+ }
135
+ /**
136
+ * An anonymous transform body for `map`/`reduce`'s inline-expression form
137
+ * (e.g. `10*x` in `map(10*x, [0,1,500])`, or `acc+x` in `reduce(acc+x,
138
+ * [1,2,3])`). Structurally identical to {@link UserFunctionDef} minus the
139
+ * `name`. See `OpCode.MAP_INVOKE`/`REDUCE_INVOKE` and
140
+ * `vm/VM.ts`'s handlers, which build a call frame from `params`/`args`
141
+ * exactly like `CALL_USER_FUNCTION` does, just without ever registering
142
+ * the body in `vm.userFunctions`.
143
+ */
144
+ interface AnonymousBodyDef {
145
+ params: string[];
146
+ program: BytecodeProgram;
147
+ }
148
+ /**
149
+ * A user-defined, parameterized, reusable function's compiled form
150
+ * (`f(x) = 2*x + 1`). See `OpCode.DEFINE_USER_FUNCTION`/`CALL_USER_FUNCTION`
151
+ * and `vm/VM.ts`'s `VM.defineUserFunction`/`getUserFunction`.
152
+ *
153
+ * `program` is the body compiled to its OWN independent `BytecodeProgram`,
154
+ * not a fragment of the definition line's own bytecode. Parameter names
155
+ * inside the body compile to ORDINARY `LOAD_VAR <name>` opcodes, no
156
+ * parse-time rewriting, because parameter resolution happens dynamically
157
+ * at the VM level: `CALL_USER_FUNCTION` pushes a name-keyed call frame
158
+ * (`Map<string, Value>`) before re-executing `program`, and `VM.getVar()`
159
+ * checks the innermost call frame before falling back to the flat
160
+ * document-variable store. This is why a `UNIT`-collision parameter name
161
+ * (e.g. `h` in `area(w, h) = w * h`, which lexes as the "hour" unit) needs
162
+ * no special handling anywhere, it's just another `LOAD_VAR "h"`, resolved
163
+ * the same way as any other name.
164
+ */
165
+ interface UserFunctionDef {
166
+ name: string;
167
+ params: string[];
168
+ program: BytecodeProgram;
169
+ }
170
+ /**
171
+ * Direct-to-bytecode compiler for the Pratt parser.
172
+ *
173
+ * Accumulates opcodes, numeric constants, and string references during parsing,
174
+ * then produces a {@link BytecodeProgram} for VM execution. Supports:
175
+ * - Standard build via {@link build}
176
+ * - Zero-copy build into pre-allocated buffers via {@link buildInto}
177
+ * - In-place reset for reuse without reallocation
178
+ */
179
+ declare class BytecodeBuilder {
180
+ private opcodes;
181
+ private numbers;
182
+ private strings;
183
+ private stringIndex;
184
+ private _hasAsync;
185
+ private userFunctionBodies;
186
+ private anonymousBodies;
187
+ /** Emit an {@link OpCode} instruction. */
188
+ emitOpcode(op: OpCode): void;
189
+ /**
190
+ * Emit a numeric literal: appends `n` to the program's constant pool and
191
+ * writes its index into the opcode stream (read back by the VM as e.g.
192
+ * `PUSH_NUMBER <idx>`).
193
+ *
194
+ * Numeric constants are NOT deduplicated (unlike {@link emitString})
195
+ * every call appends a new entry, so an expression with more than
196
+ * {@link MAX_CONSTANT_POOL_INDEX}+1 distinct numeric-literal occurrences
197
+ * throws rather than silently wrapping the index (see
198
+ * `MAX_CONSTANT_POOL_INDEX`'s doc for what that would otherwise do).
199
+ *
200
+ * @throws If the constant pool would exceed 256 entries.
201
+ */
202
+ emitNumber(n: number): void;
203
+ /**
204
+ * Emit a string literal: interns `s` into the program's string pool
205
+ * (deduplicated via `stringIndex`) and writes its index into the opcode
206
+ * stream. Subject to the same constant-pool bound as {@link emitNumber},
207
+ * but since strings ARE deduplicated, only distinct string values count
208
+ * against the limit.
209
+ *
210
+ * @throws If the string pool would exceed 256 distinct entries.
211
+ */
212
+ emitString(s: string): void;
213
+ /**
214
+ * Emit a raw numeric operand (0-255) following an opcode, e.g. a
215
+ * plugin-function index for `CALL_PLUGIN`, or an argument count. Unlike
216
+ * {@link emitOpcode}, this does not go through the `OpCode` enum, so
217
+ * package authors use this (not an unsafe cast to `OpCode`) to push
218
+ * operands their own opcode handler expects to read positionally.
219
+ */
220
+ emitIndex(idx: number): void;
221
+ /** Emit a raw byte (0-255), used for fixed small operands like argument counts. */
222
+ emitByte(b: number): void;
223
+ /** Number of opcodes/operands emitted so far, used to compute jump targets before {@link patchJump}. */
224
+ get currentLength(): number;
225
+ /**
226
+ * Register a compiled user-defined-function body, returning its index
227
+ * into this program's `userFunctionBodies` side-table, the caller emits
228
+ * that index as `DEFINE_USER_FUNCTION`'s operand via {@link emitIndex}.
229
+ * Subject to the same {@link MAX_CONSTANT_POOL_INDEX} bound as
230
+ * {@link emitNumber}/{@link emitString} (the index itself is a single
231
+ * opcode-stream byte), in practice a single line defines at most a
232
+ * handful of functions, so this limit is never realistically reached.
233
+ *
234
+ * @throws If more than 256 function bodies are registered on one program.
235
+ */
236
+ emitUserFunctionBody(name: string, params: string[], program: BytecodeProgram): number;
237
+ /**
238
+ * Register a compiled `map`/`reduce` anonymous transform body, returning
239
+ * its index into this program's `anonymousBodies` side-table, the
240
+ * caller emits that index as `MAP_INVOKE`/`REDUCE_INVOKE`'s operand via
241
+ * {@link emitIndex}. Same {@link MAX_CONSTANT_POOL_INDEX} bound as
242
+ * {@link emitUserFunctionBody}.
243
+ *
244
+ * @throws If more than 256 anonymous bodies are registered on one program.
245
+ */
246
+ emitAnonymousBody(params: string[], program: BytecodeProgram): number;
247
+ /** Overwrite a previously-emitted placeholder operand at `position` with the real jump `target`, once known. */
248
+ patchJump(position: number, target: number): void;
249
+ /**
250
+ * Build the accumulated opcodes/numbers/strings into a BytecodeProgram.
251
+ * Creates new TypedArrays, the builder can be reused after this call.
252
+ */
253
+ build(): BytecodeProgram;
254
+ /**
255
+ * Build directly into a pre-allocated buffer for zero-copy VM consumption.
256
+ *
257
+ * When `buf` is provided and large enough, writes into it and returns
258
+ * subarray **views** (not copies), the returned TypedArrays share the
259
+ * buffer's underlying ArrayBuffer. The caller MUST NOT mutate the buffer
260
+ * until the returned BytecodeProgram is no longer needed.
261
+ *
262
+ * If the caller intends to cache the result, they must copy the TypedArrays
263
+ * (e.g. `new Uint8Array(program.opcodes)`) before reusing the buffer pool.
264
+ *
265
+ * When `buf` is omitted or too small, allocates fresh TypedArrays.
266
+ */
267
+ buildInto(buf?: {
268
+ opcodes: Uint8Array;
269
+ numbers: Float64Array;
270
+ }): BytecodeProgram;
271
+ reset(): void;
272
+ }
273
+
274
+ export { type AnonymousBodyDef as A, BytecodeBuilder as B, OpCode as O, type UserFunctionDef as U, type BytecodeProgram as a, getOpCodeName as g };