solve-engine 2.31.1 → 2.33.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/dist/{EngineError-CqGtaT_v.d.cts → EngineError-Bm4OYmw8.d.cts} +6 -0
- package/dist/{EngineError-CqGtaT_v.d.ts → EngineError-Bm4OYmw8.d.ts} +6 -0
- package/dist/{Lexer-CqFjYoRA.d.ts → Lexer-DPn5dfCH.d.ts} +1 -13
- package/dist/{Lexer-sCI05tqO.d.cts → Lexer-DaWkCu84.d.cts} +1 -13
- package/dist/{PackageCompatibility-phvSFP4f.d.ts → PackageCompatibility-CkzZfoJ3.d.ts} +1 -1
- package/dist/{PackageCompatibility-Bn-T_xKW.d.cts → PackageCompatibility-E_5GtcQW.d.cts} +1 -1
- package/dist/{PackageRegistry-C78jVkI9.d.ts → PackageRegistry-DSqic8kz.d.ts} +132 -23
- package/dist/{PackageRegistry-B-C1duZw.d.cts → PackageRegistry-js47hr28.d.cts} +132 -23
- package/dist/{Parselet-Dgymjxzd.d.ts → Parselet-CQjcHOKw.d.ts} +13 -6
- package/dist/{Parselet-DF3864la.d.cts → Parselet-s1sRRn8H.d.cts} +13 -6
- package/dist/{TokenNormalizer-Pe3_390t.d.cts → TokenNormalizer-D382VSYh.d.cts} +4 -1
- package/dist/{TokenNormalizer-IF7nPRMp.d.ts → TokenNormalizer-DAzPp-j1.d.ts} +4 -1
- package/dist/{VMBuiltins-BkKzhj6C.d.cts → VMBuiltins-JCavlQUj.d.cts} +53 -18
- package/dist/{VMBuiltins-Du9y8sEo.d.ts → VMBuiltins-qgzA6qGi.d.ts} +53 -18
- package/dist/{VMCheckpoints-WdUQrdc9.d.cts → VMCheckpoints-BxPzmdu0.d.cts} +2 -2
- package/dist/{VMCheckpoints-gvy_yxYh.d.ts → VMCheckpoints-DjjE92mf.d.ts} +2 -2
- package/dist/{Value-BYHw-x7q.d.cts → Value-2TIKi-YL.d.cts} +19 -0
- package/dist/{Value-BYHw-x7q.d.ts → Value-2TIKi-YL.d.ts} +19 -0
- package/dist/{WorkerError-DTrl3Jag.d.ts → WorkerError-BaN8_eok.d.ts} +1 -1
- package/dist/{WorkerError-CRoM8Ju1.d.cts → WorkerError-CexHHmbb.d.cts} +1 -1
- package/dist/{chunk-AGCNMEP2.cjs → chunk-3MG7VIPL.cjs} +2 -2
- package/dist/{chunk-AGCNMEP2.cjs.map → chunk-3MG7VIPL.cjs.map} +1 -1
- package/dist/chunk-4ASM522I.js +2 -0
- package/dist/chunk-4ASM522I.js.map +1 -0
- package/dist/chunk-4M3FZRGL.cjs +5 -0
- package/dist/chunk-4M3FZRGL.cjs.map +1 -0
- package/dist/{chunk-KH4QXKLT.js → chunk-4MD5L23F.js} +2 -2
- package/dist/{chunk-KH4QXKLT.js.map → chunk-4MD5L23F.js.map} +1 -1
- package/dist/{chunk-IQVSCL2R.js → chunk-4XWZXP6I.js} +3 -3
- package/dist/{chunk-IQVSCL2R.js.map → chunk-4XWZXP6I.js.map} +1 -1
- package/dist/{chunk-BSGZ3OEL.cjs → chunk-6DCSGINN.cjs} +3 -3
- package/dist/{chunk-BSGZ3OEL.cjs.map → chunk-6DCSGINN.cjs.map} +1 -1
- package/dist/{chunk-RELMEWY6.js → chunk-6G2NES2I.js} +2 -2
- package/dist/chunk-6G2NES2I.js.map +1 -0
- package/dist/{chunk-CDE2ZUGG.js → chunk-6NL7RBAG.js} +2 -2
- package/dist/{chunk-CDE2ZUGG.js.map → chunk-6NL7RBAG.js.map} +1 -1
- package/dist/{chunk-SUAGBRQ7.cjs → chunk-6SYU4MH7.cjs} +2 -2
- package/dist/chunk-6SYU4MH7.cjs.map +1 -0
- package/dist/chunk-72J5V7SN.cjs +2 -0
- package/dist/chunk-72J5V7SN.cjs.map +1 -0
- package/dist/chunk-7CRVRPV7.cjs +3 -0
- package/dist/chunk-7CRVRPV7.cjs.map +1 -0
- package/dist/chunk-ADK7LGYN.js +5 -0
- package/dist/chunk-ADK7LGYN.js.map +1 -0
- package/dist/chunk-APYRNAU2.js +2 -0
- package/dist/chunk-APYRNAU2.js.map +1 -0
- package/dist/{chunk-KBRSNJMQ.js → chunk-D55NMAGM.js} +3 -3
- package/dist/{chunk-KBRSNJMQ.js.map → chunk-D55NMAGM.js.map} +1 -1
- package/dist/chunk-DB5ISONG.js +2 -0
- package/dist/chunk-DB5ISONG.js.map +1 -0
- package/dist/chunk-EOKHRS2T.js +2 -0
- package/dist/chunk-EOKHRS2T.js.map +1 -0
- package/dist/{chunk-NQFCXLEF.js → chunk-EOO6M65F.js} +2 -2
- package/dist/{chunk-NQFCXLEF.js.map → chunk-EOO6M65F.js.map} +1 -1
- package/dist/{chunk-A764BY7L.cjs → chunk-EQNKDTMX.cjs} +2 -2
- package/dist/{chunk-A764BY7L.cjs.map → chunk-EQNKDTMX.cjs.map} +1 -1
- package/dist/chunk-FESR6PZI.cjs +2 -0
- package/dist/chunk-FESR6PZI.cjs.map +1 -0
- package/dist/chunk-G5TZ6TDA.js +2 -0
- package/dist/chunk-G5TZ6TDA.js.map +1 -0
- package/dist/chunk-GDLYXRMA.cjs +2 -0
- package/dist/chunk-GDLYXRMA.cjs.map +1 -0
- package/dist/chunk-HOU7QTE7.js +3 -0
- package/dist/chunk-HOU7QTE7.js.map +1 -0
- package/dist/{chunk-VYQNPCM5.cjs → chunk-HPV4CKCC.cjs} +2 -2
- package/dist/{chunk-VYQNPCM5.cjs.map → chunk-HPV4CKCC.cjs.map} +1 -1
- package/dist/{chunk-7DJYS5PO.cjs → chunk-HSTGWWU2.cjs} +2 -2
- package/dist/{chunk-7DJYS5PO.cjs.map → chunk-HSTGWWU2.cjs.map} +1 -1
- package/dist/{chunk-OE2DBN4K.js → chunk-INMJ7ZXL.js} +2 -2
- package/dist/chunk-INMJ7ZXL.js.map +1 -0
- package/dist/{chunk-TP5EQCGH.js → chunk-J3YC3IQD.js} +2 -2
- package/dist/{chunk-TP5EQCGH.js.map → chunk-J3YC3IQD.js.map} +1 -1
- package/dist/{chunk-5AKT36UK.cjs → chunk-K3PZ66XR.cjs} +2 -2
- package/dist/{chunk-5AKT36UK.cjs.map → chunk-K3PZ66XR.cjs.map} +1 -1
- package/dist/chunk-LI6LYJDA.cjs +2 -0
- package/dist/chunk-LI6LYJDA.cjs.map +1 -0
- package/dist/{chunk-WQGHJAW2.cjs → chunk-M4UC2PB6.cjs} +2 -2
- package/dist/{chunk-WQGHJAW2.cjs.map → chunk-M4UC2PB6.cjs.map} +1 -1
- package/dist/chunk-O7HF345B.js +2 -0
- package/dist/chunk-O7HF345B.js.map +1 -0
- package/dist/{chunk-CM2WM5CM.cjs → chunk-OBZJKZ2F.cjs} +2 -2
- package/dist/{chunk-CM2WM5CM.cjs.map → chunk-OBZJKZ2F.cjs.map} +1 -1
- package/dist/{chunk-Q7TBBV62.cjs → chunk-P5YWBIIU.cjs} +2 -2
- package/dist/chunk-P5YWBIIU.cjs.map +1 -0
- package/dist/chunk-PICFFFJV.js +3 -0
- package/dist/chunk-PICFFFJV.js.map +1 -0
- package/dist/{chunk-P43SV4NJ.cjs → chunk-QOOTRUY7.cjs} +3 -3
- package/dist/{chunk-P43SV4NJ.cjs.map → chunk-QOOTRUY7.cjs.map} +1 -1
- package/dist/chunk-R3W53ZMP.cjs +2 -0
- package/dist/chunk-R3W53ZMP.cjs.map +1 -0
- package/dist/chunk-RMDCGYZM.js +2 -0
- package/dist/chunk-RMDCGYZM.js.map +1 -0
- package/dist/{chunk-CB3EXUM2.js → chunk-RU3KGJRA.js} +2 -2
- package/dist/chunk-RU3KGJRA.js.map +1 -0
- package/dist/chunk-S3SPDK6N.cjs +2 -0
- package/dist/chunk-S3SPDK6N.cjs.map +1 -0
- package/dist/chunk-SF5QVUEI.cjs +3 -0
- package/dist/chunk-SF5QVUEI.cjs.map +1 -0
- package/dist/{chunk-FXB5GCBT.js → chunk-TJKN466F.js} +2 -2
- package/dist/{chunk-FXB5GCBT.js.map → chunk-TJKN466F.js.map} +1 -1
- package/dist/{chunk-VLX7ZVK4.js → chunk-U5MESNRT.js} +2 -2
- package/dist/{chunk-VLX7ZVK4.js.map → chunk-U5MESNRT.js.map} +1 -1
- package/dist/{chunk-YWF6C2IO.cjs → chunk-WFT3XUSH.cjs} +2 -2
- package/dist/{chunk-YWF6C2IO.cjs.map → chunk-WFT3XUSH.cjs.map} +1 -1
- package/dist/{chunk-3ZGFAE3Q.js → chunk-X2GQAKL2.js} +2 -2
- package/dist/{chunk-3ZGFAE3Q.js.map → chunk-X2GQAKL2.js.map} +1 -1
- package/dist/{chunk-G3POUURF.js → chunk-YID47OPR.js} +2 -2
- package/dist/{chunk-G3POUURF.js.map → chunk-YID47OPR.js.map} +1 -1
- package/dist/chunk-YV4GDW5A.cjs +2 -0
- package/dist/chunk-YV4GDW5A.cjs.map +1 -0
- package/dist/chunk-ZSXQP7PD.cjs +2 -0
- package/dist/chunk-ZSXQP7PD.cjs.map +1 -0
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/engine.cjs +1 -1
- package/dist/engine.d.cts +10 -10
- package/dist/engine.d.ts +10 -10
- package/dist/engine.js +1 -1
- package/dist/engine.worker.cjs +1 -1
- package/dist/engine.worker.cjs.map +1 -1
- package/dist/engine.worker.js +1 -1
- package/dist/engine.worker.js.map +1 -1
- package/dist/errors.cjs +1 -1
- package/dist/errors.d.cts +3 -3
- package/dist/errors.d.ts +3 -3
- package/dist/errors.js +1 -1
- package/dist/format.cjs +1 -1
- package/dist/format.d.cts +1 -1
- package/dist/format.d.ts +1 -1
- package/dist/format.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/language.d.cts +9 -9
- package/dist/language.d.ts +9 -9
- package/dist/lexer.cjs +1 -1
- package/dist/lexer.d.cts +3 -3
- package/dist/lexer.d.ts +3 -3
- package/dist/lexer.js +1 -1
- package/dist/normalizer.cjs +1 -1
- package/dist/normalizer.d.cts +2 -2
- package/dist/normalizer.d.ts +2 -2
- package/dist/normalizer.js +1 -1
- package/dist/packages.cjs +1 -1
- package/dist/packages.d.cts +8 -8
- package/dist/packages.d.ts +8 -8
- package/dist/packages.js +1 -1
- package/dist/parser.cjs +1 -1
- package/dist/parser.d.cts +3 -3
- package/dist/parser.d.ts +3 -3
- package/dist/parser.js +1 -1
- package/dist/{pipeline-BYkKNpql.d.cts → pipeline-Bum6y1B9.d.cts} +1 -1
- package/dist/{pipeline-Cl7KW8CB.d.ts → pipeline-DOo3KHaq.d.ts} +1 -1
- package/dist/resolvers.cjs +1 -1
- package/dist/resolvers.d.cts +69 -3
- package/dist/resolvers.d.ts +69 -3
- package/dist/resolvers.js +1 -1
- package/dist/temporal.cjs +1 -1
- package/dist/temporal.js +1 -1
- package/dist/testing.cjs +2 -2
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +9 -9
- package/dist/testing.d.ts +9 -9
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/uom.cjs +1 -1
- package/dist/uom.d.cts +35 -2
- package/dist/uom.d.ts +35 -2
- package/dist/uom.js +1 -1
- package/dist/vm.cjs +1 -1
- package/dist/vm.d.cts +6 -6
- package/dist/vm.d.ts +6 -6
- package/dist/vm.js +1 -1
- package/dist/worker.cjs +2 -2
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.cts +9 -9
- package/dist/worker.d.ts +9 -9
- package/dist/worker.js +1 -1
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-4DR5RBHQ.cjs +0 -2
- package/dist/chunk-4DR5RBHQ.cjs.map +0 -1
- package/dist/chunk-6LA7HC46.js +0 -3
- package/dist/chunk-6LA7HC46.js.map +0 -1
- package/dist/chunk-A755LVPT.cjs +0 -2
- package/dist/chunk-A755LVPT.cjs.map +0 -1
- package/dist/chunk-AF6NDOIE.js +0 -2
- package/dist/chunk-AF6NDOIE.js.map +0 -1
- package/dist/chunk-B2NL65FI.js +0 -2
- package/dist/chunk-B2NL65FI.js.map +0 -1
- package/dist/chunk-CB3EXUM2.js.map +0 -1
- package/dist/chunk-DUFEONVN.cjs +0 -3
- package/dist/chunk-DUFEONVN.cjs.map +0 -1
- package/dist/chunk-IJHL3LMH.js +0 -2
- package/dist/chunk-IJHL3LMH.js.map +0 -1
- package/dist/chunk-LCYQQFUH.cjs +0 -2
- package/dist/chunk-LCYQQFUH.cjs.map +0 -1
- package/dist/chunk-LP3JYC3A.js +0 -2
- package/dist/chunk-LP3JYC3A.js.map +0 -1
- package/dist/chunk-MDTIL3UT.cjs +0 -5
- package/dist/chunk-MDTIL3UT.cjs.map +0 -1
- package/dist/chunk-MZQ3ED6J.cjs +0 -3
- package/dist/chunk-MZQ3ED6J.cjs.map +0 -1
- package/dist/chunk-OE2DBN4K.js.map +0 -1
- package/dist/chunk-OM7NOHJF.cjs +0 -2
- package/dist/chunk-OM7NOHJF.cjs.map +0 -1
- package/dist/chunk-PTXUWGRR.js +0 -3
- package/dist/chunk-PTXUWGRR.js.map +0 -1
- package/dist/chunk-Q7TBBV62.cjs.map +0 -1
- package/dist/chunk-RELMEWY6.js.map +0 -1
- package/dist/chunk-SFM4XFGJ.js +0 -2
- package/dist/chunk-SFM4XFGJ.js.map +0 -1
- package/dist/chunk-SNYFNARL.js +0 -5
- package/dist/chunk-SNYFNARL.js.map +0 -1
- package/dist/chunk-SUAGBRQ7.cjs.map +0 -1
- package/dist/chunk-UNKZ5XRC.cjs +0 -2
- package/dist/chunk-UNKZ5XRC.cjs.map +0 -1
- package/dist/chunk-WU7SBKVU.cjs +0 -2
- package/dist/chunk-WU7SBKVU.cjs.map +0 -1
- package/dist/chunk-X5K72MBV.js +0 -2
- package/dist/chunk-X5K72MBV.js.map +0 -1
- package/dist/chunk-ZVPZQ66D.cjs +0 -2
- package/dist/chunk-ZVPZQ66D.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { B as BytecodeBuilder } from './BytecodeBuilder-DSWKZi4f.js';
|
|
2
2
|
import { T as Token } from './Token-D8f7yaz1.js';
|
|
3
|
-
import { D as DiagnosticPipeline } from './pipeline-
|
|
3
|
+
import { D as DiagnosticPipeline } from './pipeline-DOo3KHaq.js';
|
|
4
4
|
import { C as CalendarBackend } from './CalendarBackend-MdS3Bb4P.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -77,16 +77,15 @@ declare class ParseletRegistry {
|
|
|
77
77
|
* one higher. That is the standard encoding for a left-associative
|
|
78
78
|
* operator, and it is what the parser itself does, see
|
|
79
79
|
* `PrecedenceParser.parseExpression()`'s `bp + 1` for the right operand.
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* `
|
|
83
|
-
* the interface. See {@link ParseletBindingPowers} for why scraping a
|
|
84
|
-
* plausible-looking one off the parselet is worse than not reporting it.
|
|
80
|
+
* An operator that declares `rightAssociative` (`^`) is reported with the
|
|
81
|
+
* right power one BELOW the left, which is how it parses its right operand
|
|
82
|
+
* (see `parseRightOperand`), and `associativity` says which in words.
|
|
85
83
|
*/
|
|
86
84
|
getAllInfix(): Array<{
|
|
87
85
|
tokenType: string;
|
|
88
86
|
leftBindingPower: number;
|
|
89
87
|
rightBindingPower: number;
|
|
88
|
+
associativity: "left" | "right";
|
|
90
89
|
category?: string;
|
|
91
90
|
}>;
|
|
92
91
|
/** Number of registered prefix parselets. */
|
|
@@ -363,6 +362,14 @@ interface InfixParselet {
|
|
|
363
362
|
readonly category: string;
|
|
364
363
|
/** Binding power (precedence), property access avoids vtable dispatch in hot loop */
|
|
365
364
|
readonly bindingPower: number;
|
|
365
|
+
/**
|
|
366
|
+
* Whether the operator groups from the right (`2 ^ 3 ^ 2` is `2 ^ (3 ^ 2)`).
|
|
367
|
+
* Absent means left, which is what every operator but exponentiation
|
|
368
|
+
* wants. Read by {@link parseRightOperand}, and reported by
|
|
369
|
+
* `ParseletRegistry.getAllInfix` so a precedence table built from the
|
|
370
|
+
* registry says what the parser does.
|
|
371
|
+
*/
|
|
372
|
+
readonly rightAssociative?: boolean;
|
|
366
373
|
parse(parser: PrecedenceParser, left: Token, token: Token, builder: BytecodeBuilder): void;
|
|
367
374
|
}
|
|
368
375
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { B as BytecodeBuilder } from './BytecodeBuilder-DSWKZi4f.cjs';
|
|
2
2
|
import { T as Token } from './Token-D8f7yaz1.cjs';
|
|
3
|
-
import { D as DiagnosticPipeline } from './pipeline-
|
|
3
|
+
import { D as DiagnosticPipeline } from './pipeline-Bum6y1B9.cjs';
|
|
4
4
|
import { C as CalendarBackend } from './CalendarBackend-MdS3Bb4P.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -77,16 +77,15 @@ declare class ParseletRegistry {
|
|
|
77
77
|
* one higher. That is the standard encoding for a left-associative
|
|
78
78
|
* operator, and it is what the parser itself does, see
|
|
79
79
|
* `PrecedenceParser.parseExpression()`'s `bp + 1` for the right operand.
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* `
|
|
83
|
-
* the interface. See {@link ParseletBindingPowers} for why scraping a
|
|
84
|
-
* plausible-looking one off the parselet is worse than not reporting it.
|
|
80
|
+
* An operator that declares `rightAssociative` (`^`) is reported with the
|
|
81
|
+
* right power one BELOW the left, which is how it parses its right operand
|
|
82
|
+
* (see `parseRightOperand`), and `associativity` says which in words.
|
|
85
83
|
*/
|
|
86
84
|
getAllInfix(): Array<{
|
|
87
85
|
tokenType: string;
|
|
88
86
|
leftBindingPower: number;
|
|
89
87
|
rightBindingPower: number;
|
|
88
|
+
associativity: "left" | "right";
|
|
90
89
|
category?: string;
|
|
91
90
|
}>;
|
|
92
91
|
/** Number of registered prefix parselets. */
|
|
@@ -363,6 +362,14 @@ interface InfixParselet {
|
|
|
363
362
|
readonly category: string;
|
|
364
363
|
/** Binding power (precedence), property access avoids vtable dispatch in hot loop */
|
|
365
364
|
readonly bindingPower: number;
|
|
365
|
+
/**
|
|
366
|
+
* Whether the operator groups from the right (`2 ^ 3 ^ 2` is `2 ^ (3 ^ 2)`).
|
|
367
|
+
* Absent means left, which is what every operator but exponentiation
|
|
368
|
+
* wants. Read by {@link parseRightOperand}, and reported by
|
|
369
|
+
* `ParseletRegistry.getAllInfix` so a precedence table built from the
|
|
370
|
+
* registry says what the parser does.
|
|
371
|
+
*/
|
|
372
|
+
readonly rightAssociative?: boolean;
|
|
366
373
|
parse(parser: PrecedenceParser, left: Token, token: Token, builder: BytecodeBuilder): void;
|
|
367
374
|
}
|
|
368
375
|
|
|
@@ -605,7 +605,10 @@ declare class TokenNormalizer {
|
|
|
605
605
|
* @param tokens - Raw tokens from the lexer
|
|
606
606
|
* @param onFusion - Optional fusion callback (overrides {@link NormalizerOptions.onFusion})
|
|
607
607
|
* @returns Normalized tokens ready for parsing
|
|
608
|
-
* @throws {Error} If the normalized token count exceeds maxTokens
|
|
608
|
+
* @throws {Error} If the normalized token count exceeds maxTokens, or the
|
|
609
|
+
* stream is still changing after maxPasses passes (a rule chain that never
|
|
610
|
+
* settles): NORMALIZER_PASS_LIMIT_EXCEEDED, rather than a stream that is
|
|
611
|
+
* quietly whatever the last pass left.
|
|
609
612
|
*/
|
|
610
613
|
normalize(tokens: Token[], onFusion?: (fusion: TokenFusion) => void): Token[];
|
|
611
614
|
}
|
|
@@ -605,7 +605,10 @@ declare class TokenNormalizer {
|
|
|
605
605
|
* @param tokens - Raw tokens from the lexer
|
|
606
606
|
* @param onFusion - Optional fusion callback (overrides {@link NormalizerOptions.onFusion})
|
|
607
607
|
* @returns Normalized tokens ready for parsing
|
|
608
|
-
* @throws {Error} If the normalized token count exceeds maxTokens
|
|
608
|
+
* @throws {Error} If the normalized token count exceeds maxTokens, or the
|
|
609
|
+
* stream is still changing after maxPasses passes (a rule chain that never
|
|
610
|
+
* settles): NORMALIZER_PASS_LIMIT_EXCEEDED, rather than a stream that is
|
|
611
|
+
* quietly whatever the last pass left.
|
|
609
612
|
*/
|
|
610
613
|
normalize(tokens: Token[], onFusion?: (fusion: TokenFusion) => void): Token[];
|
|
611
614
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { V as Value } from './Value-
|
|
1
|
+
import { V as Value } from './Value-2TIKi-YL.cjs';
|
|
2
2
|
import { U as UserFunctionDef, A as AnonymousBodyDef, a as BytecodeProgram } from './BytecodeBuilder-DSWKZi4f.cjs';
|
|
3
3
|
import { C as CalendarBackend } from './CalendarBackend-MdS3Bb4P.cjs';
|
|
4
|
-
import { E as EngineError } from './EngineError-
|
|
5
|
-
import { D as DiagnosticPipeline } from './pipeline-
|
|
4
|
+
import { E as EngineError } from './EngineError-Bm4OYmw8.cjs';
|
|
5
|
+
import { D as DiagnosticPipeline } from './pipeline-Bum6y1B9.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Create a new VM instance with the given opcode registry and configurable limits.
|
|
@@ -13,7 +13,11 @@ import { D as DiagnosticPipeline } from './pipeline-BYkKNpql.cjs';
|
|
|
13
13
|
* - An instruction counter (bounded by `maxInstructions`)
|
|
14
14
|
* - An AbortSignal for async cancellation
|
|
15
15
|
*
|
|
16
|
-
* @param registry -
|
|
16
|
+
* @param registry - Never consulted, and kept only so the parameter list a
|
|
17
|
+
* host already calls with keeps working. The dispatch loop refuses any
|
|
18
|
+
* opcode it has no arm for, whatever a registry claims about it; a package
|
|
19
|
+
* reaches the VM through `pluginFunctions` and `CALL_PLUGIN`. See
|
|
20
|
+
* `OpRegistry.ts`, and the deprecation there.
|
|
17
21
|
* @param maxStackDepth - Maximum stack slots (default 200)
|
|
18
22
|
* @param maxInstructions - Maximum opcodes per expression (default 50000)
|
|
19
23
|
* @param maxFunctionRecursionDepth - Maximum nested user-defined-function
|
|
@@ -176,9 +180,12 @@ type EvalResult = {
|
|
|
176
180
|
* switches (OpCode values 0–200) into a jump table with O(1) dispatch.
|
|
177
181
|
* All handler code is inlined directly in the switch cases, allowing
|
|
178
182
|
* TurboFan to optimize across opcode boundaries.
|
|
179
|
-
* - ADD/SUB/MUL
|
|
180
|
-
*
|
|
181
|
-
*
|
|
183
|
+
* - ADD/SUB/MUL/DIV and the six comparisons open with an inlined plain-number
|
|
184
|
+
* branch: two Numbers carrying no rational or uncertainty sidecar (>90% of
|
|
185
|
+
* arithmetic ops) are answered before any helper (fault propagation,
|
|
186
|
+
* percentage, rate period, money, unit, `binaryOp()`) is called. The
|
|
187
|
+
* sidecar checks are what keep the branch honest: an exact fraction or a
|
|
188
|
+
* measurement takes the ladder below it, exactly as before.
|
|
182
189
|
* - Tracing uses a boolean guard (`shouldTrace`) that the JIT eliminates
|
|
183
190
|
* entirely when diagnostics are disabled. No function call overhead.
|
|
184
191
|
* - `Value.toNumber()` caches its result, computed once, read thereafter.
|
|
@@ -346,26 +353,44 @@ interface ScalarEquationDef {
|
|
|
346
353
|
rhsProgram: BytecodeProgram;
|
|
347
354
|
}
|
|
348
355
|
/**
|
|
349
|
-
* Handler function for
|
|
350
|
-
* No longer dispatched directly from the VM switch, plugins register
|
|
351
|
-
* functions in pluginFunctionRegistry instead.
|
|
356
|
+
* Handler function for a custom opcode, in the shape the VM never calls.
|
|
352
357
|
*
|
|
353
|
-
* @deprecated
|
|
354
|
-
*
|
|
358
|
+
* @deprecated Nothing dispatches to a handler of this type. A package reaches
|
|
359
|
+
* the VM through `IEnginePackage.pluginFunctions`, which `CALL_PLUGIN`
|
|
360
|
+
* resolves per engine. Removed in the next major with {@link OpRegistry}.
|
|
355
361
|
*/
|
|
356
362
|
type OpcodeHandler = (vm: VM, opcodes: Uint8Array, ip: number, numbers: Float64Array, strings: string[]) => number;
|
|
357
|
-
/**
|
|
363
|
+
/**
|
|
364
|
+
* Registration payload for an opcode handler.
|
|
365
|
+
*
|
|
366
|
+
* @deprecated See {@link OpcodeHandler}. Removed in the next major.
|
|
367
|
+
*/
|
|
358
368
|
interface IOpcodeHandlerRegistration {
|
|
359
369
|
opcode: number;
|
|
360
370
|
handler: OpcodeHandler;
|
|
361
371
|
pluginName: string;
|
|
362
372
|
}
|
|
363
373
|
/**
|
|
364
|
-
*
|
|
374
|
+
* A table of custom opcode handlers the virtual machine never reads.
|
|
365
375
|
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
376
|
+
* This once described an extension point: a package allocated an opcode from
|
|
377
|
+
* the dynamic range (201 to 254), registered a handler for it, and the VM's
|
|
378
|
+
* dispatch switch was meant to call that handler from its default arm. The
|
|
379
|
+
* switch never consulted the registry, and until recently had no default arm
|
|
380
|
+
* at all, so a registered opcode ran as a no-op and the program failed some
|
|
381
|
+
* instructions later with a misleading STACK_UNDERFLOW. The dispatch loop now
|
|
382
|
+
* refuses any opcode it has no arm for, at that instruction, with
|
|
383
|
+
* `MALFORMED_BYTECODE_UNKNOWN_OPCODE`, whatever a registry claims about it.
|
|
384
|
+
*
|
|
385
|
+
* The class, the {@link sharedOpRegistry} singleton, the `registry` field on
|
|
386
|
+
* {@link VM} and the first parameter of `createVM()` are kept so the calls a
|
|
387
|
+
* host already makes keep compiling and running; every one of them is
|
|
388
|
+
* deprecated and goes in the next major. A package that wants the VM to run
|
|
389
|
+
* its code declares `IEnginePackage.pluginFunctions`, which `CALL_PLUGIN`
|
|
390
|
+
* resolves through the engine's own context, one table per engine.
|
|
391
|
+
*
|
|
392
|
+
* @deprecated Never consulted by the VM. Use `IEnginePackage.pluginFunctions`.
|
|
393
|
+
* Removed in the next major.
|
|
369
394
|
*/
|
|
370
395
|
declare class OpRegistry {
|
|
371
396
|
private handlers;
|
|
@@ -435,6 +460,11 @@ interface VM {
|
|
|
435
460
|
popString(): string;
|
|
436
461
|
peek(): Value;
|
|
437
462
|
getStack(): Value[];
|
|
463
|
+
/**
|
|
464
|
+
* The registry this machine was built with, which it never reads.
|
|
465
|
+
*
|
|
466
|
+
* @deprecated See {@link OpRegistry}. Removed in the next major.
|
|
467
|
+
*/
|
|
438
468
|
registry: OpRegistry;
|
|
439
469
|
/**
|
|
440
470
|
* Read a variable by name, checks the INNERMOST active user-defined-
|
|
@@ -550,7 +580,12 @@ interface VM {
|
|
|
550
580
|
*/
|
|
551
581
|
context: EngineContext;
|
|
552
582
|
}
|
|
553
|
-
/**
|
|
583
|
+
/**
|
|
584
|
+
* The registry every `createVM()` call without one of its own is handed.
|
|
585
|
+
*
|
|
586
|
+
* @deprecated See {@link OpRegistry}: the VM never reads it. Removed in the
|
|
587
|
+
* next major, together with `createVM()`'s first parameter.
|
|
588
|
+
*/
|
|
554
589
|
declare const sharedOpRegistry: OpRegistry;
|
|
555
590
|
|
|
556
591
|
/** Serialized snapshot of the dependency graph for diagnostic rendering. */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { V as Value } from './Value-
|
|
1
|
+
import { V as Value } from './Value-2TIKi-YL.js';
|
|
2
2
|
import { U as UserFunctionDef, A as AnonymousBodyDef, a as BytecodeProgram } from './BytecodeBuilder-DSWKZi4f.js';
|
|
3
3
|
import { C as CalendarBackend } from './CalendarBackend-MdS3Bb4P.js';
|
|
4
|
-
import { E as EngineError } from './EngineError-
|
|
5
|
-
import { D as DiagnosticPipeline } from './pipeline-
|
|
4
|
+
import { E as EngineError } from './EngineError-Bm4OYmw8.js';
|
|
5
|
+
import { D as DiagnosticPipeline } from './pipeline-DOo3KHaq.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Create a new VM instance with the given opcode registry and configurable limits.
|
|
@@ -13,7 +13,11 @@ import { D as DiagnosticPipeline } from './pipeline-Cl7KW8CB.js';
|
|
|
13
13
|
* - An instruction counter (bounded by `maxInstructions`)
|
|
14
14
|
* - An AbortSignal for async cancellation
|
|
15
15
|
*
|
|
16
|
-
* @param registry -
|
|
16
|
+
* @param registry - Never consulted, and kept only so the parameter list a
|
|
17
|
+
* host already calls with keeps working. The dispatch loop refuses any
|
|
18
|
+
* opcode it has no arm for, whatever a registry claims about it; a package
|
|
19
|
+
* reaches the VM through `pluginFunctions` and `CALL_PLUGIN`. See
|
|
20
|
+
* `OpRegistry.ts`, and the deprecation there.
|
|
17
21
|
* @param maxStackDepth - Maximum stack slots (default 200)
|
|
18
22
|
* @param maxInstructions - Maximum opcodes per expression (default 50000)
|
|
19
23
|
* @param maxFunctionRecursionDepth - Maximum nested user-defined-function
|
|
@@ -176,9 +180,12 @@ type EvalResult = {
|
|
|
176
180
|
* switches (OpCode values 0–200) into a jump table with O(1) dispatch.
|
|
177
181
|
* All handler code is inlined directly in the switch cases, allowing
|
|
178
182
|
* TurboFan to optimize across opcode boundaries.
|
|
179
|
-
* - ADD/SUB/MUL
|
|
180
|
-
*
|
|
181
|
-
*
|
|
183
|
+
* - ADD/SUB/MUL/DIV and the six comparisons open with an inlined plain-number
|
|
184
|
+
* branch: two Numbers carrying no rational or uncertainty sidecar (>90% of
|
|
185
|
+
* arithmetic ops) are answered before any helper (fault propagation,
|
|
186
|
+
* percentage, rate period, money, unit, `binaryOp()`) is called. The
|
|
187
|
+
* sidecar checks are what keep the branch honest: an exact fraction or a
|
|
188
|
+
* measurement takes the ladder below it, exactly as before.
|
|
182
189
|
* - Tracing uses a boolean guard (`shouldTrace`) that the JIT eliminates
|
|
183
190
|
* entirely when diagnostics are disabled. No function call overhead.
|
|
184
191
|
* - `Value.toNumber()` caches its result, computed once, read thereafter.
|
|
@@ -346,26 +353,44 @@ interface ScalarEquationDef {
|
|
|
346
353
|
rhsProgram: BytecodeProgram;
|
|
347
354
|
}
|
|
348
355
|
/**
|
|
349
|
-
* Handler function for
|
|
350
|
-
* No longer dispatched directly from the VM switch, plugins register
|
|
351
|
-
* functions in pluginFunctionRegistry instead.
|
|
356
|
+
* Handler function for a custom opcode, in the shape the VM never calls.
|
|
352
357
|
*
|
|
353
|
-
* @deprecated
|
|
354
|
-
*
|
|
358
|
+
* @deprecated Nothing dispatches to a handler of this type. A package reaches
|
|
359
|
+
* the VM through `IEnginePackage.pluginFunctions`, which `CALL_PLUGIN`
|
|
360
|
+
* resolves per engine. Removed in the next major with {@link OpRegistry}.
|
|
355
361
|
*/
|
|
356
362
|
type OpcodeHandler = (vm: VM, opcodes: Uint8Array, ip: number, numbers: Float64Array, strings: string[]) => number;
|
|
357
|
-
/**
|
|
363
|
+
/**
|
|
364
|
+
* Registration payload for an opcode handler.
|
|
365
|
+
*
|
|
366
|
+
* @deprecated See {@link OpcodeHandler}. Removed in the next major.
|
|
367
|
+
*/
|
|
358
368
|
interface IOpcodeHandlerRegistration {
|
|
359
369
|
opcode: number;
|
|
360
370
|
handler: OpcodeHandler;
|
|
361
371
|
pluginName: string;
|
|
362
372
|
}
|
|
363
373
|
/**
|
|
364
|
-
*
|
|
374
|
+
* A table of custom opcode handlers the virtual machine never reads.
|
|
365
375
|
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
376
|
+
* This once described an extension point: a package allocated an opcode from
|
|
377
|
+
* the dynamic range (201 to 254), registered a handler for it, and the VM's
|
|
378
|
+
* dispatch switch was meant to call that handler from its default arm. The
|
|
379
|
+
* switch never consulted the registry, and until recently had no default arm
|
|
380
|
+
* at all, so a registered opcode ran as a no-op and the program failed some
|
|
381
|
+
* instructions later with a misleading STACK_UNDERFLOW. The dispatch loop now
|
|
382
|
+
* refuses any opcode it has no arm for, at that instruction, with
|
|
383
|
+
* `MALFORMED_BYTECODE_UNKNOWN_OPCODE`, whatever a registry claims about it.
|
|
384
|
+
*
|
|
385
|
+
* The class, the {@link sharedOpRegistry} singleton, the `registry` field on
|
|
386
|
+
* {@link VM} and the first parameter of `createVM()` are kept so the calls a
|
|
387
|
+
* host already makes keep compiling and running; every one of them is
|
|
388
|
+
* deprecated and goes in the next major. A package that wants the VM to run
|
|
389
|
+
* its code declares `IEnginePackage.pluginFunctions`, which `CALL_PLUGIN`
|
|
390
|
+
* resolves through the engine's own context, one table per engine.
|
|
391
|
+
*
|
|
392
|
+
* @deprecated Never consulted by the VM. Use `IEnginePackage.pluginFunctions`.
|
|
393
|
+
* Removed in the next major.
|
|
369
394
|
*/
|
|
370
395
|
declare class OpRegistry {
|
|
371
396
|
private handlers;
|
|
@@ -435,6 +460,11 @@ interface VM {
|
|
|
435
460
|
popString(): string;
|
|
436
461
|
peek(): Value;
|
|
437
462
|
getStack(): Value[];
|
|
463
|
+
/**
|
|
464
|
+
* The registry this machine was built with, which it never reads.
|
|
465
|
+
*
|
|
466
|
+
* @deprecated See {@link OpRegistry}. Removed in the next major.
|
|
467
|
+
*/
|
|
438
468
|
registry: OpRegistry;
|
|
439
469
|
/**
|
|
440
470
|
* Read a variable by name, checks the INNERMOST active user-defined-
|
|
@@ -550,7 +580,12 @@ interface VM {
|
|
|
550
580
|
*/
|
|
551
581
|
context: EngineContext;
|
|
552
582
|
}
|
|
553
|
-
/**
|
|
583
|
+
/**
|
|
584
|
+
* The registry every `createVM()` call without one of its own is handed.
|
|
585
|
+
*
|
|
586
|
+
* @deprecated See {@link OpRegistry}: the VM never reads it. Removed in the
|
|
587
|
+
* next major, together with `createVM()`'s first parameter.
|
|
588
|
+
*/
|
|
554
589
|
declare const sharedOpRegistry: OpRegistry;
|
|
555
590
|
|
|
556
591
|
/** Serialized snapshot of the dependency graph for diagnostic rendering. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { V as Value } from './Value-
|
|
2
|
-
import { V as VM } from './VMBuiltins-
|
|
1
|
+
import { V as Value } from './Value-2TIKi-YL.cjs';
|
|
2
|
+
import { V as VM } from './VMBuiltins-JCavlQUj.cjs';
|
|
3
3
|
import { U as UserFunctionDef } from './BytecodeBuilder-DSWKZi4f.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { V as Value } from './Value-
|
|
2
|
-
import { V as VM } from './VMBuiltins-
|
|
1
|
+
import { V as Value } from './Value-2TIKi-YL.js';
|
|
2
|
+
import { V as VM } from './VMBuiltins-qgzA6qGi.js';
|
|
3
3
|
import { U as UserFunctionDef } from './BytecodeBuilder-DSWKZi4f.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -469,6 +469,25 @@ declare class Value {
|
|
|
469
469
|
* Called by ValueArena.acquire(), zero allocation, just field assignment.
|
|
470
470
|
*/
|
|
471
471
|
recycle(type: ValueType, value: number | bigint | string | boolean | MatrixData | RangeData | ColourData | SplitData | ChartData | IpCidrData | SymbolicNode, unit?: string): void;
|
|
472
|
+
/**
|
|
473
|
+
* A fresh Value carrying everything this one does: the payload, the unit,
|
|
474
|
+
* the cached number and every sidecar, present or future.
|
|
475
|
+
*
|
|
476
|
+
* The inverse of {@link recycle}, and written as a whole-object copy rather
|
|
477
|
+
* than a list of fields on purpose. `persistentValue()` used to name the
|
|
478
|
+
* sidecars it copied, and the two it did not name (`decimalPlaces`,
|
|
479
|
+
* `timedOut`) were silently dropped by every viewport evaluation, so
|
|
480
|
+
* `3.14159 to 4 dp` displayed as 3.14 there and as 3.1416 on a single line.
|
|
481
|
+
* A sidecar added later is carried here without this method knowing its
|
|
482
|
+
* name, which closes that class of bug rather than the one instance.
|
|
483
|
+
*
|
|
484
|
+
* Shallow, as the old copy was: a matrix, a chart or a symbolic tree is
|
|
485
|
+
* shared with the original, which is fine because a Value's payload is
|
|
486
|
+
* treated as immutable everywhere outside the arena's own `recycle()`.
|
|
487
|
+
*
|
|
488
|
+
* @returns A new Value equal to this one in every field.
|
|
489
|
+
*/
|
|
490
|
+
clone(): Value;
|
|
472
491
|
isNumber(): this is Value & {
|
|
473
492
|
value: number;
|
|
474
493
|
};
|
|
@@ -469,6 +469,25 @@ declare class Value {
|
|
|
469
469
|
* Called by ValueArena.acquire(), zero allocation, just field assignment.
|
|
470
470
|
*/
|
|
471
471
|
recycle(type: ValueType, value: number | bigint | string | boolean | MatrixData | RangeData | ColourData | SplitData | ChartData | IpCidrData | SymbolicNode, unit?: string): void;
|
|
472
|
+
/**
|
|
473
|
+
* A fresh Value carrying everything this one does: the payload, the unit,
|
|
474
|
+
* the cached number and every sidecar, present or future.
|
|
475
|
+
*
|
|
476
|
+
* The inverse of {@link recycle}, and written as a whole-object copy rather
|
|
477
|
+
* than a list of fields on purpose. `persistentValue()` used to name the
|
|
478
|
+
* sidecars it copied, and the two it did not name (`decimalPlaces`,
|
|
479
|
+
* `timedOut`) were silently dropped by every viewport evaluation, so
|
|
480
|
+
* `3.14159 to 4 dp` displayed as 3.14 there and as 3.1416 on a single line.
|
|
481
|
+
* A sidecar added later is carried here without this method knowing its
|
|
482
|
+
* name, which closes that class of bug rather than the one instance.
|
|
483
|
+
*
|
|
484
|
+
* Shallow, as the old copy was: a matrix, a chart or a symbolic tree is
|
|
485
|
+
* shared with the original, which is fine because a Value's payload is
|
|
486
|
+
* treated as immutable everywhere outside the arena's own `recycle()`.
|
|
487
|
+
*
|
|
488
|
+
* @returns A new Value equal to this one in every field.
|
|
489
|
+
*/
|
|
490
|
+
clone(): Value;
|
|
472
491
|
isNumber(): this is Value & {
|
|
473
492
|
value: number;
|
|
474
493
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as ErrorCategory, S as SourceSpan, E as EngineError } from './EngineError-
|
|
1
|
+
import { c as ErrorCategory, S as SourceSpan, E as EngineError } from './EngineError-Bm4OYmw8.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Structured errors for the off-main-thread worker harness, and the pair of
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as ErrorCategory, S as SourceSpan, E as EngineError } from './EngineError-
|
|
1
|
+
import { c as ErrorCategory, S as SourceSpan, E as EngineError } from './EngineError-Bm4OYmw8.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Structured errors for the off-main-thread worker harness, and the pair of
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var chunkY7O4D3BJ_cjs=require('./chunk-Y7O4D3BJ.cjs'),
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
'use strict';var chunkY7O4D3BJ_cjs=require('./chunk-Y7O4D3BJ.cjs'),chunk72J5V7SN_cjs=require('./chunk-72J5V7SN.cjs'),chunk6SYU4MH7_cjs=require('./chunk-6SYU4MH7.cjs');var h=(s=>(s.Main="main",s.Inline="inline",s.String="string",s))(h||{});var n=class{constructor(e="en",t){this.currentState="main";this.hasPeeked=false;this.tokens=[];this.tokenIdx=0;this.expressionLexer=new chunk72J5V7SN_cjs.b(e);}reset(e,t){let s=t??"main";if(this.currentState=s,this.hasPeeked=false,this.peekedToken=void 0,s==="main"){if(this.expressionLexer.classifyLine(e).skip){this.tokens=[],this.tokenIdx=0;return}this.expressionLexer.reset(e),this.tokens=this.expressionLexer.tokenizeAll(),this.tokenIdx=0;}else this.expressionLexer.reset(e),this.tokens=this.expressionLexer.tokenizeAll(),this.tokenIdx=0;}classifyLine(e){return this.expressionLexer.classifyLine(e)}findInlineSolves(e){return this.expressionLexer.findInlineSolves(e)}getKeywords(){return this.expressionLexer.getKeywords()}next(){if(this.hasPeeked)return this.hasPeeked=false,this.peekedToken;if(this.tokenIdx<this.tokens.length)return this.tokens[this.tokenIdx++]}peek(){return this.hasPeeked?this.peekedToken:(this.peekedToken=this.next(),this.hasPeeked=true,this.peekedToken)}[Symbol.iterator](){return this.tokens[Symbol.iterator]()}registerVocabulary(e){this.expressionLexer.registerVocabulary(e);}unregisterVocabulary(e){this.expressionLexer.unregisterVocabulary(e);}resetExpression(e){this.currentState="main",this.hasPeeked=false,this.peekedToken=void 0,this.expressionLexer.reset(e),this.tokens=this.expressionLexer.tokenizeAll(),this.tokenIdx=0;}scanDocument(e){return this.expressionLexer.scanDocument(e)}getState(){return this.currentState}setState(e){this.currentState=e;}getHighlightTokens(e){let t=this.expressionLexer.classifyLine(e);return t.skip&&e.startsWith("> ")?this.collectHighlightTokens(e.slice(2)):t.skip?[]:this.collectHighlightTokens(e)}getHighlightTokenObjects(e){let t=this.expressionLexer.classifyLine(e);return t.skip&&e.startsWith("> ")?this.collectTokenObjects(e.slice(2)):t.skip?[]:this.collectTokenObjects(e)}collectTokenObjects(e){this.currentState="main",this.hasPeeked=false,this.peekedToken=void 0,this.expressionLexer.reset(e);let t=[];try{this.expressionLexer.tokenizeInto(t);}catch(i){if(!(i instanceof chunk6SYU4MH7_cjs.b))throw i}let s=[];for(let i of t)i.type==="WS"||i.type==="NEWLINE"||i.type.startsWith("MD_")||i.type==="INLINE_SOLVE_START"||i.type==="BACKTICK_CLOSE"||s.push(i);return this.tokens=s,this.tokenIdx=0,s}collectHighlightTokens(e){return this.collectTokenObjects(e).map(t=>({type:t.type,value:t.value,offset:t.offset,col:t.col,length:t.text.length,category:chunkY7O4D3BJ_cjs.d(t.type)}))}},d=new n("en",void 0);exports.a=h;exports.b=n;exports.c=d;//# sourceMappingURL=chunk-3MG7VIPL.cjs.map
|
|
2
|
+
//# sourceMappingURL=chunk-3MG7VIPL.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lexer/LexerState.ts","../src/lexer/Lexer.ts"],"names":["LexerState","Lexer","localeCode","_tokenLookup","ExpressionLexer","input","state","newState","lineText","plugin","text","classification","raw","thrown","EngineError","result","token","getTokenCategory","sharedLexer"],"mappings":"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","file":"chunk-AGCNMEP2.cjs","sourcesContent":["/**\n * Lexer state machine modes.\n * - Main: document-level scanning with markdown classification\n * - Inline: expression embedded in markdown inline solve (`s\\`...\\``)\n * - String: inside a double-quoted string literal\n */\nexport enum LexerState {\n\tMain = \"main\",\n\tInline = \"inline\",\n\tString = \"string\",\n}\n","import { ExpressionLexer, LineClassification, LexerVocabulary, type ScanLineResult } from \"./ExpressionLexer\";\nimport { Token } from \"@solve-js/lexer/Token\";\nimport { EngineError } from \"@solve-js/errors/UnifiedErrorFramework\";\nimport { LexerState } from \"@solve-js/lexer/LexerState\";\nimport { getTokenCategory } from \"@solve-js/language/TokenCategoryMap\";\nimport type { TokenCategory } from \"@solve-js/language/TokenCategory\";\nimport type { TokenLookup } from \"@solve-js/lexer/TokenClassRegistry\";\n\n/**\n * Public tokenizer wrapper around {@link ExpressionLexer}.\n *\n * `ExpressionLexer` does the actual character-by-character scanning;\n * `Lexer` adds a materialized-token-array streaming interface\n * (`next()`/`peek()`) plus line-classification state (`reset()`) so\n * callers can iterate a line's tokens without re-scanning on each peek.\n *\n * Each `ExpressionEngine` instance owns its own `Lexer`, and packages\n * extend it via {@link registerVocabulary} (keywords, operators, units)\n * see `IEnginePackage.lexerVocabulary`.\n */\nexport class Lexer {\n /** Expression-mode lexer (Phase A: V8-optimized, replaces moo) */\n private expressionLexer: ExpressionLexer;\n private currentState: LexerState = LexerState.Main;\n private peekedToken: Token | undefined;\n private hasPeeked = false;\n\n // Materialized token array from the last reset() call, used for\n // next()/peek() streaming access.\n private tokens: Token[] = [];\n private tokenIdx: number = 0;\n\n /**\n * @param localeCode - Locale code (e.g., \"en\", \"de\"). Defaults to \"en\".\n * @param _tokenLookup - Ignored. The lexer never read the lookup it was\n * handed; the parameter stays so existing callers compile.\n * @deprecated Removed in 3.0.\n */\n constructor(localeCode = \"en\", _tokenLookup?: TokenLookup) {\n this.expressionLexer = new ExpressionLexer(localeCode);\n }\n\n reset(input: string, state?: LexerState): void {\n const newState = state ?? LexerState.Main;\n this.currentState = newState;\n this.hasPeeked = false;\n this.peekedToken = undefined;\n\n // Phase B: Main state classifies the line with the markdown scanner.\n // Skip lines (headings, fences, HRs, etc.) produce empty token arrays.\n // Expression lines and lines with inline solves are tokenized normally.\n if (newState === LexerState.Main) {\n const classification = this.expressionLexer.classifyLine(input);\n if (classification.skip) {\n this.tokens = [];\n this.tokenIdx = 0;\n return;\n }\n // Expression line or markdown line with inline solves, tokenize.\n this.expressionLexer.reset(input);\n this.tokens = this.expressionLexer.tokenizeAll();\n this.tokenIdx = 0;\n } else {\n // Non-main states (Inline, String), expression tokenization.\n this.expressionLexer.reset(input);\n this.tokens = this.expressionLexer.tokenizeAll();\n this.tokenIdx = 0;\n }\n }\n\n /**\n * Classify a single line of markdown text (Phase B).\n * Delegates to the ExpressionLexer's character-by-character scanner.\n */\n classifyLine(lineText: string): LineClassification {\n return this.expressionLexer.classifyLine(lineText);\n }\n\n /**\n * Find all inline solve markers in a line (Phase B).\n * Delegates to the ExpressionLexer's character-by-character scanner.\n */\n findInlineSolves(lineText: string) {\n return this.expressionLexer.findInlineSolves(lineText);\n }\n\n /**\n * Every keyword this lexer currently recognizes (locale + plugin-contributed),\n * mapped to the token type it lexes to. Delegates to the ExpressionLexer.\n */\n getKeywords(): Record<string, string> {\n return this.expressionLexer.getKeywords();\n }\n\n next(): Token | undefined {\n if (this.hasPeeked) {\n this.hasPeeked = false;\n return this.peekedToken;\n }\n // Materialized token array (ExpressionLexer path).\n if (this.tokenIdx < this.tokens.length) {\n return this.tokens[this.tokenIdx++];\n }\n return undefined;\n }\n\n peek(): Token | undefined {\n if (this.hasPeeked) return this.peekedToken;\n this.peekedToken = this.next();\n this.hasPeeked = true;\n return this.peekedToken;\n }\n\n [Symbol.iterator](): Iterator<Token> {\n return this.tokens[Symbol.iterator]();\n }\n\n /**\n * Register a plugin to extend the lexer with custom tokens.\n * Delegates to the underlying ExpressionLexer.\n *\n * @see LexerVocabulary for the supported extension points.\n */\n registerVocabulary(plugin: LexerVocabulary): void {\n this.expressionLexer.registerVocabulary(plugin);\n }\n\n /**\n * Unregister a plugin, removing its custom tokens from the lexer.\n * Delegates to the underlying ExpressionLexer.\n */\n unregisterVocabulary(plugin: LexerVocabulary): void {\n this.expressionLexer.unregisterVocabulary(plugin);\n }\n\n /**\n * Reset the lexer for expression-only text, skips the classifyLine()\n * overhead in reset() for callers that already know the input is an\n * evaluable expression (e.g., after isEmptyLine() confirmed non-skip).\n */\n resetExpression(input: string): void {\n this.currentState = LexerState.Main;\n this.hasPeeked = false;\n this.peekedToken = undefined;\n this.expressionLexer.reset(input);\n this.tokens = this.expressionLexer.tokenizeAll();\n this.tokenIdx = 0;\n }\n\n /**\n * Scan a full document in one pass, classifying each line and\n * tokenizing non-skipped lines. Delegates to ExpressionLexer.\n *\n * @returns ScanLineResult[], one per line, with classification + tokens.\n */\n scanDocument(text: string): ScanLineResult[] {\n return this.expressionLexer.scanDocument(text);\n }\n\n getState(): LexerState {\n return this.currentState;\n }\n\n setState(state: LexerState): void {\n this.currentState = state;\n }\n\n getHighlightTokens(lineText: string): {type: string; value: string; offset: number; col: number; length: number; category: TokenCategory | undefined}[] {\n const classification = this.expressionLexer.classifyLine(lineText);\n\n // For blockquote lines, strip the \"> \" prefix and tokenize the expression content.\n // This lets expressions inside blockquotes (e.g., \"> 1 + 2\") get syntax highlighted\n // while pure structural lines (headings, code fences) remain unhighlighted.\n if (classification.skip && lineText.startsWith(\"> \")) {\n return this.collectHighlightTokens(lineText.slice(2));\n }\n\n if (classification.skip) {\n return [];\n }\n\n return this.collectHighlightTokens(lineText);\n }\n\n /**\n * The same tokens {@link getHighlightTokens} reduces, before reduction.\n *\n * Exists because normalization operates on tokens, not on the flattened\n * shape, and a consumer that wants phrase-fused highlighting has to run the\n * normalizer between the two. See `LanguageService.getSemanticTokens`.\n *\n * @param lineText - One line of source.\n * @returns Every token on the line that is worth painting, unreduced.\n */\n getHighlightTokenObjects(lineText: string): Token[] {\n const classification = this.expressionLexer.classifyLine(lineText);\n if (classification.skip && lineText.startsWith(\"> \")) {\n return this.collectTokenObjects(lineText.slice(2));\n }\n if (classification.skip) return [];\n return this.collectTokenObjects(lineText);\n }\n\n private collectTokenObjects(lineText: string): Token[] {\n // Scanned into an array this method owns rather than through\n // resetExpression(), which has nothing to hand back when the line faults\n // part way. Highlighting is painted while the line is still being typed,\n // and an unterminated string is what a line looks like between the\n // opening quote and the closing one: the tokens read before the fault are\n // the right thing to paint, and letting the throw escape blanked the line.\n this.currentState = LexerState.Main;\n this.hasPeeked = false;\n this.peekedToken = undefined;\n this.expressionLexer.reset(lineText);\n const raw: Token[] = [];\n try {\n this.expressionLexer.tokenizeInto(raw);\n } catch (thrown) {\n if (!(thrown instanceof EngineError)) throw thrown;\n }\n const result: Token[] = [];\n for (const token of raw) {\n if (token.type === \"WS\" || token.type === \"NEWLINE\") continue;\n if (token.type.startsWith(\"MD_\")) continue;\n if (token.type === \"INLINE_SOLVE_START\" || token.type === \"BACKTICK_CLOSE\") continue;\n result.push(token);\n }\n this.tokens = result;\n this.tokenIdx = 0;\n return result;\n }\n\n private collectHighlightTokens(lineText: string): {type: string; value: string; offset: number; col: number; length: number; category: TokenCategory | undefined}[] {\n return this.collectTokenObjects(lineText).map(token => ({\n type: token.type,\n value: token.value,\n offset: token.offset,\n col: token.col,\n // `text`, not `value`: this is a span into the source, and the two\n // differ for a string literal, whose value is the payload while its\n // text still carries the quote characters the reader typed.\n length: token.text.length,\n category: getTokenCategory(token.type),\n }));\n }\n}\n\n/**\n * A lexer for operations that do not depend on registered vocabulary.\n *\n * Line classification and inline-solve detection read characters looking for\n * headings, comment markers, fences and backtick spans, and never consult the\n * keyword, unit or operator tables. Every lexer therefore returns the same\n * answer, so the callers that have no engine to ask can use this one. Checked\n * by `__tests__/lexer/LineClassificationIsVocabularyIndependent.spec.ts`.\n *\n * Do not tokenize with this. An engine's own lexer carries the vocabulary its\n * packages registered; this one carries none.\n */\nexport const sharedLexer = new Lexer(\"en\", undefined);"]}
|
|
1
|
+
{"version":3,"sources":["../src/lexer/LexerState.ts","../src/lexer/Lexer.ts"],"names":["LexerState","Lexer","localeCode","_tokenLookup","ExpressionLexer","input","state","newState","lineText","plugin","text","classification","raw","thrown","EngineError","result","token","getTokenCategory","sharedLexer"],"mappings":"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","file":"chunk-3MG7VIPL.cjs","sourcesContent":["/**\n * Lexer state machine modes.\n * - Main: document-level scanning with markdown classification\n * - Inline: expression embedded in markdown inline solve (`s\\`...\\``)\n * - String: inside a double-quoted string literal\n */\nexport enum LexerState {\n\tMain = \"main\",\n\tInline = \"inline\",\n\tString = \"string\",\n}\n","import { ExpressionLexer, LineClassification, LexerVocabulary, type ScanLineResult } from \"./ExpressionLexer\";\nimport { Token } from \"@solve-js/lexer/Token\";\nimport { EngineError } from \"@solve-js/errors/UnifiedErrorFramework\";\nimport { LexerState } from \"@solve-js/lexer/LexerState\";\nimport { getTokenCategory } from \"@solve-js/language/TokenCategoryMap\";\nimport type { TokenCategory } from \"@solve-js/language/TokenCategory\";\nimport type { TokenLookup } from \"@solve-js/lexer/TokenClassRegistry\";\n\n/**\n * Public tokenizer wrapper around {@link ExpressionLexer}.\n *\n * `ExpressionLexer` does the actual character-by-character scanning;\n * `Lexer` adds a materialized-token-array streaming interface\n * (`next()`/`peek()`) plus line-classification state (`reset()`) so\n * callers can iterate a line's tokens without re-scanning on each peek.\n *\n * Each `ExpressionEngine` instance owns its own `Lexer`, and packages\n * extend it via {@link registerVocabulary} (keywords, operators, units)\n * see `IEnginePackage.lexerVocabulary`.\n */\nexport class Lexer {\n /** Expression-mode lexer (Phase A: V8-optimized, replaces moo) */\n private expressionLexer: ExpressionLexer;\n private currentState: LexerState = LexerState.Main;\n private peekedToken: Token | undefined;\n private hasPeeked = false;\n\n // Materialized token array from the last reset() call, used for\n // next()/peek() streaming access.\n private tokens: Token[] = [];\n private tokenIdx: number = 0;\n\n /**\n * @param localeCode - Locale code (e.g., \"en\", \"de\"). Defaults to \"en\".\n * @param _tokenLookup - Ignored. The lexer never read the lookup it was\n * handed; the parameter stays so existing callers compile.\n * @deprecated Removed in 3.0.\n */\n constructor(localeCode = \"en\", _tokenLookup?: TokenLookup) {\n this.expressionLexer = new ExpressionLexer(localeCode);\n }\n\n reset(input: string, state?: LexerState): void {\n const newState = state ?? LexerState.Main;\n this.currentState = newState;\n this.hasPeeked = false;\n this.peekedToken = undefined;\n\n // Phase B: Main state classifies the line with the markdown scanner.\n // Skip lines (headings, fences, HRs, etc.) produce empty token arrays.\n // Expression lines and lines with inline solves are tokenized normally.\n if (newState === LexerState.Main) {\n const classification = this.expressionLexer.classifyLine(input);\n if (classification.skip) {\n this.tokens = [];\n this.tokenIdx = 0;\n return;\n }\n // Expression line or markdown line with inline solves, tokenize.\n this.expressionLexer.reset(input);\n this.tokens = this.expressionLexer.tokenizeAll();\n this.tokenIdx = 0;\n } else {\n // Non-main states (Inline, String), expression tokenization.\n this.expressionLexer.reset(input);\n this.tokens = this.expressionLexer.tokenizeAll();\n this.tokenIdx = 0;\n }\n }\n\n /**\n * Classify a single line of markdown text (Phase B).\n * Delegates to the ExpressionLexer's character-by-character scanner.\n */\n classifyLine(lineText: string): LineClassification {\n return this.expressionLexer.classifyLine(lineText);\n }\n\n /**\n * Find all inline solve markers in a line (Phase B).\n * Delegates to the ExpressionLexer's character-by-character scanner.\n */\n findInlineSolves(lineText: string) {\n return this.expressionLexer.findInlineSolves(lineText);\n }\n\n /**\n * Every keyword this lexer currently recognizes (locale + plugin-contributed),\n * mapped to the token type it lexes to. Delegates to the ExpressionLexer.\n */\n getKeywords(): Record<string, string> {\n return this.expressionLexer.getKeywords();\n }\n\n next(): Token | undefined {\n if (this.hasPeeked) {\n this.hasPeeked = false;\n return this.peekedToken;\n }\n // Materialized token array (ExpressionLexer path).\n if (this.tokenIdx < this.tokens.length) {\n return this.tokens[this.tokenIdx++];\n }\n return undefined;\n }\n\n peek(): Token | undefined {\n if (this.hasPeeked) return this.peekedToken;\n this.peekedToken = this.next();\n this.hasPeeked = true;\n return this.peekedToken;\n }\n\n [Symbol.iterator](): Iterator<Token> {\n return this.tokens[Symbol.iterator]();\n }\n\n /**\n * Register a plugin to extend the lexer with custom tokens.\n * Delegates to the underlying ExpressionLexer.\n *\n * @see LexerVocabulary for the supported extension points.\n */\n registerVocabulary(plugin: LexerVocabulary): void {\n this.expressionLexer.registerVocabulary(plugin);\n }\n\n /**\n * Unregister a plugin, removing its custom tokens from the lexer.\n * Delegates to the underlying ExpressionLexer.\n */\n unregisterVocabulary(plugin: LexerVocabulary): void {\n this.expressionLexer.unregisterVocabulary(plugin);\n }\n\n /**\n * Reset the lexer for expression-only text, skips the classifyLine()\n * overhead in reset() for callers that already know the input is an\n * evaluable expression (e.g., after isEmptyLine() confirmed non-skip).\n */\n resetExpression(input: string): void {\n this.currentState = LexerState.Main;\n this.hasPeeked = false;\n this.peekedToken = undefined;\n this.expressionLexer.reset(input);\n this.tokens = this.expressionLexer.tokenizeAll();\n this.tokenIdx = 0;\n }\n\n /**\n * Scan a full document in one pass, classifying each line and\n * tokenizing non-skipped lines. Delegates to ExpressionLexer.\n *\n * @returns ScanLineResult[], one per line, with classification + tokens.\n */\n scanDocument(text: string): ScanLineResult[] {\n return this.expressionLexer.scanDocument(text);\n }\n\n getState(): LexerState {\n return this.currentState;\n }\n\n setState(state: LexerState): void {\n this.currentState = state;\n }\n\n getHighlightTokens(lineText: string): {type: string; value: string; offset: number; col: number; length: number; category: TokenCategory | undefined}[] {\n const classification = this.expressionLexer.classifyLine(lineText);\n\n // For blockquote lines, strip the \"> \" prefix and tokenize the expression content.\n // This lets expressions inside blockquotes (e.g., \"> 1 + 2\") get syntax highlighted\n // while pure structural lines (headings, code fences) remain unhighlighted.\n if (classification.skip && lineText.startsWith(\"> \")) {\n return this.collectHighlightTokens(lineText.slice(2));\n }\n\n if (classification.skip) {\n return [];\n }\n\n return this.collectHighlightTokens(lineText);\n }\n\n /**\n * The same tokens {@link getHighlightTokens} reduces, before reduction.\n *\n * Exists because normalization operates on tokens, not on the flattened\n * shape, and a consumer that wants phrase-fused highlighting has to run the\n * normalizer between the two. See `LanguageService.getSemanticTokens`.\n *\n * @param lineText - One line of source.\n * @returns Every token on the line that is worth painting, unreduced.\n */\n getHighlightTokenObjects(lineText: string): Token[] {\n const classification = this.expressionLexer.classifyLine(lineText);\n if (classification.skip && lineText.startsWith(\"> \")) {\n return this.collectTokenObjects(lineText.slice(2));\n }\n if (classification.skip) return [];\n return this.collectTokenObjects(lineText);\n }\n\n private collectTokenObjects(lineText: string): Token[] {\n // Scanned into an array this method owns rather than through\n // resetExpression(), which has nothing to hand back when the line faults\n // part way. Highlighting is painted while the line is still being typed,\n // and an unterminated string is what a line looks like between the\n // opening quote and the closing one: the tokens read before the fault are\n // the right thing to paint, and letting the throw escape blanked the line.\n this.currentState = LexerState.Main;\n this.hasPeeked = false;\n this.peekedToken = undefined;\n this.expressionLexer.reset(lineText);\n const raw: Token[] = [];\n try {\n this.expressionLexer.tokenizeInto(raw);\n } catch (thrown) {\n if (!(thrown instanceof EngineError)) throw thrown;\n }\n const result: Token[] = [];\n for (const token of raw) {\n if (token.type === \"WS\" || token.type === \"NEWLINE\") continue;\n if (token.type.startsWith(\"MD_\")) continue;\n if (token.type === \"INLINE_SOLVE_START\" || token.type === \"BACKTICK_CLOSE\") continue;\n result.push(token);\n }\n this.tokens = result;\n this.tokenIdx = 0;\n return result;\n }\n\n private collectHighlightTokens(lineText: string): {type: string; value: string; offset: number; col: number; length: number; category: TokenCategory | undefined}[] {\n return this.collectTokenObjects(lineText).map(token => ({\n type: token.type,\n value: token.value,\n offset: token.offset,\n col: token.col,\n // `text`, not `value`: this is a span into the source, and the two\n // differ for a string literal, whose value is the payload while its\n // text still carries the quote characters the reader typed.\n length: token.text.length,\n category: getTokenCategory(token.type),\n }));\n }\n}\n\n/**\n * A lexer for operations that do not depend on registered vocabulary.\n *\n * Line classification and inline-solve detection read characters looking for\n * headings, comment markers, fences and backtick spans, and never consult the\n * keyword, unit or operator tables. Every lexer therefore returns the same\n * answer, so the callers that have no engine to ask can use this one. Checked\n * by `__tests__/lexer/LineClassificationIsVocabularyIndependent.spec.ts`.\n *\n * Do not tokenize with this. An engine's own lexer carries the vocabulary its\n * packages registered; this one carries none.\n */\nexport const sharedLexer = new Lexer(\"en\", undefined);"]}
|