fez-lisp 1.6.68 → 1.6.70

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 (3) hide show
  1. package/package.json +1 -1
  2. package/src/check.js +106 -25
  3. package/src/macros.js +14 -0
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.68",
5
+ "version": "1.6.70",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -612,13 +612,60 @@ const resolveCondition = ({ rem, name, env, exp, prop, stack, check }) => {
612
612
  break
613
613
  }
614
614
  }
615
+ const resolveGetterRec = ([head, tail], env, times = 0) => {
616
+ if (GET_ARRAY_INFERENCE_SET.has(head[VALUE])) {
617
+ return resolveGetterRec(tail, env, ++times)
618
+ } else {
619
+ if (Array.isArray(head)) {
620
+ tail = head[VALUE]
621
+ head = head[TYPE]
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]
636
+ }
637
+ }
615
638
  const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
616
639
  const array = isLeaf(rem[1]) ? rem[1] : rem[1][0]
617
640
  if (!env[array[VALUE]] || !env[name]) return true
618
641
  switch (array[TYPE]) {
619
642
  case APPLY:
620
643
  // TODO: figure out recursively what is the inner type of all nested getters
621
- if (GET_ARRAY_INFERENCE_SET.has(array[VALUE])) return true
644
+ if (GET_ARRAY_INFERENCE_SET.has(array[VALUE])) {
645
+ const rec = resolveGetterRec(rem, env)
646
+ if (!rec) return true
647
+ const [times, level, type, types] = resolveGetterRec(rem, env)
648
+ if (times >= level)
649
+ throw new RangeError(
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)`
653
+ )
654
+ if (times === level - 1) {
655
+ setPropToType(env[name][STATS], prop, {
656
+ [TYPE_PROP]: types.length
657
+ ? [type, new SubType([types.at(-1)])]
658
+ : [UNKNOWN]
659
+ })
660
+ } else {
661
+ setPropToType(env[name][STATS], prop, {
662
+ [TYPE_PROP]: types.length
663
+ ? [COLLECTION, new SubType(types.slice(times))]
664
+ : [UNKNOWN]
665
+ })
666
+ }
667
+ return true
668
+ }
622
669
  if (
623
670
  getReturn(env[array[VALUE]][STATS]) === UNKNOWN ||
624
671
  getReturn(env[array[VALUE]][STATS]) === ANY
@@ -644,8 +691,12 @@ const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
644
691
  setPropToReturn(env[name][STATS], prop, {
645
692
  [RETURNS]: [f, new SubType(r)]
646
693
  })
647
- } else return false
648
- } else return false
694
+ } else if (rightSub.has(APPLY)) {
695
+ // TODOD: abstractions go here but what can we do with them
696
+ // perhaps show the signature?
697
+ setPropToAbstraction(env[name][STATS], prop)
698
+ }
699
+ }
649
700
  break
650
701
  case WORD:
651
702
  {
@@ -675,8 +726,12 @@ const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
675
726
  setPropToType(env[name][STATS], prop, {
676
727
  [TYPE_PROP]: [f, new SubType(r)]
677
728
  })
678
- } else return false
679
- } else return false
729
+ } else if (rightSub.has(APPLY)) {
730
+ // TODOD: abstractions go here but what can we do with them
731
+ // perhaps show the signature?
732
+ setPropToAbstraction(env[name][STATS], prop)
733
+ }
734
+ }
680
735
  }
681
736
  break
682
737
  }
@@ -837,11 +892,13 @@ const initArrayType = ({ rem, env }) => {
837
892
  ret[0].length = 0
838
893
  const subT = new SubType([COLLECTION])
839
894
  ret[0].push(COLLECTION, subT)
840
- while (head && !isSubType(head[1])) {
841
- subT.add(COLLECTION)
895
+ while (Array.isArray(head) && !isSubType(head[1])) {
896
+ if (head[0] === APPLY) subT.types.push(APPLY)
897
+ else subT.add(COLLECTION)
842
898
  head = head[0]
843
899
  }
844
- if (head && head[1].types.length) subT.add(head[1].types[0])
900
+ if (Array.isArray(head) && head[1].types.length)
901
+ subT.add(head[1].types[0])
845
902
  }
846
903
  const [main, sub] = ret[0]
847
904
  if (isSubType(sub) && sub.types.at(-1) === COLLECTION) sub.types.pop()
@@ -910,8 +967,26 @@ const resolveReturnType = ({
910
967
  break
911
968
  default:
912
969
  {
913
- if (GET_ARRAY_INFERENCE_SET.has(returns[VALUE]))
914
- resolveGetter({ rem, prop, name, env, caller: returns[VALUE], exp })
970
+ if (GET_ARRAY_INFERENCE_SET.has(returns[VALUE])) {
971
+ resolveGetter({
972
+ rem,
973
+ prop,
974
+ name,
975
+ env,
976
+ caller: returns[VALUE],
977
+ exp
978
+ })
979
+ retry(env[name][STATS], exp, stack, () => {
980
+ resolveGetter({
981
+ rem,
982
+ prop,
983
+ name,
984
+ env,
985
+ caller: returns[VALUE],
986
+ exp
987
+ })
988
+ })
989
+ }
915
990
  checkPredicateNameDeep(name, exp, exp.slice(1), returns)
916
991
  // TODO: DRY
917
992
  const index = env[name][STATS][ARGUMENTS]
@@ -1267,17 +1342,23 @@ export const typeCheck = (
1267
1342
  // If current scope is root then these are user defined types
1268
1343
  if (isLambda) {
1269
1344
  const lambdaName = `${PLACEHOLDER}${name}`
1270
- check(
1271
- [
1272
- [APPLY, KEYWORDS.DEFINE_VARIABLE],
1273
- [WORD, lambdaName],
1274
- exp.at(-1)
1275
- ],
1276
- env,
1277
- scope
1278
- )
1345
+ const fn = [
1346
+ [APPLY, KEYWORDS.DEFINE_VARIABLE],
1347
+ [WORD, lambdaName],
1348
+ exp.at(-1)
1349
+ ]
1350
+ check(fn, env, scope)
1279
1351
  const expected = env[name]
1280
1352
  const actual = env[lambdaName]
1353
+ if (expected[ARG_COUNT] !== actual[ARG_COUNT]) {
1354
+ throw new RangeError(
1355
+ `Incorrect number of arguments for (${
1356
+ expected[STATS][SIGNATURE]
1357
+ }) Expected (${expected[ARG_COUNT]}) but got (${
1358
+ actual[ARG_COUNT]
1359
+ }) (${stringifyArgs(exp)}) (check #1004)`
1360
+ )
1361
+ }
1281
1362
  const checkReturns = () => {
1282
1363
  if (
1283
1364
  !isUnknownReturn(actual[STATS]) &&
@@ -1322,9 +1403,9 @@ export const typeCheck = (
1322
1403
  checkArgs()
1323
1404
  // Check lambda body with defined types
1324
1405
  const copy = Object.create(env)
1325
- for (let i = 0; i < env[name][STATS][ARGUMENTS].length; ++i) {
1326
- const A = env[lambdaName][STATS][ARGUMENTS][i]
1327
- const B = env[name][STATS][ARGUMENTS][i]
1406
+ for (let i = 0; i < expected[STATS][ARGUMENTS].length; ++i) {
1407
+ const A = actual[STATS][ARGUMENTS][i]
1408
+ const B = expected[STATS][ARGUMENTS][i]
1328
1409
  copy[A[STATS][SIGNATURE]] = {
1329
1410
  [STATS]: {
1330
1411
  [SIGNATURE]: A[STATS][SIGNATURE],
@@ -1334,12 +1415,12 @@ export const typeCheck = (
1334
1415
  }
1335
1416
  }
1336
1417
  check(
1337
- wrapInApplyLambda(exp.at(-1).slice(2)).at(-1),
1418
+ wrapInApplyLambda(
1419
+ exp.at(-1).slice(expected[ARG_COUNT] ? 2 : 1)
1420
+ ).at(-1),
1338
1421
  copy,
1339
1422
  scope
1340
1423
  )
1341
- // console.log(exp.at(-1).slice(1))
1342
- // check(exp.at(-1), env, scope)
1343
1424
  // Types.delete(`; ${rootScopeIndex} ${lambdaName}`)
1344
1425
  }
1345
1426
  typeSet(Types, name, env, exp)
package/src/macros.js CHANGED
@@ -114,6 +114,20 @@ export const deSuggarAst = (ast, scope) => {
114
114
  // }
115
115
  // }
116
116
  // break
117
+ case PLACEHOLDER:
118
+ {
119
+ exp.length = 0
120
+ rest.reverse()
121
+ let temp = exp
122
+ for (let i = 0; i < rest.length; i += 1) {
123
+ if (i < rest.length - 1) {
124
+ temp.push([APPLY, SUGGAR.GET_ARRAY], [], rest[i])
125
+ temp = temp.at(-2)
126
+ } else temp.push(...rest[i])
127
+ }
128
+ deSuggarAst(exp, scope)
129
+ }
130
+ break
117
131
  case KEYWORDS.GET_ARRAY:
118
132
  if (rest.length === 1) {
119
133
  exp[0][VALUE] = 'math:var-get'