fez-lisp 1.5.83 → 1.5.85

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/src/check.js CHANGED
@@ -1,21 +1,15 @@
1
1
  import {
2
2
  APPLY,
3
3
  ATOM,
4
- DEBUG,
5
- FALSE,
6
4
  KEYWORDS,
7
- MUTATION_SUFFIX,
8
5
  PLACEHOLDER,
9
- PREDICATE_SUFFIX,
10
6
  SPECIAL_FORMS_SET,
11
7
  STATIC_TYPES,
12
8
  STATIC_TYPES_SET,
13
- TRUE,
14
9
  TYPE,
15
10
  VALUE,
16
11
  WORD
17
12
  } from './keywords.js'
18
- import { OPTIMIZED_PREFIX } from './macros.js'
19
13
  import { isLeaf } from './parser.js'
20
14
  import {
21
15
  SPECIAL_FORM_TYPES,
@@ -29,19 +23,13 @@ import {
29
23
  SCOPE_NAME,
30
24
  TYPE_PROP,
31
25
  SIGNATURE,
32
- PREDICATE,
33
- COLLECTION,
34
26
  MAX_RETRY_DEFINITION,
35
27
  MAX_ARGUMENT_RETRY,
36
28
  ORDER,
37
- VARIABLE_ORDER_INDEX
29
+ VARIABLE_ORDER_INDEX,
30
+ COLLECTION
38
31
  } from './types.js'
39
- import {
40
- getSuffix,
41
- hasApplyLambdaBlock,
42
- hasBlock,
43
- stringifyArgs
44
- } from './utils.js'
32
+ import { hasApplyLambdaBlock, hasBlock, stringifyArgs } from './utils.js'
45
33
 
46
34
  export const identity = (name) => [
47
35
  [0, 'let'],
@@ -95,18 +83,15 @@ export const formatType = (name, env) => {
95
83
  `${
96
84
  x[STATS][TYPE_PROP][0] === APPLY
97
85
  ? `${formatType(i, stats[ARGUMENTS])}`
98
- : `${toTypeNames(
99
- x[STATS][TYPE_PROP][1] ?? x[STATS][TYPE_PROP][0]
100
- )}`
86
+ : `${toTypeNames(x[STATS][TYPE_PROP][0])}`
101
87
  }`
102
88
  )
103
89
  .join(' ')
104
- } (${KEYWORDS.BLOCK} ${toTypeNames(
105
- stats[RETURNS][1] ?? stats[RETURNS][0]
106
- )})${isAnonymous ? '' : ')'})`
107
- : `(let ${name} ${toTypeNames(
108
- stats[TYPE_PROP][1] ?? stats[TYPE_PROP][0]
109
- )})`
90
+ // TODO format returned functions when type support is added
91
+ } (${KEYWORDS.BLOCK} ${toTypeNames(stats[RETURNS][0])})${
92
+ isAnonymous ? '' : ')'
93
+ })`
94
+ : `(let ${name} ${toTypeNames(stats[TYPE_PROP][0])})`
110
95
  : name
111
96
  }
112
97
  const formatTypes = (env) => {
@@ -158,37 +143,6 @@ export const typeCheck = (ast) => {
158
143
  errorStack.add(
159
144
  `Trying to access undefined variable ${first[VALUE]} (check #11)`
160
145
  )
161
- } else {
162
- const T = env[first[VALUE]][STATS]
163
- const isKnown = T[TYPE_PROP][0] !== UNKNOWN
164
- switch (first[VALUE]) {
165
- case 'xs':
166
- case 'arr':
167
- case 'matrix':
168
- case 'table':
169
- if (isKnown && T[TYPE_PROP][0] !== COLLECTION) {
170
- warningStack.add(
171
- `A variable named ${first[VALUE]} must be of type (${
172
- STATIC_TYPES.COLLECTION
173
- }) but got type (${toTypeNames(
174
- T[TYPE_PROP][0]
175
- )}) (check #32)`
176
- )
177
- }
178
- //else T[TYPE_PROP] = [COLLECTION]
179
- break
180
- default:
181
- {
182
- const isPredicate =
183
- getSuffix(first[VALUE]) === PREDICATE_SUFFIX
184
- if (isPredicate) {
185
- // PRED ASSIGMENT
186
- if (isKnown) T[TYPE_PROP][1] = PREDICATE
187
- T[RETURNS] = [ATOM, PREDICATE]
188
- }
189
- }
190
- break
191
- }
192
146
  }
193
147
  })
194
148
  }
@@ -209,7 +163,7 @@ export const typeCheck = (ast) => {
209
163
  )
210
164
  } else {
211
165
  const name = rest[0][VALUE]
212
- const resolveRetunType = (returns, rem, prop, isPredicate) => {
166
+ const resolveRetunType = (returns, rem, prop) => {
213
167
  if (returns[TYPE] === ATOM) {
214
168
  // ATOM ASSIGMENT
215
169
  env[name][STATS][prop][0] = ATOM
@@ -223,14 +177,6 @@ export const typeCheck = (ast) => {
223
177
  // ATOM ASSIGMENT
224
178
  env[name][STATS][prop][0] = ATOM
225
179
  env[name][STATS][RETURNS][0] = ATOM
226
- if (
227
- getSuffix(re[0][VALUE]) === PREDICATE_SUFFIX ||
228
- getSuffix(re[1][VALUE]) === PREDICATE_SUFFIX
229
- ) {
230
- // ATOM ASSIGMENT PREDICATE ASSIGMENT
231
- env[name][STATS][TYPE_PROP][1] = [PREDICATE]
232
- env[name][STATS][RETURNS] = [ATOM, PREDICATE]
233
- }
234
180
  } else if (
235
181
  !isLeaf(re[0]) &&
236
182
  env[re[0][0][VALUE]] &&
@@ -238,10 +184,7 @@ export const typeCheck = (ast) => {
238
184
  ) {
239
185
  env[name][STATS][prop] =
240
186
  env[re[0][0][VALUE]][STATS][RETURNS]
241
- if (
242
- re[0][0][TYPE] === APPLY &&
243
- !name.startsWith(OPTIMIZED_PREFIX)
244
- ) {
187
+ if (re[0][0][TYPE] === APPLY) {
245
188
  switch (re[0][0][VALUE]) {
246
189
  case KEYWORDS.ANONYMOUS_FUNCTION:
247
190
  // FN UKNONW ASSIGMENT
@@ -263,10 +206,7 @@ export const typeCheck = (ast) => {
263
206
  env[re[1][0][VALUE]][STATS][prop]
264
207
  env[name][STATS][prop] =
265
208
  env[re[1][0][VALUE]][STATS][RETURNS]
266
- if (
267
- re[1][0][TYPE] === APPLY &&
268
- !name.startsWith(OPTIMIZED_PREFIX)
269
- ) {
209
+ if (re[1][0][TYPE] === APPLY) {
270
210
  switch (re[1][0][VALUE]) {
271
211
  case KEYWORDS.ANONYMOUS_FUNCTION:
272
212
  // FN ASSIGMENT
@@ -303,37 +243,15 @@ export const typeCheck = (ast) => {
303
243
  if (isLeaf(rest.at(-1).at(-1).at(-1))) {
304
244
  const fnName = rest.at(-1).at(-1).at(-1)[VALUE]
305
245
  const fn = env[fnName]
306
- if (
307
- !isPredicate &&
308
- fn[STATS][RETURNS][1] === PREDICATE
309
- ) {
310
- warningStack.add(
311
- `${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
312
- )
313
- } else if (
314
- isPredicate &&
315
- fn[STATS][RETURNS][1] !== PREDICATE
316
- ) {
317
- warningStack.add(
318
- `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #25)`
319
- )
320
- }
321
246
  env[name][STATS][TYPE_PROP][0] =
322
247
  fn[STATS][RETURNS][0]
323
- env[name][STATS][RETURNS][1] =
324
- fn[STATS][RETURNS][1]
325
248
  } else {
326
249
  const [returns, rem] = drillReturnType(
327
250
  rest.at(-1).at(-1).at(-1),
328
251
  (returns) =>
329
252
  returns[VALUE] === KEYWORDS.CALL_FUNCTION
330
253
  )
331
- resolveRetunType(
332
- returns,
333
- rem,
334
- TYPE_PROP,
335
- isPredicate
336
- )
254
+ resolveRetunType(returns, rem, TYPE_PROP)
337
255
  }
338
256
  }
339
257
  // ALWAYS APPLY
@@ -370,27 +288,6 @@ export const typeCheck = (ast) => {
370
288
  break
371
289
  }
372
290
  }
373
- if (
374
- isPredicate &&
375
- env[name][STATS][prop][0] !== UNKNOWN &&
376
- env[name][STATS][RETURNS][1] !== PREDICATE
377
- ) {
378
- warningStack.add(
379
- `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #7)`
380
- )
381
- } else if (
382
- !isPredicate &&
383
- env[name][STATS][RETURNS][1] === PREDICATE
384
- ) {
385
- warningStack.add(
386
- `${name} should end in (${PREDICATE_SUFFIX}) because it return (Predicate) (try adding ? at the end of the lambda name) (check #8)`
387
- )
388
- }
389
- if (isPredicate) {
390
- // ATOM ASSIGMENT PREDICATE ASSIGMENT
391
- env[name][STATS][prop] = [ATOM, PREDICATE]
392
- env[name][STATS][RETURNS] = [ATOM, PREDICATE]
393
- }
394
291
  }
395
292
  const checkReturnType = () => {
396
293
  const last = rest.at(-1).at(-1)
@@ -399,8 +296,7 @@ export const typeCheck = (ast) => {
399
296
  : last
400
297
  const rem = hasBlock(body) ? body.at(-1) : body
401
298
  const returns = isLeaf(rem) ? rem : rem[0]
402
- const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
403
- resolveRetunType(returns, rem, RETURNS, isPredicate)
299
+ resolveRetunType(returns, rem, RETURNS)
404
300
  }
405
301
  const rightHand = rest.at(-1)
406
302
  if (
@@ -451,30 +347,7 @@ export const typeCheck = (ast) => {
451
347
  env[name] = SPECIAL_FORMS_SET.has(rest[1][VALUE])
452
348
  ? structuredClone(env[rest[1][VALUE]])
453
349
  : env[rest[1][VALUE]]
454
-
455
- if (
456
- getSuffix(rest[1][VALUE]) === PREDICATE_SUFFIX &&
457
- getSuffix(name) !== PREDICATE_SUFFIX
458
- )
459
- warningStack.add(
460
- `${name} is assigned to ${rest[1][VALUE]} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #17)`
461
- )
462
- else if (
463
- getSuffix(rest[1][VALUE]) === MUTATION_SUFFIX &&
464
- getSuffix(name) !== MUTATION_SUFFIX
465
- )
466
- warningStack.add(
467
- `${name} is assigned to ${rest[1][VALUE]} which ends in (${MUTATION_SUFFIX}) so ${name} must also end in (${MUTATION_SUFFIX}) (check #18)`
468
- )
469
350
  } else if (isL && rightHand[TYPE] === ATOM) {
470
- const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
471
- // This never happens
472
- // if (
473
- // isPredicate &&
474
- // right[VALUE] !== TRUE &&
475
- // right[VALUE] !== FALSE
476
- // ) {
477
- // }
478
351
  // DECLARATION of ATOM
479
352
  env[name] = {
480
353
  [STATS]: {
@@ -486,31 +359,8 @@ export const typeCheck = (ast) => {
486
359
  [RETURNS]: [ATOM]
487
360
  }
488
361
  }
489
- if (isPredicate) {
490
- if (rightHand[VALUE] !== TRUE && rightHand !== FALSE) {
491
- warningStack.add(
492
- `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but the (Atom) value is neither ${TRUE} or ${FALSE} (${stringifyArgs(
493
- exp
494
- )}) (check #14)`
495
- )
496
- } else {
497
- // PREDICATE ASSIGMENT
498
- env[name][STATS][TYPE_PROP][1] = PREDICATE
499
- env[name][STATS][RETURNS] = [ATOM, PREDICATE]
500
- }
501
- }
502
362
  } else {
503
363
  const right = rightHand[0]
504
- const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
505
- if (
506
- right &&
507
- right[VALUE] &&
508
- getSuffix(right[VALUE]) === PREDICATE_SUFFIX &&
509
- !isPredicate
510
- )
511
- warningStack.add(
512
- `${name} is assigned to ${right[VALUE]} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #19)`
513
- )
514
364
  //DECLARATION
515
365
  env[name] = {
516
366
  [STATS]: {
@@ -527,31 +377,11 @@ export const typeCheck = (ast) => {
527
377
  [RETURNS]: [UNKNOWN]
528
378
  }
529
379
  }
530
- if (isPredicate) {
531
- // PREDICATE ASSIGMENT
532
- env[name][STATS][TYPE_PROP][1] = PREDICATE
533
- env[name][STATS][RETURNS] = [ATOM, PREDICATE]
534
- }
535
380
  if (right && right[VALUE]) {
536
381
  if (right[VALUE] === KEYWORDS.CALL_FUNCTION) {
537
382
  if (isLeaf(rightHand.at(-1))) {
538
383
  const fnName = rightHand.at(-1)[VALUE]
539
384
  const fn = env[fnName]
540
- if (
541
- !isPredicate &&
542
- fn[STATS][RETURNS][1] === PREDICATE
543
- ) {
544
- warningStack.add(
545
- `${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
546
- )
547
- } else if (
548
- isPredicate &&
549
- fn[STATS][RETURNS][1] !== PREDICATE
550
- ) {
551
- warningStack.add(
552
- `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #25)`
553
- )
554
- }
555
385
  // FB assigment
556
386
  env[name][STATS][TYPE_PROP] = fn[STATS][RETURNS]
557
387
  env[name][STATS][RETURNS] = fn[STATS][RETURNS]
@@ -559,29 +389,13 @@ export const typeCheck = (ast) => {
559
389
  const body = rightHand.at(-1).at(-1)
560
390
  const rem = hasBlock(body) ? body.at(-1) : body
561
391
  const returns = isLeaf(rem) ? rem : rem[0]
562
- resolveRetunType(returns, rem, TYPE_PROP, isPredicate)
392
+ resolveRetunType(returns, rem, TYPE_PROP)
563
393
  }
564
394
  } else {
565
395
  const body = rightHand
566
396
  const rem = hasBlock(body) ? body.at(-1) : body
567
397
  const returns = isLeaf(rem) ? rem : rem[0]
568
- resolveRetunType(returns, rem, TYPE_PROP, isPredicate)
569
- }
570
- if (env[right[VALUE]]?.[STATS]?.[RETURNS]?.[1]) {
571
- if (
572
- env[right[VALUE]][STATS][RETURNS][1] === PREDICATE &&
573
- !isPredicate
574
- ) {
575
- warningStack.add(
576
- `${name} is assigned to the result of a (${toTypeNames(
577
- PREDICATE
578
- )}) so ${name} must end in (${PREDICATE_SUFFIX}) (check #23)`
579
- )
580
- }
581
-
582
- // FN assigment
583
- env[name][STATS][RETURNS] =
584
- env[right[VALUE]][STATS][RETURNS]
398
+ resolveRetunType(returns, rem, TYPE_PROP)
585
399
  }
586
400
  }
587
401
  }
@@ -636,99 +450,83 @@ export const typeCheck = (ast) => {
636
450
  const ref = env[copy[SCOPE_NAME]]
637
451
  if (ref) {
638
452
  ref[STATS][ARGUMENTS][i] = copy[param[VALUE]]
639
- if (getSuffix(param[VALUE]) === PREDICATE_SUFFIX) {
640
- // copy[param[VALUE]][STATS][TYPE_PROP][1]= PREDICATE
641
- copy[param[VALUE]][STATS][RETURNS] = [ATOM, PREDICATE]
453
+ const returns = deepLambdaReturn(
454
+ hasBlock(exp) ? exp.at(-1) : exp,
455
+ (result) => result[VALUE] !== KEYWORDS.IF
456
+ )
457
+ if (isLeaf(returns)) {
458
+ // TODO figure out what we do here
459
+ // this here is a variable WORD
460
+ // so return type of that function is that varible type
461
+ if (copy[returns[VALUE]])
462
+ ref[STATS][RETURNS] =
463
+ copy[returns[VALUE]][STATS][TYPE_PROP]
464
+ else
465
+ stack.push(() => {
466
+ if (copy[returns[VALUE]])
467
+ ref[STATS][RETURNS] =
468
+ copy[returns[VALUE]][STATS][TYPE_PROP]
469
+ })
642
470
  } else {
643
- const returns = deepLambdaReturn(
644
- hasBlock(exp) ? exp.at(-1) : exp,
645
- (result) => result[VALUE] !== KEYWORDS.IF
646
- )
647
- if (isLeaf(returns)) {
648
- // TODO figure out what we do here
649
- // this here is a variable WORD
650
- // so return type of that function is that varible type
651
- if (copy[returns[VALUE]])
652
- ref[STATS][RETURNS] =
653
- copy[returns[VALUE]][STATS][TYPE_PROP]
654
- else
655
- stack.push(() => {
656
- if (copy[returns[VALUE]])
657
- ref[STATS][RETURNS] =
658
- copy[returns[VALUE]][STATS][TYPE_PROP]
659
- })
660
- } else {
661
- const ret = returns[0]
662
- switch (ret[VALUE]) {
663
- case KEYWORDS.IF:
664
- const re = returns.slice(2)
665
- // If either is an ATOM then IF returns an ATOM
666
- if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
667
- ref[STATS][RETURNS][0] = ATOM
668
- // TODO check that both brancehs are predicates if one is
669
- if (
670
- getSuffix(re[0][VALUE]) === PREDICATE_SUFFIX ||
671
- getSuffix(re[1][VALUE]) === PREDICATE_SUFFIX
672
- ) {
673
- ref[STATS][TYPE_PROP][1] = PREDICATE
674
- ref[STATS][RETURNS][1] = PREDICATE
675
- }
676
- } else {
677
- const concequent = isLeaf(re[0])
678
- ? copy[re[0][VALUE]]
679
- : copy[re[0][0][VALUE]]
680
- const alternative = isLeaf(re[1])
681
- ? copy[re[1][VALUE]]
682
- : copy[re[1][0][VALUE]]
471
+ const ret = returns[0]
472
+ switch (ret[VALUE]) {
473
+ case KEYWORDS.IF:
474
+ const re = returns.slice(2)
475
+ // If either is an ATOM then IF returns an ATOM
476
+ if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
477
+ ref[STATS][RETURNS][0] = ATOM
478
+ // TODO check that both brancehs are predicates if one is
479
+ } else {
480
+ const concequent = isLeaf(re[0])
481
+ ? copy[re[0][VALUE]]
482
+ : copy[re[0][0][VALUE]]
483
+ const alternative = isLeaf(re[1])
484
+ ? copy[re[1][VALUE]]
485
+ : copy[re[1][0][VALUE]]
683
486
 
684
- // todo check if condition matches alternative
685
- // TODO make this more simple - it's so many different things just because types are functions or not
686
- // WHY not consiter making return types for everything
687
- if (
688
- concequent &&
689
- concequent[STATS][TYPE_PROP][0] !== UNKNOWN
690
- ) {
691
- if (concequent[STATS][TYPE_PROP][0] === APPLY)
692
- ref[STATS][RETURNS] = concequent[STATS][RETURNS]
693
- else
694
- ref[STATS][RETURNS] =
695
- concequent[STATS][TYPE_PROP]
696
- } else if (
697
- alternative &&
698
- alternative[STATS][TYPE_PROP][0] !== UNKNOWN
699
- ) {
700
- if (alternative[STATS][TYPE_PROP][0] === APPLY)
701
- ref[STATS][RETURNS] =
702
- alternative[STATS][RETURNS]
703
- else
704
- ref[STATS][RETURNS] =
705
- alternative[STATS][TYPE_PROP]
706
- } else if (concequent) {
707
- if (concequent[STATS][TYPE_PROP][0] === APPLY)
708
- ref[STATS][RETURNS] = concequent[STATS][RETURNS]
709
- else
710
- ref[STATS][RETURNS] =
711
- concequent[STATS][TYPE_PROP]
712
- }
487
+ // todo check if condition matches alternative
488
+ // TODO make this more simple - it's so many different things just because types are functions or not
489
+ // WHY not consiter making return types for everything
490
+ if (
491
+ concequent &&
492
+ concequent[STATS][TYPE_PROP][0] !== UNKNOWN
493
+ ) {
494
+ if (concequent[STATS][TYPE_PROP][0] === APPLY)
495
+ ref[STATS][RETURNS] = concequent[STATS][RETURNS]
496
+ else
497
+ ref[STATS][RETURNS] = concequent[STATS][TYPE_PROP]
498
+ } else if (
499
+ alternative &&
500
+ alternative[STATS][TYPE_PROP][0] !== UNKNOWN
501
+ ) {
502
+ if (alternative[STATS][TYPE_PROP][0] === APPLY)
503
+ ref[STATS][RETURNS] = alternative[STATS][RETURNS]
504
+ else
505
+ ref[STATS][RETURNS] =
506
+ alternative[STATS][TYPE_PROP]
507
+ } else if (concequent) {
508
+ if (concequent[STATS][TYPE_PROP][0] === APPLY)
509
+ ref[STATS][RETURNS] = concequent[STATS][RETURNS]
510
+ else
511
+ ref[STATS][RETURNS] = concequent[STATS][TYPE_PROP]
713
512
  }
513
+ }
714
514
 
715
- break
716
- default:
717
- if (copy[ret[VALUE]])
718
- ref[STATS][RETURNS] =
719
- copy[ret[VALUE]][STATS][RETURNS]
720
- else
721
- stack.push(() => {
722
- if (copy[ret[VALUE]])
723
- ref[STATS][RETURNS] =
724
- copy[ret[VALUE]][STATS][RETURNS]
725
- })
515
+ break
516
+ default:
517
+ if (copy[ret[VALUE]])
518
+ ref[STATS][RETURNS] = copy[ret[VALUE]][STATS][RETURNS]
519
+ else
520
+ stack.push(() => {
521
+ if (copy[ret[VALUE]])
522
+ ref[STATS][RETURNS] =
523
+ copy[ret[VALUE]][STATS][RETURNS]
524
+ })
726
525
 
727
- break
728
- }
526
+ break
729
527
  }
730
- // TODO overwrite return type check here
731
528
  }
529
+ // TODO overwrite return type check here
732
530
  }
733
531
  }
734
532
  check(rest.at(-1), copy, copy)
@@ -821,19 +619,6 @@ export const typeCheck = (ast) => {
821
619
  )}) (${stringifyArgs(exp)}) (check #26)`
822
620
  )
823
621
  }
824
- if (fn && fn[STATS][RETURNS][1] !== PRED_TYPE) {
825
- errorStack.add(
826
- `Incorrect type of argument (${i}) for (${
827
- first[VALUE]
828
- }). Expected (${toTypeNames(
829
- PRED_TYPE
830
- )}) but got an (${toTypeNames(
831
- fn[STATS][RETURNS][1] ?? fn[STATS][RETURNS][0]
832
- )}) which is neither ${TRUE} or ${FALSE} (${stringifyArgs(
833
- exp
834
- )}) (check #27)`
835
- )
836
- }
837
622
  } else {
838
623
  const body = rest[i].at(-1).at(-1)
839
624
  const rem = hasBlock(body) ? body.at(-1) : body
@@ -850,24 +635,6 @@ export const typeCheck = (ast) => {
850
635
  )}) (${stringifyArgs(exp)}) (check #27)`
851
636
  )
852
637
  }
853
- if (
854
- PRED_TYPE &&
855
- PRED_TYPE === PREDICATE &&
856
- returns[VALUE] !== TRUE &&
857
- returns[VALUE] !== FALSE
858
- ) {
859
- errorStack.add(
860
- `Incorrect type of argument ${i} for (${
861
- first[VALUE]
862
- }). Expected (${toTypeNames(
863
- PRED_TYPE
864
- )}) but got an (${toTypeNames(
865
- ATOM
866
- )}) which is neither ${TRUE} or ${FALSE} (${stringifyArgs(
867
- exp
868
- )}) (check #27)`
869
- )
870
- }
871
638
  } else if (env[returns[VALUE]]) {
872
639
  if (
873
640
  MAIN_TYPE !==
@@ -883,41 +650,6 @@ export const typeCheck = (ast) => {
883
650
  )}) (${stringifyArgs(exp)}) (check #29)`
884
651
  )
885
652
  }
886
- // Never happens because there is only 1 sub type at the moment
887
- // if (
888
- // PRED_TYPE &&
889
- // PRED_TYPE !==
890
- // env[returns[VALUE]][STATS][RETURNS][1]
891
- // ) {
892
- // }
893
- }
894
- }
895
- } else if (
896
- PRED_TYPE &&
897
- env[current[VALUE]] &&
898
- env[current[VALUE]][STATS][RETURNS][1] !== PRED_TYPE
899
- ) {
900
- if (current[VALUE] === KEYWORDS.ANONYMOUS_FUNCTION) {
901
- const body = rest[i].at(-1)
902
- const rem = hasBlock(body) ? body.at(-1) : body
903
- const returns = isLeaf(rem) ? rem : rem[0]
904
- if (
905
- env[returns[VALUE]] &&
906
- root[returns[VALUE]][STATS][RETURNS][1] ===
907
- PREDICATE
908
- ) {
909
- // TODO invert this logic
910
- } else {
911
- errorStack.add(
912
- `Incorrect type of arguments (${i}) for (${
913
- first[VALUE]
914
- }). Expected (${toTypeNames(
915
- PRED_TYPE
916
- )}) but got (${toTypeNames(
917
- env[current[VALUE]][STATS][RETURNS][1] ??
918
- env[current[VALUE]][STATS][RETURNS][0]
919
- )}) (${stringifyArgs(exp)}) (check #21)`
920
- )
921
653
  }
922
654
  }
923
655
  }
@@ -927,7 +659,6 @@ export const typeCheck = (ast) => {
927
659
  const isCast = STATIC_TYPES_SET.has(first[VALUE])
928
660
  const expectedArgs = env[first[VALUE]][STATS][ARGUMENTS]
929
661
  for (let i = 0; i < rest.length; ++i) {
930
- const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
931
662
  const MAIN_TYPE = expectedArgs[i][STATS][TYPE_PROP][0]
932
663
  if (MAIN_TYPE === UNKNOWN && !isCast) continue
933
664
  if (!isLeaf(rest[i])) {
@@ -974,21 +705,7 @@ export const typeCheck = (ast) => {
974
705
  env[CAR][STATS][TYPE_PROP][0]
975
706
  )}) (${stringifyArgs(exp)}) (check #3)`
976
707
  )
977
- } else if (
978
- PRED_TYPE === PREDICATE &&
979
- env[CAR][STATS][RETURNS][1] !== PRED_TYPE &&
980
- !isCast
981
- )
982
- errorStack.add(
983
- `Incorrect type of argument (${i}) for special form (${
984
- first[VALUE]
985
- }). Expected (${toTypeNames(
986
- PRED_TYPE
987
- )}) but got (${toTypeNames(
988
- env[CAR][STATS][RETURNS][1] ??
989
- env[CAR][STATS][TYPE_PROP][0]
990
- )}) (${stringifyArgs(exp)}) (check #6)`
991
- )
708
+ }
992
709
  } else if (env[rest[i][VALUE]]) {
993
710
  if (isCast) {
994
711
  // CAST assigment
@@ -1016,22 +733,6 @@ export const typeCheck = (ast) => {
1016
733
  )}) (${stringifyArgs(exp)}) (check #2)`
1017
734
  )
1018
735
  }
1019
- if (
1020
- PRED_TYPE === PREDICATE &&
1021
- rest[i][VALUE] !== TRUE &&
1022
- rest[i][VALUE] !== FALSE
1023
- ) {
1024
- errorStack.add(
1025
- `Incorrect type of argument (${i}) for special form (${
1026
- first[VALUE]
1027
- }). Expected (${toTypeNames(
1028
- PRED_TYPE
1029
- )}) but got (${toTypeNames(
1030
- rest[i][VALUE]
1031
- )}) (${stringifyArgs(exp)}) (check #5)`
1032
- )
1033
- }
1034
-
1035
736
  break
1036
737
  }
1037
738
  }
@@ -1058,22 +759,6 @@ export const typeCheck = (ast) => {
1058
759
  exp
1059
760
  )}) (check #10)`
1060
761
  )
1061
- } else if (
1062
- T === ATOM &&
1063
- args[i][STATS][RETURNS][0] === ATOM &&
1064
- args[i][STATS][RETURNS][1] === PREDICATE &&
1065
- rest[i][VALUE] !== TRUE &&
1066
- rest[i][VALUE] !== FALSE
1067
- ) {
1068
- errorStack.add(
1069
- `Incorrect type of arguments ${i} for (${
1070
- first[VALUE]
1071
- }). Expected (${toTypeNames(
1072
- args[i][STATS][RETURNS][1]
1073
- )}) but got (${toTypeNames(T)}) (${stringifyArgs(
1074
- exp
1075
- )}) (check #13)`
1076
- )
1077
762
  } else if (
1078
763
  T === APPLY &&
1079
764
  args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
@@ -1099,6 +784,7 @@ export const typeCheck = (ast) => {
1099
784
  }
1100
785
  }
1101
786
  if (
787
+ T === COLLECTION &&
1102
788
  env[rest[i][VALUE]] &&
1103
789
  env[rest[i][VALUE]][STATS][TYPE_PROP][0] !== UNKNOWN &&
1104
790
  args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&