fez-lisp 1.6.81 → 1.6.83

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.6.81",
5
+ "version": "1.6.83",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -57,7 +57,8 @@ import {
57
57
  log,
58
58
  logExp,
59
59
  stringifyArgs,
60
- wrapInApplyLambda
60
+ wrapInApplyLambda,
61
+ wrapInBlock
61
62
  } from './utils.js'
62
63
 
63
64
  export const identity = (name) => [
@@ -661,7 +662,12 @@ const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
661
662
  if (times === level - 1) {
662
663
  setPropToType(env[name][STATS], prop, {
663
664
  [TYPE_PROP]: types.length
664
- ? [type, new SubType([types.at(-1)])]
665
+ ? [
666
+ type,
667
+ new SubType([
668
+ types.at(-1) === COLLECTION ? UNKNOWN : types.at(-1)
669
+ ])
670
+ ]
665
671
  : [UNKNOWN]
666
672
  })
667
673
  } else {
@@ -923,15 +929,12 @@ const initArrayType = ({ rem, env }) => {
923
929
  subT.add(head[1].types[0])
924
930
  }
925
931
  const [main, sub] = ret[0]
926
- if (isSubType(sub) && sub.types.at(-1) === COLLECTION) sub.types.pop()
927
932
  return {
928
933
  [TYPE_PROP]: [APPLY],
929
934
  [RETURNS]: [
930
935
  COLLECTION,
931
936
  isCollection
932
- ? new SubType(
933
- isSubType(sub) ? [COLLECTION, ...sub] : [COLLECTION, main]
934
- )
937
+ ? new SubType(isSubType(sub) ? [COLLECTION, ...sub] : [COLLECTION])
935
938
  : new SubType(isSubType(sub) ? [...sub] : [main])
936
939
  ]
937
940
  }
@@ -1016,137 +1019,133 @@ const resolveReturnType = ({
1016
1019
  // ALWAYS APPLY
1017
1020
  // rest.at(-1)[0][TYPE] === APPLY
1018
1021
  // Here is upon application to store the result in the variable
1019
- else if (isUnknownType(env[name][STATS]))
1020
- stagger(stack, 'prepend', exp, () => {
1021
- if (isGenericReturn(env[returns[VALUE]][STATS])) {
1022
- // env[name][STATS][TYPE_PROP] =
1023
- const [index, multiplier] =
1024
- env[returns[VALUE]][STATS][RETURNS][2]
1025
- const genericReturn = rem.slice(1)[index]
1026
- const nestGeneric =
1027
- env[returns[VALUE]][STATS][RETURNS][0] === COLLECTION
1028
- ? isSubType(env[returns[VALUE]][STATS][RETURNS][1])
1029
- ? env[returns[VALUE]][STATS][RETURNS][1].nestedLevels()
1030
- : 0
1031
- : 0
1022
+ if (isGenericReturn(env[returns[VALUE]][STATS])) {
1023
+ // env[name][STATS][TYPE_PROP] =
1024
+ const [index, multiplier] = env[returns[VALUE]][STATS][RETURNS][2]
1025
+ const genericReturn = rem.slice(1)[index]
1026
+ const nestGeneric =
1027
+ env[returns[VALUE]][STATS][RETURNS][0] === COLLECTION
1028
+ ? isSubType(env[returns[VALUE]][STATS][RETURNS][1])
1029
+ ? env[returns[VALUE]][STATS][RETURNS][1].nestedLevels()
1030
+ : 0
1031
+ : 0
1032
1032
 
1033
- const head = isLeaf(genericReturn)
1034
- ? genericReturn
1035
- : genericReturn[0]
1033
+ const head = isLeaf(genericReturn)
1034
+ ? genericReturn
1035
+ : genericReturn[0]
1036
1036
 
1037
- switch (head[TYPE]) {
1038
- case ATOM:
1039
- setTypeToAtom(env[name][STATS])
1040
- break
1041
- case WORD:
1042
- if (env[head[VALUE]])
1043
- env[name][STATS][prop] =
1044
- env[head[VALUE]][STATS][TYPE_PROP]
1045
- break
1046
- case APPLY:
1047
- switch (head[VALUE]) {
1048
- case KEYWORDS.ANONYMOUS_FUNCTION:
1049
- {
1050
- // TODO figure out a better way to do this
1051
- // This is initialization of identity or any other
1052
- // function that returns it's argument
1053
- // Redefine the variable but since it's an error doing that
1054
- // Delete it first
1055
- delete env[name]
1056
- check(
1057
- [
1058
- [APPLY, KEYWORDS.DEFINE_VARIABLE],
1059
- [WORD, name],
1060
- genericReturn
1061
- ],
1062
- env,
1063
- exp
1064
- )
1037
+ switch (head[TYPE]) {
1038
+ case ATOM:
1039
+ setTypeToAtom(env[name][STATS])
1040
+ break
1041
+ case WORD:
1042
+ if (env[head[VALUE]])
1043
+ setPropToType(
1044
+ env[name][STATS],
1045
+ prop,
1046
+ env[head[VALUE]][STATS]
1047
+ )
1048
+ break
1049
+ case APPLY:
1050
+ switch (head[VALUE]) {
1051
+ case KEYWORDS.ANONYMOUS_FUNCTION:
1052
+ {
1053
+ // TODO figure out a better way to do this
1054
+ // This is initialization of identity or any other
1055
+ // function that returns it's argument
1056
+ // Redefine the variable but since it's an error doing that
1057
+ // Delete it first
1058
+ delete env[name]
1059
+ check(
1060
+ [
1061
+ [APPLY, KEYWORDS.DEFINE_VARIABLE],
1062
+ [WORD, name],
1063
+ genericReturn
1064
+ ],
1065
+ env,
1066
+ exp
1067
+ )
1065
1068
 
1066
- // const n = genericReturn.length
1067
- // setTypeToAbstraction(env[name][STATS])
1068
- // env[name][STATS][ARG_COUNT] = n - 2
1069
- // env[name][STATS][ARGUMENTS] = fillUnknownArgs(
1070
- // n - 2
1071
- // )
1072
- // checkReturnType({
1073
- // exp: [genericReturn],
1074
- // stack,
1075
- // name,
1076
- // env,
1077
- // check
1078
- // })
1079
- }
1080
- break
1081
- case KEYWORDS.CREATE_ARRAY:
1082
- {
1083
- setTypeToCollection(env[name][STATS])
1084
- setPropToSubReturn(
1085
- env[name][STATS],
1086
- TYPE_PROP,
1087
- initArrayType({ rem: genericReturn, env })
1088
- )
1089
- }
1090
- break
1091
- default:
1092
- break
1069
+ // const n = genericReturn.length
1070
+ // setTypeToAbstraction(env[name][STATS])
1071
+ // env[name][STATS][ARG_COUNT] = n - 2
1072
+ // env[name][STATS][ARGUMENTS] = fillUnknownArgs(
1073
+ // n - 2
1074
+ // )
1075
+ // checkReturnType({
1076
+ // exp: [genericReturn],
1077
+ // stack,
1078
+ // name,
1079
+ // env,
1080
+ // check
1081
+ // })
1093
1082
  }
1094
1083
  break
1095
- default:
1096
- if (env[head[VALUE]])
1097
- setTypeToReturn(
1084
+ case KEYWORDS.CREATE_ARRAY:
1085
+ {
1086
+ setTypeToCollection(env[name][STATS])
1087
+ setPropToSubReturn(
1098
1088
  env[name][STATS],
1099
- env[head[VALUE]][STATS]
1089
+ TYPE_PROP,
1090
+ initArrayType({ rem: genericReturn, env })
1100
1091
  )
1092
+ }
1093
+ break
1094
+ default:
1101
1095
  break
1102
1096
  }
1103
- if (env[returns[VALUE]][STATS][RETURNS][0] === COLLECTION) {
1104
- const T = isSubType(env[name][STATS][prop][1])
1105
- ? env[name][STATS][prop][1].types
1106
- : [env[name][STATS][prop][0]]
1107
- if (multiplier === -1) {
1108
- if (nestGeneric === 0) {
1109
- if (T.at(-1) === NUMBER || T.at(-1) === BOOLEAN) {
1110
- if (isSubType(env[name][STATS][prop][1])) {
1111
- if (env[name][STATS][prop][1].types.length === 1)
1112
- env[name][STATS][prop][0] = ATOM
1113
- else {
1114
- env[name][STATS][prop][1] = new SubType(
1115
- env[name][STATS][prop][1].types.slice(1)
1116
- )
1117
- env[name][STATS][prop][0] = COLLECTION
1118
- }
1119
- } else env[name][STATS][prop][0] = ATOM
1097
+ break
1098
+ default:
1099
+ if (env[head[VALUE]])
1100
+ setTypeToReturn(env[name][STATS], env[head[VALUE]][STATS])
1101
+ break
1102
+ }
1103
+ if (env[returns[VALUE]][STATS][RETURNS][0] === COLLECTION) {
1104
+ const T = isSubType(env[name][STATS][prop][1])
1105
+ ? env[name][STATS][prop][1].types
1106
+ : [env[name][STATS][prop][0]]
1107
+ if (multiplier === -1) {
1108
+ if (nestGeneric === 0) {
1109
+ if (T.at(-1) === NUMBER || T.at(-1) === BOOLEAN) {
1110
+ if (isSubType(env[name][STATS][prop][1])) {
1111
+ if (env[name][STATS][prop][1].types.length === 1)
1112
+ env[name][STATS][prop][0] = ATOM
1113
+ else {
1114
+ env[name][STATS][prop][1] = new SubType(
1115
+ env[name][STATS][prop][1].types.slice(1)
1116
+ )
1117
+ env[name][STATS][prop][0] = COLLECTION
1120
1118
  }
1119
+ } else env[name][STATS][prop][0] = ATOM
1120
+ }
1121
+ } else {
1122
+ if (T.length - nestGeneric - 1) {
1123
+ for (let i = 0; i < nestGeneric + 1; ++i)
1124
+ env[name][STATS][prop][1].types.shift()
1125
+ } else {
1126
+ if (T.at(-1) === NUMBER || T.at(-1) === BOOLEAN) {
1127
+ env[name][STATS][prop][0] = ATOM
1128
+ env[name][STATS][prop][1] = new SubType([T.at(-1)])
1121
1129
  } else {
1122
- if (T.length - nestGeneric - 1) {
1123
- for (let i = 0; i < nestGeneric + 1; ++i)
1124
- env[name][STATS][prop][1].types.shift()
1125
- } else {
1126
- if (T.at(-1) === NUMBER || T.at(-1) === BOOLEAN) {
1127
- env[name][STATS][prop][0] = ATOM
1128
- env[name][STATS][prop][0] = T.at(-1)
1129
- } else {
1130
- env[name][STATS][prop][0] = APPLY
1131
- env[name][STATS][prop].length = 1
1132
- }
1133
- }
1130
+ env[name][STATS][prop][0] = APPLY
1131
+ env[name][STATS][prop].length = 1
1134
1132
  }
1135
- } else {
1136
- const st = new SubType([])
1137
- for (let i = 0; i < nestGeneric; ++i) st.add(COLLECTION)
1138
- if (env[name][STATS][prop][0] === COLLECTION)
1139
- st.add(COLLECTION)
1140
- st.add(...T)
1141
- env[name][STATS][prop][0] = COLLECTION
1142
- env[name][STATS][prop][1] = st
1143
1133
  }
1144
1134
  }
1145
- } else
1146
- setTypeToReturnRef(
1147
- env[name][STATS],
1148
- env[returns[VALUE]][STATS]
1149
- )
1135
+ } else {
1136
+ const st = new SubType([])
1137
+ for (let i = 0; i < nestGeneric; ++i) st.add(COLLECTION)
1138
+ if (env[name][STATS][prop][0] === COLLECTION)
1139
+ st.add(COLLECTION)
1140
+ st.add(...T)
1141
+ env[name][STATS][prop][0] = COLLECTION
1142
+ env[name][STATS][prop][1] = st
1143
+ }
1144
+ }
1145
+ }
1146
+ if (isUnknownType(env[name][STATS]))
1147
+ stagger(stack, 'prepend', exp, () => {
1148
+ setTypeToReturnRef(env[name][STATS], env[returns[VALUE]][STATS])
1150
1149
  })
1151
1150
  else {
1152
1151
  // if (SPECIAL_FORMS_SET.has(returns[VALUE]))
@@ -1231,7 +1230,10 @@ export const typeCheck = (
1231
1230
  env[rest[i][0][VALUE]][STATS][SIGNATURE] ===
1232
1231
  KEYWORDS.ANONYMOUS_FUNCTION
1233
1232
  ) {
1234
- if (argsN !== args[i][STATS][ARG_COUNT])
1233
+ if (
1234
+ args[i][STATS][ARG_COUNT] !== VARIADIC &&
1235
+ argsN !== args[i][STATS][ARG_COUNT]
1236
+ )
1235
1237
  throw new TypeError(
1236
1238
  `Incorrect number of arguments for (${
1237
1239
  args[i][STATS][SIGNATURE]
@@ -1275,7 +1277,8 @@ export const typeCheck = (
1275
1277
  )
1276
1278
  throw new TypeError(
1277
1279
  `Incorrect return type for (${
1278
- expected[STATS][SIGNATURE]
1280
+ expected[STATS][SIGNATURE] ??
1281
+ ANONYMOUS_FUNCTION_TYPE_PREFIX
1279
1282
  }) the (${KEYWORDS.ANONYMOUS_FUNCTION}) argument of (${
1280
1283
  first[VALUE]
1281
1284
  }) at position (${i}). Expected (${formatSubType(
@@ -1417,12 +1420,13 @@ export const typeCheck = (
1417
1420
  )
1418
1421
  // TODO check let define types
1419
1422
  const name = rest[0][VALUE]
1420
- if (name[0] !== PLACEHOLDER && env.hasOwnProperty(name))
1423
+ if (name[0] !== PLACEHOLDER && env.hasOwnProperty(name)) {
1421
1424
  throw new ReferenceError(
1422
1425
  `Attempting to redeclare (${name}) which was previously declared in this scope (${stringifyArgs(
1423
1426
  exp
1424
1427
  )})`
1425
1428
  )
1429
+ }
1426
1430
  const rightHand = rest.at(-1)
1427
1431
  const isApply =
1428
1432
  rightHand && rightHand[0] && rightHand[0][TYPE] === APPLY
@@ -1432,6 +1436,7 @@ export const typeCheck = (
1432
1436
  // Types.set(withScope(name, env), () => formatType(name, env))
1433
1437
  // If current scope is root then these are user defined types
1434
1438
  if (isLambda) {
1439
+ env[name][STATS].source = exp
1435
1440
  const lambdaName = `${PLACEHOLDER}${name}`
1436
1441
  const fn = [
1437
1442
  [APPLY, KEYWORDS.DEFINE_VARIABLE],
@@ -1445,8 +1450,8 @@ export const typeCheck = (
1445
1450
  throw new RangeError(
1446
1451
  `Incorrect number of arguments for (${
1447
1452
  expected[STATS][SIGNATURE]
1448
- }) Expected (${expected[ARG_COUNT]}) but got (${
1449
- actual[ARG_COUNT]
1453
+ }) Expected (${expected[STATS][ARG_COUNT]}) but got (${
1454
+ actual[STATS][ARG_COUNT]
1450
1455
  }) (${stringifyArgs(exp)}) (check #1004)`
1451
1456
  )
1452
1457
  }
@@ -1626,14 +1631,12 @@ export const typeCheck = (
1626
1631
  : env[right[VALUE]] == undefined
1627
1632
  ? UNKNOWN
1628
1633
  : env[right[VALUE]][STATS][RETURNS][0]
1629
-
1630
1634
  if (
1631
1635
  type !== UNKNOWN &&
1632
1636
  type !== ANY &&
1633
1637
  !isGenericReturn(env[right[VALUE]][STATS])
1634
1638
  )
1635
1639
  setTypeToReturn(env[name][STATS], env[right[VALUE]][STATS])
1636
-
1637
1640
  const resolve = () => {
1638
1641
  const body = rightHand
1639
1642
  const rem = hasBlock(body) ? body.at(-1) : body
@@ -1650,9 +1653,9 @@ export const typeCheck = (
1650
1653
  })
1651
1654
  }
1652
1655
  resolve()
1653
-
1654
- if (isUnknownType(env[name][STATS]))
1656
+ if (isUnknownType(env[name][STATS])) {
1655
1657
  once(env[name][STATS], exp, stack, () => resolve())
1658
+ }
1656
1659
  }
1657
1660
  check(rightHand, env, scope)
1658
1661
  }
@@ -1850,7 +1853,7 @@ export const typeCheck = (
1850
1853
  }
1851
1854
  // also type of arg
1852
1855
  const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
1853
- // const generics = Array.from(args).fill(null)
1856
+ const generics = Array.from(args).fill(null)
1854
1857
  for (let i = 0; i < args.length; ++i) {
1855
1858
  // type check
1856
1859
  // TODO get rof pred type
@@ -1869,7 +1872,8 @@ export const typeCheck = (
1869
1872
  !isUnknownType(env[name][STATS])
1870
1873
  if (
1871
1874
  isKnown &&
1872
- env[name][STATS][ARG_COUNT] !== VARIADIC
1875
+ env[name][STATS][ARG_COUNT] !== VARIADIC &&
1876
+ args[i][STATS][ARG_COUNT] !== VARIADIC
1873
1877
  ) {
1874
1878
  if (
1875
1879
  env[name][STATS][ARG_COUNT] !==
@@ -1892,9 +1896,6 @@ export const typeCheck = (
1892
1896
  )
1893
1897
  }
1894
1898
  }
1895
- // if (isGenericType(args[i][STATS])) {
1896
- // generics[i] = env[name]
1897
- // }
1898
1899
  const eqTypes = equalTypes(
1899
1900
  args[i][STATS],
1900
1901
  env[name][STATS]
@@ -1956,6 +1957,8 @@ export const typeCheck = (
1956
1957
  )}) (${stringifyArgs(exp)}) (check #203)`
1957
1958
  )
1958
1959
  }
1960
+ if (isGenericType(args[i][STATS]))
1961
+ generics[i] = [ATOM]
1959
1962
  break
1960
1963
  case APPLY:
1961
1964
  {
@@ -2008,9 +2011,10 @@ export const typeCheck = (
2008
2011
  isSpecial &&
2009
2012
  (!equalTypes(args[i][STATS], env[name][STATS]) ||
2010
2013
  !equalSubTypes(args[i][STATS], env[name][STATS]))
2011
- )
2014
+ ) {
2015
+ // CHECKPOINT
2012
2016
  setType(env[name][STATS], args[i][STATS])
2013
- else if (
2017
+ } else if (
2014
2018
  isUnknownType(env[name][STATS]) &&
2015
2019
  !isUnknownType(args[i][STATS])
2016
2020
  ) {
@@ -2020,11 +2024,16 @@ export const typeCheck = (
2020
2024
  // (let range (math:range 1 10))
2021
2025
  // (sum range)
2022
2026
  // But it reduces good inference too
2023
-
2024
2027
  if (getType(args[i][STATS]) !== APPLY)
2025
2028
  setTypeRef(env[name][STATS], args[i][STATS])
2026
2029
  else setStatsRef(env[rest[i][VALUE]], args[i])
2027
2030
  }
2031
+ if (
2032
+ isGenericType(args[i][STATS]) &&
2033
+ !isUnknownNotAnyType(env[name][STATS])
2034
+ ) {
2035
+ generics[i] = env[name][STATS][TYPE_PROP]
2036
+ }
2028
2037
  }
2029
2038
  if (isUnknownType(args[i][STATS])) {
2030
2039
  retry(args[i][STATS], [first, env], stack, () =>
@@ -2070,34 +2079,48 @@ export const typeCheck = (
2070
2079
  break
2071
2080
  }
2072
2081
  match({ rest, args, i, env, scope, exp })
2082
+
2083
+ if (
2084
+ isGenericType(args[i][STATS]) &&
2085
+ !isUnknownNotAnyReturn(env[name][STATS])
2086
+ )
2087
+ generics[i] = env[name][STATS][RETURNS]
2073
2088
  }
2074
2089
  }
2075
2090
  }
2076
- // if (generics.some((x) => x !== null)) {
2077
- // const copy = Object.create(env)
2078
- // const genCopy = [...generics]
2079
- // for (let i = 0; i < generics.length; ++i) {
2080
- // if (!generics[i]) continue
2081
- // genCopy[i] = structuredClone(
2082
- // copy[first[VALUE]][STATS][ARGUMENTS][i]
2083
- // )
2084
- // copy[first[VALUE]][STATS][ARGUMENTS][i] = structuredClone(
2085
- // generics[i]
2086
- // )
2087
- // copy[first[VALUE]][STATS][ARGUMENTS][i][STATS][
2088
- // TYPE_PROP
2089
- // ].length = 2
2090
- // }
2091
- // check(exp, copy, scope)
2092
-
2093
- // for (let i = 0; i < generics.length; ++i) {
2094
- // if (!generics[i]) continue
2095
- // copy[first[VALUE]][STATS][ARGUMENTS][i] = genCopy[i]
2096
- // copy[first[VALUE]][STATS][ARGUMENTS][i][STATS][
2097
- // TYPE_PROP
2098
- // ].length = 2
2099
- // }
2100
- // }
2091
+ if (generics.some((x) => x !== null && x[0] !== UNKNOWN)) {
2092
+ const copy = Object.create(env)
2093
+ const newName = `${PLACEHOLDER}${first[VALUE]}`
2094
+ // copy[newName] = structuredClone(copy[first[VALUE]])
2095
+ copy[newName] = {
2096
+ [STATS]: structuredClone(env[first[VALUE]][STATS])
2097
+ }
2098
+ for (let i = 0; i < generics.length; ++i) {
2099
+ if (!generics[i]) continue
2100
+ copy[newName][STATS][ARGUMENTS][i] = {
2101
+ [STATS]: {
2102
+ [ARG_COUNT]: VARIADIC,
2103
+ [ARGUMENTS]: [],
2104
+ [TYPE_PROP]: generics[i],
2105
+ [RETURNS]: generics[i]
2106
+ }
2107
+ }
2108
+ }
2109
+ const cexp = structuredClone(exp)
2110
+ copy[newName][STATS].source = structuredClone(
2111
+ copy[newName][STATS].source
2112
+ )
2113
+ cexp[0][VALUE] = newName
2114
+ copy[newName][STATS].source[1][VALUE] = newName
2115
+ once(copy[newName][STATS], exp, stack, () => {
2116
+ check(
2117
+ wrapInBlock([copy[newName][STATS].source, cexp]),
2118
+ copy,
2119
+ scope
2120
+ )
2121
+ })
2122
+ return
2123
+ }
2101
2124
  }
2102
2125
  }
2103
2126
  stagger(stack, 'append', [first, env], judge)
package/src/debugger.js CHANGED
@@ -874,6 +874,12 @@ const evaluate = (exp, env = keywords) => {
874
874
  KEYWORDS.ANONYMOUS_FUNCTION
875
875
  }) (${value}) (${stringifyArgs(exp)})`
876
876
  )
877
+ if (typeof apply !== 'function')
878
+ throw new TypeError(
879
+ `${value} is not a (${KEYWORDS.ANONYMOUS_FUNCTION}) (${stringifyArgs(
880
+ exp
881
+ )})`
882
+ )
877
883
  res = apply(tail, env)
878
884
  if (
879
885
  isDebugging &&