@rsconcept/domain 1.4.1 → 1.4.3

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 (41) hide show
  1. package/dist/{analyzer-BliNe3pV.d.ts → analyzer-CvnbnrSX.d.ts} +2 -2
  2. package/dist/{ast-annotations-GOkbNN8F.d.ts → ast-annotations-B4T8S2DS.d.ts} +2 -2
  3. package/dist/{calculator-DFevxZyV.d.ts → calculator-8tErfQcI.d.ts} +2 -2
  4. package/dist/{error-deey7EiC.d.ts → error-DuqsZDL5.d.ts} +2 -1
  5. package/dist/index.d.ts +4 -4
  6. package/dist/index.js +2 -2
  7. package/dist/library/rsengine.d.ts +1 -1
  8. package/dist/library/rsengine.js +2 -2
  9. package/dist/library/rsform-api.d.ts +1 -1
  10. package/dist/library/rsform.d.ts +1 -1
  11. package/dist/library/rsmodel-api.js +1 -1
  12. package/dist/rslang/ast-annotations.d.ts +1 -1
  13. package/dist/rslang/error.d.ts +1 -1
  14. package/dist/rslang/error.js +1 -0
  15. package/dist/rslang/error.js.map +1 -1
  16. package/dist/rslang/eval/calculator.d.ts +1 -1
  17. package/dist/rslang/eval/calculator.js +1 -1
  18. package/dist/rslang/eval/evaluator.d.ts +1 -1
  19. package/dist/rslang/eval/evaluator.js +7 -2
  20. package/dist/rslang/eval/evaluator.js.map +1 -1
  21. package/dist/rslang/eval/value-api.js +1 -1
  22. package/dist/rslang/eval/value.js +1 -1
  23. package/dist/rslang/index.d.ts +4 -4
  24. package/dist/rslang/index.js +1 -1
  25. package/dist/rslang/labels.js +1 -0
  26. package/dist/rslang/labels.js.map +1 -1
  27. package/dist/rslang/parser/syntax-errors.d.ts +1 -1
  28. package/dist/rslang/semantic/analyzer.d.ts +1 -1
  29. package/dist/rslang/semantic/type-auditor.d.ts +2 -1
  30. package/dist/rslang/semantic/type-auditor.js +76 -22
  31. package/dist/rslang/semantic/type-auditor.js.map +1 -1
  32. package/dist/rslang/semantic/value-auditor.d.ts +1 -1
  33. package/dist/{value-ybFBRuz6.js → value-COprb2Je.js} +2 -2
  34. package/dist/{value-ybFBRuz6.js.map → value-COprb2Je.js.map} +1 -1
  35. package/package.json +1 -1
  36. package/src/rslang/error.ts +1 -0
  37. package/src/rslang/eval/evaluator.test.ts +2 -2
  38. package/src/rslang/eval/evaluator.ts +2 -1
  39. package/src/rslang/labels.ts +1 -0
  40. package/src/rslang/semantic/type-auditor.test.ts +20 -18
  41. package/src/rslang/semantic/type-auditor.ts +68 -22
@@ -5,6 +5,7 @@
5
5
  import { type AstNode, getNodeIndices, getNodeText } from '../../parsing';
6
6
  import { annotateError } from '../ast-annotations';
7
7
  import { type ErrorReporter, RSErrorCode } from '../error';
8
+ import { labelRSLangNode } from '../labels';
8
9
  import { TokenID } from '../parser/token';
9
10
 
10
11
  import { EvaluationCache, EvaluationMetadata } from './evaluation-cache';
@@ -162,7 +163,7 @@ export class Evaluator {
162
163
  return result;
163
164
  } catch (error) {
164
165
  if (error instanceof CalcInvalidDataError) {
165
- return this.onError(RSErrorCode.calcInvalidData, node, [error.left, error.right]);
166
+ return this.onError(RSErrorCode.calcInvalidData, node, [error.left, error.right, labelRSLangNode(node)]);
166
167
  }
167
168
  this.onError(RSErrorCode.calcUnknownError, node);
168
169
  return null;
@@ -38,6 +38,7 @@ const labelTokenRecord: Partial<Record<TokenID, string>> = {
38
38
  [TokenID.NT_DECLARATIVE_EXPR]: 'D{}',
39
39
  [TokenID.NT_IMPERATIVE_EXPR]: 'I{}',
40
40
  [TokenID.NT_RECURSIVE_FULL]: 'R{}',
41
+ [TokenID.NT_RECURSIVE_SHORT]: 'R{}',
41
42
  [TokenID.BIGPR]: 'Pr1()',
42
43
  [TokenID.SMALLPR]: 'pr1()',
43
44
  [TokenID.FILTER]: 'Fi1[]()',
@@ -170,14 +170,14 @@ const errorData = [
170
170
  ['card(S3)', { code: RSErrorCode.invalidCard, from: 5, to: 7, params: ['C1'] }],
171
171
  ['card(1)', { code: RSErrorCode.invalidCard, from: 5, to: 6, params: ['Z'] }],
172
172
  ['card((1,2))', { code: RSErrorCode.invalidCard, from: 5, to: 10, params: ['Z×Z'] }],
173
- ['debool(X1)+1', { code: RSErrorCode.arithmeticNotSupported, from: 0, to: 10, params: ['X1'] }],
174
- ['1+debool(X1)', { code: RSErrorCode.arithmeticNotSupported, from: 2, to: 12, params: ['X1'] }],
173
+ ['debool(X1)+1', { code: RSErrorCode.arithmeticNotSupported, from: 0, to: 10, params: ['X1', '+'] }],
174
+ ['1+debool(X1)', { code: RSErrorCode.arithmeticNotSupported, from: 2, to: 12, params: ['X1', '+'] }],
175
175
  // Logical
176
- ['debool(X1)<1', { code: RSErrorCode.orderingNotSupported, from: 0, to: 10, params: ['X1'] }],
177
- ['1<debool(X1)', { code: RSErrorCode.orderingNotSupported, from: 2, to: 12, params: ['X1'] }],
178
- ['debool(X1)=1', { code: RSErrorCode.typesNotCompatible, from: 0, to: 12, params: ['X1', 'Z'] }],
179
- ['1=debool(X1)', { code: RSErrorCode.typesNotCompatible, from: 0, to: 12, params: ['Z', 'X1'] }],
180
- ['S1=S2', { code: RSErrorCode.typesNotCompatible, from: 0, to: 5, params: ['ℬ(X1×X1)', 'ℬℬ(X1)'] }],
176
+ ['debool(X1)<1', { code: RSErrorCode.orderingNotSupported, from: 0, to: 10, params: ['X1', '<'] }],
177
+ ['1<debool(X1)', { code: RSErrorCode.orderingNotSupported, from: 2, to: 12, params: ['X1', '<'] }],
178
+ ['debool(X1)=1', { code: RSErrorCode.typesNotCompatible, from: 0, to: 12, params: ['X1', 'Z', '='] }],
179
+ ['1=debool(X1)', { code: RSErrorCode.typesNotCompatible, from: 0, to: 12, params: ['Z', 'X1', '='] }],
180
+ ['S1=S2', { code: RSErrorCode.typesNotCompatible, from: 0, to: 5, params: ['ℬ(X1×X1)', 'ℬℬ(X1)', '='] }],
181
181
  ['∀a,a∈X1 a=a', { code: RSErrorCode.localShadowing, from: 3, to: 4, params: ['a'] }],
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 }],
@@ -190,9 +190,9 @@ const errorData = [
190
190
  ['(1,2)∈Z', { code: RSErrorCode.invalidElementPredicate, from: 0, to: 7, params: ['Z×Z', '∈', 'ℬ(Z)'] }],
191
191
  ['{1}∈Z', { code: RSErrorCode.invalidElementPredicate, from: 0, to: 5, params: ['ℬ(Z)', '∈', 'ℬ(Z)'] }],
192
192
  ['{1}∉Z', { code: RSErrorCode.invalidElementPredicate, from: 0, to: 5, params: ['ℬ(Z)', '∉', 'ℬ(Z)'] }],
193
- ['X1⊆S2', { code: RSErrorCode.typesNotEqual, from: 0, to: 5, params: ['ℬ(X1)', 'ℬℬ(X1)'] }],
194
- ['X1⊄S2', { code: RSErrorCode.typesNotEqual, from: 0, to: 5, params: ['ℬ(X1)', 'ℬℬ(X1)'] }],
195
- ['X1⊂S2', { code: RSErrorCode.typesNotEqual, from: 0, to: 5, params: ['ℬ(X1)', 'ℬℬ(X1)'] }],
193
+ ['X1⊆S2', { code: RSErrorCode.typesNotEqual, from: 0, to: 5, params: ['ℬ(X1)', 'ℬℬ(X1)', '⊆'] }],
194
+ ['X1⊄S2', { code: RSErrorCode.typesNotEqual, from: 0, to: 5, params: ['ℬ(X1)', 'ℬℬ(X1)', '⊄'] }],
195
+ ['X1⊂S2', { code: RSErrorCode.typesNotEqual, from: 0, to: 5, params: ['ℬ(X1)', 'ℬℬ(X1)', '⊂'] }],
196
196
  // Constructors
197
197
  ['ℬ(S3)', { code: RSErrorCode.invalidBoolean, from: 2, to: 4, params: ['C1'] }],
198
198
  ['ℬ((1,2))', { code: RSErrorCode.invalidBoolean, from: 2, to: 7, params: ['Z×Z'] }],
@@ -202,15 +202,15 @@ const errorData = [
202
202
  ['{1, X1}', { code: RSErrorCode.invalidEnumeration, from: 4, to: 6, params: ['Z', 'ℬ(X1)'] }],
203
203
  ['{X1, 1}', { code: RSErrorCode.invalidEnumeration, from: 5, to: 6, params: ['ℬ(X1)', 'Z'] }],
204
204
  ['{(1,2), (X1,X1)}', { code: RSErrorCode.invalidEnumeration, from: 8, to: 15, params: ['Z×Z', 'ℬ(X1)×ℬ(X1)'] }],
205
- ['R{a := S1 | {a}}', { code: RSErrorCode.typesNotEqual, from: 12, to: 15, params: ['ℬℬ(X1×X1)', 'ℬ(X1×X1)'] }],
205
+ ['R{a := S1 | {a}}', { code: RSErrorCode.typesNotEqual, from: 12, to: 15, params: ['ℬℬ(X1×X1)', 'ℬ(X1×X1)', 'R{}'] }],
206
206
  [
207
207
  'I{(a, b) | a:∈X1; b:={a}; a≠b}',
208
- { code: RSErrorCode.typesNotCompatible, from: 26, to: 29, params: ['X1', 'ℬ(X1)'] }
208
+ { code: RSErrorCode.typesNotCompatible, from: 26, to: 29, params: ['X1', 'ℬ(X1)', '≠'] }
209
209
  ],
210
210
  // Set operations
211
211
  ['X1 ∪ ∅', { code: RSErrorCode.invalidEmptySetUsage, from: 5, to: 6 }],
212
- ['X1 ∪ S1', { code: RSErrorCode.typesNotEqual, from: 0, to: 7, params: ['ℬ(X1)', 'ℬ(X1×X1)'] }],
213
- ['S1 ∪ X1', { code: RSErrorCode.typesNotEqual, from: 0, to: 7, params: ['ℬ(X1×X1)', 'ℬ(X1)'] }],
212
+ ['X1 ∪ S1', { code: RSErrorCode.typesNotEqual, from: 0, to: 7, params: ['ℬ(X1)', 'ℬ(X1×X1)', '∪'] }],
213
+ ['S1 ∪ X1', { code: RSErrorCode.typesNotEqual, from: 0, to: 7, params: ['ℬ(X1×X1)', 'ℬ(X1)', '∪'] }],
214
214
  ['Pr1(X1)', { code: RSErrorCode.invalidProjectionSet, from: 4, to: 6, params: ['Pr1', 'ℬ(X1)'] }],
215
215
  ['Pr3(S1)', { code: RSErrorCode.invalidProjectionSet, from: 4, to: 6, params: ['Pr3', 'ℬ(X1×X1)'] }],
216
216
  ['Pr1,3(S1)', { code: RSErrorCode.invalidProjectionSet, from: 6, to: 8, params: ['Pr1,3', 'ℬ(X1×X1)'] }],
@@ -219,11 +219,11 @@ const errorData = [
219
219
  ['pr1(debool(X1))', { code: RSErrorCode.invalidProjectionTuple, from: 4, to: 14, params: ['pr1', 'X1'] }],
220
220
  ['pr3(debool(S1))', { code: RSErrorCode.invalidProjectionTuple, from: 4, to: 14, params: ['pr3', 'X1×X1'] }],
221
221
  ['Fi1[X1](ℬ(X1))', { code: RSErrorCode.invalidFilterArgumentType, from: 8, to: 13, params: ['Fi1', 'ℬℬ(X1)'] }],
222
- ['Fi1[1](S1)', { code: RSErrorCode.typesNotEqual, from: 4, to: 5, params: ['Z', 'ℬ(X1)'] }],
223
- ['Fi1[X1](ℬ(X1)×X1)', { code: RSErrorCode.typesNotEqual, from: 4, to: 6, params: ['ℬ(X1)', 'ℬℬ(X1)'] }],
222
+ ['Fi1[1](S1)', { code: RSErrorCode.typesNotEqual, from: 4, to: 5, params: ['Z', 'ℬ(X1)', 'Fi1'] }],
223
+ ['Fi1[X1](ℬ(X1)×X1)', { code: RSErrorCode.typesNotEqual, from: 4, to: 6, params: ['ℬ(X1)', 'ℬℬ(X1)', 'Fi1'] }],
224
224
  ['Fi3[X1](S1)', { code: RSErrorCode.invalidFilterArgumentType, from: 8, to: 10, params: ['Fi3', 'ℬ(X1×X1)'] }],
225
225
  ['Fi1[X1,X1](S1)', { code: RSErrorCode.invalidFilterArity, from: 0, to: 14 }],
226
- ['Fi1,2[X1](S1)', { code: RSErrorCode.typesNotEqual, from: 6, to: 8, params: ['ℬ(X1)', 'ℬ(X1×X1)'] }],
226
+ ['Fi1,2[X1](S1)', { code: RSErrorCode.typesNotEqual, from: 6, to: 8, params: ['ℬ(X1)', 'ℬ(X1×X1)', 'Fi1,2'] }],
227
227
  ['red(X1)', { code: RSErrorCode.invalidReduce, from: 4, to: 6, params: ['ℬ(X1)'] }],
228
228
  ['debool(S3)', { code: RSErrorCode.invalidDebool, from: 7, to: 9, params: ['C1'] }],
229
229
  // Locals
@@ -236,7 +236,9 @@ const errorData = [
236
236
  // Logic vs setexpr discrimination
237
237
  ['D{α∈X1|F1[X1,X1]}', { code: RSErrorCode.expectedLogic, from: 7, to: 16, params: ['ℬ(X1)'] }],
238
238
  ['F1[1=1,X1]', { code: RSErrorCode.expectedSetexpr, from: 3, to: 6, params: ['Logic'] }],
239
- ['∀a∈(1=1) a=a', { code: RSErrorCode.expectedSetexpr, from: 3, to: 8, params: ['Logic'] }],
239
+ ['∀a∈(1=1) a=a', { code: RSErrorCode.invalidQuantifierDomain, from: 3, to: 8, params: ['∀', 'Logic'] }],
240
+ ['∀a∈Z a=a', { code: RSErrorCode.invalidQuantifierDomain, from: 3, to: 4, params: ['∀', 'Z'] }],
241
+ ['∃a∈Z a=a', { code: RSErrorCode.invalidQuantifierDomain, from: 3, to: 4, params: ['∃', 'Z'] }],
240
242
  ['∀a∈X1 F1[{a},X1]', { code: RSErrorCode.expectedLogic, from: 6, to: 16, params: ['ℬ(X1)'] }],
241
243
  ['(1=1)∪X1', { code: RSErrorCode.expectedSetexpr, from: 0, to: 5, params: ['Logic'] }],
242
244
  ['X1 & 1=1', { code: RSErrorCode.expectedLogic, from: 0, to: 2, params: ['ℬ(X1)'] }],
@@ -298,7 +298,12 @@ export class TypeAuditor {
298
298
  return true;
299
299
  }
300
300
 
301
- private childTypeDebool(node: AstNode, index: number, errorCode: RSErrorCode): Typification | null {
301
+ private childTypeDebool(
302
+ node: AstNode,
303
+ index: number,
304
+ errorCode: RSErrorCode,
305
+ operation?: string
306
+ ): Typification | null {
302
307
  const result = this.childTypification(node, index);
303
308
  if (result === null) {
304
309
  return null;
@@ -307,7 +312,30 @@ export class TypeAuditor {
307
312
  return result;
308
313
  }
309
314
  if (result.typeID !== TypeID.collection) {
310
- this.onError(errorCode, node.children[index], [labelType(result)]);
315
+ const params =
316
+ errorCode === RSErrorCode.invalidTypeOperation && operation !== undefined
317
+ ? [operation, labelType(result)]
318
+ : [labelType(result)];
319
+ this.onError(errorCode, node.children[index], params);
320
+ return null;
321
+ }
322
+ return debool(result);
323
+ }
324
+
325
+ private childQuantifierDomain(node: AstNode, index: number, operator: string): Typification | null {
326
+ const result = this.visitChild(node, index);
327
+ if (result === null) {
328
+ return null;
329
+ }
330
+ if (!isTypification(result)) {
331
+ this.onError(RSErrorCode.invalidQuantifierDomain, node.children[index], [operator, labelType(result)]);
332
+ return null;
333
+ }
334
+ if (result.typeID === TypeID.anyTypification) {
335
+ return result;
336
+ }
337
+ if (result.typeID !== TypeID.collection) {
338
+ this.onError(RSErrorCode.invalidQuantifierDomain, node.children[index], [operator, labelType(result)]);
311
339
  return null;
312
340
  }
313
341
  return debool(result);
@@ -415,7 +443,7 @@ export class TypeAuditor {
415
443
  if (variable.typeID === TokenID.NT_TUPLE_DECL) {
416
444
  return this.onError(RSErrorCode.invalidArgumentCortegeDeclare, variable);
417
445
  }
418
- const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
446
+ const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation, labelToken(TokenID.ITERATE));
419
447
  if (domain === null) {
420
448
  return null;
421
449
  }
@@ -433,12 +461,13 @@ export class TypeAuditor {
433
461
  }
434
462
 
435
463
  private visitArithmetic(node: AstNode): ExpressionType | null {
464
+ const operator = labelRSLangNode(node);
436
465
  const type1 = this.childTypification(node, 0);
437
466
  if (type1 === null) {
438
467
  return null;
439
468
  }
440
469
  if (!('isArithmetic' in type1 && type1.isArithmetic)) {
441
- return this.onError(RSErrorCode.arithmeticNotSupported, node.children[0], [labelType(type1)]);
470
+ return this.onError(RSErrorCode.arithmeticNotSupported, node.children[0], [labelType(type1), operator]);
442
471
  }
443
472
 
444
473
  const type2 = this.childTypification(node, 1);
@@ -446,23 +475,24 @@ export class TypeAuditor {
446
475
  return null;
447
476
  }
448
477
  if (!('isArithmetic' in type2 && type2.isArithmetic)) {
449
- return this.onError(RSErrorCode.arithmeticNotSupported, node.children[1], [labelType(type2)]);
478
+ return this.onError(RSErrorCode.arithmeticNotSupported, node.children[1], [labelType(type2), operator]);
450
479
  }
451
480
 
452
481
  const result = mergeTypifications(type1, type2);
453
482
  if (result === null) {
454
- return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2)]);
483
+ return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2), operator]);
455
484
  }
456
485
  return result;
457
486
  }
458
487
 
459
488
  private visitIntegerPredicate(node: AstNode): ExpressionType | null {
489
+ const operator = labelRSLangNode(node);
460
490
  const type1 = this.childTypification(node, 0);
461
491
  if (type1 === null) {
462
492
  return null;
463
493
  }
464
494
  if (!('isOrdered' in type1 && type1.isOrdered)) {
465
- return this.onError(RSErrorCode.orderingNotSupported, node.children[0], [labelType(type1)]);
495
+ return this.onError(RSErrorCode.orderingNotSupported, node.children[0], [labelType(type1), operator]);
466
496
  }
467
497
 
468
498
  const type2 = this.childTypification(node, 1);
@@ -470,11 +500,11 @@ export class TypeAuditor {
470
500
  return null;
471
501
  }
472
502
  if (!('isOrdered' in type2 && type2.isOrdered)) {
473
- return this.onError(RSErrorCode.orderingNotSupported, node.children[1], [labelType(type2)]);
503
+ return this.onError(RSErrorCode.orderingNotSupported, node.children[1], [labelType(type2), operator]);
474
504
  }
475
505
 
476
506
  if (!checkCompatibility(type1, type2)) {
477
- return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2)]);
507
+ return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2), operator]);
478
508
  }
479
509
  return LogicT;
480
510
  }
@@ -482,7 +512,8 @@ export class TypeAuditor {
482
512
  private visitQuantifier(node: AstNode): ExpressionType | null {
483
513
  this.locals.startScope();
484
514
 
485
- const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
515
+ const operator = labelRSLangNode(node);
516
+ const domain = this.childQuantifierDomain(node, 1, operator);
486
517
  if (domain === null) {
487
518
  return null;
488
519
  } else if (!this.visitChildDeclaration(node, 0, domain)) {
@@ -510,6 +541,7 @@ export class TypeAuditor {
510
541
  }
511
542
 
512
543
  private visitEquals(node: AstNode): ExpressionType | null {
544
+ const operator = labelRSLangNode(node);
513
545
  const type1 = this.childTypification(node, 0);
514
546
  if (type1 === null) {
515
547
  return null;
@@ -520,13 +552,14 @@ export class TypeAuditor {
520
552
  return null;
521
553
  }
522
554
  if (!checkCompatibility(type1, type2)) {
523
- return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2)]);
555
+ return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2), operator]);
524
556
  }
525
557
  return LogicT;
526
558
  }
527
559
 
528
560
  private visitSetexprPredicate(node: AstNode): ExpressionType | null {
529
- let type2 = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
561
+ const operator = labelRSLangNode(node);
562
+ let type2 = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation, operator);
530
563
  if (type2 === null) {
531
564
  return null;
532
565
  }
@@ -541,11 +574,11 @@ export class TypeAuditor {
541
574
 
542
575
  if (!checkCompatibility(type1, type2)) {
543
576
  if (isSubset) {
544
- return this.onError(RSErrorCode.typesNotEqual, node, [labelType(type1), labelType(type2)]);
577
+ return this.onError(RSErrorCode.typesNotEqual, node, [labelType(type1), labelType(type2), operator]);
545
578
  } else {
546
579
  return this.onError(RSErrorCode.invalidElementPredicate, node, [
547
580
  labelType(type1),
548
- labelToken(node.typeID as TokenID),
581
+ operator,
549
582
  labelType(bool(type2))
550
583
  ]);
551
584
  }
@@ -618,19 +651,20 @@ export class TypeAuditor {
618
651
  }
619
652
 
620
653
  private visitSetexprBinary(node: AstNode): ExpressionType | null {
621
- const type1 = this.childTypeDebool(node, 0, RSErrorCode.invalidTypeOperation);
654
+ const operator = labelRSLangNode(node);
655
+ const type1 = this.childTypeDebool(node, 0, RSErrorCode.invalidTypeOperation, operator);
622
656
  if (type1 === null) {
623
657
  return null;
624
658
  }
625
659
 
626
- const type2 = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
660
+ const type2 = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation, operator);
627
661
  if (type2 === null) {
628
662
  return null;
629
663
  }
630
664
 
631
665
  const result = mergeTypifications(type1, type2);
632
666
  if (result === null) {
633
- return this.onError(RSErrorCode.typesNotEqual, node, [labelType(bool(type1)), labelType(bool(type2))]);
667
+ return this.onError(RSErrorCode.typesNotEqual, node, [labelType(bool(type1)), labelType(bool(type2)), operator]);
634
668
  }
635
669
  return bool(result);
636
670
  }
@@ -706,6 +740,7 @@ export class TypeAuditor {
706
740
  }
707
741
 
708
742
  private visitFilter(node: AstNode): ExpressionType | null {
743
+ const operator = labelRSLangNode(node);
709
744
  const indices = getNodeIndices(node);
710
745
  const tupleParam = indices.length === node.children.length - 1;
711
746
  if (!tupleParam && node.children.length > 2) {
@@ -751,7 +786,8 @@ export class TypeAuditor {
751
786
  if (param.typeID !== TypeID.collection || !checkCompatibility(bases[child], debool(param))) {
752
787
  return this.onError(RSErrorCode.typesNotEqual, node.children[child], [
753
788
  labelType(param),
754
- labelType(bool(bases[child]))
789
+ labelType(bool(bases[child])),
790
+ operator
755
791
  ]);
756
792
  }
757
793
  }
@@ -763,7 +799,11 @@ export class TypeAuditor {
763
799
  const paramType = param;
764
800
  const expected = bool(tuple(bases));
765
801
  if (paramType.typeID !== TypeID.collection || !checkCompatibility(expected, paramType)) {
766
- return this.onError(RSErrorCode.typesNotEqual, node.children[0], [labelType(paramType), labelType(expected)]);
802
+ return this.onError(RSErrorCode.typesNotEqual, node.children[0], [
803
+ labelType(paramType),
804
+ labelType(expected),
805
+ operator
806
+ ]);
767
807
  }
768
808
  }
769
809
  return argument;
@@ -793,7 +833,12 @@ export class TypeAuditor {
793
833
  private visitDeclarative(node: AstNode): ExpressionType | null {
794
834
  this.locals.startScope();
795
835
 
796
- const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
836
+ const domain = this.childTypeDebool(
837
+ node,
838
+ 1,
839
+ RSErrorCode.invalidTypeOperation,
840
+ labelToken(TokenID.NT_DECLARATIVE_EXPR)
841
+ );
797
842
  if (domain === null) {
798
843
  return null;
799
844
  } else if (!this.visitChildDeclaration(node, 0, domain)) {
@@ -825,7 +870,7 @@ export class TypeAuditor {
825
870
  }
826
871
 
827
872
  private visitIterate(node: AstNode): ExpressionType | null {
828
- const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
873
+ const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation, labelToken(TokenID.ITERATE));
829
874
  if (domain === null) {
830
875
  return null;
831
876
  }
@@ -867,7 +912,8 @@ export class TypeAuditor {
867
912
  if (!checkCompatibility(iterationValue, initType)) {
868
913
  return this.onError(RSErrorCode.typesNotEqual, node.children[iterationIndex], [
869
914
  labelType(iterationValue),
870
- labelType(initType)
915
+ labelType(initType),
916
+ labelToken(node.typeID as TokenID)
871
917
  ]);
872
918
  }
873
919