@rsconcept/domain 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +55 -0
- package/dist/cctext/index.d.ts +1 -0
- package/dist/cctext/index.js +42 -0
- package/dist/cctext/index.js.map +1 -0
- package/dist/cctext/language-api.d.ts +43 -0
- package/dist/cctext/language-api.js +252 -0
- package/dist/cctext/language-api.js.map +1 -0
- package/dist/cctext/language.d.ts +58 -0
- package/dist/cctext/language.js +44 -0
- package/dist/cctext/language.js.map +1 -0
- package/dist/graph/graph.d.ts +62 -0
- package/dist/graph/graph.js +385 -0
- package/dist/graph/graph.js.map +1 -0
- package/dist/graph/index.d.ts +1 -0
- package/dist/graph/index.js +384 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +5851 -0
- package/dist/index.js.map +1 -0
- package/dist/library/folder-tree.d.ts +32 -0
- package/dist/library/folder-tree.js +136 -0
- package/dist/library/folder-tree.js.map +1 -0
- package/dist/library/index.d.ts +17 -0
- package/dist/library/index.js +2800 -0
- package/dist/library/index.js.map +1 -0
- package/dist/library/library-api.d.ts +6 -0
- package/dist/library/library-api.js +13 -0
- package/dist/library/library-api.js.map +1 -0
- package/dist/library/library.d.ts +56 -0
- package/dist/library/library.js +23 -0
- package/dist/library/library.js.map +1 -0
- package/dist/library/oss-api.d.ts +47 -0
- package/dist/library/oss-api.js +1105 -0
- package/dist/library/oss-api.js.map +1 -0
- package/dist/library/oss-layout-api.d.ts +36 -0
- package/dist/library/oss-layout-api.js +330 -0
- package/dist/library/oss-layout-api.js.map +1 -0
- package/dist/library/oss-layout.d.ts +25 -0
- package/dist/library/oss-layout.js +1 -0
- package/dist/library/oss-layout.js.map +1 -0
- package/dist/library/oss.d.ts +136 -0
- package/dist/library/oss.js +30 -0
- package/dist/library/oss.js.map +1 -0
- package/dist/library/rsengine.d.ts +116 -0
- package/dist/library/rsengine.js +2604 -0
- package/dist/library/rsengine.js.map +1 -0
- package/dist/library/rsform-api.d.ts +74 -0
- package/dist/library/rsform-api.js +879 -0
- package/dist/library/rsform-api.js.map +1 -0
- package/dist/library/rsform.d.ts +206 -0
- package/dist/library/rsform.js +32 -0
- package/dist/library/rsform.js.map +1 -0
- package/dist/library/rsmodel-api.d.ts +43 -0
- package/dist/library/rsmodel-api.js +836 -0
- package/dist/library/rsmodel-api.js.map +1 -0
- package/dist/library/rsmodel.d.ts +52 -0
- package/dist/library/rsmodel.js +25 -0
- package/dist/library/rsmodel.js.map +1 -0
- package/dist/library/structure-planner.d.ts +33 -0
- package/dist/library/structure-planner.js +481 -0
- package/dist/library/structure-planner.js.map +1 -0
- package/dist/parsing/ast.d.ts +49 -0
- package/dist/parsing/ast.js +93 -0
- package/dist/parsing/ast.js.map +1 -0
- package/dist/parsing/index.d.ts +3 -0
- package/dist/parsing/index.js +141 -0
- package/dist/parsing/index.js.map +1 -0
- package/dist/parsing/lezer-tree.d.ts +13 -0
- package/dist/parsing/lezer-tree.js +50 -0
- package/dist/parsing/lezer-tree.js.map +1 -0
- package/dist/rslang/api.d.ts +53 -0
- package/dist/rslang/api.js +846 -0
- package/dist/rslang/api.js.map +1 -0
- package/dist/rslang/ast-annotations.d.ts +18 -0
- package/dist/rslang/ast-annotations.js +56 -0
- package/dist/rslang/ast-annotations.js.map +1 -0
- package/dist/rslang/error.d.ts +85 -0
- package/dist/rslang/error.js +159 -0
- package/dist/rslang/error.js.map +1 -0
- package/dist/rslang/eval/calculator.d.ts +43 -0
- package/dist/rslang/eval/calculator.js +1639 -0
- package/dist/rslang/eval/calculator.js.map +1 -0
- package/dist/rslang/eval/evaluation-cache.d.ts +36 -0
- package/dist/rslang/eval/evaluation-cache.js +310 -0
- package/dist/rslang/eval/evaluation-cache.js.map +1 -0
- package/dist/rslang/eval/evaluator.d.ts +70 -0
- package/dist/rslang/eval/evaluator.js +1514 -0
- package/dist/rslang/eval/evaluator.js.map +1 -0
- package/dist/rslang/eval/value-api.d.ts +48 -0
- package/dist/rslang/eval/value-api.js +490 -0
- package/dist/rslang/eval/value-api.js.map +1 -0
- package/dist/rslang/eval/value.d.ts +36 -0
- package/dist/rslang/eval/value.js +118 -0
- package/dist/rslang/eval/value.js.map +1 -0
- package/dist/rslang/index.d.ts +17 -0
- package/dist/rslang/index.js +4314 -0
- package/dist/rslang/index.js.map +1 -0
- package/dist/rslang/labels.d.ts +16 -0
- package/dist/rslang/labels.js +315 -0
- package/dist/rslang/labels.js.map +1 -0
- package/dist/rslang/parser/expression-generator.d.ts +10 -0
- package/dist/rslang/parser/expression-generator.js +451 -0
- package/dist/rslang/parser/expression-generator.js.map +1 -0
- package/dist/rslang/parser/normalize.d.ts +11 -0
- package/dist/rslang/parser/normalize.js +507 -0
- package/dist/rslang/parser/normalize.js.map +1 -0
- package/dist/rslang/parser/parser.d.ts +5 -0
- package/dist/rslang/parser/parser.js +24 -0
- package/dist/rslang/parser/parser.js.map +1 -0
- package/dist/rslang/parser/parser.terms.d.ts +42 -0
- package/dist/rslang/parser/parser.terms.js +84 -0
- package/dist/rslang/parser/parser.terms.js.map +1 -0
- package/dist/rslang/parser/syntax-errors.d.ts +11 -0
- package/dist/rslang/parser/syntax-errors.js +403 -0
- package/dist/rslang/parser/syntax-errors.js.map +1 -0
- package/dist/rslang/parser/token.d.ts +79 -0
- package/dist/rslang/parser/token.js +95 -0
- package/dist/rslang/parser/token.js.map +1 -0
- package/dist/rslang/semantic/analyzer.d.ts +39 -0
- package/dist/rslang/semantic/analyzer.js +2604 -0
- package/dist/rslang/semantic/analyzer.js.map +1 -0
- package/dist/rslang/semantic/arguments-extractor.d.ts +42 -0
- package/dist/rslang/semantic/arguments-extractor.js +366 -0
- package/dist/rslang/semantic/arguments-extractor.js.map +1 -0
- package/dist/rslang/semantic/type-auditor.d.ts +73 -0
- package/dist/rslang/semantic/type-auditor.js +1570 -0
- package/dist/rslang/semantic/type-auditor.js.map +1 -0
- package/dist/rslang/semantic/typification-api.d.ts +27 -0
- package/dist/rslang/semantic/typification-api.js +320 -0
- package/dist/rslang/semantic/typification-api.js.map +1 -0
- package/dist/rslang/semantic/typification-parser.d.ts +12 -0
- package/dist/rslang/semantic/typification-parser.js +226 -0
- package/dist/rslang/semantic/typification-parser.js.map +1 -0
- package/dist/rslang/semantic/typification.d.ts +119 -0
- package/dist/rslang/semantic/typification.js +74 -0
- package/dist/rslang/semantic/typification.js.map +1 -0
- package/dist/rslang/semantic/value-auditor.d.ts +43 -0
- package/dist/rslang/semantic/value-auditor.js +523 -0
- package/dist/rslang/semantic/value-auditor.js.map +1 -0
- package/dist/rslang/semantic/value-class.d.ts +10 -0
- package/dist/rslang/semantic/value-class.js +9 -0
- package/dist/rslang/semantic/value-class.js.map +1 -0
- package/dist/rslang/typification-graph.d.ts +33 -0
- package/dist/rslang/typification-graph.js +311 -0
- package/dist/rslang/typification-graph.js.map +1 -0
- package/dist/shared/branded.d.ts +7 -0
- package/dist/shared/branded.js +1 -0
- package/dist/shared/branded.js.map +1 -0
- package/dist/shared/hash.d.ts +6 -0
- package/dist/shared/hash.js +18 -0
- package/dist/shared/hash.js.map +1 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.js +18 -0
- package/dist/shared/index.js.map +1 -0
- package/package.json +184 -0
- package/src/cctext/index.ts +9 -0
- package/src/cctext/language-api.test.ts +149 -0
- package/src/cctext/language-api.ts +285 -0
- package/src/cctext/language.ts +80 -0
- package/src/graph/graph.test.ts +392 -0
- package/src/graph/graph.ts +433 -0
- package/src/graph/index.ts +1 -0
- package/src/index.ts +96 -0
- package/src/library/folder-tree.test.ts +47 -0
- package/src/library/folder-tree.ts +156 -0
- package/src/library/index.ts +46 -0
- package/src/library/library-api.test.ts +32 -0
- package/src/library/library-api.ts +11 -0
- package/src/library/library.ts +61 -0
- package/src/library/oss-api.ts +449 -0
- package/src/library/oss-layout-api.ts +377 -0
- package/src/library/oss-layout.ts +27 -0
- package/src/library/oss.ts +150 -0
- package/src/library/rsengine.ts +593 -0
- package/src/library/rsform-api.ts +533 -0
- package/src/library/rsform.ts +228 -0
- package/src/library/rsmodel-api.ts +340 -0
- package/src/library/rsmodel.ts +50 -0
- package/src/library/structure-planner.ts +143 -0
- package/src/parsing/ast.ts +136 -0
- package/src/parsing/index.ts +15 -0
- package/src/parsing/lezer-tree.ts +69 -0
- package/src/rslang/api.test.ts +116 -0
- package/src/rslang/api.ts +183 -0
- package/src/rslang/ast-annotations.ts +70 -0
- package/src/rslang/error.ts +129 -0
- package/src/rslang/eval/calculator.test.ts +124 -0
- package/src/rslang/eval/calculator.ts +121 -0
- package/src/rslang/eval/evaluation-cache.ts +257 -0
- package/src/rslang/eval/evaluator.test.ts +352 -0
- package/src/rslang/eval/evaluator.ts +935 -0
- package/src/rslang/eval/value-api.test.ts +105 -0
- package/src/rslang/eval/value-api.ts +444 -0
- package/src/rslang/eval/value.ts +102 -0
- package/src/rslang/index.ts +23 -0
- package/src/rslang/labels.ts +191 -0
- package/src/rslang/parser/expression-generator.test.ts +100 -0
- package/src/rslang/parser/expression-generator.ts +466 -0
- package/src/rslang/parser/normalize.test.ts +99 -0
- package/src/rslang/parser/normalize.ts +462 -0
- package/src/rslang/parser/parser.terms.ts +42 -0
- package/src/rslang/parser/parser.test.ts +153 -0
- package/src/rslang/parser/parser.ts +20 -0
- package/src/rslang/parser/rslang.grammar +251 -0
- package/src/rslang/parser/syntax-errors.ts +209 -0
- package/src/rslang/parser/token.ts +106 -0
- package/src/rslang/semantic/analyzer.test.ts +59 -0
- package/src/rslang/semantic/analyzer.ts +179 -0
- package/src/rslang/semantic/arguments-extractor.ts +327 -0
- package/src/rslang/semantic/type-auditor.test.ts +326 -0
- package/src/rslang/semantic/type-auditor.ts +1049 -0
- package/src/rslang/semantic/typification-api.test.ts +46 -0
- package/src/rslang/semantic/typification-api.ts +321 -0
- package/src/rslang/semantic/typification-parser.test.ts +50 -0
- package/src/rslang/semantic/typification-parser.ts +220 -0
- package/src/rslang/semantic/typification.ts +180 -0
- package/src/rslang/semantic/value-auditor.test.ts +206 -0
- package/src/rslang/semantic/value-auditor.ts +332 -0
- package/src/rslang/semantic/value-class.ts +11 -0
- package/src/rslang/typification-graph.ts +155 -0
- package/src/shared/branded.ts +6 -0
- package/src/shared/hash.ts +17 -0
- package/src/shared/index.ts +2 -0
|
@@ -0,0 +1,2800 @@
|
|
|
1
|
+
// src/library/folder-tree.ts
|
|
2
|
+
var FolderNode = class _FolderNode {
|
|
3
|
+
rank = 0;
|
|
4
|
+
text;
|
|
5
|
+
children;
|
|
6
|
+
parent;
|
|
7
|
+
filesInside = 0;
|
|
8
|
+
filesTotal = 0;
|
|
9
|
+
constructor(text, parent = null) {
|
|
10
|
+
this.text = text;
|
|
11
|
+
this.parent = parent;
|
|
12
|
+
this.children = /* @__PURE__ */ new Map();
|
|
13
|
+
if (parent) {
|
|
14
|
+
this.rank = parent.rank + 1;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
addChild(text) {
|
|
18
|
+
const node = new _FolderNode(text, this);
|
|
19
|
+
this.children.set(text, node);
|
|
20
|
+
return node;
|
|
21
|
+
}
|
|
22
|
+
hasPredecessor(target) {
|
|
23
|
+
if (this.parent === target) {
|
|
24
|
+
return true;
|
|
25
|
+
} else if (!this.parent) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
let node = this.parent;
|
|
29
|
+
while (node.parent) {
|
|
30
|
+
if (node.parent === target) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
node = node.parent;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
incrementFiles(count = 1) {
|
|
38
|
+
this.filesInside = this.filesInside + count;
|
|
39
|
+
this.incrementTotal(count);
|
|
40
|
+
}
|
|
41
|
+
incrementTotal(count = 1) {
|
|
42
|
+
this.filesTotal = this.filesTotal + count;
|
|
43
|
+
if (this.parent) {
|
|
44
|
+
this.parent.incrementTotal(count);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
getPath() {
|
|
48
|
+
const suffix = this.text ? `/${this.text}` : "";
|
|
49
|
+
if (!this.parent) {
|
|
50
|
+
return suffix;
|
|
51
|
+
} else {
|
|
52
|
+
return this.parent.getPath() + suffix;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var FolderTree = class {
|
|
57
|
+
roots = /* @__PURE__ */ new Map();
|
|
58
|
+
constructor(arr) {
|
|
59
|
+
arr?.forEach((path) => this.addPath(path));
|
|
60
|
+
}
|
|
61
|
+
at(path) {
|
|
62
|
+
let parse = ChopPathHead(path);
|
|
63
|
+
if (!this.roots.has(parse.head)) {
|
|
64
|
+
return void 0;
|
|
65
|
+
}
|
|
66
|
+
let node = this.roots.get(parse.head);
|
|
67
|
+
while (parse.tail !== "") {
|
|
68
|
+
parse = ChopPathHead(parse.tail);
|
|
69
|
+
if (!node.children.has(parse.head)) {
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
node = node.children.get(parse.head);
|
|
73
|
+
}
|
|
74
|
+
return node;
|
|
75
|
+
}
|
|
76
|
+
getTree() {
|
|
77
|
+
const result = [];
|
|
78
|
+
this.roots.forEach((root) => this.visitNode(root, result));
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
visitNode(target, result) {
|
|
82
|
+
result.push(target);
|
|
83
|
+
[...target.children.keys()].sort((a, b) => a.localeCompare(b)).forEach((key) => this.visitNode(target.children.get(key), result));
|
|
84
|
+
}
|
|
85
|
+
addPath(path, filesCount = 1) {
|
|
86
|
+
let parse = ChopPathHead(path);
|
|
87
|
+
if (!parse.head) {
|
|
88
|
+
throw Error(`Invalid path ${path}`);
|
|
89
|
+
}
|
|
90
|
+
let node = this.roots.has(parse.head) ? this.roots.get(parse.head) : this.addNode(parse.head);
|
|
91
|
+
while (parse.tail !== "") {
|
|
92
|
+
parse = ChopPathHead(parse.tail);
|
|
93
|
+
if (node.children.has(parse.head)) {
|
|
94
|
+
node = node.children.get(parse.head);
|
|
95
|
+
} else {
|
|
96
|
+
node = this.addNode(parse.head, node);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
node.incrementFiles(filesCount);
|
|
100
|
+
return node;
|
|
101
|
+
}
|
|
102
|
+
addNode(text, parent) {
|
|
103
|
+
if (!parent) {
|
|
104
|
+
const newNode = new FolderNode(text);
|
|
105
|
+
this.roots.set(text, newNode);
|
|
106
|
+
return newNode;
|
|
107
|
+
} else {
|
|
108
|
+
return parent.addChild(text);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
function ChopPathHead(path) {
|
|
113
|
+
if (path?.at(0) !== "/") {
|
|
114
|
+
return {
|
|
115
|
+
head: "",
|
|
116
|
+
tail: ""
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const slash = path.indexOf("/", 1);
|
|
120
|
+
if (slash === -1) {
|
|
121
|
+
return {
|
|
122
|
+
head: path.substring(1),
|
|
123
|
+
tail: ""
|
|
124
|
+
};
|
|
125
|
+
} else {
|
|
126
|
+
return {
|
|
127
|
+
head: path.substring(1, slash),
|
|
128
|
+
tail: path.substring(slash)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/library/library.ts
|
|
134
|
+
var LibraryItemType = {
|
|
135
|
+
RSFORM: "rsform",
|
|
136
|
+
OSS: "oss",
|
|
137
|
+
RSMODEL: "rsmodel"
|
|
138
|
+
};
|
|
139
|
+
var AccessPolicy = {
|
|
140
|
+
PUBLIC: "public",
|
|
141
|
+
PROTECTED: "protected",
|
|
142
|
+
PRIVATE: "private"
|
|
143
|
+
};
|
|
144
|
+
var LocationHead = {
|
|
145
|
+
USER: "/U",
|
|
146
|
+
COMMON: "/S",
|
|
147
|
+
LIBRARY: "/L",
|
|
148
|
+
PROJECTS: "/P"
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// src/library/oss.ts
|
|
152
|
+
var NodeType = {
|
|
153
|
+
OPERATION: 1,
|
|
154
|
+
BLOCK: 2
|
|
155
|
+
};
|
|
156
|
+
var OperationType = {
|
|
157
|
+
INPUT: "input",
|
|
158
|
+
SYNTHESIS: "synthesis",
|
|
159
|
+
REPLICA: "replica"
|
|
160
|
+
};
|
|
161
|
+
var SubstitutionErrorType = {
|
|
162
|
+
invalidIDs: 0,
|
|
163
|
+
incorrectCst: 1,
|
|
164
|
+
invalidClasses: 2,
|
|
165
|
+
invalidBasic: 3,
|
|
166
|
+
invalidConstant: 4,
|
|
167
|
+
typificationCycle: 5,
|
|
168
|
+
baseSubstitutionNotSet: 6,
|
|
169
|
+
unequalTypification: 7,
|
|
170
|
+
unequalExpressions: 8,
|
|
171
|
+
unequalArgsCount: 9,
|
|
172
|
+
unequalArgs: 10,
|
|
173
|
+
invalidNominal: 11
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// src/rslang/ast-annotations.ts
|
|
177
|
+
var AST_ERRORS_KEY = "rsErrors";
|
|
178
|
+
function annotateError(node, code, params) {
|
|
179
|
+
if (typeof node.annotation === "object" && node.annotation !== null && AST_ERRORS_KEY in node.annotation && isAstNodeErrorRef(node.annotation[AST_ERRORS_KEY])) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const entry = params !== void 0 && params.length > 0 ? { code, params: [...params] } : { code };
|
|
183
|
+
node.annotation = {
|
|
184
|
+
...typeof node.annotation === "object" && node.annotation !== null ? node.annotation : {},
|
|
185
|
+
[AST_ERRORS_KEY]: entry
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function isAstNodeErrorRef(x) {
|
|
189
|
+
if (typeof x !== "object" || x === null || !("code" in x)) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
const code = x.code;
|
|
193
|
+
if (typeof code !== "number") {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
if (!("params" in x)) {
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
const p = x.params;
|
|
200
|
+
if (p === void 0) {
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
return Array.isArray(p) && p.every((item) => typeof item === "string");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/rslang/error.ts
|
|
207
|
+
var RSErrorCode = {
|
|
208
|
+
unknownSyntax: 33792,
|
|
209
|
+
// 33792
|
|
210
|
+
missingParenthesis: 33798,
|
|
211
|
+
// 33798
|
|
212
|
+
missingCurlyBrace: 33799,
|
|
213
|
+
// 33799
|
|
214
|
+
missingSquareBracket: 33800,
|
|
215
|
+
// 33800
|
|
216
|
+
bracketMismatch: 33801,
|
|
217
|
+
// 33801
|
|
218
|
+
doubleParenthesis: 33802,
|
|
219
|
+
// 33802
|
|
220
|
+
missingOpenBracket: 33803,
|
|
221
|
+
// 33803
|
|
222
|
+
expectedLocal: 33813,
|
|
223
|
+
// 33813
|
|
224
|
+
expectedType: 33814,
|
|
225
|
+
// 33814
|
|
226
|
+
localDoubleDeclare: 10241,
|
|
227
|
+
// 10241
|
|
228
|
+
localNotUsed: 10242,
|
|
229
|
+
// 10242
|
|
230
|
+
localUndeclared: 34817,
|
|
231
|
+
// 34817
|
|
232
|
+
localShadowing: 34818,
|
|
233
|
+
// 34818
|
|
234
|
+
typesNotEqual: 34819,
|
|
235
|
+
// 34819
|
|
236
|
+
globalNotTyped: 34820,
|
|
237
|
+
// 34820
|
|
238
|
+
invalidDecart: 34821,
|
|
239
|
+
// 34821
|
|
240
|
+
invalidBoolean: 34822,
|
|
241
|
+
// 34822
|
|
242
|
+
invalidTypeOperation: 34823,
|
|
243
|
+
// 34823
|
|
244
|
+
invalidCard: 34824,
|
|
245
|
+
// 34824
|
|
246
|
+
invalidDebool: 34825,
|
|
247
|
+
// 34825
|
|
248
|
+
globalFuncWithoutArgs: 34827,
|
|
249
|
+
// 34827
|
|
250
|
+
invalidReduce: 34832,
|
|
251
|
+
// 34832
|
|
252
|
+
invalidProjectionTuple: 34833,
|
|
253
|
+
// 34833
|
|
254
|
+
invalidProjectionSet: 34834,
|
|
255
|
+
// 34834
|
|
256
|
+
invalidEnumeration: 34835,
|
|
257
|
+
// 34835
|
|
258
|
+
invalidCortegeDeclare: 34836,
|
|
259
|
+
// 34836
|
|
260
|
+
localOutOfScope: 34837,
|
|
261
|
+
// 34837
|
|
262
|
+
invalidElementPredicate: 34838,
|
|
263
|
+
// 34838
|
|
264
|
+
invalidEmptySetUsage: 34839,
|
|
265
|
+
// 34839
|
|
266
|
+
invalidArgsArity: 34840,
|
|
267
|
+
// 34840
|
|
268
|
+
invalidArgumentType: 34841,
|
|
269
|
+
// 34841
|
|
270
|
+
globalStructure: 34844,
|
|
271
|
+
// 34844
|
|
272
|
+
radicalUsage: 34849,
|
|
273
|
+
// 34849
|
|
274
|
+
invalidFilterArgumentType: 34850,
|
|
275
|
+
// 34850
|
|
276
|
+
invalidFilterArity: 34851,
|
|
277
|
+
// 34851
|
|
278
|
+
arithmeticNotSupported: 34852,
|
|
279
|
+
// 34852
|
|
280
|
+
typesNotCompatible: 34853,
|
|
281
|
+
// 34853
|
|
282
|
+
orderingNotSupported: 34854,
|
|
283
|
+
// 34854
|
|
284
|
+
expectedLogic: 34855,
|
|
285
|
+
// 34855
|
|
286
|
+
expectedSetexpr: 34856,
|
|
287
|
+
// 34856
|
|
288
|
+
invalidArgumentCortegeDeclare: 34857,
|
|
289
|
+
// 34857
|
|
290
|
+
globalNoValue: 34880,
|
|
291
|
+
// 34880
|
|
292
|
+
invalidPropertyUsage: 34881,
|
|
293
|
+
// 34881
|
|
294
|
+
// Value evaluation (runtime)
|
|
295
|
+
calcUnknownError: 33024,
|
|
296
|
+
// 35328
|
|
297
|
+
setOverflow: 33025,
|
|
298
|
+
// 35329
|
|
299
|
+
booleanBaseLimit: 33026,
|
|
300
|
+
// 35330
|
|
301
|
+
calcGlobalMissing: 33027,
|
|
302
|
+
// 35331
|
|
303
|
+
iterationsLimit: 33028,
|
|
304
|
+
// 35332
|
|
305
|
+
calcInvalidDebool: 33029,
|
|
306
|
+
// 35333
|
|
307
|
+
iterateInfinity: 33030,
|
|
308
|
+
// 35334
|
|
309
|
+
calculationNotSupported: 33031,
|
|
310
|
+
// 35335
|
|
311
|
+
cstEmptyDerived: 34913,
|
|
312
|
+
// 34913
|
|
313
|
+
definitionNotAllowed: 34914
|
|
314
|
+
// 34914
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
// src/parsing/ast.ts
|
|
318
|
+
var TOKEN_ERROR = 0;
|
|
319
|
+
function getNodeText(node) {
|
|
320
|
+
if (node.data.dataType === "string" && typeof node.data.value === "string") {
|
|
321
|
+
return node.data.value;
|
|
322
|
+
}
|
|
323
|
+
return `NO DATA NODE: ${node.typeID}`;
|
|
324
|
+
}
|
|
325
|
+
function getNodeIndices(node) {
|
|
326
|
+
if (node.data.dataType === "string[]" && Array.isArray(node.data.value)) {
|
|
327
|
+
return node.data.value.map((s) => parseInt(s, 10)).filter((n) => !isNaN(n));
|
|
328
|
+
}
|
|
329
|
+
return [];
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// src/rslang/parser/token.ts
|
|
333
|
+
var TokenID = {
|
|
334
|
+
// Global, local IDs and literals
|
|
335
|
+
ERROR: TOKEN_ERROR,
|
|
336
|
+
ID_LOCAL: 258,
|
|
337
|
+
ID_GLOBAL: 259,
|
|
338
|
+
ID_FUNCTION: 260,
|
|
339
|
+
ID_PREDICATE: 261,
|
|
340
|
+
ID_RADICAL: 262,
|
|
341
|
+
LIT_INTEGER: 263,
|
|
342
|
+
LIT_WHOLE_NUMBERS: 264,
|
|
343
|
+
LIT_EMPTYSET: 265,
|
|
344
|
+
// Arithmetic
|
|
345
|
+
PLUS: 266,
|
|
346
|
+
MINUS: 267,
|
|
347
|
+
MULTIPLY: 268,
|
|
348
|
+
// Integer predicate symbols
|
|
349
|
+
GREATER: 269,
|
|
350
|
+
LESSER: 270,
|
|
351
|
+
GREATER_OR_EQ: 271,
|
|
352
|
+
LESSER_OR_EQ: 272,
|
|
353
|
+
// Equality comparison
|
|
354
|
+
EQUAL: 273,
|
|
355
|
+
NOTEQUAL: 274,
|
|
356
|
+
// Logic predicate symbols
|
|
357
|
+
QUANTOR_UNIVERSAL: 275,
|
|
358
|
+
QUANTOR_EXISTS: 276,
|
|
359
|
+
LOGIC_NOT: 277,
|
|
360
|
+
LOGIC_EQUIVALENT: 278,
|
|
361
|
+
LOGIC_IMPLICATION: 279,
|
|
362
|
+
LOGIC_OR: 280,
|
|
363
|
+
LOGIC_AND: 281,
|
|
364
|
+
// Set theory predicate symbols
|
|
365
|
+
SET_IN: 282,
|
|
366
|
+
SET_NOT_IN: 283,
|
|
367
|
+
SUBSET: 284,
|
|
368
|
+
SUBSET_OR_EQ: 285,
|
|
369
|
+
NOT_SUBSET: 286,
|
|
370
|
+
// Set theory operators
|
|
371
|
+
DECART: 287,
|
|
372
|
+
SET_UNION: 288,
|
|
373
|
+
SET_INTERSECTION: 289,
|
|
374
|
+
SET_MINUS: 290,
|
|
375
|
+
SET_SYMMETRIC_MINUS: 291,
|
|
376
|
+
BOOLEAN: 292,
|
|
377
|
+
// Structure operations
|
|
378
|
+
BIGPR: 293,
|
|
379
|
+
SMALLPR: 294,
|
|
380
|
+
FILTER: 295,
|
|
381
|
+
CARD: 296,
|
|
382
|
+
BOOL: 297,
|
|
383
|
+
DEBOOL: 298,
|
|
384
|
+
REDUCE: 299,
|
|
385
|
+
// Term constructions prefixes
|
|
386
|
+
DECLARATIVE: 300,
|
|
387
|
+
RECURSIVE: 301,
|
|
388
|
+
IMPERATIVE: 302,
|
|
389
|
+
ITERATE: 303,
|
|
390
|
+
ASSIGN: 304,
|
|
391
|
+
// Punctuation
|
|
392
|
+
PUNCTUATION_DEFINE: 305,
|
|
393
|
+
PUNCTUATION_STRUCT: 306,
|
|
394
|
+
PUNCTUATION_PL: 307,
|
|
395
|
+
PUNCTUATION_PR: 308,
|
|
396
|
+
PUNCTUATION_CL: 309,
|
|
397
|
+
PUNCTUATION_CR: 310,
|
|
398
|
+
PUNCTUATION_SL: 311,
|
|
399
|
+
PUNCTUATION_SR: 312,
|
|
400
|
+
PUNCTUATION_BAR: 313,
|
|
401
|
+
PUNCTUATION_COMMA: 314,
|
|
402
|
+
PUNCTUATION_SEMICOLON: 315,
|
|
403
|
+
// ======= Non-terminal tokens =========
|
|
404
|
+
NT_ENUM_DECL: 316,
|
|
405
|
+
NT_TUPLE: 317,
|
|
406
|
+
NT_ENUMERATION: 318,
|
|
407
|
+
NT_TUPLE_DECL: 319,
|
|
408
|
+
NT_ARG_DECL: 320,
|
|
409
|
+
NT_FUNC_DEFINITION: 321,
|
|
410
|
+
NT_ARGUMENTS: 322,
|
|
411
|
+
NT_FUNC_CALL: 323,
|
|
412
|
+
NT_DECLARATIVE_EXPR: 324,
|
|
413
|
+
NT_IMPERATIVE_EXPR: 325,
|
|
414
|
+
NT_RECURSIVE_FULL: 326,
|
|
415
|
+
NT_RECURSIVE_SHORT: 327,
|
|
416
|
+
// ======= Helper tokens ========
|
|
417
|
+
INTERRUPT: 328,
|
|
418
|
+
END: 329
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
// src/rslang/eval/evaluation-cache.ts
|
|
422
|
+
var EvaluationMetadata = class {
|
|
423
|
+
byNode = /* @__PURE__ */ new WeakMap();
|
|
424
|
+
get(node) {
|
|
425
|
+
let info = this.byNode.get(node);
|
|
426
|
+
if (!info) {
|
|
427
|
+
info = analyzeNode(node, /* @__PURE__ */ new Set());
|
|
428
|
+
this.byNode.set(node, info);
|
|
429
|
+
}
|
|
430
|
+
return info;
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
var EvaluationCache = class {
|
|
434
|
+
entries = /* @__PURE__ */ new Map();
|
|
435
|
+
/** Cache hits in the current evaluation run (for tests/diagnostics). */
|
|
436
|
+
hits = 0;
|
|
437
|
+
/** Returns cached value, or `undefined` on miss or stamp mismatch. */
|
|
438
|
+
lookup(structuralKey, stamp) {
|
|
439
|
+
const entry = this.entries.get(structuralKey);
|
|
440
|
+
if (entry?.stamp !== stamp) {
|
|
441
|
+
return void 0;
|
|
442
|
+
}
|
|
443
|
+
this.hits++;
|
|
444
|
+
return entry.value;
|
|
445
|
+
}
|
|
446
|
+
/** Stores one value per structural key (replaces previous stamp). */
|
|
447
|
+
store(structuralKey, stamp, value) {
|
|
448
|
+
this.entries.set(structuralKey, { stamp, value });
|
|
449
|
+
}
|
|
450
|
+
clear() {
|
|
451
|
+
this.entries.clear();
|
|
452
|
+
this.hits = 0;
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
function analyzeNode(node, bound) {
|
|
456
|
+
const reads = collectReads(node, bound);
|
|
457
|
+
const structuralKey = buildStructuralKey(node);
|
|
458
|
+
const cacheable = isCacheableNode(node);
|
|
459
|
+
return { reads, structuralKey, cacheable };
|
|
460
|
+
}
|
|
461
|
+
function isCacheableNode(node) {
|
|
462
|
+
switch (node.typeID) {
|
|
463
|
+
case TokenID.ASSIGN:
|
|
464
|
+
case TokenID.ITERATE:
|
|
465
|
+
case TokenID.NT_IMPERATIVE_EXPR:
|
|
466
|
+
case TokenID.NT_DECLARATIVE_EXPR:
|
|
467
|
+
case TokenID.NT_RECURSIVE_FULL:
|
|
468
|
+
case TokenID.NT_RECURSIVE_SHORT:
|
|
469
|
+
case TokenID.QUANTOR_UNIVERSAL:
|
|
470
|
+
case TokenID.QUANTOR_EXISTS:
|
|
471
|
+
case TokenID.LOGIC_AND:
|
|
472
|
+
case TokenID.LOGIC_OR:
|
|
473
|
+
case TokenID.LOGIC_IMPLICATION:
|
|
474
|
+
case TokenID.NT_FUNC_DEFINITION:
|
|
475
|
+
case TokenID.LIT_INTEGER:
|
|
476
|
+
case TokenID.LIT_EMPTYSET:
|
|
477
|
+
case TokenID.LIT_WHOLE_NUMBERS:
|
|
478
|
+
case TokenID.ID_LOCAL:
|
|
479
|
+
case TokenID.ID_RADICAL:
|
|
480
|
+
case TokenID.ID_GLOBAL:
|
|
481
|
+
return false;
|
|
482
|
+
default:
|
|
483
|
+
return !node.hasError;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function buildStructuralKey(node) {
|
|
487
|
+
switch (node.typeID) {
|
|
488
|
+
case TokenID.ID_GLOBAL:
|
|
489
|
+
case TokenID.ID_LOCAL:
|
|
490
|
+
case TokenID.ID_RADICAL:
|
|
491
|
+
case TokenID.LIT_INTEGER:
|
|
492
|
+
case TokenID.LIT_EMPTYSET:
|
|
493
|
+
case TokenID.LIT_WHOLE_NUMBERS:
|
|
494
|
+
return `${node.typeID}:${nodeTextKey(node)}`;
|
|
495
|
+
case TokenID.NT_FUNC_CALL:
|
|
496
|
+
return `${node.typeID}:${nodeTextKey(node.children[0])}(${node.children.slice(1).map(buildStructuralKey).join(",")})`;
|
|
497
|
+
case TokenID.BIGPR:
|
|
498
|
+
case TokenID.SMALLPR:
|
|
499
|
+
case TokenID.FILTER:
|
|
500
|
+
return `${node.typeID}:${indicesKey(node)}(${node.children.map(buildStructuralKey).join(",")})`;
|
|
501
|
+
default:
|
|
502
|
+
return `${node.typeID}(${node.children.map(buildStructuralKey).join(",")})`;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
function nodeTextKey(node) {
|
|
506
|
+
if (node.data.dataType === "number") {
|
|
507
|
+
return String(node.data.value);
|
|
508
|
+
}
|
|
509
|
+
return getNodeText(node);
|
|
510
|
+
}
|
|
511
|
+
function indicesKey(node) {
|
|
512
|
+
return getNodeIndices(node).join(".");
|
|
513
|
+
}
|
|
514
|
+
function collectReads(node, bound) {
|
|
515
|
+
const reads = /* @__PURE__ */ new Set();
|
|
516
|
+
collectReadsImpl(node, bound, reads);
|
|
517
|
+
return reads;
|
|
518
|
+
}
|
|
519
|
+
function collectReadsImpl(node, bound, reads) {
|
|
520
|
+
switch (node.typeID) {
|
|
521
|
+
case TokenID.ID_LOCAL:
|
|
522
|
+
case TokenID.ID_RADICAL: {
|
|
523
|
+
reads.add(getNodeText(node));
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
case TokenID.QUANTOR_UNIVERSAL:
|
|
527
|
+
case TokenID.QUANTOR_EXISTS: {
|
|
528
|
+
collectReadsImpl(node.children[1], bound, reads);
|
|
529
|
+
const innerBound = extendBound(bound, node.children[0]);
|
|
530
|
+
collectReadsImpl(node.children[2], innerBound, reads);
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
case TokenID.NT_DECLARATIVE_EXPR: {
|
|
534
|
+
collectReadsImpl(node.children[1], bound, reads);
|
|
535
|
+
const innerBound = extendBound(bound, node.children[0]);
|
|
536
|
+
collectReadsImpl(node.children[2], innerBound, reads);
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
case TokenID.ITERATE: {
|
|
540
|
+
collectReadsImpl(node.children[1], bound, reads);
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
case TokenID.ASSIGN: {
|
|
544
|
+
collectReadsImpl(node.children[1], bound, reads);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
case TokenID.NT_IMPERATIVE_EXPR: {
|
|
548
|
+
const innerBound = new Set(bound);
|
|
549
|
+
collectReadsImpl(node.children[0], innerBound, reads);
|
|
550
|
+
for (let i = 1; i < node.children.length; i++) {
|
|
551
|
+
const child = node.children[i];
|
|
552
|
+
if (child.typeID === TokenID.ITERATE) {
|
|
553
|
+
extendBoundInPlace(innerBound, child.children[0]);
|
|
554
|
+
collectReadsImpl(child.children[1], innerBound, reads);
|
|
555
|
+
} else if (child.typeID === TokenID.ASSIGN) {
|
|
556
|
+
collectReadsImpl(child.children[1], innerBound, reads);
|
|
557
|
+
extendBoundInPlace(innerBound, child.children[0]);
|
|
558
|
+
} else {
|
|
559
|
+
collectReadsImpl(child, innerBound, reads);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
case TokenID.NT_RECURSIVE_FULL:
|
|
565
|
+
case TokenID.NT_RECURSIVE_SHORT: {
|
|
566
|
+
collectReadsImpl(node.children[1], bound, reads);
|
|
567
|
+
const innerBound = extendBound(bound, node.children[0]);
|
|
568
|
+
if (node.typeID === TokenID.NT_RECURSIVE_FULL) {
|
|
569
|
+
collectReadsImpl(node.children[2], innerBound, reads);
|
|
570
|
+
collectReadsImpl(node.children[3], innerBound, reads);
|
|
571
|
+
} else {
|
|
572
|
+
collectReadsImpl(node.children[2], innerBound, reads);
|
|
573
|
+
}
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
case TokenID.NT_FUNC_DEFINITION: {
|
|
577
|
+
const innerBound = extendBound(bound, node.children[0]);
|
|
578
|
+
collectReadsImpl(node.children[1], innerBound, reads);
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
case TokenID.NT_FUNC_CALL: {
|
|
582
|
+
for (let i = 1; i < node.children.length; i++) {
|
|
583
|
+
collectReadsImpl(node.children[i], bound, reads);
|
|
584
|
+
}
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
case TokenID.LOGIC_AND:
|
|
588
|
+
case TokenID.LOGIC_OR:
|
|
589
|
+
case TokenID.LOGIC_IMPLICATION: {
|
|
590
|
+
collectReadsImpl(node.children[0], bound, reads);
|
|
591
|
+
collectReadsImpl(node.children[1], bound, reads);
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
default:
|
|
595
|
+
for (const child of node.children) {
|
|
596
|
+
collectReadsImpl(child, bound, reads);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
function extendBound(bound, declNode) {
|
|
601
|
+
const next = new Set(bound);
|
|
602
|
+
extendBoundInPlace(next, declNode);
|
|
603
|
+
return next;
|
|
604
|
+
}
|
|
605
|
+
function extendBoundInPlace(bound, declNode) {
|
|
606
|
+
switch (declNode.typeID) {
|
|
607
|
+
case TokenID.ID_LOCAL:
|
|
608
|
+
case TokenID.ID_RADICAL:
|
|
609
|
+
bound.add(getNodeText(declNode));
|
|
610
|
+
break;
|
|
611
|
+
case TokenID.NT_TUPLE_DECL:
|
|
612
|
+
case TokenID.NT_ENUM_DECL:
|
|
613
|
+
for (const child of declNode.children) {
|
|
614
|
+
extendBoundInPlace(bound, child);
|
|
615
|
+
}
|
|
616
|
+
break;
|
|
617
|
+
case TokenID.NT_ARG_DECL:
|
|
618
|
+
extendBoundInPlace(bound, declNode.children[0]);
|
|
619
|
+
break;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// src/rslang/semantic/typification.ts
|
|
624
|
+
var TypeID = {
|
|
625
|
+
anyTypification: 1,
|
|
626
|
+
integer: 2,
|
|
627
|
+
basic: 3,
|
|
628
|
+
tuple: 4,
|
|
629
|
+
collection: 5,
|
|
630
|
+
logic: 6,
|
|
631
|
+
function: 7,
|
|
632
|
+
predicate: 8
|
|
633
|
+
};
|
|
634
|
+
var TypeClass = {
|
|
635
|
+
logic: 1,
|
|
636
|
+
typification: 2,
|
|
637
|
+
function: 3,
|
|
638
|
+
predicate: 4
|
|
639
|
+
};
|
|
640
|
+
var LogicT = { typeID: TypeID.logic };
|
|
641
|
+
var IntegerT = {
|
|
642
|
+
typeID: TypeID.integer,
|
|
643
|
+
isOrdered: true,
|
|
644
|
+
isArithmetic: true,
|
|
645
|
+
isIntegerCompatible: true
|
|
646
|
+
};
|
|
647
|
+
var AnyTypificationT = { typeID: TypeID.anyTypification };
|
|
648
|
+
var EmptySetT = bool(AnyTypificationT);
|
|
649
|
+
function basic(alias) {
|
|
650
|
+
return { typeID: TypeID.basic, baseID: alias };
|
|
651
|
+
}
|
|
652
|
+
function constant(alias) {
|
|
653
|
+
return { typeID: TypeID.basic, baseID: alias, isOrdered: true, isArithmetic: true, isIntegerCompatible: true };
|
|
654
|
+
}
|
|
655
|
+
function bool(base) {
|
|
656
|
+
return { typeID: TypeID.collection, base };
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// src/rslang/eval/value-api.ts
|
|
660
|
+
function cartesianProduct(factors) {
|
|
661
|
+
const cardinality = factors.reduce((acc, f) => acc * f.length, 1);
|
|
662
|
+
if (cardinality > SET_INFINITY) {
|
|
663
|
+
return null;
|
|
664
|
+
}
|
|
665
|
+
if (cardinality === 0 || factors.length === 0) {
|
|
666
|
+
return EmptySetV;
|
|
667
|
+
}
|
|
668
|
+
let accumulator = [[]];
|
|
669
|
+
for (const factor of factors) {
|
|
670
|
+
const next = [];
|
|
671
|
+
for (const prefix of accumulator) {
|
|
672
|
+
for (const value of factor) {
|
|
673
|
+
next.push([...prefix, value]);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
accumulator = next;
|
|
677
|
+
}
|
|
678
|
+
return accumulator.map(tuple);
|
|
679
|
+
}
|
|
680
|
+
function boolean(base) {
|
|
681
|
+
if (base.length > BOOL_INFINITY) {
|
|
682
|
+
return null;
|
|
683
|
+
}
|
|
684
|
+
return powerset(base);
|
|
685
|
+
}
|
|
686
|
+
function powerset(arr) {
|
|
687
|
+
const result = [[]];
|
|
688
|
+
if (arr.length === 0) {
|
|
689
|
+
return result;
|
|
690
|
+
}
|
|
691
|
+
let current = [[]];
|
|
692
|
+
let maxIndex = [-1];
|
|
693
|
+
while (current.length > 0) {
|
|
694
|
+
const next = [];
|
|
695
|
+
const nextMaxIndex = [];
|
|
696
|
+
for (let i = 0; i < current.length; i++) {
|
|
697
|
+
for (let j = maxIndex[i] + 1; j < arr.length; j++) {
|
|
698
|
+
const subset = [...current[i], arr[j]];
|
|
699
|
+
result.push(subset);
|
|
700
|
+
if (j < arr.length - 1) {
|
|
701
|
+
next.push(subset);
|
|
702
|
+
nextMaxIndex.push(j);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
current = next;
|
|
707
|
+
maxIndex = nextMaxIndex;
|
|
708
|
+
}
|
|
709
|
+
return result;
|
|
710
|
+
}
|
|
711
|
+
function contains(setData, element) {
|
|
712
|
+
let left = 0;
|
|
713
|
+
let right = setData.length - 1;
|
|
714
|
+
while (left <= right) {
|
|
715
|
+
const mid = Math.floor((left + right) / 2);
|
|
716
|
+
const cmp = compare(setData[mid], element);
|
|
717
|
+
if (cmp === 0) {
|
|
718
|
+
return true;
|
|
719
|
+
} else if (cmp < 0) {
|
|
720
|
+
left = mid + 1;
|
|
721
|
+
} else {
|
|
722
|
+
right = mid - 1;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
return false;
|
|
726
|
+
}
|
|
727
|
+
function isSubsetOrEq(a, b) {
|
|
728
|
+
let i = 0, j = 0;
|
|
729
|
+
while (i < a.length && j < b.length) {
|
|
730
|
+
const cmp = compare(a[i], b[j]);
|
|
731
|
+
if (cmp === 0) {
|
|
732
|
+
i++;
|
|
733
|
+
j++;
|
|
734
|
+
} else if (cmp > 0) {
|
|
735
|
+
j++;
|
|
736
|
+
} else {
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
return i === a.length;
|
|
741
|
+
}
|
|
742
|
+
function reduce(target) {
|
|
743
|
+
const result = [];
|
|
744
|
+
for (const element of target) {
|
|
745
|
+
result.push(...element);
|
|
746
|
+
}
|
|
747
|
+
return set(result);
|
|
748
|
+
}
|
|
749
|
+
function setUnion(set1, set2) {
|
|
750
|
+
const result = [];
|
|
751
|
+
let i = 0, j = 0;
|
|
752
|
+
while (i < set1.length && j < set2.length) {
|
|
753
|
+
const cmp = compare(set1[i], set2[j]);
|
|
754
|
+
if (cmp < 0) {
|
|
755
|
+
result.push(set1[i]);
|
|
756
|
+
i++;
|
|
757
|
+
} else if (cmp > 0) {
|
|
758
|
+
result.push(set2[j]);
|
|
759
|
+
j++;
|
|
760
|
+
} else {
|
|
761
|
+
result.push(set1[i]);
|
|
762
|
+
i++;
|
|
763
|
+
j++;
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
while (i < set1.length) {
|
|
767
|
+
result.push(set1[i]);
|
|
768
|
+
i++;
|
|
769
|
+
}
|
|
770
|
+
while (j < set2.length) {
|
|
771
|
+
result.push(set2[j]);
|
|
772
|
+
j++;
|
|
773
|
+
}
|
|
774
|
+
return result;
|
|
775
|
+
}
|
|
776
|
+
function setIntersection(set1, set2) {
|
|
777
|
+
const result = [];
|
|
778
|
+
for (let i = 0, j = 0; i < set1.length && j < set2.length; ) {
|
|
779
|
+
const cmp = compare(set1[i], set2[j]);
|
|
780
|
+
if (cmp < 0) {
|
|
781
|
+
i++;
|
|
782
|
+
} else if (cmp > 0) {
|
|
783
|
+
j++;
|
|
784
|
+
} else {
|
|
785
|
+
result.push(set1[i]);
|
|
786
|
+
i++;
|
|
787
|
+
j++;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
return result;
|
|
791
|
+
}
|
|
792
|
+
function setDiff(set1, set2) {
|
|
793
|
+
const result = [];
|
|
794
|
+
let i = 0, j = 0;
|
|
795
|
+
while (i < set1.length && j < set2.length) {
|
|
796
|
+
const cmp = compare(set1[i], set2[j]);
|
|
797
|
+
if (cmp < 0) {
|
|
798
|
+
result.push(set1[i]);
|
|
799
|
+
i++;
|
|
800
|
+
} else if (cmp > 0) {
|
|
801
|
+
j++;
|
|
802
|
+
} else {
|
|
803
|
+
i++;
|
|
804
|
+
j++;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
while (i < set1.length) {
|
|
808
|
+
result.push(set1[i]);
|
|
809
|
+
i++;
|
|
810
|
+
}
|
|
811
|
+
return result;
|
|
812
|
+
}
|
|
813
|
+
function setSymDiff(set1, set2) {
|
|
814
|
+
const result = [];
|
|
815
|
+
let i = 0, j = 0;
|
|
816
|
+
while (i < set1.length && j < set2.length) {
|
|
817
|
+
const cmp = compare(set1[i], set2[j]);
|
|
818
|
+
if (cmp < 0) {
|
|
819
|
+
result.push(set1[i]);
|
|
820
|
+
i++;
|
|
821
|
+
} else if (cmp > 0) {
|
|
822
|
+
result.push(set2[j]);
|
|
823
|
+
j++;
|
|
824
|
+
} else {
|
|
825
|
+
i++;
|
|
826
|
+
j++;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
while (i < set1.length) {
|
|
830
|
+
result.push(set1[i]);
|
|
831
|
+
i++;
|
|
832
|
+
}
|
|
833
|
+
while (j < set2.length) {
|
|
834
|
+
result.push(set2[j]);
|
|
835
|
+
j++;
|
|
836
|
+
}
|
|
837
|
+
return result;
|
|
838
|
+
}
|
|
839
|
+
function projection(target, indices) {
|
|
840
|
+
const projectedElements = target.map((element) => {
|
|
841
|
+
const newComponents = indices.map((idx) => element[idx]);
|
|
842
|
+
return indices.length === 1 ? newComponents[0] : tuple(newComponents);
|
|
843
|
+
});
|
|
844
|
+
return set(projectedElements);
|
|
845
|
+
}
|
|
846
|
+
function printValue(data) {
|
|
847
|
+
if (!Array.isArray(data)) {
|
|
848
|
+
return String(data);
|
|
849
|
+
}
|
|
850
|
+
const len = data.length;
|
|
851
|
+
if (data.length === 0) {
|
|
852
|
+
return "{}";
|
|
853
|
+
}
|
|
854
|
+
const isTuple = data[0] === TUPLE_ID;
|
|
855
|
+
const start = isTuple ? 1 : 0;
|
|
856
|
+
let result = isTuple ? "(" : "{";
|
|
857
|
+
for (let i = start; i < len; i++) {
|
|
858
|
+
if (i > start) result += ", ";
|
|
859
|
+
result += printValue(data[i]);
|
|
860
|
+
}
|
|
861
|
+
result += isTuple ? ")" : "}";
|
|
862
|
+
return result;
|
|
863
|
+
}
|
|
864
|
+
function isSetValue(data) {
|
|
865
|
+
return Array.isArray(data) && (data.length === 0 || data[0] !== TUPLE_ID);
|
|
866
|
+
}
|
|
867
|
+
function isTupleValue(data) {
|
|
868
|
+
return Array.isArray(data) && data.length > 1 && data[0] === TUPLE_ID;
|
|
869
|
+
}
|
|
870
|
+
function validateValue(value, type, basics) {
|
|
871
|
+
switch (type.typeID) {
|
|
872
|
+
case TypeID.integer:
|
|
873
|
+
return typeof value === "number";
|
|
874
|
+
case TypeID.logic: {
|
|
875
|
+
if (typeof value !== "number") {
|
|
876
|
+
return false;
|
|
877
|
+
}
|
|
878
|
+
return value === VALUE_TRUE || value === VALUE_FALSE;
|
|
879
|
+
}
|
|
880
|
+
case TypeID.basic: {
|
|
881
|
+
if (typeof value !== "number") {
|
|
882
|
+
return false;
|
|
883
|
+
}
|
|
884
|
+
const domain = basics.get(type.baseID);
|
|
885
|
+
return !!domain && Array.isArray(domain) && domain.includes(value);
|
|
886
|
+
}
|
|
887
|
+
case TypeID.tuple: {
|
|
888
|
+
if (!Array.isArray(value) || value.length !== type.factors.length + 1 || value[0] !== TUPLE_ID) {
|
|
889
|
+
return false;
|
|
890
|
+
}
|
|
891
|
+
for (let i = 0; i < type.factors.length; i++) {
|
|
892
|
+
if (!validateValue(value[i + 1], type.factors[i], basics)) {
|
|
893
|
+
return false;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
return true;
|
|
897
|
+
}
|
|
898
|
+
case TypeID.collection: {
|
|
899
|
+
if (!isSetValue(value)) {
|
|
900
|
+
return false;
|
|
901
|
+
}
|
|
902
|
+
for (const item of value) {
|
|
903
|
+
if (!validateValue(item, type.base, basics)) {
|
|
904
|
+
return false;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
return true;
|
|
908
|
+
}
|
|
909
|
+
case TypeID.anyTypification:
|
|
910
|
+
case TypeID.predicate:
|
|
911
|
+
case TypeID.function:
|
|
912
|
+
return false;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// src/rslang/eval/value.ts
|
|
917
|
+
var TUPLE_ID = -111;
|
|
918
|
+
var VALUE_TRUE = 1;
|
|
919
|
+
var VALUE_FALSE = 0;
|
|
920
|
+
var SET_INFINITY = 1e7;
|
|
921
|
+
var BOOL_INFINITY = 18;
|
|
922
|
+
var EmptySetV = [];
|
|
923
|
+
function compare(v1, v2) {
|
|
924
|
+
const stack1 = [v1];
|
|
925
|
+
const stack2 = [v2];
|
|
926
|
+
while (stack1.length > 0 && stack2.length > 0) {
|
|
927
|
+
const el1 = stack1.pop();
|
|
928
|
+
const el2 = stack2.pop();
|
|
929
|
+
if (el1 === el2) {
|
|
930
|
+
continue;
|
|
931
|
+
}
|
|
932
|
+
const type1 = typeof el1;
|
|
933
|
+
const type2 = typeof el2;
|
|
934
|
+
if (type1 === "number" && type2 === "number") {
|
|
935
|
+
const numDiff = el1 - el2;
|
|
936
|
+
if (numDiff !== 0) return numDiff;
|
|
937
|
+
continue;
|
|
938
|
+
}
|
|
939
|
+
const isArray1 = Array.isArray(el1);
|
|
940
|
+
const isArray2 = Array.isArray(el2);
|
|
941
|
+
if (!isArray1 || !isArray2) {
|
|
942
|
+
throw new Error(`Cannot compare different types ${printValue(el1)} and ${printValue(el2)}`);
|
|
943
|
+
}
|
|
944
|
+
const arr1 = el1;
|
|
945
|
+
const arr2 = el2;
|
|
946
|
+
const len1 = arr1.length;
|
|
947
|
+
const len2 = arr2.length;
|
|
948
|
+
if (len1 !== len2) {
|
|
949
|
+
return len1 - len2;
|
|
950
|
+
}
|
|
951
|
+
for (let i = len1 - 1; i >= 0; i--) {
|
|
952
|
+
stack1.push(arr1[i]);
|
|
953
|
+
stack2.push(arr2[i]);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
return 0;
|
|
957
|
+
}
|
|
958
|
+
function tuple(components) {
|
|
959
|
+
return [TUPLE_ID, ...components];
|
|
960
|
+
}
|
|
961
|
+
function set(elements) {
|
|
962
|
+
const sorted = [...elements].sort(compare);
|
|
963
|
+
for (let i = 1; i < sorted.length; ) {
|
|
964
|
+
if (compare(sorted[i - 1], sorted[i]) === 0) {
|
|
965
|
+
sorted.splice(i, 1);
|
|
966
|
+
} else {
|
|
967
|
+
i++;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
return sorted;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
// src/rslang/eval/evaluator.ts
|
|
974
|
+
var MAX_ITERATIONS = 1e6;
|
|
975
|
+
var TICK_PER_FUNCTION = 3;
|
|
976
|
+
var TICK_PER_RECURSION = 3;
|
|
977
|
+
var TICK_PER_IMPERATIVE = 1;
|
|
978
|
+
var TICK_PER_DECLARATIVE = 1;
|
|
979
|
+
var TICK_PER_QUANTIFIER = 1;
|
|
980
|
+
var Evaluator = class {
|
|
981
|
+
reporter;
|
|
982
|
+
annotateErrors = false;
|
|
983
|
+
disableCache = false;
|
|
984
|
+
locals = new LocalContext();
|
|
985
|
+
nodeMetadata = new EvaluationMetadata();
|
|
986
|
+
evalCache = new EvaluationCache();
|
|
987
|
+
callSiteStack = [];
|
|
988
|
+
context;
|
|
989
|
+
treeContext;
|
|
990
|
+
iterationCounter = 0;
|
|
991
|
+
/** Cache hits in the current evaluation run (for tests/diagnostics). */
|
|
992
|
+
get cacheHits() {
|
|
993
|
+
return this.evalCache.hits;
|
|
994
|
+
}
|
|
995
|
+
constructor(context, astContext) {
|
|
996
|
+
this.treeContext = astContext;
|
|
997
|
+
this.context = context;
|
|
998
|
+
}
|
|
999
|
+
run(ast, reporter, annotateErrors = false, disableCache = false) {
|
|
1000
|
+
if (ast.hasError) {
|
|
1001
|
+
return null;
|
|
1002
|
+
}
|
|
1003
|
+
this.reporter = reporter;
|
|
1004
|
+
this.annotateErrors = annotateErrors;
|
|
1005
|
+
this.disableCache = disableCache;
|
|
1006
|
+
this.clear();
|
|
1007
|
+
return this.dispatchVisit(ast);
|
|
1008
|
+
}
|
|
1009
|
+
clear() {
|
|
1010
|
+
this.locals = new LocalContext();
|
|
1011
|
+
this.evalCache.clear();
|
|
1012
|
+
this.callSiteStack = [];
|
|
1013
|
+
this.iterationCounter = 0;
|
|
1014
|
+
}
|
|
1015
|
+
errorNode(node) {
|
|
1016
|
+
if (this.callSiteStack.length > 0) {
|
|
1017
|
+
return this.callSiteStack[this.callSiteStack.length - 1];
|
|
1018
|
+
}
|
|
1019
|
+
return node;
|
|
1020
|
+
}
|
|
1021
|
+
onError(code, node, params) {
|
|
1022
|
+
const target = this.errorNode(node);
|
|
1023
|
+
this.reporter?.({ code, from: target.from, to: target.to, params });
|
|
1024
|
+
if (this.annotateErrors) {
|
|
1025
|
+
annotateError(target, code, params);
|
|
1026
|
+
}
|
|
1027
|
+
return null;
|
|
1028
|
+
}
|
|
1029
|
+
tick(node, counter = 1) {
|
|
1030
|
+
this.iterationCounter += counter;
|
|
1031
|
+
if (this.iterationCounter > MAX_ITERATIONS) {
|
|
1032
|
+
this.onError(RSErrorCode.iterationsLimit, node, [String(MAX_ITERATIONS)]);
|
|
1033
|
+
return false;
|
|
1034
|
+
}
|
|
1035
|
+
return true;
|
|
1036
|
+
}
|
|
1037
|
+
dispatchDeclare(node, value) {
|
|
1038
|
+
switch (node.typeID) {
|
|
1039
|
+
case TokenID.ID_LOCAL:
|
|
1040
|
+
return this.declareLocal(node, value);
|
|
1041
|
+
case TokenID.NT_TUPLE_DECL:
|
|
1042
|
+
return this.declareTuple(node, value);
|
|
1043
|
+
case TokenID.NT_ARG_DECL:
|
|
1044
|
+
return this.dispatchDeclare(node.children[0], value);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
declareLocal(node, value) {
|
|
1048
|
+
const alias = getNodeText(node);
|
|
1049
|
+
this.locals.setLocal(alias, value);
|
|
1050
|
+
}
|
|
1051
|
+
declareTuple(node, value) {
|
|
1052
|
+
for (let child = 0; child < node.children.length; child++) {
|
|
1053
|
+
this.dispatchDeclare(node.children[child], value[child + 1]);
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
dispatchVisit(node) {
|
|
1057
|
+
const info = this.nodeMetadata.get(node);
|
|
1058
|
+
let stamp = null;
|
|
1059
|
+
if (info.cacheable && !this.disableCache) {
|
|
1060
|
+
stamp = this.locals.buildDependencyStamp(info.reads);
|
|
1061
|
+
if (stamp !== null) {
|
|
1062
|
+
const cached = this.evalCache.lookup(info.structuralKey, stamp);
|
|
1063
|
+
if (cached !== void 0) {
|
|
1064
|
+
return cached;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
const result = this.dispatchVisitImpl(node);
|
|
1069
|
+
if (!this.disableCache && result !== null && info.cacheable && stamp !== null) {
|
|
1070
|
+
this.evalCache.store(info.structuralKey, stamp, result);
|
|
1071
|
+
}
|
|
1072
|
+
return result;
|
|
1073
|
+
}
|
|
1074
|
+
dispatchVisitImpl(node) {
|
|
1075
|
+
switch (node.typeID) {
|
|
1076
|
+
case TokenID.ID_GLOBAL:
|
|
1077
|
+
return this.visitGlobal(node);
|
|
1078
|
+
case TokenID.NT_FUNC_CALL:
|
|
1079
|
+
return this.visitFunctionCall(node);
|
|
1080
|
+
case TokenID.ID_LOCAL:
|
|
1081
|
+
case TokenID.ID_RADICAL:
|
|
1082
|
+
return this.visitLocal(node);
|
|
1083
|
+
case TokenID.LIT_INTEGER:
|
|
1084
|
+
return this.visitInteger(node);
|
|
1085
|
+
case TokenID.LIT_WHOLE_NUMBERS:
|
|
1086
|
+
return this.onError(RSErrorCode.iterateInfinity, node);
|
|
1087
|
+
case TokenID.LIT_EMPTYSET:
|
|
1088
|
+
return EmptySetV;
|
|
1089
|
+
case TokenID.PLUS:
|
|
1090
|
+
case TokenID.MINUS:
|
|
1091
|
+
case TokenID.MULTIPLY:
|
|
1092
|
+
return this.visitArithmetic(node);
|
|
1093
|
+
case TokenID.CARD:
|
|
1094
|
+
return this.visitCard(node);
|
|
1095
|
+
case TokenID.QUANTOR_UNIVERSAL:
|
|
1096
|
+
case TokenID.QUANTOR_EXISTS:
|
|
1097
|
+
return this.visitQuantifier(node);
|
|
1098
|
+
case TokenID.LOGIC_NOT:
|
|
1099
|
+
return this.visitNegation(node);
|
|
1100
|
+
case TokenID.LOGIC_AND:
|
|
1101
|
+
case TokenID.LOGIC_OR:
|
|
1102
|
+
case TokenID.LOGIC_IMPLICATION:
|
|
1103
|
+
case TokenID.LOGIC_EQUIVALENT:
|
|
1104
|
+
return this.visitLogicBinary(node);
|
|
1105
|
+
case TokenID.EQUAL:
|
|
1106
|
+
case TokenID.NOTEQUAL:
|
|
1107
|
+
return this.visitEquals(node);
|
|
1108
|
+
case TokenID.GREATER:
|
|
1109
|
+
case TokenID.LESSER:
|
|
1110
|
+
case TokenID.GREATER_OR_EQ:
|
|
1111
|
+
case TokenID.LESSER_OR_EQ:
|
|
1112
|
+
return this.visitIntegerPredicate(node);
|
|
1113
|
+
case TokenID.SET_IN:
|
|
1114
|
+
case TokenID.SET_NOT_IN:
|
|
1115
|
+
case TokenID.SUBSET:
|
|
1116
|
+
case TokenID.SUBSET_OR_EQ:
|
|
1117
|
+
case TokenID.NOT_SUBSET:
|
|
1118
|
+
return this.visitSetexprPredicate(node);
|
|
1119
|
+
case TokenID.DECART:
|
|
1120
|
+
return this.visitDecart(node);
|
|
1121
|
+
case TokenID.BOOLEAN:
|
|
1122
|
+
return this.visitBoolean(node);
|
|
1123
|
+
case TokenID.NT_TUPLE:
|
|
1124
|
+
return this.visitTuple(node);
|
|
1125
|
+
case TokenID.NT_ENUMERATION:
|
|
1126
|
+
return this.visitEnumeration(node);
|
|
1127
|
+
case TokenID.BOOL:
|
|
1128
|
+
return this.visitBool(node);
|
|
1129
|
+
case TokenID.DEBOOL:
|
|
1130
|
+
return this.visitDebool(node);
|
|
1131
|
+
case TokenID.SET_UNION:
|
|
1132
|
+
case TokenID.SET_INTERSECTION:
|
|
1133
|
+
case TokenID.SET_MINUS:
|
|
1134
|
+
case TokenID.SET_SYMMETRIC_MINUS:
|
|
1135
|
+
return this.visitSetexprBinary(node);
|
|
1136
|
+
case TokenID.BIGPR:
|
|
1137
|
+
return this.visitProjectSet(node);
|
|
1138
|
+
case TokenID.SMALLPR:
|
|
1139
|
+
return this.visitProjectTuple(node);
|
|
1140
|
+
case TokenID.FILTER:
|
|
1141
|
+
return this.visitFilter(node);
|
|
1142
|
+
case TokenID.REDUCE:
|
|
1143
|
+
return this.visitReduce(node);
|
|
1144
|
+
case TokenID.NT_DECLARATIVE_EXPR:
|
|
1145
|
+
return this.visitDeclarative(node);
|
|
1146
|
+
case TokenID.NT_IMPERATIVE_EXPR:
|
|
1147
|
+
return this.visitImperative(node);
|
|
1148
|
+
case TokenID.ASSIGN:
|
|
1149
|
+
return this.visitAssign(node);
|
|
1150
|
+
case TokenID.NT_RECURSIVE_FULL:
|
|
1151
|
+
case TokenID.NT_RECURSIVE_SHORT:
|
|
1152
|
+
return this.visitRecursion(node);
|
|
1153
|
+
case TokenID.NT_FUNC_DEFINITION:
|
|
1154
|
+
return this.onError(RSErrorCode.calculationNotSupported, node);
|
|
1155
|
+
}
|
|
1156
|
+
return null;
|
|
1157
|
+
}
|
|
1158
|
+
visitChild(node, index) {
|
|
1159
|
+
return this.dispatchVisit(node.children[index]);
|
|
1160
|
+
}
|
|
1161
|
+
visitGlobal(node) {
|
|
1162
|
+
const alias = getNodeText(node);
|
|
1163
|
+
const value = this.context.get(alias);
|
|
1164
|
+
if (value === void 0) {
|
|
1165
|
+
return this.onError(RSErrorCode.calcGlobalMissing, node, [alias]);
|
|
1166
|
+
}
|
|
1167
|
+
return value;
|
|
1168
|
+
}
|
|
1169
|
+
visitLocal(node) {
|
|
1170
|
+
const alias = getNodeText(node);
|
|
1171
|
+
return this.locals.getLocal(alias);
|
|
1172
|
+
}
|
|
1173
|
+
visitFunctionCall(node) {
|
|
1174
|
+
const funcName = getNodeText(node.children[0]);
|
|
1175
|
+
const ast = this.treeContext.get(funcName);
|
|
1176
|
+
if (!ast) {
|
|
1177
|
+
return this.onError(RSErrorCode.calcGlobalMissing, node.children[0], [funcName]);
|
|
1178
|
+
}
|
|
1179
|
+
if (!this.tick(node, TICK_PER_FUNCTION)) {
|
|
1180
|
+
return null;
|
|
1181
|
+
}
|
|
1182
|
+
const args = [];
|
|
1183
|
+
for (let i = 1; i < node.children.length; i++) {
|
|
1184
|
+
const arg = this.visitChild(node, i);
|
|
1185
|
+
if (arg === null) {
|
|
1186
|
+
return null;
|
|
1187
|
+
}
|
|
1188
|
+
args.push(arg);
|
|
1189
|
+
}
|
|
1190
|
+
this.locals.startScope();
|
|
1191
|
+
for (let i = 0; i < args.length; i++) {
|
|
1192
|
+
this.dispatchDeclare(ast.children[0].children[i], args[i]);
|
|
1193
|
+
}
|
|
1194
|
+
this.callSiteStack.push(node);
|
|
1195
|
+
let result;
|
|
1196
|
+
try {
|
|
1197
|
+
result = this.visitChild(ast, 1);
|
|
1198
|
+
} finally {
|
|
1199
|
+
this.callSiteStack.pop();
|
|
1200
|
+
}
|
|
1201
|
+
this.locals.endScope();
|
|
1202
|
+
return result;
|
|
1203
|
+
}
|
|
1204
|
+
visitInteger(node) {
|
|
1205
|
+
const value = node.data.dataType === "number" ? node.data.value : Number(node.data.value);
|
|
1206
|
+
return Math.floor(value);
|
|
1207
|
+
}
|
|
1208
|
+
visitArithmetic(node) {
|
|
1209
|
+
const v1 = this.visitChild(node, 0);
|
|
1210
|
+
const v2 = this.visitChild(node, 1);
|
|
1211
|
+
if (v1 === null || v2 === null) {
|
|
1212
|
+
return null;
|
|
1213
|
+
}
|
|
1214
|
+
const a = v1;
|
|
1215
|
+
const b = v2;
|
|
1216
|
+
switch (node.typeID) {
|
|
1217
|
+
case TokenID.PLUS:
|
|
1218
|
+
return a + b;
|
|
1219
|
+
case TokenID.MINUS:
|
|
1220
|
+
return a - b;
|
|
1221
|
+
case TokenID.MULTIPLY:
|
|
1222
|
+
return a * b;
|
|
1223
|
+
}
|
|
1224
|
+
return null;
|
|
1225
|
+
}
|
|
1226
|
+
visitCard(node) {
|
|
1227
|
+
const base = this.visitChild(node, 0);
|
|
1228
|
+
if (base === null || !Array.isArray(base)) {
|
|
1229
|
+
return null;
|
|
1230
|
+
}
|
|
1231
|
+
return base.length;
|
|
1232
|
+
}
|
|
1233
|
+
visitQuantifier(node) {
|
|
1234
|
+
const domain = this.visitChild(node, 1);
|
|
1235
|
+
if (domain === null) {
|
|
1236
|
+
return null;
|
|
1237
|
+
}
|
|
1238
|
+
const isUniversal = node.typeID === TokenID.QUANTOR_UNIVERSAL;
|
|
1239
|
+
if (domain.length === 0) {
|
|
1240
|
+
return isUniversal ? VALUE_TRUE : VALUE_FALSE;
|
|
1241
|
+
}
|
|
1242
|
+
const varNodes = node.children[0].typeID === TokenID.NT_ENUM_DECL ? node.children[0].children : [node.children[0]];
|
|
1243
|
+
const count = domain.length;
|
|
1244
|
+
const iterators = [];
|
|
1245
|
+
for (const declaration of varNodes) {
|
|
1246
|
+
iterators.push(0);
|
|
1247
|
+
this.dispatchDeclare(declaration, domain[0]);
|
|
1248
|
+
}
|
|
1249
|
+
let finishIteration = false;
|
|
1250
|
+
while (!finishIteration) {
|
|
1251
|
+
const iterationValue = this.visitChild(node, 2);
|
|
1252
|
+
if (iterationValue === null) {
|
|
1253
|
+
return null;
|
|
1254
|
+
}
|
|
1255
|
+
if (iterationValue === VALUE_TRUE !== isUniversal) {
|
|
1256
|
+
return !isUniversal ? VALUE_TRUE : VALUE_FALSE;
|
|
1257
|
+
}
|
|
1258
|
+
let incrementIndex = iterators.length - 1;
|
|
1259
|
+
while (true) {
|
|
1260
|
+
if (iterators[incrementIndex] < count - 1) {
|
|
1261
|
+
iterators[incrementIndex]++;
|
|
1262
|
+
if (!this.tick(node, TICK_PER_QUANTIFIER)) {
|
|
1263
|
+
return null;
|
|
1264
|
+
}
|
|
1265
|
+
this.dispatchDeclare(varNodes[incrementIndex], domain[iterators[incrementIndex]]);
|
|
1266
|
+
incrementIndex = iterators.length - 1;
|
|
1267
|
+
break;
|
|
1268
|
+
} else if (incrementIndex === 0) {
|
|
1269
|
+
finishIteration = true;
|
|
1270
|
+
break;
|
|
1271
|
+
} else {
|
|
1272
|
+
iterators[incrementIndex] = 0;
|
|
1273
|
+
this.dispatchDeclare(varNodes[incrementIndex], domain[0]);
|
|
1274
|
+
incrementIndex--;
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
return isUniversal ? VALUE_TRUE : VALUE_FALSE;
|
|
1279
|
+
}
|
|
1280
|
+
visitNegation(node) {
|
|
1281
|
+
const value = this.visitChild(node, 0);
|
|
1282
|
+
if (value === null) {
|
|
1283
|
+
return null;
|
|
1284
|
+
}
|
|
1285
|
+
return value === VALUE_TRUE ? VALUE_FALSE : VALUE_TRUE;
|
|
1286
|
+
}
|
|
1287
|
+
tryEvaluateFromFirstArg(op, first) {
|
|
1288
|
+
if (op === TokenID.LOGIC_AND && !first || op === TokenID.LOGIC_OR && first) {
|
|
1289
|
+
return first ? VALUE_TRUE : VALUE_FALSE;
|
|
1290
|
+
}
|
|
1291
|
+
if (op === TokenID.LOGIC_IMPLICATION && !first) {
|
|
1292
|
+
return VALUE_TRUE;
|
|
1293
|
+
}
|
|
1294
|
+
return null;
|
|
1295
|
+
}
|
|
1296
|
+
visitLogicBinary(node) {
|
|
1297
|
+
const v1 = this.visitChild(node, 0);
|
|
1298
|
+
if (v1 === null) {
|
|
1299
|
+
return null;
|
|
1300
|
+
}
|
|
1301
|
+
const b1 = v1 === VALUE_TRUE;
|
|
1302
|
+
const attempt = this.tryEvaluateFromFirstArg(node.typeID, b1);
|
|
1303
|
+
if (attempt !== null) {
|
|
1304
|
+
return attempt;
|
|
1305
|
+
}
|
|
1306
|
+
const v2 = this.visitChild(node, 1);
|
|
1307
|
+
if (v2 === null) {
|
|
1308
|
+
return null;
|
|
1309
|
+
}
|
|
1310
|
+
const b2 = v2 === VALUE_TRUE;
|
|
1311
|
+
let result;
|
|
1312
|
+
switch (node.typeID) {
|
|
1313
|
+
case TokenID.LOGIC_AND:
|
|
1314
|
+
result = b1 && b2;
|
|
1315
|
+
break;
|
|
1316
|
+
case TokenID.LOGIC_OR:
|
|
1317
|
+
result = b1 || b2;
|
|
1318
|
+
break;
|
|
1319
|
+
case TokenID.LOGIC_IMPLICATION:
|
|
1320
|
+
result = !b1 || b2;
|
|
1321
|
+
break;
|
|
1322
|
+
case TokenID.LOGIC_EQUIVALENT:
|
|
1323
|
+
result = b1 === b2;
|
|
1324
|
+
break;
|
|
1325
|
+
default:
|
|
1326
|
+
return null;
|
|
1327
|
+
}
|
|
1328
|
+
return result ? VALUE_TRUE : VALUE_FALSE;
|
|
1329
|
+
}
|
|
1330
|
+
visitEquals(node) {
|
|
1331
|
+
const v1 = this.visitChild(node, 0);
|
|
1332
|
+
if (v1 === null) {
|
|
1333
|
+
return null;
|
|
1334
|
+
}
|
|
1335
|
+
const v2 = this.visitChild(node, 1);
|
|
1336
|
+
if (v2 === null) {
|
|
1337
|
+
return null;
|
|
1338
|
+
}
|
|
1339
|
+
const areEqual = compare(v1, v2) === 0;
|
|
1340
|
+
return areEqual === (node.typeID !== TokenID.NOTEQUAL) ? VALUE_TRUE : VALUE_FALSE;
|
|
1341
|
+
}
|
|
1342
|
+
visitIntegerPredicate(node) {
|
|
1343
|
+
const v1 = this.visitChild(node, 0);
|
|
1344
|
+
if (v1 === null) {
|
|
1345
|
+
return null;
|
|
1346
|
+
}
|
|
1347
|
+
const v2 = this.visitChild(node, 1);
|
|
1348
|
+
if (v2 === null) {
|
|
1349
|
+
return null;
|
|
1350
|
+
}
|
|
1351
|
+
const a = v1;
|
|
1352
|
+
const b = v2;
|
|
1353
|
+
let result;
|
|
1354
|
+
switch (node.typeID) {
|
|
1355
|
+
case TokenID.GREATER:
|
|
1356
|
+
result = a > b;
|
|
1357
|
+
break;
|
|
1358
|
+
case TokenID.LESSER:
|
|
1359
|
+
result = a < b;
|
|
1360
|
+
break;
|
|
1361
|
+
case TokenID.GREATER_OR_EQ:
|
|
1362
|
+
result = a >= b;
|
|
1363
|
+
break;
|
|
1364
|
+
case TokenID.LESSER_OR_EQ:
|
|
1365
|
+
result = a <= b;
|
|
1366
|
+
break;
|
|
1367
|
+
default:
|
|
1368
|
+
return null;
|
|
1369
|
+
}
|
|
1370
|
+
return result ? VALUE_TRUE : VALUE_FALSE;
|
|
1371
|
+
}
|
|
1372
|
+
visitSetexprPredicate(node) {
|
|
1373
|
+
const v1 = this.visitChild(node, 0);
|
|
1374
|
+
if (v1 === null) {
|
|
1375
|
+
return null;
|
|
1376
|
+
}
|
|
1377
|
+
const v2 = this.visitChild(node, 1);
|
|
1378
|
+
if (v2 === null) {
|
|
1379
|
+
return null;
|
|
1380
|
+
}
|
|
1381
|
+
let result;
|
|
1382
|
+
switch (node.typeID) {
|
|
1383
|
+
case TokenID.SET_IN:
|
|
1384
|
+
result = contains(v2, v1);
|
|
1385
|
+
break;
|
|
1386
|
+
case TokenID.SET_NOT_IN:
|
|
1387
|
+
result = !contains(v2, v1);
|
|
1388
|
+
break;
|
|
1389
|
+
case TokenID.SUBSET:
|
|
1390
|
+
result = compare(v1, v2) !== 0 && isSubsetOrEq(v1, v2);
|
|
1391
|
+
break;
|
|
1392
|
+
case TokenID.NOT_SUBSET:
|
|
1393
|
+
result = compare(v1, v2) === 0 || !isSubsetOrEq(v1, v2);
|
|
1394
|
+
break;
|
|
1395
|
+
case TokenID.SUBSET_OR_EQ:
|
|
1396
|
+
result = isSubsetOrEq(v1, v2);
|
|
1397
|
+
break;
|
|
1398
|
+
default:
|
|
1399
|
+
return null;
|
|
1400
|
+
}
|
|
1401
|
+
return result ? VALUE_TRUE : VALUE_FALSE;
|
|
1402
|
+
}
|
|
1403
|
+
visitDecart(node) {
|
|
1404
|
+
const args = [];
|
|
1405
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
1406
|
+
const component2 = this.visitChild(node, i);
|
|
1407
|
+
if (component2 === null) {
|
|
1408
|
+
return null;
|
|
1409
|
+
}
|
|
1410
|
+
if (component2.length === 0) {
|
|
1411
|
+
return EmptySetV;
|
|
1412
|
+
}
|
|
1413
|
+
args.push(component2);
|
|
1414
|
+
}
|
|
1415
|
+
const result = cartesianProduct(args);
|
|
1416
|
+
if (result === null) {
|
|
1417
|
+
this.onError(RSErrorCode.setOverflow, node, [String(SET_INFINITY)]);
|
|
1418
|
+
return null;
|
|
1419
|
+
}
|
|
1420
|
+
return result;
|
|
1421
|
+
}
|
|
1422
|
+
visitBoolean(node) {
|
|
1423
|
+
const base = this.visitChild(node, 0);
|
|
1424
|
+
if (base === null) {
|
|
1425
|
+
return null;
|
|
1426
|
+
}
|
|
1427
|
+
const result = boolean(base);
|
|
1428
|
+
if (result === null) {
|
|
1429
|
+
this.onError(RSErrorCode.booleanBaseLimit, node.children[0], [String(BOOL_INFINITY)]);
|
|
1430
|
+
return null;
|
|
1431
|
+
}
|
|
1432
|
+
return result;
|
|
1433
|
+
}
|
|
1434
|
+
visitTuple(node) {
|
|
1435
|
+
const args = [];
|
|
1436
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
1437
|
+
const component2 = this.visitChild(node, i);
|
|
1438
|
+
if (component2 === null) {
|
|
1439
|
+
return null;
|
|
1440
|
+
}
|
|
1441
|
+
args.push(component2);
|
|
1442
|
+
}
|
|
1443
|
+
return tuple(args);
|
|
1444
|
+
}
|
|
1445
|
+
visitEnumeration(node) {
|
|
1446
|
+
const args = [];
|
|
1447
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
1448
|
+
const element = this.visitChild(node, i);
|
|
1449
|
+
if (element === null) {
|
|
1450
|
+
return null;
|
|
1451
|
+
}
|
|
1452
|
+
args.push(element);
|
|
1453
|
+
}
|
|
1454
|
+
return set(args);
|
|
1455
|
+
}
|
|
1456
|
+
visitBool(node) {
|
|
1457
|
+
const element = this.visitChild(node, 0);
|
|
1458
|
+
if (element === null) {
|
|
1459
|
+
return null;
|
|
1460
|
+
}
|
|
1461
|
+
return [element];
|
|
1462
|
+
}
|
|
1463
|
+
visitDebool(node) {
|
|
1464
|
+
const target = this.visitChild(node, 0);
|
|
1465
|
+
if (target === null) {
|
|
1466
|
+
return null;
|
|
1467
|
+
}
|
|
1468
|
+
if (target.length !== 1) {
|
|
1469
|
+
return this.onError(RSErrorCode.calcInvalidDebool, node.children[0]);
|
|
1470
|
+
}
|
|
1471
|
+
return target[0];
|
|
1472
|
+
}
|
|
1473
|
+
visitSetexprBinary(node) {
|
|
1474
|
+
const v1 = this.visitChild(node, 0);
|
|
1475
|
+
if (v1 === null) {
|
|
1476
|
+
return null;
|
|
1477
|
+
}
|
|
1478
|
+
const v2 = this.visitChild(node, 1);
|
|
1479
|
+
if (v2 === null) {
|
|
1480
|
+
return null;
|
|
1481
|
+
}
|
|
1482
|
+
switch (node.typeID) {
|
|
1483
|
+
case TokenID.SET_UNION:
|
|
1484
|
+
return setUnion(v1, v2);
|
|
1485
|
+
case TokenID.SET_INTERSECTION:
|
|
1486
|
+
return setIntersection(v1, v2);
|
|
1487
|
+
case TokenID.SET_MINUS:
|
|
1488
|
+
return setDiff(v1, v2);
|
|
1489
|
+
case TokenID.SET_SYMMETRIC_MINUS:
|
|
1490
|
+
return setSymDiff(v1, v2);
|
|
1491
|
+
}
|
|
1492
|
+
return null;
|
|
1493
|
+
}
|
|
1494
|
+
visitProjectSet(node) {
|
|
1495
|
+
const target = this.visitChild(node, 0);
|
|
1496
|
+
if (target === null) {
|
|
1497
|
+
return null;
|
|
1498
|
+
}
|
|
1499
|
+
const indices = getNodeIndices(node);
|
|
1500
|
+
return projection(target, indices);
|
|
1501
|
+
}
|
|
1502
|
+
visitProjectTuple(node) {
|
|
1503
|
+
const target = this.visitChild(node, 0);
|
|
1504
|
+
if (target === null) {
|
|
1505
|
+
return null;
|
|
1506
|
+
}
|
|
1507
|
+
const indices = getNodeIndices(node);
|
|
1508
|
+
const components = indices.map((i) => target[i]);
|
|
1509
|
+
return components.length === 1 ? components[0] : tuple(components);
|
|
1510
|
+
}
|
|
1511
|
+
visitFilter(node) {
|
|
1512
|
+
const lastIdx = node.children.length - 1;
|
|
1513
|
+
const argVal = this.visitChild(node, lastIdx);
|
|
1514
|
+
if (argVal === null) {
|
|
1515
|
+
return null;
|
|
1516
|
+
}
|
|
1517
|
+
if (argVal.length === 0) {
|
|
1518
|
+
return EmptySetV;
|
|
1519
|
+
}
|
|
1520
|
+
const indices = getNodeIndices(node);
|
|
1521
|
+
const tupleParam = indices.length === lastIdx;
|
|
1522
|
+
if (tupleParam) {
|
|
1523
|
+
const params = [];
|
|
1524
|
+
for (let i = 0; i < lastIdx; i++) {
|
|
1525
|
+
const param = this.visitChild(node, i);
|
|
1526
|
+
if (param === null) {
|
|
1527
|
+
return null;
|
|
1528
|
+
}
|
|
1529
|
+
if (param.length === 0) {
|
|
1530
|
+
return EmptySetV;
|
|
1531
|
+
}
|
|
1532
|
+
params.push(param);
|
|
1533
|
+
}
|
|
1534
|
+
const result = [];
|
|
1535
|
+
for (const element of argVal) {
|
|
1536
|
+
let valid = true;
|
|
1537
|
+
for (let j = 0; j < indices.length; j++) {
|
|
1538
|
+
const comp = element[indices[j]];
|
|
1539
|
+
const paramSet = params[j];
|
|
1540
|
+
if (!contains(paramSet, comp)) {
|
|
1541
|
+
valid = false;
|
|
1542
|
+
break;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
if (valid) {
|
|
1546
|
+
result.push(element);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
return result;
|
|
1550
|
+
} else {
|
|
1551
|
+
const paramVal = this.visitChild(node, 0);
|
|
1552
|
+
if (paramVal === null) {
|
|
1553
|
+
return null;
|
|
1554
|
+
}
|
|
1555
|
+
if (paramVal.length === 0) {
|
|
1556
|
+
return EmptySetV;
|
|
1557
|
+
}
|
|
1558
|
+
const result = [];
|
|
1559
|
+
for (const element of argVal) {
|
|
1560
|
+
const comps = indices.map((i) => element[i]);
|
|
1561
|
+
const testElement = comps.length === 1 ? comps[0] : tuple(comps);
|
|
1562
|
+
if (contains(paramVal, testElement)) result.push(element);
|
|
1563
|
+
}
|
|
1564
|
+
return result;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
visitReduce(node) {
|
|
1568
|
+
const target = this.visitChild(node, 0);
|
|
1569
|
+
if (target === null) {
|
|
1570
|
+
return null;
|
|
1571
|
+
}
|
|
1572
|
+
return reduce(target);
|
|
1573
|
+
}
|
|
1574
|
+
visitDeclarative(node) {
|
|
1575
|
+
const domain = this.visitChild(node, 1);
|
|
1576
|
+
if (domain === null) {
|
|
1577
|
+
return null;
|
|
1578
|
+
}
|
|
1579
|
+
const elements = [];
|
|
1580
|
+
for (const element of domain) {
|
|
1581
|
+
if (!this.tick(node, TICK_PER_DECLARATIVE)) {
|
|
1582
|
+
return null;
|
|
1583
|
+
}
|
|
1584
|
+
this.dispatchDeclare(node.children[0], element);
|
|
1585
|
+
const value = this.visitChild(node, 2);
|
|
1586
|
+
if (value === null) {
|
|
1587
|
+
return null;
|
|
1588
|
+
}
|
|
1589
|
+
if (value === VALUE_TRUE) {
|
|
1590
|
+
elements.push(element);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
return elements.length === 0 ? EmptySetV : elements;
|
|
1594
|
+
}
|
|
1595
|
+
visitImperative(node) {
|
|
1596
|
+
const result = [];
|
|
1597
|
+
const frames = [];
|
|
1598
|
+
let currentChild = 1;
|
|
1599
|
+
const advanceIterator = () => {
|
|
1600
|
+
while (frames.length > 0) {
|
|
1601
|
+
const top = frames[frames.length - 1];
|
|
1602
|
+
if (top.valueID < top.domain.length - 1) {
|
|
1603
|
+
top.valueID++;
|
|
1604
|
+
const nextValue = top.domain[top.valueID];
|
|
1605
|
+
if (!this.tick(node.children[top.childID], TICK_PER_IMPERATIVE)) {
|
|
1606
|
+
return false;
|
|
1607
|
+
}
|
|
1608
|
+
this.dispatchDeclare(node.children[top.childID].children[0], nextValue);
|
|
1609
|
+
currentChild = top.childID + 1;
|
|
1610
|
+
return true;
|
|
1611
|
+
}
|
|
1612
|
+
frames.pop();
|
|
1613
|
+
}
|
|
1614
|
+
return false;
|
|
1615
|
+
};
|
|
1616
|
+
while (true) {
|
|
1617
|
+
if (currentChild >= node.children.length) {
|
|
1618
|
+
const element = this.visitChild(node, 0);
|
|
1619
|
+
if (element === null) {
|
|
1620
|
+
return null;
|
|
1621
|
+
}
|
|
1622
|
+
result.push(element);
|
|
1623
|
+
if (!advanceIterator()) {
|
|
1624
|
+
break;
|
|
1625
|
+
}
|
|
1626
|
+
continue;
|
|
1627
|
+
}
|
|
1628
|
+
const child = node.children[currentChild];
|
|
1629
|
+
if (child.typeID === TokenID.ITERATE) {
|
|
1630
|
+
const domain = this.visitChild(child, 1);
|
|
1631
|
+
if (domain === null) {
|
|
1632
|
+
return null;
|
|
1633
|
+
}
|
|
1634
|
+
if (domain.length === 0) {
|
|
1635
|
+
if (!advanceIterator()) {
|
|
1636
|
+
break;
|
|
1637
|
+
}
|
|
1638
|
+
continue;
|
|
1639
|
+
}
|
|
1640
|
+
if (!this.tick(child, TICK_PER_IMPERATIVE)) {
|
|
1641
|
+
return null;
|
|
1642
|
+
}
|
|
1643
|
+
frames.push({
|
|
1644
|
+
childID: currentChild,
|
|
1645
|
+
domain,
|
|
1646
|
+
valueID: 0
|
|
1647
|
+
});
|
|
1648
|
+
this.dispatchDeclare(child.children[0], domain[0]);
|
|
1649
|
+
currentChild++;
|
|
1650
|
+
continue;
|
|
1651
|
+
}
|
|
1652
|
+
const value = this.dispatchVisit(child);
|
|
1653
|
+
if (value === null) {
|
|
1654
|
+
return null;
|
|
1655
|
+
}
|
|
1656
|
+
if (value === VALUE_FALSE) {
|
|
1657
|
+
if (!advanceIterator()) {
|
|
1658
|
+
break;
|
|
1659
|
+
}
|
|
1660
|
+
continue;
|
|
1661
|
+
}
|
|
1662
|
+
currentChild++;
|
|
1663
|
+
}
|
|
1664
|
+
return set(result);
|
|
1665
|
+
}
|
|
1666
|
+
visitAssign(node) {
|
|
1667
|
+
const value = this.visitChild(node, 1);
|
|
1668
|
+
if (value === null) {
|
|
1669
|
+
return null;
|
|
1670
|
+
}
|
|
1671
|
+
this.dispatchDeclare(node.children[0], value);
|
|
1672
|
+
return VALUE_TRUE;
|
|
1673
|
+
}
|
|
1674
|
+
visitRecursion(node) {
|
|
1675
|
+
const initialValue = this.visitChild(node, 1);
|
|
1676
|
+
if (initialValue === null) {
|
|
1677
|
+
return null;
|
|
1678
|
+
}
|
|
1679
|
+
const bodyIndex = node.typeID === TokenID.NT_RECURSIVE_FULL ? 3 : 2;
|
|
1680
|
+
let current = initialValue;
|
|
1681
|
+
while (true) {
|
|
1682
|
+
if (!this.tick(node, TICK_PER_RECURSION)) {
|
|
1683
|
+
return null;
|
|
1684
|
+
}
|
|
1685
|
+
this.dispatchDeclare(node.children[0], current);
|
|
1686
|
+
if (node.typeID === TokenID.NT_RECURSIVE_FULL) {
|
|
1687
|
+
const pred = this.visitChild(node, 2);
|
|
1688
|
+
if (pred === null) {
|
|
1689
|
+
return null;
|
|
1690
|
+
}
|
|
1691
|
+
if (pred !== VALUE_TRUE) {
|
|
1692
|
+
break;
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
const next = this.visitChild(node, bodyIndex);
|
|
1696
|
+
if (next === null) {
|
|
1697
|
+
return null;
|
|
1698
|
+
}
|
|
1699
|
+
if (compare(current, next) === 0) {
|
|
1700
|
+
break;
|
|
1701
|
+
}
|
|
1702
|
+
current = next;
|
|
1703
|
+
}
|
|
1704
|
+
return current;
|
|
1705
|
+
}
|
|
1706
|
+
};
|
|
1707
|
+
var LocalContext = class {
|
|
1708
|
+
nextBindingId = 1;
|
|
1709
|
+
data = /* @__PURE__ */ new Map();
|
|
1710
|
+
callStack = [];
|
|
1711
|
+
startScope() {
|
|
1712
|
+
this.callStack.push(this.data);
|
|
1713
|
+
this.data = /* @__PURE__ */ new Map();
|
|
1714
|
+
}
|
|
1715
|
+
endScope() {
|
|
1716
|
+
this.data = this.callStack.pop();
|
|
1717
|
+
}
|
|
1718
|
+
setLocal(alias, value) {
|
|
1719
|
+
const existing = this.data.get(alias);
|
|
1720
|
+
if (existing) {
|
|
1721
|
+
existing.value = value;
|
|
1722
|
+
existing.version++;
|
|
1723
|
+
} else {
|
|
1724
|
+
this.data.set(alias, { id: this.nextBindingId++, version: 0, value });
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
getLocal(alias) {
|
|
1728
|
+
const binding = this.data.get(alias);
|
|
1729
|
+
if (binding === void 0) {
|
|
1730
|
+
throw new Error(`Local variable "${alias}" not found`);
|
|
1731
|
+
}
|
|
1732
|
+
return binding.value;
|
|
1733
|
+
}
|
|
1734
|
+
buildDependencyStamp(reads) {
|
|
1735
|
+
if (reads.size === 0) {
|
|
1736
|
+
return "";
|
|
1737
|
+
}
|
|
1738
|
+
const parts = [];
|
|
1739
|
+
for (const alias of [...reads].sort()) {
|
|
1740
|
+
const binding = this.data.get(alias);
|
|
1741
|
+
if (binding === void 0) {
|
|
1742
|
+
return null;
|
|
1743
|
+
}
|
|
1744
|
+
parts.push(`${binding.id}:${binding.version}`);
|
|
1745
|
+
}
|
|
1746
|
+
return parts.join("|");
|
|
1747
|
+
}
|
|
1748
|
+
};
|
|
1749
|
+
|
|
1750
|
+
// src/rslang/eval/calculator.ts
|
|
1751
|
+
var RSCalculator = class {
|
|
1752
|
+
context = /* @__PURE__ */ new Map();
|
|
1753
|
+
treeContext = /* @__PURE__ */ new Map();
|
|
1754
|
+
evaluator = new Evaluator(this.context, this.treeContext);
|
|
1755
|
+
listeners = /* @__PURE__ */ new Map();
|
|
1756
|
+
subscribe = (alias, listener) => {
|
|
1757
|
+
let notifyList = this.listeners.get(alias);
|
|
1758
|
+
if (!notifyList) {
|
|
1759
|
+
notifyList = /* @__PURE__ */ new Set();
|
|
1760
|
+
this.listeners.set(alias, notifyList);
|
|
1761
|
+
}
|
|
1762
|
+
notifyList.add(listener);
|
|
1763
|
+
return () => {
|
|
1764
|
+
notifyList.delete(listener);
|
|
1765
|
+
if (notifyList.size === 0) {
|
|
1766
|
+
this.listeners.delete(alias);
|
|
1767
|
+
}
|
|
1768
|
+
};
|
|
1769
|
+
};
|
|
1770
|
+
setValue(alias, value) {
|
|
1771
|
+
this.context.set(alias, value);
|
|
1772
|
+
this.notify(alias);
|
|
1773
|
+
}
|
|
1774
|
+
resetValue(alias) {
|
|
1775
|
+
this.context.delete(alias);
|
|
1776
|
+
this.notify(alias);
|
|
1777
|
+
}
|
|
1778
|
+
clearAllAst() {
|
|
1779
|
+
this.treeContext.clear();
|
|
1780
|
+
}
|
|
1781
|
+
getValue(alias) {
|
|
1782
|
+
return this.context.get(alias) ?? null;
|
|
1783
|
+
}
|
|
1784
|
+
setAST(alias, ast) {
|
|
1785
|
+
this.treeContext.set(alias, ast);
|
|
1786
|
+
}
|
|
1787
|
+
validate(value, type) {
|
|
1788
|
+
return validateValue(value, type, this.context);
|
|
1789
|
+
}
|
|
1790
|
+
evaluateFast(ast) {
|
|
1791
|
+
if (ast.hasError) {
|
|
1792
|
+
return null;
|
|
1793
|
+
}
|
|
1794
|
+
return this.evaluator.run(ast);
|
|
1795
|
+
}
|
|
1796
|
+
evaluateFull(ast, options) {
|
|
1797
|
+
const errors = [];
|
|
1798
|
+
const reporter = (error) => {
|
|
1799
|
+
errors.push(error);
|
|
1800
|
+
};
|
|
1801
|
+
if (ast.hasError) {
|
|
1802
|
+
return { value: null, iterations: 0, cacheHits: 0, errors };
|
|
1803
|
+
}
|
|
1804
|
+
const value = this.evaluator.run(ast, reporter, options?.annotateErrors ?? false, options?.disableCache ?? false);
|
|
1805
|
+
if (value === null && errors.length === 0) {
|
|
1806
|
+
errors.push({ code: RSErrorCode.calcUnknownError, from: 0, to: 0 });
|
|
1807
|
+
if (options?.annotateErrors) {
|
|
1808
|
+
annotateError(ast, RSErrorCode.calcUnknownError);
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
return {
|
|
1812
|
+
value,
|
|
1813
|
+
iterations: this.evaluator.iterationCounter,
|
|
1814
|
+
cacheHits: this.evaluator.cacheHits,
|
|
1815
|
+
errors
|
|
1816
|
+
};
|
|
1817
|
+
}
|
|
1818
|
+
notify(alias) {
|
|
1819
|
+
const set2 = this.listeners.get(alias);
|
|
1820
|
+
if (!set2) return;
|
|
1821
|
+
for (const l of set2) {
|
|
1822
|
+
l();
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
};
|
|
1826
|
+
|
|
1827
|
+
// src/rslang/parser/parser.ts
|
|
1828
|
+
import { LRParser } from "@lezer/lr";
|
|
1829
|
+
var parser = LRParser.deserialize({
|
|
1830
|
+
version: 14,
|
|
1831
|
+
states: "2lO!sQPOOOVQPO'#CdO$qQPO'#C`O&pQPO'#C`O*bQPO'#C_Q*jQPOOO,TQPO'#CyOVQPO'#CtO,]QPO'#CtOOQO'#Ct'#CtOOQO'#C^'#C^OOQO'#ES'#ESOOQO'#ET'#ETO,bQPO'#DeO,iQPO'#DfO,qQPO'#DhO,vQPO'#DjO,{QPO'#DnO-QQPO'#DrOOQO'#EU'#EUOOQO'#EV'#EVOOQO'#DS'#DSO-VQPO'#DSO-[QPO'#DSOOQO'#EQ'#EQO,TQPO'#DzQOQPOOO-aQPO'#ERO-nQPO,59OO-vQPO'#CeO-{QPO,58xO/lQPO,59tOVQPO,58yOVQPO,58yOVQPO,59iOVQPO,59iOVQPO,59iOVQPO,59iOVQPO,59tOVQPO,59tOVQPO,59tOVQPO,59tOVQPO,59tOVQPO,59tOVQPO,59tOVQPO,59tOVQPO'#CdOOQO'#C`'#C`OOQO'#C{'#C{O1]QPO,59eO2rQPO,59`OVQPO,59`OOQO'#ER'#ERO5TQPO,5:PO5]QPO,5:UOVQPO,5:QOOQO,5:Q,5:QOVQPO,5:SO,TQPO,5:UOVQPO,5:YO,TQPO,5:^OVQPO,59nOVQPO,59nO5dQPO'#D|OOQO'#D{'#D{O5iQPO,5:fOOQO1G.j1G.jOVQPO,59POOQO1G.d1G.dOOQO1G/`1G/`O5qQPO1G.eO7vQPO1G.eO:zQPO1G/TO=]QPO1G/TO?nQPO1G/TOBPQPO1G/TOGyQPO1G/`OHQQPO1G/`OKpQPO1G/`O! `QPO1G/`O! gQPO1G/`O! nQPO1G/`O! uQPO1G/`O,TQPO,59gOVQPO1G/PO!%aQPO1G.zOOQO1G/k1G/kOVQPO1G/pO!%iQPO1G/lO!%pQPO1G/nO!%xQPO1G/pO!%}QPO1G/tO!&UQPO1G/xO!&ZQPO1G/YO!&cQPO1G/YOVQPO,5:hO,TQPO,5:gOVQPO1G0QO!&jQPO1G.kOOQO1G/R1G/RO!&zQPO7+$kOOQO7+$f7+$fO!(gQPO7+%[OOQO7+%W7+%WO!(nQPO7+%YOVQPO7+%[OVQPO7+%`OVQPO7+%dOOQO7+$t7+$tO!(sQPO1G0SOOQO1G0R1G0RO!(}QPO7+%lO!)UQPO<<HVOVQPO<<HvOVQPO<<HtO!+gQPO<<HvO!+nQPO'#DoO!+xQPO<<HzO!,QQPO<<IOO!,XQPOAN>bO!,`QPOAN>`OVQPOAN>bOVQPO,5:ZOOQOAN>fAN>fOVQPOAN>jOOQOG23|G23|OOQOG23zG23zO!,gQPOG23|O!,nQPO1G/uO!,xQPOG24UOOQOLD)hLD)hOOQOLD)pLD)pOVQPOLD)pO!-SQPO!$'M[OOQO!)9Bv!)9Bv",
|
|
1832
|
+
stateData: "!-l~O!sOS~OTQOVPOiVOjWOnUOpUOwZOxZOyZOz[O{[O!W]O!Z^O!]_O!``O!aaO!ebO!gfO!hdO!idO!jdO!kdO!ldO!mdO~OkiO~PVOZSX[SX]!wX^!wX_!wX`!wXa!wXb!wXc!wXd!wXe!wXf!wXg!wXr!wXs!wXt!wXu!wX}!wX!O!wX!P!wX!Q!wX!R!wX!S!wX!T!wX!U!wXY!wX!V!wX~O!q!wXU!wXl!wX!_!wXT!wXV!wXi!wXj!wXn!wXp!wXw!wXx!wXy!wXz!wX{!wX!W!wX!Z!wX!]!wX!`!wX!a!wX!e!wX!g!wX!h!wX!i!wX!j!wX!k!wX!l!wX!m!wX!d!wX~P!zOZSX[SX]!xX^!xX_!xX`!xXa!xXb!xXc!xXd!xXe!xXf!xXg!xXr!xXs!xXt!xXu!xX}!xX!O!xX!P!xX!Q!xX!R!xX!S!xX!T!xX!U!xX!q!xXY!xX!V!xXU!xXl!xX!_!xXT!xXV!xXi!xXj!xXn!xXp!xXw!xXx!xXy!xXz!xX{!xX!W!xX!Z!xX!]!xX!`!xX!a!xX!e!xX!g!xX!h!xX!i!xX!j!xX!k!xX!l!xX!m!xX!d!xX~OZpO[pO~O]qO^qO_qO`qOaqObqOcqOdqOeqOfqOgqOrrOssOttOuuO}vO!OwO!PxO!QyO!RzO!S{O!T|O!U}O~OT!POV!OO~Ok!TO~OT!WO~PYOV!XO!Z^O~Ok!ZO~O!W![O~O!W!]O~O!W!^O~Ok!_O~OV!`O~OY!uX!V!uXl!uX~P*jOU!dOY!uX~OY!eO~OU!fOY!tX]!tX^!tX_!tX`!tXa!tXb!tXc!tXd!tXe!tXf!tXg!tXr!tXs!tXt!tXu!tX}!tX!O!tX!P!tX!Q!tX!R!tX!S!tX!T!tX!U!tX~OU!gOYvX]vX^vX_vX`vXavXbvXcvXdvXevXfvXgvXrvXsvXtvXuvX}vX!OvX!PvX!QvX!RvX!SvX!TvX!UvX~OY!uO]!vO~O]qO^qO_qO`qOaqObqOcqOdqOeqOfqOgqO}vO!OwO!PxO!QyO!RzO!S{O!T|O!U}O~Orhashathauha!qhaUhaYha!Vhalha!_haThaVhaihajhanhaphawhaxhayhazha{ha!Wha!Zha!]ha!`ha!aha!eha!gha!hha!iha!jha!kha!lha!mha!dha~P1eOY!eO!V!xO~O]!yO~P!zO]#RO~OY#SOl#TO~O!qRiURiYRi!VRilRi!_RiTRiVRiiRijRinRipRiwRixRiyRizRi{Ri!WRi!ZRi!]Ri!`Ri!aRi!eRi!gRi!hRi!iRi!jRi!kRi!lRi!mRi!dRi~P*jO]Ri^Ri_Ri`RiaRibRicRidRieRifRigRirRisRitRiuRi!qRiURiYRi!VRilRi!_RiTRiVRiiRijRinRipRiwRixRiyRizRi{Ri!WRi!ZRi!]Ri!`Ri!aRi!eRi!gRi!hRi!iRi!jRi!kRi!lRi!mRi!dRi~P+iOssOttOuuOrqi!qqiUqiYqi!Vqilqi!_qiTqiVqiiqijqinqipqiwqixqiyqizqi{qi!Wqi!Zqi!]qi!`qi!aqi!eqi!gqi!hqi!iqi!jqi!kqi!lqi!mqi!dqi~P1eOttOuuOrqisqi!qqiUqiYqi!Vqilqi!_qiTqiVqiiqijqinqipqiwqixqiyqizqi{qi!Wqi!Zqi!]qi!`qi!aqi!eqi!gqi!hqi!iqi!jqi!kqi!lqi!mqi!dqi~P1eOuuOrqisqitqi!qqiUqiYqi!Vqilqi!_qiTqiVqiiqijqinqipqiwqixqiyqizqi{qi!Wqi!Zqi!]qi!`qi!aqi!eqi!gqi!hqi!iqi!jqi!kqi!lqi!mqi!dqi~P1eOrqisqitqiuqi!qqiUqiYqi!Vqilqi!_qiTqiVqiiqijqinqipqiwqixqiyqizqi{qi!Wqi!Zqi!]qi!`qi!aqi!eqi!gqi!hqi!iqi!jqi!kqi!lqi!mqi!dqi~P1eO}vO]|i^|i_|i`|ia|ib|ic|id|ie|if|ig|ir|is|it|iu|i!P|i!Q|i!R|i!S|i!T|i!U|i!q|iU|iY|i!V|il|i!_|iT|iV|ii|ij|in|ip|iw|ix|iy|iz|i{|i!W|i!Z|i!]|i!`|i!a|i!e|i!g|i!h|i!i|i!j|i!k|i!l|i!m|i!d|i~O!O|i~PDbO!OwO~PDbO}vO!OwO!PxO!U}O]|i^|i_|i`|ia|ib|ic|id|ie|if|ig|ir|is|it|iu|i!R|i!S|i!T|i!q|iU|iY|i!V|il|i!_|iT|iV|ii|ij|in|ip|iw|ix|iy|iz|i{|i!W|i!Z|i!]|i!`|i!a|i!e|i!g|i!h|i!i|i!j|i!k|i!l|i!m|i!d|i~O!Q|i~PHXO}vO!OwO!PxO!QyO!T|O!U}O]|i^|i_|i`|ia|ib|ic|id|ie|if|ig|ir|is|it|iu|i!S|i!q|iU|iY|i!V|il|i!_|iT|iV|ii|ij|in|ip|iw|ix|iy|iz|i{|i!W|i!Z|i!]|i!`|i!a|i!e|i!g|i!h|i!i|i!j|i!k|i!l|i!m|i!d|i~O!R|i~PKwO!RzO~PKwO!QyO~PHXO}vO!OwO!PxO]|i^|i_|i`|ia|ib|ic|id|ie|if|ig|ir|is|it|iu|i!Q|i!R|i!S|i!T|i!U|i!q|iU|iY|i!V|il|i!_|iT|iV|ii|ij|in|ip|iw|ix|iy|iz|i{|i!W|i!Z|i!]|i!`|i!a|i!e|i!g|i!h|i!i|i!j|i!k|i!l|i!m|i!d|i~OY!eOl#XO~OU#ZO~P*jOY!eOl#[O~O]#]O~O!_#^O~P*jO[#_O~OY!eOl#`O~OU#`O~P*jOUXiYXi!VXilXi~P*jO]qO^qO_qO`qOaqObqOcqOdqOeqOfqOgqOrrOssOttOuuO}vO!OwO!PxO!QyO!RzO!S{O!T|O!U}O~PVO!_#eO~P*jOV#fO~OY!pil!pi~P*jO!q!nq~P*jOrmysmytmyumy!qmyUmyYmy!Vmylmy!_myTmyVmyimyjmynmypmywmyxmyymyzmy{my!Wmy!Zmy!]my!`my!amy!emy!gmy!hmy!imy!jmy!kmy!lmy!mmy!dmy~P1eO!_#mO~P*jO!V!cX!d!cX~P*jO!V#oO!d#nO~O!_#pO~P*jO!V#qO~P*jOU#rO~P*jO!V#vO~P*jO!V!ci!d!ci~P*jO!V#wO!_#xO~P*jO!V#zO~P*jO!]!hj!gz{!j!k!l!m!iT!e!a!`!a~",
|
|
1833
|
+
goto: "1O!zPP!{#y$uPPP&R'VPPPPPPPPPPPPPP#yPPPP'aP(]P#yPPPP(`PPPPP)[PPPPPPPPPP*Y+UP*YP*YPPP*Y,TPP*YPPPPPPP,W,Z,^PPP,d.v/W/W/W0S!phOV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#xRnP!sYOPV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#x!rSOPV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#xQ!QUS!ai#SQ!|![Q#O!^R#V!u!rROPV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#x]!PUi![!^!u#SSlP!OX!U]!T!Z!_!sXOPV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#xR!RU!shOPV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#x!peOV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#xRoP!scOPV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#x!rcOPV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#xR!Y^R#i#^RjOR!ciQ!biR#b#SQTO[kP]!O!T!Z!_Q!SVQ!gvQ!hpQ!iqQ!jrQ!ksQ!ltQ!muQ!nwQ!oxQ!pyQ!qzQ!r{Q!s|Q!t}Q!z!XQ!}!]Q#Q!`Q#U!eQ#W!vQ#Y!yQ#a#RQ#c#TQ#d#WQ#g#]Q#h#^Q#j#_Q#k#eQ#l#fQ#s#mQ#t#nQ#u#pR#y#xSmP!OQ!V]Q!w!TQ!{!ZR#P!_!seOPV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#x!sgOPV]pqrstuvwxyz{|}!O!T!X!Z!]!_!`!e!v!y#R#T#W#]#^#_#e#f#m#n#p#x",
|
|
1834
|
+
nodeNames: "\u26A0 Expression Logic Logic_predicates Variable Local ) ( Tuple Expr_enum_min2 , :\u2208 := \u2208 \u2209 \u2286 \u2284 \u2282 > \u2265 < \u2264 \u2260 = Logic_unary \xAC Predicate [ ] Logic_quantor \u2200 Variable_pack \u2203 Logic_binary \u21D4 \u21D2 \u2228 & Setexpr Integer EmptySet IntegerSet Global Radical Setexpr_binary * + - \u222A \\ \u2206 \u2229 \xD7 } { Enumeration Boolean \u212C Filter_expression Filter Declarative | PrefixD PrefixI Imperative Imp_blocks ; PrefixR Recursion Function BigPr SmallPr Card Bool Debool Red Function_decl Arguments Declaration",
|
|
1835
|
+
maxTerm: 87,
|
|
1836
|
+
nodeProps: [
|
|
1837
|
+
["openedBy", 6, "(", 53, "{"],
|
|
1838
|
+
["closedBy", 7, ")", 54, "}"]
|
|
1839
|
+
],
|
|
1840
|
+
skippedNodes: [0],
|
|
1841
|
+
repeatNodeCount: 0,
|
|
1842
|
+
tokenData: "6j~R!jX^%spq%svw&hxy&myz&rz{&w{|&||}'R}!O'W!Q![']![!]'e!]!^'x!^!_'}!_!`(S!`!a(X!c!d(^!e!f(^!f!g(l!h!i(t!k!l)h!p!q(^!r!s)m!t!u*a!u!v(^!v!w(^!z!{(^!|!}*q!}#O*v#O#P*{#P#Q+Q#R#S+V#T#U+V#U#V+m#V#W-]#W#X.x#X#d+V#d#e1b#e#f+V#f#g2w#g#o+V#o#p4R#p#q4W#q#r4]#y#z%s$f$g%s$r$s4b%o%p4g5i6S+V#BY#BZ%s$IS$I_%s$I|$JO%s$JT$JU%s$KV$KW%s% l% m4l%%Y%%Z4q%%[%%]4v%&Y%&Z4{%&]%&^5Q%&_%&`5V%&`%&a5[%&b%&c5a%&c%&d5f%'S%'T5k%'T%'U5p%'U%'V5u%(^%(_5z%(b%(c6P%(c%(d6U%)Q%)R6Z%)S%)T6`%)U%)V6e&FU&FV%s~%xY!s~X^%spq%s#y#z%s$f$g%s#BY#BZ%s$IS$I_%s$I|$JO%s$JT$JU%s$KV$KW%s&FU&FV%s~&mOu~~&rOV~~&wOU~~&|O}~~'RO!O~~'WOY~~']O!P~~'bPw~!Q![']~'hQ!_!`'n%&b%&c's~'sO[~~'xOZ~~'}O!d~~(SOd~~(XOg~~(^Ob~~(aP!Q![(d~(iPz~!Q![(d~(qP!`~!Q![(d~(wQ!Q![(}#]#^)V~)SP!g~!Q![(}~)YP!R![)]~)bQ!]~|})V!Q![)]~)mO!a~~)pQ!Q![)v#f#g*O~){Pj~!Q![)v~*RP!R![*U~*ZQ!h~|}*O!Q![*U~*fP!e~!Q![*i~*nP{~!Q![*i~*vOy~~*{Ok~~+QO!R~~+VOl~~+[RT~!Q![+e#T#o+V5i6S+V~+jPT~!Q![+e~+rTT~!Q![+e#T#c+V#c#d,R#d#o+V5i6S+V~,WTT~!Q![+e#T#c+V#c#d,g#d#o+V5i6S+V~,lTT~!Q![+e#T#`+V#`#a,{#a#o+V5i6S+V~-SR!k~T~!Q![+e#T#o+V5i6S+V~-bST~!Q![+e#T#U-n#U#o+V5i6S+V~-sTT~!Q![+e#T#f+V#f#g.S#g#o+V5i6S+V~.XTT~!Q![+e#T#W+V#W#X.h#X#o+V5i6S+V~.oR!j~T~!Q![+e#T#o+V5i6S+V~.}TT~!Q![+e#T#X+V#X#Y/^#Y#o+V5i6S+V~/cTT~!Q![+e#T#U+V#U#V/r#V#o+V5i6S+V~/wTT~!Q![+e#T#c+V#c#d0W#d#o+V5i6S+V~0]TT~!Q![+e#T#c+V#c#d0l#d#o+V5i6S+V~0qTT~!Q![+e#T#`+V#`#a1Q#a#o+V5i6S+V~1XR!l~T~!Q![+e#T#o+V5i6S+V~1gTT~!Q![+e#T#f+V#f#g1v#g#o+V5i6S+V~1{ST~!Q!R+e!R![2X#T#o+V5i6S+V~2`Q!i~T~|}2f!Q![2X~2iP!R![2l~2qQ!i~|}2f!Q![2l~2|TT~!Q![+e#T#X+V#X#Y3]#Y#o+V5i6S+V~3bTT~!Q![+e#T#W+V#W#X3q#X#o+V5i6S+V~3xR!m~T~!Q![+e#T#o+V5i6S+V~4WO!W~~4]O!_~~4bO!V~~4gOi~~4lO!U~~4qO!Z~~4vOs~~4{Or~~5QOn~~5VOp~~5[Ox~~5aO!S~~5fO]~~5kO^~~5pOt~~5uO!T~~5zO!Q~~6POf~~6UOe~~6ZOc~~6`Oa~~6eO`~~6jO_~",
|
|
1843
|
+
tokenizers: [0],
|
|
1844
|
+
topRules: { "Expression": [0, 1] },
|
|
1845
|
+
tokenPrec: 2679
|
|
1846
|
+
});
|
|
1847
|
+
|
|
1848
|
+
// src/rslang/parser/parser.terms.ts
|
|
1849
|
+
var Local = 5;
|
|
1850
|
+
var Tuple = 8;
|
|
1851
|
+
var Predicate = 26;
|
|
1852
|
+
var Variable_pack = 31;
|
|
1853
|
+
var Integer = 39;
|
|
1854
|
+
var EmptySet = 40;
|
|
1855
|
+
var IntegerSet = 41;
|
|
1856
|
+
var Global = 42;
|
|
1857
|
+
var Radical = 43;
|
|
1858
|
+
var Enumeration = 55;
|
|
1859
|
+
var Boolean = 56;
|
|
1860
|
+
var Filter = 59;
|
|
1861
|
+
var Declarative = 60;
|
|
1862
|
+
var Imperative = 64;
|
|
1863
|
+
var Function = 69;
|
|
1864
|
+
var BigPr = 70;
|
|
1865
|
+
var SmallPr = 71;
|
|
1866
|
+
var Card = 72;
|
|
1867
|
+
var Bool = 73;
|
|
1868
|
+
var Debool = 74;
|
|
1869
|
+
var Red = 75;
|
|
1870
|
+
var Function_decl = 76;
|
|
1871
|
+
var Arguments = 77;
|
|
1872
|
+
var Declaration = 78;
|
|
1873
|
+
|
|
1874
|
+
// src/rslang/parser/normalize.ts
|
|
1875
|
+
var idRecord = {
|
|
1876
|
+
[Global]: TokenID.ID_GLOBAL,
|
|
1877
|
+
[Local]: TokenID.ID_LOCAL,
|
|
1878
|
+
[Radical]: TokenID.ID_RADICAL,
|
|
1879
|
+
[Function]: TokenID.ID_FUNCTION,
|
|
1880
|
+
[Predicate]: TokenID.ID_PREDICATE,
|
|
1881
|
+
[Integer]: TokenID.LIT_INTEGER,
|
|
1882
|
+
[EmptySet]: TokenID.LIT_EMPTYSET,
|
|
1883
|
+
[IntegerSet]: TokenID.LIT_WHOLE_NUMBERS,
|
|
1884
|
+
[Boolean]: TokenID.BOOLEAN,
|
|
1885
|
+
[BigPr]: TokenID.BIGPR,
|
|
1886
|
+
[SmallPr]: TokenID.SMALLPR,
|
|
1887
|
+
[Filter]: TokenID.FILTER,
|
|
1888
|
+
[Bool]: TokenID.BOOL,
|
|
1889
|
+
[Debool]: TokenID.DEBOOL,
|
|
1890
|
+
[Red]: TokenID.REDUCE,
|
|
1891
|
+
[Card]: TokenID.CARD,
|
|
1892
|
+
[Enumeration]: TokenID.NT_ENUMERATION,
|
|
1893
|
+
[Tuple]: TokenID.NT_TUPLE,
|
|
1894
|
+
[Arguments]: TokenID.NT_ARGUMENTS,
|
|
1895
|
+
[Declaration]: TokenID.NT_ARG_DECL,
|
|
1896
|
+
[Function_decl]: TokenID.NT_FUNC_DEFINITION,
|
|
1897
|
+
[Variable_pack]: TokenID.NT_ENUM_DECL,
|
|
1898
|
+
[Declarative]: TokenID.NT_DECLARATIVE_EXPR,
|
|
1899
|
+
[Imperative]: TokenID.NT_IMPERATIVE_EXPR
|
|
1900
|
+
};
|
|
1901
|
+
|
|
1902
|
+
// src/rslang/labels.ts
|
|
1903
|
+
var ANY_TYPE_NAME = "R0";
|
|
1904
|
+
var LOGIC_TYPE_NAME = "Logic";
|
|
1905
|
+
var labelTokenRecord = {
|
|
1906
|
+
[TokenID.DECART]: "\xD7",
|
|
1907
|
+
[TokenID.PUNCTUATION_PL]: "( )",
|
|
1908
|
+
[TokenID.PUNCTUATION_SL]: "[ ]",
|
|
1909
|
+
[TokenID.QUANTOR_UNIVERSAL]: "\u2200",
|
|
1910
|
+
[TokenID.QUANTOR_EXISTS]: "\u2203",
|
|
1911
|
+
[TokenID.LOGIC_NOT]: "\xAC",
|
|
1912
|
+
[TokenID.LOGIC_AND]: "&",
|
|
1913
|
+
[TokenID.LOGIC_OR]: "\u2228",
|
|
1914
|
+
[TokenID.LOGIC_IMPLICATION]: "\u21D2",
|
|
1915
|
+
[TokenID.LOGIC_EQUIVALENT]: "\u21D4",
|
|
1916
|
+
[TokenID.LIT_EMPTYSET]: "\u2205",
|
|
1917
|
+
[TokenID.LIT_WHOLE_NUMBERS]: "Z",
|
|
1918
|
+
[TokenID.MULTIPLY]: "*",
|
|
1919
|
+
[TokenID.EQUAL]: "=",
|
|
1920
|
+
[TokenID.NOTEQUAL]: "\u2260",
|
|
1921
|
+
[TokenID.GREATER_OR_EQ]: "\u2265",
|
|
1922
|
+
[TokenID.LESSER_OR_EQ]: "\u2264",
|
|
1923
|
+
[TokenID.SET_IN]: "\u2208",
|
|
1924
|
+
[TokenID.SET_NOT_IN]: "\u2209",
|
|
1925
|
+
[TokenID.SUBSET_OR_EQ]: "\u2286",
|
|
1926
|
+
[TokenID.SUBSET]: "\u2282",
|
|
1927
|
+
[TokenID.NOT_SUBSET]: "\u2284",
|
|
1928
|
+
[TokenID.SET_INTERSECTION]: "\u2229",
|
|
1929
|
+
[TokenID.SET_UNION]: "\u222A",
|
|
1930
|
+
[TokenID.SET_MINUS]: "\\",
|
|
1931
|
+
[TokenID.SET_SYMMETRIC_MINUS]: "\u2206",
|
|
1932
|
+
[TokenID.BOOLEAN]: "\u212C()",
|
|
1933
|
+
[TokenID.NT_DECLARATIVE_EXPR]: "D{}",
|
|
1934
|
+
[TokenID.NT_IMPERATIVE_EXPR]: "I{}",
|
|
1935
|
+
[TokenID.NT_RECURSIVE_FULL]: "R{}",
|
|
1936
|
+
[TokenID.BIGPR]: "Pr1()",
|
|
1937
|
+
[TokenID.SMALLPR]: "pr1()",
|
|
1938
|
+
[TokenID.FILTER]: "Fi1[]()",
|
|
1939
|
+
[TokenID.REDUCE]: "red()",
|
|
1940
|
+
[TokenID.CARD]: "card()",
|
|
1941
|
+
[TokenID.BOOL]: "bool()",
|
|
1942
|
+
[TokenID.DEBOOL]: "debool()",
|
|
1943
|
+
[TokenID.ASSIGN]: ":=",
|
|
1944
|
+
[TokenID.ITERATE]: ":\u2208"
|
|
1945
|
+
};
|
|
1946
|
+
function normalizeType(type) {
|
|
1947
|
+
if (!type) {
|
|
1948
|
+
return "N/A";
|
|
1949
|
+
}
|
|
1950
|
+
switch (type.typeID) {
|
|
1951
|
+
case TypeID.anyTypification:
|
|
1952
|
+
return ANY_TYPE_NAME;
|
|
1953
|
+
case TypeID.integer:
|
|
1954
|
+
case TypeID.basic:
|
|
1955
|
+
return "X1";
|
|
1956
|
+
case TypeID.tuple:
|
|
1957
|
+
return type.factors.map((factor) => factor.typeID === TypeID.tuple ? `(${normalizeType(factor)})` : normalizeType(factor)).join("\xD7");
|
|
1958
|
+
case TypeID.collection:
|
|
1959
|
+
return type.base.typeID === TypeID.collection ? `\u212C${normalizeType(type.base)}` : `\u212C(${normalizeType(type.base)})`;
|
|
1960
|
+
case TypeID.logic:
|
|
1961
|
+
return LOGIC_TYPE_NAME;
|
|
1962
|
+
case TypeID.predicate:
|
|
1963
|
+
case TypeID.function:
|
|
1964
|
+
const argsText = type.args.map((arg) => normalizeType(arg.type)).join(", ");
|
|
1965
|
+
return `[${argsText}] \u2192 ${normalizeType(type.result)}`;
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
// src/rslang/semantic/typification-api.ts
|
|
1970
|
+
var TypeIDToClass = {
|
|
1971
|
+
[TypeID.anyTypification]: TypeClass.typification,
|
|
1972
|
+
[TypeID.integer]: TypeClass.typification,
|
|
1973
|
+
[TypeID.basic]: TypeClass.typification,
|
|
1974
|
+
[TypeID.tuple]: TypeClass.typification,
|
|
1975
|
+
[TypeID.collection]: TypeClass.typification,
|
|
1976
|
+
[TypeID.logic]: TypeClass.logic,
|
|
1977
|
+
[TypeID.function]: TypeClass.function,
|
|
1978
|
+
[TypeID.predicate]: TypeClass.predicate
|
|
1979
|
+
};
|
|
1980
|
+
|
|
1981
|
+
// src/rslang/semantic/value-class.ts
|
|
1982
|
+
var ValueClass = {
|
|
1983
|
+
VALUE: "value",
|
|
1984
|
+
PROPERTY: "property"
|
|
1985
|
+
};
|
|
1986
|
+
|
|
1987
|
+
// src/library/rsform.ts
|
|
1988
|
+
var CstType = {
|
|
1989
|
+
NOMINAL: "nominal",
|
|
1990
|
+
BASE: "basic",
|
|
1991
|
+
STRUCTURED: "structure",
|
|
1992
|
+
TERM: "term",
|
|
1993
|
+
AXIOM: "axiom",
|
|
1994
|
+
FUNCTION: "function",
|
|
1995
|
+
PREDICATE: "predicate",
|
|
1996
|
+
CONSTANT: "constant",
|
|
1997
|
+
STATEMENT: "statement"
|
|
1998
|
+
};
|
|
1999
|
+
var CstClass = {
|
|
2000
|
+
NOMINAL: "nominal",
|
|
2001
|
+
BASIC: "basic",
|
|
2002
|
+
DERIVED: "derived",
|
|
2003
|
+
STATEMENT: "statement",
|
|
2004
|
+
TEMPLATE: "template"
|
|
2005
|
+
};
|
|
2006
|
+
var CstStatus = {
|
|
2007
|
+
VERIFIED: "verified",
|
|
2008
|
+
INCORRECT: "incorrect",
|
|
2009
|
+
INCALCULABLE: "incalculable",
|
|
2010
|
+
PROPERTY: "property",
|
|
2011
|
+
UNKNOWN: "unknown"
|
|
2012
|
+
};
|
|
2013
|
+
|
|
2014
|
+
// src/library/rsform-api.ts
|
|
2015
|
+
var CST_TYPE_PREFIX = {
|
|
2016
|
+
[CstType.NOMINAL]: "N",
|
|
2017
|
+
[CstType.BASE]: "X",
|
|
2018
|
+
[CstType.CONSTANT]: "C",
|
|
2019
|
+
[CstType.STRUCTURED]: "S",
|
|
2020
|
+
[CstType.AXIOM]: "A",
|
|
2021
|
+
[CstType.TERM]: "D",
|
|
2022
|
+
[CstType.FUNCTION]: "F",
|
|
2023
|
+
[CstType.PREDICATE]: "P",
|
|
2024
|
+
[CstType.STATEMENT]: "T"
|
|
2025
|
+
};
|
|
2026
|
+
var CST_TYPE_TO_CLASS = {
|
|
2027
|
+
[CstType.NOMINAL]: CstClass.NOMINAL,
|
|
2028
|
+
[CstType.BASE]: CstClass.BASIC,
|
|
2029
|
+
[CstType.CONSTANT]: CstClass.BASIC,
|
|
2030
|
+
[CstType.STRUCTURED]: CstClass.BASIC,
|
|
2031
|
+
[CstType.TERM]: CstClass.DERIVED,
|
|
2032
|
+
[CstType.FUNCTION]: CstClass.DERIVED,
|
|
2033
|
+
[CstType.AXIOM]: CstClass.STATEMENT,
|
|
2034
|
+
[CstType.PREDICATE]: CstClass.DERIVED,
|
|
2035
|
+
[CstType.STATEMENT]: CstClass.STATEMENT
|
|
2036
|
+
};
|
|
2037
|
+
function isBasicConcept(type) {
|
|
2038
|
+
switch (type) {
|
|
2039
|
+
case CstType.NOMINAL:
|
|
2040
|
+
case CstType.BASE:
|
|
2041
|
+
case CstType.CONSTANT:
|
|
2042
|
+
case CstType.STRUCTURED:
|
|
2043
|
+
case CstType.AXIOM:
|
|
2044
|
+
return true;
|
|
2045
|
+
case CstType.TERM:
|
|
2046
|
+
case CstType.FUNCTION:
|
|
2047
|
+
case CstType.PREDICATE:
|
|
2048
|
+
case CstType.STATEMENT:
|
|
2049
|
+
return false;
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
function isBaseSet(type) {
|
|
2053
|
+
switch (type) {
|
|
2054
|
+
case CstType.BASE:
|
|
2055
|
+
case CstType.CONSTANT:
|
|
2056
|
+
return true;
|
|
2057
|
+
case CstType.NOMINAL:
|
|
2058
|
+
case CstType.STRUCTURED:
|
|
2059
|
+
case CstType.AXIOM:
|
|
2060
|
+
case CstType.TERM:
|
|
2061
|
+
case CstType.FUNCTION:
|
|
2062
|
+
case CstType.PREDICATE:
|
|
2063
|
+
case CstType.STATEMENT:
|
|
2064
|
+
return false;
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
function isFunctional(type) {
|
|
2068
|
+
switch (type) {
|
|
2069
|
+
case CstType.FUNCTION:
|
|
2070
|
+
case CstType.PREDICATE:
|
|
2071
|
+
return true;
|
|
2072
|
+
case CstType.NOMINAL:
|
|
2073
|
+
case CstType.BASE:
|
|
2074
|
+
case CstType.CONSTANT:
|
|
2075
|
+
case CstType.STRUCTURED:
|
|
2076
|
+
case CstType.AXIOM:
|
|
2077
|
+
case CstType.TERM:
|
|
2078
|
+
case CstType.STATEMENT:
|
|
2079
|
+
return false;
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
function typeClassForCstType(cstType) {
|
|
2083
|
+
switch (cstType) {
|
|
2084
|
+
case CstType.NOMINAL:
|
|
2085
|
+
case CstType.BASE:
|
|
2086
|
+
case CstType.CONSTANT:
|
|
2087
|
+
case CstType.STRUCTURED:
|
|
2088
|
+
case CstType.TERM:
|
|
2089
|
+
return TypeClass.typification;
|
|
2090
|
+
case CstType.FUNCTION:
|
|
2091
|
+
return TypeClass.function;
|
|
2092
|
+
case CstType.PREDICATE:
|
|
2093
|
+
return TypeClass.predicate;
|
|
2094
|
+
case CstType.AXIOM:
|
|
2095
|
+
case CstType.STATEMENT:
|
|
2096
|
+
return TypeClass.logic;
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
function canHaveFormalDefinition(cstType) {
|
|
2100
|
+
return cstType !== CstType.BASE && cstType !== CstType.CONSTANT;
|
|
2101
|
+
}
|
|
2102
|
+
function getAnalysisFor(expression, cstType, schema, alias) {
|
|
2103
|
+
if (!canHaveFormalDefinition(cstType)) {
|
|
2104
|
+
if (expression.trim().length === 0) {
|
|
2105
|
+
const fallbackAlias = alias && alias.length > 0 ? alias : "X0";
|
|
2106
|
+
const type = cstType === CstType.BASE ? bool(basic(fallbackAlias)) : bool(constant(fallbackAlias));
|
|
2107
|
+
return {
|
|
2108
|
+
success: true,
|
|
2109
|
+
type,
|
|
2110
|
+
valueClass: ValueClass.VALUE,
|
|
2111
|
+
errors: [],
|
|
2112
|
+
ast: null
|
|
2113
|
+
};
|
|
2114
|
+
}
|
|
2115
|
+
return {
|
|
2116
|
+
success: false,
|
|
2117
|
+
type: null,
|
|
2118
|
+
valueClass: null,
|
|
2119
|
+
errors: [
|
|
2120
|
+
{
|
|
2121
|
+
code: RSErrorCode.definitionNotAllowed,
|
|
2122
|
+
from: 0,
|
|
2123
|
+
to: Math.max(0, expression.length - 1)
|
|
2124
|
+
}
|
|
2125
|
+
],
|
|
2126
|
+
ast: null
|
|
2127
|
+
};
|
|
2128
|
+
}
|
|
2129
|
+
return schema.analyzer.checkFull(expression, {
|
|
2130
|
+
expected: typeClassForCstType(cstType),
|
|
2131
|
+
isDomain: cstType === CstType.STRUCTURED
|
|
2132
|
+
});
|
|
2133
|
+
}
|
|
2134
|
+
|
|
2135
|
+
// src/library/rsmodel.ts
|
|
2136
|
+
var TYPE_BASIC = "basic";
|
|
2137
|
+
var EvalStatus = {
|
|
2138
|
+
NO_EVAL: 1,
|
|
2139
|
+
// не вычисляется
|
|
2140
|
+
NOT_PROCESSED: 2,
|
|
2141
|
+
// Интерпретация не вычислялась
|
|
2142
|
+
INVALID_DATA: 3,
|
|
2143
|
+
// Неверные данные
|
|
2144
|
+
EVAL_FAIL: 4,
|
|
2145
|
+
// Ошибка при вычислении
|
|
2146
|
+
AXIOM_FALSE: 5,
|
|
2147
|
+
// Значение аксиомы = FALSE
|
|
2148
|
+
EMPTY: 6,
|
|
2149
|
+
// Значение пусто
|
|
2150
|
+
HAS_DATA: 7
|
|
2151
|
+
// Интерпретация вычислена и не пуста
|
|
2152
|
+
};
|
|
2153
|
+
var DEFAULT_VALUE_TEXT = "N/A";
|
|
2154
|
+
|
|
2155
|
+
// src/library/rsmodel-api.ts
|
|
2156
|
+
function isInferrable(type) {
|
|
2157
|
+
switch (type) {
|
|
2158
|
+
case CstType.AXIOM:
|
|
2159
|
+
case CstType.STATEMENT:
|
|
2160
|
+
case CstType.TERM:
|
|
2161
|
+
return true;
|
|
2162
|
+
case CstType.NOMINAL:
|
|
2163
|
+
case CstType.BASE:
|
|
2164
|
+
case CstType.CONSTANT:
|
|
2165
|
+
case CstType.STRUCTURED:
|
|
2166
|
+
case CstType.FUNCTION:
|
|
2167
|
+
case CstType.PREDICATE:
|
|
2168
|
+
return false;
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
function inferEvalStatus(value, cstType, wasCalculated = true, isInvalid = false) {
|
|
2172
|
+
if (isBaseSet(cstType) || cstType === CstType.STRUCTURED) {
|
|
2173
|
+
if (isInvalid) {
|
|
2174
|
+
return EvalStatus.INVALID_DATA;
|
|
2175
|
+
}
|
|
2176
|
+
if (value === null || Array.isArray(value) && value.length === 0) {
|
|
2177
|
+
return EvalStatus.EMPTY;
|
|
2178
|
+
}
|
|
2179
|
+
return EvalStatus.HAS_DATA;
|
|
2180
|
+
}
|
|
2181
|
+
if (!isInferrable(cstType)) {
|
|
2182
|
+
return EvalStatus.NO_EVAL;
|
|
2183
|
+
}
|
|
2184
|
+
if (!wasCalculated) {
|
|
2185
|
+
return EvalStatus.NOT_PROCESSED;
|
|
2186
|
+
}
|
|
2187
|
+
if (value === null) {
|
|
2188
|
+
return EvalStatus.EVAL_FAIL;
|
|
2189
|
+
}
|
|
2190
|
+
if (cstType === CstType.AXIOM && value !== VALUE_TRUE) {
|
|
2191
|
+
return EvalStatus.AXIOM_FALSE;
|
|
2192
|
+
}
|
|
2193
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
2194
|
+
return EvalStatus.EMPTY;
|
|
2195
|
+
}
|
|
2196
|
+
return EvalStatus.HAS_DATA;
|
|
2197
|
+
}
|
|
2198
|
+
function tryFixValue(value, type, targetAlias, targetValue) {
|
|
2199
|
+
switch (type.typeID) {
|
|
2200
|
+
case TypeID.integer:
|
|
2201
|
+
return false;
|
|
2202
|
+
case TypeID.basic:
|
|
2203
|
+
if (type.baseID !== targetAlias) {
|
|
2204
|
+
return false;
|
|
2205
|
+
}
|
|
2206
|
+
if (typeof value !== "number") {
|
|
2207
|
+
return null;
|
|
2208
|
+
}
|
|
2209
|
+
if (!targetValue.includes(value)) {
|
|
2210
|
+
return null;
|
|
2211
|
+
}
|
|
2212
|
+
return false;
|
|
2213
|
+
case TypeID.tuple: {
|
|
2214
|
+
if (!isTupleValue(value)) {
|
|
2215
|
+
return null;
|
|
2216
|
+
}
|
|
2217
|
+
let wasChanged2 = false;
|
|
2218
|
+
for (let i = 0; i < type.factors.length; i++) {
|
|
2219
|
+
const componentChanged = tryFixValue(value[i + 1], type.factors[i], targetAlias, targetValue);
|
|
2220
|
+
if (componentChanged === null) {
|
|
2221
|
+
return null;
|
|
2222
|
+
}
|
|
2223
|
+
if (componentChanged) {
|
|
2224
|
+
wasChanged2 = true;
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
return wasChanged2;
|
|
2228
|
+
}
|
|
2229
|
+
case TypeID.collection:
|
|
2230
|
+
if (!Array.isArray(value) || value.length > 1 && value[0] === TUPLE_ID) {
|
|
2231
|
+
return null;
|
|
2232
|
+
}
|
|
2233
|
+
let wasChanged = false;
|
|
2234
|
+
const removeElements = [];
|
|
2235
|
+
for (const item of value) {
|
|
2236
|
+
const elementChanged = tryFixValue(item, type.base, targetAlias, targetValue);
|
|
2237
|
+
if (elementChanged === null || elementChanged === true) {
|
|
2238
|
+
wasChanged = true;
|
|
2239
|
+
if (elementChanged === null) {
|
|
2240
|
+
removeElements.push(item);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
for (const item of removeElements) {
|
|
2245
|
+
const index = value.indexOf(item);
|
|
2246
|
+
if (index !== -1) {
|
|
2247
|
+
value.splice(index, 1);
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
if (wasChanged) {
|
|
2251
|
+
value.sort((a, b) => compare(a, b));
|
|
2252
|
+
let i = 1;
|
|
2253
|
+
while (i < value.length) {
|
|
2254
|
+
if (compare(value[i], value[i - 1]) === 0) {
|
|
2255
|
+
value.splice(i, 1);
|
|
2256
|
+
} else {
|
|
2257
|
+
i++;
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
return wasChanged;
|
|
2262
|
+
case TypeID.logic:
|
|
2263
|
+
case TypeID.anyTypification:
|
|
2264
|
+
case TypeID.predicate:
|
|
2265
|
+
case TypeID.function:
|
|
2266
|
+
return null;
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
// src/library/rsengine.ts
|
|
2271
|
+
var INVALID_TYPE_MARKER = "INVALID";
|
|
2272
|
+
var RSEngine = class {
|
|
2273
|
+
modelID;
|
|
2274
|
+
schema = null;
|
|
2275
|
+
data = null;
|
|
2276
|
+
calculator = new RSCalculator();
|
|
2277
|
+
basics = /* @__PURE__ */ new Map();
|
|
2278
|
+
services;
|
|
2279
|
+
notifications;
|
|
2280
|
+
invalidData = /* @__PURE__ */ new Set();
|
|
2281
|
+
calculatedSet = /* @__PURE__ */ new Set();
|
|
2282
|
+
valueSubscribers = /* @__PURE__ */ new Map();
|
|
2283
|
+
statusSubscribers = /* @__PURE__ */ new Map();
|
|
2284
|
+
changeSubscribers = /* @__PURE__ */ new Set();
|
|
2285
|
+
changeGeneration = 0;
|
|
2286
|
+
pendingChange = false;
|
|
2287
|
+
coalescedEmitTimeout = null;
|
|
2288
|
+
constructor(modelID, services, notifications = null) {
|
|
2289
|
+
this.services = services;
|
|
2290
|
+
this.notifications = notifications;
|
|
2291
|
+
this.modelID = modelID;
|
|
2292
|
+
}
|
|
2293
|
+
/** Updates data for {@link RSEngine}. */
|
|
2294
|
+
loadData(schema, model) {
|
|
2295
|
+
const oldSchema = this.schema;
|
|
2296
|
+
const newSchema = oldSchema !== schema;
|
|
2297
|
+
this.schema = schema;
|
|
2298
|
+
if (newSchema) {
|
|
2299
|
+
const changedCst = this.collectChanged(oldSchema, schema);
|
|
2300
|
+
this.prepareAst();
|
|
2301
|
+
this.setupEmptySets();
|
|
2302
|
+
this.onChangeDefinitions(changedCst);
|
|
2303
|
+
}
|
|
2304
|
+
if (this.data !== model) {
|
|
2305
|
+
this.data = model;
|
|
2306
|
+
this.prepareValues();
|
|
2307
|
+
}
|
|
2308
|
+
this.notifyAll();
|
|
2309
|
+
}
|
|
2310
|
+
/** Updates services for {@link RSEngine}. */
|
|
2311
|
+
updateServices(services) {
|
|
2312
|
+
this.services = services;
|
|
2313
|
+
}
|
|
2314
|
+
/** Updates notifications for {@link RSEngine}. */
|
|
2315
|
+
updateNotifications(notifications) {
|
|
2316
|
+
this.notifications = notifications;
|
|
2317
|
+
}
|
|
2318
|
+
/** Gets value of {@link Constituenta}. */
|
|
2319
|
+
getCstValue(cstID) {
|
|
2320
|
+
const cst = this.schema?.cstByID.get(cstID);
|
|
2321
|
+
if (!cst) {
|
|
2322
|
+
return null;
|
|
2323
|
+
}
|
|
2324
|
+
return this.calculator.getValue(cst.alias);
|
|
2325
|
+
}
|
|
2326
|
+
/** Gets status of {@link Constituenta}. */
|
|
2327
|
+
getCstStatus(cstID) {
|
|
2328
|
+
const cst = this.schema?.cstByID.get(cstID);
|
|
2329
|
+
if (!cst) {
|
|
2330
|
+
return inferEvalStatus(null, CstType.NOMINAL, false);
|
|
2331
|
+
}
|
|
2332
|
+
const value = this.calculator.getValue(cst.alias);
|
|
2333
|
+
return inferEvalStatus(value, cst.cst_type, this.calculatedSet.has(cstID), this.invalidData.has(cstID));
|
|
2334
|
+
}
|
|
2335
|
+
/** Subscribe to value change of {@link Constituenta}. */
|
|
2336
|
+
subscribeValue(cstID, callbackFn) {
|
|
2337
|
+
let subs = this.valueSubscribers.get(cstID);
|
|
2338
|
+
if (!subs) {
|
|
2339
|
+
subs = /* @__PURE__ */ new Set();
|
|
2340
|
+
this.valueSubscribers.set(cstID, subs);
|
|
2341
|
+
}
|
|
2342
|
+
subs.add(callbackFn);
|
|
2343
|
+
return () => {
|
|
2344
|
+
const current = this.valueSubscribers.get(cstID);
|
|
2345
|
+
if (!current) {
|
|
2346
|
+
return;
|
|
2347
|
+
}
|
|
2348
|
+
current.delete(callbackFn);
|
|
2349
|
+
if (current.size === 0) {
|
|
2350
|
+
this.valueSubscribers.delete(cstID);
|
|
2351
|
+
}
|
|
2352
|
+
};
|
|
2353
|
+
}
|
|
2354
|
+
/** Subscribe to status change of {@link Constituenta}. */
|
|
2355
|
+
subscribeStatus(cstID, callbackFn) {
|
|
2356
|
+
let subs = this.statusSubscribers.get(cstID);
|
|
2357
|
+
if (!subs) {
|
|
2358
|
+
subs = /* @__PURE__ */ new Set();
|
|
2359
|
+
this.statusSubscribers.set(cstID, subs);
|
|
2360
|
+
}
|
|
2361
|
+
subs.add(callbackFn);
|
|
2362
|
+
return () => {
|
|
2363
|
+
const current = this.statusSubscribers.get(cstID);
|
|
2364
|
+
if (!current) {
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
current.delete(callbackFn);
|
|
2368
|
+
if (current.size === 0) {
|
|
2369
|
+
this.statusSubscribers.delete(cstID);
|
|
2370
|
+
}
|
|
2371
|
+
};
|
|
2372
|
+
}
|
|
2373
|
+
/**
|
|
2374
|
+
* Subscribe to any engine change that can affect evaluation (values, status, or loaded data).
|
|
2375
|
+
*/
|
|
2376
|
+
subscribeChanges(callbackFn) {
|
|
2377
|
+
this.changeSubscribers.add(callbackFn);
|
|
2378
|
+
return () => {
|
|
2379
|
+
this.changeSubscribers.delete(callbackFn);
|
|
2380
|
+
};
|
|
2381
|
+
}
|
|
2382
|
+
/** Monotonic counter bumped whenever the engine emits a change to {@link RSEngine.subscribeChanges} listeners. */
|
|
2383
|
+
getChangeGeneration() {
|
|
2384
|
+
return this.changeGeneration;
|
|
2385
|
+
}
|
|
2386
|
+
/**
|
|
2387
|
+
* Runs pending {@link RSEngine.subscribeChanges} notifications immediately and clears the coalescing queue.
|
|
2388
|
+
* Use after a synchronous batch of engine updates when listeners must observe a bumped {@link getChangeGeneration}
|
|
2389
|
+
* in the same turn.
|
|
2390
|
+
*/
|
|
2391
|
+
flushPendingChanges() {
|
|
2392
|
+
if (this.coalescedEmitTimeout !== null) {
|
|
2393
|
+
clearTimeout(this.coalescedEmitTimeout);
|
|
2394
|
+
this.coalescedEmitTimeout = null;
|
|
2395
|
+
}
|
|
2396
|
+
if (!this.pendingChange) {
|
|
2397
|
+
return;
|
|
2398
|
+
}
|
|
2399
|
+
this.pendingChange = false;
|
|
2400
|
+
this.emitChange();
|
|
2401
|
+
}
|
|
2402
|
+
/** Sets value for {@link Constituenta} from {@link Value}. */
|
|
2403
|
+
async setStructureValue(cstID, data) {
|
|
2404
|
+
const cst = this.schema?.cstByID.get(cstID);
|
|
2405
|
+
if (!this.schema || !cst || isInferrable(cst.cst_type)) {
|
|
2406
|
+
this.notifications?.onInvalidSetValue();
|
|
2407
|
+
return;
|
|
2408
|
+
}
|
|
2409
|
+
const typeStr = cst.effectiveType ? normalizeType(cst.effectiveType) : INVALID_TYPE_MARKER;
|
|
2410
|
+
const payload = [{ target: cstID, type: typeStr, data }];
|
|
2411
|
+
await this.services.setCstValue({ itemID: this.modelID, data: payload });
|
|
2412
|
+
if (!cst.effectiveType || !this.calculator.validate(data, cst.effectiveType)) {
|
|
2413
|
+
this.invalidData.add(cstID);
|
|
2414
|
+
} else {
|
|
2415
|
+
this.invalidData.delete(cstID);
|
|
2416
|
+
}
|
|
2417
|
+
this.calculator.setValue(cst.alias, data);
|
|
2418
|
+
this.notifyCst(cstID);
|
|
2419
|
+
this.cascadeReset([cstID]);
|
|
2420
|
+
}
|
|
2421
|
+
/** Sets value for {@link Constituenta} from {@link BasicBinding}. */
|
|
2422
|
+
async setBasicValue(cstID, data) {
|
|
2423
|
+
const cst = this.schema?.cstByID.get(cstID);
|
|
2424
|
+
if (!this.schema || !cst || !isBaseSet(cst.cst_type)) {
|
|
2425
|
+
this.notifications?.onInvalidSetValue();
|
|
2426
|
+
return;
|
|
2427
|
+
}
|
|
2428
|
+
const oldValue = this.calculator.getValue(cst.alias);
|
|
2429
|
+
const newValue = Object.keys(data).map(Number);
|
|
2430
|
+
const updateList = [
|
|
2431
|
+
{ target: cstID, type: TYPE_BASIC, data }
|
|
2432
|
+
];
|
|
2433
|
+
const resetList = [];
|
|
2434
|
+
if (oldValue !== null && compare(newValue, oldValue) !== 0) {
|
|
2435
|
+
const dependencies = this.schema.graph.expandAllOutputs([cstID]);
|
|
2436
|
+
for (const childID of dependencies) {
|
|
2437
|
+
const child = this.schema.cstByID.get(childID);
|
|
2438
|
+
if (child.cst_type === CstType.STRUCTURED && !!child.effectiveType) {
|
|
2439
|
+
const value = this.calculator.getValue(child.alias);
|
|
2440
|
+
if (value !== null) {
|
|
2441
|
+
const fix = tryFixValue(value, child.effectiveType, cst.alias, newValue);
|
|
2442
|
+
if (fix === null) {
|
|
2443
|
+
resetList.push(childID);
|
|
2444
|
+
} else if (fix === true) {
|
|
2445
|
+
const typeStr = normalizeType(child.effectiveType);
|
|
2446
|
+
updateList.push({ target: childID, type: typeStr, data: [...value] });
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
if (resetList.length > 0) {
|
|
2453
|
+
await Promise.all([
|
|
2454
|
+
this.services.setCstValue({ itemID: this.modelID, data: updateList }),
|
|
2455
|
+
this.services.clearValues({ itemID: this.modelID, data: { items: resetList } })
|
|
2456
|
+
]);
|
|
2457
|
+
} else {
|
|
2458
|
+
await this.services.setCstValue({ itemID: this.modelID, data: updateList });
|
|
2459
|
+
}
|
|
2460
|
+
const changed = [...resetList, ...updateList.map((item) => item.target)];
|
|
2461
|
+
this.basics.set(cstID, data);
|
|
2462
|
+
this.calculator.setValue(cst.alias, Object.keys(data).map(Number));
|
|
2463
|
+
for (const item of resetList) {
|
|
2464
|
+
this.calculator.resetValue(this.schema.cstByID.get(item).alias);
|
|
2465
|
+
this.notifyCst(item);
|
|
2466
|
+
}
|
|
2467
|
+
for (const updateData of updateList) {
|
|
2468
|
+
if (updateData.target !== cstID) {
|
|
2469
|
+
this.calculator.setValue(
|
|
2470
|
+
this.schema.cstByID.get(updateData.target).alias,
|
|
2471
|
+
updateData.data
|
|
2472
|
+
);
|
|
2473
|
+
this.notifyCst(updateData.target);
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
for (const item of changed) {
|
|
2477
|
+
this.notifyCst(item);
|
|
2478
|
+
}
|
|
2479
|
+
this.cascadeReset(changed);
|
|
2480
|
+
}
|
|
2481
|
+
/** Resets value for {@link Constituenta}. */
|
|
2482
|
+
async resetValue(cstID) {
|
|
2483
|
+
const cst = this.schema?.cstByID.get(cstID);
|
|
2484
|
+
if (!cst) {
|
|
2485
|
+
return;
|
|
2486
|
+
}
|
|
2487
|
+
await this.services.clearValues({ itemID: this.modelID, data: { items: [cstID] } });
|
|
2488
|
+
this.calculator.resetValue(cst.alias);
|
|
2489
|
+
this.basics.delete(cstID);
|
|
2490
|
+
this.calculatedSet.delete(cstID);
|
|
2491
|
+
this.invalidData.delete(cstID);
|
|
2492
|
+
this.notifyCst(cstID);
|
|
2493
|
+
}
|
|
2494
|
+
/** Evaluates expression for {@link RSEngine}. */
|
|
2495
|
+
evaluateExpression(expression, cstType) {
|
|
2496
|
+
return getEvaluationFor(
|
|
2497
|
+
expression,
|
|
2498
|
+
cstType,
|
|
2499
|
+
this.schema,
|
|
2500
|
+
this.calculator,
|
|
2501
|
+
(message) => this.notifications?.onEvaluationError(message)
|
|
2502
|
+
);
|
|
2503
|
+
}
|
|
2504
|
+
/** Evaluates AST for {@link RSEngine}. */
|
|
2505
|
+
evaluateAst(ast, options) {
|
|
2506
|
+
try {
|
|
2507
|
+
const evaluation = this.calculator.evaluateFull(ast, options);
|
|
2508
|
+
return evaluation;
|
|
2509
|
+
} catch (error) {
|
|
2510
|
+
this.notifications?.onEvaluationError(error.message);
|
|
2511
|
+
console.error(error);
|
|
2512
|
+
return {
|
|
2513
|
+
value: null,
|
|
2514
|
+
iterations: 0,
|
|
2515
|
+
cacheHits: 0,
|
|
2516
|
+
errors: []
|
|
2517
|
+
};
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
/** Calculates value for {@link Constituenta}. */
|
|
2521
|
+
calculateCst(cstID) {
|
|
2522
|
+
const cst = this.schema?.cstByID.get(cstID);
|
|
2523
|
+
if (!cst || !this.schema) {
|
|
2524
|
+
return { value: null, iterations: 0, errors: [], cacheHits: 0 };
|
|
2525
|
+
}
|
|
2526
|
+
if (!this.calculatedSet.has(cstID)) {
|
|
2527
|
+
const predecessors = this.schema.graph.expandAllInputs([cstID]);
|
|
2528
|
+
this.prepareEvaluation(predecessors);
|
|
2529
|
+
}
|
|
2530
|
+
const result = getEvaluationFor(
|
|
2531
|
+
cst.definition_formal,
|
|
2532
|
+
cst.cst_type,
|
|
2533
|
+
this.schema,
|
|
2534
|
+
this.calculator,
|
|
2535
|
+
(message) => this.notifications?.onEvaluationError(message)
|
|
2536
|
+
);
|
|
2537
|
+
if (result.value === null) {
|
|
2538
|
+
this.calculator.resetValue(cst.alias);
|
|
2539
|
+
} else {
|
|
2540
|
+
this.calculator.setValue(cst.alias, result.value);
|
|
2541
|
+
}
|
|
2542
|
+
this.calculatedSet.add(cstID);
|
|
2543
|
+
this.notifyCst(cstID);
|
|
2544
|
+
return result;
|
|
2545
|
+
}
|
|
2546
|
+
/** Recalculate model for all inferrable expressions. */
|
|
2547
|
+
recalculateAll() {
|
|
2548
|
+
const start = performance.now();
|
|
2549
|
+
this.calculatedSet.clear();
|
|
2550
|
+
this.recalculateInternal();
|
|
2551
|
+
const end = performance.now();
|
|
2552
|
+
const timeSpent = ((end - start) / 1e3).toFixed(2);
|
|
2553
|
+
this.notifications?.onCalculationSuccess(timeSpent);
|
|
2554
|
+
}
|
|
2555
|
+
/** Notify subscribers about value and status change of {@link Constituenta}. */
|
|
2556
|
+
notifyCst(cstID) {
|
|
2557
|
+
this.notifyStatus(cstID);
|
|
2558
|
+
this.notifyValue(cstID);
|
|
2559
|
+
this.scheduleCoalescedEmitChange();
|
|
2560
|
+
}
|
|
2561
|
+
/** Notify all subscribers about value change. */
|
|
2562
|
+
notifyValue(cstID) {
|
|
2563
|
+
const subs = this.valueSubscribers.get(cstID);
|
|
2564
|
+
if (subs) {
|
|
2565
|
+
for (const cb of subs) cb();
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
/** Notify all subscribers about status change. */
|
|
2569
|
+
notifyStatus(cstID) {
|
|
2570
|
+
const subs = this.statusSubscribers.get(cstID);
|
|
2571
|
+
if (subs) {
|
|
2572
|
+
for (const cb of subs) cb();
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
/** Notify all subscribers about value and status change. */
|
|
2576
|
+
notifyAll() {
|
|
2577
|
+
for (const subs of this.valueSubscribers.values()) {
|
|
2578
|
+
for (const cb of subs) cb();
|
|
2579
|
+
}
|
|
2580
|
+
for (const subs of this.statusSubscribers.values()) {
|
|
2581
|
+
for (const cb of subs) cb();
|
|
2582
|
+
}
|
|
2583
|
+
this.scheduleCoalescedEmitChange();
|
|
2584
|
+
}
|
|
2585
|
+
scheduleCoalescedEmitChange() {
|
|
2586
|
+
this.pendingChange = true;
|
|
2587
|
+
if (this.coalescedEmitTimeout !== null) {
|
|
2588
|
+
return;
|
|
2589
|
+
}
|
|
2590
|
+
this.coalescedEmitTimeout = setTimeout(
|
|
2591
|
+
function runCoalescedEmitChange() {
|
|
2592
|
+
this.coalescedEmitTimeout = null;
|
|
2593
|
+
if (!this.pendingChange) {
|
|
2594
|
+
return;
|
|
2595
|
+
}
|
|
2596
|
+
this.pendingChange = false;
|
|
2597
|
+
this.emitChange();
|
|
2598
|
+
}.bind(this),
|
|
2599
|
+
0
|
|
2600
|
+
);
|
|
2601
|
+
}
|
|
2602
|
+
emitChange() {
|
|
2603
|
+
this.changeGeneration += 1;
|
|
2604
|
+
for (const cb of this.changeSubscribers) {
|
|
2605
|
+
cb();
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
prepareAst() {
|
|
2609
|
+
this.calculator.clearAllAst();
|
|
2610
|
+
const functions = this.schema.items.filter((cst) => isFunctional(cst.cst_type) && cst.analysis?.success);
|
|
2611
|
+
for (const cst of functions) {
|
|
2612
|
+
const fullAnalysis = getAnalysisFor(cst.definition_formal, cst.cst_type, this.schema);
|
|
2613
|
+
if (fullAnalysis.ast) {
|
|
2614
|
+
this.calculator.setAST(cst.alias, fullAnalysis.ast);
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
prepareValues() {
|
|
2619
|
+
this.basics.clear();
|
|
2620
|
+
this.invalidData.clear();
|
|
2621
|
+
this.calculatedSet.clear();
|
|
2622
|
+
for (const item of this.data.items) {
|
|
2623
|
+
const cst = this.schema.cstByID.get(item.id);
|
|
2624
|
+
if (item.type === TYPE_BASIC) {
|
|
2625
|
+
if (cst.cst_type !== CstType.BASE && cst.cst_type !== CstType.CONSTANT) {
|
|
2626
|
+
throw new Error(`Invalid data for ${cst.alias}`);
|
|
2627
|
+
}
|
|
2628
|
+
const data = item.value;
|
|
2629
|
+
this.basics.set(cst.id, data);
|
|
2630
|
+
this.calculator.setValue(cst.alias, Object.keys(data).map(Number));
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
for (const item of this.data.items) {
|
|
2634
|
+
const cst = this.schema.cstByID.get(item.id);
|
|
2635
|
+
if (item.type !== TYPE_BASIC) {
|
|
2636
|
+
this.calculator.setValue(cst.alias, item.value);
|
|
2637
|
+
if (!cst.effectiveType || !this.calculator.validate(item.value, cst.effectiveType)) {
|
|
2638
|
+
this.invalidData.add(item.id);
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
this.setupEmptySets();
|
|
2643
|
+
}
|
|
2644
|
+
setupEmptySets() {
|
|
2645
|
+
for (const cst of this.schema.items) {
|
|
2646
|
+
if (isBasicConcept(cst.cst_type) && this.schema.analyzer.getType(cst.alias)?.typeID === TypeID.collection) {
|
|
2647
|
+
if (this.calculator.getValue(cst.alias) === null) {
|
|
2648
|
+
this.calculator.setValue(cst.alias, []);
|
|
2649
|
+
}
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
collectChanged(previousSchema, nextSchema) {
|
|
2654
|
+
if (!previousSchema) {
|
|
2655
|
+
return [];
|
|
2656
|
+
}
|
|
2657
|
+
const changedIDs = [];
|
|
2658
|
+
for (const cst of nextSchema.items) {
|
|
2659
|
+
const prev = previousSchema.cstByID.get(cst.id);
|
|
2660
|
+
if (prev && (prev.definition_formal !== cst.definition_formal || prev.alias !== cst.alias)) {
|
|
2661
|
+
changedIDs.push(cst.id);
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
return changedIDs;
|
|
2665
|
+
}
|
|
2666
|
+
onChangeDefinitions(cstIDs) {
|
|
2667
|
+
if (!this.schema || cstIDs.length === 0) {
|
|
2668
|
+
return;
|
|
2669
|
+
}
|
|
2670
|
+
for (const cstID of cstIDs) {
|
|
2671
|
+
const cst = this.schema.cstByID.get(cstID);
|
|
2672
|
+
if (!cst || !isInferrable(cst.cst_type)) {
|
|
2673
|
+
continue;
|
|
2674
|
+
}
|
|
2675
|
+
this.calculatedSet.delete(cstID);
|
|
2676
|
+
this.calculator.resetValue(cst.alias);
|
|
2677
|
+
this.notifyCst(cstID);
|
|
2678
|
+
}
|
|
2679
|
+
this.cascadeReset(cstIDs);
|
|
2680
|
+
}
|
|
2681
|
+
cascadeReset(cstIDs) {
|
|
2682
|
+
if (!this.schema) {
|
|
2683
|
+
return;
|
|
2684
|
+
}
|
|
2685
|
+
const dependencies = this.schema.graph.expandAllOutputs(cstIDs);
|
|
2686
|
+
for (const cstID of dependencies) {
|
|
2687
|
+
const cst = this.schema.cstByID.get(cstID);
|
|
2688
|
+
if (!cst || !isInferrable(cst.cst_type)) {
|
|
2689
|
+
continue;
|
|
2690
|
+
}
|
|
2691
|
+
this.calculatedSet.delete(cstID);
|
|
2692
|
+
this.calculator.resetValue(this.schema.cstByID.get(cstID).alias);
|
|
2693
|
+
this.notifyCst(cstID);
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
prepareEvaluation(dependencies) {
|
|
2697
|
+
for (const cstID of this.schema.graph.topologicalOrder()) {
|
|
2698
|
+
if (dependencies.includes(cstID)) {
|
|
2699
|
+
const cst = this.schema.cstByID.get(cstID);
|
|
2700
|
+
if (isInferrable(cst.cst_type)) {
|
|
2701
|
+
const value = fastEvaluation(
|
|
2702
|
+
cst.definition_formal,
|
|
2703
|
+
cst.cst_type,
|
|
2704
|
+
this.schema,
|
|
2705
|
+
this.calculator,
|
|
2706
|
+
(message) => this.notifications?.onEvaluationError(message)
|
|
2707
|
+
);
|
|
2708
|
+
if (value !== null) {
|
|
2709
|
+
this.calculator.setValue(cst.alias, value);
|
|
2710
|
+
} else {
|
|
2711
|
+
this.calculator.resetValue(cst.alias);
|
|
2712
|
+
}
|
|
2713
|
+
this.notifyCst(cstID);
|
|
2714
|
+
}
|
|
2715
|
+
this.calculatedSet.add(cstID);
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
}
|
|
2719
|
+
recalculateInternal() {
|
|
2720
|
+
const processedIDs = [];
|
|
2721
|
+
for (const cst of this.schema.cstByID.values()) {
|
|
2722
|
+
if (isInferrable(cst.cst_type)) {
|
|
2723
|
+
this.calculator.resetValue(cst.alias);
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
for (const cstID of this.schema.graph.topologicalOrder()) {
|
|
2727
|
+
processedIDs.push(cstID);
|
|
2728
|
+
const cst = this.schema.cstByID.get(cstID);
|
|
2729
|
+
if (isInferrable(cst.cst_type)) {
|
|
2730
|
+
const value = fastEvaluation(cst.definition_formal, cst.cst_type, this.schema, this.calculator);
|
|
2731
|
+
this.calculatedSet.add(cstID);
|
|
2732
|
+
if (value !== null) {
|
|
2733
|
+
this.calculator.setValue(cst.alias, value);
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
this.notifyAll();
|
|
2738
|
+
}
|
|
2739
|
+
};
|
|
2740
|
+
function getEvaluationFor(expression, cstType, schema, calculator, onEvaluationError) {
|
|
2741
|
+
const parse = getAnalysisFor(expression, cstType, schema);
|
|
2742
|
+
if (!parse.success || !parse.ast) {
|
|
2743
|
+
return {
|
|
2744
|
+
value: null,
|
|
2745
|
+
iterations: 0,
|
|
2746
|
+
cacheHits: 0,
|
|
2747
|
+
errors: parse.errors
|
|
2748
|
+
};
|
|
2749
|
+
} else {
|
|
2750
|
+
try {
|
|
2751
|
+
const result = calculator.evaluateFull(parse.ast);
|
|
2752
|
+
return {
|
|
2753
|
+
value: result.value,
|
|
2754
|
+
iterations: result.iterations,
|
|
2755
|
+
cacheHits: result.cacheHits,
|
|
2756
|
+
errors: [...parse.errors, ...result.errors]
|
|
2757
|
+
};
|
|
2758
|
+
} catch (error) {
|
|
2759
|
+
onEvaluationError?.(error.message);
|
|
2760
|
+
console.error(expression, error);
|
|
2761
|
+
return {
|
|
2762
|
+
value: null,
|
|
2763
|
+
iterations: 0,
|
|
2764
|
+
cacheHits: 0,
|
|
2765
|
+
errors: []
|
|
2766
|
+
};
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
function fastEvaluation(expression, cstType, schema, calculator, onEvaluationError) {
|
|
2771
|
+
const parse = getAnalysisFor(expression, cstType, schema);
|
|
2772
|
+
if (!parse.success || !parse.ast) {
|
|
2773
|
+
return null;
|
|
2774
|
+
} else {
|
|
2775
|
+
try {
|
|
2776
|
+
return calculator.evaluateFast(parse.ast);
|
|
2777
|
+
} catch (error) {
|
|
2778
|
+
onEvaluationError?.(error.message);
|
|
2779
|
+
console.error(expression, error);
|
|
2780
|
+
return null;
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
export {
|
|
2785
|
+
AccessPolicy,
|
|
2786
|
+
CstClass,
|
|
2787
|
+
CstStatus,
|
|
2788
|
+
CstType,
|
|
2789
|
+
DEFAULT_VALUE_TEXT,
|
|
2790
|
+
EvalStatus,
|
|
2791
|
+
FolderNode,
|
|
2792
|
+
FolderTree,
|
|
2793
|
+
LibraryItemType,
|
|
2794
|
+
LocationHead,
|
|
2795
|
+
NodeType,
|
|
2796
|
+
OperationType,
|
|
2797
|
+
RSEngine,
|
|
2798
|
+
SubstitutionErrorType
|
|
2799
|
+
};
|
|
2800
|
+
//# sourceMappingURL=index.js.map
|