@rsconcept/domain 1.5.1 → 1.6.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/dist/{analyzer-Bx7SOXWN.d.ts → analyzer-A82AxKdS.d.ts} +2 -2
- package/dist/{ast-annotations-DBZCQOsx.d.ts → ast-annotations-YzvwjoFW.d.ts} +2 -2
- package/dist/{calculator-Dwv_yn2r.d.ts → calculator-Cyy9eYyx.d.ts} +2 -2
- package/dist/{error-CB3HYTri.d.ts → error-Cv4sntcy.d.ts} +8 -3
- package/dist/index.d.ts +4 -4
- package/dist/library/rsengine.d.ts +1 -1
- package/dist/library/rsform-api.d.ts +1 -1
- package/dist/library/rsform-api.js +2 -1
- package/dist/library/rsform-api.js.map +1 -1
- package/dist/library/rsform.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 +7 -2
- 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/index.d.ts +4 -4
- package/dist/rslang/parser/syntax-errors.d.ts +1 -1
- package/dist/rslang/semantic/analyzer.d.ts +1 -1
- package/dist/rslang/semantic/analyzer.js +5 -2
- package/dist/rslang/semantic/analyzer.js.map +1 -1
- package/dist/rslang/semantic/type-auditor.d.ts +1 -1
- package/dist/rslang/semantic/type-auditor.js +56 -7
- package/dist/rslang/semantic/type-auditor.js.map +1 -1
- package/dist/rslang/semantic/value-auditor.d.ts +1 -1
- package/package.json +1 -1
- package/src/library/rsform-api.test.ts +30 -2
- package/src/library/rsform-api.ts +2 -1
- package/src/rslang/error.ts +7 -2
- package/src/rslang/parser/parser.test.ts +2 -1
- package/src/rslang/semantic/analyzer.test.ts +56 -6
- package/src/rslang/semantic/analyzer.ts +5 -2
- package/src/rslang/semantic/type-auditor.test.ts +21 -9
- package/src/rslang/semantic/type-auditor.ts +72 -15
|
@@ -673,18 +673,21 @@ export class TypeAuditor {
|
|
|
673
673
|
}
|
|
674
674
|
|
|
675
675
|
private visitProjectSet(node: AstNode): ExpressionType | null {
|
|
676
|
-
const
|
|
677
|
-
|
|
676
|
+
const operator = labelRSLangNode(node);
|
|
677
|
+
const argNode = node.children[0];
|
|
678
|
+
const argType = this.childTypification(node, 0);
|
|
679
|
+
if (argType === null) {
|
|
678
680
|
return null;
|
|
679
681
|
}
|
|
680
|
-
if (
|
|
682
|
+
if (argType.typeID === TypeID.anyTypification) {
|
|
681
683
|
return EmptySetT;
|
|
682
684
|
}
|
|
685
|
+
if (argType.typeID !== TypeID.collection) {
|
|
686
|
+
return this.onError(RSErrorCode.projectionSetArgumentNotSet, argNode, [operator, labelType(argType)]);
|
|
687
|
+
}
|
|
688
|
+
const argument = debool(argType);
|
|
683
689
|
if (argument.typeID !== TypeID.tuple) {
|
|
684
|
-
return this.onError(RSErrorCode.
|
|
685
|
-
labelRSLangNode(node),
|
|
686
|
-
labelType(bool(argument))
|
|
687
|
-
]);
|
|
690
|
+
return this.onError(RSErrorCode.projectionSetArgumentNotTupleSet, argNode, [operator, labelType(bool(argument))]);
|
|
688
691
|
}
|
|
689
692
|
|
|
690
693
|
const indices = getNodeIndices(node);
|
|
@@ -692,8 +695,10 @@ export class TypeAuditor {
|
|
|
692
695
|
for (const index of indices) {
|
|
693
696
|
const newComponent = component(argument, index);
|
|
694
697
|
if (newComponent === null) {
|
|
695
|
-
return this.onError(RSErrorCode.
|
|
696
|
-
|
|
698
|
+
return this.onError(RSErrorCode.projectionSetIndexOutOfRange, argNode, [
|
|
699
|
+
operator,
|
|
700
|
+
String(index),
|
|
701
|
+
String(argument.factors.length),
|
|
697
702
|
labelType(bool(argument))
|
|
698
703
|
]);
|
|
699
704
|
} else {
|
|
@@ -708,6 +713,8 @@ export class TypeAuditor {
|
|
|
708
713
|
}
|
|
709
714
|
|
|
710
715
|
private visitProjectTuple(node: AstNode): ExpressionType | null {
|
|
716
|
+
const operator = labelRSLangNode(node);
|
|
717
|
+
const argNode = node.children[0];
|
|
711
718
|
const argument = this.childTypification(node, 0);
|
|
712
719
|
if (argument === null) {
|
|
713
720
|
return null;
|
|
@@ -716,10 +723,7 @@ export class TypeAuditor {
|
|
|
716
723
|
return argument;
|
|
717
724
|
}
|
|
718
725
|
if (argument.typeID !== TypeID.tuple) {
|
|
719
|
-
return this.onError(RSErrorCode.
|
|
720
|
-
labelRSLangNode(node),
|
|
721
|
-
labelType(argument)
|
|
722
|
-
]);
|
|
726
|
+
return this.onError(RSErrorCode.projectionTupleArgumentNotTuple, argNode, [operator, labelType(argument)]);
|
|
723
727
|
}
|
|
724
728
|
|
|
725
729
|
const indices = getNodeIndices(node);
|
|
@@ -727,8 +731,10 @@ export class TypeAuditor {
|
|
|
727
731
|
for (const index of indices) {
|
|
728
732
|
const newComponent = component(argument, index);
|
|
729
733
|
if (newComponent === null) {
|
|
730
|
-
return this.onError(RSErrorCode.
|
|
731
|
-
|
|
734
|
+
return this.onError(RSErrorCode.projectionTupleIndexOutOfRange, argNode, [
|
|
735
|
+
operator,
|
|
736
|
+
String(index),
|
|
737
|
+
String(argument.factors.length),
|
|
732
738
|
labelType(argument)
|
|
733
739
|
]);
|
|
734
740
|
} else {
|
|
@@ -1067,6 +1073,50 @@ interface LocalData {
|
|
|
1067
1073
|
type: Typification;
|
|
1068
1074
|
}
|
|
1069
1075
|
|
|
1076
|
+
function isLogicBinaryNode(typeID: number): boolean {
|
|
1077
|
+
return (
|
|
1078
|
+
typeID === TokenID.LOGIC_AND ||
|
|
1079
|
+
typeID === TokenID.LOGIC_OR ||
|
|
1080
|
+
typeID === TokenID.LOGIC_IMPLICATION ||
|
|
1081
|
+
typeID === TokenID.LOGIC_EQUIVALENT
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
function isQuantifierNode(typeID: number): boolean {
|
|
1086
|
+
return typeID === TokenID.QUANTOR_UNIVERSAL || typeID === TokenID.QUANTOR_EXISTS;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
/** Quantifier on the path from `node` up through `stopAt` (inclusive). */
|
|
1090
|
+
function pathContainsQuantifier(node: AstNode, stopAt: AstNode): boolean {
|
|
1091
|
+
let current: AstNode | null = node;
|
|
1092
|
+
while (current !== null) {
|
|
1093
|
+
if (isQuantifierNode(current.typeID)) {
|
|
1094
|
+
return true;
|
|
1095
|
+
}
|
|
1096
|
+
if (current === stopAt) {
|
|
1097
|
+
return false;
|
|
1098
|
+
}
|
|
1099
|
+
current = current.parent;
|
|
1100
|
+
}
|
|
1101
|
+
return false;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
/** Right operand subtree of the innermost logic binary containing `node`. */
|
|
1105
|
+
function findRightLogicOperandRoot(node: AstNode): AstNode | null {
|
|
1106
|
+
let current: AstNode | null = node;
|
|
1107
|
+
while (current !== null && current.parent !== null) {
|
|
1108
|
+
const parent: AstNode = current.parent;
|
|
1109
|
+
if (isLogicBinaryNode(parent.typeID)) {
|
|
1110
|
+
const childIndex = parent.children.indexOf(current);
|
|
1111
|
+
if (childIndex > 0) {
|
|
1112
|
+
return current;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
current = parent;
|
|
1116
|
+
}
|
|
1117
|
+
return null;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1070
1120
|
/** Local variables context. */
|
|
1071
1121
|
class LocalContext {
|
|
1072
1122
|
private onError: (code: RSErrorCode, node: AstNode, params: string[]) => null;
|
|
@@ -1124,6 +1174,13 @@ class LocalContext {
|
|
|
1124
1174
|
this.onError(RSErrorCode.localUndeclared, node, [alias]);
|
|
1125
1175
|
return null;
|
|
1126
1176
|
} else if (local.level < 1) {
|
|
1177
|
+
const subexprRoot = findRightLogicOperandRoot(node);
|
|
1178
|
+
if (subexprRoot !== null) {
|
|
1179
|
+
if (pathContainsQuantifier(node, subexprRoot)) {
|
|
1180
|
+
return this.onError(RSErrorCode.localUndeclaredInSubexpr, node, [alias, labelType(local.type)]);
|
|
1181
|
+
}
|
|
1182
|
+
return this.onError(RSErrorCode.localOutOfScopeParentheses, node, [alias]);
|
|
1183
|
+
}
|
|
1127
1184
|
this.onError(RSErrorCode.localOutOfScope, node, [alias]);
|
|
1128
1185
|
return null;
|
|
1129
1186
|
} else {
|