fez-lisp 1.5.101 → 1.5.103
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/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/check.js +77 -131
- package/src/utils.js +113 -0
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -37,6 +37,7 @@ import {
|
|
37
37
|
validateLambda
|
38
38
|
} from './types.js'
|
39
39
|
import {
|
40
|
+
Brr,
|
40
41
|
getSuffix,
|
41
42
|
hasApplyLambdaBlock,
|
42
43
|
hasBlock,
|
@@ -146,12 +147,12 @@ export const compareReturns = (a, b) =>
|
|
146
147
|
isAnyReturn(a) || isAnyReturn(b) || a[RETURNS][0] === b[RETURNS][0]
|
147
148
|
export const compareTypeWithReturn = (a, b) =>
|
148
149
|
isAnyType(a) || isAnyReturn(b) || a[TYPE_PROP][0] === b[RETURNS][0]
|
149
|
-
const checkPredicateName = (exp, rest
|
150
|
+
const checkPredicateName = (exp, rest) => {
|
150
151
|
if (getSuffix(rest[0][VALUE]) === PREDICATE_SUFFIX) {
|
151
152
|
const last = rest.at(-1)
|
152
153
|
if (isLeaf(last)) {
|
153
154
|
if (last[TYPE] === ATOM && last[VALUE] !== TRUE && last[VALUE] !== FALSE)
|
154
|
-
|
155
|
+
throw new TypeError(
|
155
156
|
`Assigning predicate (ending in ?) variable (${
|
156
157
|
rest[0][VALUE]
|
157
158
|
}) to an (${
|
@@ -163,7 +164,7 @@ const checkPredicateName = (exp, rest, errors) => {
|
|
163
164
|
getSuffix(last[VALUE]) !== PREDICATE_SUFFIX &&
|
164
165
|
!PREDICATES_OUTPUT_SET.has(last[VALUE])
|
165
166
|
)
|
166
|
-
|
167
|
+
throw new TypeError(
|
167
168
|
`Assigning predicate (ending in ?) variable (${
|
168
169
|
rest[0][VALUE]
|
169
170
|
}) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
|
@@ -181,7 +182,7 @@ const checkPredicateName = (exp, rest, errors) => {
|
|
181
182
|
getSuffix(application[VALUE]) !== PREDICATE_SUFFIX &&
|
182
183
|
!PREDICATES_OUTPUT_SET.has(application[VALUE])
|
183
184
|
)
|
184
|
-
|
185
|
+
throw new TypeError(
|
185
186
|
`Assigning predicate (ending in ?) variable (${
|
186
187
|
application[VALUE]
|
187
188
|
}) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
|
@@ -193,21 +194,17 @@ const checkPredicateName = (exp, rest, errors) => {
|
|
193
194
|
}
|
194
195
|
}
|
195
196
|
}
|
196
|
-
const checkPredicateNameDeep = (name, exp, rest, returns
|
197
|
+
const checkPredicateNameDeep = (name, exp, rest, returns) => {
|
197
198
|
if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
|
198
199
|
const fn = rest.at(-1).at(-1).at(-1)
|
199
|
-
checkPredicateName(
|
200
|
-
|
201
|
-
|
202
|
-
[
|
203
|
-
|
204
|
-
|
205
|
-
: drillReturnType(fn, (r) => r[VALUE] === KEYWORDS.CALL_FUNCTION) // when apply is an annonymous lambda // (let fn? (lambda x (apply x (lambda x (array:empty! [])))))
|
206
|
-
],
|
207
|
-
errors
|
208
|
-
)
|
200
|
+
checkPredicateName(exp, [
|
201
|
+
[WORD, name],
|
202
|
+
isLeaf(fn)
|
203
|
+
? fn // when apply is a word (let x? (lambda (apply [] array:empty!)))
|
204
|
+
: drillReturnType(fn, (r) => r[VALUE] === KEYWORDS.CALL_FUNCTION) // when apply is an annonymous lambda // (let fn? (lambda x (apply x (lambda x (array:empty! [])))))
|
205
|
+
])
|
209
206
|
} else {
|
210
|
-
checkPredicateName(exp, [[WORD, name], returns]
|
207
|
+
checkPredicateName(exp, [[WORD, name], returns])
|
211
208
|
}
|
212
209
|
}
|
213
210
|
const fillUknownArgs = (n) =>
|
@@ -238,20 +235,19 @@ const withScope = (name, scope) => {
|
|
238
235
|
const chain = getScopeNames(scope)
|
239
236
|
return `${chain.length === 1 ? '; ' : ''}${chain.join(' ')} ${name}`
|
240
237
|
}
|
241
|
-
const retry = (stats, stack,
|
238
|
+
const retry = (stats, stack, cb) => {
|
242
239
|
if (
|
243
|
-
errors.size === 0 &&
|
244
240
|
(isUnknownNotAnyType(stats) || isUnknownNotAnyReturn(stats)) &&
|
245
241
|
stats.retried < MAX_RETRY_DEFINITION
|
246
242
|
) {
|
247
243
|
stats.retried += 1
|
248
|
-
stack.
|
244
|
+
stack.prepend(() => cb())
|
249
245
|
}
|
250
246
|
}
|
251
|
-
const retryArgs = (stats, stack,
|
252
|
-
if (
|
247
|
+
const retryArgs = (stats, stack, cb) => {
|
248
|
+
if (stats.counter < MAX_ARGUMENT_RETRY) {
|
253
249
|
stats.counter++
|
254
|
-
stack.
|
250
|
+
stack.prepend(cb)
|
255
251
|
}
|
256
252
|
}
|
257
253
|
const ifExpression = ({ re, env, ref }) => {
|
@@ -291,18 +287,10 @@ const resolveApplyAssigment = (re, name, env) => {
|
|
291
287
|
}
|
292
288
|
}
|
293
289
|
}
|
294
|
-
const resolveIfAssigment = ({ rem, name, env, exp,
|
290
|
+
const resolveIfAssigment = ({ rem, name, env, exp, prop }) => {
|
295
291
|
const re = rem.slice(2)
|
296
|
-
checkPredicateName(
|
297
|
-
|
298
|
-
[[WORD, name], isLeaf(re[0]) ? re[0] : re[0][0]],
|
299
|
-
errors
|
300
|
-
)
|
301
|
-
checkPredicateName(
|
302
|
-
exp,
|
303
|
-
[[WORD, name], isLeaf(re[1]) ? re[1] : re[1][0]],
|
304
|
-
errors
|
305
|
-
)
|
292
|
+
checkPredicateName(exp, [[WORD, name], isLeaf(re[0]) ? re[0] : re[0][0]])
|
293
|
+
checkPredicateName(exp, [[WORD, name], isLeaf(re[1]) ? re[1] : re[1][0]])
|
306
294
|
if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM)
|
307
295
|
// ATOM ASSIGMENT
|
308
296
|
setPropToAtom(env[name][STATS], prop)
|
@@ -328,21 +316,13 @@ const resolveIfAssigment = ({ rem, name, env, exp, errors, prop }) => {
|
|
328
316
|
// ASSIGMENT
|
329
317
|
setPropRef(env[name][STATS], prop, env[re[1][VALUE]][STATS])
|
330
318
|
}
|
331
|
-
const resolveCondition = ({ rem, name, env, exp
|
319
|
+
const resolveCondition = ({ rem, name, env, exp }) => {
|
332
320
|
const ret = rem[0]
|
333
321
|
const re = rem.slice(2)
|
334
322
|
resolveApplyAssigment(re, name, env)
|
335
323
|
const ref = env[name]
|
336
|
-
checkPredicateName(
|
337
|
-
|
338
|
-
[[WORD, name], isLeaf(re[0]) ? re[0] : re[0][0]],
|
339
|
-
errors
|
340
|
-
)
|
341
|
-
checkPredicateName(
|
342
|
-
exp,
|
343
|
-
[[WORD, name], isLeaf(re[1]) ? re[1] : re[1][0]],
|
344
|
-
errors
|
345
|
-
)
|
324
|
+
checkPredicateName(exp, [[WORD, name], isLeaf(re[0]) ? re[0] : re[0][0]])
|
325
|
+
checkPredicateName(exp, [[WORD, name], isLeaf(re[1]) ? re[1] : re[1][0]])
|
346
326
|
switch (ret[VALUE]) {
|
347
327
|
case KEYWORDS.IF:
|
348
328
|
ifExpression({ re, env, ref })
|
@@ -350,33 +330,24 @@ const resolveCondition = ({ rem, name, env, exp, errors }) => {
|
|
350
330
|
default:
|
351
331
|
if (env[ret[VALUE]]) setReturnRef(ref[STATS], env[ret[VALUE]][STATS])
|
352
332
|
else
|
353
|
-
stack.
|
333
|
+
stack.append(() => {
|
354
334
|
if (env[ret[VALUE]]) setReturnRef(ref[STATS], env[ret[VALUE]][STATS])
|
355
335
|
})
|
356
336
|
break
|
357
337
|
}
|
358
338
|
}
|
359
|
-
const resolveRetunType = ({
|
360
|
-
returns,
|
361
|
-
rem,
|
362
|
-
stack,
|
363
|
-
prop,
|
364
|
-
exp,
|
365
|
-
name,
|
366
|
-
errors,
|
367
|
-
env
|
368
|
-
}) => {
|
339
|
+
const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
|
369
340
|
if (returns[TYPE] === ATOM) {
|
370
341
|
// ATOM ASSIGMENT
|
371
342
|
setPropToAtom(env[name][STATS], prop)
|
372
|
-
checkPredicateName(exp, [[WORD, name], returns]
|
343
|
+
checkPredicateName(exp, [[WORD, name], returns])
|
373
344
|
} else {
|
374
345
|
switch (returns[VALUE]) {
|
375
346
|
case KEYWORDS.IF:
|
376
|
-
resolveIfAssigment({ rem, name, env, exp,
|
347
|
+
resolveIfAssigment({ rem, name, env, exp, prop })
|
377
348
|
break
|
378
349
|
default:
|
379
|
-
checkPredicateNameDeep(name, exp, exp.slice(1), returns
|
350
|
+
checkPredicateNameDeep(name, exp, exp.slice(1), returns)
|
380
351
|
if (!env[returns[VALUE]]) return false
|
381
352
|
else if (getType(env[returns[VALUE]][STATS]) === APPLY) {
|
382
353
|
if (returns[TYPE] === WORD) setReturnToAbbstraction(env[name][STATS])
|
@@ -385,7 +356,7 @@ const resolveRetunType = ({
|
|
385
356
|
// rest.at(-1)[0][TYPE] === APPLY
|
386
357
|
// Here is upon application to store the result in the variable
|
387
358
|
if (isUnknownType(env[name][STATS]))
|
388
|
-
stack.
|
359
|
+
stack.prepend(() => {
|
389
360
|
setTypeToReturn(env[name][STATS], env[returns[VALUE]][STATS])
|
390
361
|
// env[name][STATS][TYPE_PROP][0] =
|
391
362
|
// env[returns[VALUE]][STATS][RETURNS][0]
|
@@ -401,7 +372,7 @@ const resolveRetunType = ({
|
|
401
372
|
}
|
402
373
|
return true
|
403
374
|
}
|
404
|
-
const checkReturnType = ({ exp, stack, name,
|
375
|
+
const checkReturnType = ({ exp, stack, name, env }) => {
|
405
376
|
const last = exp.at(-1).at(-1)
|
406
377
|
const body = hasApplyLambdaBlock(last) ? last.at(-1).at(-1) : last
|
407
378
|
const rem = hasBlock(body) ? body.at(-1) : body
|
@@ -412,7 +383,6 @@ const checkReturnType = ({ exp, stack, name, errors, env }) => {
|
|
412
383
|
prop: RETURNS,
|
413
384
|
exp,
|
414
385
|
name,
|
415
|
-
errors,
|
416
386
|
env,
|
417
387
|
stack
|
418
388
|
})
|
@@ -420,9 +390,8 @@ const checkReturnType = ({ exp, stack, name, errors, env }) => {
|
|
420
390
|
export const typeCheck = (ast, error = true) => {
|
421
391
|
let scopeIndex = 0
|
422
392
|
const root = structuredClone(SPECIAL_FORM_TYPES)
|
423
|
-
const errors = new Set()
|
424
393
|
const Types = new Map()
|
425
|
-
const stack =
|
394
|
+
const stack = new Brr()
|
426
395
|
const check = (exp, env, scope) => {
|
427
396
|
const [first, ...rest] = isLeaf(exp) ? [exp] : exp
|
428
397
|
if (first === undefined)
|
@@ -434,14 +403,14 @@ export const typeCheck = (ast, error = true) => {
|
|
434
403
|
switch (first[TYPE]) {
|
435
404
|
case WORD:
|
436
405
|
if (!isSpecial)
|
437
|
-
stack.
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
errors.add(
|
406
|
+
stack.append(() => {
|
407
|
+
// Figure out how to determine if varible is define after it's used
|
408
|
+
if (env[first[VALUE]] === undefined) {
|
409
|
+
throw new TypeError(
|
442
410
|
`Trying to access undefined variable ${first[VALUE]} (check #11)`
|
443
411
|
)
|
444
|
-
|
412
|
+
}
|
413
|
+
})
|
445
414
|
break
|
446
415
|
case ATOM:
|
447
416
|
break
|
@@ -483,30 +452,28 @@ export const typeCheck = (ast, error = true) => {
|
|
483
452
|
stack,
|
484
453
|
exp,
|
485
454
|
env,
|
486
|
-
name
|
487
|
-
errors
|
455
|
+
name
|
488
456
|
}) ||
|
489
457
|
isUnknownReturn(env[name][STATS])
|
490
458
|
) {
|
491
|
-
retry(env[name][STATS], stack,
|
459
|
+
retry(env[name][STATS], stack, () => {
|
492
460
|
checkReturnType({
|
493
461
|
stack,
|
494
462
|
exp,
|
495
463
|
env,
|
496
|
-
name
|
497
|
-
errors
|
464
|
+
name
|
498
465
|
})
|
499
466
|
check(rightHand, env, exp)
|
500
467
|
})
|
501
468
|
check(rightHand, env, exp)
|
502
469
|
} else check(rightHand, env, exp)
|
503
470
|
} else {
|
504
|
-
checkPredicateName(exp, rest
|
471
|
+
checkPredicateName(exp, rest)
|
505
472
|
const isLeafNode = isLeaf(rightHand)
|
506
473
|
if (isLeafNode && rightHand[TYPE] === WORD) {
|
507
474
|
// TODO make sure this prevents the assigment all together
|
508
475
|
if (env[rest[1][VALUE]] === undefined)
|
509
|
-
|
476
|
+
throw new TypeError(
|
510
477
|
`Trying to access undefined variable ${rest[1][VALUE]} (check #22)`
|
511
478
|
)
|
512
479
|
// Used to be checkin if it's an assigment to a special form
|
@@ -555,8 +522,7 @@ export const typeCheck = (ast, error = true) => {
|
|
555
522
|
prop: TYPE_PROP,
|
556
523
|
exp,
|
557
524
|
env,
|
558
|
-
name
|
559
|
-
errors
|
525
|
+
name
|
560
526
|
})
|
561
527
|
}
|
562
528
|
check(rightHand, env, scope)
|
@@ -574,7 +540,7 @@ export const typeCheck = (ast, error = true) => {
|
|
574
540
|
const param = params[i]
|
575
541
|
// TODO move this somewhere else
|
576
542
|
if (!isLeaf(param))
|
577
|
-
|
543
|
+
throw new TypeError(
|
578
544
|
`Invalid body for (${
|
579
545
|
first[VALUE]
|
580
546
|
}) if it takes more than one expression it must be wrapped in a (${
|
@@ -602,7 +568,7 @@ export const typeCheck = (ast, error = true) => {
|
|
602
568
|
// TODO figure out what we do here
|
603
569
|
// this here is a variable WORD
|
604
570
|
// so return type of that function is that varible type
|
605
|
-
stack.
|
571
|
+
stack.append(
|
606
572
|
() =>
|
607
573
|
copy[returns[VALUE]] &&
|
608
574
|
setReturnToType(ref[STATS], copy[returns[VALUE]][STATS])
|
@@ -617,7 +583,6 @@ export const typeCheck = (ast, error = true) => {
|
|
617
583
|
name: ref[STATS][SIGNATURE],
|
618
584
|
env: copy,
|
619
585
|
exp,
|
620
|
-
errors,
|
621
586
|
stack
|
622
587
|
})
|
623
588
|
break
|
@@ -625,7 +590,7 @@ export const typeCheck = (ast, error = true) => {
|
|
625
590
|
if (copy[ret[VALUE]])
|
626
591
|
setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
|
627
592
|
else
|
628
|
-
stack.
|
593
|
+
stack.append(() => {
|
629
594
|
if (copy[ret[VALUE]])
|
630
595
|
setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
|
631
596
|
})
|
@@ -655,9 +620,9 @@ export const typeCheck = (ast, error = true) => {
|
|
655
620
|
}
|
656
621
|
break
|
657
622
|
default:
|
658
|
-
stack.
|
623
|
+
stack.append(() => {
|
659
624
|
if (!isSpecial && env[first[VALUE]] === undefined)
|
660
|
-
|
625
|
+
throw new TypeError(
|
661
626
|
`Trying to call undefined (lambda) ${first[VALUE]} (check #9)`
|
662
627
|
)
|
663
628
|
else if (
|
@@ -665,7 +630,7 @@ export const typeCheck = (ast, error = true) => {
|
|
665
630
|
env[first[VALUE]][STATS][ARG_COUNT] !== VARIADIC &&
|
666
631
|
env[first[VALUE]][STATS][ARG_COUNT] !== rest.length
|
667
632
|
)
|
668
|
-
|
633
|
+
throw new TypeError(
|
669
634
|
`Incorrect number of arguments for (${
|
670
635
|
first[VALUE]
|
671
636
|
}). Expected (= ${
|
@@ -675,7 +640,7 @@ export const typeCheck = (ast, error = true) => {
|
|
675
640
|
else {
|
676
641
|
if (first[TYPE] === APPLY && !isSpecial) {
|
677
642
|
if (getType(env[first[VALUE]][STATS]) === ATOM)
|
678
|
-
|
643
|
+
throw new TypeError(
|
679
644
|
`(${first[VALUE]}) is not a (lambda) (${stringifyArgs(
|
680
645
|
exp
|
681
646
|
)}) (check #12)`
|
@@ -746,7 +711,7 @@ export const typeCheck = (ast, error = true) => {
|
|
746
711
|
const fnName = rest[i].at(-1)[VALUE]
|
747
712
|
const fn = env[fnName]
|
748
713
|
if (fn && getReturn(fn[STATS]) !== ATOM)
|
749
|
-
|
714
|
+
throw new TypeError(
|
750
715
|
`Incorrect type of argument (${i}) for (${
|
751
716
|
first[VALUE]
|
752
717
|
}). Expected (${toTypeNames(
|
@@ -761,7 +726,7 @@ export const typeCheck = (ast, error = true) => {
|
|
761
726
|
const returns = isLeaf(rem) ? rem : rem[0]
|
762
727
|
if (returns[TYPE] === ATOM) {
|
763
728
|
if (MAIN_TYPE !== ATOM)
|
764
|
-
|
729
|
+
throw new TypeError(
|
765
730
|
`Incorrect type of argument ${i} for (${
|
766
731
|
first[VALUE]
|
767
732
|
}). Expected (${toTypeNames(
|
@@ -775,7 +740,7 @@ export const typeCheck = (ast, error = true) => {
|
|
775
740
|
!isUnknownReturn(env[returns[VALUE]][STATS]) &&
|
776
741
|
getReturn(env[returns[VALUE]][STATS]) !== ATOM
|
777
742
|
)
|
778
|
-
|
743
|
+
throw new TypeError(
|
779
744
|
`Incorrect type of argument ${i} for (${
|
780
745
|
first[VALUE]
|
781
746
|
}). Expected (${toTypeNames(
|
@@ -798,7 +763,7 @@ export const typeCheck = (ast, error = true) => {
|
|
798
763
|
env[name][STATS]
|
799
764
|
)
|
800
765
|
)
|
801
|
-
|
766
|
+
throw new TypeError(
|
802
767
|
`Incorrect type of argument (${i}) for special form (${
|
803
768
|
first[VALUE]
|
804
769
|
}). Expected (${toTypeNames(
|
@@ -838,7 +803,7 @@ export const typeCheck = (ast, error = true) => {
|
|
838
803
|
env[name][STATS]
|
839
804
|
)
|
840
805
|
)
|
841
|
-
|
806
|
+
throw new TypeError(
|
842
807
|
`Incorrect type of argument (${i}) for special form (${
|
843
808
|
first[VALUE]
|
844
809
|
}). Expected (${toTypeNames(
|
@@ -856,7 +821,7 @@ export const typeCheck = (ast, error = true) => {
|
|
856
821
|
rest[i][TYPE] !==
|
857
822
|
expectedArgs[i][STATS][TYPE_PROP][0]
|
858
823
|
)
|
859
|
-
|
824
|
+
throw new TypeError(
|
860
825
|
`Incorrect type of argument (${i}) for special form (${
|
861
826
|
first[VALUE]
|
862
827
|
}). Expected (${toTypeNames(
|
@@ -883,7 +848,7 @@ export const typeCheck = (ast, error = true) => {
|
|
883
848
|
!isUnknownType(args[i][STATS]) &&
|
884
849
|
getType(args[i][STATS]) !== ATOM
|
885
850
|
) {
|
886
|
-
|
851
|
+
throw new TypeError(
|
887
852
|
`Incorrect type of arguments ${i} for (${
|
888
853
|
first[VALUE]
|
889
854
|
}). Expected (${toTypeNames(
|
@@ -903,7 +868,7 @@ export const typeCheck = (ast, error = true) => {
|
|
903
868
|
env[rest[i][VALUE]][STATS][ARG_COUNT] !==
|
904
869
|
args[i][STATS][ARG_COUNT]
|
905
870
|
) {
|
906
|
-
|
871
|
+
throw new TypeError(
|
907
872
|
`Incorrect number of arguments for (${
|
908
873
|
args[i][STATS][SIGNATURE]
|
909
874
|
}) the (lambda) argument of (${
|
@@ -927,7 +892,7 @@ export const typeCheck = (ast, error = true) => {
|
|
927
892
|
!isUnknownReturn(actual[STATS]) &&
|
928
893
|
!compareReturns(expected[STATS], actual[STATS])
|
929
894
|
) {
|
930
|
-
|
895
|
+
throw new TypeError(
|
931
896
|
`Incorrect return type for (${
|
932
897
|
expected[STATS][SIGNATURE]
|
933
898
|
}) the (lambda) argument of (${
|
@@ -938,8 +903,7 @@ export const typeCheck = (ast, error = true) => {
|
|
938
903
|
getReturn(actual[STATS])
|
939
904
|
)}) (${stringifyArgs(exp)}) (check #782)`
|
940
905
|
)
|
941
|
-
} else
|
942
|
-
retry(actual[STATS], stack, errors, () => match1())
|
906
|
+
} else retry(actual[STATS], stack, () => match1())
|
943
907
|
}
|
944
908
|
match1()
|
945
909
|
for (
|
@@ -956,7 +920,7 @@ export const typeCheck = (ast, error = true) => {
|
|
956
920
|
!isUnknownType(expected[STATS]) &&
|
957
921
|
!compareTypes(actual[STATS], expected[STATS])
|
958
922
|
)
|
959
|
-
|
923
|
+
throw new TypeError(
|
960
924
|
`Incorrect type for (lambda) (${
|
961
925
|
args[i][STATS][SIGNATURE]
|
962
926
|
}) argument at position (${j}) named as (${
|
@@ -967,14 +931,7 @@ export const typeCheck = (ast, error = true) => {
|
|
967
931
|
getType(actual[STATS])
|
968
932
|
)}) (${stringifyArgs(exp)}) (check #781)`
|
969
933
|
)
|
970
|
-
else
|
971
|
-
retry(
|
972
|
-
actual[STATS],
|
973
|
-
stack,
|
974
|
-
errors,
|
975
|
-
|
976
|
-
() => match2()
|
977
|
-
)
|
934
|
+
else retry(actual[STATS], stack, () => match2())
|
978
935
|
}
|
979
936
|
match2()
|
980
937
|
}
|
@@ -987,7 +944,7 @@ export const typeCheck = (ast, error = true) => {
|
|
987
944
|
!isUnknownType(args[i][STATS]) &&
|
988
945
|
!compareTypes(env[rest[i][VALUE]][STATS], args[i][STATS])
|
989
946
|
) {
|
990
|
-
|
947
|
+
throw new TypeError(
|
991
948
|
`Incorrect type of arguments ${i} for (${
|
992
949
|
first[VALUE]
|
993
950
|
}). Expected (${toTypeNames(
|
@@ -997,9 +954,7 @@ export const typeCheck = (ast, error = true) => {
|
|
997
954
|
)}) (check #30)`
|
998
955
|
)
|
999
956
|
} else if (isUnknownType(args[i][STATS]))
|
1000
|
-
retry(args[i][STATS], stack,
|
1001
|
-
check(exp, env, scope)
|
1002
|
-
)
|
957
|
+
retry(args[i][STATS], stack, () => check(exp, env, scope))
|
1003
958
|
else if (
|
1004
959
|
env[rest[i][VALUE]] &&
|
1005
960
|
!isUnknownType(args[i][STATS]) &&
|
@@ -1016,10 +971,10 @@ export const typeCheck = (ast, error = true) => {
|
|
1016
971
|
const match = () => {
|
1017
972
|
const actual = env[rest[i][0][VALUE]][STATS]
|
1018
973
|
const expected = args[i][STATS]
|
1019
|
-
retryArgs(args[i][STATS], stack,
|
974
|
+
retryArgs(args[i][STATS], stack, () => match())
|
1020
975
|
if (!isUnknownType(expected) && !isUnknownReturn(actual))
|
1021
976
|
if (!compareTypeWithReturn(expected, actual))
|
1022
|
-
|
977
|
+
throw new TypeError(
|
1023
978
|
`Incorrect type of arguments ${i} for (${
|
1024
979
|
first[VALUE]
|
1025
980
|
}). Expected (${toTypeNames(
|
@@ -1039,7 +994,7 @@ export const typeCheck = (ast, error = true) => {
|
|
1039
994
|
KEYWORDS.ANONYMOUS_FUNCTION
|
1040
995
|
) {
|
1041
996
|
if (argsN !== args[i][STATS][ARG_COUNT])
|
1042
|
-
|
997
|
+
throw new TypeError(
|
1043
998
|
`Incorrect number of arguments for (${
|
1044
999
|
args[i][STATS][SIGNATURE]
|
1045
1000
|
}) the (lambda) argument of (${
|
@@ -1077,7 +1032,7 @@ export const typeCheck = (ast, error = true) => {
|
|
1077
1032
|
actual[STATS]
|
1078
1033
|
)
|
1079
1034
|
)
|
1080
|
-
|
1035
|
+
throw new TypeError(
|
1081
1036
|
`Incorrect return type for (${
|
1082
1037
|
expected[STATS][SIGNATURE]
|
1083
1038
|
}) the (lambda) argument of (${
|
@@ -1091,12 +1046,8 @@ export const typeCheck = (ast, error = true) => {
|
|
1091
1046
|
)}) (check #779)`
|
1092
1047
|
)
|
1093
1048
|
else
|
1094
|
-
retry(
|
1095
|
-
|
1096
|
-
stack,
|
1097
|
-
errors,
|
1098
|
-
|
1099
|
-
() => match1()
|
1049
|
+
retry(actual[STATS], stack, () =>
|
1050
|
+
match1()
|
1100
1051
|
)
|
1101
1052
|
}
|
1102
1053
|
match1()
|
@@ -1118,7 +1069,7 @@ export const typeCheck = (ast, error = true) => {
|
|
1118
1069
|
expected[STATS]
|
1119
1070
|
)
|
1120
1071
|
)
|
1121
|
-
|
1072
|
+
throw new TypeError(
|
1122
1073
|
`Incorrect type for (lambda) (${
|
1123
1074
|
args[i][STATS][SIGNATURE]
|
1124
1075
|
}) argument at position (${j}) named as (${
|
@@ -1134,12 +1085,8 @@ export const typeCheck = (ast, error = true) => {
|
|
1134
1085
|
)}) (check #780)`
|
1135
1086
|
)
|
1136
1087
|
else
|
1137
|
-
retry(
|
1138
|
-
|
1139
|
-
stack,
|
1140
|
-
errors,
|
1141
|
-
|
1142
|
-
() => match2()
|
1088
|
+
retry(actual[STATS], stack, () =>
|
1089
|
+
match2()
|
1143
1090
|
)
|
1144
1091
|
}
|
1145
1092
|
match2()
|
@@ -1156,7 +1103,7 @@ export const typeCheck = (ast, error = true) => {
|
|
1156
1103
|
}
|
1157
1104
|
}
|
1158
1105
|
else if (isUnknownType(expected))
|
1159
|
-
retry(args[i][STATS], stack,
|
1106
|
+
retry(args[i][STATS], stack, () => match())
|
1160
1107
|
}
|
1161
1108
|
match()
|
1162
1109
|
}
|
@@ -1168,7 +1115,7 @@ export const typeCheck = (ast, error = true) => {
|
|
1168
1115
|
const r = rest[i]
|
1169
1116
|
if (isLeaf(r) && r[TYPE] !== ATOM)
|
1170
1117
|
if (env[r[VALUE]] == undefined)
|
1171
|
-
|
1118
|
+
throw new TypeError(
|
1172
1119
|
`(${
|
1173
1120
|
first[VALUE]
|
1174
1121
|
}) is trying to access undefined variable (${
|
@@ -1184,8 +1131,7 @@ export const typeCheck = (ast, error = true) => {
|
|
1184
1131
|
}
|
1185
1132
|
const copy = JSON.parse(JSON.stringify(ast))
|
1186
1133
|
check(copy, root, copy)
|
1187
|
-
while (stack.length) stack.
|
1188
|
-
if (error && errors.size) throw new TypeError([...errors.values()].join('\n'))
|
1134
|
+
while (stack.length) stack.cut()()
|
1189
1135
|
return [ast, Types]
|
1190
1136
|
}
|
1191
1137
|
export const type = (ast) => typeCheck(ast)[0]
|