@rsconcept/domain 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/{analyzer-54lGGg13.d.ts → analyzer-0kmNRqcr.d.ts} +2 -2
  2. package/dist/{ast-annotations-C0eMySxt.d.ts → ast-annotations-BnVekMjH.d.ts} +2 -2
  3. package/dist/{calculator-BQnE2gws.d.ts → calculator-OV-RNXre.d.ts} +2 -2
  4. package/dist/{error-CxIs0A7Y.d.ts → error-DYLkv4B3.d.ts} +6 -1
  5. package/dist/index.d.ts +4 -4
  6. package/dist/library/rsengine.d.ts +1 -1
  7. package/dist/library/rsform-api.d.ts +1 -1
  8. package/dist/library/rsform.d.ts +1 -1
  9. package/dist/rslang/ast-annotations.d.ts +1 -1
  10. package/dist/rslang/error.d.ts +1 -1
  11. package/dist/rslang/error.js +5 -0
  12. package/dist/rslang/error.js.map +1 -1
  13. package/dist/rslang/eval/calculator.d.ts +1 -1
  14. package/dist/rslang/eval/evaluator.d.ts +1 -1
  15. package/dist/rslang/index.d.ts +4 -4
  16. package/dist/rslang/parser/syntax-errors.d.ts +9 -3
  17. package/dist/rslang/parser/syntax-errors.js +58 -33
  18. package/dist/rslang/parser/syntax-errors.js.map +1 -1
  19. package/dist/rslang/semantic/analyzer.d.ts +1 -1
  20. package/dist/rslang/semantic/analyzer.js +1 -1
  21. package/dist/rslang/semantic/analyzer.js.map +1 -1
  22. package/dist/rslang/semantic/type-auditor.d.ts +1 -1
  23. package/dist/rslang/semantic/type-auditor.js +30 -6
  24. package/dist/rslang/semantic/type-auditor.js.map +1 -1
  25. package/dist/rslang/semantic/value-auditor.d.ts +1 -1
  26. package/package.json +1 -1
  27. package/src/rslang/error.ts +5 -0
  28. package/src/rslang/parser/parser.test.ts +21 -1
  29. package/src/rslang/parser/syntax-errors.ts +113 -48
  30. package/src/rslang/semantic/analyzer.ts +3 -1
  31. package/src/rslang/semantic/type-auditor.test.ts +36 -10
  32. package/src/rslang/semantic/type-auditor.ts +50 -3
@@ -157,12 +157,12 @@ const errorData = [
157
157
  ['R1', { code: RSErrorCode.radicalUsage, from: 0, to: 2, params: ['R1'] }],
158
158
  ['[a∈ℬ(R1)] R1\\a', { code: RSErrorCode.radicalUsage, from: 10, to: 12, params: ['R1'] }],
159
159
  // Functions
160
- ['F1[X1]', { code: RSErrorCode.invalidArgsArity, from: 3, to: 5, params: ['2', '1'] }],
161
- ['F1[X1, X1, X1]', { code: RSErrorCode.invalidArgsArity, from: 3, to: 5, params: ['2', '3'] }],
160
+ ['F1[X1]', { code: RSErrorCode.invalidArgsArity, from: 0, to: 6, params: ['2', '1'] }],
161
+ ['F1[X1, X1, X1]', { code: RSErrorCode.invalidArgsArity, from: 0, to: 14, params: ['2', '3'] }],
162
162
  ['F1[X1, S1]', { code: RSErrorCode.invalidArgumentType, from: 7, to: 9, params: ['b∈ℬ(X1)', 'ℬ(X1×X1)'] }],
163
163
  ['F1[S1, X1]', { code: RSErrorCode.invalidArgumentType, from: 3, to: 5, params: ['a∈ℬ(X1)', 'ℬ(X1×X1)'] }],
164
- ['P1[X1]', { code: RSErrorCode.invalidArgsArity, from: 3, to: 5, params: ['2', '1'] }],
165
- ['P1[X1, X1, X1]', { code: RSErrorCode.invalidArgsArity, from: 3, to: 5, params: ['2', '3'] }],
164
+ ['P1[X1]', { code: RSErrorCode.invalidArgsArity, from: 0, to: 6, params: ['2', '1'] }],
165
+ ['P1[X1, X1, X1]', { code: RSErrorCode.invalidArgsArity, from: 0, to: 14, params: ['2', '3'] }],
166
166
  ['P1[X1, S1]', { code: RSErrorCode.invalidArgumentType, from: 7, to: 9, params: ['b∈ℬ(X1)', 'ℬ(X1×X1)'] }],
167
167
  ['P1[S1, X1]', { code: RSErrorCode.invalidArgumentType, from: 3, to: 5, params: ['a∈ℬ(X1)', 'ℬ(X1×X1)'] }],
168
168
  // Integral
@@ -182,8 +182,10 @@ const errorData = [
182
182
  ['∀(a,a)∈S1 a=a', { code: RSErrorCode.localShadowing, from: 4, to: 5, params: ['a'] }],
183
183
  ['∀(a,b)∈X1 a=b', { code: RSErrorCode.invalidCortegeDeclare, from: 2, to: 3 }],
184
184
  ['∀a∈X1 D{a∈S1| 1=1}=S1', { code: RSErrorCode.localShadowing, from: 8, to: 9, params: ['a'] }],
185
- ['∀a∈X1 a=a & a=a', { code: RSErrorCode.localOutOfScope, from: 12, to: 13, params: ['a'] }],
186
- ['∀a∈X1 a=a & debool(X1)=a', { code: RSErrorCode.localOutOfScope, from: 23, to: 24, params: ['a'] }],
185
+ ['∀a∈X1 a=a & a=a', { code: RSErrorCode.localOutOfScopeParentheses, from: 12, to: 13, params: ['a'] }],
186
+ ['∀a∈X1 a=a & debool(X1)=a', { code: RSErrorCode.localOutOfScopeParentheses, from: 23, to: 24, params: ['a'] }],
187
+ ['∀ξ∈X1 ξ=ξ & ∀φ∈X1 φ=ξ', { code: RSErrorCode.localUndeclaredInSubexpr, from: 20, to: 21, params: ['ξ', 'X1'] }],
188
+ ['D{t∈X1 | t=t} ∪ {t}', { code: RSErrorCode.localOutOfScope, from: 17, to: 18, params: ['t'] }],
187
189
  // Set predicates
188
190
  ['X1∈X1', { code: RSErrorCode.invalidElementPredicate, from: 0, to: 5, params: ['ℬ(X1)', '∈', 'ℬ(X1)'] }],
189
191
  ['(1,2)∈X1', { code: RSErrorCode.invalidElementPredicate, from: 0, to: 8, params: ['Z×Z', '∈', 'ℬ(X1)'] }],
@@ -223,10 +225,7 @@ const errorData = [
223
225
  { code: RSErrorCode.invalidFilterArgumentType, from: 8, to: 13, params: ['Fi1', 'ℬℬ(X1)', 'ℬ(R0)'] }
224
226
  ],
225
227
  ['Fi1[1](S1)', { code: RSErrorCode.invalidFilterParameterType, from: 4, to: 5, params: ['Z', 'ℬ(X1)', 'Fi1'] }],
226
- [
227
- 'Fi1[X1](ℬ(X1)×X1)',
228
- { code: RSErrorCode.invalidFilterBooleanEchelon, from: 4, to: 6, params: ['Fi1', 'ℬ(X1)', 'ℬℬ(X1)'] }
229
- ],
228
+ ['Fi1[X1](ℬ(X1)×X1)', { code: RSErrorCode.invalidFilterBooleanEchelon, from: 4, to: 6, params: ['Fi1', 'ℬ(X1)'] }],
230
229
  ['Fi3[X1](S1)', { code: RSErrorCode.invalidFilterIndex, from: 8, to: 10, params: ['Fi3', 'ℬ(X1×X1)', '3', '2'] }],
231
230
  ['Fi1[X1,X1](S1)', { code: RSErrorCode.invalidFilterArity, from: 7, to: 9, params: ['1', '2', 'Fi1'] }],
232
231
  [
@@ -328,6 +327,33 @@ describe('TypeAuditor', () => {
328
327
  expectType('F4[Z]', 'ℬ(X1)');
329
328
  });
330
329
 
330
+ it('Highlights the function call site for invalidArgsArity', () => {
331
+ typeContext.set('F7', {
332
+ typeID: TypeID.function,
333
+ result: bool(basic('X1')),
334
+ args: [
335
+ { alias: 'a', type: bool(basic('X1')) },
336
+ { alias: 'b', type: bool(basic('X1')) },
337
+ { alias: 'c', type: bool(basic('X1')) }
338
+ ]
339
+ });
340
+ typeContext.set('F8', {
341
+ typeID: TypeID.function,
342
+ result: bool(basic('X1')),
343
+ args: [
344
+ { alias: 'a', type: bool(basic('X1')) },
345
+ { alias: 'b', type: bool(basic('X1')) },
346
+ { alias: 'c', type: bool(basic('X1')) }
347
+ ]
348
+ });
349
+ expectError('F8[X1,F7[X1,X1],X1]', {
350
+ code: RSErrorCode.invalidArgsArity,
351
+ from: 6,
352
+ to: 15,
353
+ params: ['3', '2']
354
+ });
355
+ });
356
+
331
357
  it('Templated nesting', () => {
332
358
  typeContext.set('F2', {
333
359
  typeID: TypeID.function,
@@ -837,8 +837,7 @@ export class TypeAuditor {
837
837
  if (checkEquality(wrapped, expected) || checkCompatibility(wrapped, expected)) {
838
838
  return this.onError(RSErrorCode.invalidFilterBooleanEchelon, node.children[childIndex], [
839
839
  operator,
840
- labelType(param),
841
- labelType(expected)
840
+ labelType(param)
842
841
  ]);
843
842
  }
844
843
  return this.onError(RSErrorCode.invalidFilterParameterType, node.children[childIndex], [
@@ -999,7 +998,7 @@ export class TypeAuditor {
999
998
 
1000
999
  private checkFuncArguments(node: AstNode, alias: string, type: Parametrized): Map<string, Typification> | null {
1001
1000
  if (node.children.length - 1 !== type.args.length) {
1002
- return this.onError(RSErrorCode.invalidArgsArity, node.children[1], [
1001
+ return this.onError(RSErrorCode.invalidArgsArity, node, [
1003
1002
  String(type.args.length),
1004
1003
  String(node.children.length - 1)
1005
1004
  ]);
@@ -1068,6 +1067,47 @@ interface LocalData {
1068
1067
  type: Typification;
1069
1068
  }
1070
1069
 
1070
+ function isLogicBinaryNode(typeID: number): boolean {
1071
+ return (
1072
+ typeID === TokenID.LOGIC_AND ||
1073
+ typeID === TokenID.LOGIC_OR ||
1074
+ typeID === TokenID.LOGIC_IMPLICATION ||
1075
+ typeID === TokenID.LOGIC_EQUIVALENT
1076
+ );
1077
+ }
1078
+
1079
+ function isQuantifierNode(typeID: number): boolean {
1080
+ return typeID === TokenID.QUANTOR_UNIVERSAL || typeID === TokenID.QUANTOR_EXISTS;
1081
+ }
1082
+
1083
+ function subtreeContainsQuantifier(node: AstNode): boolean {
1084
+ if (isQuantifierNode(node.typeID)) {
1085
+ return true;
1086
+ }
1087
+ for (const child of node.children) {
1088
+ if (subtreeContainsQuantifier(child)) {
1089
+ return true;
1090
+ }
1091
+ }
1092
+ return false;
1093
+ }
1094
+
1095
+ /** Right operand subtree of the innermost logic binary containing `node`. */
1096
+ function findRightLogicOperandRoot(node: AstNode): AstNode | null {
1097
+ let current: AstNode | null = node;
1098
+ while (current !== null && current.parent !== null) {
1099
+ const parent: AstNode = current.parent;
1100
+ if (isLogicBinaryNode(parent.typeID)) {
1101
+ const childIndex = parent.children.indexOf(current);
1102
+ if (childIndex > 0) {
1103
+ return current;
1104
+ }
1105
+ }
1106
+ current = parent;
1107
+ }
1108
+ return null;
1109
+ }
1110
+
1071
1111
  /** Local variables context. */
1072
1112
  class LocalContext {
1073
1113
  private onError: (code: RSErrorCode, node: AstNode, params: string[]) => null;
@@ -1125,6 +1165,13 @@ class LocalContext {
1125
1165
  this.onError(RSErrorCode.localUndeclared, node, [alias]);
1126
1166
  return null;
1127
1167
  } else if (local.level < 1) {
1168
+ const subexprRoot = findRightLogicOperandRoot(node);
1169
+ if (subexprRoot !== null) {
1170
+ if (subtreeContainsQuantifier(subexprRoot)) {
1171
+ return this.onError(RSErrorCode.localUndeclaredInSubexpr, node, [alias, labelType(local.type)]);
1172
+ }
1173
+ return this.onError(RSErrorCode.localOutOfScopeParentheses, node, [alias]);
1174
+ }
1128
1175
  this.onError(RSErrorCode.localOutOfScope, node, [alias]);
1129
1176
  return null;
1130
1177
  } else {