fez-lisp 1.5.84 → 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/package.json +1 -1
- package/src/check.js +86 -393
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -1,16 +1,11 @@
|
|
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
|
@@ -28,19 +23,13 @@ import {
|
|
28
23
|
SCOPE_NAME,
|
29
24
|
TYPE_PROP,
|
30
25
|
SIGNATURE,
|
31
|
-
PREDICATE,
|
32
|
-
COLLECTION,
|
33
26
|
MAX_RETRY_DEFINITION,
|
34
27
|
MAX_ARGUMENT_RETRY,
|
35
28
|
ORDER,
|
36
|
-
VARIABLE_ORDER_INDEX
|
29
|
+
VARIABLE_ORDER_INDEX,
|
30
|
+
COLLECTION
|
37
31
|
} from './types.js'
|
38
|
-
import {
|
39
|
-
getSuffix,
|
40
|
-
hasApplyLambdaBlock,
|
41
|
-
hasBlock,
|
42
|
-
stringifyArgs
|
43
|
-
} from './utils.js'
|
32
|
+
import { hasApplyLambdaBlock, hasBlock, stringifyArgs } from './utils.js'
|
44
33
|
|
45
34
|
export const identity = (name) => [
|
46
35
|
[0, 'let'],
|
@@ -94,18 +83,15 @@ export const formatType = (name, env) => {
|
|
94
83
|
`${
|
95
84
|
x[STATS][TYPE_PROP][0] === APPLY
|
96
85
|
? `${formatType(i, stats[ARGUMENTS])}`
|
97
|
-
: `${toTypeNames(
|
98
|
-
x[STATS][TYPE_PROP][1] ?? x[STATS][TYPE_PROP][0]
|
99
|
-
)}`
|
86
|
+
: `${toTypeNames(x[STATS][TYPE_PROP][0])}`
|
100
87
|
}`
|
101
88
|
)
|
102
89
|
.join(' ')
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
)})`
|
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])})`
|
109
95
|
: name
|
110
96
|
}
|
111
97
|
const formatTypes = (env) => {
|
@@ -157,37 +143,6 @@ export const typeCheck = (ast) => {
|
|
157
143
|
errorStack.add(
|
158
144
|
`Trying to access undefined variable ${first[VALUE]} (check #11)`
|
159
145
|
)
|
160
|
-
} else {
|
161
|
-
const T = env[first[VALUE]][STATS]
|
162
|
-
const isKnown = T[TYPE_PROP][0] !== UNKNOWN
|
163
|
-
switch (first[VALUE]) {
|
164
|
-
case 'xs':
|
165
|
-
case 'arr':
|
166
|
-
case 'matrix':
|
167
|
-
case 'table':
|
168
|
-
if (isKnown && T[TYPE_PROP][0] !== COLLECTION) {
|
169
|
-
warningStack.add(
|
170
|
-
`A variable named ${first[VALUE]} must be of type (${
|
171
|
-
STATIC_TYPES.COLLECTION
|
172
|
-
}) but got type (${toTypeNames(
|
173
|
-
T[TYPE_PROP][0]
|
174
|
-
)}) (check #32)`
|
175
|
-
)
|
176
|
-
}
|
177
|
-
//else T[TYPE_PROP] = [COLLECTION]
|
178
|
-
break
|
179
|
-
default:
|
180
|
-
{
|
181
|
-
const isPredicate =
|
182
|
-
getSuffix(first[VALUE]) === PREDICATE_SUFFIX
|
183
|
-
if (isPredicate) {
|
184
|
-
// PRED ASSIGMENT
|
185
|
-
if (isKnown) T[TYPE_PROP][1] = PREDICATE
|
186
|
-
T[RETURNS] = [ATOM, PREDICATE]
|
187
|
-
}
|
188
|
-
}
|
189
|
-
break
|
190
|
-
}
|
191
146
|
}
|
192
147
|
})
|
193
148
|
}
|
@@ -208,7 +163,7 @@ export const typeCheck = (ast) => {
|
|
208
163
|
)
|
209
164
|
} else {
|
210
165
|
const name = rest[0][VALUE]
|
211
|
-
const resolveRetunType = (returns, rem, prop
|
166
|
+
const resolveRetunType = (returns, rem, prop) => {
|
212
167
|
if (returns[TYPE] === ATOM) {
|
213
168
|
// ATOM ASSIGMENT
|
214
169
|
env[name][STATS][prop][0] = ATOM
|
@@ -222,14 +177,6 @@ export const typeCheck = (ast) => {
|
|
222
177
|
// ATOM ASSIGMENT
|
223
178
|
env[name][STATS][prop][0] = ATOM
|
224
179
|
env[name][STATS][RETURNS][0] = ATOM
|
225
|
-
if (
|
226
|
-
getSuffix(re[0][VALUE]) === PREDICATE_SUFFIX ||
|
227
|
-
getSuffix(re[1][VALUE]) === PREDICATE_SUFFIX
|
228
|
-
) {
|
229
|
-
// ATOM ASSIGMENT PREDICATE ASSIGMENT
|
230
|
-
env[name][STATS][TYPE_PROP][1] = [PREDICATE]
|
231
|
-
env[name][STATS][RETURNS] = [ATOM, PREDICATE]
|
232
|
-
}
|
233
180
|
} else if (
|
234
181
|
!isLeaf(re[0]) &&
|
235
182
|
env[re[0][0][VALUE]] &&
|
@@ -296,37 +243,15 @@ export const typeCheck = (ast) => {
|
|
296
243
|
if (isLeaf(rest.at(-1).at(-1).at(-1))) {
|
297
244
|
const fnName = rest.at(-1).at(-1).at(-1)[VALUE]
|
298
245
|
const fn = env[fnName]
|
299
|
-
if (
|
300
|
-
!isPredicate &&
|
301
|
-
fn[STATS][RETURNS][1] === PREDICATE
|
302
|
-
) {
|
303
|
-
warningStack.add(
|
304
|
-
`${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
|
305
|
-
)
|
306
|
-
} else if (
|
307
|
-
isPredicate &&
|
308
|
-
fn[STATS][RETURNS][1] !== PREDICATE
|
309
|
-
) {
|
310
|
-
warningStack.add(
|
311
|
-
`${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #25)`
|
312
|
-
)
|
313
|
-
}
|
314
246
|
env[name][STATS][TYPE_PROP][0] =
|
315
247
|
fn[STATS][RETURNS][0]
|
316
|
-
env[name][STATS][RETURNS][1] =
|
317
|
-
fn[STATS][RETURNS][1]
|
318
248
|
} else {
|
319
249
|
const [returns, rem] = drillReturnType(
|
320
250
|
rest.at(-1).at(-1).at(-1),
|
321
251
|
(returns) =>
|
322
252
|
returns[VALUE] === KEYWORDS.CALL_FUNCTION
|
323
253
|
)
|
324
|
-
resolveRetunType(
|
325
|
-
returns,
|
326
|
-
rem,
|
327
|
-
TYPE_PROP,
|
328
|
-
isPredicate
|
329
|
-
)
|
254
|
+
resolveRetunType(returns, rem, TYPE_PROP)
|
330
255
|
}
|
331
256
|
}
|
332
257
|
// ALWAYS APPLY
|
@@ -363,27 +288,6 @@ export const typeCheck = (ast) => {
|
|
363
288
|
break
|
364
289
|
}
|
365
290
|
}
|
366
|
-
if (
|
367
|
-
isPredicate &&
|
368
|
-
env[name][STATS][prop][0] !== UNKNOWN &&
|
369
|
-
env[name][STATS][RETURNS][1] !== PREDICATE
|
370
|
-
) {
|
371
|
-
warningStack.add(
|
372
|
-
`${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #7)`
|
373
|
-
)
|
374
|
-
} else if (
|
375
|
-
!isPredicate &&
|
376
|
-
env[name][STATS][RETURNS][1] === PREDICATE
|
377
|
-
) {
|
378
|
-
warningStack.add(
|
379
|
-
`${name} should end in (${PREDICATE_SUFFIX}) because it return (Predicate) (try adding ? at the end of the lambda name) (check #8)`
|
380
|
-
)
|
381
|
-
}
|
382
|
-
if (isPredicate) {
|
383
|
-
// ATOM ASSIGMENT PREDICATE ASSIGMENT
|
384
|
-
env[name][STATS][prop] = [ATOM, PREDICATE]
|
385
|
-
env[name][STATS][RETURNS] = [ATOM, PREDICATE]
|
386
|
-
}
|
387
291
|
}
|
388
292
|
const checkReturnType = () => {
|
389
293
|
const last = rest.at(-1).at(-1)
|
@@ -392,8 +296,7 @@ export const typeCheck = (ast) => {
|
|
392
296
|
: last
|
393
297
|
const rem = hasBlock(body) ? body.at(-1) : body
|
394
298
|
const returns = isLeaf(rem) ? rem : rem[0]
|
395
|
-
|
396
|
-
resolveRetunType(returns, rem, RETURNS, isPredicate)
|
299
|
+
resolveRetunType(returns, rem, RETURNS)
|
397
300
|
}
|
398
301
|
const rightHand = rest.at(-1)
|
399
302
|
if (
|
@@ -444,30 +347,7 @@ export const typeCheck = (ast) => {
|
|
444
347
|
env[name] = SPECIAL_FORMS_SET.has(rest[1][VALUE])
|
445
348
|
? structuredClone(env[rest[1][VALUE]])
|
446
349
|
: env[rest[1][VALUE]]
|
447
|
-
|
448
|
-
if (
|
449
|
-
getSuffix(rest[1][VALUE]) === PREDICATE_SUFFIX &&
|
450
|
-
getSuffix(name) !== PREDICATE_SUFFIX
|
451
|
-
)
|
452
|
-
warningStack.add(
|
453
|
-
`${name} is assigned to ${rest[1][VALUE]} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #17)`
|
454
|
-
)
|
455
|
-
else if (
|
456
|
-
getSuffix(rest[1][VALUE]) === MUTATION_SUFFIX &&
|
457
|
-
getSuffix(name) !== MUTATION_SUFFIX
|
458
|
-
)
|
459
|
-
warningStack.add(
|
460
|
-
`${name} is assigned to ${rest[1][VALUE]} which ends in (${MUTATION_SUFFIX}) so ${name} must also end in (${MUTATION_SUFFIX}) (check #18)`
|
461
|
-
)
|
462
350
|
} else if (isL && rightHand[TYPE] === ATOM) {
|
463
|
-
const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
|
464
|
-
// This never happens
|
465
|
-
// if (
|
466
|
-
// isPredicate &&
|
467
|
-
// right[VALUE] !== TRUE &&
|
468
|
-
// right[VALUE] !== FALSE
|
469
|
-
// ) {
|
470
|
-
// }
|
471
351
|
// DECLARATION of ATOM
|
472
352
|
env[name] = {
|
473
353
|
[STATS]: {
|
@@ -479,31 +359,8 @@ export const typeCheck = (ast) => {
|
|
479
359
|
[RETURNS]: [ATOM]
|
480
360
|
}
|
481
361
|
}
|
482
|
-
if (isPredicate) {
|
483
|
-
if (rightHand[VALUE] !== TRUE && rightHand !== FALSE) {
|
484
|
-
warningStack.add(
|
485
|
-
`${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but the (Atom) value is neither ${TRUE} or ${FALSE} (${stringifyArgs(
|
486
|
-
exp
|
487
|
-
)}) (check #14)`
|
488
|
-
)
|
489
|
-
} else {
|
490
|
-
// PREDICATE ASSIGMENT
|
491
|
-
env[name][STATS][TYPE_PROP][1] = PREDICATE
|
492
|
-
env[name][STATS][RETURNS] = [ATOM, PREDICATE]
|
493
|
-
}
|
494
|
-
}
|
495
362
|
} else {
|
496
363
|
const right = rightHand[0]
|
497
|
-
const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
|
498
|
-
if (
|
499
|
-
right &&
|
500
|
-
right[VALUE] &&
|
501
|
-
getSuffix(right[VALUE]) === PREDICATE_SUFFIX &&
|
502
|
-
!isPredicate
|
503
|
-
)
|
504
|
-
warningStack.add(
|
505
|
-
`${name} is assigned to ${right[VALUE]} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #19)`
|
506
|
-
)
|
507
364
|
//DECLARATION
|
508
365
|
env[name] = {
|
509
366
|
[STATS]: {
|
@@ -520,31 +377,11 @@ export const typeCheck = (ast) => {
|
|
520
377
|
[RETURNS]: [UNKNOWN]
|
521
378
|
}
|
522
379
|
}
|
523
|
-
if (isPredicate) {
|
524
|
-
// PREDICATE ASSIGMENT
|
525
|
-
env[name][STATS][TYPE_PROP][1] = PREDICATE
|
526
|
-
env[name][STATS][RETURNS] = [ATOM, PREDICATE]
|
527
|
-
}
|
528
380
|
if (right && right[VALUE]) {
|
529
381
|
if (right[VALUE] === KEYWORDS.CALL_FUNCTION) {
|
530
382
|
if (isLeaf(rightHand.at(-1))) {
|
531
383
|
const fnName = rightHand.at(-1)[VALUE]
|
532
384
|
const fn = env[fnName]
|
533
|
-
if (
|
534
|
-
!isPredicate &&
|
535
|
-
fn[STATS][RETURNS][1] === PREDICATE
|
536
|
-
) {
|
537
|
-
warningStack.add(
|
538
|
-
`${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
|
539
|
-
)
|
540
|
-
} else if (
|
541
|
-
isPredicate &&
|
542
|
-
fn[STATS][RETURNS][1] !== PREDICATE
|
543
|
-
) {
|
544
|
-
warningStack.add(
|
545
|
-
`${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #25)`
|
546
|
-
)
|
547
|
-
}
|
548
385
|
// FB assigment
|
549
386
|
env[name][STATS][TYPE_PROP] = fn[STATS][RETURNS]
|
550
387
|
env[name][STATS][RETURNS] = fn[STATS][RETURNS]
|
@@ -552,29 +389,13 @@ export const typeCheck = (ast) => {
|
|
552
389
|
const body = rightHand.at(-1).at(-1)
|
553
390
|
const rem = hasBlock(body) ? body.at(-1) : body
|
554
391
|
const returns = isLeaf(rem) ? rem : rem[0]
|
555
|
-
resolveRetunType(returns, rem, TYPE_PROP
|
392
|
+
resolveRetunType(returns, rem, TYPE_PROP)
|
556
393
|
}
|
557
394
|
} else {
|
558
395
|
const body = rightHand
|
559
396
|
const rem = hasBlock(body) ? body.at(-1) : body
|
560
397
|
const returns = isLeaf(rem) ? rem : rem[0]
|
561
|
-
resolveRetunType(returns, rem, TYPE_PROP
|
562
|
-
}
|
563
|
-
if (env[right[VALUE]]?.[STATS]?.[RETURNS]?.[1]) {
|
564
|
-
if (
|
565
|
-
env[right[VALUE]][STATS][RETURNS][1] === PREDICATE &&
|
566
|
-
!isPredicate
|
567
|
-
) {
|
568
|
-
warningStack.add(
|
569
|
-
`${name} is assigned to the result of a (${toTypeNames(
|
570
|
-
PREDICATE
|
571
|
-
)}) so ${name} must end in (${PREDICATE_SUFFIX}) (check #23)`
|
572
|
-
)
|
573
|
-
}
|
574
|
-
|
575
|
-
// FN assigment
|
576
|
-
env[name][STATS][RETURNS] =
|
577
|
-
env[right[VALUE]][STATS][RETURNS]
|
398
|
+
resolveRetunType(returns, rem, TYPE_PROP)
|
578
399
|
}
|
579
400
|
}
|
580
401
|
}
|
@@ -629,99 +450,83 @@ export const typeCheck = (ast) => {
|
|
629
450
|
const ref = env[copy[SCOPE_NAME]]
|
630
451
|
if (ref) {
|
631
452
|
ref[STATS][ARGUMENTS][i] = copy[param[VALUE]]
|
632
|
-
|
633
|
-
|
634
|
-
|
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
|
+
})
|
635
470
|
} else {
|
636
|
-
const
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
copy[returns[VALUE]][STATS][TYPE_PROP]
|
652
|
-
})
|
653
|
-
} else {
|
654
|
-
const ret = returns[0]
|
655
|
-
switch (ret[VALUE]) {
|
656
|
-
case KEYWORDS.IF:
|
657
|
-
const re = returns.slice(2)
|
658
|
-
// If either is an ATOM then IF returns an ATOM
|
659
|
-
if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
|
660
|
-
ref[STATS][RETURNS][0] = ATOM
|
661
|
-
// TODO check that both brancehs are predicates if one is
|
662
|
-
if (
|
663
|
-
getSuffix(re[0][VALUE]) === PREDICATE_SUFFIX ||
|
664
|
-
getSuffix(re[1][VALUE]) === PREDICATE_SUFFIX
|
665
|
-
) {
|
666
|
-
ref[STATS][TYPE_PROP][1] = PREDICATE
|
667
|
-
ref[STATS][RETURNS][1] = PREDICATE
|
668
|
-
}
|
669
|
-
} else {
|
670
|
-
const concequent = isLeaf(re[0])
|
671
|
-
? copy[re[0][VALUE]]
|
672
|
-
: copy[re[0][0][VALUE]]
|
673
|
-
const alternative = isLeaf(re[1])
|
674
|
-
? copy[re[1][VALUE]]
|
675
|
-
: 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]]
|
676
486
|
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
)
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
else
|
703
|
-
ref[STATS][RETURNS] =
|
704
|
-
concequent[STATS][TYPE_PROP]
|
705
|
-
}
|
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]
|
706
512
|
}
|
513
|
+
}
|
707
514
|
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
})
|
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
|
+
})
|
719
525
|
|
720
|
-
|
721
|
-
}
|
526
|
+
break
|
722
527
|
}
|
723
|
-
// TODO overwrite return type check here
|
724
528
|
}
|
529
|
+
// TODO overwrite return type check here
|
725
530
|
}
|
726
531
|
}
|
727
532
|
check(rest.at(-1), copy, copy)
|
@@ -814,19 +619,6 @@ export const typeCheck = (ast) => {
|
|
814
619
|
)}) (${stringifyArgs(exp)}) (check #26)`
|
815
620
|
)
|
816
621
|
}
|
817
|
-
if (fn && fn[STATS][RETURNS][1] !== PRED_TYPE) {
|
818
|
-
errorStack.add(
|
819
|
-
`Incorrect type of argument (${i}) for (${
|
820
|
-
first[VALUE]
|
821
|
-
}). Expected (${toTypeNames(
|
822
|
-
PRED_TYPE
|
823
|
-
)}) but got an (${toTypeNames(
|
824
|
-
fn[STATS][RETURNS][1] ?? fn[STATS][RETURNS][0]
|
825
|
-
)}) which is neither ${TRUE} or ${FALSE} (${stringifyArgs(
|
826
|
-
exp
|
827
|
-
)}) (check #27)`
|
828
|
-
)
|
829
|
-
}
|
830
622
|
} else {
|
831
623
|
const body = rest[i].at(-1).at(-1)
|
832
624
|
const rem = hasBlock(body) ? body.at(-1) : body
|
@@ -843,24 +635,6 @@ export const typeCheck = (ast) => {
|
|
843
635
|
)}) (${stringifyArgs(exp)}) (check #27)`
|
844
636
|
)
|
845
637
|
}
|
846
|
-
if (
|
847
|
-
PRED_TYPE &&
|
848
|
-
PRED_TYPE === PREDICATE &&
|
849
|
-
returns[VALUE] !== TRUE &&
|
850
|
-
returns[VALUE] !== FALSE
|
851
|
-
) {
|
852
|
-
errorStack.add(
|
853
|
-
`Incorrect type of argument ${i} for (${
|
854
|
-
first[VALUE]
|
855
|
-
}). Expected (${toTypeNames(
|
856
|
-
PRED_TYPE
|
857
|
-
)}) but got an (${toTypeNames(
|
858
|
-
ATOM
|
859
|
-
)}) which is neither ${TRUE} or ${FALSE} (${stringifyArgs(
|
860
|
-
exp
|
861
|
-
)}) (check #27)`
|
862
|
-
)
|
863
|
-
}
|
864
638
|
} else if (env[returns[VALUE]]) {
|
865
639
|
if (
|
866
640
|
MAIN_TYPE !==
|
@@ -876,41 +650,6 @@ export const typeCheck = (ast) => {
|
|
876
650
|
)}) (${stringifyArgs(exp)}) (check #29)`
|
877
651
|
)
|
878
652
|
}
|
879
|
-
// Never happens because there is only 1 sub type at the moment
|
880
|
-
// if (
|
881
|
-
// PRED_TYPE &&
|
882
|
-
// PRED_TYPE !==
|
883
|
-
// env[returns[VALUE]][STATS][RETURNS][1]
|
884
|
-
// ) {
|
885
|
-
// }
|
886
|
-
}
|
887
|
-
}
|
888
|
-
} else if (
|
889
|
-
PRED_TYPE &&
|
890
|
-
env[current[VALUE]] &&
|
891
|
-
env[current[VALUE]][STATS][RETURNS][1] !== PRED_TYPE
|
892
|
-
) {
|
893
|
-
if (current[VALUE] === KEYWORDS.ANONYMOUS_FUNCTION) {
|
894
|
-
const body = rest[i].at(-1)
|
895
|
-
const rem = hasBlock(body) ? body.at(-1) : body
|
896
|
-
const returns = isLeaf(rem) ? rem : rem[0]
|
897
|
-
if (
|
898
|
-
env[returns[VALUE]] &&
|
899
|
-
root[returns[VALUE]][STATS][RETURNS][1] ===
|
900
|
-
PREDICATE
|
901
|
-
) {
|
902
|
-
// TODO invert this logic
|
903
|
-
} else {
|
904
|
-
errorStack.add(
|
905
|
-
`Incorrect type of arguments (${i}) for (${
|
906
|
-
first[VALUE]
|
907
|
-
}). Expected (${toTypeNames(
|
908
|
-
PRED_TYPE
|
909
|
-
)}) but got (${toTypeNames(
|
910
|
-
env[current[VALUE]][STATS][RETURNS][1] ??
|
911
|
-
env[current[VALUE]][STATS][RETURNS][0]
|
912
|
-
)}) (${stringifyArgs(exp)}) (check #21)`
|
913
|
-
)
|
914
653
|
}
|
915
654
|
}
|
916
655
|
}
|
@@ -920,7 +659,6 @@ export const typeCheck = (ast) => {
|
|
920
659
|
const isCast = STATIC_TYPES_SET.has(first[VALUE])
|
921
660
|
const expectedArgs = env[first[VALUE]][STATS][ARGUMENTS]
|
922
661
|
for (let i = 0; i < rest.length; ++i) {
|
923
|
-
const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
|
924
662
|
const MAIN_TYPE = expectedArgs[i][STATS][TYPE_PROP][0]
|
925
663
|
if (MAIN_TYPE === UNKNOWN && !isCast) continue
|
926
664
|
if (!isLeaf(rest[i])) {
|
@@ -967,21 +705,7 @@ export const typeCheck = (ast) => {
|
|
967
705
|
env[CAR][STATS][TYPE_PROP][0]
|
968
706
|
)}) (${stringifyArgs(exp)}) (check #3)`
|
969
707
|
)
|
970
|
-
}
|
971
|
-
PRED_TYPE === PREDICATE &&
|
972
|
-
env[CAR][STATS][RETURNS][1] !== PRED_TYPE &&
|
973
|
-
!isCast
|
974
|
-
)
|
975
|
-
errorStack.add(
|
976
|
-
`Incorrect type of argument (${i}) for special form (${
|
977
|
-
first[VALUE]
|
978
|
-
}). Expected (${toTypeNames(
|
979
|
-
PRED_TYPE
|
980
|
-
)}) but got (${toTypeNames(
|
981
|
-
env[CAR][STATS][RETURNS][1] ??
|
982
|
-
env[CAR][STATS][TYPE_PROP][0]
|
983
|
-
)}) (${stringifyArgs(exp)}) (check #6)`
|
984
|
-
)
|
708
|
+
}
|
985
709
|
} else if (env[rest[i][VALUE]]) {
|
986
710
|
if (isCast) {
|
987
711
|
// CAST assigment
|
@@ -1009,22 +733,6 @@ export const typeCheck = (ast) => {
|
|
1009
733
|
)}) (${stringifyArgs(exp)}) (check #2)`
|
1010
734
|
)
|
1011
735
|
}
|
1012
|
-
if (
|
1013
|
-
PRED_TYPE === PREDICATE &&
|
1014
|
-
rest[i][VALUE] !== TRUE &&
|
1015
|
-
rest[i][VALUE] !== FALSE
|
1016
|
-
) {
|
1017
|
-
errorStack.add(
|
1018
|
-
`Incorrect type of argument (${i}) for special form (${
|
1019
|
-
first[VALUE]
|
1020
|
-
}). Expected (${toTypeNames(
|
1021
|
-
PRED_TYPE
|
1022
|
-
)}) but got (${toTypeNames(
|
1023
|
-
rest[i][VALUE]
|
1024
|
-
)}) (${stringifyArgs(exp)}) (check #5)`
|
1025
|
-
)
|
1026
|
-
}
|
1027
|
-
|
1028
736
|
break
|
1029
737
|
}
|
1030
738
|
}
|
@@ -1051,22 +759,6 @@ export const typeCheck = (ast) => {
|
|
1051
759
|
exp
|
1052
760
|
)}) (check #10)`
|
1053
761
|
)
|
1054
|
-
} else if (
|
1055
|
-
T === ATOM &&
|
1056
|
-
args[i][STATS][RETURNS][0] === ATOM &&
|
1057
|
-
args[i][STATS][RETURNS][1] === PREDICATE &&
|
1058
|
-
rest[i][VALUE] !== TRUE &&
|
1059
|
-
rest[i][VALUE] !== FALSE
|
1060
|
-
) {
|
1061
|
-
errorStack.add(
|
1062
|
-
`Incorrect type of arguments ${i} for (${
|
1063
|
-
first[VALUE]
|
1064
|
-
}). Expected (${toTypeNames(
|
1065
|
-
args[i][STATS][RETURNS][1]
|
1066
|
-
)}) but got (${toTypeNames(T)}) (${stringifyArgs(
|
1067
|
-
exp
|
1068
|
-
)}) (check #13)`
|
1069
|
-
)
|
1070
762
|
} else if (
|
1071
763
|
T === APPLY &&
|
1072
764
|
args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
|
@@ -1092,6 +784,7 @@ export const typeCheck = (ast) => {
|
|
1092
784
|
}
|
1093
785
|
}
|
1094
786
|
if (
|
787
|
+
T === COLLECTION &&
|
1095
788
|
env[rest[i][VALUE]] &&
|
1096
789
|
env[rest[i][VALUE]][STATS][TYPE_PROP][0] !== UNKNOWN &&
|
1097
790
|
args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
|