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.
- package/package.json +1 -1
- package/src/check.js +106 -25
- package/src/macros.js +14 -0
package/package.json
CHANGED
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]))
|
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
|
648
|
-
|
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
|
679
|
-
|
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.
|
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)
|
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({
|
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
|
-
|
1271
|
-
[
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
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 <
|
1326
|
-
const A =
|
1327
|
-
const B =
|
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(
|
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'
|