solve-engine 1.0.0-beta.0 → 1.0.0-beta.1
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/BytecodeBuilder-3egMyuDi.d.cts +274 -0
- package/dist/BytecodeBuilder-3egMyuDi.d.ts +274 -0
- package/dist/Configuration-fVpd-HC-.d.cts +228 -0
- package/dist/Configuration-fVpd-HC-.d.ts +228 -0
- package/dist/EngineError-DvPSnhZi.d.cts +304 -0
- package/dist/EngineError-DvPSnhZi.d.ts +304 -0
- package/dist/Lexer-BJdhlnej.d.cts +531 -0
- package/dist/Lexer-D9l4Yrk2.d.ts +531 -0
- package/dist/NormalizerRule-BrVoVjmP.d.cts +163 -0
- package/dist/NormalizerRule-CEjf1FyD.d.ts +163 -0
- package/dist/PackageRegistry-D-Tv_7ca.d.cts +2572 -0
- package/dist/PackageRegistry-DaH4aIKP.d.ts +2572 -0
- package/dist/Parselet-CK8cQu2a.d.cts +299 -0
- package/dist/Parselet-ConOIdRO.d.ts +299 -0
- package/dist/ScopeManager-B5k0nk05.d.ts +559 -0
- package/dist/ScopeManager-CKfQtl7l.d.cts +559 -0
- package/dist/Token-0jpvUdPY.d.cts +245 -0
- package/dist/Token-0jpvUdPY.d.ts +245 -0
- package/dist/VMCheckpoints-BmDwIXgK.d.ts +171 -0
- package/dist/VMCheckpoints-CqFuLwrT.d.cts +171 -0
- package/dist/Value-KtAQNHur.d.cts +295 -0
- package/dist/Value-KtAQNHur.d.ts +295 -0
- package/dist/chunk-2RWAXT6O.js +3 -0
- package/dist/chunk-2RWAXT6O.js.map +1 -0
- package/dist/chunk-34RRD7PC.js +1492 -0
- package/dist/chunk-34RRD7PC.js.map +1 -0
- package/dist/chunk-3PPFLFH4.js +5097 -0
- package/dist/chunk-3PPFLFH4.js.map +1 -0
- package/dist/chunk-3VGDNEE3.js +84 -0
- package/dist/chunk-3VGDNEE3.js.map +1 -0
- package/dist/chunk-3YNVWKR2.cjs +370 -0
- package/dist/chunk-3YNVWKR2.cjs.map +1 -0
- package/dist/chunk-47LRVGOT.cjs +316 -0
- package/dist/chunk-47LRVGOT.cjs.map +1 -0
- package/dist/chunk-4MG4XKO2.js +1644 -0
- package/dist/chunk-4MG4XKO2.js.map +1 -0
- package/dist/chunk-4QADQTWS.js +2392 -0
- package/dist/chunk-4QADQTWS.js.map +1 -0
- package/dist/chunk-53B6KDDJ.cjs +1651 -0
- package/dist/chunk-53B6KDDJ.cjs.map +1 -0
- package/dist/chunk-5X2PTP6F.cjs +104 -0
- package/dist/chunk-5X2PTP6F.cjs.map +1 -0
- package/dist/chunk-5YEMOYSE.js +264 -0
- package/dist/chunk-5YEMOYSE.js.map +1 -0
- package/dist/chunk-64W6GLLZ.js +481 -0
- package/dist/chunk-64W6GLLZ.js.map +1 -0
- package/dist/chunk-6BKTCEUP.cjs +233 -0
- package/dist/chunk-6BKTCEUP.cjs.map +1 -0
- package/dist/chunk-6NTVRDQV.cjs +1642 -0
- package/dist/chunk-6NTVRDQV.cjs.map +1 -0
- package/dist/chunk-6RDSQURE.js +290 -0
- package/dist/chunk-6RDSQURE.js.map +1 -0
- package/dist/chunk-75JP4BZX.js +93 -0
- package/dist/chunk-75JP4BZX.js.map +1 -0
- package/dist/chunk-BVAR5J2F.js +257 -0
- package/dist/chunk-BVAR5J2F.js.map +1 -0
- package/dist/chunk-C4XZV6E7.cjs +269 -0
- package/dist/chunk-C4XZV6E7.cjs.map +1 -0
- package/dist/chunk-CCJPSHGI.cjs +40 -0
- package/dist/chunk-CCJPSHGI.cjs.map +1 -0
- package/dist/chunk-CLL7RUQV.cjs +316 -0
- package/dist/chunk-CLL7RUQV.cjs.map +1 -0
- package/dist/chunk-DM3LMRBC.js +329 -0
- package/dist/chunk-DM3LMRBC.js.map +1 -0
- package/dist/chunk-DUEZFTK2.js +38 -0
- package/dist/chunk-DUEZFTK2.js.map +1 -0
- package/dist/chunk-EBSPLUW4.cjs +489 -0
- package/dist/chunk-EBSPLUW4.cjs.map +1 -0
- package/dist/chunk-EHAHVROS.cjs +261 -0
- package/dist/chunk-EHAHVROS.cjs.map +1 -0
- package/dist/chunk-EPOXXJBK.js +96 -0
- package/dist/chunk-EPOXXJBK.js.map +1 -0
- package/dist/chunk-FEAIOR7N.cjs +91 -0
- package/dist/chunk-FEAIOR7N.cjs.map +1 -0
- package/dist/chunk-G535KJEG.js +312 -0
- package/dist/chunk-G535KJEG.js.map +1 -0
- package/dist/chunk-GCM5JHMX.js +88 -0
- package/dist/chunk-GCM5JHMX.js.map +1 -0
- package/dist/chunk-GOLDJNMZ.js +368 -0
- package/dist/chunk-GOLDJNMZ.js.map +1 -0
- package/dist/chunk-GW32KPCU.cjs +360 -0
- package/dist/chunk-GW32KPCU.cjs.map +1 -0
- package/dist/chunk-HO2CDZRC.js +5508 -0
- package/dist/chunk-HO2CDZRC.js.map +1 -0
- package/dist/chunk-HTXVVJRA.cjs +1549 -0
- package/dist/chunk-HTXVVJRA.cjs.map +1 -0
- package/dist/chunk-HWSZJQCI.js +311 -0
- package/dist/chunk-HWSZJQCI.js.map +1 -0
- package/dist/chunk-IF532O7C.js +101 -0
- package/dist/chunk-IF532O7C.js.map +1 -0
- package/dist/chunk-J73SJHR3.cjs +2415 -0
- package/dist/chunk-J73SJHR3.cjs.map +1 -0
- package/dist/chunk-KVILKGMS.js +228 -0
- package/dist/chunk-KVILKGMS.js.map +1 -0
- package/dist/chunk-LIPPNDBE.js +258 -0
- package/dist/chunk-LIPPNDBE.js.map +1 -0
- package/dist/chunk-M4N5GA5Z.cjs +309 -0
- package/dist/chunk-M4N5GA5Z.cjs.map +1 -0
- package/dist/chunk-MZOVP3WI.cjs +96 -0
- package/dist/chunk-MZOVP3WI.cjs.map +1 -0
- package/dist/chunk-N5YFR4UP.cjs +10 -0
- package/dist/chunk-N5YFR4UP.cjs.map +1 -0
- package/dist/chunk-NGBBNL4K.cjs +4 -0
- package/dist/chunk-NGBBNL4K.cjs.map +1 -0
- package/dist/chunk-NH2O2AUR.js +146 -0
- package/dist/chunk-NH2O2AUR.js.map +1 -0
- package/dist/chunk-NLNDMWZC.js +31 -0
- package/dist/chunk-NLNDMWZC.js.map +1 -0
- package/dist/chunk-NMCRQP3Z.cjs +778 -0
- package/dist/chunk-NMCRQP3Z.cjs.map +1 -0
- package/dist/chunk-NMD5VRN4.cjs +1327 -0
- package/dist/chunk-NMD5VRN4.cjs.map +1 -0
- package/dist/chunk-OC6LTXYS.cjs +286 -0
- package/dist/chunk-OC6LTXYS.cjs.map +1 -0
- package/dist/chunk-OT6OJY7C.cjs +114 -0
- package/dist/chunk-OT6OJY7C.cjs.map +1 -0
- package/dist/chunk-PEWZMGH7.cjs +5522 -0
- package/dist/chunk-PEWZMGH7.cjs.map +1 -0
- package/dist/chunk-PFSDGGYL.js +8 -0
- package/dist/chunk-PFSDGGYL.js.map +1 -0
- package/dist/chunk-QNJ4ACRT.cjs +155 -0
- package/dist/chunk-QNJ4ACRT.cjs.map +1 -0
- package/dist/chunk-QWY3VEZN.js +1637 -0
- package/dist/chunk-QWY3VEZN.js.map +1 -0
- package/dist/chunk-RFYD5TJE.js +111 -0
- package/dist/chunk-RFYD5TJE.js.map +1 -0
- package/dist/chunk-RIN643A3.js +354 -0
- package/dist/chunk-RIN643A3.js.map +1 -0
- package/dist/chunk-RZCWSXTA.cjs +5122 -0
- package/dist/chunk-RZCWSXTA.cjs.map +1 -0
- package/dist/chunk-SDGRK7EP.js +774 -0
- package/dist/chunk-SDGRK7EP.js.map +1 -0
- package/dist/chunk-VEKIWQ3F.cjs +39 -0
- package/dist/chunk-VEKIWQ3F.cjs.map +1 -0
- package/dist/chunk-W44QGY5J.cjs +172 -0
- package/dist/chunk-W44QGY5J.cjs.map +1 -0
- package/dist/chunk-WQTTOGXC.cjs +99 -0
- package/dist/chunk-WQTTOGXC.cjs.map +1 -0
- package/dist/chunk-X6K3HUOY.cjs +86 -0
- package/dist/chunk-X6K3HUOY.cjs.map +1 -0
- package/dist/chunk-XJCMXB2E.cjs +333 -0
- package/dist/chunk-XJCMXB2E.cjs.map +1 -0
- package/dist/chunk-XVWCOTR6.js +1324 -0
- package/dist/chunk-XVWCOTR6.js.map +1 -0
- package/dist/chunk-Z2XP767T.cjs +35 -0
- package/dist/chunk-Z2XP767T.cjs.map +1 -0
- package/dist/chunk-Z4X2RWOF.js +37 -0
- package/dist/chunk-Z4X2RWOF.js.map +1 -0
- package/dist/chunk-ZP3UY6ZX.js +167 -0
- package/dist/chunk-ZP3UY6ZX.js.map +1 -0
- package/dist/constants.cjs +21 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.d.cts +12 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -0
- package/dist/engine.cjs +78 -0
- package/dist/engine.cjs.map +1 -0
- package/dist/engine.d.cts +587 -0
- package/dist/engine.d.ts +587 -0
- package/dist/engine.js +33 -0
- package/dist/engine.js.map +1 -0
- package/dist/errors.cjs +80 -0
- package/dist/errors.cjs.map +1 -0
- package/dist/errors.d.cts +95 -0
- package/dist/errors.d.ts +95 -0
- package/dist/errors.js +3 -0
- package/dist/errors.js.map +1 -0
- package/dist/format.cjs +170 -0
- package/dist/format.cjs.map +1 -0
- package/dist/format.d.cts +51 -0
- package/dist/format.d.ts +51 -0
- package/dist/format.js +167 -0
- package/dist/format.js.map +1 -0
- package/dist/index.cjs +96 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +152 -0
- package/dist/index.d.ts +152 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/language.cjs +307 -0
- package/dist/language.cjs.map +1 -0
- package/dist/language.d.cts +110 -0
- package/dist/language.d.ts +110 -0
- package/dist/language.js +286 -0
- package/dist/language.js.map +1 -0
- package/dist/lexer.cjs +63 -0
- package/dist/lexer.cjs.map +1 -0
- package/dist/lexer.d.cts +56 -0
- package/dist/lexer.d.ts +56 -0
- package/dist/lexer.js +10 -0
- package/dist/lexer.js.map +1 -0
- package/dist/normalizer.cjs +39 -0
- package/dist/normalizer.cjs.map +1 -0
- package/dist/normalizer.d.cts +364 -0
- package/dist/normalizer.d.ts +364 -0
- package/dist/normalizer.js +10 -0
- package/dist/normalizer.js.map +1 -0
- package/dist/packages.cjs +120 -0
- package/dist/packages.cjs.map +1 -0
- package/dist/packages.d.cts +691 -0
- package/dist/packages.d.ts +691 -0
- package/dist/packages.js +23 -0
- package/dist/packages.js.map +1 -0
- package/dist/parser.cjs +54 -0
- package/dist/parser.cjs.map +1 -0
- package/dist/parser.d.cts +46 -0
- package/dist/parser.d.ts +46 -0
- package/dist/parser.js +9 -0
- package/dist/parser.js.map +1 -0
- package/dist/pipeline-CrsRPmsv.d.ts +285 -0
- package/dist/pipeline-DPUQt7yL.d.cts +285 -0
- package/dist/resolvers.cjs +12 -0
- package/dist/resolvers.cjs.map +1 -0
- package/dist/resolvers.d.cts +111 -0
- package/dist/resolvers.d.ts +111 -0
- package/dist/resolvers.js +3 -0
- package/dist/resolvers.js.map +1 -0
- package/dist/services.cjs +20 -0
- package/dist/services.cjs.map +1 -0
- package/dist/services.d.cts +30 -0
- package/dist/services.d.ts +30 -0
- package/dist/services.js +3 -0
- package/dist/services.js.map +1 -0
- package/dist/uom.cjs +55 -0
- package/dist/uom.cjs.map +1 -0
- package/dist/uom.d.cts +224 -0
- package/dist/uom.d.ts +224 -0
- package/dist/uom.js +10 -0
- package/dist/uom.js.map +1 -0
- package/dist/utilities.cjs +31 -0
- package/dist/utilities.cjs.map +1 -0
- package/dist/utilities.d.cts +113 -0
- package/dist/utilities.d.ts +113 -0
- package/dist/utilities.js +6 -0
- package/dist/utilities.js.map +1 -0
- package/dist/variables.cjs +16 -0
- package/dist/variables.cjs.map +1 -0
- package/dist/variables.d.cts +87 -0
- package/dist/variables.d.ts +87 -0
- package/dist/variables.js +3 -0
- package/dist/variables.js.map +1 -0
- package/dist/vm.cjs +283 -0
- package/dist/vm.cjs.map +1 -0
- package/dist/vm.d.cts +68 -0
- package/dist/vm.d.ts +68 -0
- package/dist/vm.js +193 -0
- package/dist/vm.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk53B6KDDJ_cjs = require('./chunk-53B6KDDJ.cjs');
|
|
4
|
+
|
|
5
|
+
// src/lexer/units.ts
|
|
6
|
+
var EXCLUDED_UNIT_SPELLINGS = /* @__PURE__ */ new Map([
|
|
7
|
+
["in", "the IN keyword owns this word (the conversion operator). ConvertParselet and friends special-case the IN token type directly and trust its text as a unit name, so inches still convert"],
|
|
8
|
+
["dec", "already a converter name, as in `255 as dec`"],
|
|
9
|
+
["M", "the millions magnitude suffix, as in `2.5M`. Nautical miles are still spelled `nmi` and `NM`"],
|
|
10
|
+
// Claimed by a normalizer rule rather than by the keyword table, which is why
|
|
11
|
+
// scanning the locale keywords alone does not find it. Admitting `pm`
|
|
12
|
+
// (picometre) broke every clock time in the suite: `4pm` lexed as 4
|
|
13
|
+
// picometres. There is deliberately no entry for `am`: the table's SI
|
|
14
|
+
// prefixes stop at femto, so attometres do not exist and an exclusion would
|
|
15
|
+
// be dead weight. `UnitVocabularyCollisions.spec.ts` asserts that.
|
|
16
|
+
["pm", "the meridiem marker, as in `4pm`. Picometres lose, and `picometre` still works"],
|
|
17
|
+
["are", "the English verb, against a 100-square-metre unit almost nobody writes"],
|
|
18
|
+
["ares", "the English verb in plural, same reasoning as `are` above"],
|
|
19
|
+
["turn", "ordinary English, against a full-rotation angle unit also spelled in gradians"],
|
|
20
|
+
["turns", "ordinary English in plural, same reasoning as `turn` above"],
|
|
21
|
+
["grade", "ordinary English. The angle unit is also spelled `gon` and `grad`"],
|
|
22
|
+
["grades", "ordinary English in plural, same reasoning as `grade` above"],
|
|
23
|
+
["point", "ordinary English. The typographic point is also reachable as `pica`"],
|
|
24
|
+
["points", "ordinary English in plural, same reasoning as `point` above"],
|
|
25
|
+
["moment", "ordinary English, against an obscure medieval time unit of 90 seconds"],
|
|
26
|
+
["moments", "ordinary English in plural, same reasoning as `moment` above"],
|
|
27
|
+
["shake", "ordinary English, against an obscure physics unit of ten nanoseconds"],
|
|
28
|
+
["shakes", "ordinary English in plural, same reasoning as `shake` above"]
|
|
29
|
+
]);
|
|
30
|
+
function isTokenizableSpelling(spelling) {
|
|
31
|
+
return /^[A-Za-z0-9_]+$/.test(spelling);
|
|
32
|
+
}
|
|
33
|
+
var GRANDFATHERED_SINGLE_CHARACTER_UNITS = /* @__PURE__ */ new Set([
|
|
34
|
+
"m",
|
|
35
|
+
"g",
|
|
36
|
+
"t",
|
|
37
|
+
"s",
|
|
38
|
+
"h",
|
|
39
|
+
"d",
|
|
40
|
+
"l",
|
|
41
|
+
"b",
|
|
42
|
+
"B",
|
|
43
|
+
"C",
|
|
44
|
+
"F",
|
|
45
|
+
"K",
|
|
46
|
+
"W"
|
|
47
|
+
]);
|
|
48
|
+
function isAdmissible(spelling) {
|
|
49
|
+
if (!isTokenizableSpelling(spelling)) return false;
|
|
50
|
+
if (EXCLUDED_UNIT_SPELLINGS.has(spelling)) return false;
|
|
51
|
+
if (spelling.length === 1) return GRANDFATHERED_SINGLE_CHARACTER_UNITS.has(spelling);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
var CURRENCY_CODES = [
|
|
55
|
+
"USD",
|
|
56
|
+
"EUR",
|
|
57
|
+
"GBP",
|
|
58
|
+
"JPY",
|
|
59
|
+
"AUD",
|
|
60
|
+
"CAD",
|
|
61
|
+
"CHF",
|
|
62
|
+
"CNY",
|
|
63
|
+
"SEK",
|
|
64
|
+
"NOK",
|
|
65
|
+
"DKK",
|
|
66
|
+
"NZD",
|
|
67
|
+
"KRW",
|
|
68
|
+
"SGD",
|
|
69
|
+
"HKD",
|
|
70
|
+
"TWD",
|
|
71
|
+
"INR",
|
|
72
|
+
"BRL",
|
|
73
|
+
"ZAR",
|
|
74
|
+
"MXN",
|
|
75
|
+
"RUB",
|
|
76
|
+
"TRY",
|
|
77
|
+
"SAR",
|
|
78
|
+
"AED",
|
|
79
|
+
"ILS",
|
|
80
|
+
"PLN",
|
|
81
|
+
"CZK",
|
|
82
|
+
"HUF",
|
|
83
|
+
"THB",
|
|
84
|
+
"IDR",
|
|
85
|
+
"MYR",
|
|
86
|
+
"PHP",
|
|
87
|
+
"CLP",
|
|
88
|
+
"COP",
|
|
89
|
+
"ARS",
|
|
90
|
+
"NGN",
|
|
91
|
+
"EGP",
|
|
92
|
+
"PKR",
|
|
93
|
+
"BDT",
|
|
94
|
+
"VND",
|
|
95
|
+
"KES",
|
|
96
|
+
"XOF",
|
|
97
|
+
"XAF",
|
|
98
|
+
"MAD",
|
|
99
|
+
"QAR",
|
|
100
|
+
"KWD",
|
|
101
|
+
"OMR",
|
|
102
|
+
"BHD",
|
|
103
|
+
"JOD",
|
|
104
|
+
"LKR",
|
|
105
|
+
"MMK",
|
|
106
|
+
"UZS",
|
|
107
|
+
"KZT",
|
|
108
|
+
"RON",
|
|
109
|
+
"BGN",
|
|
110
|
+
"HRK",
|
|
111
|
+
"ISK",
|
|
112
|
+
"UAH",
|
|
113
|
+
"GEL",
|
|
114
|
+
"AZN",
|
|
115
|
+
"BTN",
|
|
116
|
+
"BND",
|
|
117
|
+
"BOB",
|
|
118
|
+
"BWP",
|
|
119
|
+
"BYN",
|
|
120
|
+
"BZD",
|
|
121
|
+
"CDF",
|
|
122
|
+
"CRC",
|
|
123
|
+
"CUP",
|
|
124
|
+
"DOP",
|
|
125
|
+
"DZD",
|
|
126
|
+
"ERN",
|
|
127
|
+
"ETB",
|
|
128
|
+
"FJD",
|
|
129
|
+
"FKP",
|
|
130
|
+
"GMD",
|
|
131
|
+
"GNF",
|
|
132
|
+
"GYD",
|
|
133
|
+
"HNL",
|
|
134
|
+
"HTG",
|
|
135
|
+
"JMD",
|
|
136
|
+
"KGZ",
|
|
137
|
+
"KHR",
|
|
138
|
+
"KMF",
|
|
139
|
+
"KYD",
|
|
140
|
+
"LAK",
|
|
141
|
+
"LBP",
|
|
142
|
+
"LRD",
|
|
143
|
+
"LSL",
|
|
144
|
+
"LYD",
|
|
145
|
+
"MDL",
|
|
146
|
+
"MGA",
|
|
147
|
+
"MKD",
|
|
148
|
+
"MNT",
|
|
149
|
+
"MOP",
|
|
150
|
+
"MRU",
|
|
151
|
+
"MUR",
|
|
152
|
+
"MVR",
|
|
153
|
+
"MWK",
|
|
154
|
+
"MZN",
|
|
155
|
+
"NAD",
|
|
156
|
+
"NIO",
|
|
157
|
+
"NPR",
|
|
158
|
+
"PGK",
|
|
159
|
+
"PYG",
|
|
160
|
+
"RSD",
|
|
161
|
+
"RWF",
|
|
162
|
+
"SBD",
|
|
163
|
+
"SCR",
|
|
164
|
+
"SDG",
|
|
165
|
+
"SHP",
|
|
166
|
+
"SLE",
|
|
167
|
+
"SOS",
|
|
168
|
+
"SRD",
|
|
169
|
+
"SSP",
|
|
170
|
+
"STN",
|
|
171
|
+
"SVC",
|
|
172
|
+
"SYP",
|
|
173
|
+
"SZL",
|
|
174
|
+
"TJS",
|
|
175
|
+
"TMT",
|
|
176
|
+
"TND",
|
|
177
|
+
"TOP",
|
|
178
|
+
"TTD",
|
|
179
|
+
"TZS",
|
|
180
|
+
"UGX",
|
|
181
|
+
"UYU",
|
|
182
|
+
"VEB",
|
|
183
|
+
"VUV",
|
|
184
|
+
"WST",
|
|
185
|
+
"XCD",
|
|
186
|
+
"XDR",
|
|
187
|
+
"XPF",
|
|
188
|
+
"YER",
|
|
189
|
+
"ZMW",
|
|
190
|
+
"ZWL",
|
|
191
|
+
"BTC",
|
|
192
|
+
"ETH",
|
|
193
|
+
"SOL",
|
|
194
|
+
"XRP",
|
|
195
|
+
"ADA",
|
|
196
|
+
"DOGE",
|
|
197
|
+
"DOT"
|
|
198
|
+
];
|
|
199
|
+
var CURRENCY_WORD_FORMS = [
|
|
200
|
+
"dollar",
|
|
201
|
+
"dollars",
|
|
202
|
+
"euro",
|
|
203
|
+
"euros",
|
|
204
|
+
"yen",
|
|
205
|
+
"ruble",
|
|
206
|
+
"rubles",
|
|
207
|
+
"rouble",
|
|
208
|
+
"roubles",
|
|
209
|
+
"won",
|
|
210
|
+
"rupee",
|
|
211
|
+
"rupees",
|
|
212
|
+
"yuan",
|
|
213
|
+
"renminbi",
|
|
214
|
+
"franc",
|
|
215
|
+
"francs",
|
|
216
|
+
"rand",
|
|
217
|
+
"krona",
|
|
218
|
+
"kronor",
|
|
219
|
+
"krone",
|
|
220
|
+
"kroner",
|
|
221
|
+
"real",
|
|
222
|
+
"reais",
|
|
223
|
+
"peso",
|
|
224
|
+
"pesos",
|
|
225
|
+
"shekel",
|
|
226
|
+
"shekels",
|
|
227
|
+
"lira",
|
|
228
|
+
"hryvnia",
|
|
229
|
+
"hryvnias",
|
|
230
|
+
"zloty",
|
|
231
|
+
"zlotys",
|
|
232
|
+
"forint",
|
|
233
|
+
"koruna",
|
|
234
|
+
"dirham",
|
|
235
|
+
"dirhams",
|
|
236
|
+
"riyal",
|
|
237
|
+
"riyals",
|
|
238
|
+
"rial",
|
|
239
|
+
"rials",
|
|
240
|
+
"ringgit",
|
|
241
|
+
"rupiah",
|
|
242
|
+
"baht",
|
|
243
|
+
"dong",
|
|
244
|
+
"naira"
|
|
245
|
+
];
|
|
246
|
+
var WORKDAY_UNITS = ["workday", "workdays"];
|
|
247
|
+
var knownUnits = /* @__PURE__ */ new Set([
|
|
248
|
+
...Object.keys(chunk53B6KDDJ_cjs.UNIT_TABLE).filter(isAdmissible),
|
|
249
|
+
...Object.keys(chunk53B6KDDJ_cjs.EXTENDED_UNITS),
|
|
250
|
+
...WORKDAY_UNITS,
|
|
251
|
+
...CURRENCY_CODES,
|
|
252
|
+
...CURRENCY_WORD_FORMS
|
|
253
|
+
]);
|
|
254
|
+
function isKnownUnit(text) {
|
|
255
|
+
return knownUnits.has(text);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
exports.isKnownUnit = isKnownUnit;
|
|
259
|
+
exports.knownUnits = knownUnits;
|
|
260
|
+
//# sourceMappingURL=chunk-EHAHVROS.cjs.map
|
|
261
|
+
//# sourceMappingURL=chunk-EHAHVROS.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lexer/units.ts"],"names":["UNIT_TABLE","EXTENDED_UNITS"],"mappings":";;;;;AAmCA,IAAM,uBAAA,uBAA2D,GAAA,CAAI;AAAA,EACnE,CAAC,MAAM,yLAAyL,CAAA;AAAA,EAChM,CAAC,OAAO,8CAA8C,CAAA;AAAA,EACtD,CAAC,KAAK,8FAA8F,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpG,CAAC,MAAM,gFAAgF,CAAA;AAAA,EACvF,CAAC,OAAO,wEAAwE,CAAA;AAAA,EAChF,CAAC,QAAQ,2DAA2D,CAAA;AAAA,EACpE,CAAC,QAAQ,+EAA+E,CAAA;AAAA,EACxF,CAAC,SAAS,4DAA4D,CAAA;AAAA,EACtE,CAAC,SAAS,mEAAmE,CAAA;AAAA,EAC7E,CAAC,UAAU,6DAA6D,CAAA;AAAA,EACxE,CAAC,SAAS,qEAAqE,CAAA;AAAA,EAC/E,CAAC,UAAU,6DAA6D,CAAA;AAAA,EACxE,CAAC,UAAU,uEAAuE,CAAA;AAAA,EAClF,CAAC,WAAW,8DAA8D,CAAA;AAAA,EAC1E,CAAC,SAAS,sEAAsE,CAAA;AAAA,EAChF,CAAC,UAAU,6DAA6D;AAC1E,CAAC,CAAA;AAYD,SAAS,sBAAsB,QAAA,EAA2B;AACxD,EAAA,OAAO,iBAAA,CAAkB,KAAK,QAAQ,CAAA;AACxC;AAaA,IAAM,oCAAA,uBAA2C,GAAA,CAAI;AAAA,EACnD,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK;AAC9D,CAAC,CAAA;AAGD,SAAS,aAAa,QAAA,EAA2B;AAC/C,EAAA,IAAI,CAAC,qBAAA,CAAsB,QAAQ,CAAA,EAAG,OAAO,KAAA;AAC7C,EAAA,IAAI,uBAAA,CAAwB,GAAA,CAAI,QAAQ,CAAA,EAAG,OAAO,KAAA;AAClD,EAAA,IAAI,SAAS,MAAA,KAAW,CAAA,EAAG,OAAO,oCAAA,CAAqC,IAAI,QAAQ,CAAA;AACnF,EAAA,OAAO,IAAA;AACT;AAaA,IAAM,cAAA,GAAiB;AAAA,EACrB,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACrB,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACjD,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACjD,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACjD,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACjD,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACjD,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACjD,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACjD,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACjD,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACjD,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KA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","file":"chunk-EHAHVROS.cjs","sourcesContent":["/**\n * The set of unit identifiers the lexer will turn into a UNIT token.\n *\n * DERIVED, not hand-listed. This used to be a hand-maintained list of about a\n * hundred spellings, which existed only because the conversion tables lived\n * inside a third-party package and could not be enumerated. Every spelling had\n * to be transcribed by hand and kept in sync, and this file's own history\n * records the consequences: the IEC binary prefixes (`GiB`, `TiB`) were absent\n * for a long time, and the note explaining the fix said it was \"purely a lexer\n * allowlist gap, not a conversion-logic one\".\n *\n * The tables are now in-repo (see `uom/generated/UnitTable.generated.ts`), so\n * the allowlist is computed from them. Roughly 975 base spellings are\n * recognized instead of about 101, which is why `1 kilojoule to Wh`,\n * `5 arcminutes to deg` and `2 fortnights in days` work at all.\n *\n * Units are case-sensitive to eliminate ambiguity (`C` is Celsius and `c` is a\n * cup, `B` is bytes and `b` is bits). Nothing here normalizes or aliases.\n */\n\nimport { UNIT_TABLE } from \"@solve-js/uom/generated/UnitTable.generated\";\nimport { EXTENDED_UNITS } from \"@solve-js/uom/ExtendedUnits\";\n\n/**\n * Spellings the conversion tables accept but the lexer must not claim, each\n * with its reason. `UnitVocabulary.spec.ts` asserts every one of these still\n * fails to lex, so nobody can quietly delete an entry.\n *\n * Only three spellings in the whole table collide with an existing language\n * keyword (`in`, `min`, `dec`), and `min` is left alone because it has always\n * been a time unit here and works. The rest of this list is about ordinary\n * English: a unit spelling that is also a common word turns prose into\n * arithmetic. `shouldEvaluateLine`'s prose gate is a backstop, not a licence\n * to claim every word in the dictionary.\n */\nconst EXCLUDED_UNIT_SPELLINGS: ReadonlyMap<string, string> = new Map([\n [\"in\", \"the IN keyword owns this word (the conversion operator). ConvertParselet and friends special-case the IN token type directly and trust its text as a unit name, so inches still convert\"],\n [\"dec\", \"already a converter name, as in `255 as dec`\"],\n [\"M\", \"the millions magnitude suffix, as in `2.5M`. Nautical miles are still spelled `nmi` and `NM`\"],\n // Claimed by a normalizer rule rather than by the keyword table, which is why\n // scanning the locale keywords alone does not find it. Admitting `pm`\n // (picometre) broke every clock time in the suite: `4pm` lexed as 4\n // picometres. There is deliberately no entry for `am`: the table's SI\n // prefixes stop at femto, so attometres do not exist and an exclusion would\n // be dead weight. `UnitVocabularyCollisions.spec.ts` asserts that.\n [\"pm\", \"the meridiem marker, as in `4pm`. Picometres lose, and `picometre` still works\"],\n [\"are\", \"the English verb, against a 100-square-metre unit almost nobody writes\"],\n [\"ares\", \"the English verb in plural, same reasoning as `are` above\"],\n [\"turn\", \"ordinary English, against a full-rotation angle unit also spelled in gradians\"],\n [\"turns\", \"ordinary English in plural, same reasoning as `turn` above\"],\n [\"grade\", \"ordinary English. The angle unit is also spelled `gon` and `grad`\"],\n [\"grades\", \"ordinary English in plural, same reasoning as `grade` above\"],\n [\"point\", \"ordinary English. The typographic point is also reachable as `pica`\"],\n [\"points\", \"ordinary English in plural, same reasoning as `point` above\"],\n [\"moment\", \"ordinary English, against an obscure medieval time unit of 90 seconds\"],\n [\"moments\", \"ordinary English in plural, same reasoning as `moment` above\"],\n [\"shake\", \"ordinary English, against an obscure physics unit of ten nanoseconds\"],\n [\"shakes\", \"ordinary English in plural, same reasoning as `shake` above\"],\n]);\n\n/**\n * Whether a spelling can be a single UNIT token at all.\n *\n * The lexer reads a unit as one run of `[A-Za-z0-9_]`, so the 465 spellings\n * containing a space, a slash, a prime or a non-ASCII character cannot be\n * tokenized however well the converter understands them. `square metres`,\n * `cd/m2` and `µm²` all remain reachable through the conversion API (notably\n * the cooking package's free-text target unit), just not by typing them in an\n * expression.\n */\nfunction isTokenizableSpelling(spelling: string): boolean {\n return /^[A-Za-z0-9_]+$/.test(spelling);\n}\n\n/**\n * The single-character units that were already claimed before the vocabulary\n * was derived from the tables, and are therefore grandfathered in.\n *\n * No OTHER single character is admitted. A one-letter unit is indistinguishable\n * from the placeholder names people actually write (`x`, `y`, `n`), and the\n * table has ten more of them: `r a y c p S L N J R`. Admitting those turned\n * `x.y` into a unit expression and broke comparison-operator tests that had\n * deliberately picked letters which were not units. The upside was a handful of\n * spellings that all have an unambiguous longer form (`rad`, `year`, `cup`).\n */\nconst GRANDFATHERED_SINGLE_CHARACTER_UNITS = new Set([\n \"m\", \"g\", \"t\", \"s\", \"h\", \"d\", \"l\", \"b\", \"B\", \"C\", \"F\", \"K\", \"W\",\n]);\n\n/** Whether a base-table spelling should become a lexer token. */\nfunction isAdmissible(spelling: string): boolean {\n if (!isTokenizableSpelling(spelling)) return false;\n if (EXCLUDED_UNIT_SPELLINGS.has(spelling)) return false;\n if (spelling.length === 1) return GRANDFATHERED_SINGLE_CHARACTER_UNITS.has(spelling);\n return true;\n}\n\n/**\n * ISO 4217 codes and the crypto tickers handled alongside them.\n *\n * Hand-maintained on purpose: these are NOT units. They route through\n * CurrencyExchangeService, and `getMeasure()` deliberately returns undefined\n * for every one of them, which is how `VM.ts` tells a currency from a unit.\n * Must stay in sync with CurrencyExchangeService's `isCurrency()`: without a\n * lexer entry a code never becomes a UNIT token, so `1 BTC to USD` used to\n * fail at tokenization with \"Undefined variable: BTC\" before ever reaching\n * the currency service that could have handled it.\n */\nconst CURRENCY_CODES = [\n \"USD\", \"EUR\", \"GBP\", \"JPY\",\n \"AUD\", \"CAD\", \"CHF\", \"CNY\", \"SEK\", \"NOK\", \"DKK\", \"NZD\",\n \"KRW\", \"SGD\", \"HKD\", \"TWD\", \"INR\", \"BRL\", \"ZAR\", \"MXN\",\n \"RUB\", \"TRY\", \"SAR\", \"AED\", \"ILS\", \"PLN\", \"CZK\", \"HUF\",\n \"THB\", \"IDR\", \"MYR\", \"PHP\", \"CLP\", \"COP\", \"ARS\", \"NGN\",\n \"EGP\", \"PKR\", \"BDT\", \"VND\", \"KES\", \"XOF\", \"XAF\", \"MAD\",\n \"QAR\", \"KWD\", \"OMR\", \"BHD\", \"JOD\", \"LKR\", \"MMK\", \"UZS\",\n \"KZT\", \"RON\", \"BGN\", \"HRK\", \"ISK\", \"UAH\", \"GEL\", \"AZN\",\n \"BTN\", \"BND\", \"BOB\", \"BWP\", \"BYN\", \"BZD\", \"CDF\", \"CRC\",\n \"CUP\", \"DOP\", \"DZD\", \"ERN\", \"ETB\", \"FJD\", \"FKP\", \"GMD\",\n \"GNF\", \"GYD\", \"HNL\", \"HTG\", \"JMD\", \"KGZ\", \"KHR\", \"KMF\",\n \"KYD\", \"LAK\", \"LBP\", \"LRD\", \"LSL\", \"LYD\", \"MDL\", \"MGA\",\n \"MKD\", \"MNT\", \"MOP\", \"MRU\", \"MUR\", \"MVR\", \"MWK\", \"MZN\",\n \"NAD\", \"NIO\", \"NPR\", \"PGK\", \"PYG\", \"RSD\", \"RWF\", \"SBD\",\n \"SCR\", \"SDG\", \"SHP\", \"SLE\", \"SOS\", \"SRD\", \"SSP\", \"STN\",\n \"SVC\", \"SYP\", \"SZL\", \"TJS\", \"TMT\", \"TND\", \"TOP\", \"TTD\",\n \"TZS\", \"UGX\", \"UYU\", \"VEB\", \"VUV\", \"WST\", \"XCD\", \"XDR\",\n \"XPF\", \"YER\", \"ZMW\", \"ZWL\",\n \"BTC\", \"ETH\", \"SOL\", \"XRP\", \"ADA\", \"DOGE\", \"DOT\",\n];\n\n/**\n * Currency WORD forms, resolved to their canonical ISO code by\n * `UomLiteralParselet.ts` via `uom/CurrencyAliases.ts`.\n *\n * That table doc-comments every ambiguous choice (peso to MXN, franc to CHF,\n * krona to SEK) and explains why \"pound\"/\"pounds\" is deliberately absent: the\n * mass unit already claims it, and remapping would be exactly the kind of\n * guessing the case-sensitive, no-alias policy exists to prevent.\n */\nconst CURRENCY_WORD_FORMS = [\n \"dollar\", \"dollars\", \"euro\", \"euros\", \"yen\",\n \"ruble\", \"rubles\", \"rouble\", \"roubles\", \"won\",\n \"rupee\", \"rupees\", \"yuan\", \"renminbi\", \"franc\", \"francs\", \"rand\",\n \"krona\", \"kronor\", \"krone\", \"kroner\", \"real\", \"reais\", \"peso\", \"pesos\",\n \"shekel\", \"shekels\", \"lira\", \"hryvnia\", \"hryvnias\", \"zloty\", \"zlotys\",\n \"forint\", \"koruna\", \"dirham\", \"dirhams\", \"riyal\", \"riyals\", \"rial\", \"rials\",\n \"ringgit\", \"rupiah\", \"baht\", \"dong\", \"naira\",\n];\n\n/**\n * \"workday\" and \"workdays\", a business day (Mon-Fri).\n *\n * Backs the datetime package's `<date> + N workdays` arithmetic and\n * `$X/workday` Rate literals. Not a real unit (a business day has no fixed\n * physical duration, it depends on which dates are weekends), so it has no\n * entry in the conversion tables and is shimmed at a fixed 7/5 ratio for rate\n * math only. See `uom/UomConverter.ts`.\n *\n * Safe with respect to variable names: VariableParselet accepts UNIT-typed\n * tokens as names, so `:workday = 5` keeps working, exactly as `:b = 5`\n * already did for the bits unit.\n */\nconst WORKDAY_UNITS = [\"workday\", \"workdays\"];\n\n/**\n * Set of all known unit identifiers (case-sensitive).\n *\n * Base units come from the conversion table; the extended units (speed,\n * voltage, parts-per and the other categories the base table has no measure\n * for) come from ExtendedUnits.ts; currencies and workdays are listed above.\n *\n * Note ExtendedUnits deliberately omits bare `V` (collides with the stocks\n * package's Visa ticker), bare `var` (reads as a variable name) and `fps`\n * (the Time package needs it for frames per second, so speed uses `ft_s`).\n * Those exclusions live there rather than here because they are properties of\n * that table.\n */\nexport const knownUnits: ReadonlySet<string> = new Set([\n ...Object.keys(UNIT_TABLE).filter(isAdmissible),\n ...Object.keys(EXTENDED_UNITS),\n ...WORKDAY_UNITS,\n ...CURRENCY_CODES,\n ...CURRENCY_WORD_FORMS,\n]);\n\n/** The exclusion list, exported so the vocabulary spec can assert each entry. */\nexport const excludedUnitSpellings: ReadonlyMap<string, string> = EXCLUDED_UNIT_SPELLINGS;\n\n/** Units are case-sensitive to eliminate ambiguity (e.g. C=Celsius, c=cup). */\nexport function isKnownUnit(text: string): boolean {\n return knownUnits.has(text);\n}\n"]}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { currencyExchangeService } from './chunk-DM3LMRBC.js';
|
|
2
|
+
import { numberValue } from './chunk-BVAR5J2F.js';
|
|
3
|
+
|
|
4
|
+
// src/parser/OperandWidth.ts
|
|
5
|
+
var ONE_OPERAND = [
|
|
6
|
+
10 /* PUSH_NUMBER */,
|
|
7
|
+
11 /* PUSH_BIGINT */,
|
|
8
|
+
12 /* PUSH_HEX */,
|
|
9
|
+
13 /* PUSH_STRING */,
|
|
10
|
+
14 /* PUSH_BOOLEAN */,
|
|
11
|
+
60 /* LOAD_VAR */,
|
|
12
|
+
61 /* STORE_VAR */,
|
|
13
|
+
62 /* LOAD_GLOBAL_VAR */,
|
|
14
|
+
63 /* STORE_GLOBAL_VAR */,
|
|
15
|
+
150 /* DEFINE_USER_FUNCTION */
|
|
16
|
+
];
|
|
17
|
+
var TWO_OPERANDS = [
|
|
18
|
+
50 /* CALL_PLUGIN */,
|
|
19
|
+
51 /* CALL_BUILTIN */,
|
|
20
|
+
151 /* CALL_USER_FUNCTION */,
|
|
21
|
+
152 /* MAT_NEW */
|
|
22
|
+
];
|
|
23
|
+
var THREE_OPERANDS = [157 /* MAP_INVOKE */, 158 /* REDUCE_INVOKE */];
|
|
24
|
+
var OPERAND_BYTES = (() => {
|
|
25
|
+
const widths = new Array(256).fill(0);
|
|
26
|
+
for (const op of ONE_OPERAND) widths[op] = 1;
|
|
27
|
+
for (const op of TWO_OPERANDS) widths[op] = 2;
|
|
28
|
+
for (const op of THREE_OPERANDS) widths[op] = 3;
|
|
29
|
+
return widths;
|
|
30
|
+
})();
|
|
31
|
+
[
|
|
32
|
+
...ONE_OPERAND,
|
|
33
|
+
...TWO_OPERANDS,
|
|
34
|
+
...THREE_OPERANDS
|
|
35
|
+
];
|
|
36
|
+
function nextInstruction(opcodes, index) {
|
|
37
|
+
return index + 1 + (OPERAND_BYTES[opcodes[index]] ?? 0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/uom/CurrencyResolver.ts
|
|
41
|
+
var CURRENCY_NS = "currency";
|
|
42
|
+
var CurrencyAsyncResolver = class {
|
|
43
|
+
constructor(exchange) {
|
|
44
|
+
this.namespace = CURRENCY_NS;
|
|
45
|
+
this.exchange = exchange ?? currencyExchangeService;
|
|
46
|
+
}
|
|
47
|
+
preflight(_tokens, bytecode, packageId, signal, queryClient) {
|
|
48
|
+
const { opcodes, strings } = bytecode;
|
|
49
|
+
const len = opcodes.length;
|
|
50
|
+
let i = 0;
|
|
51
|
+
let lastStrIdx = -1;
|
|
52
|
+
let prevStrIdx = -1;
|
|
53
|
+
while (i < len) {
|
|
54
|
+
const op = opcodes[i];
|
|
55
|
+
if (op === 13 /* PUSH_STRING */) {
|
|
56
|
+
prevStrIdx = lastStrIdx;
|
|
57
|
+
lastStrIdx = opcodes[i + 1];
|
|
58
|
+
}
|
|
59
|
+
const isCurrencyCombiningOp = op === 84 /* UOM_CONVERT_IN */ || op === 81 /* UOM_CONVERT_TO */ || op === 20 /* ADD */ || op === 21 /* SUB */ || op === 22 /* MUL */ || op === 23 /* DIV */;
|
|
60
|
+
if (isCurrencyCombiningOp) {
|
|
61
|
+
if (prevStrIdx >= 0 && lastStrIdx >= 0) {
|
|
62
|
+
const fromUnit = strings[prevStrIdx];
|
|
63
|
+
const toUnit = strings[lastStrIdx];
|
|
64
|
+
if (this.exchange.isCurrency(fromUnit) && this.exchange.isCurrency(toUnit) && fromUnit.toUpperCase() !== toUnit.toUpperCase()) {
|
|
65
|
+
const syncRate = this.exchange.getRateSync(fromUnit, toUnit);
|
|
66
|
+
if (syncRate === null) {
|
|
67
|
+
const fromUpper = fromUnit.toUpperCase();
|
|
68
|
+
const toUpper = toUnit.toUpperCase();
|
|
69
|
+
const cacheKey = [CURRENCY_NS, fromUpper, toUpper];
|
|
70
|
+
if (queryClient.getQueryData(cacheKey) !== void 0) {
|
|
71
|
+
i++;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const resolver = queryClient.fetchQuery({
|
|
75
|
+
queryKey: cacheKey,
|
|
76
|
+
queryFn: ({ signal: qSignal }) => {
|
|
77
|
+
return this.exchange.getRate(fromUnit, toUnit, qSignal).then((rate) => numberValue(rate));
|
|
78
|
+
},
|
|
79
|
+
staleTime: 5 * 60 * 1e3
|
|
80
|
+
});
|
|
81
|
+
return { queryKey: cacheKey.join(":"), resolver, packageId, signal, metadata: { fromUnit, toUnit } };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
i = nextInstruction(opcodes, i);
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
destroy() {
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export { CurrencyAsyncResolver, nextInstruction };
|
|
95
|
+
//# sourceMappingURL=chunk-EPOXXJBK.js.map
|
|
96
|
+
//# sourceMappingURL=chunk-EPOXXJBK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/parser/OperandWidth.ts","../src/uom/CurrencyResolver.ts"],"names":[],"mappings":"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","file":"chunk-EPOXXJBK.js","sourcesContent":["/**\n * How many operand bytes follow each opcode, and how to step over one.\n *\n * Anything walking a bytecode stream without executing it needs this: the\n * resolver preflight scanners look for specific opcodes and must skip past\n * everything else without mistaking an operand byte for an instruction.\n *\n * It used to be a hand-copied switch in each of those scanners. They had\n * already drifted: two counted `CALL_PLUGIN` as three bytes wide and the third\n * omitted it from that arm, so a stream containing one desynchronised there and\n * every opcode after it was read at the wrong offset. Adding an opcode meant\n * remembering every copy, and nothing checked that you had.\n *\n * `__tests__/parser/OperandWidth.spec.ts` asserts every opcode has a width, so\n * a new one fails a test rather than silently defaulting to zero operands.\n */\n\nimport { OpCode } from \"@solve-js/parser/OpCode\";\n\n/**\n * Opcodes taking one operand byte.\n *\n * A constant-pool index, or a variable-name index.\n */\nconst ONE_OPERAND: readonly OpCode[] = [\n\tOpCode.PUSH_NUMBER,\n\tOpCode.PUSH_BIGINT,\n\tOpCode.PUSH_HEX,\n\tOpCode.PUSH_STRING,\n\tOpCode.PUSH_BOOLEAN,\n\tOpCode.LOAD_VAR,\n\tOpCode.STORE_VAR,\n\tOpCode.LOAD_GLOBAL_VAR,\n\tOpCode.STORE_GLOBAL_VAR,\n\tOpCode.DEFINE_USER_FUNCTION,\n];\n\n/**\n * Opcodes taking two operand bytes.\n *\n * A callable index plus an argument count, or a matrix's row and column counts.\n */\nconst TWO_OPERANDS: readonly OpCode[] = [\n\tOpCode.CALL_PLUGIN,\n\tOpCode.CALL_BUILTIN,\n\tOpCode.CALL_USER_FUNCTION,\n\tOpCode.MAT_NEW,\n];\n\n/**\n * Opcodes taking three operand bytes.\n *\n * The map and reduce invocations, which carry a body index alongside their\n * other operands.\n */\nconst THREE_OPERANDS: readonly OpCode[] = [OpCode.MAP_INVOKE, OpCode.REDUCE_INVOKE];\n\n/**\n * Operand byte count for every opcode, indexed by opcode value.\n *\n * A dense array rather than a map, because the preflight scanners run on every\n * keystroke and this is read once per instruction.\n */\nexport const OPERAND_BYTES: readonly number[] = (() => {\n\tconst widths = new Array<number>(256).fill(0);\n\tfor (const op of ONE_OPERAND) widths[op] = 1;\n\tfor (const op of TWO_OPERANDS) widths[op] = 2;\n\tfor (const op of THREE_OPERANDS) widths[op] = 3;\n\treturn widths;\n})();\n\n/**\n * Every opcode that takes at least one operand.\n *\n * Exported so a test can assert the table stays complete as opcodes are added.\n */\nexport const OPCODES_WITH_OPERANDS: readonly OpCode[] = [\n\t...ONE_OPERAND,\n\t...TWO_OPERANDS,\n\t...THREE_OPERANDS,\n];\n\n/**\n * Offset of the instruction after the one at `index`.\n *\n * @param opcodes - The bytecode stream.\n * @param index - Offset of an opcode, not of an operand byte. Passing an\n * operand offset yields nonsense, which is the failure mode this exists to\n * prevent: a caller stepping by hand and getting one width wrong reads the rest\n * of the stream misaligned.\n * @returns Offset of the next opcode. May be past the end when the instruction\n * at `index` is the last one, so callers loop while it is under `opcodes.length`.\n */\nexport function nextInstruction(opcodes: Uint8Array, index: number): number {\n\treturn index + 1 + (OPERAND_BYTES[opcodes[index]] ?? 0);\n}\n","/**\n * Currency async resolver, bridges CurrencyExchangeService to the\n * IAsyncResolver interface for the Suspense architecture.\n *\n * Uses TanStack Query (injected via queryClient) as the single cache layer.\n */\nimport type { QueryClient } from \"@tanstack/query-core\";\nimport type { Token } from \"@solve-js/lexer\";\nimport type { BytecodeProgram } from \"@solve-js/parser/BytecodeBuilder\";\nimport { OpCode } from \"@solve-js/parser/OpCode\";\nimport { numberValue } from \"@solve-js/vm/Value\";\nimport {\n\tcurrencyExchangeService,\n\tCurrencyExchangeService,\n} from \"@solve-js/uom/CurrencyExchange\";\nimport type { IAsyncResolver, AsyncCheckResult } from \"@solve-js/resolvers/ResolverRegistry\";\nimport { nextInstruction } from \"@solve-js/parser/OperandWidth\";\n\nconst CURRENCY_NS = \"currency\";\n\n/**\n * Fetches exchange rates before the VM runs, so a conversion has real numbers.\n *\n * Until rates arrive the line evaluates to a pending value rather than a\n * guessed one, and re-evaluates when they land.\n */\nexport class CurrencyAsyncResolver implements IAsyncResolver {\n\treadonly namespace = CURRENCY_NS;\n\n\tprivate exchange: CurrencyExchangeService;\n\n\tconstructor(exchange?: CurrencyExchangeService) {\n\t\tthis.exchange = exchange ?? currencyExchangeService;\n\t}\n\n\tpreflight(_tokens: Token[], bytecode: BytecodeProgram, packageId: string, signal: AbortSignal, queryClient: QueryClient): AsyncCheckResult | null {\n\t\tconst { opcodes, strings } = bytecode;\n\t\tconst len = opcodes.length;\n\t\tlet i = 0;\n\n\t\tlet lastStrIdx = -1;\n\t\tlet prevStrIdx = -1;\n\n\t\twhile (i < len) {\n\t\t\tconst op = opcodes[i] as OpCode;\n\n\t\t\tif (op === OpCode.PUSH_STRING) {\n\t\t\t\tprevStrIdx = lastStrIdx;\n\t\t\t\tlastStrIdx = opcodes[i + 1];\n\t\t\t}\n\n\t\t\t// Explicit \"X to Y\"/\"X in Y\" conversions (UOM_CONVERT_IN/_TO) are\n\t\t\t// the obvious case, but arithmetic directly on two differently-\n\t\t\t// denominated currency literals, \"0.01 BTC + 1 ETH\", needs the\n\t\t\t// exact same preflight fetch and previously never got it: this\n\t\t\t// scanner only looked for the CONVERT opcodes, so ADD/SUB/MUL/DIV\n\t\t\t// between two currency UOMs skipped preflight entirely, ran with\n\t\t\t// no cached rate, and fell through to the VM's silent-wrong-math\n\t\t\t// fallback instead of ever reaching a network fetch.\n\t\t\tconst isCurrencyCombiningOp =\n\t\t\t\top === OpCode.UOM_CONVERT_IN || op === OpCode.UOM_CONVERT_TO ||\n\t\t\t\top === OpCode.ADD || op === OpCode.SUB || op === OpCode.MUL || op === OpCode.DIV;\n\t\t\tif (isCurrencyCombiningOp) {\n\t\t\t\tif (prevStrIdx >= 0 && lastStrIdx >= 0) {\n\t\t\t\t\tconst fromUnit = strings[prevStrIdx];\n\t\t\t\t\tconst toUnit = strings[lastStrIdx];\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.exchange.isCurrency(fromUnit) &&\n\t\t\t\t\t\tthis.exchange.isCurrency(toUnit) &&\n\t\t\t\t\t\tfromUnit.toUpperCase() !== toUnit.toUpperCase()\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst syncRate = this.exchange.getRateSync(fromUnit, toUnit);\n\t\t\t\t\t\tif (syncRate === null) {\n\t\t\t\t\t\t\tconst fromUpper = fromUnit.toUpperCase();\n\t\t\t\t\t\t\tconst toUpper = toUnit.toUpperCase();\n\n\t\t\t\t\t\t\t// Check TanStack Query cache\n\t\t\t\t\t\t\tconst cacheKey = [CURRENCY_NS, fromUpper, toUpper];\n\t\t\t\t\t\t\tif (queryClient.getQueryData(cacheKey) !== undefined) {\n\t\t\t\t\t\t\t\ti++;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Fetch via TanStack Query (dedup + retry automatic)\n\t\t\t\t\t\t\tconst resolver = queryClient.fetchQuery({\n\t\t\t\t\t\t\t\tqueryKey: cacheKey,\n\t\t\t\t\t\t\t\tqueryFn: ({ signal: qSignal }) => {\n\t\t\t\t\t\t\t\t\treturn this.exchange.getRate(fromUnit, toUnit, qSignal).then((rate) => numberValue(rate));\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tstaleTime: 5 * 60 * 1000,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\treturn { queryKey: cacheKey.join(\":\"), resolver, packageId, signal, metadata: { fromUnit, toUnit } };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Step over this instruction and its operands. Shared table, because\n\t\t\t// three hand-copied versions of this had already drifted.\n\t\t\ti = nextInstruction(opcodes, i);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tdestroy(): void {\n\t\t// Cache cleared by ResolverRegistry.unregister() via removeQueries({ queryKey: [\"currency\"] })\n\t}\n}\n"]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/variables/VariableResolver.ts
|
|
4
|
+
var VariableResolver = class {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.sources = [];
|
|
7
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
8
|
+
this.cacheEnabled = true;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Register a variable source with a given priority.
|
|
12
|
+
* Sources are sorted so lower-priority-number sources are queried first.
|
|
13
|
+
*
|
|
14
|
+
* @param source - The variable source to register
|
|
15
|
+
*/
|
|
16
|
+
registerSource(source) {
|
|
17
|
+
this.sources.push(source);
|
|
18
|
+
this.sources.sort((a, b) => a.priority - b.priority);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Remove a previously registered variable source (identity match).
|
|
22
|
+
* The lookup cache is cleared because resolution results may change
|
|
23
|
+
* once the source no longer participates.
|
|
24
|
+
*
|
|
25
|
+
* @param source - The exact source instance passed to registerSource.
|
|
26
|
+
*/
|
|
27
|
+
unregisterSource(source) {
|
|
28
|
+
const idx = this.sources.indexOf(source);
|
|
29
|
+
if (idx !== -1) {
|
|
30
|
+
this.sources.splice(idx, 1);
|
|
31
|
+
this.cache.clear();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Resolve a variable name to its value.
|
|
36
|
+
*
|
|
37
|
+
* Checks the cache first (if enabled), then queries registered sources
|
|
38
|
+
* in priority order. The first source returning a non-undefined value wins.
|
|
39
|
+
* Cached results are stored and returned on subsequent calls until invalidated.
|
|
40
|
+
*
|
|
41
|
+
* @param name - The variable name to resolve
|
|
42
|
+
* @returns The resolved value, or undefined if not found in any source
|
|
43
|
+
*/
|
|
44
|
+
async resolve(name) {
|
|
45
|
+
if (this.cacheEnabled) {
|
|
46
|
+
const cached = this.cache.get(name);
|
|
47
|
+
if (cached !== void 0) return cached;
|
|
48
|
+
}
|
|
49
|
+
for (const source of this.sources) {
|
|
50
|
+
const value = await source.get(name);
|
|
51
|
+
if (value !== void 0) {
|
|
52
|
+
if (this.cacheEnabled) {
|
|
53
|
+
this.cache.set(name, value);
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return void 0;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Set a variable value across all registered sources.
|
|
62
|
+
* Also updates the local cache so subsequent reads return the new value.
|
|
63
|
+
*
|
|
64
|
+
* @param name - The variable name
|
|
65
|
+
* @param value - The value to set
|
|
66
|
+
*/
|
|
67
|
+
async set(name, value) {
|
|
68
|
+
for (const source of this.sources) {
|
|
69
|
+
await source.set(name, value);
|
|
70
|
+
}
|
|
71
|
+
this.cache.set(name, value);
|
|
72
|
+
}
|
|
73
|
+
/** Invalidate a single variable in the cache, forcing re-resolution on next read. */
|
|
74
|
+
invalidate(name) {
|
|
75
|
+
this.cache.delete(name);
|
|
76
|
+
}
|
|
77
|
+
/** Invalidate all cached variable lookups. */
|
|
78
|
+
invalidateAll() {
|
|
79
|
+
this.cache.clear();
|
|
80
|
+
}
|
|
81
|
+
/** Enable or disable the lookup cache. When disabled, every read queries sources directly. */
|
|
82
|
+
setCacheEnabled(enabled) {
|
|
83
|
+
this.cacheEnabled = enabled;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var sharedVariableResolver = new VariableResolver();
|
|
87
|
+
|
|
88
|
+
exports.VariableResolver = VariableResolver;
|
|
89
|
+
exports.sharedVariableResolver = sharedVariableResolver;
|
|
90
|
+
//# sourceMappingURL=chunk-FEAIOR7N.cjs.map
|
|
91
|
+
//# sourceMappingURL=chunk-FEAIOR7N.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/variables/VariableResolver.ts"],"names":[],"mappings":";;;AASO,IAAM,mBAAN,MAAuB;AAAA,EAAvB,WAAA,GAAA;AACN,IAAA,IAAA,CAAQ,UAA6B,EAAC;AACtC,IAAA,IAAA,CAAQ,KAAA,uBAAsD,GAAA,EAAI;AAClE,IAAA,IAAA,CAAQ,YAAA,GAAe,IAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQvB,eAAe,MAAA,EAA+B;AAC7C,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,MAAM,CAAA;AACxB,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,QAAA,GAAW,EAAE,QAAQ,CAAA;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,iBAAiB,MAAA,EAA+B;AAC/C,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA;AACvC,IAAA,IAAI,QAAQ,EAAA,EAAI;AACf,MAAA,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,GAAA,EAAK,CAAC,CAAA;AAC1B,MAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AAAA,IAClB;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,QAAQ,IAAA,EAAoD;AACjE,IAAA,IAAI,KAAK,YAAA,EAAc;AACtB,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA;AAClC,MAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AAAA,IAClC;AAEA,IAAA,KAAA,MAAW,MAAA,IAAU,KAAK,OAAA,EAAS;AAClC,MAAA,MAAM,KAAA,GAAQ,MAAM,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AACnC,MAAA,IAAI,UAAU,MAAA,EAAW;AACxB,QAAA,IAAI,KAAK,YAAA,EAAc;AACtB,UAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAA,EAAM,KAAK,CAAA;AAAA,QAC3B;AACA,QAAA,OAAO,KAAA;AAAA,MACR;AAAA,IACD;AAEA,IAAA,OAAO,MAAA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,GAAA,CAAI,IAAA,EAAc,KAAA,EAAuC;AAC9D,IAAA,KAAA,MAAW,MAAA,IAAU,KAAK,OAAA,EAAS;AAClC,MAAA,MAAM,MAAA,CAAO,GAAA,CAAI,IAAA,EAAM,KAAK,CAAA;AAAA,IAC7B;AACA,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAA,EAAM,KAAK,CAAA;AAAA,EAC3B;AAAA;AAAA,EAGA,WAAW,IAAA,EAAoB;AAC9B,IAAA,IAAA,CAAK,KAAA,CAAM,OAAO,IAAI,CAAA;AAAA,EACvB;AAAA;AAAA,EAGA,aAAA,GAAsB;AACrB,IAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AAAA,EAClB;AAAA;AAAA,EAGA,gBAAgB,OAAA,EAAwB;AACvC,IAAA,IAAA,CAAK,YAAA,GAAe,OAAA;AAAA,EACrB;AACD;AAGO,IAAM,sBAAA,GAAyB,IAAI,gBAAA","file":"chunk-FEAIOR7N.cjs","sourcesContent":["import { IVariableSource } from \"@solve-js/variables/IVariableSource\";\n\n/**\n * Resolves variable names by querying registered {@link IVariableSource} instances\n * in priority order. Supports caching for repeated lookups.\n *\n * Sources are sorted by priority (lowest first) on registration. When resolving\n * a variable, sources are queried in order and the first non-undefined result wins.\n */\nexport class VariableResolver {\n\tprivate sources: IVariableSource[] = [];\n\tprivate cache: Map<string, number | string | undefined> = new Map();\n\tprivate cacheEnabled = true;\n\n\t/**\n\t * Register a variable source with a given priority.\n\t * Sources are sorted so lower-priority-number sources are queried first.\n\t *\n\t * @param source - The variable source to register\n\t */\n\tregisterSource(source: IVariableSource): void {\n\t\tthis.sources.push(source);\n\t\tthis.sources.sort((a, b) => a.priority - b.priority);\n\t}\n\n\t/**\n\t * Remove a previously registered variable source (identity match).\n\t * The lookup cache is cleared because resolution results may change\n\t * once the source no longer participates.\n\t *\n\t * @param source - The exact source instance passed to registerSource.\n\t */\n\tunregisterSource(source: IVariableSource): void {\n\t\tconst idx = this.sources.indexOf(source);\n\t\tif (idx !== -1) {\n\t\t\tthis.sources.splice(idx, 1);\n\t\t\tthis.cache.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Resolve a variable name to its value.\n\t *\n\t * Checks the cache first (if enabled), then queries registered sources\n\t * in priority order. The first source returning a non-undefined value wins.\n\t * Cached results are stored and returned on subsequent calls until invalidated.\n\t *\n\t * @param name - The variable name to resolve\n\t * @returns The resolved value, or undefined if not found in any source\n\t */\n\tasync resolve(name: string): Promise<number | string | undefined> {\n\t\tif (this.cacheEnabled) {\n\t\t\tconst cached = this.cache.get(name);\n\t\t\tif (cached !== undefined) return cached;\n\t\t}\n\n\t\tfor (const source of this.sources) {\n\t\t\tconst value = await source.get(name);\n\t\t\tif (value !== undefined) {\n\t\t\t\tif (this.cacheEnabled) {\n\t\t\t\t\tthis.cache.set(name, value);\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Set a variable value across all registered sources.\n\t * Also updates the local cache so subsequent reads return the new value.\n\t *\n\t * @param name - The variable name\n\t * @param value - The value to set\n\t */\n\tasync set(name: string, value: number | string): Promise<void> {\n\t\tfor (const source of this.sources) {\n\t\t\tawait source.set(name, value);\n\t\t}\n\t\tthis.cache.set(name, value);\n\t}\n\n\t/** Invalidate a single variable in the cache, forcing re-resolution on next read. */\n\tinvalidate(name: string): void {\n\t\tthis.cache.delete(name);\n\t}\n\n\t/** Invalidate all cached variable lookups. */\n\tinvalidateAll(): void {\n\t\tthis.cache.clear();\n\t}\n\n\t/** Enable or disable the lookup cache. When disabled, every read queries sources directly. */\n\tsetCacheEnabled(enabled: boolean): void {\n\t\tthis.cacheEnabled = enabled;\n\t}\n}\n\n/** Shared singleton VariableResolver instance. */\nexport const sharedVariableResolver = new VariableResolver();\n"]}
|