fez-lisp 1.6.39 → 1.6.41

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 +81 -9
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.39",
5
+ "version": "1.6.41",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -1204,26 +1204,98 @@ export const typeCheck = (
1204
1204
  )
1205
1205
  // TODO check let define types
1206
1206
  const name = rest[0][VALUE]
1207
- if (env.hasOwnProperty(name))
1207
+ if (name[0] !== PLACEHOLDER && env.hasOwnProperty(name))
1208
1208
  throw new ReferenceError(
1209
1209
  `Attempting to redeclare (${name}) which was previously declared in this scope (${stringifyArgs(
1210
1210
  exp
1211
1211
  )})`
1212
1212
  )
1213
+ const rightHand = rest.at(-1)
1214
+ const isApply =
1215
+ rightHand && rightHand[0] && rightHand[0][TYPE] === APPLY
1216
+ const isLambda =
1217
+ isApply && rightHand[0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
1213
1218
  if (name in env) {
1214
- typeSet(Types, name, env, exp)
1215
1219
  // Types.set(withScope(name, env), () => formatType(name, env))
1216
1220
  // If current scope is root then these are user defined types
1221
+ if (isLambda && !isUnknownReturn(env[name][STATS])) {
1222
+ const lambdaName = `${PLACEHOLDER}${ANONYMOUS_FUNCTION_TYPE_PREFIX}${rootScopeIndex}`
1223
+ check(
1224
+ [
1225
+ [APPLY, KEYWORDS.DEFINE_VARIABLE],
1226
+ [WORD, lambdaName],
1227
+ exp.at(-1)
1228
+ ],
1229
+ env,
1230
+ scope
1231
+ )
1232
+ const expected = env[name]
1233
+ const actual = env[lambdaName]
1234
+ const checkReturns = () => {
1235
+ if (
1236
+ !isUnknownReturn(actual[STATS]) &&
1237
+ (!equalReturns(expected[STATS], actual[STATS]) ||
1238
+ !equalSubReturns(expected[STATS], actual[STATS]))
1239
+ )
1240
+ throw new TypeError(
1241
+ `Incorrect return type for (${
1242
+ expected[STATS][SIGNATURE]
1243
+ }) Expected (${formatSubType(
1244
+ getReturns(expected[STATS])
1245
+ )}) but got (${formatSubType(
1246
+ getReturns(actual[STATS])
1247
+ )}) (${stringifyArgs(exp)}) (check #999)`
1248
+ )
1249
+ else retry(actual[STATS], exp, stack, checkReturns)
1250
+ }
1251
+ const checkArgs = () => {
1252
+ if (
1253
+ !isUnknownReturn(actual[STATS]) &&
1254
+ (!equalReturns(expected[STATS], actual[STATS]) ||
1255
+ !equalSubReturns(expected[STATS], actual[STATS]))
1256
+ )
1257
+ throw new TypeError(
1258
+ `Incorrect return type for (${
1259
+ expected[STATS][SIGNATURE]
1260
+ }) Expected (${formatSubType(
1261
+ getReturns(expected[STATS])
1262
+ )}) but got (${formatSubType(
1263
+ getReturns(actual[STATS])
1264
+ )}) (${stringifyArgs(exp)}) (check #999)`
1265
+ )
1266
+ for (let i = 0; i < expected[STATS][ARGUMENTS].length; ++i) {
1267
+ const argE = expected[STATS][ARGUMENTS][i]
1268
+ const argA = actual[STATS][ARGUMENTS][i]
1269
+ if (
1270
+ !isUnknownType(argA[STATS]) &&
1271
+ (!equalTypes(argE[STATS], argA[STATS]) ||
1272
+ !equalSubTypes(argE[STATS], argA[STATS]))
1273
+ )
1274
+ throw new TypeError(
1275
+ `Incorrect type for argument (${
1276
+ argA[STATS][SIGNATURE]
1277
+ }) The (${KEYWORDS.ANONYMOUS_FUNCTION}) argument of (${
1278
+ expected[STATS][SIGNATURE]
1279
+ }) at position (${i}). Expected (${formatSubType(
1280
+ getTypes(argE[STATS])
1281
+ )}) but got (${formatSubType(
1282
+ getTypes(argA[STATS])
1283
+ )}) (${stringifyArgs(exp)}) (check #1000)`
1284
+ )
1285
+ else retry(actual[STATS], exp, stack, checkArgs)
1286
+ }
1287
+ }
1288
+ once(actual[STATS], exp, stack, () => {
1289
+ checkReturns()
1290
+ checkArgs()
1291
+ Types.delete(`; ${rootScopeIndex} ${lambdaName}`)
1292
+ })
1293
+ }
1294
+ typeSet(Types, name, env, exp)
1217
1295
  if (env[SCOPE_NAME] === rootScopeIndex) break
1218
1296
  }
1219
1297
  // Predicate name consistency
1220
- const rightHand = rest.at(-1)
1221
- const isApply =
1222
- rightHand && rightHand[0] && rightHand[0][TYPE] === APPLY
1223
- if (
1224
- isApply &&
1225
- rightHand[0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
1226
- ) {
1298
+ if (isLambda) {
1227
1299
  validateLambda(rightHand, name)
1228
1300
  const n = rightHand.length
1229
1301
  env[name] = {