fez-lisp 1.5.88 → 1.5.90

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/check.js +158 -51
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.88",
5
+ "version": "1.5.90",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -90,6 +90,9 @@ const checkPredicateName = (exp, rest, warningStack) => {
90
90
  } else if (last[0][0] === APPLY) {
91
91
  const application = last[0]
92
92
  switch (application[VALUE]) {
93
+ case KEYWORDS.IF:
94
+ // TODO finishthis #1
95
+ break
93
96
  default:
94
97
  if (
95
98
  getSuffix(application[VALUE]) !== PREDICATE_SUFFIX &&
@@ -107,6 +110,23 @@ const checkPredicateName = (exp, rest, warningStack) => {
107
110
  }
108
111
  }
109
112
  }
113
+ const checkPredicateNameDeep = (name, exp, rest, returns, warningStack) => {
114
+ if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
115
+ const fn = rest.at(-1).at(-1).at(-1)
116
+ checkPredicateName(
117
+ exp,
118
+ [
119
+ [WORD, name],
120
+ isLeaf(fn)
121
+ ? fn // when apply is a word (let x? (lambda (apply [] array:empty!)))
122
+ : drillReturnType(fn, (r) => r[VALUE] === KEYWORDS.CALL_FUNCTION) // when apply is an annonymous lambda // (let fn? (lambda x (apply x (lambda x (array:empty! [])))))
123
+ ],
124
+ warningStack
125
+ )
126
+ } else {
127
+ checkPredicateName(exp, [[WORD, name], returns], warningStack)
128
+ }
129
+ }
110
130
  // const assign = (a, b, i) => {
111
131
  // a[i] = b[i]
112
132
  // }
@@ -177,6 +197,8 @@ export const typeCheck = (ast) => {
177
197
  root[ORDER] = 0
178
198
  const errorStack = new Set()
179
199
  const warningStack = new Set()
200
+ // TODO delete this
201
+ const tempStack = new Set()
180
202
  const Types = new Map()
181
203
  const stack = []
182
204
  const check = (exp, env, scope) => {
@@ -306,9 +328,11 @@ export const typeCheck = (ast) => {
306
328
  }
307
329
  break
308
330
  default:
309
- checkPredicateName(
331
+ checkPredicateNameDeep(
332
+ name,
310
333
  exp,
311
- [[WORD, name], returns],
334
+ rest,
335
+ returns,
312
336
  warningStack
313
337
  )
314
338
  if (!env[returns[VALUE]])
@@ -317,41 +341,6 @@ export const typeCheck = (ast) => {
317
341
  else if (
318
342
  env[returns[VALUE]][STATS][TYPE_PROP][0] === APPLY
319
343
  ) {
320
- if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
321
- const fn = rest.at(-1).at(-1).at(-1)
322
- checkPredicateName(
323
- exp,
324
- [
325
- [WORD, name],
326
- isLeaf(fn)
327
- ? fn // when apply is a word (let x? (lambda (apply [] array:empty!)))
328
- : drillReturnType(
329
- fn,
330
- (r) => r[VALUE] === KEYWORDS.CALL_FUNCTION
331
- ) // when apply is an annonymous lambda // (let fn? (lambda x (apply x (lambda x (array:empty! [])))))
332
- ],
333
- warningStack
334
- )
335
- }
336
-
337
- // TODO This seems to be able to be deleted
338
- // FOR NOT IT CAN BE
339
- // if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
340
- // if (isLeaf(rest.at(-1).at(-1).at(-1))) {
341
- // const fnName = rest.at(-1).at(-1).at(-1)[VALUE]
342
- // const fn = env[fnName]
343
- // env[name][STATS][TYPE_PROP][0] =
344
- // fn[STATS][RETURNS][0]
345
- // } else {
346
- // const [returns, rem] = drillReturnType(
347
- // rest.at(-1).at(-1).at(-1),
348
- // (returns) =>
349
- // returns[VALUE] === KEYWORDS.CALL_FUNCTION
350
- // )
351
- // resolveRetunType(returns, rem, TYPE_PROP)
352
- // }
353
- // }
354
-
355
344
  // ALWAYS APPLY
356
345
  // rest.at(-1)[0][TYPE] === APPLY
357
346
  // Here is upon application to store the result in the variable
@@ -632,16 +621,18 @@ export const typeCheck = (ast) => {
632
621
  )
633
622
  } else if (!env[first[VALUE]][STATS][ARG_COUNT]) {
634
623
  // TODO recursively take return type of applicaion
635
- if (env[first[VALUE]][STATS][RETURNS][0] === APPLY) {
636
- env[first[VALUE]][STATS][RETURNS] = [UNKNOWN]
637
- }
624
+ // if (env[first[VALUE]][STATS][RETURNS][0] === APPLY) {
625
+ // env[first[VALUE]][STATS][RETURNS] = [UNKNOWN]
626
+ // }
638
627
  // FN ASSIGMENT
628
+
629
+ // ASSIGMENT of paramaters of lambda that are a lambda
630
+ // minus one to remove the body
639
631
  env[first[VALUE]][STATS][TYPE_PROP] = [APPLY]
640
632
  env[first[VALUE]][STATS][ARG_COUNT] = rest.length
641
633
  env[first[VALUE]][STATS][ARGUMENTS] = fillUknownArgs(
642
634
  rest.length
643
635
  )
644
- // ASSIGMENT of paramaters of lambda that are a lambda
645
636
  for (let i = 0; i < rest.length; ++i) {
646
637
  const arg = env[first[VALUE]][STATS][ARGUMENTS]
647
638
  arg[i] = {
@@ -654,13 +645,23 @@ export const typeCheck = (ast) => {
654
645
  [ARG_COUNT]: 0
655
646
  }
656
647
  }
657
- switch (rest[i][TYPE]) {
658
- case ATOM:
659
- arg[i][STATS][TYPE_PROP][0] = ATOM
648
+ const ARG = isLeaf(rest[i]) ? rest[i] : rest[i][0]
649
+ if (!env[ARG[VALUE]]) continue
650
+ // console.log(stringifyArgs(exp), ARG)
651
+ switch (ARG[TYPE]) {
652
+ // THERE ARE NO ATOM ARGUMENTS
653
+ // case ATOM:
654
+ // break
655
+ case APPLY:
656
+ // passing arg asA APPLICATION
657
+ if (arg[i][STATS][TYPE_PROP][0] === UNKNOWN)
658
+ arg[i][STATS][TYPE_PROP] =
659
+ env[ARG[VALUE]][STATS][RETURNS]
660
660
  break
661
661
  case WORD:
662
- case APPLY:
663
- arg[i][STATS] = env[rest[i][VALUE]][STATS]
662
+ // if param is a word we assosiate them by referanc
663
+ if (arg[i][STATS][TYPE_PROP][0] === UNKNOWN)
664
+ arg[i][STATS] = env[ARG[VALUE]][STATS]
664
665
  break
665
666
  }
666
667
  }
@@ -674,16 +675,12 @@ export const typeCheck = (ast) => {
674
675
  // TODO get rof pred type
675
676
  // const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
676
677
  const MAIN_TYPE = args[i][STATS][TYPE_PROP][0]
678
+
677
679
  if (first[TYPE] === APPLY && isSpecial) {
678
680
  if (
679
681
  MAIN_TYPE === ATOM &&
680
682
  PREDICATES_INPUT_SET.has(first[VALUE])
681
683
  ) {
682
- // if (isRestILeaf && rest[i][TYPE] === ATOM && rest[i][VALUE] !== TRUE && rest[i][TYPE] !== FALSE) throw some rror
683
- // else if (
684
- // isRestILeaf && est[i][TYPE] === ATOM && (rest[i][VALUE] === TRUE || rest[i][VALUE] === FALSE)
685
- // ) continue
686
- // else
687
684
  if (
688
685
  !isRestILeaf &&
689
686
  rest[i][0][TYPE] === APPLY &&
@@ -763,6 +760,15 @@ export const typeCheck = (ast) => {
763
760
  // env[CAR][STATS][RETURNS][1] !== PRED_TYPE
764
761
  // ) {
765
762
  // }
763
+ } else if (!isKnown && !isCast && env[CAR]) {
764
+ if (
765
+ env[CAR][STATS][TYPE_PROP][0] === APPLY &&
766
+ root[first[VALUE]][STATS][RETURNS][0] !== UNKNOWN &&
767
+ env[CAR][STATS][RETURNS][0] !== UNKNOWN
768
+ )
769
+ env[CAR][STATS][RETURNS][0] =
770
+ root[first[VALUE]][STATS][RETURNS][0]
771
+ // TODO also handle casting
766
772
  }
767
773
  } else {
768
774
  switch (rest[i][TYPE]) {
@@ -940,6 +946,107 @@ export const typeCheck = (ast) => {
940
946
  exp
941
947
  )}) (check #777)`
942
948
  )
949
+ } else {
950
+ // ANONYMOUS LAMBDAS TYPE CHECKING
951
+ const local = Object.create(env)
952
+ const lambdaName = `lambda::annonymous::${i}::${performance
953
+ .now()
954
+ .toString()
955
+ .replace('.', 0)}*`
956
+ check(
957
+ [
958
+ [APPLY, KEYWORDS.DEFINE_VARIABLE],
959
+ [WORD, lambdaName],
960
+ rest[i]
961
+ ],
962
+ local,
963
+ scope
964
+ )
965
+ const match1 = () => {
966
+ const actual = local[lambdaName]
967
+ const expected = args[i]
968
+ if (
969
+ expected[STATS][RETURNS][0] !==
970
+ UNKNOWN &&
971
+ actual[STATS][RETURNS][0] !== UNKNOWN &&
972
+ expected[STATS][RETURNS][0] !==
973
+ actual[STATS][RETURNS][0]
974
+ ) {
975
+ errorStack.add(
976
+ `Incorrect return type for (${
977
+ expected[STATS][SIGNATURE]
978
+ }) the (lambda) argument of (${
979
+ first[VALUE]
980
+ }) at position (${i}). Expected (${toTypeNames(
981
+ expected[STATS][RETURNS][0]
982
+ )}) but got (${toTypeNames(
983
+ actual[STATS][RETURNS][0]
984
+ )}) (${stringifyArgs(
985
+ exp
986
+ )}) (check #779)`
987
+ )
988
+ } else if (
989
+ actual[STATS].retried <
990
+ MAX_RETRY_DEFINITION
991
+ ) {
992
+ actual[STATS].retried += 1
993
+ stack.unshift(() => match1())
994
+ }
995
+ }
996
+ match1()
997
+ for (
998
+ let j = 0;
999
+ j < args[i][STATS][ARGUMENTS].length;
1000
+ ++j
1001
+ ) {
1002
+ const match2 = () => {
1003
+ const actual =
1004
+ local[lambdaName][STATS][ARGUMENTS][j]
1005
+ const expected =
1006
+ args[i][STATS][ARGUMENTS][j]
1007
+ if (
1008
+ actual[STATS][TYPE_PROP][0] !==
1009
+ UNKNOWN &&
1010
+ expected[STATS][TYPE_PROP][0] !==
1011
+ UNKNOWN &&
1012
+ actual[STATS][TYPE_PROP][0] !==
1013
+ expected[STATS][TYPE_PROP][0]
1014
+ )
1015
+ errorStack.add(
1016
+ `Incorrect type for (lambda) (${
1017
+ args[i][STATS][SIGNATURE]
1018
+ }) argument at position (${j}) named as (${
1019
+ local[lambdaName][STATS][
1020
+ ARGUMENTS
1021
+ ][j][STATS][SIGNATURE]
1022
+ }). Expected (${toTypeNames(
1023
+ args[i][STATS][ARGUMENTS][j][
1024
+ STATS
1025
+ ][TYPE_PROP][0]
1026
+ )}) but got (${toTypeNames(
1027
+ local[lambdaName][STATS][
1028
+ ARGUMENTS
1029
+ ][j][STATS][TYPE_PROP][0]
1030
+ )}) (${stringifyArgs(
1031
+ exp
1032
+ )}) (check #780)`
1033
+ )
1034
+ else if (
1035
+ actual[STATS].retried <
1036
+ MAX_RETRY_DEFINITION
1037
+ ) {
1038
+ actual[STATS].retried += 1
1039
+ stack.unshift(() => match2())
1040
+ }
1041
+ }
1042
+ match2()
1043
+ }
1044
+ // console.log(
1045
+ // env[first[VALUE]][STATS][ARGUMENTS][i][
1046
+ // STATS
1047
+ // ],
1048
+ // args[i][STATS]
1049
+ // )
943
1050
  }
944
1051
  } else {
945
1052
  // TODO fix curry: lambdas enter here as undefined