solve-engine 1.0.0-beta.6 → 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.
- package/README.md +10 -3
- package/dist/{BytecodeBuilder-3egMyuDi.d.cts → BytecodeBuilder-B0xskcv5.d.cts} +2 -1
- package/dist/{BytecodeBuilder-3egMyuDi.d.ts → BytecodeBuilder-B0xskcv5.d.ts} +2 -1
- package/dist/{Configuration-fVpd-HC-.d.cts → Configuration-B-G5gTRn.d.cts} +107 -29
- package/dist/{Configuration-fVpd-HC-.d.ts → Configuration-B-G5gTRn.d.ts} +107 -29
- package/dist/{EngineError-DvPSnhZi.d.cts → EngineError-LU7W7AgI.d.cts} +96 -16
- package/dist/{EngineError-DvPSnhZi.d.ts → EngineError-LU7W7AgI.d.ts} +96 -16
- package/dist/{Lexer-W9MBOP0V.d.ts → Lexer-BN5mt30n.d.ts} +16 -0
- package/dist/{Lexer-Cfm79Dak.d.cts → Lexer-D78E2yDW.d.cts} +16 -0
- package/dist/{PackageRegistry-CjDt-Jy_.d.ts → PackageRegistry-DFeINv2O.d.ts} +54 -13
- package/dist/{PackageRegistry-pHtKythi.d.cts → PackageRegistry-u2zdfFaj.d.cts} +54 -13
- package/dist/{Parselet-DEdF9I7n.d.ts → Parselet-BaySkMV3.d.ts} +37 -5
- package/dist/{Parselet-Cu0bLSis.d.cts → Parselet-DuI1Pjiq.d.cts} +37 -5
- package/dist/{ScopeManager-CKfQtl7l.d.cts → ScopeManager-B6GzdhVG.d.cts} +75 -6
- package/dist/{ScopeManager-B5k0nk05.d.ts → ScopeManager-udv4Twwq.d.ts} +75 -6
- package/dist/{VMCheckpoints-BmDwIXgK.d.ts → VMCheckpoints-BiaIlOOY.d.ts} +4 -4
- package/dist/{VMCheckpoints-CqFuLwrT.d.cts → VMCheckpoints-DwLjivM7.d.cts} +4 -4
- package/dist/{Value-KtAQNHur.d.cts → Value-CXJqDH9J.d.cts} +5 -2
- package/dist/{Value-KtAQNHur.d.ts → Value-CXJqDH9J.d.ts} +5 -2
- package/dist/{chunk-CSG5XVNJ.cjs → chunk-3AFRJYP4.cjs} +556 -414
- package/dist/chunk-3AFRJYP4.cjs.map +1 -0
- package/dist/chunk-3BOK2LDK.js +17 -0
- package/dist/chunk-3BOK2LDK.js.map +1 -0
- package/dist/{chunk-6RDSQURE.js → chunk-3D7V24DG.js} +57 -6
- package/dist/chunk-3D7V24DG.js.map +1 -0
- package/dist/{chunk-MEOHSQEH.js → chunk-3LAEG75D.js} +47 -15
- package/dist/chunk-3LAEG75D.js.map +1 -0
- package/dist/{chunk-NUR3K7EW.js → chunk-3VNGREMU.js} +118 -41
- package/dist/chunk-3VNGREMU.js.map +1 -0
- package/dist/{chunk-4AVD7NZW.cjs → chunk-4B2CNWQU.cjs} +13 -7
- package/dist/chunk-4B2CNWQU.cjs.map +1 -0
- package/dist/{chunk-6GCKCWLB.js → chunk-526PMQOA.js} +126 -69
- package/dist/chunk-526PMQOA.js.map +1 -0
- package/dist/{chunk-2CS6OMZK.js → chunk-5F4C26RU.js} +8 -5
- package/dist/chunk-5F4C26RU.js.map +1 -0
- package/dist/{chunk-M4N5GA5Z.cjs → chunk-5KMIY374.cjs} +57 -6
- package/dist/chunk-5KMIY374.cjs.map +1 -0
- package/dist/{chunk-R24DI24X.cjs → chunk-5LI5EPGJ.cjs} +6 -5
- package/dist/chunk-5LI5EPGJ.cjs.map +1 -0
- package/dist/{chunk-BAMZT3GL.js → chunk-5WVP4YHP.js} +939 -134
- package/dist/chunk-5WVP4YHP.js.map +1 -0
- package/dist/{chunk-MZOVP3WI.cjs → chunk-6KFYJ6TD.cjs} +3 -2
- package/dist/chunk-6KFYJ6TD.cjs.map +1 -0
- package/dist/{chunk-BXKJLM5R.cjs → chunk-6WFMPTGB.cjs} +972 -636
- package/dist/chunk-6WFMPTGB.cjs.map +1 -0
- package/dist/{chunk-2MV4HBKC.cjs → chunk-A2N2GFCG.cjs} +10 -10
- package/dist/{chunk-2MV4HBKC.cjs.map → chunk-A2N2GFCG.cjs.map} +1 -1
- package/dist/chunk-ADBA3XBE.cjs +20 -0
- package/dist/chunk-ADBA3XBE.cjs.map +1 -0
- package/dist/{chunk-MBNQVDVC.cjs → chunk-AMOJYLG2.cjs} +16 -10
- package/dist/chunk-AMOJYLG2.cjs.map +1 -0
- package/dist/{chunk-CLVQBF5C.cjs → chunk-AQNHHJMJ.cjs} +5 -5
- package/dist/{chunk-CLVQBF5C.cjs.map → chunk-AQNHHJMJ.cjs.map} +1 -1
- package/dist/{chunk-AHCLWAM5.cjs → chunk-BHTNFEGZ.cjs} +13 -13
- package/dist/chunk-BHTNFEGZ.cjs.map +1 -0
- package/dist/{chunk-62W2DYYA.cjs → chunk-E4NUZXVK.cjs} +58 -27
- package/dist/chunk-E4NUZXVK.cjs.map +1 -0
- package/dist/{chunk-LVLUHTRD.js → chunk-GLG5ZMX7.js} +54 -23
- package/dist/chunk-GLG5ZMX7.js.map +1 -0
- package/dist/{chunk-BVAR5J2F.js → chunk-GQCOSXMG.js} +117 -6
- package/dist/chunk-GQCOSXMG.js.map +1 -0
- package/dist/{chunk-QDMPOAI7.cjs → chunk-HDP7VK3C.cjs} +1118 -313
- package/dist/chunk-HDP7VK3C.cjs.map +1 -0
- package/dist/{chunk-GVWHCL2N.js → chunk-HMOISHXR.js} +217 -75
- package/dist/chunk-HMOISHXR.js.map +1 -0
- package/dist/{chunk-MTX2KVU7.cjs → chunk-HVQFNJKE.cjs} +122 -90
- package/dist/chunk-HVQFNJKE.cjs.map +1 -0
- package/dist/{chunk-OC6LTXYS.cjs → chunk-JMXUNXQS.cjs} +126 -7
- package/dist/chunk-JMXUNXQS.cjs.map +1 -0
- package/dist/{chunk-WWOLFXTX.cjs → chunk-KBSXGXPM.cjs} +10 -7
- package/dist/chunk-KBSXGXPM.cjs.map +1 -0
- package/dist/{chunk-YU2CUNFO.js → chunk-KV7UW6T6.js} +11 -5
- package/dist/chunk-KV7UW6T6.js.map +1 -0
- package/dist/{chunk-CCJPSHGI.cjs → chunk-N7FNVFXW.cjs} +4 -12
- package/dist/chunk-N7FNVFXW.cjs.map +1 -0
- package/dist/{chunk-CYFK5SY2.js → chunk-O3ANBHSA.js} +169 -39
- package/dist/chunk-O3ANBHSA.js.map +1 -0
- package/dist/{chunk-NZFKROS7.cjs → chunk-PA4VC73I.cjs} +130 -72
- package/dist/chunk-PA4VC73I.cjs.map +1 -0
- package/dist/{chunk-NJTXJ5AG.cjs → chunk-PFUESQTW.cjs} +18 -18
- package/dist/{chunk-NJTXJ5AG.cjs.map → chunk-PFUESQTW.cjs.map} +1 -1
- package/dist/{chunk-SFQWJMKT.js → chunk-QY25VWBF.js} +51 -12
- package/dist/chunk-QY25VWBF.js.map +1 -0
- package/dist/{chunk-WC5FFSHB.js → chunk-R3PY4G7J.js} +3 -3
- package/dist/{chunk-WC5FFSHB.js.map → chunk-R3PY4G7J.js.map} +1 -1
- package/dist/{chunk-M5E34VG5.js → chunk-SBUFNJVE.js} +3 -3
- package/dist/{chunk-M5E34VG5.js.map → chunk-SBUFNJVE.js.map} +1 -1
- package/dist/{chunk-UKPGSAZW.js → chunk-TMA4RCEN.js} +3 -3
- package/dist/{chunk-UKPGSAZW.js.map → chunk-TMA4RCEN.js.map} +1 -1
- package/dist/{chunk-FN2WMF2W.cjs → chunk-U5VAY32K.cjs} +215 -138
- package/dist/chunk-U5VAY32K.cjs.map +1 -0
- package/dist/{chunk-DUEZFTK2.js → chunk-UKQHXPGW.js} +4 -12
- package/dist/chunk-UKQHXPGW.js.map +1 -0
- package/dist/{chunk-4CVLFLOB.cjs → chunk-UM6BVY2S.cjs} +201 -69
- package/dist/chunk-UM6BVY2S.cjs.map +1 -0
- package/dist/{chunk-75JP4BZX.js → chunk-UQ3UIZJC.js} +3 -2
- package/dist/chunk-UQ3UIZJC.js.map +1 -0
- package/dist/{chunk-PCPX42KL.js → chunk-V4XG5QF6.js} +16 -10
- package/dist/chunk-V4XG5QF6.js.map +1 -0
- package/dist/{chunk-GPPLSM2Z.js → chunk-VB37OC6I.js} +6 -5
- package/dist/chunk-VB37OC6I.js.map +1 -0
- package/dist/{chunk-MVBEL57Q.js → chunk-Y7FT4IQT.js} +500 -170
- package/dist/chunk-Y7FT4IQT.js.map +1 -0
- package/dist/{chunk-OFXOTECC.js → chunk-YPPPYLSR.js} +7 -7
- package/dist/chunk-YPPPYLSR.js.map +1 -0
- package/dist/{chunk-M4F66R4O.cjs → chunk-YWQ6V4ZN.cjs} +121 -82
- package/dist/chunk-YWQ6V4ZN.cjs.map +1 -0
- package/dist/constants.cjs +5 -5
- package/dist/constants.d.cts +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +2 -2
- package/dist/engine.cjs +31 -31
- package/dist/engine.d.cts +11 -11
- package/dist/engine.d.ts +11 -11
- package/dist/engine.js +21 -21
- package/dist/errors.cjs +19 -19
- package/dist/errors.d.cts +2 -2
- package/dist/errors.d.ts +2 -2
- package/dist/errors.js +1 -1
- package/dist/format.cjs +29 -22
- package/dist/format.cjs.map +1 -1
- package/dist/format.d.cts +1 -2
- package/dist/format.d.ts +1 -2
- package/dist/format.js +23 -16
- package/dist/format.js.map +1 -1
- package/dist/index.cjs +31 -31
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +22 -22
- package/dist/language.cjs +8 -8
- package/dist/language.cjs.map +1 -1
- package/dist/language.d.cts +10 -10
- package/dist/language.d.ts +10 -10
- package/dist/language.js +6 -6
- package/dist/language.js.map +1 -1
- package/dist/lexer.cjs +18 -18
- package/dist/lexer.d.cts +2 -2
- package/dist/lexer.d.ts +2 -2
- package/dist/lexer.js +6 -6
- package/dist/normalizer.cjs +12 -12
- package/dist/normalizer.js +6 -6
- package/dist/packages.cjs +39 -39
- package/dist/packages.d.cts +9 -9
- package/dist/packages.d.ts +9 -9
- package/dist/packages.js +16 -16
- package/dist/parser.cjs +15 -15
- package/dist/parser.d.cts +23 -9
- package/dist/parser.d.ts +23 -9
- package/dist/parser.js +5 -5
- package/dist/{pipeline-CrsRPmsv.d.ts → pipeline-B6k5lCB7.d.ts} +1 -1
- package/dist/{pipeline-DPUQt7yL.d.cts → pipeline-BEb3hujr.d.cts} +1 -1
- package/dist/resolvers.d.cts +2 -2
- package/dist/resolvers.d.ts +2 -2
- package/dist/uom.cjs +17 -17
- package/dist/uom.d.cts +2 -2
- package/dist/uom.d.ts +2 -2
- package/dist/uom.js +7 -7
- package/dist/utilities.cjs +8 -4
- package/dist/utilities.d.cts +19 -3
- package/dist/utilities.d.ts +19 -3
- package/dist/utilities.js +2 -2
- package/dist/vm.cjs +43 -31
- package/dist/vm.d.cts +105 -9
- package/dist/vm.d.ts +105 -9
- package/dist/vm.js +9 -9
- package/package.json +3 -3
- package/dist/chunk-2CS6OMZK.js.map +0 -1
- package/dist/chunk-4AVD7NZW.cjs.map +0 -1
- package/dist/chunk-4CVLFLOB.cjs.map +0 -1
- package/dist/chunk-62W2DYYA.cjs.map +0 -1
- package/dist/chunk-6GCKCWLB.js.map +0 -1
- package/dist/chunk-6RDSQURE.js.map +0 -1
- package/dist/chunk-75JP4BZX.js.map +0 -1
- package/dist/chunk-AHCLWAM5.cjs.map +0 -1
- package/dist/chunk-BAMZT3GL.js.map +0 -1
- package/dist/chunk-BVAR5J2F.js.map +0 -1
- package/dist/chunk-BXKJLM5R.cjs.map +0 -1
- package/dist/chunk-CCJPSHGI.cjs.map +0 -1
- package/dist/chunk-CSG5XVNJ.cjs.map +0 -1
- package/dist/chunk-CYFK5SY2.js.map +0 -1
- package/dist/chunk-DUEZFTK2.js.map +0 -1
- package/dist/chunk-FN2WMF2W.cjs.map +0 -1
- package/dist/chunk-GPPLSM2Z.js.map +0 -1
- package/dist/chunk-GVWHCL2N.js.map +0 -1
- package/dist/chunk-LVLUHTRD.js.map +0 -1
- package/dist/chunk-M4F66R4O.cjs.map +0 -1
- package/dist/chunk-M4N5GA5Z.cjs.map +0 -1
- package/dist/chunk-MBNQVDVC.cjs.map +0 -1
- package/dist/chunk-MEOHSQEH.js.map +0 -1
- package/dist/chunk-MTX2KVU7.cjs.map +0 -1
- package/dist/chunk-MVBEL57Q.js.map +0 -1
- package/dist/chunk-MZOVP3WI.cjs.map +0 -1
- package/dist/chunk-N5YFR4UP.cjs +0 -10
- package/dist/chunk-N5YFR4UP.cjs.map +0 -1
- package/dist/chunk-NUR3K7EW.js.map +0 -1
- package/dist/chunk-NZFKROS7.cjs.map +0 -1
- package/dist/chunk-OC6LTXYS.cjs.map +0 -1
- package/dist/chunk-OFXOTECC.js.map +0 -1
- package/dist/chunk-PCPX42KL.js.map +0 -1
- package/dist/chunk-PFSDGGYL.js +0 -8
- package/dist/chunk-PFSDGGYL.js.map +0 -1
- package/dist/chunk-QDMPOAI7.cjs.map +0 -1
- package/dist/chunk-R24DI24X.cjs.map +0 -1
- package/dist/chunk-SFQWJMKT.js.map +0 -1
- package/dist/chunk-WWOLFXTX.cjs.map +0 -1
- package/dist/chunk-YU2CUNFO.js.map +0 -1
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
*/
|
|
29
29
|
declare const CoreErrorCodes: {
|
|
30
30
|
readonly INVALID_NUMBER_LITERAL: "INVALID_NUMBER_LITERAL";
|
|
31
|
+
/** A `"` that never meets its closing partner (`lexer/ExpressionLexer.ts`'s `tokenizeString()`). Previously the tokenizer ran off the end of the input and returned what it had, so `"abc` lexed to an ordinary String and an unterminated literal was indistinguishable from a terminated one. */
|
|
32
|
+
readonly UNTERMINATED_STRING: "UNTERMINATED_STRING";
|
|
31
33
|
readonly NO_PREFIX_PARSELET: "NO_PREFIX_PARSELET";
|
|
32
34
|
readonly UNEXPECTED_END_OF_INPUT: "UNEXPECTED_END_OF_INPUT";
|
|
33
35
|
readonly UNEXPECTED_TOKEN_TYPE: "UNEXPECTED_TOKEN_TYPE";
|
|
@@ -53,7 +55,9 @@ declare const CoreErrorCodes: {
|
|
|
53
55
|
readonly EVALUATION_ERROR: "EVALUATION_ERROR";
|
|
54
56
|
readonly INSTRUCTION_LIMIT_EXCEEDED: "INSTRUCTION_LIMIT_EXCEEDED";
|
|
55
57
|
readonly STACK_LIMIT_EXCEEDED: "STACK_LIMIT_EXCEEDED";
|
|
56
|
-
/**
|
|
58
|
+
/** One evaluation asking for more elements (collection Values, matrix cells) than `vm.maxAllocatedElements` allows. The counter the two limits above cannot be: both are checked between opcodes, so neither can see what a single opcode allocates inside a loop of its own. See `vm/AllocationBudget.ts`. Recoverable, since it describes this expression rather than the engine. */
|
|
59
|
+
readonly ALLOCATION_LIMIT_EXCEEDED: "ALLOCATION_LIMIT_EXCEEDED";
|
|
60
|
+
/** New this phase. See `VM.ts`'s `safePop()`: a stack-underflow (corrupted bytecode, a buggy plugin) is now a controlled EngineError instead of a raw TypeError. Category INTERNAL, since it is an engine or plugin fault rather than a typed line, but recoverable: it happened on one line and the engine is still usable. */
|
|
57
61
|
readonly STACK_UNDERFLOW: "STACK_UNDERFLOW";
|
|
58
62
|
readonly UNDEFINED_VARIABLE: "UNDEFINED_VARIABLE";
|
|
59
63
|
/** New this phase, the Tier-2/`LOAD_GLOBAL_VAR` hardening: a global variable read before its async preflight resolved, surfaced as a controlled error instead of pushing `undefined`. */
|
|
@@ -64,15 +68,43 @@ declare const CoreErrorCodes: {
|
|
|
64
68
|
/** User-defined-function call/definition errors (`CALL_USER_FUNCTION`/`DEFINE_USER_FUNCTION` opcodes), calling a name with no matching definition, calling with the wrong argument count, and the deliberate v1 restriction that a function body can't itself contain async work. */
|
|
65
69
|
readonly UNDEFINED_FUNCTION: "UNDEFINED_FUNCTION";
|
|
66
70
|
readonly FUNCTION_ARITY_MISMATCH: "FUNCTION_ARITY_MISMATCH";
|
|
71
|
+
/** The same mistake against a BUILT-IN rather than a user-defined function (`sqrt()`, `atan2(1)`, `sqrt(1,2,3)`). Separate from `FUNCTION_ARITY_MISMATCH` above because the two are raised by different opcodes and a host may want to word them differently. Checked at the `CALL_BUILTIN` dispatch against `vm/VMBuiltinArity.ts`; recoverable, since it is a typo in the line, not an engine fault. */
|
|
72
|
+
readonly BUILTIN_ARITY_MISMATCH: "BUILTIN_ARITY_MISMATCH";
|
|
67
73
|
readonly USER_FUNCTION_ASYNC_UNSUPPORTED: "USER_FUNCTION_ASYNC_UNSUPPORTED";
|
|
68
74
|
/** A map/reduce transform body (inline expression or user-defined function) calling an async plugin. Same v1 scope restriction as `USER_FUNCTION_ASYNC_UNSUPPORTED` above, enforced both at parse time (`MAP_REDUCE_TRANSFORM_MUST_BE_SYNCHRONOUS`, packages/mapreduce/) and as a defense-in-depth runtime backstop here. */
|
|
69
75
|
readonly MAP_REDUCE_ASYNC_UNSUPPORTED: "MAP_REDUCE_ASYNC_UNSUPPORTED";
|
|
76
|
+
/** An algebra verb's expression argument (`BIND_UNKNOWN`'s body) calling an async plugin. Same v1 scope restriction as the two above, and likewise refused at parse time first (`SYMBOLIC_ARGUMENT_MUST_BE_SYNCHRONOUS`, packages/symbolic/). */
|
|
77
|
+
readonly SYMBOLIC_ASYNC_UNSUPPORTED: "SYMBOLIC_ASYNC_UNSUPPORTED";
|
|
70
78
|
/** `pushCallFrame()`'s recursion guard, a nested `CALL_USER_FUNCTION` re-enters `executeBytecode()`, so `maxInstructions` alone can't catch e.g. `f(x) = f(x)`; this is the dedicated backstop. `recoverable: true` (the default for `.execution()`), ordinary user-written infinite recursion, not an engine bug; the guard exists precisely so it surfaces as a clear error instead of overflowing the native call stack uncatchably. */
|
|
71
79
|
readonly FUNCTION_RECURSION_LIMIT_EXCEEDED: "FUNCTION_RECURSION_LIMIT_EXCEEDED";
|
|
80
|
+
/** The companion to the code above, and the half it could never see: how MANY user-defined-function calls one evaluation makes, rather than how deeply they nest. A twenty-two-line doubling chain nests twenty-two deep (legal) and makes two million calls (a fatal heap abort). Counted in `vm/AllocationBudget.ts`, because the tally has to survive `executeBytecode()` re-entering itself. Recoverable. */
|
|
81
|
+
readonly FUNCTION_CALL_LIMIT_EXCEEDED: "FUNCTION_CALL_LIMIT_EXCEEDED";
|
|
82
|
+
/** A `<date> + N workdays` offset outside `date.maxOffsetYears`/`minOffsetYears`. Workdays are the one date offset that walks the calendar a day at a time, so the one whose cost is the offset; every other one moves a Date field once. Recoverable. */
|
|
83
|
+
readonly DATE_OFFSET_LIMIT_EXCEEDED: "DATE_OFFSET_LIMIT_EXCEEDED";
|
|
84
|
+
/** A `<<`/`>>` with a bigint operand whose exact result would pass `MAX_EXACT_SHIFT_BITS`, whichever operand is the bigint. Both spellings refuse as of 1.0.0: a bigint on the left used to fall through to `x * 2^n` in doubles and report a 19,870-digit integer as Infinity. See `vm/VM.ts`'s `bigIntShift()`. Recoverable. */
|
|
85
|
+
readonly BIGINT_SHIFT_LIMIT_EXCEEDED: "BIGINT_SHIFT_LIMIT_EXCEEDED";
|
|
86
|
+
/** The same ceiling for `^`, the operator it was written for: `2n ^ 100000` asks for the same 100,001-bit integer `1n << 100000` does, so the two spellings answer the same way. Also new in 1.0.0, and for the same reason: this used to fall through to the double path and answer Infinity. A fractional or negative exponent (`4n ^ 0.5`, `2n ^ -1`) has no exact answer to bound and still uses the double path. See `vm/VM.ts`'s `MAX_EXACT_POW_BITS`. Recoverable. */
|
|
87
|
+
readonly BIGINT_POW_LIMIT_EXCEEDED: "BIGINT_POW_LIMIT_EXCEEDED";
|
|
88
|
+
/** An operand with no whole-number form (a fraction, an infinity, a NaN) meeting a bigint: `1n + 0.5`, `1n & 1.5`, `5n/pi`. `BigInt()` answers those with a raw RangeError, which the VM relabelled UNEXPECTED_ERROR, so a typo in the line was reported as an engine fault. Recoverable; see `vm/VMConversion.ts`'s `toBigIntOperand()`. */
|
|
89
|
+
readonly BIGINT_INEXACT_OPERAND: "BIGINT_INEXACT_OPERAND";
|
|
90
|
+
/** `10n / 0n` and `10n mod 0n`. Deliberately NOT what `1 / 0` does, which is Infinity: a bigint division is exact integer division (`7n / 2n` is 3n), and integer division by zero has no answer, exactly as it has none in C, Java, Python or JavaScript's own BigInt. Previously V8's own RangeError, relabelled UNEXPECTED_ERROR. Recoverable; see `vm/VMConversion.ts`'s `bigIntDivisionByZero()`. */
|
|
91
|
+
readonly BIGINT_DIVISION_BY_ZERO: "BIGINT_DIVISION_BY_ZERO";
|
|
72
92
|
/** `DEFINE_USER_FUNCTION`'s body-index lookup failing, a compiler/VM invariant violation (the opcode stream referenced a `userFunctionBodies` slot that doesn't exist), never a user-input error. */
|
|
73
93
|
readonly INTERNAL_MISSING_FUNCTION_BODY: "INTERNAL_MISSING_FUNCTION_BODY";
|
|
74
94
|
/** `MAP_INVOKE`/`REDUCE_INVOKE`'s anonymous-body-index lookup failing. Same class as `INTERNAL_MISSING_FUNCTION_BODY` above, for the `anonymousBodies` side-table instead of `userFunctionBodies`. */
|
|
75
95
|
readonly INTERNAL_MISSING_ANONYMOUS_BODY: "INTERNAL_MISSING_ANONYMOUS_BODY";
|
|
96
|
+
/** An operand byte read past the end of the stream: the program ends in the middle of an instruction. */
|
|
97
|
+
readonly MALFORMED_BYTECODE_TRUNCATED: "MALFORMED_BYTECODE_TRUNCATED";
|
|
98
|
+
/** A constant-pool operand indexing a `numbers`/`strings` entry that does not exist, or that is not of the pool's type. */
|
|
99
|
+
readonly MALFORMED_BYTECODE_CONSTANT_INDEX: "MALFORMED_BYTECODE_CONSTANT_INDEX";
|
|
100
|
+
/** A unit or converter name read off the value stack that is not a string. Distinct from the pool case above: the operand is a Value another opcode pushed, not a pool entry. */
|
|
101
|
+
readonly MALFORMED_BYTECODE_OPERAND_TYPE: "MALFORMED_BYTECODE_OPERAND_TYPE";
|
|
102
|
+
/** `MAP_INVOKE`/`REDUCE_INVOKE` carrying a body kind other than 0/1/2. Used to fall through every arm with no body and recurse into `executeBytecode(undefined)`. */
|
|
103
|
+
readonly MALFORMED_BYTECODE_BODY_KIND: "MALFORMED_BYTECODE_BODY_KIND";
|
|
104
|
+
/** A `PUSH_BIGINT` pool entry that is not a whole number, e.g. `"1.000"`. `BigInt()` answers that with a raw SyntaxError. */
|
|
105
|
+
readonly MALFORMED_BYTECODE_BIGINT_LITERAL: "MALFORMED_BYTECODE_BIGINT_LITERAL";
|
|
106
|
+
/** `executeBytecode()` called with something that is not a runnable program at all. Checked before the destructure that used to throw outside the function's own try/catch. */
|
|
107
|
+
readonly MALFORMED_BYTECODE_PROGRAM: "MALFORMED_BYTECODE_PROGRAM";
|
|
76
108
|
/** A coefficient grew past `RATIONAL_MAX_BITS`, e.g. repeated exact elimination multiplying denominators together. */
|
|
77
109
|
readonly SYMBOLIC_RATIONAL_OVERFLOW: "SYMBOLIC_RATIONAL_OVERFLOW";
|
|
78
110
|
/** `NaN` or `±Infinity` reaching a symbolic expression, neither of which has an exact rational value. */
|
|
@@ -87,6 +119,8 @@ declare const CoreErrorCodes: {
|
|
|
87
119
|
readonly SYMBOLIC_FACTOR_LIMIT_EXCEEDED: "SYMBOLIC_FACTOR_LIMIT_EXCEEDED";
|
|
88
120
|
/** An equation outside what the solver attempts: not a polynomial, above the degree ceiling, or non-linear in the unknown while another unknown is present. */
|
|
89
121
|
readonly SYMBOLIC_SOLVE_UNSUPPORTED: "SYMBOLIC_SOLVE_UNSUPPORTED";
|
|
122
|
+
/** Some but not all of an equation's roots were found. Reported rather than returned, because a partial list of roots looks exactly like a complete one. */
|
|
123
|
+
readonly SYMBOLIC_SOLVE_INCOMPLETE: "SYMBOLIC_SOLVE_INCOMPLETE";
|
|
90
124
|
/** `solve`'s second argument not being a bare name. */
|
|
91
125
|
readonly SOLVE_REQUIRES_VARIABLE_NAME: "SOLVE_REQUIRES_VARIABLE_NAME";
|
|
92
126
|
/** A derivative order outside 0..`DERIVATIVE_MAX_ORDER`. */
|
|
@@ -105,11 +139,15 @@ declare const CoreErrorCodes: {
|
|
|
105
139
|
readonly INTERNAL_RATIONAL_PARSE: "INTERNAL_RATIONAL_PARSE";
|
|
106
140
|
readonly EXPRESSION_TOO_LONG: "EXPRESSION_TOO_LONG";
|
|
107
141
|
readonly EXPRESSION_TOO_COMPLEX: "EXPRESSION_TOO_COMPLEX";
|
|
142
|
+
/** A document with more lines than `performance.maxDocumentLines`. The per-line limits above bound what one line may ask for and say nothing about how many lines there are; two hundred thousand of `1 + 1` exhausted the heap on the line records alone. Recoverable. */
|
|
143
|
+
readonly DOCUMENT_TOO_LARGE: "DOCUMENT_TOO_LARGE";
|
|
108
144
|
readonly NORMALIZED_TOKEN_LIMIT_EXCEEDED: "NORMALIZED_TOKEN_LIMIT_EXCEEDED";
|
|
109
145
|
/** `"=>"` with nothing before it, needs an expression or variable name to solve/simplify. */
|
|
110
146
|
readonly THEREFORE_REQUIRES_EXPRESSION: "THEREFORE_REQUIRES_EXPRESSION";
|
|
111
147
|
/** A `"=>"`-triggered expression called an async plugin (weather/stocks/currency). Same v1 scope restriction as user-function/map-reduce bodies. */
|
|
112
148
|
readonly THEREFORE_ASYNC_UNSUPPORTED: "THEREFORE_ASYNC_UNSUPPORTED";
|
|
149
|
+
/** Colon-separated numbers that are not a time any clock can show ("24:00", "9:60", "100:5"). Raised by the labeled-line fallback, which used to answer them with whatever stood after the colon. */
|
|
150
|
+
readonly INVALID_TIME_LITERAL: "INVALID_TIME_LITERAL";
|
|
113
151
|
readonly CONFIG_PATH_NOT_FOUND: "CONFIG_PATH_NOT_FOUND";
|
|
114
152
|
readonly INVALID_CONFIG_PATH: "INVALID_CONFIG_PATH";
|
|
115
153
|
readonly CONFIG_SECTION_NOT_FOUND: "CONFIG_SECTION_NOT_FOUND";
|
|
@@ -192,20 +230,29 @@ interface EngineErrorInit {
|
|
|
192
230
|
/** An actionable, worked-example fix, e.g. `e.g. "weather in London"`. Mirrors this codebase's best existing messages (`WEATHER_EXPECTED_CITY`, `AS_CONVERTER_EXPECTED_NAME`). */
|
|
193
231
|
suggestion?: string;
|
|
194
232
|
/**
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
233
|
+
* Whether this engine instance is still usable. `true` for everything that
|
|
234
|
+
* went wrong on ONE line, whether the line's fault (bad syntax, an unknown
|
|
235
|
+
* variable, a safety limit exceeded), the environment's (an external API
|
|
236
|
+
* down), or the engine's own (corrupted bytecode, a stack underflow from a
|
|
237
|
+
* buggy plugin). `false` is for the far rarer case where there is no working
|
|
238
|
+
* engine to go on with: a configuration or package-registration failure,
|
|
239
|
+
* which is what `ErrorFactory.config()` is for and the only factory method
|
|
240
|
+
* that still defaults to it.
|
|
202
241
|
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
242
|
+
* The category answers a different question, and the two used to be answered
|
|
243
|
+
* as one. Category INTERNAL says whose fault this is, the engine's, worth
|
|
244
|
+
* reporting as a bug. `recoverable` says whether the host may carry on, and
|
|
245
|
+
* after an internal slip on one line it may:
|
|
246
|
+
* `__tests__/hardening/RobustnessEngineLifecycle.spec.ts` alternates a
|
|
247
|
+
* throwing line with a good one five hundred times and every answer stays
|
|
248
|
+
* correct. Reporting that as `isFatal()` told a host the opposite, and a host
|
|
249
|
+
* that honours the name would tear a document down over one bad line.
|
|
250
|
+
*
|
|
251
|
+
* This has never gated "does evaluation of the rest of the document
|
|
252
|
+
* continue"; with this engine's per-line containment it always does, even for
|
|
253
|
+
* a `recoverable: false` error (see `ARCHITECTURE.md`'s async-batcher/Tier-2
|
|
254
|
+
* hardening notes). It gates what a host is TOLD. See
|
|
255
|
+
* {@link EngineError.isFatal}.
|
|
209
256
|
*/
|
|
210
257
|
recoverable?: boolean;
|
|
211
258
|
/** Character-offset span into the source expression, when available. Not yet threaded through every call site, populate opportunistically, don't block on retrofitting every existing throw site. */
|
|
@@ -281,10 +328,23 @@ declare class ErrorFactory {
|
|
|
281
328
|
static execution(init: EngineErrorInit): EngineError;
|
|
282
329
|
static external(code: string, message: string, context?: Record<string, unknown>): EngineError;
|
|
283
330
|
static external(init: EngineErrorInit): EngineError;
|
|
284
|
-
/**
|
|
331
|
+
/**
|
|
332
|
+
* Reserve for genuine engine-internal invariant violations (corrupted
|
|
333
|
+
* bytecode, a stack underflow from a buggy plugin, an "impossible" state),
|
|
334
|
+
* not for user-input errors: the category is a bug report.
|
|
335
|
+
*
|
|
336
|
+
* Defaults `recoverable: true` all the same, because every one of these sites
|
|
337
|
+
* is an invariant that failed on ONE line and none of them leaves the engine
|
|
338
|
+
* unusable. This used to default to `false`, which conflated "the engine's
|
|
339
|
+
* fault" with "the engine is finished" and told a host to tear a document
|
|
340
|
+
* down over a line it could simply have shown an error against. A site that
|
|
341
|
+
* has looked at its own case and concluded the instance really is gone can
|
|
342
|
+
* still pass `recoverable: false` explicitly. See {@link
|
|
343
|
+
* EngineErrorInit.recoverable}.
|
|
344
|
+
*/
|
|
285
345
|
static internal(code: string, message: string, context?: Record<string, unknown>): EngineError;
|
|
286
346
|
static internal(init: EngineErrorInit): EngineError;
|
|
287
|
-
/** Defaults `recoverable: false`, a
|
|
347
|
+
/** Defaults `recoverable: false`, and is now the only method that does: a configuration or package-registration failure is the one class that leaves no working engine to carry on with, rather than one bad line in a document. */
|
|
288
348
|
static config(code: string, message: string, context?: Record<string, unknown>): EngineError;
|
|
289
349
|
static config(init: EngineErrorInit): EngineError;
|
|
290
350
|
}
|
|
@@ -298,6 +358,26 @@ declare class ErrorFactory {
|
|
|
298
358
|
* per-line containment) so a raw `TypeError` from a genuine engine bug
|
|
299
359
|
* still surfaces as a structured, catalogued error instead of an opaque
|
|
300
360
|
* uncaught exception.
|
|
361
|
+
*
|
|
362
|
+
* Both branches state RECOVERABLE explicitly, while keeping the INTERNAL
|
|
363
|
+
* category. The two fields answer different questions and were previously
|
|
364
|
+
* answering the same one:
|
|
365
|
+
*
|
|
366
|
+
* category INTERNAL whose fault is this? The engine's. Worth reporting.
|
|
367
|
+
* recoverable is this engine instance still usable? Yes.
|
|
368
|
+
*
|
|
369
|
+
* Everything reaching here is by definition something the engine did not
|
|
370
|
+
* anticipate on ONE line, and per-line containment means the next line
|
|
371
|
+
* evaluates normally, which `__tests__/hardening/RobustnessEngineLifecycle`
|
|
372
|
+
* demonstrates over hundreds of alternating failure/success pairs. Reporting
|
|
373
|
+
* that as `isFatal()` told a host the opposite, and a host that honours the
|
|
374
|
+
* name would tear a document down over a single bad line. The "this is an
|
|
375
|
+
* engine bug rather than your syntax" signal a caller wants for telemetry is
|
|
376
|
+
* the CATEGORY, which is unchanged.
|
|
377
|
+
*
|
|
378
|
+
* The flag is written out here rather than inherited from
|
|
379
|
+
* `ErrorFactory.internal()`, which now defaults the same way, so that this
|
|
380
|
+
* function's contract survives a future change to that default.
|
|
301
381
|
*/
|
|
302
382
|
declare function normalizeUnknownError(error: unknown): EngineError;
|
|
303
383
|
|
|
@@ -364,6 +364,22 @@ declare class ExpressionLexer {
|
|
|
364
364
|
private tokenizeOperator;
|
|
365
365
|
/**
|
|
366
366
|
* Reads a double-quoted string literal. Supports backslash escapes.
|
|
367
|
+
*
|
|
368
|
+
* `text` is the raw source slice, quotes included, because that is what
|
|
369
|
+
* `offset` + `text.length` has to span for a host to underline the literal.
|
|
370
|
+
* `value` is the PAYLOAD, quotes excluded, because that is what
|
|
371
|
+
* `PUSH_STRING` puts into the Value.
|
|
372
|
+
*
|
|
373
|
+
* The two used to be the same string. `"abc"` carried the five characters
|
|
374
|
+
* `"abc"` as its value, which was invisible on screen (the formatter prints
|
|
375
|
+
* the payload raw and the retained quotes landed where a display would have
|
|
376
|
+
* put them back) and not invisible anywhere else: `parseFloat('"5"')` is NaN
|
|
377
|
+
* whatever the digits say, so `"5" + 5` answered 5.
|
|
378
|
+
*
|
|
379
|
+
* An unterminated literal is an error rather than a string that happens to
|
|
380
|
+
* reach the end of the line. It used to return what it had, so `"abc` and
|
|
381
|
+
* `"abc"` were indistinguishable by payload once the quotes were stripped,
|
|
382
|
+
* which is the other half of why they are stripped here rather than later.
|
|
367
383
|
*/
|
|
368
384
|
private tokenizeString;
|
|
369
385
|
/**
|
|
@@ -364,6 +364,22 @@ declare class ExpressionLexer {
|
|
|
364
364
|
private tokenizeOperator;
|
|
365
365
|
/**
|
|
366
366
|
* Reads a double-quoted string literal. Supports backslash escapes.
|
|
367
|
+
*
|
|
368
|
+
* `text` is the raw source slice, quotes included, because that is what
|
|
369
|
+
* `offset` + `text.length` has to span for a host to underline the literal.
|
|
370
|
+
* `value` is the PAYLOAD, quotes excluded, because that is what
|
|
371
|
+
* `PUSH_STRING` puts into the Value.
|
|
372
|
+
*
|
|
373
|
+
* The two used to be the same string. `"abc"` carried the five characters
|
|
374
|
+
* `"abc"` as its value, which was invisible on screen (the formatter prints
|
|
375
|
+
* the payload raw and the retained quotes landed where a display would have
|
|
376
|
+
* put them back) and not invisible anywhere else: `parseFloat('"5"')` is NaN
|
|
377
|
+
* whatever the digits say, so `"5" + 5` answered 5.
|
|
378
|
+
*
|
|
379
|
+
* An unterminated literal is an error rather than a string that happens to
|
|
380
|
+
* reach the end of the line. It used to return what it had, so `"abc` and
|
|
381
|
+
* `"abc"` were indistinguishable by payload once the quotes were stripped,
|
|
382
|
+
* which is the other half of why they are stripped here rather than later.
|
|
367
383
|
*/
|
|
368
384
|
private tokenizeString;
|
|
369
385
|
/**
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { a as PrecedenceParser, b as PrefixParselet, I as InfixParselet } from './Parselet-
|
|
2
|
-
import { V as Value } from './Value-
|
|
1
|
+
import { a as PrecedenceParser, b as PrefixParselet, I as InfixParselet } from './Parselet-BaySkMV3.js';
|
|
2
|
+
import { V as Value } from './Value-CXJqDH9J.js';
|
|
3
3
|
import { IVariableSource } from './variables.js';
|
|
4
|
-
import { M as MarkdownLineType, L as Lexer, e as TokenCategory, c as LexerVocabulary } from './Lexer-
|
|
4
|
+
import { M as MarkdownLineType, L as Lexer, e as TokenCategory, c as LexerVocabulary } from './Lexer-BN5mt30n.js';
|
|
5
5
|
import { IAsyncResolver } from './resolvers.js';
|
|
6
6
|
import { T as TokenFusion, c as TokenNormalizer, a as NormalizerRule } from './TokenNormalizer-t_GotBxr.js';
|
|
7
|
-
import {
|
|
8
|
-
import { a as BytecodeProgram } from './BytecodeBuilder-
|
|
7
|
+
import { a as DependencyGraph, V as VM, D as DagSnapshot, b as EngineContext, S as ScopeManager, L as LineExecutionContext } from './ScopeManager-udv4Twwq.js';
|
|
8
|
+
import { a as BytecodeProgram } from './BytecodeBuilder-B0xskcv5.js';
|
|
9
9
|
import { QueryClient } from '@tanstack/query-core';
|
|
10
|
-
import { E as EngineError } from './EngineError-
|
|
11
|
-
import { a as DiagnosticReportJSON, D as DiagnosticPipeline } from './pipeline-
|
|
10
|
+
import { E as EngineError } from './EngineError-LU7W7AgI.js';
|
|
11
|
+
import { a as DiagnosticReportJSON, D as DiagnosticPipeline } from './pipeline-B6k5lCB7.js';
|
|
12
12
|
import { T as Token } from './Token-BzG5G4ja.js';
|
|
13
|
-
import { D as DEFAULT_CONFIG, E as EngineConfig } from './Configuration-
|
|
13
|
+
import { D as DEFAULT_CONFIG, E as EngineConfig } from './Configuration-B-G5gTRn.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* One line's compiled bytecode, plus the variables it reads and writes.
|
|
@@ -213,9 +213,28 @@ declare class DocumentModel {
|
|
|
213
213
|
* bottom of a 20k-line document before this fix.
|
|
214
214
|
*/
|
|
215
215
|
private dirtyLineIds;
|
|
216
|
+
/**
|
|
217
|
+
* Most lines this model will hold. See `constants/Configuration.ts`'s
|
|
218
|
+
* `performance.maxDocumentLines`, which is where the default comes from and
|
|
219
|
+
* which a host raises through its engine config; a host that builds a
|
|
220
|
+
* DocumentModel directly passes it here instead.
|
|
221
|
+
*/
|
|
222
|
+
private readonly maxLines;
|
|
223
|
+
/**
|
|
224
|
+
* @param maxLines - Ceiling on the line count, defaulting to the engine's
|
|
225
|
+
* configured one. Every line costs a LineState with six arrays in it
|
|
226
|
+
* whatever the line says, so the cost of a document is its line count and
|
|
227
|
+
* nothing else bounds it: two hundred thousand lines of `1 + 1` exhausted
|
|
228
|
+
* the heap here, before a single expression had been looked at.
|
|
229
|
+
*/
|
|
230
|
+
constructor(maxLines?: number);
|
|
216
231
|
/**
|
|
217
232
|
* Initialize or replace the entire document from a text blob.
|
|
218
233
|
* Clears all existing state and assigns new persistent line IDs.
|
|
234
|
+
*
|
|
235
|
+
* @throws `DOCUMENT_TOO_LARGE` for a document past {@link maxLines}, before
|
|
236
|
+
* any of it is stored. Recoverable: nothing has been replaced yet, so the
|
|
237
|
+
* model still holds whatever it held.
|
|
219
238
|
*/
|
|
220
239
|
setDocument(text: string): void;
|
|
221
240
|
/**
|
|
@@ -1407,9 +1426,17 @@ declare class ExpressionEngine {
|
|
|
1407
1426
|
* own contract). This engine-instance-local registration is reversed
|
|
1408
1427
|
* here too, even though it isn't a "shared" registry, so a package's
|
|
1409
1428
|
* lexer and highlighting contributions clean up together rather than
|
|
1410
|
-
* only half-reversing on unregister.
|
|
1411
|
-
*
|
|
1412
|
-
*
|
|
1429
|
+
* only half-reversing on unregister. Normalizer rules are reversed here
|
|
1430
|
+
* for the same reason: they are per-engine, but they live in an ARRAY the
|
|
1431
|
+
* normalizer walks at every token position, so re-registering a package
|
|
1432
|
+
* appended a second copy of every rule and lexing got slower with every
|
|
1433
|
+
* register/unregister cycle.
|
|
1434
|
+
*
|
|
1435
|
+
* Per-engine parselets and phrases are still left in place: a parselet
|
|
1436
|
+
* lives in this engine's isolated registry and a phrase goes into a
|
|
1437
|
+
* text-keyed trie where registering the same phrase twice is the same as
|
|
1438
|
+
* registering it once, so neither accumulates and both are discarded with
|
|
1439
|
+
* the engine instance.
|
|
1413
1440
|
*
|
|
1414
1441
|
* Clears the bytecode cache, removing handlers changes what compiled
|
|
1415
1442
|
* bytecode is valid.
|
|
@@ -1527,6 +1554,12 @@ declare class ExpressionEngine {
|
|
|
1527
1554
|
* parseExpression(). Abstracts the API difference between the two parsers:
|
|
1528
1555
|
* - PrecedenceParser: parser.setBuilder(builder); parser.parseExpression(0)
|
|
1529
1556
|
* - RD: parser.builder = builder; parser.parseExpression(0)
|
|
1557
|
+
*
|
|
1558
|
+
* @param allowLabelFallback - Whether a line that does not parse whole may
|
|
1559
|
+
* be retried as "<label>: <expression>". True for a real line, false for
|
|
1560
|
+
* the retries that fallback makes itself, which is what stops it costing
|
|
1561
|
+
* exponential time; see the loop below, and the comment on its recursive
|
|
1562
|
+
* call for the measurement.
|
|
1530
1563
|
*/
|
|
1531
1564
|
private parseExpression;
|
|
1532
1565
|
/**
|
|
@@ -1548,9 +1581,17 @@ declare class ExpressionEngine {
|
|
|
1548
1581
|
* (a bare assignment's RHS, and an equation's own RHS at solve time)
|
|
1549
1582
|
*, every one of these needs forward-tolerant reads of not-yet-defined
|
|
1550
1583
|
* names, which ordinary evaluation deliberately never allows.
|
|
1584
|
+
*
|
|
1585
|
+
* `lineNumber` is the 1-based document line this program belongs to, so
|
|
1586
|
+
* the RHS still receives a {@link makeLineContext}, a bare assignment's
|
|
1587
|
+
* right-hand side (`total = prev`, `x = line2`) can therefore read
|
|
1588
|
+
* cross-line results exactly as a bare expression line does. Defaults to
|
|
1589
|
+
* `-1` (the "no real document" sentinel) for the expression-level and
|
|
1590
|
+
* `=>`-without-a-document callers, which naturally yields the same
|
|
1591
|
+
* `LINE_REF_NO_DOCUMENT` a single-expression eval already returns.
|
|
1551
1592
|
*/
|
|
1552
1593
|
private executeSymbolicTolerant;
|
|
1553
|
-
/** Compiles and executes `tokens` in symbolic-tolerant mode, the "just simplify this" `=>` fallback when there's no stored equation to solve. */
|
|
1594
|
+
/** Compiles and executes `tokens` in symbolic-tolerant mode, the "just simplify this" `=>` fallback when there's no stored equation to solve. `lineNumber` (1-based, `-1` outside a document) is forwarded so a bare assignment's RHS can resolve cross-line references. */
|
|
1554
1595
|
private simplifySymbolically;
|
|
1555
1596
|
/**
|
|
1556
1597
|
* Parses a bare (colon-less) equation's left-hand side, `factor1 *
|
|
@@ -2270,7 +2311,7 @@ declare class LanguageService {
|
|
|
2270
2311
|
* highlighted the obvious way.
|
|
2271
2312
|
*
|
|
2272
2313
|
* A token the normalizer left alone still describes its own text, so its
|
|
2273
|
-
* span is `offset` to `offset +
|
|
2314
|
+
* span is `offset` to `offset + text.length`, exactly as before.
|
|
2274
2315
|
*
|
|
2275
2316
|
* A FUSED token does not. `10 frames` becomes a FRAME_COUNT whose value is
|
|
2276
2317
|
* `10`, and a timecode becomes a token whose value is a comma-separated
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { a as PrecedenceParser, b as PrefixParselet, I as InfixParselet } from './Parselet-
|
|
2
|
-
import { V as Value } from './Value-
|
|
1
|
+
import { a as PrecedenceParser, b as PrefixParselet, I as InfixParselet } from './Parselet-DuI1Pjiq.cjs';
|
|
2
|
+
import { V as Value } from './Value-CXJqDH9J.cjs';
|
|
3
3
|
import { IVariableSource } from './variables.cjs';
|
|
4
|
-
import { M as MarkdownLineType, L as Lexer, e as TokenCategory, c as LexerVocabulary } from './Lexer-
|
|
4
|
+
import { M as MarkdownLineType, L as Lexer, e as TokenCategory, c as LexerVocabulary } from './Lexer-D78E2yDW.cjs';
|
|
5
5
|
import { IAsyncResolver } from './resolvers.cjs';
|
|
6
6
|
import { T as TokenFusion, c as TokenNormalizer, a as NormalizerRule } from './TokenNormalizer-DGVa24Q-.cjs';
|
|
7
|
-
import {
|
|
8
|
-
import { a as BytecodeProgram } from './BytecodeBuilder-
|
|
7
|
+
import { a as DependencyGraph, V as VM, D as DagSnapshot, b as EngineContext, S as ScopeManager, L as LineExecutionContext } from './ScopeManager-B6GzdhVG.cjs';
|
|
8
|
+
import { a as BytecodeProgram } from './BytecodeBuilder-B0xskcv5.cjs';
|
|
9
9
|
import { QueryClient } from '@tanstack/query-core';
|
|
10
|
-
import { E as EngineError } from './EngineError-
|
|
11
|
-
import { a as DiagnosticReportJSON, D as DiagnosticPipeline } from './pipeline-
|
|
10
|
+
import { E as EngineError } from './EngineError-LU7W7AgI.cjs';
|
|
11
|
+
import { a as DiagnosticReportJSON, D as DiagnosticPipeline } from './pipeline-BEb3hujr.cjs';
|
|
12
12
|
import { T as Token } from './Token-BzG5G4ja.cjs';
|
|
13
|
-
import { D as DEFAULT_CONFIG, E as EngineConfig } from './Configuration-
|
|
13
|
+
import { D as DEFAULT_CONFIG, E as EngineConfig } from './Configuration-B-G5gTRn.cjs';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* One line's compiled bytecode, plus the variables it reads and writes.
|
|
@@ -213,9 +213,28 @@ declare class DocumentModel {
|
|
|
213
213
|
* bottom of a 20k-line document before this fix.
|
|
214
214
|
*/
|
|
215
215
|
private dirtyLineIds;
|
|
216
|
+
/**
|
|
217
|
+
* Most lines this model will hold. See `constants/Configuration.ts`'s
|
|
218
|
+
* `performance.maxDocumentLines`, which is where the default comes from and
|
|
219
|
+
* which a host raises through its engine config; a host that builds a
|
|
220
|
+
* DocumentModel directly passes it here instead.
|
|
221
|
+
*/
|
|
222
|
+
private readonly maxLines;
|
|
223
|
+
/**
|
|
224
|
+
* @param maxLines - Ceiling on the line count, defaulting to the engine's
|
|
225
|
+
* configured one. Every line costs a LineState with six arrays in it
|
|
226
|
+
* whatever the line says, so the cost of a document is its line count and
|
|
227
|
+
* nothing else bounds it: two hundred thousand lines of `1 + 1` exhausted
|
|
228
|
+
* the heap here, before a single expression had been looked at.
|
|
229
|
+
*/
|
|
230
|
+
constructor(maxLines?: number);
|
|
216
231
|
/**
|
|
217
232
|
* Initialize or replace the entire document from a text blob.
|
|
218
233
|
* Clears all existing state and assigns new persistent line IDs.
|
|
234
|
+
*
|
|
235
|
+
* @throws `DOCUMENT_TOO_LARGE` for a document past {@link maxLines}, before
|
|
236
|
+
* any of it is stored. Recoverable: nothing has been replaced yet, so the
|
|
237
|
+
* model still holds whatever it held.
|
|
219
238
|
*/
|
|
220
239
|
setDocument(text: string): void;
|
|
221
240
|
/**
|
|
@@ -1407,9 +1426,17 @@ declare class ExpressionEngine {
|
|
|
1407
1426
|
* own contract). This engine-instance-local registration is reversed
|
|
1408
1427
|
* here too, even though it isn't a "shared" registry, so a package's
|
|
1409
1428
|
* lexer and highlighting contributions clean up together rather than
|
|
1410
|
-
* only half-reversing on unregister.
|
|
1411
|
-
*
|
|
1412
|
-
*
|
|
1429
|
+
* only half-reversing on unregister. Normalizer rules are reversed here
|
|
1430
|
+
* for the same reason: they are per-engine, but they live in an ARRAY the
|
|
1431
|
+
* normalizer walks at every token position, so re-registering a package
|
|
1432
|
+
* appended a second copy of every rule and lexing got slower with every
|
|
1433
|
+
* register/unregister cycle.
|
|
1434
|
+
*
|
|
1435
|
+
* Per-engine parselets and phrases are still left in place: a parselet
|
|
1436
|
+
* lives in this engine's isolated registry and a phrase goes into a
|
|
1437
|
+
* text-keyed trie where registering the same phrase twice is the same as
|
|
1438
|
+
* registering it once, so neither accumulates and both are discarded with
|
|
1439
|
+
* the engine instance.
|
|
1413
1440
|
*
|
|
1414
1441
|
* Clears the bytecode cache, removing handlers changes what compiled
|
|
1415
1442
|
* bytecode is valid.
|
|
@@ -1527,6 +1554,12 @@ declare class ExpressionEngine {
|
|
|
1527
1554
|
* parseExpression(). Abstracts the API difference between the two parsers:
|
|
1528
1555
|
* - PrecedenceParser: parser.setBuilder(builder); parser.parseExpression(0)
|
|
1529
1556
|
* - RD: parser.builder = builder; parser.parseExpression(0)
|
|
1557
|
+
*
|
|
1558
|
+
* @param allowLabelFallback - Whether a line that does not parse whole may
|
|
1559
|
+
* be retried as "<label>: <expression>". True for a real line, false for
|
|
1560
|
+
* the retries that fallback makes itself, which is what stops it costing
|
|
1561
|
+
* exponential time; see the loop below, and the comment on its recursive
|
|
1562
|
+
* call for the measurement.
|
|
1530
1563
|
*/
|
|
1531
1564
|
private parseExpression;
|
|
1532
1565
|
/**
|
|
@@ -1548,9 +1581,17 @@ declare class ExpressionEngine {
|
|
|
1548
1581
|
* (a bare assignment's RHS, and an equation's own RHS at solve time)
|
|
1549
1582
|
*, every one of these needs forward-tolerant reads of not-yet-defined
|
|
1550
1583
|
* names, which ordinary evaluation deliberately never allows.
|
|
1584
|
+
*
|
|
1585
|
+
* `lineNumber` is the 1-based document line this program belongs to, so
|
|
1586
|
+
* the RHS still receives a {@link makeLineContext}, a bare assignment's
|
|
1587
|
+
* right-hand side (`total = prev`, `x = line2`) can therefore read
|
|
1588
|
+
* cross-line results exactly as a bare expression line does. Defaults to
|
|
1589
|
+
* `-1` (the "no real document" sentinel) for the expression-level and
|
|
1590
|
+
* `=>`-without-a-document callers, which naturally yields the same
|
|
1591
|
+
* `LINE_REF_NO_DOCUMENT` a single-expression eval already returns.
|
|
1551
1592
|
*/
|
|
1552
1593
|
private executeSymbolicTolerant;
|
|
1553
|
-
/** Compiles and executes `tokens` in symbolic-tolerant mode, the "just simplify this" `=>` fallback when there's no stored equation to solve. */
|
|
1594
|
+
/** Compiles and executes `tokens` in symbolic-tolerant mode, the "just simplify this" `=>` fallback when there's no stored equation to solve. `lineNumber` (1-based, `-1` outside a document) is forwarded so a bare assignment's RHS can resolve cross-line references. */
|
|
1554
1595
|
private simplifySymbolically;
|
|
1555
1596
|
/**
|
|
1556
1597
|
* Parses a bare (colon-less) equation's left-hand side, `factor1 *
|
|
@@ -2270,7 +2311,7 @@ declare class LanguageService {
|
|
|
2270
2311
|
* highlighted the obvious way.
|
|
2271
2312
|
*
|
|
2272
2313
|
* A token the normalizer left alone still describes its own text, so its
|
|
2273
|
-
* span is `offset` to `offset +
|
|
2314
|
+
* span is `offset` to `offset + text.length`, exactly as before.
|
|
2274
2315
|
*
|
|
2275
2316
|
* A FUSED token does not. `10 frames` becomes a FRAME_COUNT whose value is
|
|
2276
2317
|
* `10`, and a timecode becomes a token whose value is a comma-separated
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { B as BytecodeBuilder } from './BytecodeBuilder-
|
|
1
|
+
import { B as BytecodeBuilder } from './BytecodeBuilder-B0xskcv5.js';
|
|
2
2
|
import { T as Token } from './Token-BzG5G4ja.js';
|
|
3
|
-
import { D as DiagnosticPipeline } from './pipeline-
|
|
3
|
+
import { D as DiagnosticPipeline } from './pipeline-B6k5lCB7.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Dual-keyed ParseletRegistry, accepts both string token types and
|
|
@@ -44,13 +44,44 @@ declare class ParseletRegistry {
|
|
|
44
44
|
registerPrefix(tokenType: string, parselet: PrefixParselet): void;
|
|
45
45
|
/** Register an infix parselet for `tokenType`. See {@link registerPrefix} for the collision-warning behavior this mirrors. */
|
|
46
46
|
registerInfix(tokenType: string, parselet: InfixParselet): void;
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Iterate all registered prefix parselets for diagnostic display.
|
|
49
|
+
*
|
|
50
|
+
* `PrefixParselet` declares no binding power, and this used to read a field
|
|
51
|
+
* of that name and report 0 for every one of them. 0 is not a neutral
|
|
52
|
+
* wrong answer: it is the value that means "not an operator, stop the
|
|
53
|
+
* expression", so a host drawing a table from this was told none of them
|
|
54
|
+
* bind at all. A prefix parselet in this parser has no per-parselet power
|
|
55
|
+
* to report, they all bind at the prefix level and each chooses for itself
|
|
56
|
+
* at what power to parse its own operand, so that level is what is
|
|
57
|
+
* reported. A parselet that does carry its own `bindingPower` still wins.
|
|
58
|
+
*/
|
|
48
59
|
getAllPrefix(): Array<{
|
|
49
60
|
tokenType: string;
|
|
50
61
|
bindingPower: number;
|
|
51
62
|
category?: string;
|
|
52
63
|
}>;
|
|
53
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Iterate all registered infix parselets for diagnostic display.
|
|
66
|
+
*
|
|
67
|
+
* The field an `InfixParselet` actually declares is `bindingPower`. This
|
|
68
|
+
* used to read `leftBindingPower` and `rightBindingPower`, which no
|
|
69
|
+
* parselet in this codebase declares, so both reads were `undefined`, both
|
|
70
|
+
* fell to the `?? 0` default, and the public `getParseletRegistry()`
|
|
71
|
+
* reported a binding power of 0 for every one of the ~60 infix operators.
|
|
72
|
+
* A host building a precedence table from it was told `*` and `+` bind
|
|
73
|
+
* equally, and that neither binds at all.
|
|
74
|
+
*
|
|
75
|
+
* The left/right split: `bindingPower` is the LEFT power, and the right is
|
|
76
|
+
* one higher. That is the standard encoding for a left-associative
|
|
77
|
+
* operator, and it is what the parser itself does, see
|
|
78
|
+
* `PrecedenceParser.parseExpression()`'s `bp + 1` for the right operand.
|
|
79
|
+
* Every operator is reported that way, `^` included. Associativity is not
|
|
80
|
+
* something a parselet declares, it is a property of how each one calls
|
|
81
|
+
* `parseExpression`, so this API cannot report it without a new field on
|
|
82
|
+
* the interface. See {@link ParseletBindingPowers} for why scraping a
|
|
83
|
+
* plausible-looking one off the parselet is worse than not reporting it.
|
|
84
|
+
*/
|
|
54
85
|
getAllInfix(): Array<{
|
|
55
86
|
tokenType: string;
|
|
56
87
|
leftBindingPower: number;
|
|
@@ -137,6 +168,7 @@ declare class PrecedenceParser {
|
|
|
137
168
|
private static readonly CARET_ID;
|
|
138
169
|
private static readonly LSHIFT_ID;
|
|
139
170
|
private static readonly RSHIFT_ID;
|
|
171
|
+
private static readonly URSHIFT_ID;
|
|
140
172
|
private static readonly BIT_AND_ID;
|
|
141
173
|
private static readonly BIT_OR_ID;
|
|
142
174
|
private static readonly BIT_XOR_ID;
|
|
@@ -170,7 +202,7 @@ declare class PrecedenceParser {
|
|
|
170
202
|
*
|
|
171
203
|
* @param minBp - minimum binding power (precedence climbing threshold).
|
|
172
204
|
* For left-associative operators, the recursive call uses `bp + 1`.
|
|
173
|
-
* For right-associative operators (^), it uses `bp`.
|
|
205
|
+
* For right-associative operators (^), it uses `bp - 1`.
|
|
174
206
|
* @param _builder - accepted for parselet API compatibility; always uses `this.builder`.
|
|
175
207
|
*/
|
|
176
208
|
parseExpression(minBp?: number, _builder?: BytecodeBuilder): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { B as BytecodeBuilder } from './BytecodeBuilder-
|
|
1
|
+
import { B as BytecodeBuilder } from './BytecodeBuilder-B0xskcv5.cjs';
|
|
2
2
|
import { T as Token } from './Token-BzG5G4ja.cjs';
|
|
3
|
-
import { D as DiagnosticPipeline } from './pipeline-
|
|
3
|
+
import { D as DiagnosticPipeline } from './pipeline-BEb3hujr.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Dual-keyed ParseletRegistry, accepts both string token types and
|
|
@@ -44,13 +44,44 @@ declare class ParseletRegistry {
|
|
|
44
44
|
registerPrefix(tokenType: string, parselet: PrefixParselet): void;
|
|
45
45
|
/** Register an infix parselet for `tokenType`. See {@link registerPrefix} for the collision-warning behavior this mirrors. */
|
|
46
46
|
registerInfix(tokenType: string, parselet: InfixParselet): void;
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Iterate all registered prefix parselets for diagnostic display.
|
|
49
|
+
*
|
|
50
|
+
* `PrefixParselet` declares no binding power, and this used to read a field
|
|
51
|
+
* of that name and report 0 for every one of them. 0 is not a neutral
|
|
52
|
+
* wrong answer: it is the value that means "not an operator, stop the
|
|
53
|
+
* expression", so a host drawing a table from this was told none of them
|
|
54
|
+
* bind at all. A prefix parselet in this parser has no per-parselet power
|
|
55
|
+
* to report, they all bind at the prefix level and each chooses for itself
|
|
56
|
+
* at what power to parse its own operand, so that level is what is
|
|
57
|
+
* reported. A parselet that does carry its own `bindingPower` still wins.
|
|
58
|
+
*/
|
|
48
59
|
getAllPrefix(): Array<{
|
|
49
60
|
tokenType: string;
|
|
50
61
|
bindingPower: number;
|
|
51
62
|
category?: string;
|
|
52
63
|
}>;
|
|
53
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Iterate all registered infix parselets for diagnostic display.
|
|
66
|
+
*
|
|
67
|
+
* The field an `InfixParselet` actually declares is `bindingPower`. This
|
|
68
|
+
* used to read `leftBindingPower` and `rightBindingPower`, which no
|
|
69
|
+
* parselet in this codebase declares, so both reads were `undefined`, both
|
|
70
|
+
* fell to the `?? 0` default, and the public `getParseletRegistry()`
|
|
71
|
+
* reported a binding power of 0 for every one of the ~60 infix operators.
|
|
72
|
+
* A host building a precedence table from it was told `*` and `+` bind
|
|
73
|
+
* equally, and that neither binds at all.
|
|
74
|
+
*
|
|
75
|
+
* The left/right split: `bindingPower` is the LEFT power, and the right is
|
|
76
|
+
* one higher. That is the standard encoding for a left-associative
|
|
77
|
+
* operator, and it is what the parser itself does, see
|
|
78
|
+
* `PrecedenceParser.parseExpression()`'s `bp + 1` for the right operand.
|
|
79
|
+
* Every operator is reported that way, `^` included. Associativity is not
|
|
80
|
+
* something a parselet declares, it is a property of how each one calls
|
|
81
|
+
* `parseExpression`, so this API cannot report it without a new field on
|
|
82
|
+
* the interface. See {@link ParseletBindingPowers} for why scraping a
|
|
83
|
+
* plausible-looking one off the parselet is worse than not reporting it.
|
|
84
|
+
*/
|
|
54
85
|
getAllInfix(): Array<{
|
|
55
86
|
tokenType: string;
|
|
56
87
|
leftBindingPower: number;
|
|
@@ -137,6 +168,7 @@ declare class PrecedenceParser {
|
|
|
137
168
|
private static readonly CARET_ID;
|
|
138
169
|
private static readonly LSHIFT_ID;
|
|
139
170
|
private static readonly RSHIFT_ID;
|
|
171
|
+
private static readonly URSHIFT_ID;
|
|
140
172
|
private static readonly BIT_AND_ID;
|
|
141
173
|
private static readonly BIT_OR_ID;
|
|
142
174
|
private static readonly BIT_XOR_ID;
|
|
@@ -170,7 +202,7 @@ declare class PrecedenceParser {
|
|
|
170
202
|
*
|
|
171
203
|
* @param minBp - minimum binding power (precedence climbing threshold).
|
|
172
204
|
* For left-associative operators, the recursive call uses `bp + 1`.
|
|
173
|
-
* For right-associative operators (^), it uses `bp`.
|
|
205
|
+
* For right-associative operators (^), it uses `bp - 1`.
|
|
174
206
|
* @param _builder - accepted for parselet API compatibility; always uses `this.builder`.
|
|
175
207
|
*/
|
|
176
208
|
parseExpression(minBp?: number, _builder?: BytecodeBuilder): void;
|