fez-lisp 1.5.33 → 1.5.35

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 CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "fez-lisp",
3
3
  "description": "Lisp interpreted & compiled to JavaScript",
4
4
  "author": "AT290690",
5
- "version": "1.5.33",
5
+ "version": "1.5.35",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  WORD
12
12
  } from './keywords.js'
13
13
  import { isLeaf } from './parser.js'
14
- import { stringifyArgs } from './utils.js'
14
+ import { hasBlock, stringifyArgs } from './utils.js'
15
15
  const ARGS_COUNT = 'n'
16
16
  const VARIADIC = '...'
17
17
  const STATS = '__stats__'
@@ -395,7 +395,6 @@ export const typeCheck = (ast) => {
395
395
  const withScope = (name, scope) => {
396
396
  const chain = getScopeNames(scope)
397
397
  const str = `${chain.join('_')}_${name}`
398
- // console.log({ str })
399
398
  return { str, chain }
400
399
  }
401
400
 
@@ -445,9 +444,65 @@ export const typeCheck = (ast) => {
445
444
  [ARGS]: []
446
445
  }
447
446
  }
448
- if (name[name.length - 1] === PREDICATE_SUFFIX)
449
- env[name][STATS][SUBTYPE] = PREDICATE
450
- check(rest.at(-1), env, exp)
447
+ const checkReturnType = () => {
448
+ if (name[name.length - 1] === PREDICATE_SUFFIX) {
449
+ env[name][STATS][RETURNS] = ATOM
450
+ env[name][STATS][SUBTYPE] = PREDICATE
451
+ } else {
452
+ const body = rest.at(-1).at(-1)
453
+ const rem = hasBlock(body) ? body.at(-1) : body
454
+ const returns = isLeaf(rem) ? rem : rem[0]
455
+ if (returns[TYPE] === ATOM) {
456
+ env[name][STATS][RETURNS] = ATOM
457
+ } else {
458
+ switch (returns[VALUE]) {
459
+ case KEYWORDS.IF:
460
+ const re = rem.slice(2)
461
+ if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM)
462
+ env[name][STATS][RETURNS] = ATOM
463
+ else if (!isLeaf(re[0]) && env[re[0][0][VALUE]]) {
464
+ env[name][STATS][RETURNS] =
465
+ env[re[0][0][VALUE]][STATS][RETURNS]
466
+ } else {
467
+ if (env[re[0][VALUE]])
468
+ env[name][STATS][RETURNS] =
469
+ env[re[0][VALUE]][STATS].type
470
+ else env[name][STATS][RETURNS] = UNKNOWN
471
+ }
472
+ break
473
+ default:
474
+ if (env[returns[VALUE]]) {
475
+ if (env[returns[VALUE]][STATS].type === APPLY) {
476
+ env[name][STATS][RETURNS] =
477
+ env[returns[VALUE]][STATS][RETURNS]
478
+ // env[name][STATS][SUBTYPE] =
479
+ // env[returns[VALUE]][STATS][SUBTYPE]
480
+ } else {
481
+ env[name][STATS][RETURNS] =
482
+ env[returns[VALUE]].type
483
+ }
484
+ } else {
485
+ env[name][STATS][RETURNS] = UNKNOWN
486
+ }
487
+ break
488
+ }
489
+ }
490
+ }
491
+ }
492
+ checkReturnType()
493
+ if (
494
+ env[name][STATS][RETURNS] === UNKNOWN &&
495
+ !env[name].retried
496
+ ) {
497
+ env[name].retried = true
498
+ stack.unshift(() => {
499
+ checkReturnType()
500
+ check(rest.at(-1), env, exp)
501
+ })
502
+ check(rest.at(-1), env, exp)
503
+ } else {
504
+ check(rest.at(-1), env, exp)
505
+ }
451
506
  } else {
452
507
  if (!(name in env)) {
453
508
  if (rest[1][TYPE] === WORD)
@@ -505,138 +560,111 @@ export const typeCheck = (ast) => {
505
560
  key.str,
506
561
  `Trying to call undefined (lambda) ${first[VALUE]} (check #9)`
507
562
  )
508
- else if (
509
- env[first[VALUE]][STATS].type === APPLY &&
510
- env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC &&
511
- env[first[VALUE]][STATS][ARGS_COUNT] !== rest.length
512
- ) {
513
- errorStack.set(
514
- key.str,
515
- `Incorrect number of arguments for (${
516
- first[VALUE]
517
- }). Expected (= ${
518
- env[first[VALUE]][STATS][ARGS_COUNT]
519
- }) but got ${rest.length} (${stringifyArgs(
520
- exp
521
- )}) (check #8)`
522
- )
523
- } else {
524
- const isSpecial = SPECIAL_FORMS_SET.has(first[VALUE])
563
+ else {
564
+ if (
565
+ env[first[VALUE]][STATS].type === APPLY &&
566
+ env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC &&
567
+ env[first[VALUE]][STATS][ARGS_COUNT] !== rest.length
568
+ ) {
569
+ errorStack.set(
570
+ key.str,
571
+ `Incorrect number of arguments for (${
572
+ first[VALUE]
573
+ }). Expected (= ${
574
+ env[first[VALUE]][STATS][ARGS_COUNT]
575
+ }) but got ${rest.length} (${stringifyArgs(
576
+ exp
577
+ )}) (check #8)`
578
+ )
579
+ } else {
580
+ const isSpecial = SPECIAL_FORMS_SET.has(first[VALUE])
525
581
 
526
- if (first[TYPE] === APPLY && !isSpecial) {
527
- if (env[first[VALUE]][STATS].type === ATOM) {
528
- errorStack.set(
529
- key.str,
530
- `(${first[VALUE]}) is not a (lambda) (${stringifyArgs(
531
- exp
532
- )}) (check #12)`
533
- )
534
- } else if (!env[first[VALUE]][STATS][ARGS_COUNT]) {
535
- env[first[VALUE]][STATS][RETURNS] = UNKNOWN
536
- env[first[VALUE]][STATS].type = APPLY
537
- env[first[VALUE]][STATS][ARGS_COUNT] = rest.length
582
+ if (first[TYPE] === APPLY && !isSpecial) {
583
+ if (env[first[VALUE]][STATS].type === ATOM) {
584
+ errorStack.set(
585
+ key.str,
586
+ `(${first[VALUE]}) is not a (lambda) (${stringifyArgs(
587
+ exp
588
+ )}) (check #12)`
589
+ )
590
+ } else if (!env[first[VALUE]][STATS][ARGS_COUNT]) {
591
+ env[first[VALUE]][STATS][RETURNS] = UNKNOWN
592
+ env[first[VALUE]][STATS].type = APPLY
593
+ env[first[VALUE]][STATS][ARGS_COUNT] = rest.length
594
+ }
538
595
  }
539
- }
540
- // also type of arg
541
- const args = env[first[VALUE]][STATS][ARGS]
542
- if (args) {
543
- for (let i = 0; i < args.length; ++i) {
544
- if (
545
- args[i][STATS] &&
546
- args[i][STATS].type === APPLY &&
547
- env[rest[i][VALUE]] &&
548
- env[rest[i][VALUE]][STATS] &&
549
- env[rest[i][VALUE]][STATS][ARGS_COUNT] &&
550
- args[i][STATS][ARGS_COUNT] !== VARIADIC &&
551
- env[rest[i][VALUE]][STATS][ARGS_COUNT] !== VARIADIC
552
- ) {
596
+ // also type of arg
597
+ const args = env[first[VALUE]][STATS][ARGS]
598
+ if (args) {
599
+ for (let i = 0; i < args.length; ++i) {
600
+ // type check
553
601
  if (
554
- args[i][STATS][ARGS_COUNT] !==
555
- env[rest[i][VALUE]][STATS][ARGS_COUNT]
602
+ first[TYPE] === APPLY &&
603
+ isSpecial &&
604
+ env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC
556
605
  ) {
557
- errorStack.set(
558
- key.str,
559
- `Incorrect number of arguments for (${
560
- first[VALUE]
561
- }). Expected (= ${
562
- args[i][STATS][ARGS_COUNT]
563
- }) but got ${rest.length} (${stringifyArgs(
564
- exp
565
- )}) (check #7)`
566
- )
567
- }
568
- } else if (
569
- args[i][STATS] &&
570
- args[i][STATS].type === APPLY &&
571
- !isLeaf(rest[i]) &&
572
- rest[i][0][TYPE] === APPLY &&
573
- rest[i][0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
574
- ) {
575
- if (args[i][STATS][ARGS_COUNT] !== rest[i].length - 2)
576
- errorStack.set(
577
- key.str,
578
- `Incorrect number of arguments for (${
579
- first[VALUE]
580
- }). Expected (= ${
581
- args[i][STATS][ARGS_COUNT]
582
- }) but got ${rest.length} (${stringifyArgs(
583
- exp
584
- )}) (check #6)`
585
- )
586
- }
587
-
588
- // type check
589
- if (
590
- first[TYPE] === APPLY &&
591
- isSpecial &&
592
- env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC
593
- ) {
594
- const expectedArgs = env[first[VALUE]][STATS][ARGS]
595
- for (let i = 0; i < rest.length; ++i) {
596
- if (expectedArgs[i][TYPE] === UNKNOWN) continue
597
- if (!isLeaf(rest[i])) {
598
- const CAR = rest[i][0][VALUE]
599
- if (
600
- env[CAR] &&
601
- env[CAR][STATS][RETURNS] != undefined &&
602
- env[CAR][STATS][RETURNS] !== UNKNOWN &&
603
- env[CAR][STATS][RETURNS] !== expectedArgs[i][TYPE]
604
- ) {
605
- // console.log(env[CAR][STATS], expectedArgs[i][TYPE])
606
- errorStack.set(
607
- key.str,
608
- `Incorrect type of arguments for special form (${
609
- first[VALUE]
610
- }). Expected (${toTypeNames(
606
+ const expectedArgs = env[first[VALUE]][STATS][ARGS]
607
+ for (let i = 0; i < rest.length; ++i) {
608
+ if (expectedArgs[i][TYPE] === UNKNOWN) continue
609
+ if (!isLeaf(rest[i])) {
610
+ const CAR = rest[i][0][VALUE]
611
+ if (
612
+ env[CAR] &&
613
+ env[CAR][STATS][RETURNS] != undefined &&
614
+ env[CAR][STATS][RETURNS] !== UNKNOWN &&
615
+ env[CAR][STATS][RETURNS] !==
611
616
  expectedArgs[i][TYPE]
612
- )}) but got (${toTypeNames(
613
- env[CAR][STATS][RETURNS]
614
- )}) (${stringifyArgs(exp)}) (check #1)`
615
- )
617
+ ) {
618
+ // console.log(env[CAR][STATS], expectedArgs[i][TYPE])
619
+ errorStack.set(
620
+ key.str,
621
+ `Incorrect type of arguments for special form (${
622
+ first[VALUE]
623
+ }). Expected (${toTypeNames(
624
+ expectedArgs[i][TYPE]
625
+ )}) but got (${toTypeNames(
626
+ env[CAR][STATS][RETURNS]
627
+ )}) (${stringifyArgs(exp)}) (check #1)`
628
+ )
629
+ }
630
+ // else {
631
+ // console.log(env[CAR])
632
+ // }
616
633
  }
617
- // else {
618
- // console.log(env[CAR])
619
- // }
620
- }
621
- if (
622
- env[rest[i][VALUE]] &&
623
- expectedArgs[i][TYPE] !== rest[i][TYPE]
624
- ) {
625
- switch (rest[i][TYPE]) {
626
- case UNKNOWN:
627
- env[first[VALUE]][STATS].type =
628
- expectedArgs[i][TYPE]
629
- break
630
- case WORD:
631
- const T = env[rest[i][VALUE]][STATS].type
632
- if (Array.isArray(T)) {
633
- const TT = T[VALUE]
634
- if (
635
- env[TT][STATS][RETURNS] &&
636
- env[TT][STATS][RETURNS] !== UNKNOWN &&
637
- expectedArgs[i][TYPE] !==
638
- env[TT][STATS][RETURNS]
639
- )
634
+ if (
635
+ env[rest[i][VALUE]] &&
636
+ expectedArgs[i][TYPE] !== rest[i][TYPE]
637
+ ) {
638
+ switch (rest[i][TYPE]) {
639
+ case UNKNOWN:
640
+ env[first[VALUE]][STATS].type =
641
+ expectedArgs[i][TYPE]
642
+ break
643
+ case WORD:
644
+ const T = env[rest[i][VALUE]][STATS].type
645
+ if (Array.isArray(T)) {
646
+ const TT = T[VALUE]
647
+ if (
648
+ env[TT][STATS][RETURNS] &&
649
+ env[TT][STATS][RETURNS] !== UNKNOWN &&
650
+ expectedArgs[i][TYPE] !==
651
+ env[TT][STATS][RETURNS]
652
+ )
653
+ errorStack.set(
654
+ key.str,
655
+ `Incorrect type of arguments for special form (${
656
+ first[VALUE]
657
+ }). Expected (${toTypeNames(
658
+ expectedArgs[i][TYPE]
659
+ )}) but got (${toTypeNames(
660
+ rest[i][TYPE]
661
+ )}) (${stringifyArgs(exp)}) (check #2)`
662
+ )
663
+ } else if (
664
+ T !== UNKNOWN &&
665
+ expectedArgs[i][TYPE] !== UNKNOWN &&
666
+ expectedArgs[i][TYPE] !== T
667
+ ) {
640
668
  errorStack.set(
641
669
  key.str,
642
670
  `Incorrect type of arguments for special form (${
@@ -644,66 +672,89 @@ export const typeCheck = (ast) => {
644
672
  }). Expected (${toTypeNames(
645
673
  expectedArgs[i][TYPE]
646
674
  )}) but got (${toTypeNames(
647
- rest[i][TYPE]
648
- )}) (${stringifyArgs(exp)}) (check #2)`
675
+ T
676
+ )}) (${stringifyArgs(exp)}) (check #3)`
649
677
  )
650
- } else if (
651
- T !== UNKNOWN &&
652
- expectedArgs[i][TYPE] !== UNKNOWN &&
653
- expectedArgs[i][TYPE] !== T
654
- ) {
678
+ } else {
679
+ env[rest[i][VALUE]][STATS].type =
680
+ expectedArgs[i][TYPE]
681
+ }
682
+ break
683
+ case APPLY:
684
+ case ATOM:
655
685
  errorStack.set(
656
686
  key.str,
657
- `Incorrect type of arguments for special form (${
687
+ `Incorrect type of arguments for (${
658
688
  first[VALUE]
659
689
  }). Expected (${toTypeNames(
660
690
  expectedArgs[i][TYPE]
661
691
  )}) but got (${toTypeNames(
662
- T
663
- )}) (${stringifyArgs(exp)}) (check #3)`
692
+ rest[i][TYPE]
693
+ )}) (${stringifyArgs(exp)}) (check #5)`
664
694
  )
665
- } else {
666
- env[rest[i][VALUE]][STATS].type =
667
- expectedArgs[i][TYPE]
668
- }
669
- break
670
- case APPLY:
671
- case ATOM:
672
- errorStack.set(
673
- key.str,
674
- `Incorrect type of arguments for (${
675
- first[VALUE]
676
- }). Expected (${toTypeNames(
677
- expectedArgs[i][TYPE]
678
- )}) but got (${toTypeNames(
679
- rest[i][TYPE]
680
- )}) (${stringifyArgs(exp)}) (check #5)`
681
- )
682
- break
695
+ break
696
+ }
683
697
  }
684
698
  }
685
699
  }
686
- }
687
- // type checking
688
- else if (
689
- rest[i] &&
690
- args[i][STATS] &&
691
- rest[i][TYPE] !== args[i][STATS].type
692
- ) {
693
- if (isLeaf(rest[i])) {
694
- const T =
695
- rest[i][TYPE] === WORD && env[rest[i][VALUE]]
696
- ? env[rest[i][VALUE]][STATS].type
697
- : rest[i][TYPE]
698
- if (
699
- (args[i][STATS].type !== UNKNOWN &&
700
- T === ATOM &&
701
- args[i][STATS].type !== ATOM) ||
702
- (env[rest[i][VALUE]] &&
703
- env[rest[i][VALUE]][STATS].type !== UNKNOWN &&
704
- args[i][STATS].type !== UNKNOWN &&
705
- env[rest[i][VALUE]][STATS].type !==
706
- args[i][STATS].type)
700
+ // type checking
701
+ else if (
702
+ rest[i] &&
703
+ args[i][STATS] &&
704
+ rest[i][TYPE] !== args[i][STATS].type
705
+ ) {
706
+ if (isLeaf(rest[i])) {
707
+ const T =
708
+ rest[i][TYPE] === WORD && env[rest[i][VALUE]]
709
+ ? env[rest[i][VALUE]][STATS].type
710
+ : rest[i][TYPE]
711
+ if (
712
+ (args[i][STATS].type !== UNKNOWN &&
713
+ T === ATOM &&
714
+ args[i][STATS].type !== ATOM) ||
715
+ (env[rest[i][VALUE]] &&
716
+ env[rest[i][VALUE]][STATS].type !== UNKNOWN &&
717
+ args[i][STATS].type !== UNKNOWN &&
718
+ env[rest[i][VALUE]][STATS].type !==
719
+ args[i][STATS].type)
720
+ ) {
721
+ errorStack.set(
722
+ key.str,
723
+ `Incorrect type of arguments ${i} for (${
724
+ first[VALUE]
725
+ }). Expected (${toTypeNames(
726
+ args[i][STATS].type
727
+ )}) but got (${toTypeNames(
728
+ T
729
+ )}) (${stringifyArgs(exp)})`
730
+ )
731
+ } else {
732
+ // env[rest[i][VALUE]][STATS] THiss SHOULD BE
733
+ const retry = env[rest[i][VALUE]]
734
+ if (
735
+ retry &&
736
+ !retry.retried &&
737
+ args[i][STATS].type === UNKNOWN
738
+ ) {
739
+ retry.retried = true
740
+ stack.unshift(() => check(exp, env, scope))
741
+ }
742
+ // console.log(
743
+ // first[VALUE],
744
+ // env[first[VALUE]][STATS],
745
+ // rest[i][TYPE],
746
+ // args[i][STATS].type
747
+ // )
748
+ }
749
+ } else if (
750
+ rest[i].length &&
751
+ SPECIAL_FORMS_SET.has(rest[i][0][VALUE]) &&
752
+ env[rest[i][0][VALUE]] &&
753
+ env[rest[i][0][VALUE]][STATS][RETURNS] !==
754
+ UNKNOWN &&
755
+ args[i][STATS].type !== UNKNOWN &&
756
+ env[rest[i][0][VALUE]][STATS][RETURNS] !==
757
+ args[i][STATS].type
707
758
  ) {
708
759
  errorStack.set(
709
760
  key.str,
@@ -711,58 +762,22 @@ export const typeCheck = (ast) => {
711
762
  first[VALUE]
712
763
  }). Expected (${toTypeNames(
713
764
  args[i][STATS].type
714
- )}) but got (${toTypeNames(T)}) (${stringifyArgs(
715
- exp
716
- )})`
765
+ )}) but got (${toTypeNames(
766
+ env[rest[i][0][VALUE]][STATS][RETURNS]
767
+ )}) (${stringifyArgs(exp)}) (check #4)`
717
768
  )
718
769
  } else {
719
- // env[rest[i][VALUE]][STATS] THiss SHOULD BE
720
- const retry = env[rest[i][VALUE]]
721
770
  if (
722
- retry &&
723
- !retry.retried &&
724
- args[i][STATS].type === UNKNOWN
771
+ rest[i].length &&
772
+ env[rest[i][0][VALUE]] &&
773
+ args[i][STATS].type === UNKNOWN &&
774
+ !env[rest[i][0][VALUE]].retried
725
775
  ) {
726
- retry.retried = true
776
+ env[rest[i][0][VALUE]].retried = true
777
+ if (!scope[SCOPE_NAME])
778
+ scope[SCOPE_NAME] = scope[1][VALUE]
727
779
  stack.unshift(() => check(exp, env, scope))
728
780
  }
729
- // console.log(
730
- // first[VALUE],
731
- // env[first[VALUE]][STATS],
732
- // rest[i][TYPE],
733
- // args[i][STATS].type
734
- // )
735
- }
736
- } else if (
737
- rest[i].length &&
738
- SPECIAL_FORMS_SET.has(rest[i][0][VALUE]) &&
739
- env[rest[i][0][VALUE]] &&
740
- env[rest[i][0][VALUE]][STATS][RETURNS] !== UNKNOWN &&
741
- args[i][STATS].type !== UNKNOWN &&
742
- env[rest[i][0][VALUE]][STATS][RETURNS] !==
743
- args[i][STATS].type
744
- ) {
745
- errorStack.set(
746
- key.str,
747
- `Incorrect type of arguments ${i} for (${
748
- first[VALUE]
749
- }). Expected (${toTypeNames(
750
- args[i][STATS].type
751
- )}) but got (${toTypeNames(
752
- env[rest[i][0][VALUE]][STATS][RETURNS]
753
- )}) (${stringifyArgs(exp)})`
754
- )
755
- } else {
756
- if (
757
- rest[i].length &&
758
- env[rest[i][0][VALUE]] &&
759
- args[i][STATS].type === UNKNOWN &&
760
- !env[rest[i][0][VALUE]].retried
761
- ) {
762
- env[rest[i][0][VALUE]].retried = true
763
- if (!scope[SCOPE_NAME])
764
- scope[SCOPE_NAME] = scope[1][VALUE]
765
- stack.unshift(() => check(exp, env, scope))
766
781
  }
767
782
  }
768
783
  }
package/src/macros.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  VALUE,
16
16
  WORD
17
17
  } from './keywords.js'
18
- import { stringifyArgs } from './utils.js'
18
+ import { hasBlock, stringifyArgs } from './utils.js'
19
19
  export const SUGGAR = {
20
20
  // Syntactic suggars
21
21
  PIPE: '|>',
@@ -821,8 +821,7 @@ export const replaceStrings = (source) => {
821
821
  )
822
822
  return source
823
823
  }
824
- const hasBlock = (body) =>
825
- body[0] && body[0][TYPE] === APPLY && body[0][VALUE] === KEYWORDS.BLOCK
824
+
826
825
  const iron = (scope) => {
827
826
  const indecies = scope
828
827
  .map((x, i) => {
package/src/utils.js CHANGED
@@ -190,11 +190,16 @@ const deepShake = (tree, deps, visited = new Set(), ignored = new Set()) => {
190
190
  deepShake(deps.get(value).value, deps, visited, ignored)
191
191
  }
192
192
  }
193
+
194
+ export const hasBlock = (body) =>
195
+ body[0] && body[0][TYPE] === APPLY && body[0][VALUE] === KEYWORDS.BLOCK
196
+
193
197
  const extractDeps = (visited, deps) =>
194
198
  [...visited]
195
199
  .map((x) => deps.get(x))
196
200
  .sort((a, b) => a.index - b.index)
197
201
  .map((x) => x.value)
202
+
198
203
  const toIgnore = (ast) => {
199
204
  const out = []
200
205
  const dfs = (exp) => {