@rsconcept/domain 1.7.4 → 1.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{analyzer-QxWs73gP.d.ts → analyzer-DqjdciC5.d.ts} +3 -3
- package/dist/{arguments-extractor-1acwjQNc.d.ts → arguments-extractor-Dd1lFom9.d.ts} +2 -2
- package/dist/{ast-annotations-CtF7C9uK.d.ts → ast-annotations-CZCzs9Uk.d.ts} +3 -3
- package/dist/{calculator-REeX2ZS1.d.ts → calculator-Dt03dsnd.d.ts} +3 -3
- package/dist/{error-toW0TUHF.d.ts → error-CzIbnP-N.d.ts} +3 -3
- package/dist/index.d.ts +9 -9
- package/dist/library/rsengine.d.ts +1 -1
- package/dist/library/rsform-api.d.ts +2 -2
- package/dist/library/rsform.d.ts +2 -2
- package/dist/library/rsmodel-api.d.ts +1 -1
- package/dist/library/structure-planner.d.ts +1 -1
- package/dist/rslang/api.d.ts +1 -1
- package/dist/rslang/ast-annotations.d.ts +1 -1
- package/dist/rslang/error.d.ts +1 -1
- package/dist/rslang/error.js +4 -3
- package/dist/rslang/error.js.map +1 -1
- package/dist/rslang/eval/calculator.d.ts +1 -1
- package/dist/rslang/eval/evaluator.d.ts +1 -1
- package/dist/rslang/eval/value-api.d.ts +1 -1
- package/dist/rslang/index.d.ts +9 -9
- package/dist/rslang/labels.d.ts +1 -1
- package/dist/rslang/parser/syntax-errors/index.d.ts +2 -2
- package/dist/rslang/semantic/analyzer.d.ts +1 -1
- package/dist/rslang/semantic/arguments-extractor.d.ts +1 -1
- package/dist/rslang/semantic/type-auditor.d.ts +2 -2
- package/dist/rslang/semantic/type-auditor.js +11 -13
- package/dist/rslang/semantic/type-auditor.js.map +1 -1
- package/dist/rslang/semantic/typification-api.d.ts +4 -2
- package/dist/rslang/semantic/typification-api.js +17 -1
- package/dist/rslang/semantic/typification-api.js.map +1 -1
- package/dist/rslang/semantic/typification-parser.d.ts +1 -1
- package/dist/rslang/semantic/typification.d.ts +2 -2
- package/dist/rslang/semantic/typification.js +11 -3
- package/dist/rslang/semantic/typification.js.map +1 -1
- package/dist/rslang/semantic/value-auditor.d.ts +1 -1
- package/dist/rslang/typification-graph.d.ts +1 -1
- package/dist/{typification-Dk-fisgO.d.ts → typification-DDuv88ir.d.ts} +7 -3
- package/dist/{typification-graph-6HcZ-rKH.d.ts → typification-graph-8VdK6_Fh.d.ts} +2 -2
- package/dist/{typification-parser-BBVx1RxP.d.ts → typification-parser-DHO42ZRc.d.ts} +2 -2
- package/dist/{value-api-B6T6f4Ia.d.ts → value-api-C2X4Pom5.d.ts} +2 -2
- package/package.json +4 -4
- package/src/rslang/error.ts +6 -3
- package/src/rslang/semantic/analyzer.test.ts +8 -0
- package/src/rslang/semantic/type-auditor.test.ts +19 -1
- package/src/rslang/semantic/type-auditor.ts +13 -12
- package/src/rslang/semantic/typification-api.test.ts +19 -2
- package/src/rslang/semantic/typification-api.ts +15 -0
- package/src/rslang/semantic/typification.ts +12 -2
|
@@ -313,7 +313,25 @@ describe('TypeAuditor', () => {
|
|
|
313
313
|
code: RSErrorCode.invalidArgumentType,
|
|
314
314
|
from: 7,
|
|
315
315
|
to: 12,
|
|
316
|
-
params: ['b∈
|
|
316
|
+
params: ['b∈X1', 'ℬℬ(X1)']
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it('Resolves templated radicals in invalidArgumentType message', () => {
|
|
321
|
+
typeContext.set('S5', bool(bool(basic('X1'))));
|
|
322
|
+
typeContext.set('P2', {
|
|
323
|
+
typeID: TypeID.predicate,
|
|
324
|
+
result: LogicT,
|
|
325
|
+
args: [
|
|
326
|
+
{ alias: 'σ', type: bool(bool(basic('R1'))) },
|
|
327
|
+
{ alias: 'ζ', type: bool(bool(basic('R1'))) }
|
|
328
|
+
]
|
|
329
|
+
});
|
|
330
|
+
expectError('P2[S5, 12]', {
|
|
331
|
+
code: RSErrorCode.invalidArgumentType,
|
|
332
|
+
from: 7,
|
|
333
|
+
to: 9,
|
|
334
|
+
params: ['ζ∈ℬℬ(X1)', 'Z']
|
|
317
335
|
});
|
|
318
336
|
});
|
|
319
337
|
|
|
@@ -17,9 +17,10 @@ import {
|
|
|
17
17
|
EmptySetT,
|
|
18
18
|
type ExpressionType,
|
|
19
19
|
IntegerT,
|
|
20
|
-
|
|
20
|
+
isTemplateRadical,
|
|
21
21
|
isTypification,
|
|
22
22
|
LogicT,
|
|
23
|
+
mangleRadicalId,
|
|
23
24
|
type Parametrized,
|
|
24
25
|
tuple,
|
|
25
26
|
type TypeContext,
|
|
@@ -29,6 +30,7 @@ import {
|
|
|
29
30
|
import {
|
|
30
31
|
checkCompatibility,
|
|
31
32
|
checkEquality,
|
|
33
|
+
cloneTypification,
|
|
32
34
|
compareTemplated,
|
|
33
35
|
hasGenerics,
|
|
34
36
|
mergeTypifications,
|
|
@@ -1018,8 +1020,12 @@ export class TypeAuditor {
|
|
|
1018
1020
|
}
|
|
1019
1021
|
const argType = mangleRadicals(alias, type.args[child - 1].type);
|
|
1020
1022
|
if (!compareTemplated(substitutes, argType, childType)) {
|
|
1023
|
+
const expectedType = cloneTypification(argType);
|
|
1024
|
+
if (substitutes.size > 0) {
|
|
1025
|
+
substituteBase(expectedType, substitutes);
|
|
1026
|
+
}
|
|
1021
1027
|
this.onError(RSErrorCode.invalidArgumentType, node.children[child], [
|
|
1022
|
-
`${type.args[child - 1].alias}∈${labelType(
|
|
1028
|
+
`${type.args[child - 1].alias}∈${labelType(expectedType)}`,
|
|
1023
1029
|
labelType(childType)
|
|
1024
1030
|
]);
|
|
1025
1031
|
return null;
|
|
@@ -1038,10 +1044,10 @@ function mangleRadicals(funcName: string, type: Typification): Typification {
|
|
|
1038
1044
|
case TypeID.integer:
|
|
1039
1045
|
return type;
|
|
1040
1046
|
case TypeID.basic: {
|
|
1041
|
-
if (
|
|
1047
|
+
if (isTemplateRadical(type.baseID)) {
|
|
1042
1048
|
return {
|
|
1043
1049
|
typeID: type.typeID,
|
|
1044
|
-
baseID: type.baseID
|
|
1050
|
+
baseID: mangleRadicalId(type.baseID, funcName)
|
|
1045
1051
|
};
|
|
1046
1052
|
}
|
|
1047
1053
|
return type;
|
|
@@ -1157,10 +1163,7 @@ class LocalContext {
|
|
|
1157
1163
|
return false;
|
|
1158
1164
|
} else {
|
|
1159
1165
|
this.onError(RSErrorCode.localDoubleDeclare, node, [alias]);
|
|
1160
|
-
|
|
1161
|
-
if (index !== -1) {
|
|
1162
|
-
this.data.splice(index, 1);
|
|
1163
|
-
}
|
|
1166
|
+
return false;
|
|
1164
1167
|
}
|
|
1165
1168
|
}
|
|
1166
1169
|
this.data.push({ alias, type, level: 1, useCount: 0 });
|
|
@@ -1171,8 +1174,7 @@ class LocalContext {
|
|
|
1171
1174
|
const alias = getNodeText(node);
|
|
1172
1175
|
const local = this.data.find(data => data.alias === alias);
|
|
1173
1176
|
if (local === undefined) {
|
|
1174
|
-
this.onError(RSErrorCode.localUndeclared, node, [alias]);
|
|
1175
|
-
return null;
|
|
1177
|
+
return this.onError(RSErrorCode.localUndeclared, node, [alias]);
|
|
1176
1178
|
} else if (local.level < 1) {
|
|
1177
1179
|
const subexprRoot = findRightLogicOperandRoot(node);
|
|
1178
1180
|
if (subexprRoot !== null) {
|
|
@@ -1181,8 +1183,7 @@ class LocalContext {
|
|
|
1181
1183
|
}
|
|
1182
1184
|
return this.onError(RSErrorCode.localOutOfScopeParentheses, node, [alias]);
|
|
1183
1185
|
}
|
|
1184
|
-
this.onError(RSErrorCode.localOutOfScope, node, [alias]);
|
|
1185
|
-
return null;
|
|
1186
|
+
return this.onError(RSErrorCode.localOutOfScope, node, [alias]);
|
|
1186
1187
|
} else {
|
|
1187
1188
|
local.useCount++;
|
|
1188
1189
|
return local.type;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
|
|
3
3
|
import type { TypePath } from './typification';
|
|
4
|
-
import { AnyTypificationT, basic, bool, IntegerT, tuple, type Typification } from './typification';
|
|
5
|
-
import { applyPath, compareTemplated } from './typification-api';
|
|
4
|
+
import { AnyTypificationT, basic, bool, IntegerT, mangleRadicalId, tuple, type Typification } from './typification';
|
|
5
|
+
import { applyPath, cloneTypification, compareTemplated, substituteBase } from './typification-api';
|
|
6
6
|
|
|
7
7
|
describe('applyPath', () => {
|
|
8
8
|
function typePath(path: number[]): TypePath {
|
|
@@ -53,3 +53,20 @@ describe('compareTemplated', () => {
|
|
|
53
53
|
expect(compareTemplated(substitutes, AnyTypificationT, AnyTypificationT)).toBe(true);
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
|
+
|
|
57
|
+
describe('mangleRadicalId', () => {
|
|
58
|
+
it('qualifies template radical with function name', () => {
|
|
59
|
+
expect(mangleRadicalId('R1', 'P2')).toBe('R1<P2>');
|
|
60
|
+
expect(mangleRadicalId('R2', 'F10')).toBe('R2<F10>');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('cloneTypification + substituteBase', () => {
|
|
65
|
+
it('resolves mangled radicals for error messages', () => {
|
|
66
|
+
const argType = bool(basic('R1<F2>'));
|
|
67
|
+
const substitutes = new Map<string, Typification>([['R1<F2>', basic('X1')]]);
|
|
68
|
+
const expectedType = cloneTypification(argType);
|
|
69
|
+
substituteBase(expectedType, substitutes);
|
|
70
|
+
expect(expectedType).toEqual(bool(basic('X1')));
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -227,6 +227,21 @@ export function compareTemplated(
|
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
/** Clone typification tree. */
|
|
231
|
+
export function cloneTypification(type: Typification): Typification {
|
|
232
|
+
switch (type.typeID) {
|
|
233
|
+
case TypeID.anyTypification:
|
|
234
|
+
case TypeID.integer:
|
|
235
|
+
return type;
|
|
236
|
+
case TypeID.basic:
|
|
237
|
+
return { ...type };
|
|
238
|
+
case TypeID.collection:
|
|
239
|
+
return { typeID: type.typeID, base: cloneTypification(type.base) };
|
|
240
|
+
case TypeID.tuple:
|
|
241
|
+
return { typeID: type.typeID, factors: type.factors.map(cloneTypification) };
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
230
245
|
/** Apply substitutions to typification. */
|
|
231
246
|
export function substituteBase(target: Typification, substitutes: Map<string, Typification>): void {
|
|
232
247
|
switch (target.typeID) {
|
|
@@ -174,7 +174,17 @@ export function isTypification(type: ExpressionType | null): boolean {
|
|
|
174
174
|
);
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
/** Checks if given
|
|
177
|
+
/** Checks if given alias is a template or mangled radical. */
|
|
178
178
|
export function isRadical(alias: string): boolean {
|
|
179
|
-
return
|
|
179
|
+
return /^R[1-9]\d*(?:<[^>]+>)?$/.test(alias);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** Checks if given alias is an unmangled template radical. */
|
|
183
|
+
export function isTemplateRadical(alias: string): boolean {
|
|
184
|
+
return /^R[1-9]\d*$/.test(alias);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Mangle template radical with calling function name. */
|
|
188
|
+
export function mangleRadicalId(radical: string, funcName: string): string {
|
|
189
|
+
return `${radical}<${funcName}>`;
|
|
180
190
|
}
|