fez-lisp 1.6.69 → 1.6.71

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 +65 -40
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.69",
5
+ "version": "1.6.71",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -616,25 +616,23 @@ const resolveGetterRec = ([head, tail], env, times = 0) => {
616
616
  if (GET_ARRAY_INFERENCE_SET.has(head[VALUE])) {
617
617
  return resolveGetterRec(tail, env, ++times)
618
618
  } else {
619
- switch (head) {
620
- case APPLY:
621
- break
622
- case WORD:
623
- {
624
- if (env[tail][STATS][TYPE_PROP][0] === UNKNOWN) return
625
- const types = env[tail][STATS][TYPE_PROP][1].types
626
- const sub = types.at(-1)
627
- const type =
628
- sub === ATOM || sub === NUMBER || sub === BOOLEAN
629
- ? ATOM
630
- : sub === APPLY
631
- ? APPLY
632
- : COLLECTION
633
- const len = types.length ? types.length + 1 : times + 1
634
- return [times, len, type, types]
635
- }
636
- break
619
+ if (Array.isArray(head)) {
620
+ tail = head[VALUE]
621
+ head = head[TYPE]
637
622
  }
623
+ if (head !== WORD && head !== APPLY) return
624
+ const prop = head === WORD ? TYPE_PROP : RETURNS
625
+ if (!env[tail] || env[tail][STATS][prop][0] === UNKNOWN) return
626
+ const types = env[tail][STATS][prop][1].types
627
+ const sub = types.at(-1)
628
+ const type =
629
+ sub === ATOM || sub === NUMBER || sub === BOOLEAN
630
+ ? ATOM
631
+ : sub === APPLY
632
+ ? APPLY
633
+ : COLLECTION
634
+ const len = types.length ? types.length + 1 : times + 1
635
+ return [times, len, type, types]
638
636
  }
639
637
  }
640
638
  const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
@@ -649,9 +647,9 @@ const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
649
647
  const [times, level, type, types] = resolveGetterRec(rem, env)
650
648
  if (times >= level)
651
649
  throw new RangeError(
652
- `(${caller}) is trying to access nested structure at level (${level}) which is deeper than it's (${times}) levels at (${stringifyArgs(
653
- exp
654
- )}) (check #1003)`
650
+ `(${caller}) is trying to access nested structure at level (${level}) which is deeper than it's (${
651
+ times - 1
652
+ }) levels at (${stringifyArgs(exp)}) (check #1003)`
655
653
  )
656
654
  if (times === level - 1) {
657
655
  setPropToType(env[name][STATS], prop, {
@@ -668,7 +666,6 @@ const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
668
666
  }
669
667
  return true
670
668
  }
671
-
672
669
  if (
673
670
  getReturn(env[array[VALUE]][STATS]) === UNKNOWN ||
674
671
  getReturn(env[array[VALUE]][STATS]) === ANY
@@ -889,7 +886,11 @@ const initArrayType = ({ rem, env }) => {
889
886
  const ret = initArrayTypeRec({ rem, env })
890
887
  const known = ret.find((x) => x[0] !== ANY && x[0] !== UNKNOWN)
891
888
  const isCollection = ret.length && ret[0] && ret[0][0] === COLLECTION
892
- if (known && ret.length) {
889
+ if (
890
+ known &&
891
+ ret.length &&
892
+ !ret.some((x) => known[0][0] !== x[0][0] || known[0].length !== x[0].length)
893
+ ) {
893
894
  if (Array.isArray(ret[0][0])) {
894
895
  let head = ret[0][0]
895
896
  ret[0].length = 0
@@ -970,8 +971,26 @@ const resolveReturnType = ({
970
971
  break
971
972
  default:
972
973
  {
973
- if (GET_ARRAY_INFERENCE_SET.has(returns[VALUE]))
974
- resolveGetter({ rem, prop, name, env, caller: returns[VALUE], exp })
974
+ if (GET_ARRAY_INFERENCE_SET.has(returns[VALUE])) {
975
+ resolveGetter({
976
+ rem,
977
+ prop,
978
+ name,
979
+ env,
980
+ caller: returns[VALUE],
981
+ exp
982
+ })
983
+ retry(env[name][STATS], exp, stack, () => {
984
+ resolveGetter({
985
+ rem,
986
+ prop,
987
+ name,
988
+ env,
989
+ caller: returns[VALUE],
990
+ exp
991
+ })
992
+ })
993
+ }
975
994
  checkPredicateNameDeep(name, exp, exp.slice(1), returns)
976
995
  // TODO: DRY
977
996
  const index = env[name][STATS][ARGUMENTS]
@@ -1327,17 +1346,23 @@ export const typeCheck = (
1327
1346
  // If current scope is root then these are user defined types
1328
1347
  if (isLambda) {
1329
1348
  const lambdaName = `${PLACEHOLDER}${name}`
1330
- check(
1331
- [
1332
- [APPLY, KEYWORDS.DEFINE_VARIABLE],
1333
- [WORD, lambdaName],
1334
- exp.at(-1)
1335
- ],
1336
- env,
1337
- scope
1338
- )
1349
+ const fn = [
1350
+ [APPLY, KEYWORDS.DEFINE_VARIABLE],
1351
+ [WORD, lambdaName],
1352
+ exp.at(-1)
1353
+ ]
1354
+ check(fn, env, scope)
1339
1355
  const expected = env[name]
1340
1356
  const actual = env[lambdaName]
1357
+ if (expected[ARG_COUNT] !== actual[ARG_COUNT]) {
1358
+ throw new RangeError(
1359
+ `Incorrect number of arguments for (${
1360
+ expected[STATS][SIGNATURE]
1361
+ }) Expected (${expected[ARG_COUNT]}) but got (${
1362
+ actual[ARG_COUNT]
1363
+ }) (${stringifyArgs(exp)}) (check #1004)`
1364
+ )
1365
+ }
1341
1366
  const checkReturns = () => {
1342
1367
  if (
1343
1368
  !isUnknownReturn(actual[STATS]) &&
@@ -1382,9 +1407,9 @@ export const typeCheck = (
1382
1407
  checkArgs()
1383
1408
  // Check lambda body with defined types
1384
1409
  const copy = Object.create(env)
1385
- for (let i = 0; i < env[name][STATS][ARGUMENTS].length; ++i) {
1386
- const A = env[lambdaName][STATS][ARGUMENTS][i]
1387
- const B = env[name][STATS][ARGUMENTS][i]
1410
+ for (let i = 0; i < expected[STATS][ARGUMENTS].length; ++i) {
1411
+ const A = actual[STATS][ARGUMENTS][i]
1412
+ const B = expected[STATS][ARGUMENTS][i]
1388
1413
  copy[A[STATS][SIGNATURE]] = {
1389
1414
  [STATS]: {
1390
1415
  [SIGNATURE]: A[STATS][SIGNATURE],
@@ -1394,12 +1419,12 @@ export const typeCheck = (
1394
1419
  }
1395
1420
  }
1396
1421
  check(
1397
- wrapInApplyLambda(exp.at(-1).slice(2)).at(-1),
1422
+ wrapInApplyLambda(
1423
+ exp.at(-1).slice(expected[ARG_COUNT] ? 2 : 1)
1424
+ ).at(-1),
1398
1425
  copy,
1399
1426
  scope
1400
1427
  )
1401
- // console.log(exp.at(-1).slice(1))
1402
- // check(exp.at(-1), env, scope)
1403
1428
  // Types.delete(`; ${rootScopeIndex} ${lambdaName}`)
1404
1429
  }
1405
1430
  typeSet(Types, name, env, exp)