fez-lisp 1.5.86 → 1.5.87

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.86",
5
+ "version": "1.5.87",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -1,12 +1,16 @@
1
1
  import {
2
2
  APPLY,
3
3
  ATOM,
4
+ FALSE,
4
5
  KEYWORDS,
5
6
  PLACEHOLDER,
6
- PREDICATES_SET,
7
+ PREDICATE_SUFFIX,
8
+ PREDICATES_INPUT_SET,
9
+ PREDICATES_OUTPUT_SET,
7
10
  SPECIAL_FORMS_SET,
8
11
  STATIC_TYPES,
9
12
  STATIC_TYPES_SET,
13
+ TRUE,
10
14
  TYPE,
11
15
  VALUE,
12
16
  WORD
@@ -30,7 +34,12 @@ import {
30
34
  VARIABLE_ORDER_INDEX,
31
35
  COLLECTION
32
36
  } from './types.js'
33
- import { hasApplyLambdaBlock, hasBlock, stringifyArgs } from './utils.js'
37
+ import {
38
+ getSuffix,
39
+ hasApplyLambdaBlock,
40
+ hasBlock,
41
+ stringifyArgs
42
+ } from './utils.js'
34
43
 
35
44
  export const identity = (name) => [
36
45
  [0, 'let'],
@@ -54,6 +63,50 @@ const deepLambdaReturn = (rest, condition) => {
54
63
  const rem = hasBlock(body) ? body.at(-1) : body
55
64
  return condition(rem) ? rem : deepLambdaReturn(rem, condition)
56
65
  }
66
+ const checkPredicateName = (exp, rest, warningStack) => {
67
+ if (getSuffix(rest[0][VALUE]) === PREDICATE_SUFFIX) {
68
+ const last = rest.at(-1)
69
+ if (isLeaf(last)) {
70
+ if (last[TYPE] === ATOM && last[VALUE] !== TRUE && last[VALUE] !== FALSE)
71
+ warningStack.add(
72
+ `Assigning predicate (ending in ?) variable (${
73
+ rest[0][VALUE]
74
+ }) to an (${
75
+ STATIC_TYPES.ATOM
76
+ }) that is not (or ${TRUE} ${FALSE}) (${stringifyArgs(rest)})`
77
+ )
78
+ else if (
79
+ last[TYPE] === WORD &&
80
+ getSuffix(last[VALUE]) !== PREDICATE_SUFFIX &&
81
+ !PREDICATES_OUTPUT_SET.has(last[VALUE])
82
+ )
83
+ warningStack.add(
84
+ `Assigning predicate (ending in ?) variable (${
85
+ rest[0][VALUE]
86
+ }) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
87
+ exp
88
+ )})`
89
+ )
90
+ } else if (last[0][0] === APPLY) {
91
+ const application = last[0]
92
+ switch (application[VALUE]) {
93
+ default:
94
+ if (
95
+ getSuffix(application[VALUE]) !== PREDICATE_SUFFIX &&
96
+ !PREDICATES_OUTPUT_SET.has(application[VALUE])
97
+ )
98
+ warningStack.add(
99
+ `Assigning predicate (ending in ?) variable (${
100
+ application[VALUE]
101
+ }) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
102
+ exp
103
+ )})`
104
+ )
105
+ break
106
+ }
107
+ }
108
+ }
109
+ }
57
110
  // const assign = (a, b, i) => {
58
111
  // a[i] = b[i]
59
112
  // }
@@ -164,6 +217,7 @@ export const typeCheck = (ast) => {
164
217
  )
165
218
  } else {
166
219
  const name = rest[0][VALUE]
220
+ // Predicate name consistency
167
221
  const resolveRetunType = (returns, rem, prop) => {
168
222
  if (returns[TYPE] === ATOM) {
169
223
  // ATOM ASSIGMENT
@@ -324,6 +378,7 @@ export const typeCheck = (ast) => {
324
378
  check(rightHand, env, exp)
325
379
  }
326
380
  } else {
381
+ checkPredicateName(exp, rest, warningStack)
327
382
  const isL = isLeaf(rightHand)
328
383
  if (isL && rightHand[TYPE] === WORD) {
329
384
  // TODO make sure this prevents the assigment all together
@@ -574,10 +629,10 @@ export const typeCheck = (ast) => {
574
629
  }
575
630
  }
576
631
  }
577
-
578
632
  // also type of arg
579
633
  const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
580
634
  for (let i = 0; i < args.length; ++i) {
635
+ const isRestILeaf = isLeaf(rest[i])
581
636
  // type check
582
637
  // TODO get rof pred type
583
638
  // const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
@@ -585,50 +640,57 @@ export const typeCheck = (ast) => {
585
640
  if (first[TYPE] === APPLY && isSpecial) {
586
641
  if (
587
642
  MAIN_TYPE === ATOM &&
588
- PREDICATES_SET.has(first[VALUE]) &&
589
- !isLeaf(rest[i]) &&
590
- rest[i][0][TYPE] === APPLY &&
591
- rest[i][0][VALUE] === KEYWORDS.CALL_FUNCTION
643
+ PREDICATES_INPUT_SET.has(first[VALUE])
592
644
  ) {
593
- if (isLeaf(rest[i].at(-1))) {
594
- const fnName = rest[i].at(-1)[VALUE]
595
- const fn = env[fnName]
596
- if (fn && fn[STATS][RETURNS][0] !== MAIN_TYPE) {
597
- errorStack.add(
598
- `Incorrect type of argument (${i}) for (${
599
- first[VALUE]
600
- }). Expected (${toTypeNames(
601
- MAIN_TYPE
602
- )}) but got an (${toTypeNames(
603
- fn[STATS][RETURNS][0]
604
- )}) (${stringifyArgs(exp)}) (check #26)`
605
- )
606
- }
607
- } else {
608
- const body = rest[i].at(-1).at(-1)
609
- const rem = hasBlock(body) ? body.at(-1) : body
610
- const returns = isLeaf(rem) ? rem : rem[0]
611
- if (returns[TYPE] === ATOM) {
612
- if (MAIN_TYPE !== ATOM) {
645
+ // if (isRestILeaf && rest[i][TYPE] === ATOM && rest[i][VALUE] !== TRUE && rest[i][TYPE] !== FALSE) throw some rror
646
+ // else if (
647
+ // isRestILeaf && est[i][TYPE] === ATOM && (rest[i][VALUE] === TRUE || rest[i][VALUE] === FALSE)
648
+ // ) continue
649
+ // else
650
+ if (
651
+ !isRestILeaf &&
652
+ rest[i][0][TYPE] === APPLY &&
653
+ rest[i][0][VALUE] === KEYWORDS.CALL_FUNCTION
654
+ ) {
655
+ if (isLeaf(rest[i].at(-1))) {
656
+ const fnName = rest[i].at(-1)[VALUE]
657
+ const fn = env[fnName]
658
+ if (fn && fn[STATS][RETURNS][0] !== ATOM) {
613
659
  errorStack.add(
614
- `Incorrect type of argument ${i} for (${
660
+ `Incorrect type of argument (${i}) for (${
615
661
  first[VALUE]
616
662
  }). Expected (${toTypeNames(
617
- MAIN_TYPE
618
- )}) but got an (${toTypeNames(
619
663
  ATOM
620
- )}) (${stringifyArgs(exp)}) (check #27)`
664
+ )}) but got an (${toTypeNames(
665
+ fn[STATS][RETURNS][0]
666
+ )}) (${stringifyArgs(exp)}) (check #26)`
621
667
  )
622
668
  }
623
- } else if (env[returns[VALUE]]) {
624
- if (
625
- MAIN_TYPE !== env[returns[VALUE]][STATS][RETURNS][0]
669
+ } else {
670
+ const body = rest[i].at(-1).at(-1)
671
+ const rem = hasBlock(body) ? body.at(-1) : body
672
+ const returns = isLeaf(rem) ? rem : rem[0]
673
+ if (returns[TYPE] === ATOM) {
674
+ if (MAIN_TYPE !== ATOM) {
675
+ errorStack.add(
676
+ `Incorrect type of argument ${i} for (${
677
+ first[VALUE]
678
+ }). Expected (${toTypeNames(
679
+ MAIN_TYPE
680
+ )}) but got an (${toTypeNames(
681
+ ATOM
682
+ )}) (${stringifyArgs(exp)}) (check #27)`
683
+ )
684
+ }
685
+ } else if (
686
+ env[returns[VALUE]] &&
687
+ env[returns[VALUE]][STATS][RETURNS][0] !== ATOM
626
688
  ) {
627
689
  errorStack.add(
628
690
  `Incorrect type of argument ${i} for (${
629
691
  first[VALUE]
630
692
  }). Expected (${toTypeNames(
631
- MAIN_TYPE
693
+ ATOM
632
694
  )}) but got (${toTypeNames(
633
695
  env[returns[VALUE]][STATS][TYPE_PROP]
634
696
  )}) (${stringifyArgs(exp)}) (check #29)`
@@ -639,89 +701,88 @@ export const typeCheck = (ast) => {
639
701
  }
640
702
  const isCast = STATIC_TYPES_SET.has(first[VALUE])
641
703
  const expectedArgs = env[first[VALUE]][STATS][ARGUMENTS]
642
- for (let i = 0; i < rest.length; ++i) {
643
- const MAIN_TYPE = expectedArgs[i][STATS][TYPE_PROP][0]
644
- if (MAIN_TYPE === UNKNOWN && !isCast) continue
645
- if (!isLeaf(rest[i])) {
646
- const CAR = rest[i][0][VALUE]
647
- const isKnown =
648
- env[CAR] && env[CAR][STATS][RETURNS][0] !== UNKNOWN
649
- if (isKnown && !isCast) {
650
- if (env[CAR][STATS][RETURNS][0] !== MAIN_TYPE) {
704
+ const EXPECTED_TYPE = expectedArgs[i][STATS][TYPE_PROP][0]
705
+ // IF UKNOWN andnot csted -we have nothing much to do
706
+ if (EXPECTED_TYPE === UNKNOWN && !isCast) continue
707
+ if (!isRestILeaf) {
708
+ const CAR = rest[i][0][VALUE]
709
+ const isKnown =
710
+ env[CAR] && env[CAR][STATS][RETURNS][0] !== UNKNOWN
711
+ if (isKnown && !isCast) {
712
+ if (env[CAR][STATS][RETURNS][0] !== EXPECTED_TYPE) {
713
+ errorStack.add(
714
+ `Incorrect type of argument (${i}) for special form (${
715
+ first[VALUE]
716
+ }). Expected (${toTypeNames(
717
+ EXPECTED_TYPE
718
+ )}) but got (${toTypeNames(
719
+ env[CAR][STATS][RETURNS][0]
720
+ )}) (${stringifyArgs(exp)}) (check #1)`
721
+ )
722
+ }
723
+ // never reached because there is only 1 subtype at the moment
724
+ // else if (
725
+ // PRED_TYPE &&
726
+ // env[CAR][STATS][RETURNS][1] !== PRED_TYPE
727
+ // ) {
728
+ // }
729
+ }
730
+ } else {
731
+ switch (rest[i][TYPE]) {
732
+ case WORD:
733
+ {
734
+ const CAR = rest[i][VALUE]
735
+ const isKnown =
736
+ env[CAR] &&
737
+ env[CAR][STATS][TYPE_PROP][0] !== UNKNOWN
738
+ if (isKnown && !isCast) {
739
+ if (
740
+ EXPECTED_TYPE !== env[CAR][STATS][TYPE_PROP][0]
741
+ ) {
742
+ errorStack.add(
743
+ `Incorrect type of argument (${i}) for special form (${
744
+ first[VALUE]
745
+ }). Expected (${toTypeNames(
746
+ EXPECTED_TYPE
747
+ )}) but got (${toTypeNames(
748
+ env[CAR][STATS][TYPE_PROP][0]
749
+ )}) (${stringifyArgs(exp)}) (check #3)`
750
+ )
751
+ }
752
+ } else if (env[CAR]) {
753
+ if (isCast) {
754
+ // CAST assigment
755
+ env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
756
+ root[first[VALUE]][STATS][RETURNS][0]
757
+
758
+ // root[first[VALUE]][STATS][RETURNS] =
759
+ // root[first[VALUE]][STATS][RETURNS]
760
+ } else {
761
+ // VALUE assigment
762
+ env[CAR][STATS][TYPE_PROP][0] = EXPECTED_TYPE
763
+ }
764
+ }
765
+ }
766
+ break
767
+ case ATOM: {
768
+ if (rest[i][TYPE] !== EXPECTED_TYPE) {
651
769
  errorStack.add(
652
770
  `Incorrect type of argument (${i}) for special form (${
653
771
  first[VALUE]
654
772
  }). Expected (${toTypeNames(
655
- MAIN_TYPE
773
+ EXPECTED_TYPE
656
774
  )}) but got (${toTypeNames(
657
- env[CAR][STATS][RETURNS][0]
658
- )}) (${stringifyArgs(exp)}) (check #1)`
775
+ rest[i][TYPE]
776
+ )}) (${stringifyArgs(exp)}) (check #2)`
659
777
  )
660
778
  }
661
- // never reached because there is only 1 subtype at the moment
662
- // else if (
663
- // PRED_TYPE &&
664
- // env[CAR][STATS][RETURNS][1] !== PRED_TYPE
665
- // ) {
666
- // }
667
- }
668
- } else {
669
- switch (rest[i][TYPE]) {
670
- case WORD:
671
- {
672
- const CAR = rest[i][VALUE]
673
- const isKnown =
674
- env[CAR] &&
675
- env[CAR][STATS][TYPE_PROP][0] !== UNKNOWN
676
- if (isKnown && !isCast) {
677
- if (
678
- MAIN_TYPE !== env[CAR][STATS][TYPE_PROP][0]
679
- ) {
680
- errorStack.add(
681
- `Incorrect type of argument (${i}) for special form (${
682
- first[VALUE]
683
- }). Expected (${toTypeNames(
684
- MAIN_TYPE
685
- )}) but got (${toTypeNames(
686
- env[CAR][STATS][TYPE_PROP][0]
687
- )}) (${stringifyArgs(exp)}) (check #3)`
688
- )
689
- }
690
- } else if (env[CAR]) {
691
- if (isCast) {
692
- // CAST assigment
693
- env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
694
- root[first[VALUE]][STATS][RETURNS][0]
695
-
696
- // root[first[VALUE]][STATS][RETURNS] =
697
- // root[first[VALUE]][STATS][RETURNS]
698
- } else {
699
- // VALUE assigment
700
- env[CAR][STATS][TYPE_PROP][0] = MAIN_TYPE
701
- }
702
- }
703
- }
704
- break
705
- case ATOM: {
706
- if (rest[i][TYPE] !== MAIN_TYPE) {
707
- errorStack.add(
708
- `Incorrect type of argument (${i}) for special form (${
709
- first[VALUE]
710
- }). Expected (${toTypeNames(
711
- MAIN_TYPE
712
- )}) but got (${toTypeNames(
713
- rest[i][TYPE]
714
- )}) (${stringifyArgs(exp)}) (check #2)`
715
- )
716
- }
717
- break
718
- }
779
+ break
719
780
  }
720
781
  }
721
782
  }
722
783
  }
723
784
  // type checking
724
- else if (isLeaf(rest[i])) {
785
+ else if (isRestILeaf) {
725
786
  const T =
726
787
  rest[i][TYPE] === WORD && env[rest[i][VALUE]]
727
788
  ? env[rest[i][VALUE]][STATS][TYPE_PROP][0]
package/src/keywords.js CHANGED
@@ -77,10 +77,22 @@ export const SPECIAL_FORMS_SET = new Set(
77
77
  Object.values(KEYWORDS).concat(Object.values(STATIC_TYPES))
78
78
  )
79
79
  export const STATIC_TYPES_SET = new Set(Object.values(STATIC_TYPES))
80
- export const PREDICATES_SET = new Set([
80
+ export const PREDICATES_INPUT_SET = new Set([
81
81
  KEYWORDS.IF,
82
82
  KEYWORDS.AND,
83
83
  KEYWORDS.OR,
84
84
  KEYWORDS.NOT,
85
85
  KEYWORDS.LOOP
86
86
  ])
87
+ export const PREDICATES_OUTPUT_SET = new Set([
88
+ KEYWORDS.AND,
89
+ KEYWORDS.OR,
90
+ KEYWORDS.NOT,
91
+ KEYWORDS.EQUAL,
92
+ KEYWORDS.GREATHER_THAN,
93
+ KEYWORDS.LESS_THAN,
94
+ KEYWORDS.GREATHER_THAN_OR_EQUAL,
95
+ KEYWORDS.LESS_THAN_OR_EQUAL,
96
+ KEYWORDS.IS_ATOM,
97
+ KEYWORDS.IS_LAMBDA
98
+ ])
package/src/macros.js CHANGED
@@ -10,14 +10,12 @@ import {
10
10
  FALSE,
11
11
  KEYWORDS,
12
12
  PLACEHOLDER,
13
- PREDICATE_SUFFIX,
14
- STATIC_TYPES,
15
13
  TRUE,
16
14
  TYPE,
17
15
  VALUE,
18
16
  WORD
19
17
  } from './keywords.js'
20
- import { getSuffix, hasBlock, stringifyArgs } from './utils.js'
18
+ import { hasBlock, stringifyArgs } from './utils.js'
21
19
  export const SUGGAR = {
22
20
  // Syntactic suggars
23
21
  PIPE: '|>',