fez-lisp 1.5.90 → 1.5.92

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
@@ -32,12 +32,14 @@ import {
32
32
  MAX_ARGUMENT_RETRY,
33
33
  ORDER,
34
34
  VARIABLE_ORDER_INDEX,
35
- COLLECTION
35
+ COLLECTION,
36
+ ANY
36
37
  } from './types.js'
37
38
  import {
38
39
  getSuffix,
39
40
  hasApplyLambdaBlock,
40
41
  hasBlock,
42
+ logExp,
41
43
  stringifyArgs
42
44
  } from './utils.js'
43
45
 
@@ -63,6 +65,84 @@ const deepLambdaReturn = (rest, condition) => {
63
65
  const rem = hasBlock(body) ? body.at(-1) : body
64
66
  return condition(rem) ? rem : deepLambdaReturn(rem, condition)
65
67
  }
68
+ export const isTypeAbstraction = (stats) => {
69
+ return stats[TYPE_PROP] === APPLY
70
+ }
71
+ export const setTypeRef = (stats, value) => {
72
+ // if (!isAnyReturn(stats) && !isAnyReturn(value))
73
+ if (isUnknownType(stats)) stats[TYPE_PROP] = value[TYPE_PROP]
74
+ }
75
+ export const setReturnRef = (stats, value) => {
76
+ // if (!isAnyReturn(stats) && !isAnyReturn(value))
77
+ if (isUnknownReturn(stats)) stats[RETURNS] = value[RETURNS]
78
+ }
79
+ export const setReturnToTypeRef = (stats, value) => {
80
+ // if (!isAnyReturn(stats) && !isAnyReturn(value))
81
+ if (isUnknownReturn(stats)) stats[RETURNS] = value[TYPE_PROP]
82
+ }
83
+ export const setPropRef = (stats, prop, value) => {
84
+ // if (stats[prop][0] !== ANY && value[prop][0] !== ANY)
85
+ if (stats[prop][0] === UNKNOWN) stats[prop] = value[prop]
86
+ }
87
+ export const setReturn = (stats, value) => {
88
+ // if (!isAnyReturn(stats) && !isAnyReturn(value))
89
+ if (isUnknownReturn(stats) && !isUnknownReturn(value))
90
+ stats[RETURNS][0] = value[RETURNS][0]
91
+ }
92
+ export const setType = (stats, value) => {
93
+ // if (!isAnyType(stats) && !isAnyType(value))
94
+
95
+ if (isUnknownType(stats) && !isUnknownType(value))
96
+ stats[TYPE_PROP][0] = value[TYPE_PROP][0]
97
+ }
98
+ export const setTypeToReturn = (stats, value) => {
99
+ // if (!isAnyType(stats) && !isAnyReturn(value))
100
+ if (isUnknownType(stats) && !isUnknownReturn(value))
101
+ stats[TYPE_PROP][0] = value[RETURNS][0]
102
+ }
103
+ export const setReturnToType = (stats, value) => {
104
+ // if (!isAnyType(stats) && !isAnyReturn(value))
105
+ if (isUnknownReturn(stats) && !isUnknownType(value))
106
+ stats[RETURNS][0] = value[TYPE_PROP][0]
107
+ }
108
+ export const setProp = (stats, prop, value) => {
109
+ // if (stats[prop][0] !== ANY && value[prop][0] !== ANY)
110
+ if (stats[prop][0] === UNKNOWN && value[prop][0] !== UNKNOWN)
111
+ stats[prop][0] = value[prop][0]
112
+ }
113
+ export const isAnyReturn = (stats) => {
114
+ return stats && stats[RETURNS][0] === ANY
115
+ }
116
+ export const isAnyType = (stats) => {
117
+ return stats && stats[TYPE_PROP][0] === ANY
118
+ }
119
+ export const isUnknownType = (stats) => {
120
+ return stats && stats[TYPE_PROP][0] === UNKNOWN
121
+ }
122
+ export const isUnknownReturn = (stats) => {
123
+ return stats[RETURNS][0] === UNKNOWN
124
+ }
125
+ export const getType = (stats) => {
126
+ return stats && stats[TYPE_PROP][0]
127
+ }
128
+ export const getReturn = (stats) => {
129
+ return stats && stats[RETURNS][0]
130
+ }
131
+ export const isAtomType = (stats) => {
132
+ return isAnyType(stats) || stats[TYPE_PROP][0] === ATOM
133
+ }
134
+ export const isAtomReturn = (stats) => {
135
+ return isAnyType(stats) || stats[RETURNS][0] === ATOM
136
+ }
137
+ export const compareTypes = (a, b) => {
138
+ return isAnyType(a) || isAnyType(b) || a[TYPE_PROP][0] === b[TYPE_PROP][0]
139
+ }
140
+ export const compareReturns = (a, b) => {
141
+ return isAnyReturn(a) || isAnyReturn(b) || a[RETURNS][0] === b[RETURNS][0]
142
+ }
143
+ export const compareTypeWithReturn = (a, b) => {
144
+ return isAnyType(a) || isAnyReturn(b) || a[TYPE_PROP][0] === b[RETURNS][0]
145
+ }
66
146
  const checkPredicateName = (exp, rest, warningStack) => {
67
147
  if (getSuffix(rest[0][VALUE]) === PREDICATE_SUFFIX) {
68
148
  const last = rest.at(-1)
@@ -147,7 +227,7 @@ export const formatType = (name, env) => {
147
227
  const stats = env[name][STATS]
148
228
  const isAnonymous = typeof name === 'number'
149
229
  return stats
150
- ? stats[TYPE_PROP][0] === APPLY
230
+ ? getType(stats) === APPLY
151
231
  ? `${isAnonymous ? '' : `(let ${name} `}(lambda ${
152
232
  stats[ARG_COUNT] === VARIADIC
153
233
  ? '... ' + STATIC_TYPES.UNKNOWN
@@ -155,17 +235,17 @@ export const formatType = (name, env) => {
155
235
  .map(
156
236
  (x, i) =>
157
237
  `${
158
- x[STATS][TYPE_PROP][0] === APPLY
238
+ getType(x[STATS]) === APPLY
159
239
  ? `${formatType(i, stats[ARGUMENTS])}`
160
- : `${toTypeNames(x[STATS][TYPE_PROP][0])}`
240
+ : `${toTypeNames(getType(x[STATS]))}`
161
241
  }`
162
242
  )
163
243
  .join(' ')
164
244
  // TODO format returned functions when type support is added
165
- } (${KEYWORDS.BLOCK} ${toTypeNames(stats[RETURNS][0])})${
245
+ } (${KEYWORDS.BLOCK} ${toTypeNames(getReturn(stats))})${
166
246
  isAnonymous ? '' : ')'
167
247
  })`
168
- : `(let ${name} ${toTypeNames(stats[TYPE_PROP][0])})`
248
+ : `(let ${name} ${toTypeNames(getType(stats))})`
169
249
  : name
170
250
  }
171
251
  const formatTypes = (env) => {
@@ -192,9 +272,9 @@ const withScope = (name, scope) => {
192
272
  .map((x) => (Number.isInteger(+x) ? '::' : x))
193
273
  .join(' ')} ${name}`
194
274
  }
195
- export const typeCheck = (ast) => {
275
+ export const typeCheck = (ast, error = true) => {
196
276
  const root = structuredClone(SPECIAL_FORM_TYPES)
197
- root[ORDER] = 0
277
+ // root[ORDER] = 0
198
278
  const errorStack = new Set()
199
279
  const warningStack = new Set()
200
280
  // TODO delete this
@@ -273,7 +353,7 @@ export const typeCheck = (ast) => {
273
353
  } else if (
274
354
  !isLeaf(re[0]) &&
275
355
  env[re[0][0][VALUE]] &&
276
- env[re[0][0][VALUE]][STATS][RETURNS][0] !== UNKNOWN
356
+ !isUnknownReturn(env[re[0][0][VALUE]][STATS])
277
357
  ) {
278
358
  env[name][STATS][prop] =
279
359
  env[re[0][0][VALUE]][STATS][RETURNS]
@@ -293,10 +373,13 @@ export const typeCheck = (ast) => {
293
373
  } else if (
294
374
  !isLeaf(re[1]) &&
295
375
  env[re[1][0][VALUE]] &&
296
- env[re[1][0][VALUE]][STATS][RETURNS][0] !== UNKNOWN
376
+ !isUnknownReturn(env[re[1][0][VALUE]][STATS])
297
377
  ) {
298
- env[name][STATS][prop] =
299
- env[re[1][0][VALUE]][STATS][prop]
378
+ setProp(
379
+ env[name][STATS],
380
+ prop,
381
+ env[re[1][0][VALUE]][STATS]
382
+ )
300
383
  env[name][STATS][prop] =
301
384
  env[re[1][0][VALUE]][STATS][RETURNS]
302
385
  if (re[1][0][TYPE] === APPLY) {
@@ -320,11 +403,24 @@ export const typeCheck = (ast) => {
320
403
  env[re[0][VALUE]][STATS][RETURNS]
321
404
  } else if (env[re[1][VALUE]]) {
322
405
  // ASSIGMENT
323
- env[name][STATS][prop] =
324
- env[re[1][VALUE]][STATS][prop]
325
- env[name][STATS][RETURNS] =
326
- env[re[1][VALUE]][STATS][RETURNS]
327
- } else env[name][STATS][prop] = [UNKNOWN]
406
+ setProp(
407
+ env[name][STATS],
408
+ prop,
409
+ env[re[1][VALUE]][STATS]
410
+ )
411
+ // env[name][STATS][prop] =
412
+ // env[re[1][VALUE]][STATS][prop]
413
+ setReturnRef(
414
+ env[name][STATS],
415
+ env[re[1][VALUE]][STATS]
416
+ )
417
+ }
418
+ // else {
419
+ // // setProp(env[name][STATS], prop, {
420
+ // // [prop]: [UNKNOWN]
421
+ // // })
422
+ // // env[name][STATS][prop] = [UNKNOWN]
423
+ // }
328
424
  }
329
425
  break
330
426
  default:
@@ -335,29 +431,38 @@ export const typeCheck = (ast) => {
335
431
  returns,
336
432
  warningStack
337
433
  )
338
- if (!env[returns[VALUE]])
339
- env[name][STATS][RETURNS] = [UNKNOWN]
434
+ if (!env[returns[VALUE]]) {
435
+ return false
436
+ // env[name][STATS][RETURNS] = [ANY]
437
+ }
340
438
  // env[name][STATS][RETURNS] = APPLY
341
439
  else if (
342
- env[returns[VALUE]][STATS][TYPE_PROP][0] === APPLY
440
+ getType(env[returns[VALUE]][STATS]) === APPLY
343
441
  ) {
344
442
  // ALWAYS APPLY
345
443
  // rest.at(-1)[0][TYPE] === APPLY
346
444
  // Here is upon application to store the result in the variable
347
- if (env[name][STATS][TYPE_PROP][0] === UNKNOWN)
445
+ if (isUnknownType(env[name][STATS]))
348
446
  stack.unshift(() => {
349
- env[name][STATS][TYPE_PROP][0] =
350
- env[returns[VALUE]][STATS][RETURNS][0]
447
+ setTypeToReturn(
448
+ env[name][STATS],
449
+ env[returns[VALUE]][STATS]
450
+ )
451
+ // env[name][STATS][TYPE_PROP][0] =
452
+ // env[returns[VALUE]][STATS][RETURNS][0]
351
453
  // this seems to be able to be deleted
352
454
  // env[name][STATS][TYPE_PROP][1] =
353
455
  // env[returns[VALUE]][STATS][RETURNS][1]
354
456
  })
355
- env[name][STATS][RETURNS] =
356
- env[returns[VALUE]][STATS][RETURNS]
457
+ setReturnRef(
458
+ env[name][STATS],
459
+ env[returns[VALUE]][STATS]
460
+ )
357
461
  }
358
462
  break
359
463
  }
360
464
  }
465
+ return true
361
466
  }
362
467
  const checkReturnType = () => {
363
468
  const last = rest.at(-1).at(-1)
@@ -366,7 +471,7 @@ export const typeCheck = (ast) => {
366
471
  : last
367
472
  const rem = hasBlock(body) ? body.at(-1) : body
368
473
  const returns = isLeaf(rem) ? rem : rem[0]
369
- resolveRetunType(returns, rem, RETURNS)
474
+ return resolveRetunType(returns, rem, RETURNS)
370
475
  }
371
476
  const rightHand = rest.at(-1)
372
477
  if (
@@ -382,17 +487,16 @@ export const typeCheck = (ast) => {
382
487
  [SIGNATURE]: name,
383
488
  retried: 0,
384
489
  counter: 0,
385
- [VARIABLE_ORDER_INDEX]: env[ORDER],
490
+ // [VARIABLE_ORDER_INDEX]: env[ORDER],
386
491
  [ARG_COUNT]: n - 2,
387
492
  [ARGUMENTS]: fillUknownArgs(n - 2),
388
493
  [RETURNS]: [UNKNOWN]
389
494
  }
390
495
  }
391
-
392
- checkReturnType()
393
496
  if (
394
- env[name][STATS][RETURNS][0] === UNKNOWN &&
395
- env[name][STATS].retried < MAX_RETRY_DEFINITION
497
+ !checkReturnType() ||
498
+ (isUnknownReturn(env[name][STATS]) &&
499
+ env[name][STATS].retried < MAX_RETRY_DEFINITION)
396
500
  ) {
397
501
  env[name][STATS].retried += 1
398
502
  stack.unshift(() => {
@@ -424,7 +528,7 @@ export const typeCheck = (ast) => {
424
528
  [SIGNATURE]: name,
425
529
  retried: 0,
426
530
  counter: 0,
427
- [VARIABLE_ORDER_INDEX]: env[ORDER],
531
+ // [VARIABLE_ORDER_INDEX]: env[ORDER],
428
532
  [TYPE_PROP]: [ATOM],
429
533
  [RETURNS]: [ATOM]
430
534
  }
@@ -437,7 +541,7 @@ export const typeCheck = (ast) => {
437
541
  retried: 0,
438
542
  counter: 0,
439
543
  [SIGNATURE]: name,
440
- [VARIABLE_ORDER_INDEX]: env[ORDER],
544
+ // [VARIABLE_ORDER_INDEX]: env[ORDER],
441
545
  [TYPE_PROP]: [
442
546
  isL
443
547
  ? right[TYPE]
@@ -466,7 +570,7 @@ export const typeCheck = (ast) => {
466
570
  }
467
571
  Types.set(withScope(name, env), () => formatType(name, env))
468
572
  }
469
- root[ORDER]++
573
+ // root[ORDER]++
470
574
  }
471
575
  break
472
576
  case KEYWORDS.ANONYMOUS_FUNCTION:
@@ -521,13 +625,17 @@ export const typeCheck = (ast) => {
521
625
  // this here is a variable WORD
522
626
  // so return type of that function is that varible type
523
627
  if (copy[returns[VALUE]])
524
- ref[STATS][RETURNS] =
525
- copy[returns[VALUE]][STATS][TYPE_PROP]
628
+ setReturnToTypeRef(
629
+ ref[STATS],
630
+ copy[returns[VALUE]][STATS]
631
+ )
526
632
  else
527
633
  stack.push(() => {
528
634
  if (copy[returns[VALUE]])
529
- ref[STATS][RETURNS] =
530
- copy[returns[VALUE]][STATS][TYPE_PROP]
635
+ setReturnToTypeRef(
636
+ ref[STATS],
637
+ copy[returns[VALUE]][STATS]
638
+ )
531
639
  })
532
640
  } else {
533
641
  const ret = returns[0]
@@ -551,37 +659,35 @@ export const typeCheck = (ast) => {
551
659
  // WHY not consiter making return types for everything
552
660
  if (
553
661
  concequent &&
554
- concequent[STATS][TYPE_PROP][0] !== UNKNOWN
662
+ getType(concequent[STATS]) !== UNKNOWN
555
663
  ) {
556
- if (concequent[STATS][TYPE_PROP][0] === APPLY)
557
- ref[STATS][RETURNS] = concequent[STATS][RETURNS]
664
+ if (getType(concequent[STATS]) === APPLY)
665
+ setReturnRef(ref[STATS], concequent[STATS])
558
666
  else
559
667
  ref[STATS][RETURNS] = concequent[STATS][TYPE_PROP]
560
668
  } else if (
561
669
  alternative &&
562
- alternative[STATS][TYPE_PROP][0] !== UNKNOWN
670
+ isUnknownType(alternative[STATS])
563
671
  ) {
564
- if (alternative[STATS][TYPE_PROP][0] === APPLY)
565
- ref[STATS][RETURNS] = alternative[STATS][RETURNS]
672
+ if (getType(alternative[STATS]) === APPLY)
673
+ setReturnRef(ref[STATS], alternative[STATS])
566
674
  else
567
- ref[STATS][RETURNS] =
568
- alternative[STATS][TYPE_PROP]
675
+ setReturnToTypeRef(ref[STATS], alternative[STATS])
569
676
  } else if (concequent) {
570
- if (concequent[STATS][TYPE_PROP][0] === APPLY)
571
- ref[STATS][RETURNS] = concequent[STATS][RETURNS]
677
+ if (getType(concequent[STATS]) === APPLY)
678
+ setReturnRef(ref[STATS], concequent[STATS])
572
679
  else
573
- ref[STATS][RETURNS] = concequent[STATS][TYPE_PROP]
680
+ setReturnToTypeRef(ref[STATS], concequent[STATS])
574
681
  }
575
682
  }
576
683
  break
577
684
  default:
578
685
  if (copy[ret[VALUE]])
579
- ref[STATS][RETURNS] = copy[ret[VALUE]][STATS][RETURNS]
686
+ setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
580
687
  else
581
688
  stack.push(() => {
582
689
  if (copy[ret[VALUE]])
583
- ref[STATS][RETURNS] =
584
- copy[ret[VALUE]][STATS][RETURNS]
690
+ setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
585
691
  })
586
692
 
587
693
  break
@@ -594,483 +700,585 @@ export const typeCheck = (ast) => {
594
700
  }
595
701
  break
596
702
  default:
597
- stack.push(() => {
598
- if (env[first[VALUE]] === undefined)
599
- errorStack.add(
600
- `Trying to call undefined (lambda) ${first[VALUE]} (check #9)`
601
- )
602
- else if (
603
- env[first[VALUE]][STATS][TYPE_PROP][0] === APPLY &&
604
- env[first[VALUE]][STATS][ARG_COUNT] !== VARIADIC &&
605
- env[first[VALUE]][STATS][ARG_COUNT] !== rest.length
606
- ) {
607
- errorStack.add(
608
- `Incorrect number of arguments for (${
609
- first[VALUE]
610
- }). Expected (= ${
611
- env[first[VALUE]][STATS][ARG_COUNT]
612
- }) but got ${rest.length} (${stringifyArgs(exp)}) (check #15)`
613
- )
614
- } else {
615
- if (first[TYPE] === APPLY && !isSpecial) {
616
- if (env[first[VALUE]][STATS][TYPE_PROP][0] === ATOM) {
617
- errorStack.add(
618
- `(${first[VALUE]}) is not a (lambda) (${stringifyArgs(
619
- exp
620
- )}) (check #12)`
621
- )
622
- } else if (!env[first[VALUE]][STATS][ARG_COUNT]) {
623
- // TODO recursively take return type of applicaion
624
- // if (env[first[VALUE]][STATS][RETURNS][0] === APPLY) {
625
- // env[first[VALUE]][STATS][RETURNS] = [UNKNOWN]
626
- // }
627
- // FN ASSIGMENT
703
+ if (!STATIC_TYPES_SET.has(first[VALUE]))
704
+ stack.push(() => {
705
+ if (env[first[VALUE]] === undefined)
706
+ errorStack.add(
707
+ `Trying to call undefined (lambda) ${first[VALUE]} (check #9)`
708
+ )
709
+ else if (
710
+ env[first[VALUE]][STATS][TYPE_PROP][0] === APPLY &&
711
+ env[first[VALUE]][STATS][ARG_COUNT] !== VARIADIC &&
712
+ env[first[VALUE]][STATS][ARG_COUNT] !== rest.length
713
+ ) {
714
+ errorStack.add(
715
+ `Incorrect number of arguments for (${
716
+ first[VALUE]
717
+ }). Expected (= ${
718
+ env[first[VALUE]][STATS][ARG_COUNT]
719
+ }) but got ${rest.length} (${stringifyArgs(
720
+ exp
721
+ )}) (check #15)`
722
+ )
723
+ } else {
724
+ if (first[TYPE] === APPLY && !isSpecial) {
725
+ if (getType(env[first[VALUE]][STATS]) === ATOM) {
726
+ errorStack.add(
727
+ `(${first[VALUE]}) is not a (lambda) (${stringifyArgs(
728
+ exp
729
+ )}) (check #12)`
730
+ )
731
+ } else if (!env[first[VALUE]][STATS][ARG_COUNT]) {
732
+ // TODO recursively take return type of applicaion
733
+ // if (env[first[VALUE]][STATS][RETURNS][0] === APPLY) {
734
+ // env[first[VALUE]][STATS][RETURNS] = [UNKNOWN]
735
+ // }
736
+ // FN ASSIGMENT
628
737
 
629
- // ASSIGMENT of paramaters of lambda that are a lambda
630
- // minus one to remove the body
631
- env[first[VALUE]][STATS][TYPE_PROP] = [APPLY]
632
- env[first[VALUE]][STATS][ARG_COUNT] = rest.length
633
- env[first[VALUE]][STATS][ARGUMENTS] = fillUknownArgs(
634
- rest.length
635
- )
636
- for (let i = 0; i < rest.length; ++i) {
637
- const arg = env[first[VALUE]][STATS][ARGUMENTS]
638
- arg[i] = {
639
- [STATS]: {
640
- retried: 0,
641
- [SIGNATURE]: PLACEHOLDER,
642
- [TYPE_PROP]: [UNKNOWN],
643
- [RETURNS]: [UNKNOWN],
644
- [ARGUMENTS]: [],
645
- [ARG_COUNT]: 0
738
+ // ASSIGMENT of paramaters of lambda that are a lambda
739
+ // minus one to remove the body
740
+ env[first[VALUE]][STATS][TYPE_PROP] = [APPLY]
741
+ env[first[VALUE]][STATS][ARG_COUNT] = rest.length
742
+ env[first[VALUE]][STATS][ARGUMENTS] = fillUknownArgs(
743
+ rest.length
744
+ )
745
+ for (let i = 0; i < rest.length; ++i) {
746
+ const arg = env[first[VALUE]][STATS][ARGUMENTS]
747
+ arg[i] = {
748
+ [STATS]: {
749
+ retried: 0,
750
+ [SIGNATURE]: PLACEHOLDER,
751
+ [TYPE_PROP]: [UNKNOWN],
752
+ [RETURNS]: [UNKNOWN],
753
+ [ARGUMENTS]: [],
754
+ [ARG_COUNT]: 0
755
+ }
756
+ }
757
+ const ARG = isLeaf(rest[i]) ? rest[i] : rest[i][0]
758
+ if (!env[ARG[VALUE]]) continue
759
+ // console.log(stringifyArgs(exp), ARG)
760
+ switch (ARG[TYPE]) {
761
+ // THERE ARE NO ATOM ARGUMENTS
762
+ // case ATOM:
763
+ // break
764
+ case APPLY:
765
+ // passing arg asA APPLICATION
766
+ if (isUnknownType(arg[i][STATS]))
767
+ arg[i][STATS][TYPE_PROP] =
768
+ env[ARG[VALUE]][STATS][RETURNS]
769
+ break
770
+ case WORD:
771
+ // if param is a word we assosiate them by referanc
772
+ if (isUnknownType(arg[i][STATS]))
773
+ arg[i][STATS] = env[ARG[VALUE]][STATS]
774
+ break
646
775
  }
647
- }
648
- const ARG = isLeaf(rest[i]) ? rest[i] : rest[i][0]
649
- if (!env[ARG[VALUE]]) continue
650
- // console.log(stringifyArgs(exp), ARG)
651
- switch (ARG[TYPE]) {
652
- // THERE ARE NO ATOM ARGUMENTS
653
- // case ATOM:
654
- // break
655
- case APPLY:
656
- // passing arg asA APPLICATION
657
- if (arg[i][STATS][TYPE_PROP][0] === UNKNOWN)
658
- arg[i][STATS][TYPE_PROP] =
659
- env[ARG[VALUE]][STATS][RETURNS]
660
- break
661
- case WORD:
662
- // if param is a word we assosiate them by referanc
663
- if (arg[i][STATS][TYPE_PROP][0] === UNKNOWN)
664
- arg[i][STATS] = env[ARG[VALUE]][STATS]
665
- break
666
776
  }
667
777
  }
668
778
  }
669
- }
670
- // also type of arg
671
- const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
672
- for (let i = 0; i < args.length; ++i) {
673
- const isRestILeaf = isLeaf(rest[i])
674
- // type check
675
- // TODO get rof pred type
676
- // const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
677
- const MAIN_TYPE = args[i][STATS][TYPE_PROP][0]
678
-
679
- if (first[TYPE] === APPLY && isSpecial) {
680
- if (
681
- MAIN_TYPE === ATOM &&
682
- PREDICATES_INPUT_SET.has(first[VALUE])
683
- ) {
779
+ // also type of arg
780
+ const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
781
+ for (let i = 0; i < args.length; ++i) {
782
+ const isRestILeaf = isLeaf(rest[i])
783
+ // type check
784
+ // TODO get rof pred type
785
+ // const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
786
+ const MAIN_TYPE = getType(args[i][STATS])
787
+ if (MAIN_TYPE === ANY) continue
788
+ if (first[TYPE] === APPLY && isSpecial) {
684
789
  if (
685
- !isRestILeaf &&
686
- rest[i][0][TYPE] === APPLY &&
687
- rest[i][0][VALUE] === KEYWORDS.CALL_FUNCTION
790
+ MAIN_TYPE === ATOM &&
791
+ PREDICATES_INPUT_SET.has(first[VALUE])
688
792
  ) {
689
- if (isLeaf(rest[i].at(-1))) {
690
- const fnName = rest[i].at(-1)[VALUE]
691
- const fn = env[fnName]
692
- if (fn && fn[STATS][RETURNS][0] !== ATOM) {
693
- errorStack.add(
694
- `Incorrect type of argument (${i}) for (${
695
- first[VALUE]
696
- }). Expected (${toTypeNames(
697
- ATOM
698
- )}) but got an (${toTypeNames(
699
- fn[STATS][RETURNS][0]
700
- )}) (${stringifyArgs(exp)}) (check #26)`
701
- )
702
- }
703
- } else {
704
- const body = rest[i].at(-1).at(-1)
705
- const rem = hasBlock(body) ? body.at(-1) : body
706
- const returns = isLeaf(rem) ? rem : rem[0]
707
- if (returns[TYPE] === ATOM) {
708
- if (MAIN_TYPE !== ATOM) {
793
+ if (
794
+ !isRestILeaf &&
795
+ rest[i][0][TYPE] === APPLY &&
796
+ rest[i][0][VALUE] === KEYWORDS.CALL_FUNCTION
797
+ ) {
798
+ if (isLeaf(rest[i].at(-1))) {
799
+ const fnName = rest[i].at(-1)[VALUE]
800
+ const fn = env[fnName]
801
+ if (fn && getReturn(fn[STATS]) !== ATOM) {
709
802
  errorStack.add(
710
- `Incorrect type of argument ${i} for (${
803
+ `Incorrect type of argument (${i}) for (${
711
804
  first[VALUE]
712
805
  }). Expected (${toTypeNames(
713
- MAIN_TYPE
806
+ ATOM
714
807
  )}) but got an (${toTypeNames(
808
+ getReturn(fn[STATS])
809
+ )}) (${stringifyArgs(exp)}) (check #26)`
810
+ )
811
+ }
812
+ } else {
813
+ const body = rest[i].at(-1).at(-1)
814
+ const rem = hasBlock(body) ? body.at(-1) : body
815
+ const returns = isLeaf(rem) ? rem : rem[0]
816
+ if (returns[TYPE] === ATOM) {
817
+ if (MAIN_TYPE !== ATOM) {
818
+ errorStack.add(
819
+ `Incorrect type of argument ${i} for (${
820
+ first[VALUE]
821
+ }). Expected (${toTypeNames(
822
+ MAIN_TYPE
823
+ )}) but got an (${toTypeNames(
824
+ ATOM
825
+ )}) (${stringifyArgs(exp)}) (check #27)`
826
+ )
827
+ }
828
+ } else if (
829
+ env[returns[VALUE]] &&
830
+ !isUnknownReturn(env[returns[VALUE]][STATS]) &&
831
+ getReturn(env[returns[VALUE]][STATS]) !== ATOM
832
+ ) {
833
+ errorStack.add(
834
+ `Incorrect type of argument ${i} for (${
835
+ first[VALUE]
836
+ }). Expected (${toTypeNames(
715
837
  ATOM
716
- )}) (${stringifyArgs(exp)}) (check #27)`
838
+ )}) but got (${toTypeNames(
839
+ getReturn(env[returns[VALUE]][STATS])
840
+ )}) (${stringifyArgs(exp)}) (check #29)`
717
841
  )
718
842
  }
719
- } else if (
720
- env[returns[VALUE]] &&
721
- env[returns[VALUE]][STATS][RETURNS][0] !== ATOM
843
+ }
844
+ }
845
+ }
846
+ const isCast = STATIC_TYPES_SET.has(first[VALUE])
847
+ const expectedArgs = env[first[VALUE]][STATS][ARGUMENTS]
848
+ // IF UKNOWN andnot csted -we have nothing much to do
849
+ if (isUnknownType(expectedArgs[i][STATS]) && !isCast)
850
+ continue
851
+ if (!isRestILeaf) {
852
+ const CAR = rest[i][0][VALUE]
853
+ if (!env[CAR]) continue
854
+ const isKnown = !isUnknownReturn(env[CAR][STATS])
855
+ if (isKnown && !isCast) {
856
+ if (
857
+ !compareTypeWithReturn(
858
+ expectedArgs[i][STATS],
859
+ env[CAR][STATS]
860
+ )
722
861
  ) {
723
862
  errorStack.add(
724
- `Incorrect type of argument ${i} for (${
863
+ `Incorrect type of argument (${i}) for special form (${
725
864
  first[VALUE]
726
865
  }). Expected (${toTypeNames(
727
- ATOM
866
+ getType(expectedArgs[i][STATS])
728
867
  )}) but got (${toTypeNames(
729
- env[returns[VALUE]][STATS][TYPE_PROP]
730
- )}) (${stringifyArgs(exp)}) (check #29)`
868
+ getReturn(env[CAR][STATS])
869
+ )}) (${stringifyArgs(exp)}) (check #1)`
731
870
  )
732
871
  }
872
+ // never reached because there is only 1 subtype at the moment
873
+ // else if (
874
+ // PRED_TYPE &&
875
+ // env[CAR][STATS][RETURNS][1] !== PRED_TYPE
876
+ // ) {
877
+ // }
878
+ } else if (!isKnown && !isCast) {
879
+ if (env[CAR] && getType(env[CAR][STATS]) === APPLY) {
880
+ switch (first[VALUE]) {
881
+ case KEYWORDS.IF:
882
+ break
883
+ case KEYWORDS.CALL_FUNCTION:
884
+ break
885
+ default:
886
+ // console.log(stringifyArgs(exp))
887
+ // TODO fix this assigment
888
+ // It turns out it's not possible to determine return type of function here
889
+ // what if it's a global function used elsewhere where the return type mwould be different
890
+ // THIS willgive lambda return types but refactor is needed still
891
+ setReturn(
892
+ env[CAR][STATS],
893
+ expectedArgs[i][STATS]
894
+ )
895
+ break
896
+ }
897
+ }
898
+
899
+ // TODO also handle casting
900
+ }
901
+ } else {
902
+ switch (rest[i][TYPE]) {
903
+ case WORD:
904
+ {
905
+ const CAR = rest[i][VALUE]
906
+ if (!env[CAR]) continue
907
+ const isKnown = !isUnknownType(env[CAR][STATS])
908
+ if (isKnown && !isCast) {
909
+ if (
910
+ !compareTypes(
911
+ expectedArgs[i][STATS],
912
+ env[CAR][STATS]
913
+ )
914
+ ) {
915
+ errorStack.add(
916
+ `Incorrect type of argument (${i}) for special form (${
917
+ first[VALUE]
918
+ }). Expected (${toTypeNames(
919
+ getType(expectedArgs[i][STATS])
920
+ )}) but got (${toTypeNames(
921
+ getType(env[CAR][STATS])
922
+ )}) (${stringifyArgs(exp)}) (check #3)`
923
+ )
924
+ }
925
+ } else if (env[CAR]) {
926
+ if (isCast) {
927
+ // CAST assigment
928
+ setTypeToReturn(
929
+ env[rest[i][VALUE]][STATS],
930
+ root[first[VALUE]][STATS]
931
+ )
932
+ // root[first[VALUE]][STATS][RETURNS] =
933
+ // root[first[VALUE]][STATS][RETURNS]
934
+ } else {
935
+ // VALUE assigment
936
+ setType(
937
+ env[CAR][STATS],
938
+ expectedArgs[i][STATS]
939
+ )
940
+ // env[CAR][STATS][TYPE_PROP][0] =
941
+ // expectedArgs[i][STATS][TYPE_PROP][0]
942
+ }
943
+ }
944
+ }
945
+ break
946
+ case ATOM: {
947
+ if (
948
+ rest[i][TYPE] !==
949
+ expectedArgs[i][STATS][TYPE_PROP][0]
950
+ ) {
951
+ errorStack.add(
952
+ `Incorrect type of argument (${i}) for special form (${
953
+ first[VALUE]
954
+ }). Expected (${toTypeNames(
955
+ expectedArgs[i][STATS][TYPE_PROP][0]
956
+ )}) but got (${toTypeNames(
957
+ rest[i][TYPE]
958
+ )}) (${stringifyArgs(exp)}) (check #2)`
959
+ )
960
+ }
961
+ break
962
+ }
733
963
  }
734
964
  }
735
965
  }
736
- const isCast = STATIC_TYPES_SET.has(first[VALUE])
737
- const expectedArgs = env[first[VALUE]][STATS][ARGUMENTS]
738
- const EXPECTED_TYPE = expectedArgs[i][STATS][TYPE_PROP][0]
739
- // IF UKNOWN andnot csted -we have nothing much to do
740
- if (EXPECTED_TYPE === UNKNOWN && !isCast) continue
741
- if (!isRestILeaf) {
742
- const CAR = rest[i][0][VALUE]
743
- const isKnown =
744
- env[CAR] && env[CAR][STATS][RETURNS][0] !== UNKNOWN
745
- if (isKnown && !isCast) {
746
- if (env[CAR][STATS][RETURNS][0] !== EXPECTED_TYPE) {
966
+ // type checking
967
+ else if (isRestILeaf) {
968
+ const T =
969
+ rest[i][TYPE] === WORD
970
+ ? env[rest[i][VALUE]]
971
+ ? getType(env[rest[i][VALUE]][STATS])
972
+ : UNKNOWN
973
+ : rest[i][TYPE]
974
+ if (
975
+ T === ATOM &&
976
+ !isUnknownType(args[i][STATS]) &&
977
+ getType(args[i][STATS]) !== ATOM
978
+ ) {
979
+ errorStack.add(
980
+ `Incorrect type of arguments ${i} for (${
981
+ first[VALUE]
982
+ }). Expected (${toTypeNames(
983
+ getType(args[i][STATS])
984
+ )}) but got (${toTypeNames(T)}) (${stringifyArgs(
985
+ exp
986
+ )}) (check #10)`
987
+ )
988
+ } else if (
989
+ T === APPLY &&
990
+ !isUnknownType(args[i][STATS]) &&
991
+ !isUnknownType(env[rest[i][VALUE]][STATS]) &&
992
+ env[rest[i][VALUE]][STATS][ARG_COUNT] !== VARIADIC
993
+ ) {
994
+ // Handles words that are Lambdas
995
+ if (
996
+ env[rest[i][VALUE]][STATS][ARG_COUNT] !==
997
+ args[i][STATS][ARG_COUNT]
998
+ ) {
747
999
  errorStack.add(
748
- `Incorrect type of argument (${i}) for special form (${
1000
+ `Incorrect number of arguments for (${
1001
+ args[i][STATS][SIGNATURE]
1002
+ }) the (lambda) argument of (${
749
1003
  first[VALUE]
750
- }). Expected (${toTypeNames(
751
- EXPECTED_TYPE
752
- )}) but got (${toTypeNames(
753
- env[CAR][STATS][RETURNS][0]
754
- )}) (${stringifyArgs(exp)}) (check #1)`
1004
+ }) at position (${i}). Expected (= ${
1005
+ args[i][STATS][ARG_COUNT]
1006
+ }) but got ${
1007
+ env[rest[i][VALUE]][STATS][ARG_COUNT]
1008
+ } (${stringifyArgs(exp)}) (check #778)`
755
1009
  )
756
- }
757
- // never reached because there is only 1 subtype at the moment
758
- // else if (
759
- // PRED_TYPE &&
760
- // env[CAR][STATS][RETURNS][1] !== PRED_TYPE
761
- // ) {
762
- // }
763
- } else if (!isKnown && !isCast && env[CAR]) {
764
- if (
765
- env[CAR][STATS][TYPE_PROP][0] === APPLY &&
766
- root[first[VALUE]][STATS][RETURNS][0] !== UNKNOWN &&
767
- env[CAR][STATS][RETURNS][0] !== UNKNOWN
768
- )
769
- env[CAR][STATS][RETURNS][0] =
770
- root[first[VALUE]][STATS][RETURNS][0]
771
- // TODO also handle casting
772
- }
773
- } else {
774
- switch (rest[i][TYPE]) {
775
- case WORD:
776
- {
777
- const CAR = rest[i][VALUE]
778
- const isKnown =
779
- env[CAR] &&
780
- env[CAR][STATS][TYPE_PROP][0] !== UNKNOWN
781
- if (isKnown && !isCast) {
1010
+ } else {
1011
+ // DEFINED LAMBDAS TYPE CHECKING
1012
+ // #C1
1013
+ // TODO delete this maybe
1014
+ // It will not be possilbe to know return type
1015
+ const match1 = () => {
1016
+ const actual = env[rest[i][VALUE]]
1017
+ const expected = args[i]
1018
+ if (
1019
+ !isUnknownReturn(expected[STATS]) &&
1020
+ !isUnknownReturn(actual[STATS]) &&
1021
+ !compareReturns(expected[STATS], actual[STATS])
1022
+ ) {
1023
+ errorStack.add(
1024
+ `Incorrect return type for (${
1025
+ expected[STATS][SIGNATURE]
1026
+ }) the (lambda) argument of (${
1027
+ first[VALUE]
1028
+ }) at position (${i}). Expected (${toTypeNames(
1029
+ getReturn(expected[STATS])
1030
+ )}) but got (${toTypeNames(
1031
+ getReturn(actual[STATS])
1032
+ )}) (${stringifyArgs(exp)}) (check #782)`
1033
+ )
1034
+ } else if (
1035
+ actual[STATS].retried < MAX_RETRY_DEFINITION
1036
+ ) {
1037
+ actual[STATS].retried += 1
1038
+ stack.unshift(() => match1())
1039
+ }
1040
+ }
1041
+ match1()
1042
+ for (
1043
+ let j = 0;
1044
+ j < args[i][STATS][ARGUMENTS].length;
1045
+ ++j
1046
+ ) {
1047
+ const match2 = () => {
1048
+ const actual =
1049
+ env[rest[i][VALUE]][STATS][ARGUMENTS][j]
1050
+ const expected = args[i][STATS][ARGUMENTS][j]
782
1051
  if (
783
- EXPECTED_TYPE !== env[CAR][STATS][TYPE_PROP][0]
784
- ) {
1052
+ !isUnknownType(actual[STATS]) &&
1053
+ !isUnknownType(expected[STATS]) &&
1054
+ !compareTypes(actual[STATS], expected[STATS])
1055
+ )
785
1056
  errorStack.add(
786
- `Incorrect type of argument (${i}) for special form (${
787
- first[VALUE]
1057
+ `Incorrect type for (lambda) (${
1058
+ args[i][STATS][SIGNATURE]
1059
+ }) argument at position (${j}) named as (${
1060
+ actual[STATS][SIGNATURE]
788
1061
  }). Expected (${toTypeNames(
789
- EXPECTED_TYPE
1062
+ getType(expected[STATS])
790
1063
  )}) but got (${toTypeNames(
791
- env[CAR][STATS][TYPE_PROP][0]
792
- )}) (${stringifyArgs(exp)}) (check #3)`
1064
+ getType(actual[STATS])
1065
+ )}) (${stringifyArgs(exp)}) (check #781)`
793
1066
  )
794
- }
795
- } else if (env[CAR]) {
796
- if (isCast) {
797
- // CAST assigment
798
- env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
799
- root[first[VALUE]][STATS][RETURNS][0]
800
-
801
- // root[first[VALUE]][STATS][RETURNS] =
802
- // root[first[VALUE]][STATS][RETURNS]
803
- } else {
804
- // VALUE assigment
805
- env[CAR][STATS][TYPE_PROP][0] = EXPECTED_TYPE
1067
+ else if (
1068
+ actual[STATS].retried < MAX_RETRY_DEFINITION
1069
+ ) {
1070
+ actual[STATS].retried += 1
1071
+ stack.unshift(() => match2())
806
1072
  }
807
1073
  }
1074
+ match2()
808
1075
  }
809
- break
810
- case ATOM: {
811
- if (rest[i][TYPE] !== EXPECTED_TYPE) {
812
- errorStack.add(
813
- `Incorrect type of argument (${i}) for special form (${
814
- first[VALUE]
815
- }). Expected (${toTypeNames(
816
- EXPECTED_TYPE
817
- )}) but got (${toTypeNames(
818
- rest[i][TYPE]
819
- )}) (${stringifyArgs(exp)}) (check #2)`
820
- )
821
- }
822
- break
823
1076
  }
824
1077
  }
825
- }
826
- }
827
- // type checking
828
- else if (isRestILeaf) {
829
- const T =
830
- rest[i][TYPE] === WORD && env[rest[i][VALUE]]
831
- ? env[rest[i][VALUE]][STATS][TYPE_PROP][0]
832
- : rest[i][TYPE]
833
- if (
834
- T === ATOM &&
835
- args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
836
- args[i][STATS][TYPE_PROP][0] !== ATOM
837
- ) {
838
- errorStack.add(
839
- `Incorrect type of arguments ${i} for (${
840
- first[VALUE]
841
- }). Expected (${toTypeNames(
842
- args[i][STATS][TYPE_PROP][0]
843
- )}) but got (${toTypeNames(T)}) (${stringifyArgs(
844
- exp
845
- )}) (check #10)`
846
- )
847
- } else if (
848
- T === APPLY &&
849
- args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
850
- env[rest[i][VALUE]][STATS][TYPE_PROP][0] !== UNKNOWN &&
851
- env[rest[i][VALUE]][STATS][ARG_COUNT] !== VARIADIC
852
- ) {
853
- // Handles words that are Lambdas
854
1078
  if (
855
- env[rest[i][VALUE]][STATS][ARG_COUNT] !==
856
- args[i][STATS][ARG_COUNT]
1079
+ T === COLLECTION &&
1080
+ env[rest[i][VALUE]] &&
1081
+ !isUnknownType(env[rest[i][VALUE]][STATS]) &&
1082
+ !isUnknownType(args[i][STATS]) &&
1083
+ !compareTypes(
1084
+ env[rest[i][VALUE]][STATS],
1085
+ args[i][STATS]
1086
+ )
857
1087
  ) {
858
1088
  errorStack.add(
859
- `Incorrect number of arguments for (${
860
- args[i][STATS][SIGNATURE]
861
- }) the (lambda) argument of (${
1089
+ `Incorrect type of arguments ${i} for (${
862
1090
  first[VALUE]
863
- }) at position (${i}). Expected (= ${
864
- args[i][STATS][ARG_COUNT]
865
- }) but got ${
866
- env[rest[i][VALUE]][STATS][ARG_COUNT]
867
- } (${stringifyArgs(exp)}) (check #778)`
1091
+ }). Expected (${toTypeNames(
1092
+ getType(args[i][STATS])
1093
+ )}) but got (${toTypeNames(T)}) (${stringifyArgs(
1094
+ exp
1095
+ )}) (check #30)`
868
1096
  )
869
- }
870
- }
871
- if (
872
- T === COLLECTION &&
873
- env[rest[i][VALUE]] &&
874
- env[rest[i][VALUE]][STATS][TYPE_PROP][0] !== UNKNOWN &&
875
- args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
876
- env[rest[i][VALUE]][STATS][TYPE_PROP][0] !==
877
- args[i][STATS][TYPE_PROP][0]
878
- ) {
879
- errorStack.add(
880
- `Incorrect type of arguments ${i} for (${
881
- first[VALUE]
882
- }). Expected (${toTypeNames(
883
- args[i][STATS][TYPE_PROP][0]
884
- )}) but got (${toTypeNames(T)}) (${stringifyArgs(
885
- exp
886
- )}) (check #30)`
887
- )
888
- } else if (
889
- args[i][STATS][TYPE_PROP][0] === UNKNOWN &&
890
- args[i][STATS].retried < MAX_RETRY_DEFINITION
891
- ) {
892
- args[i][STATS].retried += 1
893
- stack.unshift(() => check(exp, env, scope))
894
- } else {
895
- if (
896
- env[rest[i][VALUE]] &&
897
- args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
898
- env[rest[i][VALUE]][STATS][TYPE_PROP][0] === UNKNOWN &&
899
- args[i][STATS][TYPE_PROP][0] !== APPLY
1097
+ } else if (
1098
+ isUnknownType(args[i][STATS]) &&
1099
+ args[i][STATS].retried < MAX_RETRY_DEFINITION
900
1100
  ) {
901
- // REFF ASSIGMENT
902
- env[rest[i][VALUE]][STATS][TYPE_PROP] =
903
- args[i][STATS][TYPE_PROP]
904
- env[rest[i][VALUE]][STATS][RETURNS] =
905
- args[i][STATS][RETURNS]
906
- }
907
- }
908
- } else if (env[rest[i][0][VALUE]]) {
909
- const match = () => {
910
- const actual = env[rest[i][0][VALUE]][STATS][RETURNS]
911
- const expected = args[i][STATS][TYPE_PROP]
912
- if (args[i][STATS].counter < MAX_ARGUMENT_RETRY) {
913
- args[i][STATS].counter++
914
- stack.unshift(() => match())
1101
+ args[i][STATS].retried += 1
1102
+ stack.unshift(() => check(exp, env, scope))
1103
+ } else {
1104
+ if (
1105
+ env[rest[i][VALUE]] &&
1106
+ !isUnknownType(args[i][STATS]) &&
1107
+ isUnknownType(env[rest[i][VALUE]][STATS]) &&
1108
+ getType(args[i][STATS]) !== APPLY
1109
+ ) {
1110
+ // REFF ASSIGMENT
1111
+ env[rest[i][VALUE]][STATS][TYPE_PROP] =
1112
+ args[i][STATS][TYPE_PROP]
1113
+ env[rest[i][VALUE]][STATS][RETURNS] =
1114
+ args[i][STATS][RETURNS]
1115
+ }
915
1116
  }
916
- if (expected[0] !== UNKNOWN && actual[0] !== UNKNOWN) {
917
- if (expected[0] !== actual[0])
918
- errorStack.add(
919
- `Incorrect type of arguments ${i} for (${
920
- first[VALUE]
921
- }). Expected (${toTypeNames(
922
- expected[0]
923
- )}) but got (${toTypeNames(
924
- actual[0]
925
- )}) (${stringifyArgs(exp)}) (check #16)`
926
- )
927
- else {
928
- switch (expected[0]) {
929
- // almost exclusively for anonymous lambdas
930
- case APPLY:
931
- {
932
- const argsN = rest[i].length - 2
933
- if (
934
- env[rest[i][0][VALUE]][STATS][SIGNATURE] ===
935
- KEYWORDS.ANONYMOUS_FUNCTION
936
- ) {
937
- if (argsN !== args[i][STATS][ARG_COUNT]) {
938
- errorStack.add(
939
- `Incorrect number of arguments for (${
940
- args[i][STATS][SIGNATURE]
941
- }) the (lambda) argument of (${
942
- first[VALUE]
943
- }) at position (${i}). Expected (= ${
944
- args[i][STATS][ARG_COUNT]
945
- }) but got ${argsN} (${stringifyArgs(
946
- exp
947
- )}) (check #777)`
948
- )
949
- } else {
950
- // ANONYMOUS LAMBDAS TYPE CHECKING
951
- const local = Object.create(env)
952
- const lambdaName = `lambda::annonymous::${i}::${performance
953
- .now()
954
- .toString()
955
- .replace('.', 0)}*`
956
- check(
957
- [
958
- [APPLY, KEYWORDS.DEFINE_VARIABLE],
959
- [WORD, lambdaName],
960
- rest[i]
961
- ],
962
- local,
963
- scope
964
- )
965
- const match1 = () => {
966
- const actual = local[lambdaName]
967
- const expected = args[i]
968
- if (
969
- expected[STATS][RETURNS][0] !==
970
- UNKNOWN &&
971
- actual[STATS][RETURNS][0] !== UNKNOWN &&
972
- expected[STATS][RETURNS][0] !==
973
- actual[STATS][RETURNS][0]
974
- ) {
975
- errorStack.add(
976
- `Incorrect return type for (${
977
- expected[STATS][SIGNATURE]
978
- }) the (lambda) argument of (${
979
- first[VALUE]
980
- }) at position (${i}). Expected (${toTypeNames(
981
- expected[STATS][RETURNS][0]
982
- )}) but got (${toTypeNames(
983
- actual[STATS][RETURNS][0]
984
- )}) (${stringifyArgs(
985
- exp
986
- )}) (check #779)`
987
- )
988
- } else if (
989
- actual[STATS].retried <
990
- MAX_RETRY_DEFINITION
991
- ) {
992
- actual[STATS].retried += 1
993
- stack.unshift(() => match1())
994
- }
995
- }
996
- match1()
997
- for (
998
- let j = 0;
999
- j < args[i][STATS][ARGUMENTS].length;
1000
- ++j
1001
- ) {
1002
- const match2 = () => {
1003
- const actual =
1004
- local[lambdaName][STATS][ARGUMENTS][j]
1005
- const expected =
1006
- args[i][STATS][ARGUMENTS][j]
1117
+ } else if (env[rest[i][0][VALUE]]) {
1118
+ const match = () => {
1119
+ const actual = env[rest[i][0][VALUE]][STATS]
1120
+ const expected = args[i][STATS]
1121
+ if (args[i][STATS].counter < MAX_ARGUMENT_RETRY) {
1122
+ args[i][STATS].counter++
1123
+ stack.unshift(() => match())
1124
+ }
1125
+ if (
1126
+ !isUnknownType(expected) &&
1127
+ !isUnknownReturn(actual)
1128
+ ) {
1129
+ if (!compareTypeWithReturn(expected, actual)) {
1130
+ errorStack.add(
1131
+ `Incorrect type of arguments ${i} for (${
1132
+ first[VALUE]
1133
+ }). Expected (${toTypeNames(
1134
+ getType(expected)
1135
+ )}) but got (${toTypeNames(
1136
+ getReturn(actual)
1137
+ )}) (${stringifyArgs(exp)}) (check #16)`
1138
+ )
1139
+ } else {
1140
+ switch (getType(expected)) {
1141
+ // almost exclusively for anonymous lambdas
1142
+ case APPLY:
1143
+ {
1144
+ const argsN = rest[i].length - 2
1145
+ if (
1146
+ env[rest[i][0][VALUE]][STATS][SIGNATURE] ===
1147
+ KEYWORDS.ANONYMOUS_FUNCTION
1148
+ ) {
1149
+ if (argsN !== args[i][STATS][ARG_COUNT]) {
1150
+ errorStack.add(
1151
+ `Incorrect number of arguments for (${
1152
+ args[i][STATS][SIGNATURE]
1153
+ }) the (lambda) argument of (${
1154
+ first[VALUE]
1155
+ }) at position (${i}). Expected (= ${
1156
+ args[i][STATS][ARG_COUNT]
1157
+ }) but got ${argsN} (${stringifyArgs(
1158
+ exp
1159
+ )}) (check #777)`
1160
+ )
1161
+ } else {
1162
+ // ANONYMOUS LAMBDAS TYPE CHECKING
1163
+ const local = Object.create(env)
1164
+ const lambdaName = `lambda::annonymous::${i}::${performance
1165
+ .now()
1166
+ .toString()
1167
+ .replace('.', 0)}*`
1168
+ check(
1169
+ [
1170
+ [APPLY, KEYWORDS.DEFINE_VARIABLE],
1171
+ [WORD, lambdaName],
1172
+ rest[i]
1173
+ ],
1174
+ local,
1175
+ scope
1176
+ )
1177
+ // TODO delete this maybe
1178
+ // #C2
1179
+ // It will not be possilbe to know return type
1180
+ const match1 = () => {
1181
+ const actual = local[lambdaName]
1182
+ const expected = args[i]
1007
1183
  if (
1008
- actual[STATS][TYPE_PROP][0] !==
1009
- UNKNOWN &&
1010
- expected[STATS][TYPE_PROP][0] !==
1011
- UNKNOWN &&
1012
- actual[STATS][TYPE_PROP][0] !==
1013
- expected[STATS][TYPE_PROP][0]
1014
- )
1184
+ !isUnknownReturn(expected[STATS]) &&
1185
+ !isUnknownReturn(actual[STATS]) &&
1186
+ !compareReturns(
1187
+ expected[STATS],
1188
+ actual[STATS]
1189
+ )
1190
+ ) {
1015
1191
  errorStack.add(
1016
- `Incorrect type for (lambda) (${
1017
- args[i][STATS][SIGNATURE]
1018
- }) argument at position (${j}) named as (${
1019
- local[lambdaName][STATS][
1020
- ARGUMENTS
1021
- ][j][STATS][SIGNATURE]
1022
- }). Expected (${toTypeNames(
1023
- args[i][STATS][ARGUMENTS][j][
1024
- STATS
1025
- ][TYPE_PROP][0]
1192
+ `Incorrect return type for (${
1193
+ expected[STATS][SIGNATURE]
1194
+ }) the (lambda) argument of (${
1195
+ first[VALUE]
1196
+ }) at position (${i}). Expected (${toTypeNames(
1197
+ getReturn(expected[STATS])
1026
1198
  )}) but got (${toTypeNames(
1027
- local[lambdaName][STATS][
1028
- ARGUMENTS
1029
- ][j][STATS][TYPE_PROP][0]
1199
+ getReturn(actual[STATS])
1030
1200
  )}) (${stringifyArgs(
1031
1201
  exp
1032
- )}) (check #780)`
1202
+ )}) (check #779)`
1033
1203
  )
1034
- else if (
1204
+ } else if (
1035
1205
  actual[STATS].retried <
1036
1206
  MAX_RETRY_DEFINITION
1037
1207
  ) {
1038
1208
  actual[STATS].retried += 1
1039
- stack.unshift(() => match2())
1209
+ stack.unshift(() => match1())
1210
+ }
1211
+ }
1212
+ match1()
1213
+ for (
1214
+ let j = 0;
1215
+ j < args[i][STATS][ARGUMENTS].length;
1216
+ ++j
1217
+ ) {
1218
+ const match2 = () => {
1219
+ const actual =
1220
+ local[lambdaName][STATS][ARGUMENTS][
1221
+ j
1222
+ ]
1223
+ const expected =
1224
+ args[i][STATS][ARGUMENTS][j]
1225
+ if (
1226
+ !isUnknownType(actual[STATS]) &&
1227
+ !isUnknownType(expected[STATS]) &&
1228
+ !compareTypes(
1229
+ actual[STATS],
1230
+ expected[STATS]
1231
+ )
1232
+ ) {
1233
+ errorStack.add(
1234
+ `Incorrect type for (lambda) (${
1235
+ args[i][STATS][SIGNATURE]
1236
+ }) argument at position (${j}) named as (${
1237
+ local[lambdaName][STATS][
1238
+ ARGUMENTS
1239
+ ][j][STATS][SIGNATURE]
1240
+ }). Expected (${toTypeNames(
1241
+ getType(expected[STATS])
1242
+ )}) but got (${toTypeNames(
1243
+ getType(actual[STATS])
1244
+ )}) (${stringifyArgs(
1245
+ exp
1246
+ )}) (check #780)`
1247
+ )
1248
+ } else if (
1249
+ actual[STATS].retried <
1250
+ MAX_RETRY_DEFINITION
1251
+ ) {
1252
+ actual[STATS].retried += 1
1253
+ stack.unshift(() => match2())
1254
+ }
1040
1255
  }
1256
+ match2()
1041
1257
  }
1042
- match2()
1043
1258
  }
1044
- // console.log(
1045
- // env[first[VALUE]][STATS][ARGUMENTS][i][
1046
- // STATS
1047
- // ],
1048
- // args[i][STATS]
1049
- // )
1259
+ } else {
1260
+ // TODO fix curry: lambdas enter here as undefined
1050
1261
  }
1051
- } else {
1052
- // TODO fix curry: lambdas enter here as undefined
1053
1262
  }
1054
- }
1055
- break
1056
- // case ATOM:
1057
- // case COLLECTION:
1058
- // break
1263
+ break
1264
+ // case ATOM:
1265
+ // case COLLECTION:
1266
+ // break
1267
+ }
1059
1268
  }
1269
+ } else if (
1270
+ isUnknownType(expected) &&
1271
+ args[i][STATS].retried < MAX_RETRY_DEFINITION
1272
+ ) {
1273
+ args[i][STATS].retried += 1
1274
+ stack.unshift(() => match())
1060
1275
  }
1061
- } else if (
1062
- expected[0] === UNKNOWN &&
1063
- args[i][STATS].retried < MAX_RETRY_DEFINITION
1064
- ) {
1065
- args[i][STATS].retried += 1
1066
- stack.unshift(() => match())
1067
1276
  }
1277
+ match()
1068
1278
  }
1069
- match()
1070
1279
  }
1071
1280
  }
1072
- }
1073
- })
1281
+ })
1074
1282
  for (let i = 0; i < rest.length; ++i) {
1075
1283
  const r = rest[i]
1076
1284
  if (isLeaf(r) && r[TYPE] !== ATOM) {
@@ -1094,8 +1302,10 @@ export const typeCheck = (ast) => {
1094
1302
  const copy = JSON.parse(JSON.stringify(ast))
1095
1303
  check(copy, root, copy)
1096
1304
  while (stack.length) stack.pop()()
1097
- const issues = [...errorStack, ...warningStack]
1098
- if (issues.length) throw new TypeError(issues.join('\n'))
1305
+ if (error) {
1306
+ const issues = [...errorStack, ...warningStack]
1307
+ if (issues.length) throw new TypeError(issues.join('\n'))
1308
+ }
1099
1309
  return [ast, Types]
1100
1310
  }
1101
1311
  export const type = (ast) => typeCheck(ast)[0]