@rsconcept/domain 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/README.md +3 -3
  2. package/dist/analyzer-DlSq3Y3r.d.ts +39 -0
  3. package/dist/arguments-extractor-1acwjQNc.d.ts +38 -0
  4. package/dist/ast-C8sIpKdL.d.ts +51 -0
  5. package/dist/ast-annotations-BiMjkKvz.d.ts +16 -0
  6. package/dist/branded-ZlzIcxzu.d.ts +9 -0
  7. package/dist/calculator-C9W2jkSx.d.ts +39 -0
  8. package/dist/cctext/index.d.ts +2 -1
  9. package/dist/cctext/index.js +2 -42
  10. package/dist/cctext/language-api.d.ts +10 -12
  11. package/dist/cctext/language-api.js +157 -227
  12. package/dist/cctext/language-api.js.map +1 -1
  13. package/dist/cctext/language.d.ts +24 -22
  14. package/dist/cctext/language.js +43 -39
  15. package/dist/cctext/language.js.map +1 -1
  16. package/dist/error-E1LVq_3w.d.ts +87 -0
  17. package/dist/graph/graph.d.ts +2 -62
  18. package/dist/graph/graph.js +339 -382
  19. package/dist/graph/graph.js.map +1 -1
  20. package/dist/graph/index.d.ts +2 -1
  21. package/dist/graph/index.js +2 -384
  22. package/dist/graph-DR8rL2o3.d.ts +64 -0
  23. package/dist/hash-Y8I4c6Al.d.ts +8 -0
  24. package/dist/index-BKZ67WMa.d.ts +1 -0
  25. package/dist/index-BVVgDSdq.d.ts +1 -0
  26. package/dist/index-DmtQKWjk.d.ts +1 -0
  27. package/dist/index-_6s0AX1B.d.ts +1 -0
  28. package/dist/index.d.ts +27 -28
  29. package/dist/index.js +23 -5851
  30. package/dist/lezer-tree-iS7LpLBJ.d.ts +14 -0
  31. package/dist/library/folder-tree.d.ts +22 -20
  32. package/dist/library/folder-tree.js +108 -130
  33. package/dist/library/folder-tree.js.map +1 -1
  34. package/dist/library/index.d.ts +8 -17
  35. package/dist/library/index.js +7 -2800
  36. package/dist/library/library-api.d.ts +3 -1
  37. package/dist/library/library-api.js +9 -8
  38. package/dist/library/library-api.js.map +1 -1
  39. package/dist/library/library.d.ts +2 -56
  40. package/dist/library/library.js +23 -19
  41. package/dist/library/library.js.map +1 -1
  42. package/dist/library/oss-api.d.ts +26 -37
  43. package/dist/library/oss-api.js +258 -1096
  44. package/dist/library/oss-api.js.map +1 -1
  45. package/dist/library/oss-layout-api.d.ts +28 -28
  46. package/dist/library/oss-layout-api.js +239 -316
  47. package/dist/library/oss-layout-api.js.map +1 -1
  48. package/dist/library/oss-layout.d.ts +2 -25
  49. package/dist/library/oss-layout.js +1 -1
  50. package/dist/library/oss.d.ts +87 -89
  51. package/dist/library/oss.js +27 -26
  52. package/dist/library/oss.js.map +1 -1
  53. package/dist/library/rsengine.d.ts +100 -106
  54. package/dist/library/rsengine.js +439 -2599
  55. package/dist/library/rsengine.js.map +1 -1
  56. package/dist/library/rsform-api.d.ts +11 -16
  57. package/dist/library/rsform-api.js +313 -825
  58. package/dist/library/rsform-api.js.map +1 -1
  59. package/dist/library/rsform.d.ts +159 -167
  60. package/dist/library/rsform.js +29 -28
  61. package/dist/library/rsform.js.map +1 -1
  62. package/dist/library/rsmodel-api.d.ts +8 -15
  63. package/dist/library/rsmodel-api.js +172 -813
  64. package/dist/library/rsmodel-api.js.map +1 -1
  65. package/dist/library/rsmodel.d.ts +27 -33
  66. package/dist/library/rsmodel.js +16 -23
  67. package/dist/library/rsmodel.js.map +1 -1
  68. package/dist/library/structure-planner.d.ts +20 -26
  69. package/dist/library/structure-planner.js +106 -474
  70. package/dist/library/structure-planner.js.map +1 -1
  71. package/dist/library-CYun28Xz.d.ts +58 -0
  72. package/dist/oss-layout-3glgAqfn.d.ts +27 -0
  73. package/dist/parser-Bwd8LxJ1.d.ts +7 -0
  74. package/dist/parsing/ast.d.ts +2 -49
  75. package/dist/parsing/ast.js +68 -76
  76. package/dist/parsing/ast.js.map +1 -1
  77. package/dist/parsing/index.d.ts +3 -3
  78. package/dist/parsing/index.js +3 -141
  79. package/dist/parsing/lezer-tree.d.ts +2 -13
  80. package/dist/parsing/lezer-tree.js +50 -43
  81. package/dist/parsing/lezer-tree.js.map +1 -1
  82. package/dist/rslang/api.d.ts +9 -14
  83. package/dist/rslang/api.js +114 -827
  84. package/dist/rslang/api.js.map +1 -1
  85. package/dist/rslang/ast-annotations.d.ts +2 -18
  86. package/dist/rslang/ast-annotations.js +34 -45
  87. package/dist/rslang/ast-annotations.js.map +1 -1
  88. package/dist/rslang/error.d.ts +2 -85
  89. package/dist/rslang/error.js +88 -150
  90. package/dist/rslang/error.js.map +1 -1
  91. package/dist/rslang/eval/calculator.d.ts +2 -43
  92. package/dist/rslang/eval/calculator.js +81 -1636
  93. package/dist/rslang/eval/calculator.js.map +1 -1
  94. package/dist/rslang/eval/evaluation-cache.d.ts +22 -26
  95. package/dist/rslang/eval/evaluation-cache.js +168 -287
  96. package/dist/rslang/eval/evaluation-cache.js.map +1 -1
  97. package/dist/rslang/eval/evaluator.d.ts +59 -63
  98. package/dist/rslang/eval/evaluator.js +602 -1509
  99. package/dist/rslang/eval/evaluator.js.map +1 -1
  100. package/dist/rslang/eval/value-api.d.ts +2 -48
  101. package/dist/rslang/eval/value-api.js +2 -490
  102. package/dist/rslang/eval/value.d.ts +2 -36
  103. package/dist/rslang/eval/value.js +2 -118
  104. package/dist/rslang/index.d.ts +14 -17
  105. package/dist/rslang/index.js +12 -4314
  106. package/dist/rslang/labels.d.ts +6 -6
  107. package/dist/rslang/labels.js +139 -305
  108. package/dist/rslang/labels.js.map +1 -1
  109. package/dist/rslang/parser/expression-generator.d.ts +5 -5
  110. package/dist/rslang/parser/expression-generator.js +248 -446
  111. package/dist/rslang/parser/expression-generator.js.map +1 -1
  112. package/dist/rslang/parser/normalize.d.ts +4 -8
  113. package/dist/rslang/parser/normalize.js +286 -481
  114. package/dist/rslang/parser/normalize.js.map +1 -1
  115. package/dist/rslang/parser/parser.d.ts +2 -5
  116. package/dist/rslang/parser/parser.js +30 -21
  117. package/dist/rslang/parser/parser.js.map +1 -1
  118. package/dist/rslang/parser/parser.terms.d.ts +43 -41
  119. package/dist/rslang/parser/parser.terms.js +44 -83
  120. package/dist/rslang/parser/parser.terms.js.map +1 -1
  121. package/dist/rslang/parser/syntax-errors.d.ts +5 -8
  122. package/dist/rslang/parser/syntax-errors.js +113 -382
  123. package/dist/rslang/parser/syntax-errors.js.map +1 -1
  124. package/dist/rslang/parser/token.d.ts +2 -79
  125. package/dist/rslang/parser/token.js +81 -93
  126. package/dist/rslang/parser/token.js.map +1 -1
  127. package/dist/rslang/semantic/analyzer.d.ts +2 -39
  128. package/dist/rslang/semantic/analyzer.js +186 -2600
  129. package/dist/rslang/semantic/analyzer.js.map +1 -1
  130. package/dist/rslang/semantic/arguments-extractor.d.ts +2 -42
  131. package/dist/rslang/semantic/arguments-extractor.js +202 -361
  132. package/dist/rslang/semantic/arguments-extractor.js.map +1 -1
  133. package/dist/rslang/semantic/type-auditor.d.ts +64 -68
  134. package/dist/rslang/semantic/type-auditor.js +594 -1564
  135. package/dist/rslang/semantic/type-auditor.js.map +1 -1
  136. package/dist/rslang/semantic/typification-api.d.ts +4 -7
  137. package/dist/rslang/semantic/typification-api.js +162 -303
  138. package/dist/rslang/semantic/typification-api.js.map +1 -1
  139. package/dist/rslang/semantic/typification-parser.d.ts +2 -12
  140. package/dist/rslang/semantic/typification-parser.js +165 -219
  141. package/dist/rslang/semantic/typification-parser.js.map +1 -1
  142. package/dist/rslang/semantic/typification.d.ts +2 -119
  143. package/dist/rslang/semantic/typification.js +66 -52
  144. package/dist/rslang/semantic/typification.js.map +1 -1
  145. package/dist/rslang/semantic/value-auditor.d.ts +32 -38
  146. package/dist/rslang/semantic/value-auditor.js +206 -518
  147. package/dist/rslang/semantic/value-auditor.js.map +1 -1
  148. package/dist/rslang/semantic/value-class.d.ts +2 -10
  149. package/dist/rslang/semantic/value-class.js +8 -7
  150. package/dist/rslang/semantic/value-class.js.map +1 -1
  151. package/dist/rslang/typification-graph.d.ts +2 -33
  152. package/dist/rslang/typification-graph.js +94 -306
  153. package/dist/rslang/typification-graph.js.map +1 -1
  154. package/dist/shared/branded.d.ts +2 -7
  155. package/dist/shared/branded.js +1 -1
  156. package/dist/shared/hash.d.ts +2 -6
  157. package/dist/shared/hash.js +13 -13
  158. package/dist/shared/hash.js.map +1 -1
  159. package/dist/shared/index.d.ts +3 -2
  160. package/dist/shared/index.js +2 -18
  161. package/dist/token-DeXAmzwr.d.ts +81 -0
  162. package/dist/typification-Dk-fisgO.d.ts +120 -0
  163. package/dist/typification-graph-6HcZ-rKH.d.ts +30 -0
  164. package/dist/typification-parser-BBVx1RxP.d.ts +13 -0
  165. package/dist/value-B8UtCqaK.js +366 -0
  166. package/dist/value-B8UtCqaK.js.map +1 -0
  167. package/dist/value-CTjX6825.d.ts +33 -0
  168. package/dist/value-api-Bw-SgaYY.d.ts +49 -0
  169. package/dist/value-class-CNI-lqXJ.d.ts +12 -0
  170. package/package.json +8 -8
  171. package/src/library/oss-api.test.ts +76 -0
  172. package/src/library/oss-api.ts +4 -1
  173. package/src/library/rsform-api.test.ts +24 -0
  174. package/src/library/rsform-api.ts +12 -4
  175. package/dist/cctext/index.js.map +0 -1
  176. package/dist/graph/index.js.map +0 -1
  177. package/dist/index.js.map +0 -1
  178. package/dist/library/index.js.map +0 -1
  179. package/dist/library/oss-layout.js.map +0 -1
  180. package/dist/parsing/index.js.map +0 -1
  181. package/dist/rslang/eval/value-api.js.map +0 -1
  182. package/dist/rslang/eval/value.js.map +0 -1
  183. package/dist/rslang/index.js.map +0 -1
  184. package/dist/shared/branded.js.map +0 -1
  185. package/dist/shared/index.js.map +0 -1
@@ -1,1514 +1,607 @@
1
- // src/parsing/ast.ts
2
- var TOKEN_ERROR = 0;
3
- function getNodeText(node) {
4
- if (node.data.dataType === "string" && typeof node.data.value === "string") {
5
- return node.data.value;
6
- }
7
- return `NO DATA NODE: ${node.typeID}`;
8
- }
9
- function getNodeIndices(node) {
10
- if (node.data.dataType === "string[]" && Array.isArray(node.data.value)) {
11
- return node.data.value.map((s) => parseInt(s, 10)).filter((n) => !isNaN(n));
12
- }
13
- return [];
14
- }
15
-
16
- // src/rslang/ast-annotations.ts
17
- var AST_ERRORS_KEY = "rsErrors";
18
- function annotateError(node, code, params) {
19
- if (typeof node.annotation === "object" && node.annotation !== null && AST_ERRORS_KEY in node.annotation && isAstNodeErrorRef(node.annotation[AST_ERRORS_KEY])) {
20
- return;
21
- }
22
- const entry = params !== void 0 && params.length > 0 ? { code, params: [...params] } : { code };
23
- node.annotation = {
24
- ...typeof node.annotation === "object" && node.annotation !== null ? node.annotation : {},
25
- [AST_ERRORS_KEY]: entry
26
- };
27
- }
28
- function isAstNodeErrorRef(x) {
29
- if (typeof x !== "object" || x === null || !("code" in x)) {
30
- return false;
31
- }
32
- const code = x.code;
33
- if (typeof code !== "number") {
34
- return false;
35
- }
36
- if (!("params" in x)) {
37
- return true;
38
- }
39
- const p = x.params;
40
- if (p === void 0) {
41
- return true;
42
- }
43
- return Array.isArray(p) && p.every((item) => typeof item === "string");
44
- }
45
-
46
- // src/rslang/error.ts
47
- var RSErrorCode = {
48
- unknownSyntax: 33792,
49
- // 33792
50
- missingParenthesis: 33798,
51
- // 33798
52
- missingCurlyBrace: 33799,
53
- // 33799
54
- missingSquareBracket: 33800,
55
- // 33800
56
- bracketMismatch: 33801,
57
- // 33801
58
- doubleParenthesis: 33802,
59
- // 33802
60
- missingOpenBracket: 33803,
61
- // 33803
62
- expectedLocal: 33813,
63
- // 33813
64
- expectedType: 33814,
65
- // 33814
66
- localDoubleDeclare: 10241,
67
- // 10241
68
- localNotUsed: 10242,
69
- // 10242
70
- localUndeclared: 34817,
71
- // 34817
72
- localShadowing: 34818,
73
- // 34818
74
- typesNotEqual: 34819,
75
- // 34819
76
- globalNotTyped: 34820,
77
- // 34820
78
- invalidDecart: 34821,
79
- // 34821
80
- invalidBoolean: 34822,
81
- // 34822
82
- invalidTypeOperation: 34823,
83
- // 34823
84
- invalidCard: 34824,
85
- // 34824
86
- invalidDebool: 34825,
87
- // 34825
88
- globalFuncWithoutArgs: 34827,
89
- // 34827
90
- invalidReduce: 34832,
91
- // 34832
92
- invalidProjectionTuple: 34833,
93
- // 34833
94
- invalidProjectionSet: 34834,
95
- // 34834
96
- invalidEnumeration: 34835,
97
- // 34835
98
- invalidCortegeDeclare: 34836,
99
- // 34836
100
- localOutOfScope: 34837,
101
- // 34837
102
- invalidElementPredicate: 34838,
103
- // 34838
104
- invalidEmptySetUsage: 34839,
105
- // 34839
106
- invalidArgsArity: 34840,
107
- // 34840
108
- invalidArgumentType: 34841,
109
- // 34841
110
- globalStructure: 34844,
111
- // 34844
112
- radicalUsage: 34849,
113
- // 34849
114
- invalidFilterArgumentType: 34850,
115
- // 34850
116
- invalidFilterArity: 34851,
117
- // 34851
118
- arithmeticNotSupported: 34852,
119
- // 34852
120
- typesNotCompatible: 34853,
121
- // 34853
122
- orderingNotSupported: 34854,
123
- // 34854
124
- expectedLogic: 34855,
125
- // 34855
126
- expectedSetexpr: 34856,
127
- // 34856
128
- invalidArgumentCortegeDeclare: 34857,
129
- // 34857
130
- globalNoValue: 34880,
131
- // 34880
132
- invalidPropertyUsage: 34881,
133
- // 34881
134
- // Value evaluation (runtime)
135
- calcUnknownError: 33024,
136
- // 35328
137
- setOverflow: 33025,
138
- // 35329
139
- booleanBaseLimit: 33026,
140
- // 35330
141
- calcGlobalMissing: 33027,
142
- // 35331
143
- iterationsLimit: 33028,
144
- // 35332
145
- calcInvalidDebool: 33029,
146
- // 35333
147
- iterateInfinity: 33030,
148
- // 35334
149
- calculationNotSupported: 33031,
150
- // 35335
151
- cstEmptyDerived: 34913,
152
- // 34913
153
- definitionNotAllowed: 34914
154
- // 34914
155
- };
156
-
157
- // src/rslang/parser/token.ts
158
- var TokenID = {
159
- // Global, local IDs and literals
160
- ERROR: TOKEN_ERROR,
161
- ID_LOCAL: 258,
162
- ID_GLOBAL: 259,
163
- ID_FUNCTION: 260,
164
- ID_PREDICATE: 261,
165
- ID_RADICAL: 262,
166
- LIT_INTEGER: 263,
167
- LIT_WHOLE_NUMBERS: 264,
168
- LIT_EMPTYSET: 265,
169
- // Arithmetic
170
- PLUS: 266,
171
- MINUS: 267,
172
- MULTIPLY: 268,
173
- // Integer predicate symbols
174
- GREATER: 269,
175
- LESSER: 270,
176
- GREATER_OR_EQ: 271,
177
- LESSER_OR_EQ: 272,
178
- // Equality comparison
179
- EQUAL: 273,
180
- NOTEQUAL: 274,
181
- // Logic predicate symbols
182
- QUANTOR_UNIVERSAL: 275,
183
- QUANTOR_EXISTS: 276,
184
- LOGIC_NOT: 277,
185
- LOGIC_EQUIVALENT: 278,
186
- LOGIC_IMPLICATION: 279,
187
- LOGIC_OR: 280,
188
- LOGIC_AND: 281,
189
- // Set theory predicate symbols
190
- SET_IN: 282,
191
- SET_NOT_IN: 283,
192
- SUBSET: 284,
193
- SUBSET_OR_EQ: 285,
194
- NOT_SUBSET: 286,
195
- // Set theory operators
196
- DECART: 287,
197
- SET_UNION: 288,
198
- SET_INTERSECTION: 289,
199
- SET_MINUS: 290,
200
- SET_SYMMETRIC_MINUS: 291,
201
- BOOLEAN: 292,
202
- // Structure operations
203
- BIGPR: 293,
204
- SMALLPR: 294,
205
- FILTER: 295,
206
- CARD: 296,
207
- BOOL: 297,
208
- DEBOOL: 298,
209
- REDUCE: 299,
210
- // Term constructions prefixes
211
- DECLARATIVE: 300,
212
- RECURSIVE: 301,
213
- IMPERATIVE: 302,
214
- ITERATE: 303,
215
- ASSIGN: 304,
216
- // Punctuation
217
- PUNCTUATION_DEFINE: 305,
218
- PUNCTUATION_STRUCT: 306,
219
- PUNCTUATION_PL: 307,
220
- PUNCTUATION_PR: 308,
221
- PUNCTUATION_CL: 309,
222
- PUNCTUATION_CR: 310,
223
- PUNCTUATION_SL: 311,
224
- PUNCTUATION_SR: 312,
225
- PUNCTUATION_BAR: 313,
226
- PUNCTUATION_COMMA: 314,
227
- PUNCTUATION_SEMICOLON: 315,
228
- // ======= Non-terminal tokens =========
229
- NT_ENUM_DECL: 316,
230
- NT_TUPLE: 317,
231
- NT_ENUMERATION: 318,
232
- NT_TUPLE_DECL: 319,
233
- NT_ARG_DECL: 320,
234
- NT_FUNC_DEFINITION: 321,
235
- NT_ARGUMENTS: 322,
236
- NT_FUNC_CALL: 323,
237
- NT_DECLARATIVE_EXPR: 324,
238
- NT_IMPERATIVE_EXPR: 325,
239
- NT_RECURSIVE_FULL: 326,
240
- NT_RECURSIVE_SHORT: 327,
241
- // ======= Helper tokens ========
242
- INTERRUPT: 328,
243
- END: 329
244
- };
245
-
246
- // src/rslang/eval/evaluation-cache.ts
247
- var EvaluationMetadata = class {
248
- byNode = /* @__PURE__ */ new WeakMap();
249
- get(node) {
250
- let info = this.byNode.get(node);
251
- if (!info) {
252
- info = analyzeNode(node, /* @__PURE__ */ new Set());
253
- this.byNode.set(node, info);
254
- }
255
- return info;
256
- }
257
- };
258
- var EvaluationCache = class {
259
- entries = /* @__PURE__ */ new Map();
260
- /** Cache hits in the current evaluation run (for tests/diagnostics). */
261
- hits = 0;
262
- /** Returns cached value, or `undefined` on miss or stamp mismatch. */
263
- lookup(structuralKey, stamp) {
264
- const entry = this.entries.get(structuralKey);
265
- if (entry?.stamp !== stamp) {
266
- return void 0;
267
- }
268
- this.hits++;
269
- return entry.value;
270
- }
271
- /** Stores one value per structural key (replaces previous stamp). */
272
- store(structuralKey, stamp, value) {
273
- this.entries.set(structuralKey, { stamp, value });
274
- }
275
- clear() {
276
- this.entries.clear();
277
- this.hits = 0;
278
- }
279
- };
280
- function analyzeNode(node, bound) {
281
- const reads = collectReads(node, bound);
282
- const structuralKey = buildStructuralKey(node);
283
- const cacheable = isCacheableNode(node);
284
- return { reads, structuralKey, cacheable };
285
- }
286
- function isCacheableNode(node) {
287
- switch (node.typeID) {
288
- case TokenID.ASSIGN:
289
- case TokenID.ITERATE:
290
- case TokenID.NT_IMPERATIVE_EXPR:
291
- case TokenID.NT_DECLARATIVE_EXPR:
292
- case TokenID.NT_RECURSIVE_FULL:
293
- case TokenID.NT_RECURSIVE_SHORT:
294
- case TokenID.QUANTOR_UNIVERSAL:
295
- case TokenID.QUANTOR_EXISTS:
296
- case TokenID.LOGIC_AND:
297
- case TokenID.LOGIC_OR:
298
- case TokenID.LOGIC_IMPLICATION:
299
- case TokenID.NT_FUNC_DEFINITION:
300
- case TokenID.LIT_INTEGER:
301
- case TokenID.LIT_EMPTYSET:
302
- case TokenID.LIT_WHOLE_NUMBERS:
303
- case TokenID.ID_LOCAL:
304
- case TokenID.ID_RADICAL:
305
- case TokenID.ID_GLOBAL:
306
- return false;
307
- default:
308
- return !node.hasError;
309
- }
310
- }
311
- function buildStructuralKey(node) {
312
- switch (node.typeID) {
313
- case TokenID.ID_GLOBAL:
314
- case TokenID.ID_LOCAL:
315
- case TokenID.ID_RADICAL:
316
- case TokenID.LIT_INTEGER:
317
- case TokenID.LIT_EMPTYSET:
318
- case TokenID.LIT_WHOLE_NUMBERS:
319
- return `${node.typeID}:${nodeTextKey(node)}`;
320
- case TokenID.NT_FUNC_CALL:
321
- return `${node.typeID}:${nodeTextKey(node.children[0])}(${node.children.slice(1).map(buildStructuralKey).join(",")})`;
322
- case TokenID.BIGPR:
323
- case TokenID.SMALLPR:
324
- case TokenID.FILTER:
325
- return `${node.typeID}:${indicesKey(node)}(${node.children.map(buildStructuralKey).join(",")})`;
326
- default:
327
- return `${node.typeID}(${node.children.map(buildStructuralKey).join(",")})`;
328
- }
329
- }
330
- function nodeTextKey(node) {
331
- if (node.data.dataType === "number") {
332
- return String(node.data.value);
333
- }
334
- return getNodeText(node);
335
- }
336
- function indicesKey(node) {
337
- return getNodeIndices(node).join(".");
338
- }
339
- function collectReads(node, bound) {
340
- const reads = /* @__PURE__ */ new Set();
341
- collectReadsImpl(node, bound, reads);
342
- return reads;
343
- }
344
- function collectReadsImpl(node, bound, reads) {
345
- switch (node.typeID) {
346
- case TokenID.ID_LOCAL:
347
- case TokenID.ID_RADICAL: {
348
- reads.add(getNodeText(node));
349
- return;
350
- }
351
- case TokenID.QUANTOR_UNIVERSAL:
352
- case TokenID.QUANTOR_EXISTS: {
353
- collectReadsImpl(node.children[1], bound, reads);
354
- const innerBound = extendBound(bound, node.children[0]);
355
- collectReadsImpl(node.children[2], innerBound, reads);
356
- return;
357
- }
358
- case TokenID.NT_DECLARATIVE_EXPR: {
359
- collectReadsImpl(node.children[1], bound, reads);
360
- const innerBound = extendBound(bound, node.children[0]);
361
- collectReadsImpl(node.children[2], innerBound, reads);
362
- return;
363
- }
364
- case TokenID.ITERATE: {
365
- collectReadsImpl(node.children[1], bound, reads);
366
- return;
367
- }
368
- case TokenID.ASSIGN: {
369
- collectReadsImpl(node.children[1], bound, reads);
370
- return;
371
- }
372
- case TokenID.NT_IMPERATIVE_EXPR: {
373
- const innerBound = new Set(bound);
374
- collectReadsImpl(node.children[0], innerBound, reads);
375
- for (let i = 1; i < node.children.length; i++) {
376
- const child = node.children[i];
377
- if (child.typeID === TokenID.ITERATE) {
378
- extendBoundInPlace(innerBound, child.children[0]);
379
- collectReadsImpl(child.children[1], innerBound, reads);
380
- } else if (child.typeID === TokenID.ASSIGN) {
381
- collectReadsImpl(child.children[1], innerBound, reads);
382
- extendBoundInPlace(innerBound, child.children[0]);
383
- } else {
384
- collectReadsImpl(child, innerBound, reads);
385
- }
386
- }
387
- return;
388
- }
389
- case TokenID.NT_RECURSIVE_FULL:
390
- case TokenID.NT_RECURSIVE_SHORT: {
391
- collectReadsImpl(node.children[1], bound, reads);
392
- const innerBound = extendBound(bound, node.children[0]);
393
- if (node.typeID === TokenID.NT_RECURSIVE_FULL) {
394
- collectReadsImpl(node.children[2], innerBound, reads);
395
- collectReadsImpl(node.children[3], innerBound, reads);
396
- } else {
397
- collectReadsImpl(node.children[2], innerBound, reads);
398
- }
399
- return;
400
- }
401
- case TokenID.NT_FUNC_DEFINITION: {
402
- const innerBound = extendBound(bound, node.children[0]);
403
- collectReadsImpl(node.children[1], innerBound, reads);
404
- return;
405
- }
406
- case TokenID.NT_FUNC_CALL: {
407
- for (let i = 1; i < node.children.length; i++) {
408
- collectReadsImpl(node.children[i], bound, reads);
409
- }
410
- return;
411
- }
412
- case TokenID.LOGIC_AND:
413
- case TokenID.LOGIC_OR:
414
- case TokenID.LOGIC_IMPLICATION: {
415
- collectReadsImpl(node.children[0], bound, reads);
416
- collectReadsImpl(node.children[1], bound, reads);
417
- return;
418
- }
419
- default:
420
- for (const child of node.children) {
421
- collectReadsImpl(child, bound, reads);
422
- }
423
- }
424
- }
425
- function extendBound(bound, declNode) {
426
- const next = new Set(bound);
427
- extendBoundInPlace(next, declNode);
428
- return next;
429
- }
430
- function extendBoundInPlace(bound, declNode) {
431
- switch (declNode.typeID) {
432
- case TokenID.ID_LOCAL:
433
- case TokenID.ID_RADICAL:
434
- bound.add(getNodeText(declNode));
435
- break;
436
- case TokenID.NT_TUPLE_DECL:
437
- case TokenID.NT_ENUM_DECL:
438
- for (const child of declNode.children) {
439
- extendBoundInPlace(bound, child);
440
- }
441
- break;
442
- case TokenID.NT_ARG_DECL:
443
- extendBoundInPlace(bound, declNode.children[0]);
444
- break;
445
- }
446
- }
447
-
448
- // src/rslang/semantic/typification.ts
449
- var TypeID = {
450
- anyTypification: 1,
451
- integer: 2,
452
- basic: 3,
453
- tuple: 4,
454
- collection: 5,
455
- logic: 6,
456
- function: 7,
457
- predicate: 8
458
- };
459
- var LogicT = { typeID: TypeID.logic };
460
- var IntegerT = {
461
- typeID: TypeID.integer,
462
- isOrdered: true,
463
- isArithmetic: true,
464
- isIntegerCompatible: true
465
- };
466
- var AnyTypificationT = { typeID: TypeID.anyTypification };
467
- var EmptySetT = bool(AnyTypificationT);
468
- function bool(base) {
469
- return { typeID: TypeID.collection, base };
470
- }
471
-
472
- // src/rslang/eval/value-api.ts
473
- function cartesianProduct(factors) {
474
- const cardinality = factors.reduce((acc, f) => acc * f.length, 1);
475
- if (cardinality > SET_INFINITY) {
476
- return null;
477
- }
478
- if (cardinality === 0 || factors.length === 0) {
479
- return EmptySetV;
480
- }
481
- let accumulator = [[]];
482
- for (const factor of factors) {
483
- const next = [];
484
- for (const prefix of accumulator) {
485
- for (const value of factor) {
486
- next.push([...prefix, value]);
487
- }
488
- }
489
- accumulator = next;
490
- }
491
- return accumulator.map(tuple);
492
- }
493
- function boolean(base) {
494
- if (base.length > BOOL_INFINITY) {
495
- return null;
496
- }
497
- return powerset(base);
498
- }
499
- function powerset(arr) {
500
- const result = [[]];
501
- if (arr.length === 0) {
502
- return result;
503
- }
504
- let current = [[]];
505
- let maxIndex = [-1];
506
- while (current.length > 0) {
507
- const next = [];
508
- const nextMaxIndex = [];
509
- for (let i = 0; i < current.length; i++) {
510
- for (let j = maxIndex[i] + 1; j < arr.length; j++) {
511
- const subset = [...current[i], arr[j]];
512
- result.push(subset);
513
- if (j < arr.length - 1) {
514
- next.push(subset);
515
- nextMaxIndex.push(j);
516
- }
517
- }
518
- }
519
- current = next;
520
- maxIndex = nextMaxIndex;
521
- }
522
- return result;
523
- }
524
- function contains(setData, element) {
525
- let left = 0;
526
- let right = setData.length - 1;
527
- while (left <= right) {
528
- const mid = Math.floor((left + right) / 2);
529
- const cmp = compare(setData[mid], element);
530
- if (cmp === 0) {
531
- return true;
532
- } else if (cmp < 0) {
533
- left = mid + 1;
534
- } else {
535
- right = mid - 1;
536
- }
537
- }
538
- return false;
539
- }
540
- function isSubsetOrEq(a, b) {
541
- let i = 0, j = 0;
542
- while (i < a.length && j < b.length) {
543
- const cmp = compare(a[i], b[j]);
544
- if (cmp === 0) {
545
- i++;
546
- j++;
547
- } else if (cmp > 0) {
548
- j++;
549
- } else {
550
- return false;
551
- }
552
- }
553
- return i === a.length;
554
- }
555
- function reduce(target) {
556
- const result = [];
557
- for (const element of target) {
558
- result.push(...element);
559
- }
560
- return set(result);
561
- }
562
- function setUnion(set1, set2) {
563
- const result = [];
564
- let i = 0, j = 0;
565
- while (i < set1.length && j < set2.length) {
566
- const cmp = compare(set1[i], set2[j]);
567
- if (cmp < 0) {
568
- result.push(set1[i]);
569
- i++;
570
- } else if (cmp > 0) {
571
- result.push(set2[j]);
572
- j++;
573
- } else {
574
- result.push(set1[i]);
575
- i++;
576
- j++;
577
- }
578
- }
579
- while (i < set1.length) {
580
- result.push(set1[i]);
581
- i++;
582
- }
583
- while (j < set2.length) {
584
- result.push(set2[j]);
585
- j++;
586
- }
587
- return result;
588
- }
589
- function setIntersection(set1, set2) {
590
- const result = [];
591
- for (let i = 0, j = 0; i < set1.length && j < set2.length; ) {
592
- const cmp = compare(set1[i], set2[j]);
593
- if (cmp < 0) {
594
- i++;
595
- } else if (cmp > 0) {
596
- j++;
597
- } else {
598
- result.push(set1[i]);
599
- i++;
600
- j++;
601
- }
602
- }
603
- return result;
604
- }
605
- function setDiff(set1, set2) {
606
- const result = [];
607
- let i = 0, j = 0;
608
- while (i < set1.length && j < set2.length) {
609
- const cmp = compare(set1[i], set2[j]);
610
- if (cmp < 0) {
611
- result.push(set1[i]);
612
- i++;
613
- } else if (cmp > 0) {
614
- j++;
615
- } else {
616
- i++;
617
- j++;
618
- }
619
- }
620
- while (i < set1.length) {
621
- result.push(set1[i]);
622
- i++;
623
- }
624
- return result;
625
- }
626
- function setSymDiff(set1, set2) {
627
- const result = [];
628
- let i = 0, j = 0;
629
- while (i < set1.length && j < set2.length) {
630
- const cmp = compare(set1[i], set2[j]);
631
- if (cmp < 0) {
632
- result.push(set1[i]);
633
- i++;
634
- } else if (cmp > 0) {
635
- result.push(set2[j]);
636
- j++;
637
- } else {
638
- i++;
639
- j++;
640
- }
641
- }
642
- while (i < set1.length) {
643
- result.push(set1[i]);
644
- i++;
645
- }
646
- while (j < set2.length) {
647
- result.push(set2[j]);
648
- j++;
649
- }
650
- return result;
651
- }
652
- function projection(target, indices) {
653
- const projectedElements = target.map((element) => {
654
- const newComponents = indices.map((idx) => element[idx]);
655
- return indices.length === 1 ? newComponents[0] : tuple(newComponents);
656
- });
657
- return set(projectedElements);
658
- }
659
- function printValue(data) {
660
- if (!Array.isArray(data)) {
661
- return String(data);
662
- }
663
- const len = data.length;
664
- if (data.length === 0) {
665
- return "{}";
666
- }
667
- const isTuple = data[0] === TUPLE_ID;
668
- const start = isTuple ? 1 : 0;
669
- let result = isTuple ? "(" : "{";
670
- for (let i = start; i < len; i++) {
671
- if (i > start) result += ", ";
672
- result += printValue(data[i]);
673
- }
674
- result += isTuple ? ")" : "}";
675
- return result;
676
- }
677
-
678
- // src/rslang/eval/value.ts
679
- var TUPLE_ID = -111;
680
- var VALUE_TRUE = 1;
681
- var VALUE_FALSE = 0;
682
- var SET_INFINITY = 1e7;
683
- var BOOL_INFINITY = 18;
684
- var EmptySetV = [];
685
- function compare(v1, v2) {
686
- const stack1 = [v1];
687
- const stack2 = [v2];
688
- while (stack1.length > 0 && stack2.length > 0) {
689
- const el1 = stack1.pop();
690
- const el2 = stack2.pop();
691
- if (el1 === el2) {
692
- continue;
693
- }
694
- const type1 = typeof el1;
695
- const type2 = typeof el2;
696
- if (type1 === "number" && type2 === "number") {
697
- const numDiff = el1 - el2;
698
- if (numDiff !== 0) return numDiff;
699
- continue;
700
- }
701
- const isArray1 = Array.isArray(el1);
702
- const isArray2 = Array.isArray(el2);
703
- if (!isArray1 || !isArray2) {
704
- throw new Error(`Cannot compare different types ${printValue(el1)} and ${printValue(el2)}`);
705
- }
706
- const arr1 = el1;
707
- const arr2 = el2;
708
- const len1 = arr1.length;
709
- const len2 = arr2.length;
710
- if (len1 !== len2) {
711
- return len1 - len2;
712
- }
713
- for (let i = len1 - 1; i >= 0; i--) {
714
- stack1.push(arr1[i]);
715
- stack2.push(arr2[i]);
716
- }
717
- }
718
- return 0;
719
- }
720
- function tuple(components) {
721
- return [TUPLE_ID, ...components];
722
- }
723
- function set(elements) {
724
- const sorted = [...elements].sort(compare);
725
- for (let i = 1; i < sorted.length; ) {
726
- if (compare(sorted[i - 1], sorted[i]) === 0) {
727
- sorted.splice(i, 1);
728
- } else {
729
- i++;
730
- }
731
- }
732
- return sorted;
733
- }
734
-
735
- // src/rslang/eval/evaluator.ts
736
- var MAX_ITERATIONS = 1e6;
737
- var TICK_PER_FUNCTION = 3;
738
- var TICK_PER_RECURSION = 3;
739
- var TICK_PER_IMPERATIVE = 1;
740
- var TICK_PER_DECLARATIVE = 1;
741
- var TICK_PER_QUANTIFIER = 1;
1
+ import { annotateError } from "../ast-annotations.js";
2
+ import { RSErrorCode } from "../error.js";
3
+ import { getNodeIndices, getNodeText } from "../../parsing/ast.js";
4
+ import "../../parsing/index.js";
5
+ import { TokenID } from "../parser/token.js";
6
+ import { EvaluationCache, EvaluationMetadata } from "./evaluation-cache.js";
7
+ import { C as projection, E as setIntersection, O as setSymDiff, T as setDiff, c as compare, d as tuple, f as boolean, i as SET_INFINITY, k as setUnion, m as contains, n as EmptySetV, p as cartesianProduct, u as set, v as isSubsetOrEq, w as reduce } from "../../value-B8UtCqaK.js";
8
+ //#region src/rslang/eval/evaluator.ts
9
+ /**
10
+ * Module: AST evaluation - visitor-pattern evaluator for RS expressions.
11
+ */
12
+ /** Maximum iterations to prevent infinite loops (recursion, quantifiers, etc.). */
13
+ const MAX_ITERATIONS = 1e6;
14
+ const TICK_PER_FUNCTION = 3;
15
+ const TICK_PER_RECURSION = 3;
16
+ const TICK_PER_IMPERATIVE = 1;
17
+ const TICK_PER_DECLARATIVE = 1;
18
+ const TICK_PER_QUANTIFIER = 1;
19
+ /** AST calculator - evaluates RS expressions via visitor pattern and provides updates via listeners.
20
+ * Not safe for concurrent {@link run} calls on the same instance; use separate evaluators instead. */
742
21
  var Evaluator = class {
743
- reporter;
744
- annotateErrors = false;
745
- disableCache = false;
746
- locals = new LocalContext();
747
- nodeMetadata = new EvaluationMetadata();
748
- evalCache = new EvaluationCache();
749
- callSiteStack = [];
750
- context;
751
- treeContext;
752
- iterationCounter = 0;
753
- /** Cache hits in the current evaluation run (for tests/diagnostics). */
754
- get cacheHits() {
755
- return this.evalCache.hits;
756
- }
757
- constructor(context, astContext) {
758
- this.treeContext = astContext;
759
- this.context = context;
760
- }
761
- run(ast, reporter, annotateErrors = false, disableCache = false) {
762
- if (ast.hasError) {
763
- return null;
764
- }
765
- this.reporter = reporter;
766
- this.annotateErrors = annotateErrors;
767
- this.disableCache = disableCache;
768
- this.clear();
769
- return this.dispatchVisit(ast);
770
- }
771
- clear() {
772
- this.locals = new LocalContext();
773
- this.evalCache.clear();
774
- this.callSiteStack = [];
775
- this.iterationCounter = 0;
776
- }
777
- errorNode(node) {
778
- if (this.callSiteStack.length > 0) {
779
- return this.callSiteStack[this.callSiteStack.length - 1];
780
- }
781
- return node;
782
- }
783
- onError(code, node, params) {
784
- const target = this.errorNode(node);
785
- this.reporter?.({ code, from: target.from, to: target.to, params });
786
- if (this.annotateErrors) {
787
- annotateError(target, code, params);
788
- }
789
- return null;
790
- }
791
- tick(node, counter = 1) {
792
- this.iterationCounter += counter;
793
- if (this.iterationCounter > MAX_ITERATIONS) {
794
- this.onError(RSErrorCode.iterationsLimit, node, [String(MAX_ITERATIONS)]);
795
- return false;
796
- }
797
- return true;
798
- }
799
- dispatchDeclare(node, value) {
800
- switch (node.typeID) {
801
- case TokenID.ID_LOCAL:
802
- return this.declareLocal(node, value);
803
- case TokenID.NT_TUPLE_DECL:
804
- return this.declareTuple(node, value);
805
- case TokenID.NT_ARG_DECL:
806
- return this.dispatchDeclare(node.children[0], value);
807
- }
808
- }
809
- declareLocal(node, value) {
810
- const alias = getNodeText(node);
811
- this.locals.setLocal(alias, value);
812
- }
813
- declareTuple(node, value) {
814
- for (let child = 0; child < node.children.length; child++) {
815
- this.dispatchDeclare(node.children[child], value[child + 1]);
816
- }
817
- }
818
- dispatchVisit(node) {
819
- const info = this.nodeMetadata.get(node);
820
- let stamp = null;
821
- if (info.cacheable && !this.disableCache) {
822
- stamp = this.locals.buildDependencyStamp(info.reads);
823
- if (stamp !== null) {
824
- const cached = this.evalCache.lookup(info.structuralKey, stamp);
825
- if (cached !== void 0) {
826
- return cached;
827
- }
828
- }
829
- }
830
- const result = this.dispatchVisitImpl(node);
831
- if (!this.disableCache && result !== null && info.cacheable && stamp !== null) {
832
- this.evalCache.store(info.structuralKey, stamp, result);
833
- }
834
- return result;
835
- }
836
- dispatchVisitImpl(node) {
837
- switch (node.typeID) {
838
- case TokenID.ID_GLOBAL:
839
- return this.visitGlobal(node);
840
- case TokenID.NT_FUNC_CALL:
841
- return this.visitFunctionCall(node);
842
- case TokenID.ID_LOCAL:
843
- case TokenID.ID_RADICAL:
844
- return this.visitLocal(node);
845
- case TokenID.LIT_INTEGER:
846
- return this.visitInteger(node);
847
- case TokenID.LIT_WHOLE_NUMBERS:
848
- return this.onError(RSErrorCode.iterateInfinity, node);
849
- case TokenID.LIT_EMPTYSET:
850
- return EmptySetV;
851
- case TokenID.PLUS:
852
- case TokenID.MINUS:
853
- case TokenID.MULTIPLY:
854
- return this.visitArithmetic(node);
855
- case TokenID.CARD:
856
- return this.visitCard(node);
857
- case TokenID.QUANTOR_UNIVERSAL:
858
- case TokenID.QUANTOR_EXISTS:
859
- return this.visitQuantifier(node);
860
- case TokenID.LOGIC_NOT:
861
- return this.visitNegation(node);
862
- case TokenID.LOGIC_AND:
863
- case TokenID.LOGIC_OR:
864
- case TokenID.LOGIC_IMPLICATION:
865
- case TokenID.LOGIC_EQUIVALENT:
866
- return this.visitLogicBinary(node);
867
- case TokenID.EQUAL:
868
- case TokenID.NOTEQUAL:
869
- return this.visitEquals(node);
870
- case TokenID.GREATER:
871
- case TokenID.LESSER:
872
- case TokenID.GREATER_OR_EQ:
873
- case TokenID.LESSER_OR_EQ:
874
- return this.visitIntegerPredicate(node);
875
- case TokenID.SET_IN:
876
- case TokenID.SET_NOT_IN:
877
- case TokenID.SUBSET:
878
- case TokenID.SUBSET_OR_EQ:
879
- case TokenID.NOT_SUBSET:
880
- return this.visitSetexprPredicate(node);
881
- case TokenID.DECART:
882
- return this.visitDecart(node);
883
- case TokenID.BOOLEAN:
884
- return this.visitBoolean(node);
885
- case TokenID.NT_TUPLE:
886
- return this.visitTuple(node);
887
- case TokenID.NT_ENUMERATION:
888
- return this.visitEnumeration(node);
889
- case TokenID.BOOL:
890
- return this.visitBool(node);
891
- case TokenID.DEBOOL:
892
- return this.visitDebool(node);
893
- case TokenID.SET_UNION:
894
- case TokenID.SET_INTERSECTION:
895
- case TokenID.SET_MINUS:
896
- case TokenID.SET_SYMMETRIC_MINUS:
897
- return this.visitSetexprBinary(node);
898
- case TokenID.BIGPR:
899
- return this.visitProjectSet(node);
900
- case TokenID.SMALLPR:
901
- return this.visitProjectTuple(node);
902
- case TokenID.FILTER:
903
- return this.visitFilter(node);
904
- case TokenID.REDUCE:
905
- return this.visitReduce(node);
906
- case TokenID.NT_DECLARATIVE_EXPR:
907
- return this.visitDeclarative(node);
908
- case TokenID.NT_IMPERATIVE_EXPR:
909
- return this.visitImperative(node);
910
- case TokenID.ASSIGN:
911
- return this.visitAssign(node);
912
- case TokenID.NT_RECURSIVE_FULL:
913
- case TokenID.NT_RECURSIVE_SHORT:
914
- return this.visitRecursion(node);
915
- case TokenID.NT_FUNC_DEFINITION:
916
- return this.onError(RSErrorCode.calculationNotSupported, node);
917
- }
918
- return null;
919
- }
920
- visitChild(node, index) {
921
- return this.dispatchVisit(node.children[index]);
922
- }
923
- visitGlobal(node) {
924
- const alias = getNodeText(node);
925
- const value = this.context.get(alias);
926
- if (value === void 0) {
927
- return this.onError(RSErrorCode.calcGlobalMissing, node, [alias]);
928
- }
929
- return value;
930
- }
931
- visitLocal(node) {
932
- const alias = getNodeText(node);
933
- return this.locals.getLocal(alias);
934
- }
935
- visitFunctionCall(node) {
936
- const funcName = getNodeText(node.children[0]);
937
- const ast = this.treeContext.get(funcName);
938
- if (!ast) {
939
- return this.onError(RSErrorCode.calcGlobalMissing, node.children[0], [funcName]);
940
- }
941
- if (!this.tick(node, TICK_PER_FUNCTION)) {
942
- return null;
943
- }
944
- const args = [];
945
- for (let i = 1; i < node.children.length; i++) {
946
- const arg = this.visitChild(node, i);
947
- if (arg === null) {
948
- return null;
949
- }
950
- args.push(arg);
951
- }
952
- this.locals.startScope();
953
- for (let i = 0; i < args.length; i++) {
954
- this.dispatchDeclare(ast.children[0].children[i], args[i]);
955
- }
956
- this.callSiteStack.push(node);
957
- let result;
958
- try {
959
- result = this.visitChild(ast, 1);
960
- } finally {
961
- this.callSiteStack.pop();
962
- }
963
- this.locals.endScope();
964
- return result;
965
- }
966
- visitInteger(node) {
967
- const value = node.data.dataType === "number" ? node.data.value : Number(node.data.value);
968
- return Math.floor(value);
969
- }
970
- visitArithmetic(node) {
971
- const v1 = this.visitChild(node, 0);
972
- const v2 = this.visitChild(node, 1);
973
- if (v1 === null || v2 === null) {
974
- return null;
975
- }
976
- const a = v1;
977
- const b = v2;
978
- switch (node.typeID) {
979
- case TokenID.PLUS:
980
- return a + b;
981
- case TokenID.MINUS:
982
- return a - b;
983
- case TokenID.MULTIPLY:
984
- return a * b;
985
- }
986
- return null;
987
- }
988
- visitCard(node) {
989
- const base = this.visitChild(node, 0);
990
- if (base === null || !Array.isArray(base)) {
991
- return null;
992
- }
993
- return base.length;
994
- }
995
- visitQuantifier(node) {
996
- const domain = this.visitChild(node, 1);
997
- if (domain === null) {
998
- return null;
999
- }
1000
- const isUniversal = node.typeID === TokenID.QUANTOR_UNIVERSAL;
1001
- if (domain.length === 0) {
1002
- return isUniversal ? VALUE_TRUE : VALUE_FALSE;
1003
- }
1004
- const varNodes = node.children[0].typeID === TokenID.NT_ENUM_DECL ? node.children[0].children : [node.children[0]];
1005
- const count = domain.length;
1006
- const iterators = [];
1007
- for (const declaration of varNodes) {
1008
- iterators.push(0);
1009
- this.dispatchDeclare(declaration, domain[0]);
1010
- }
1011
- let finishIteration = false;
1012
- while (!finishIteration) {
1013
- const iterationValue = this.visitChild(node, 2);
1014
- if (iterationValue === null) {
1015
- return null;
1016
- }
1017
- if (iterationValue === VALUE_TRUE !== isUniversal) {
1018
- return !isUniversal ? VALUE_TRUE : VALUE_FALSE;
1019
- }
1020
- let incrementIndex = iterators.length - 1;
1021
- while (true) {
1022
- if (iterators[incrementIndex] < count - 1) {
1023
- iterators[incrementIndex]++;
1024
- if (!this.tick(node, TICK_PER_QUANTIFIER)) {
1025
- return null;
1026
- }
1027
- this.dispatchDeclare(varNodes[incrementIndex], domain[iterators[incrementIndex]]);
1028
- incrementIndex = iterators.length - 1;
1029
- break;
1030
- } else if (incrementIndex === 0) {
1031
- finishIteration = true;
1032
- break;
1033
- } else {
1034
- iterators[incrementIndex] = 0;
1035
- this.dispatchDeclare(varNodes[incrementIndex], domain[0]);
1036
- incrementIndex--;
1037
- }
1038
- }
1039
- }
1040
- return isUniversal ? VALUE_TRUE : VALUE_FALSE;
1041
- }
1042
- visitNegation(node) {
1043
- const value = this.visitChild(node, 0);
1044
- if (value === null) {
1045
- return null;
1046
- }
1047
- return value === VALUE_TRUE ? VALUE_FALSE : VALUE_TRUE;
1048
- }
1049
- tryEvaluateFromFirstArg(op, first) {
1050
- if (op === TokenID.LOGIC_AND && !first || op === TokenID.LOGIC_OR && first) {
1051
- return first ? VALUE_TRUE : VALUE_FALSE;
1052
- }
1053
- if (op === TokenID.LOGIC_IMPLICATION && !first) {
1054
- return VALUE_TRUE;
1055
- }
1056
- return null;
1057
- }
1058
- visitLogicBinary(node) {
1059
- const v1 = this.visitChild(node, 0);
1060
- if (v1 === null) {
1061
- return null;
1062
- }
1063
- const b1 = v1 === VALUE_TRUE;
1064
- const attempt = this.tryEvaluateFromFirstArg(node.typeID, b1);
1065
- if (attempt !== null) {
1066
- return attempt;
1067
- }
1068
- const v2 = this.visitChild(node, 1);
1069
- if (v2 === null) {
1070
- return null;
1071
- }
1072
- const b2 = v2 === VALUE_TRUE;
1073
- let result;
1074
- switch (node.typeID) {
1075
- case TokenID.LOGIC_AND:
1076
- result = b1 && b2;
1077
- break;
1078
- case TokenID.LOGIC_OR:
1079
- result = b1 || b2;
1080
- break;
1081
- case TokenID.LOGIC_IMPLICATION:
1082
- result = !b1 || b2;
1083
- break;
1084
- case TokenID.LOGIC_EQUIVALENT:
1085
- result = b1 === b2;
1086
- break;
1087
- default:
1088
- return null;
1089
- }
1090
- return result ? VALUE_TRUE : VALUE_FALSE;
1091
- }
1092
- visitEquals(node) {
1093
- const v1 = this.visitChild(node, 0);
1094
- if (v1 === null) {
1095
- return null;
1096
- }
1097
- const v2 = this.visitChild(node, 1);
1098
- if (v2 === null) {
1099
- return null;
1100
- }
1101
- const areEqual = compare(v1, v2) === 0;
1102
- return areEqual === (node.typeID !== TokenID.NOTEQUAL) ? VALUE_TRUE : VALUE_FALSE;
1103
- }
1104
- visitIntegerPredicate(node) {
1105
- const v1 = this.visitChild(node, 0);
1106
- if (v1 === null) {
1107
- return null;
1108
- }
1109
- const v2 = this.visitChild(node, 1);
1110
- if (v2 === null) {
1111
- return null;
1112
- }
1113
- const a = v1;
1114
- const b = v2;
1115
- let result;
1116
- switch (node.typeID) {
1117
- case TokenID.GREATER:
1118
- result = a > b;
1119
- break;
1120
- case TokenID.LESSER:
1121
- result = a < b;
1122
- break;
1123
- case TokenID.GREATER_OR_EQ:
1124
- result = a >= b;
1125
- break;
1126
- case TokenID.LESSER_OR_EQ:
1127
- result = a <= b;
1128
- break;
1129
- default:
1130
- return null;
1131
- }
1132
- return result ? VALUE_TRUE : VALUE_FALSE;
1133
- }
1134
- visitSetexprPredicate(node) {
1135
- const v1 = this.visitChild(node, 0);
1136
- if (v1 === null) {
1137
- return null;
1138
- }
1139
- const v2 = this.visitChild(node, 1);
1140
- if (v2 === null) {
1141
- return null;
1142
- }
1143
- let result;
1144
- switch (node.typeID) {
1145
- case TokenID.SET_IN:
1146
- result = contains(v2, v1);
1147
- break;
1148
- case TokenID.SET_NOT_IN:
1149
- result = !contains(v2, v1);
1150
- break;
1151
- case TokenID.SUBSET:
1152
- result = compare(v1, v2) !== 0 && isSubsetOrEq(v1, v2);
1153
- break;
1154
- case TokenID.NOT_SUBSET:
1155
- result = compare(v1, v2) === 0 || !isSubsetOrEq(v1, v2);
1156
- break;
1157
- case TokenID.SUBSET_OR_EQ:
1158
- result = isSubsetOrEq(v1, v2);
1159
- break;
1160
- default:
1161
- return null;
1162
- }
1163
- return result ? VALUE_TRUE : VALUE_FALSE;
1164
- }
1165
- visitDecart(node) {
1166
- const args = [];
1167
- for (let i = 0; i < node.children.length; i++) {
1168
- const component = this.visitChild(node, i);
1169
- if (component === null) {
1170
- return null;
1171
- }
1172
- if (component.length === 0) {
1173
- return EmptySetV;
1174
- }
1175
- args.push(component);
1176
- }
1177
- const result = cartesianProduct(args);
1178
- if (result === null) {
1179
- this.onError(RSErrorCode.setOverflow, node, [String(SET_INFINITY)]);
1180
- return null;
1181
- }
1182
- return result;
1183
- }
1184
- visitBoolean(node) {
1185
- const base = this.visitChild(node, 0);
1186
- if (base === null) {
1187
- return null;
1188
- }
1189
- const result = boolean(base);
1190
- if (result === null) {
1191
- this.onError(RSErrorCode.booleanBaseLimit, node.children[0], [String(BOOL_INFINITY)]);
1192
- return null;
1193
- }
1194
- return result;
1195
- }
1196
- visitTuple(node) {
1197
- const args = [];
1198
- for (let i = 0; i < node.children.length; i++) {
1199
- const component = this.visitChild(node, i);
1200
- if (component === null) {
1201
- return null;
1202
- }
1203
- args.push(component);
1204
- }
1205
- return tuple(args);
1206
- }
1207
- visitEnumeration(node) {
1208
- const args = [];
1209
- for (let i = 0; i < node.children.length; i++) {
1210
- const element = this.visitChild(node, i);
1211
- if (element === null) {
1212
- return null;
1213
- }
1214
- args.push(element);
1215
- }
1216
- return set(args);
1217
- }
1218
- visitBool(node) {
1219
- const element = this.visitChild(node, 0);
1220
- if (element === null) {
1221
- return null;
1222
- }
1223
- return [element];
1224
- }
1225
- visitDebool(node) {
1226
- const target = this.visitChild(node, 0);
1227
- if (target === null) {
1228
- return null;
1229
- }
1230
- if (target.length !== 1) {
1231
- return this.onError(RSErrorCode.calcInvalidDebool, node.children[0]);
1232
- }
1233
- return target[0];
1234
- }
1235
- visitSetexprBinary(node) {
1236
- const v1 = this.visitChild(node, 0);
1237
- if (v1 === null) {
1238
- return null;
1239
- }
1240
- const v2 = this.visitChild(node, 1);
1241
- if (v2 === null) {
1242
- return null;
1243
- }
1244
- switch (node.typeID) {
1245
- case TokenID.SET_UNION:
1246
- return setUnion(v1, v2);
1247
- case TokenID.SET_INTERSECTION:
1248
- return setIntersection(v1, v2);
1249
- case TokenID.SET_MINUS:
1250
- return setDiff(v1, v2);
1251
- case TokenID.SET_SYMMETRIC_MINUS:
1252
- return setSymDiff(v1, v2);
1253
- }
1254
- return null;
1255
- }
1256
- visitProjectSet(node) {
1257
- const target = this.visitChild(node, 0);
1258
- if (target === null) {
1259
- return null;
1260
- }
1261
- const indices = getNodeIndices(node);
1262
- return projection(target, indices);
1263
- }
1264
- visitProjectTuple(node) {
1265
- const target = this.visitChild(node, 0);
1266
- if (target === null) {
1267
- return null;
1268
- }
1269
- const indices = getNodeIndices(node);
1270
- const components = indices.map((i) => target[i]);
1271
- return components.length === 1 ? components[0] : tuple(components);
1272
- }
1273
- visitFilter(node) {
1274
- const lastIdx = node.children.length - 1;
1275
- const argVal = this.visitChild(node, lastIdx);
1276
- if (argVal === null) {
1277
- return null;
1278
- }
1279
- if (argVal.length === 0) {
1280
- return EmptySetV;
1281
- }
1282
- const indices = getNodeIndices(node);
1283
- const tupleParam = indices.length === lastIdx;
1284
- if (tupleParam) {
1285
- const params = [];
1286
- for (let i = 0; i < lastIdx; i++) {
1287
- const param = this.visitChild(node, i);
1288
- if (param === null) {
1289
- return null;
1290
- }
1291
- if (param.length === 0) {
1292
- return EmptySetV;
1293
- }
1294
- params.push(param);
1295
- }
1296
- const result = [];
1297
- for (const element of argVal) {
1298
- let valid = true;
1299
- for (let j = 0; j < indices.length; j++) {
1300
- const comp = element[indices[j]];
1301
- const paramSet = params[j];
1302
- if (!contains(paramSet, comp)) {
1303
- valid = false;
1304
- break;
1305
- }
1306
- }
1307
- if (valid) {
1308
- result.push(element);
1309
- }
1310
- }
1311
- return result;
1312
- } else {
1313
- const paramVal = this.visitChild(node, 0);
1314
- if (paramVal === null) {
1315
- return null;
1316
- }
1317
- if (paramVal.length === 0) {
1318
- return EmptySetV;
1319
- }
1320
- const result = [];
1321
- for (const element of argVal) {
1322
- const comps = indices.map((i) => element[i]);
1323
- const testElement = comps.length === 1 ? comps[0] : tuple(comps);
1324
- if (contains(paramVal, testElement)) result.push(element);
1325
- }
1326
- return result;
1327
- }
1328
- }
1329
- visitReduce(node) {
1330
- const target = this.visitChild(node, 0);
1331
- if (target === null) {
1332
- return null;
1333
- }
1334
- return reduce(target);
1335
- }
1336
- visitDeclarative(node) {
1337
- const domain = this.visitChild(node, 1);
1338
- if (domain === null) {
1339
- return null;
1340
- }
1341
- const elements = [];
1342
- for (const element of domain) {
1343
- if (!this.tick(node, TICK_PER_DECLARATIVE)) {
1344
- return null;
1345
- }
1346
- this.dispatchDeclare(node.children[0], element);
1347
- const value = this.visitChild(node, 2);
1348
- if (value === null) {
1349
- return null;
1350
- }
1351
- if (value === VALUE_TRUE) {
1352
- elements.push(element);
1353
- }
1354
- }
1355
- return elements.length === 0 ? EmptySetV : elements;
1356
- }
1357
- visitImperative(node) {
1358
- const result = [];
1359
- const frames = [];
1360
- let currentChild = 1;
1361
- const advanceIterator = () => {
1362
- while (frames.length > 0) {
1363
- const top = frames[frames.length - 1];
1364
- if (top.valueID < top.domain.length - 1) {
1365
- top.valueID++;
1366
- const nextValue = top.domain[top.valueID];
1367
- if (!this.tick(node.children[top.childID], TICK_PER_IMPERATIVE)) {
1368
- return false;
1369
- }
1370
- this.dispatchDeclare(node.children[top.childID].children[0], nextValue);
1371
- currentChild = top.childID + 1;
1372
- return true;
1373
- }
1374
- frames.pop();
1375
- }
1376
- return false;
1377
- };
1378
- while (true) {
1379
- if (currentChild >= node.children.length) {
1380
- const element = this.visitChild(node, 0);
1381
- if (element === null) {
1382
- return null;
1383
- }
1384
- result.push(element);
1385
- if (!advanceIterator()) {
1386
- break;
1387
- }
1388
- continue;
1389
- }
1390
- const child = node.children[currentChild];
1391
- if (child.typeID === TokenID.ITERATE) {
1392
- const domain = this.visitChild(child, 1);
1393
- if (domain === null) {
1394
- return null;
1395
- }
1396
- if (domain.length === 0) {
1397
- if (!advanceIterator()) {
1398
- break;
1399
- }
1400
- continue;
1401
- }
1402
- if (!this.tick(child, TICK_PER_IMPERATIVE)) {
1403
- return null;
1404
- }
1405
- frames.push({
1406
- childID: currentChild,
1407
- domain,
1408
- valueID: 0
1409
- });
1410
- this.dispatchDeclare(child.children[0], domain[0]);
1411
- currentChild++;
1412
- continue;
1413
- }
1414
- const value = this.dispatchVisit(child);
1415
- if (value === null) {
1416
- return null;
1417
- }
1418
- if (value === VALUE_FALSE) {
1419
- if (!advanceIterator()) {
1420
- break;
1421
- }
1422
- continue;
1423
- }
1424
- currentChild++;
1425
- }
1426
- return set(result);
1427
- }
1428
- visitAssign(node) {
1429
- const value = this.visitChild(node, 1);
1430
- if (value === null) {
1431
- return null;
1432
- }
1433
- this.dispatchDeclare(node.children[0], value);
1434
- return VALUE_TRUE;
1435
- }
1436
- visitRecursion(node) {
1437
- const initialValue = this.visitChild(node, 1);
1438
- if (initialValue === null) {
1439
- return null;
1440
- }
1441
- const bodyIndex = node.typeID === TokenID.NT_RECURSIVE_FULL ? 3 : 2;
1442
- let current = initialValue;
1443
- while (true) {
1444
- if (!this.tick(node, TICK_PER_RECURSION)) {
1445
- return null;
1446
- }
1447
- this.dispatchDeclare(node.children[0], current);
1448
- if (node.typeID === TokenID.NT_RECURSIVE_FULL) {
1449
- const pred = this.visitChild(node, 2);
1450
- if (pred === null) {
1451
- return null;
1452
- }
1453
- if (pred !== VALUE_TRUE) {
1454
- break;
1455
- }
1456
- }
1457
- const next = this.visitChild(node, bodyIndex);
1458
- if (next === null) {
1459
- return null;
1460
- }
1461
- if (compare(current, next) === 0) {
1462
- break;
1463
- }
1464
- current = next;
1465
- }
1466
- return current;
1467
- }
22
+ reporter;
23
+ annotateErrors = false;
24
+ disableCache = false;
25
+ locals = new LocalContext();
26
+ nodeMetadata = new EvaluationMetadata();
27
+ evalCache = new EvaluationCache();
28
+ callSiteStack = [];
29
+ context;
30
+ treeContext;
31
+ iterationCounter = 0;
32
+ /** Cache hits in the current evaluation run (for tests/diagnostics). */
33
+ get cacheHits() {
34
+ return this.evalCache.hits;
35
+ }
36
+ constructor(context, astContext) {
37
+ this.treeContext = astContext;
38
+ this.context = context;
39
+ }
40
+ run(ast, reporter, annotateErrors = false, disableCache = false) {
41
+ if (ast.hasError) return null;
42
+ this.reporter = reporter;
43
+ this.annotateErrors = annotateErrors;
44
+ this.disableCache = disableCache;
45
+ this.clear();
46
+ return this.dispatchVisit(ast);
47
+ }
48
+ clear() {
49
+ this.locals = new LocalContext();
50
+ this.evalCache.clear();
51
+ this.callSiteStack = [];
52
+ this.iterationCounter = 0;
53
+ }
54
+ errorNode(node) {
55
+ if (this.callSiteStack.length > 0) return this.callSiteStack[this.callSiteStack.length - 1];
56
+ return node;
57
+ }
58
+ onError(code, node, params) {
59
+ const target = this.errorNode(node);
60
+ this.reporter?.({
61
+ code,
62
+ from: target.from,
63
+ to: target.to,
64
+ params
65
+ });
66
+ if (this.annotateErrors) annotateError(target, code, params);
67
+ return null;
68
+ }
69
+ tick(node, counter = 1) {
70
+ this.iterationCounter += counter;
71
+ if (this.iterationCounter > MAX_ITERATIONS) {
72
+ this.onError(RSErrorCode.iterationsLimit, node, [String(MAX_ITERATIONS)]);
73
+ return false;
74
+ }
75
+ return true;
76
+ }
77
+ dispatchDeclare(node, value) {
78
+ switch (node.typeID) {
79
+ case TokenID.ID_LOCAL: return this.declareLocal(node, value);
80
+ case TokenID.NT_TUPLE_DECL: return this.declareTuple(node, value);
81
+ case TokenID.NT_ARG_DECL: return this.dispatchDeclare(node.children[0], value);
82
+ }
83
+ }
84
+ declareLocal(node, value) {
85
+ const alias = getNodeText(node);
86
+ this.locals.setLocal(alias, value);
87
+ }
88
+ declareTuple(node, value) {
89
+ for (let child = 0; child < node.children.length; child++) this.dispatchDeclare(node.children[child], value[child + 1]);
90
+ }
91
+ dispatchVisit(node) {
92
+ const info = this.nodeMetadata.get(node);
93
+ let stamp = null;
94
+ if (info.cacheable && !this.disableCache) {
95
+ stamp = this.locals.buildDependencyStamp(info.reads);
96
+ if (stamp !== null) {
97
+ const cached = this.evalCache.lookup(info.structuralKey, stamp);
98
+ if (cached !== void 0) return cached;
99
+ }
100
+ }
101
+ const result = this.dispatchVisitImpl(node);
102
+ if (!this.disableCache && result !== null && info.cacheable && stamp !== null) this.evalCache.store(info.structuralKey, stamp, result);
103
+ return result;
104
+ }
105
+ dispatchVisitImpl(node) {
106
+ switch (node.typeID) {
107
+ case TokenID.ID_GLOBAL: return this.visitGlobal(node);
108
+ case TokenID.NT_FUNC_CALL: return this.visitFunctionCall(node);
109
+ case TokenID.ID_LOCAL:
110
+ case TokenID.ID_RADICAL: return this.visitLocal(node);
111
+ case TokenID.LIT_INTEGER: return this.visitInteger(node);
112
+ case TokenID.LIT_WHOLE_NUMBERS: return this.onError(RSErrorCode.iterateInfinity, node);
113
+ case TokenID.LIT_EMPTYSET: return EmptySetV;
114
+ case TokenID.PLUS:
115
+ case TokenID.MINUS:
116
+ case TokenID.MULTIPLY: return this.visitArithmetic(node);
117
+ case TokenID.CARD: return this.visitCard(node);
118
+ case TokenID.QUANTOR_UNIVERSAL:
119
+ case TokenID.QUANTOR_EXISTS: return this.visitQuantifier(node);
120
+ case TokenID.LOGIC_NOT: return this.visitNegation(node);
121
+ case TokenID.LOGIC_AND:
122
+ case TokenID.LOGIC_OR:
123
+ case TokenID.LOGIC_IMPLICATION:
124
+ case TokenID.LOGIC_EQUIVALENT: return this.visitLogicBinary(node);
125
+ case TokenID.EQUAL:
126
+ case TokenID.NOTEQUAL: return this.visitEquals(node);
127
+ case TokenID.GREATER:
128
+ case TokenID.LESSER:
129
+ case TokenID.GREATER_OR_EQ:
130
+ case TokenID.LESSER_OR_EQ: return this.visitIntegerPredicate(node);
131
+ case TokenID.SET_IN:
132
+ case TokenID.SET_NOT_IN:
133
+ case TokenID.SUBSET:
134
+ case TokenID.SUBSET_OR_EQ:
135
+ case TokenID.NOT_SUBSET: return this.visitSetexprPredicate(node);
136
+ case TokenID.DECART: return this.visitDecart(node);
137
+ case TokenID.BOOLEAN: return this.visitBoolean(node);
138
+ case TokenID.NT_TUPLE: return this.visitTuple(node);
139
+ case TokenID.NT_ENUMERATION: return this.visitEnumeration(node);
140
+ case TokenID.BOOL: return this.visitBool(node);
141
+ case TokenID.DEBOOL: return this.visitDebool(node);
142
+ case TokenID.SET_UNION:
143
+ case TokenID.SET_INTERSECTION:
144
+ case TokenID.SET_MINUS:
145
+ case TokenID.SET_SYMMETRIC_MINUS: return this.visitSetexprBinary(node);
146
+ case TokenID.BIGPR: return this.visitProjectSet(node);
147
+ case TokenID.SMALLPR: return this.visitProjectTuple(node);
148
+ case TokenID.FILTER: return this.visitFilter(node);
149
+ case TokenID.REDUCE: return this.visitReduce(node);
150
+ case TokenID.NT_DECLARATIVE_EXPR: return this.visitDeclarative(node);
151
+ case TokenID.NT_IMPERATIVE_EXPR: return this.visitImperative(node);
152
+ case TokenID.ASSIGN: return this.visitAssign(node);
153
+ case TokenID.NT_RECURSIVE_FULL:
154
+ case TokenID.NT_RECURSIVE_SHORT: return this.visitRecursion(node);
155
+ case TokenID.NT_FUNC_DEFINITION: return this.onError(RSErrorCode.calculationNotSupported, node);
156
+ }
157
+ return null;
158
+ }
159
+ visitChild(node, index) {
160
+ return this.dispatchVisit(node.children[index]);
161
+ }
162
+ visitGlobal(node) {
163
+ const alias = getNodeText(node);
164
+ const value = this.context.get(alias);
165
+ if (value === void 0) return this.onError(RSErrorCode.calcGlobalMissing, node, [alias]);
166
+ return value;
167
+ }
168
+ visitLocal(node) {
169
+ const alias = getNodeText(node);
170
+ return this.locals.getLocal(alias);
171
+ }
172
+ visitFunctionCall(node) {
173
+ const funcName = getNodeText(node.children[0]);
174
+ const ast = this.treeContext.get(funcName);
175
+ if (!ast) return this.onError(RSErrorCode.calcGlobalMissing, node.children[0], [funcName]);
176
+ if (!this.tick(node, TICK_PER_FUNCTION)) return null;
177
+ const args = [];
178
+ for (let i = 1; i < node.children.length; i++) {
179
+ const arg = this.visitChild(node, i);
180
+ if (arg === null) return null;
181
+ args.push(arg);
182
+ }
183
+ this.locals.startScope();
184
+ for (let i = 0; i < args.length; i++) this.dispatchDeclare(ast.children[0].children[i], args[i]);
185
+ this.callSiteStack.push(node);
186
+ let result;
187
+ try {
188
+ result = this.visitChild(ast, 1);
189
+ } finally {
190
+ this.callSiteStack.pop();
191
+ }
192
+ this.locals.endScope();
193
+ return result;
194
+ }
195
+ visitInteger(node) {
196
+ const value = node.data.dataType === "number" ? node.data.value : Number(node.data.value);
197
+ return Math.floor(value);
198
+ }
199
+ visitArithmetic(node) {
200
+ const v1 = this.visitChild(node, 0);
201
+ const v2 = this.visitChild(node, 1);
202
+ if (v1 === null || v2 === null) return null;
203
+ const a = v1;
204
+ const b = v2;
205
+ switch (node.typeID) {
206
+ case TokenID.PLUS: return a + b;
207
+ case TokenID.MINUS: return a - b;
208
+ case TokenID.MULTIPLY: return a * b;
209
+ }
210
+ return null;
211
+ }
212
+ visitCard(node) {
213
+ const base = this.visitChild(node, 0);
214
+ if (base === null || !Array.isArray(base)) return null;
215
+ return base.length;
216
+ }
217
+ visitQuantifier(node) {
218
+ const domain = this.visitChild(node, 1);
219
+ if (domain === null) return null;
220
+ const isUniversal = node.typeID === TokenID.QUANTOR_UNIVERSAL;
221
+ if (domain.length === 0) return isUniversal ? 1 : 0;
222
+ const varNodes = node.children[0].typeID === TokenID.NT_ENUM_DECL ? node.children[0].children : [node.children[0]];
223
+ const count = domain.length;
224
+ const iterators = [];
225
+ for (const declaration of varNodes) {
226
+ iterators.push(0);
227
+ this.dispatchDeclare(declaration, domain[0]);
228
+ }
229
+ let finishIteration = false;
230
+ while (!finishIteration) {
231
+ const iterationValue = this.visitChild(node, 2);
232
+ if (iterationValue === null) return null;
233
+ if (iterationValue === 1 !== isUniversal) return !isUniversal ? 1 : 0;
234
+ let incrementIndex = iterators.length - 1;
235
+ while (true) if (iterators[incrementIndex] < count - 1) {
236
+ iterators[incrementIndex]++;
237
+ if (!this.tick(node, TICK_PER_QUANTIFIER)) return null;
238
+ this.dispatchDeclare(varNodes[incrementIndex], domain[iterators[incrementIndex]]);
239
+ incrementIndex = iterators.length - 1;
240
+ break;
241
+ } else if (incrementIndex === 0) {
242
+ finishIteration = true;
243
+ break;
244
+ } else {
245
+ iterators[incrementIndex] = 0;
246
+ this.dispatchDeclare(varNodes[incrementIndex], domain[0]);
247
+ incrementIndex--;
248
+ }
249
+ }
250
+ return isUniversal ? 1 : 0;
251
+ }
252
+ visitNegation(node) {
253
+ const value = this.visitChild(node, 0);
254
+ if (value === null) return null;
255
+ return value === 1 ? 0 : 1;
256
+ }
257
+ tryEvaluateFromFirstArg(op, first) {
258
+ if (op === TokenID.LOGIC_AND && !first || op === TokenID.LOGIC_OR && first) return first ? 1 : 0;
259
+ if (op === TokenID.LOGIC_IMPLICATION && !first) return 1;
260
+ return null;
261
+ }
262
+ visitLogicBinary(node) {
263
+ const v1 = this.visitChild(node, 0);
264
+ if (v1 === null) return null;
265
+ const b1 = v1 === 1;
266
+ const attempt = this.tryEvaluateFromFirstArg(node.typeID, b1);
267
+ if (attempt !== null) return attempt;
268
+ const v2 = this.visitChild(node, 1);
269
+ if (v2 === null) return null;
270
+ const b2 = v2 === 1;
271
+ let result;
272
+ switch (node.typeID) {
273
+ case TokenID.LOGIC_AND:
274
+ result = b1 && b2;
275
+ break;
276
+ case TokenID.LOGIC_OR:
277
+ result = b1 || b2;
278
+ break;
279
+ case TokenID.LOGIC_IMPLICATION:
280
+ result = !b1 || b2;
281
+ break;
282
+ case TokenID.LOGIC_EQUIVALENT:
283
+ result = b1 === b2;
284
+ break;
285
+ default: return null;
286
+ }
287
+ return result ? 1 : 0;
288
+ }
289
+ visitEquals(node) {
290
+ const v1 = this.visitChild(node, 0);
291
+ if (v1 === null) return null;
292
+ const v2 = this.visitChild(node, 1);
293
+ if (v2 === null) return null;
294
+ return compare(v1, v2) === 0 === (node.typeID !== TokenID.NOTEQUAL) ? 1 : 0;
295
+ }
296
+ visitIntegerPredicate(node) {
297
+ const v1 = this.visitChild(node, 0);
298
+ if (v1 === null) return null;
299
+ const v2 = this.visitChild(node, 1);
300
+ if (v2 === null) return null;
301
+ const a = v1;
302
+ const b = v2;
303
+ let result;
304
+ switch (node.typeID) {
305
+ case TokenID.GREATER:
306
+ result = a > b;
307
+ break;
308
+ case TokenID.LESSER:
309
+ result = a < b;
310
+ break;
311
+ case TokenID.GREATER_OR_EQ:
312
+ result = a >= b;
313
+ break;
314
+ case TokenID.LESSER_OR_EQ:
315
+ result = a <= b;
316
+ break;
317
+ default: return null;
318
+ }
319
+ return result ? 1 : 0;
320
+ }
321
+ visitSetexprPredicate(node) {
322
+ const v1 = this.visitChild(node, 0);
323
+ if (v1 === null) return null;
324
+ const v2 = this.visitChild(node, 1);
325
+ if (v2 === null) return null;
326
+ let result;
327
+ switch (node.typeID) {
328
+ case TokenID.SET_IN:
329
+ result = contains(v2, v1);
330
+ break;
331
+ case TokenID.SET_NOT_IN:
332
+ result = !contains(v2, v1);
333
+ break;
334
+ case TokenID.SUBSET:
335
+ result = compare(v1, v2) !== 0 && isSubsetOrEq(v1, v2);
336
+ break;
337
+ case TokenID.NOT_SUBSET:
338
+ result = compare(v1, v2) === 0 || !isSubsetOrEq(v1, v2);
339
+ break;
340
+ case TokenID.SUBSET_OR_EQ:
341
+ result = isSubsetOrEq(v1, v2);
342
+ break;
343
+ default: return null;
344
+ }
345
+ return result ? 1 : 0;
346
+ }
347
+ visitDecart(node) {
348
+ const args = [];
349
+ for (let i = 0; i < node.children.length; i++) {
350
+ const component = this.visitChild(node, i);
351
+ if (component === null) return null;
352
+ if (component.length === 0) return EmptySetV;
353
+ args.push(component);
354
+ }
355
+ const result = cartesianProduct(args);
356
+ if (result === null) {
357
+ this.onError(RSErrorCode.setOverflow, node, [String(SET_INFINITY)]);
358
+ return null;
359
+ }
360
+ return result;
361
+ }
362
+ visitBoolean(node) {
363
+ const base = this.visitChild(node, 0);
364
+ if (base === null) return null;
365
+ const result = boolean(base);
366
+ if (result === null) {
367
+ this.onError(RSErrorCode.booleanBaseLimit, node.children[0], [String(18)]);
368
+ return null;
369
+ }
370
+ return result;
371
+ }
372
+ visitTuple(node) {
373
+ const args = [];
374
+ for (let i = 0; i < node.children.length; i++) {
375
+ const component = this.visitChild(node, i);
376
+ if (component === null) return null;
377
+ args.push(component);
378
+ }
379
+ return tuple(args);
380
+ }
381
+ visitEnumeration(node) {
382
+ const args = [];
383
+ for (let i = 0; i < node.children.length; i++) {
384
+ const element = this.visitChild(node, i);
385
+ if (element === null) return null;
386
+ args.push(element);
387
+ }
388
+ return set(args);
389
+ }
390
+ visitBool(node) {
391
+ const element = this.visitChild(node, 0);
392
+ if (element === null) return null;
393
+ return [element];
394
+ }
395
+ visitDebool(node) {
396
+ const target = this.visitChild(node, 0);
397
+ if (target === null) return null;
398
+ if (target.length !== 1) return this.onError(RSErrorCode.calcInvalidDebool, node.children[0]);
399
+ return target[0];
400
+ }
401
+ visitSetexprBinary(node) {
402
+ const v1 = this.visitChild(node, 0);
403
+ if (v1 === null) return null;
404
+ const v2 = this.visitChild(node, 1);
405
+ if (v2 === null) return null;
406
+ switch (node.typeID) {
407
+ case TokenID.SET_UNION: return setUnion(v1, v2);
408
+ case TokenID.SET_INTERSECTION: return setIntersection(v1, v2);
409
+ case TokenID.SET_MINUS: return setDiff(v1, v2);
410
+ case TokenID.SET_SYMMETRIC_MINUS: return setSymDiff(v1, v2);
411
+ }
412
+ return null;
413
+ }
414
+ visitProjectSet(node) {
415
+ const target = this.visitChild(node, 0);
416
+ if (target === null) return null;
417
+ return projection(target, getNodeIndices(node));
418
+ }
419
+ visitProjectTuple(node) {
420
+ const target = this.visitChild(node, 0);
421
+ if (target === null) return null;
422
+ const components = getNodeIndices(node).map((i) => target[i]);
423
+ return components.length === 1 ? components[0] : tuple(components);
424
+ }
425
+ visitFilter(node) {
426
+ const lastIdx = node.children.length - 1;
427
+ const argVal = this.visitChild(node, lastIdx);
428
+ if (argVal === null) return null;
429
+ if (argVal.length === 0) return EmptySetV;
430
+ const indices = getNodeIndices(node);
431
+ if (indices.length === lastIdx) {
432
+ const params = [];
433
+ for (let i = 0; i < lastIdx; i++) {
434
+ const param = this.visitChild(node, i);
435
+ if (param === null) return null;
436
+ if (param.length === 0) return EmptySetV;
437
+ params.push(param);
438
+ }
439
+ const result = [];
440
+ for (const element of argVal) {
441
+ let valid = true;
442
+ for (let j = 0; j < indices.length; j++) {
443
+ const comp = element[indices[j]];
444
+ const paramSet = params[j];
445
+ if (!contains(paramSet, comp)) {
446
+ valid = false;
447
+ break;
448
+ }
449
+ }
450
+ if (valid) result.push(element);
451
+ }
452
+ return result;
453
+ } else {
454
+ const paramVal = this.visitChild(node, 0);
455
+ if (paramVal === null) return null;
456
+ if (paramVal.length === 0) return EmptySetV;
457
+ const result = [];
458
+ for (const element of argVal) {
459
+ const comps = indices.map((i) => element[i]);
460
+ if (contains(paramVal, comps.length === 1 ? comps[0] : tuple(comps))) result.push(element);
461
+ }
462
+ return result;
463
+ }
464
+ }
465
+ visitReduce(node) {
466
+ const target = this.visitChild(node, 0);
467
+ if (target === null) return null;
468
+ return reduce(target);
469
+ }
470
+ visitDeclarative(node) {
471
+ const domain = this.visitChild(node, 1);
472
+ if (domain === null) return null;
473
+ const elements = [];
474
+ for (const element of domain) {
475
+ if (!this.tick(node, TICK_PER_DECLARATIVE)) return null;
476
+ this.dispatchDeclare(node.children[0], element);
477
+ const value = this.visitChild(node, 2);
478
+ if (value === null) return null;
479
+ if (value === 1) elements.push(element);
480
+ }
481
+ return elements.length === 0 ? EmptySetV : elements;
482
+ }
483
+ visitImperative(node) {
484
+ const result = [];
485
+ const frames = [];
486
+ let currentChild = 1;
487
+ const advanceIterator = () => {
488
+ while (frames.length > 0) {
489
+ const top = frames[frames.length - 1];
490
+ if (top.valueID < top.domain.length - 1) {
491
+ top.valueID++;
492
+ const nextValue = top.domain[top.valueID];
493
+ if (!this.tick(node.children[top.childID], TICK_PER_IMPERATIVE)) return false;
494
+ this.dispatchDeclare(node.children[top.childID].children[0], nextValue);
495
+ currentChild = top.childID + 1;
496
+ return true;
497
+ }
498
+ frames.pop();
499
+ }
500
+ return false;
501
+ };
502
+ while (true) {
503
+ if (currentChild >= node.children.length) {
504
+ const element = this.visitChild(node, 0);
505
+ if (element === null) return null;
506
+ result.push(element);
507
+ if (!advanceIterator()) break;
508
+ continue;
509
+ }
510
+ const child = node.children[currentChild];
511
+ if (child.typeID === TokenID.ITERATE) {
512
+ const domain = this.visitChild(child, 1);
513
+ if (domain === null) return null;
514
+ if (domain.length === 0) {
515
+ if (!advanceIterator()) break;
516
+ continue;
517
+ }
518
+ if (!this.tick(child, TICK_PER_IMPERATIVE)) return null;
519
+ frames.push({
520
+ childID: currentChild,
521
+ domain,
522
+ valueID: 0
523
+ });
524
+ this.dispatchDeclare(child.children[0], domain[0]);
525
+ currentChild++;
526
+ continue;
527
+ }
528
+ const value = this.dispatchVisit(child);
529
+ if (value === null) return null;
530
+ if (value === 0) {
531
+ if (!advanceIterator()) break;
532
+ continue;
533
+ }
534
+ currentChild++;
535
+ }
536
+ return set(result);
537
+ }
538
+ visitAssign(node) {
539
+ const value = this.visitChild(node, 1);
540
+ if (value === null) return null;
541
+ this.dispatchDeclare(node.children[0], value);
542
+ return 1;
543
+ }
544
+ visitRecursion(node) {
545
+ const initialValue = this.visitChild(node, 1);
546
+ if (initialValue === null) return null;
547
+ const bodyIndex = node.typeID === TokenID.NT_RECURSIVE_FULL ? 3 : 2;
548
+ let current = initialValue;
549
+ while (true) {
550
+ if (!this.tick(node, TICK_PER_RECURSION)) return null;
551
+ this.dispatchDeclare(node.children[0], current);
552
+ if (node.typeID === TokenID.NT_RECURSIVE_FULL) {
553
+ const pred = this.visitChild(node, 2);
554
+ if (pred === null) return null;
555
+ if (pred !== 1) break;
556
+ }
557
+ const next = this.visitChild(node, bodyIndex);
558
+ if (next === null) return null;
559
+ if (compare(current, next) === 0) break;
560
+ current = next;
561
+ }
562
+ return current;
563
+ }
1468
564
  };
565
+ /** Local variables context. */
1469
566
  var LocalContext = class {
1470
- nextBindingId = 1;
1471
- data = /* @__PURE__ */ new Map();
1472
- callStack = [];
1473
- startScope() {
1474
- this.callStack.push(this.data);
1475
- this.data = /* @__PURE__ */ new Map();
1476
- }
1477
- endScope() {
1478
- this.data = this.callStack.pop();
1479
- }
1480
- setLocal(alias, value) {
1481
- const existing = this.data.get(alias);
1482
- if (existing) {
1483
- existing.value = value;
1484
- existing.version++;
1485
- } else {
1486
- this.data.set(alias, { id: this.nextBindingId++, version: 0, value });
1487
- }
1488
- }
1489
- getLocal(alias) {
1490
- const binding = this.data.get(alias);
1491
- if (binding === void 0) {
1492
- throw new Error(`Local variable "${alias}" not found`);
1493
- }
1494
- return binding.value;
1495
- }
1496
- buildDependencyStamp(reads) {
1497
- if (reads.size === 0) {
1498
- return "";
1499
- }
1500
- const parts = [];
1501
- for (const alias of [...reads].sort()) {
1502
- const binding = this.data.get(alias);
1503
- if (binding === void 0) {
1504
- return null;
1505
- }
1506
- parts.push(`${binding.id}:${binding.version}`);
1507
- }
1508
- return parts.join("|");
1509
- }
1510
- };
1511
- export {
1512
- Evaluator
567
+ nextBindingId = 1;
568
+ data = /* @__PURE__ */ new Map();
569
+ callStack = [];
570
+ startScope() {
571
+ this.callStack.push(this.data);
572
+ this.data = /* @__PURE__ */ new Map();
573
+ }
574
+ endScope() {
575
+ this.data = this.callStack.pop();
576
+ }
577
+ setLocal(alias, value) {
578
+ const existing = this.data.get(alias);
579
+ if (existing) {
580
+ existing.value = value;
581
+ existing.version++;
582
+ } else this.data.set(alias, {
583
+ id: this.nextBindingId++,
584
+ version: 0,
585
+ value
586
+ });
587
+ }
588
+ getLocal(alias) {
589
+ const binding = this.data.get(alias);
590
+ if (binding === void 0) throw new Error(`Local variable "${alias}" not found`);
591
+ return binding.value;
592
+ }
593
+ buildDependencyStamp(reads) {
594
+ if (reads.size === 0) return "";
595
+ const parts = [];
596
+ for (const alias of [...reads].sort()) {
597
+ const binding = this.data.get(alias);
598
+ if (binding === void 0) return null;
599
+ parts.push(`${binding.id}:${binding.version}`);
600
+ }
601
+ return parts.join("|");
602
+ }
1513
603
  };
604
+ //#endregion
605
+ export { Evaluator };
606
+
1514
607
  //# sourceMappingURL=evaluator.js.map