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/index.js +2 -1
- package/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/check.js +88 -402
- package/src/compiler.js +0 -1
- package/src/enchance.js +231 -0
- package/src/macros.js +0 -202
- package/src/utils.js +2 -2
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
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
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
|
-
|
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
|
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
|
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
|
-
|
640
|
-
|
641
|
-
|
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
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
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
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
)
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
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
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
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
|
-
|
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
|
-
}
|
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 &&
|