fez-lisp 1.6.81 → 1.6.82

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