@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,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module: Value auditor for AST value class checking.
|
|
3
|
+
*
|
|
4
|
+
* Determines whether an expression yields a concrete value (computable)
|
|
5
|
+
* or a property (e.g., depends on a quantified variable).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { type AstNode, getNodeText } from '../../parsing';
|
|
9
|
+
import { annotateError } from '../ast-annotations';
|
|
10
|
+
import { type ErrorReporter, RSErrorCode } from '../error';
|
|
11
|
+
import { TokenID } from '../parser/token';
|
|
12
|
+
|
|
13
|
+
import { ValueClass, type ValueClassContext } from './value-class';
|
|
14
|
+
|
|
15
|
+
/** Value auditor for AST value class checking. */
|
|
16
|
+
export class ValueAuditor {
|
|
17
|
+
private context: ValueClassContext;
|
|
18
|
+
private annotateErrors: boolean;
|
|
19
|
+
private reporter?: ErrorReporter;
|
|
20
|
+
|
|
21
|
+
constructor(context: ValueClassContext) {
|
|
22
|
+
this.context = context;
|
|
23
|
+
this.annotateErrors = false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Runs value audit on the AST. Returns the value class on success, null on failure.
|
|
28
|
+
*/
|
|
29
|
+
run(ast: AstNode, reporter?: ErrorReporter, annotateErrors: boolean = false): ValueClass | null {
|
|
30
|
+
if (ast.hasError) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
this.reporter = reporter;
|
|
34
|
+
this.annotateErrors = annotateErrors;
|
|
35
|
+
return this.dispatchVisit(ast);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private dispatchVisit(node: AstNode): ValueClass | null {
|
|
39
|
+
switch (node.typeID) {
|
|
40
|
+
case TokenID.ID_GLOBAL:
|
|
41
|
+
case TokenID.ID_FUNCTION:
|
|
42
|
+
case TokenID.ID_PREDICATE:
|
|
43
|
+
return this.visitGlobal(node);
|
|
44
|
+
|
|
45
|
+
case TokenID.ID_LOCAL:
|
|
46
|
+
case TokenID.ID_RADICAL:
|
|
47
|
+
case TokenID.LIT_INTEGER:
|
|
48
|
+
case TokenID.LIT_EMPTYSET:
|
|
49
|
+
return ValueClass.VALUE;
|
|
50
|
+
|
|
51
|
+
case TokenID.LIT_WHOLE_NUMBERS:
|
|
52
|
+
return ValueClass.PROPERTY;
|
|
53
|
+
|
|
54
|
+
case TokenID.NT_TUPLE_DECL:
|
|
55
|
+
case TokenID.NT_ENUM_DECL:
|
|
56
|
+
return this.visitAllAndReturn(node, ValueClass.VALUE);
|
|
57
|
+
|
|
58
|
+
case TokenID.NT_ARGUMENTS:
|
|
59
|
+
case TokenID.NT_ARG_DECL:
|
|
60
|
+
return this.visitAllAndReturn(node, ValueClass.VALUE);
|
|
61
|
+
|
|
62
|
+
case TokenID.PLUS:
|
|
63
|
+
case TokenID.MINUS:
|
|
64
|
+
case TokenID.MULTIPLY:
|
|
65
|
+
return this.visitAllAndReturn(node, ValueClass.VALUE);
|
|
66
|
+
|
|
67
|
+
case TokenID.QUANTOR_UNIVERSAL:
|
|
68
|
+
case TokenID.QUANTOR_EXISTS:
|
|
69
|
+
return this.visitQuantifier(node);
|
|
70
|
+
|
|
71
|
+
case TokenID.LOGIC_NOT:
|
|
72
|
+
case TokenID.LOGIC_AND:
|
|
73
|
+
case TokenID.LOGIC_OR:
|
|
74
|
+
case TokenID.LOGIC_IMPLICATION:
|
|
75
|
+
case TokenID.LOGIC_EQUIVALENT:
|
|
76
|
+
return this.visitAllAndReturn(node, ValueClass.VALUE);
|
|
77
|
+
|
|
78
|
+
case TokenID.EQUAL:
|
|
79
|
+
case TokenID.NOTEQUAL:
|
|
80
|
+
return this.assertAllValues(node);
|
|
81
|
+
|
|
82
|
+
case TokenID.GREATER:
|
|
83
|
+
case TokenID.LESSER:
|
|
84
|
+
case TokenID.GREATER_OR_EQ:
|
|
85
|
+
case TokenID.LESSER_OR_EQ:
|
|
86
|
+
return this.visitAllAndReturn(node, ValueClass.VALUE);
|
|
87
|
+
|
|
88
|
+
case TokenID.SET_IN:
|
|
89
|
+
case TokenID.SET_NOT_IN:
|
|
90
|
+
case TokenID.SUBSET:
|
|
91
|
+
case TokenID.SUBSET_OR_EQ:
|
|
92
|
+
case TokenID.NOT_SUBSET:
|
|
93
|
+
return this.visitSetexprPredicate(node);
|
|
94
|
+
|
|
95
|
+
case TokenID.DECART:
|
|
96
|
+
return this.visitDecart(node);
|
|
97
|
+
case TokenID.BOOLEAN:
|
|
98
|
+
return this.visitBoolean(node);
|
|
99
|
+
|
|
100
|
+
case TokenID.NT_TUPLE:
|
|
101
|
+
case TokenID.NT_ENUMERATION:
|
|
102
|
+
return this.assertAllValues(node);
|
|
103
|
+
|
|
104
|
+
case TokenID.FILTER:
|
|
105
|
+
return this.visitFilter(node);
|
|
106
|
+
|
|
107
|
+
case TokenID.CARD:
|
|
108
|
+
case TokenID.BOOL:
|
|
109
|
+
case TokenID.DEBOOL:
|
|
110
|
+
case TokenID.BIGPR:
|
|
111
|
+
case TokenID.SMALLPR:
|
|
112
|
+
case TokenID.REDUCE:
|
|
113
|
+
return this.assertChildIsValue(node, 0);
|
|
114
|
+
|
|
115
|
+
case TokenID.SET_UNION:
|
|
116
|
+
case TokenID.SET_INTERSECTION:
|
|
117
|
+
case TokenID.SET_MINUS:
|
|
118
|
+
case TokenID.SET_SYMMETRIC_MINUS:
|
|
119
|
+
return this.visitSetexprBinary(node);
|
|
120
|
+
|
|
121
|
+
case TokenID.NT_FUNC_DEFINITION:
|
|
122
|
+
return this.visitFunctionDefinition(node);
|
|
123
|
+
case TokenID.NT_FUNC_CALL:
|
|
124
|
+
return this.visitFunctionCall(node);
|
|
125
|
+
|
|
126
|
+
case TokenID.NT_DECLARATIVE_EXPR:
|
|
127
|
+
return this.visitDeclarative(node);
|
|
128
|
+
case TokenID.NT_IMPERATIVE_EXPR:
|
|
129
|
+
return this.visitImperative(node);
|
|
130
|
+
|
|
131
|
+
case TokenID.NT_RECURSIVE_FULL:
|
|
132
|
+
case TokenID.NT_RECURSIVE_SHORT:
|
|
133
|
+
return this.assertAllValues(node);
|
|
134
|
+
|
|
135
|
+
case TokenID.ITERATE:
|
|
136
|
+
case TokenID.ASSIGN:
|
|
137
|
+
return this.visitIterateOrAssign(node);
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private onError(code: RSErrorCode, node: AstNode, params?: string[]): null {
|
|
143
|
+
this.reporter?.({ code, from: node.from, to: node.to, params });
|
|
144
|
+
if (this.annotateErrors) {
|
|
145
|
+
annotateError(node, code, params);
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private visitChild(node: AstNode, index: number): ValueClass | null {
|
|
151
|
+
return this.dispatchVisit(node.children[index]);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private visitAllAndReturn(node: AstNode, value: ValueClass): ValueClass | null {
|
|
155
|
+
for (const child of node.children) {
|
|
156
|
+
if (this.dispatchVisit(child) === null) {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return value;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private assertChildIsValue(node: AstNode, index: number): ValueClass | null {
|
|
164
|
+
const result = this.visitChild(node, index);
|
|
165
|
+
if (result === null) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
if (result !== ValueClass.VALUE) {
|
|
169
|
+
const child = node.children[index];
|
|
170
|
+
return this.onError(RSErrorCode.invalidPropertyUsage, child ?? node);
|
|
171
|
+
}
|
|
172
|
+
return ValueClass.VALUE;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private assertAllValues(node: AstNode): ValueClass | null {
|
|
176
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
177
|
+
if (this.assertChildIsValue(node, i) === null) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return ValueClass.VALUE;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private visitFunctionDefinition(node: AstNode): ValueClass | null {
|
|
185
|
+
if (this.visitChild(node, 0) === null) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
return this.visitChild(node, 1);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private visitFunctionCall(node: AstNode): ValueClass | null {
|
|
192
|
+
const result = this.visitChild(node, 0);
|
|
193
|
+
if (result === null) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
for (let child = 1; child < node.children.length; child++) {
|
|
197
|
+
if (this.assertChildIsValue(node, child) === null) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
private visitGlobal(node: AstNode): ValueClass | null {
|
|
205
|
+
const alias = getNodeText(node);
|
|
206
|
+
const result = this.context.get(alias);
|
|
207
|
+
if (!result) {
|
|
208
|
+
return this.onError(RSErrorCode.globalNoValue, node, [alias]);
|
|
209
|
+
}
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
private visitQuantifier(node: AstNode): ValueClass | null {
|
|
214
|
+
if (this.assertChildIsValue(node, 1) === null) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
if (this.visitChild(node, 2) === null) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
return ValueClass.VALUE;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private visitSetexprPredicate(node: AstNode): ValueClass | null {
|
|
224
|
+
const tokenId = node.typeID as TokenID;
|
|
225
|
+
switch (tokenId) {
|
|
226
|
+
case TokenID.SET_IN:
|
|
227
|
+
case TokenID.SET_NOT_IN:
|
|
228
|
+
case TokenID.SUBSET_OR_EQ:
|
|
229
|
+
if (this.assertChildIsValue(node, 0) === null) {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
if (this.visitChild(node, 1) === null) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
return ValueClass.VALUE;
|
|
236
|
+
|
|
237
|
+
case TokenID.SUBSET:
|
|
238
|
+
case TokenID.NOT_SUBSET:
|
|
239
|
+
return this.assertAllValues(node);
|
|
240
|
+
}
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
private visitDeclarative(node: AstNode): ValueClass | null {
|
|
245
|
+
if (this.visitChild(node, 2) === null) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
return this.visitChild(node, 1);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private visitImperative(node: AstNode): ValueClass | null {
|
|
252
|
+
for (let child = 1; child < node.children.length; child++) {
|
|
253
|
+
if (this.visitChild(node, child) === null) {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return this.assertChildIsValue(node, 0);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
private visitIterateOrAssign(node: AstNode): ValueClass | null {
|
|
261
|
+
if (this.visitChild(node, 0) === null) {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
return this.assertChildIsValue(node, 1);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
private visitDecart(node: AstNode): ValueClass | null {
|
|
268
|
+
let result: ValueClass = ValueClass.VALUE;
|
|
269
|
+
for (let child = 0; child < node.children.length; child++) {
|
|
270
|
+
const childClass = this.visitChild(node, child);
|
|
271
|
+
if (childClass === null) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
if (childClass === ValueClass.PROPERTY) {
|
|
275
|
+
result = ValueClass.PROPERTY;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return result;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
private visitBoolean(node: AstNode): ValueClass | null {
|
|
282
|
+
if (this.visitChild(node, 0) === null) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
return ValueClass.PROPERTY;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private visitFilter(node: AstNode): ValueClass | null {
|
|
289
|
+
let last: ValueClass | null = null;
|
|
290
|
+
for (const child of node.children) {
|
|
291
|
+
last = this.dispatchVisit(child);
|
|
292
|
+
if (last === null) {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return last;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
private visitSetexprBinary(node: AstNode): ValueClass | null {
|
|
300
|
+
const first = this.visitChild(node, 0);
|
|
301
|
+
if (first === null) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
const second = this.visitChild(node, 1);
|
|
305
|
+
if (second === null) {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
const isValue = combineOperationValues(
|
|
309
|
+
node.typeID as TokenID,
|
|
310
|
+
first === ValueClass.VALUE,
|
|
311
|
+
second === ValueClass.VALUE
|
|
312
|
+
);
|
|
313
|
+
return isValue ? ValueClass.VALUE : ValueClass.PROPERTY;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// ====== Internals ======
|
|
318
|
+
|
|
319
|
+
/** Combines value flags for set operations. */
|
|
320
|
+
function combineOperationValues(op: TokenID, v1: boolean, v2: boolean): boolean {
|
|
321
|
+
switch (op) {
|
|
322
|
+
case TokenID.SET_SYMMETRIC_MINUS:
|
|
323
|
+
case TokenID.SET_UNION:
|
|
324
|
+
return v1 && v2;
|
|
325
|
+
case TokenID.SET_INTERSECTION:
|
|
326
|
+
return v1 || v2;
|
|
327
|
+
case TokenID.SET_MINUS:
|
|
328
|
+
return v1;
|
|
329
|
+
default:
|
|
330
|
+
return v1 && v2;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/* Module: Calculation for RSLang. */
|
|
2
|
+
|
|
3
|
+
/** Represents computability class. */
|
|
4
|
+
export const ValueClass = {
|
|
5
|
+
VALUE: 'value',
|
|
6
|
+
PROPERTY: 'property'
|
|
7
|
+
} as const;
|
|
8
|
+
export type ValueClass = (typeof ValueClass)[keyof typeof ValueClass];
|
|
9
|
+
|
|
10
|
+
/** ValueClass context. */
|
|
11
|
+
export type ValueClassContext = Map<string, ValueClass>;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module: Multi-graph for typifications.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
bool,
|
|
7
|
+
type EchelonCollection,
|
|
8
|
+
type EchelonTuple,
|
|
9
|
+
type ExpressionType,
|
|
10
|
+
tuple,
|
|
11
|
+
TypeID,
|
|
12
|
+
type Typification
|
|
13
|
+
} from './semantic/typification';
|
|
14
|
+
import { labelType } from './labels';
|
|
15
|
+
|
|
16
|
+
/** Represents a single node of a {@link TypificationGraph}. */
|
|
17
|
+
export interface TypificationNodeData extends Record<string, unknown> {
|
|
18
|
+
id: number;
|
|
19
|
+
rank: number;
|
|
20
|
+
text: string;
|
|
21
|
+
parents: number[];
|
|
22
|
+
annotations: string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Represents a typification multi-graph. */
|
|
26
|
+
export class TypificationGraph {
|
|
27
|
+
/** List of nodes. */
|
|
28
|
+
nodes: TypificationNodeData[] = [];
|
|
29
|
+
/** Map of nodes by ID. */
|
|
30
|
+
nodeById = new Map<number, TypificationNodeData>();
|
|
31
|
+
/** Map of nodes by alias. */
|
|
32
|
+
nodeByAlias = new Map<string, TypificationNodeData>();
|
|
33
|
+
|
|
34
|
+
/** Adds an element to the graph. */
|
|
35
|
+
addElement(alias: string, type: ExpressionType): void {
|
|
36
|
+
const node = this.processType(type);
|
|
37
|
+
if (!node) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this.addAliasAnnotation(node.id, alias);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private processType(type: ExpressionType): TypificationNodeData | null {
|
|
44
|
+
switch (type.typeID) {
|
|
45
|
+
case TypeID.logic:
|
|
46
|
+
return null;
|
|
47
|
+
|
|
48
|
+
case TypeID.anyTypification:
|
|
49
|
+
case TypeID.integer:
|
|
50
|
+
case TypeID.basic:
|
|
51
|
+
return this.addBaseNode(type);
|
|
52
|
+
|
|
53
|
+
case TypeID.collection:
|
|
54
|
+
return this.addBooleanNode(type);
|
|
55
|
+
case TypeID.tuple:
|
|
56
|
+
return this.addCartesianNode(type);
|
|
57
|
+
|
|
58
|
+
case TypeID.function:
|
|
59
|
+
case TypeID.predicate:
|
|
60
|
+
const combined = convertFunctionToTypification(type);
|
|
61
|
+
if (!combined) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return this.processType(combined);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private addBaseNode(type: Typification): TypificationNodeData {
|
|
69
|
+
const text = labelType(type);
|
|
70
|
+
const existingNode = this.nodes.find(node => node.text === text);
|
|
71
|
+
if (existingNode) {
|
|
72
|
+
return existingNode;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const node: TypificationNodeData = {
|
|
76
|
+
id: this.nodes.length,
|
|
77
|
+
text: text,
|
|
78
|
+
rank: 0,
|
|
79
|
+
parents: [],
|
|
80
|
+
annotations: []
|
|
81
|
+
};
|
|
82
|
+
this.nodes.push(node);
|
|
83
|
+
this.nodeById.set(node.id, node);
|
|
84
|
+
return node;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private addBooleanNode(type: EchelonCollection): TypificationNodeData | null {
|
|
88
|
+
const baseNode = this.processType(type.base);
|
|
89
|
+
if (!baseNode) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const existingNode = this.nodes.find(node => node.parents.length === 1 && node.parents[0] === baseNode.id);
|
|
94
|
+
if (existingNode) {
|
|
95
|
+
return existingNode;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const node: TypificationNodeData = {
|
|
99
|
+
id: this.nodes.length,
|
|
100
|
+
rank: baseNode.rank + 1,
|
|
101
|
+
text: labelType(type),
|
|
102
|
+
parents: [baseNode.id],
|
|
103
|
+
annotations: []
|
|
104
|
+
};
|
|
105
|
+
this.nodes.push(node);
|
|
106
|
+
this.nodeById.set(node.id, node);
|
|
107
|
+
return node;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private addCartesianNode(type: EchelonTuple): TypificationNodeData | null {
|
|
111
|
+
const factors = type.factors.map(factor => this.processType(factor)).filter(factor => factor !== null);
|
|
112
|
+
if (factors.length !== type.factors.length) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const existingNode = this.nodes.find(
|
|
117
|
+
node => node.parents.length === factors.length && node.parents.every((p, i) => p === factors[i].id)
|
|
118
|
+
);
|
|
119
|
+
if (existingNode) {
|
|
120
|
+
return existingNode;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const node: TypificationNodeData = {
|
|
124
|
+
id: this.nodes.length,
|
|
125
|
+
text: labelType(type),
|
|
126
|
+
rank: Math.max(...factors.map(factor => factor.rank)) + 1,
|
|
127
|
+
parents: factors.map(factor => factor.id),
|
|
128
|
+
annotations: []
|
|
129
|
+
};
|
|
130
|
+
this.nodes.push(node);
|
|
131
|
+
this.nodeById.set(node.id, node);
|
|
132
|
+
return node;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private addAliasAnnotation(node: number, alias: string): void {
|
|
136
|
+
const nodeToAnnotate = this.nodeById.get(node);
|
|
137
|
+
if (!nodeToAnnotate) {
|
|
138
|
+
throw new Error(`Node ${node} not found`);
|
|
139
|
+
}
|
|
140
|
+
nodeToAnnotate.annotations.push(alias);
|
|
141
|
+
this.nodeByAlias.set(alias, nodeToAnnotate);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function convertFunctionToTypification(type: ExpressionType): Typification | null {
|
|
146
|
+
if (!('args' in type) || type.args.length === 0) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
const args = type.args.length === 1 ? type.args[0].type : tuple(type.args.map(arg => arg.type));
|
|
150
|
+
if (type.result.typeID === TypeID.logic) {
|
|
151
|
+
return bool(args);
|
|
152
|
+
} else {
|
|
153
|
+
return bool(tuple([type.result, args]));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** 32-bit FNV-1a hash */
|
|
2
|
+
export function applyHash_fnv1a(str: string): number {
|
|
3
|
+
let hash = 0x811c9dc5;
|
|
4
|
+
|
|
5
|
+
for (let i = 0; i < str.length; i++) {
|
|
6
|
+
hash ^= str.charCodeAt(i);
|
|
7
|
+
hash = Math.imul(hash, 0x01000193);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return hash >>> 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Generates stub ID for text. */
|
|
14
|
+
export function generateStub(text: string): string {
|
|
15
|
+
const hash = applyHash_fnv1a(text);
|
|
16
|
+
return hash.toString(16).padStart(8, '0').slice(0, 8);
|
|
17
|
+
}
|