fez-lisp 1.6.84 → 1.6.87
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 +244 -106
- package/src/types.js +8 -1
- package/src/utils.js +57 -56
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -47,7 +47,9 @@ import {
|
|
47
47
|
NUMBER_SUBTYPE,
|
48
48
|
SubType,
|
49
49
|
GET_ARRAY_INFERENCE_SET,
|
50
|
-
GENERIC
|
50
|
+
GENERIC,
|
51
|
+
TYPE_NAME,
|
52
|
+
RETURN_NAME
|
51
53
|
} from './types.js'
|
52
54
|
import {
|
53
55
|
Brr,
|
@@ -58,6 +60,7 @@ import {
|
|
58
60
|
logExp,
|
59
61
|
stringifyArgs,
|
60
62
|
wrapInApplyLambda,
|
63
|
+
wrapInArray,
|
61
64
|
wrapInBlock
|
62
65
|
} from './utils.js'
|
63
66
|
|
@@ -110,6 +113,8 @@ export const isGenericReturn = (stats) =>
|
|
110
113
|
stats[RETURNS].length === 3 && stats[RETURNS][2][0] !== -1
|
111
114
|
export const isGenericType = (stats) =>
|
112
115
|
stats[TYPE_PROP].length === 3 && stats[TYPE_PROP][2][0] !== -1
|
116
|
+
export const isGenericProp = (stats, prop) =>
|
117
|
+
stats[prop].length === 3 && stats[prop][2][0] !== -1
|
113
118
|
|
114
119
|
export const isTypeAbstraction = (stats) => stats[TYPE_PROP] === APPLY
|
115
120
|
export const setPropToAtom = (stats, prop) => {
|
@@ -340,6 +345,69 @@ const isRedefinedInLambda = (env, name, exp) => {
|
|
340
345
|
return true
|
341
346
|
else return false
|
342
347
|
}
|
348
|
+
const getGenericPropNest = (ref, prop) =>
|
349
|
+
ref[STATS][prop][0] === COLLECTION
|
350
|
+
? isSubType(ref[STATS][prop][1])
|
351
|
+
? ref[STATS][prop][1].nestedLevels()
|
352
|
+
: 0
|
353
|
+
: 0
|
354
|
+
const getGenericProp = (ref, rem, prop) => {
|
355
|
+
const [index, multiplier] = ref[STATS][prop][2]
|
356
|
+
const generic = rem.slice(1)[index]
|
357
|
+
const nestGeneric = getGenericPropNest(ref, prop)
|
358
|
+
return [
|
359
|
+
generic,
|
360
|
+
isLeaf(generic) ? generic : generic[0],
|
361
|
+
nestGeneric,
|
362
|
+
multiplier
|
363
|
+
]
|
364
|
+
}
|
365
|
+
const getGenericReturn = (ref, rem) => getGenericProp(ref, rem, RETURNS)
|
366
|
+
const getGenericType = (ref, rem) => getGenericProp(ref, rem, TYPE_PROP)
|
367
|
+
const resolveGenericNest = (ref, prop, nestGeneric, multiplier) => {
|
368
|
+
const T = isSubType(ref[STATS][prop][1])
|
369
|
+
? ref[STATS][prop][1].types
|
370
|
+
: [ref[STATS][prop][0]]
|
371
|
+
if (multiplier === -1) {
|
372
|
+
if (nestGeneric === 0) {
|
373
|
+
if (T.at(-1) === NUMBER || T.at(-1) === BOOLEAN) {
|
374
|
+
if (isSubType(ref[STATS][prop][1])) {
|
375
|
+
if (ref[STATS][prop][1].types.length === 1) ref[STATS][prop][0] = ATOM
|
376
|
+
else {
|
377
|
+
ref[STATS][prop][1] = new SubType(
|
378
|
+
ref[STATS][prop][1].types.slice(1)
|
379
|
+
)
|
380
|
+
ref[STATS][prop][0] = COLLECTION
|
381
|
+
ref[STATS][prop].length = 2
|
382
|
+
}
|
383
|
+
} else ref[STATS][prop][0] = ATOM
|
384
|
+
}
|
385
|
+
} else {
|
386
|
+
if (T.length - nestGeneric - 1) {
|
387
|
+
for (let i = 0; i < nestGeneric + 1; ++i)
|
388
|
+
ref[STATS][prop][1].types.shift()
|
389
|
+
ref[STATS][prop].length = 2
|
390
|
+
} else {
|
391
|
+
if (T.at(-1) === NUMBER || T.at(-1) === BOOLEAN) {
|
392
|
+
ref[STATS][prop][0] = ATOM
|
393
|
+
ref[STATS][prop][1] = new SubType([T.at(-1)])
|
394
|
+
ref[STATS][prop].length = 2
|
395
|
+
} else {
|
396
|
+
ref[STATS][prop][0] = APPLY
|
397
|
+
ref[STATS][prop].length = 1
|
398
|
+
}
|
399
|
+
}
|
400
|
+
}
|
401
|
+
} else if (multiplier === 1) {
|
402
|
+
const st = new SubType([])
|
403
|
+
for (let i = 0; i < nestGeneric; ++i) st.add(COLLECTION)
|
404
|
+
if (ref[STATS][prop][0] === COLLECTION) st.add(COLLECTION)
|
405
|
+
st.add(...T)
|
406
|
+
ref[STATS][prop][0] = COLLECTION
|
407
|
+
ref[STATS][prop][1] = st
|
408
|
+
}
|
409
|
+
}
|
410
|
+
|
343
411
|
export const equalReturns = (a, b) =>
|
344
412
|
isAnyReturn(a) || isAnyReturn(b) || a[RETURNS][0] === b[RETURNS][0]
|
345
413
|
export const equalsTypeWithReturn = (a, b) =>
|
@@ -470,6 +538,12 @@ const once = (stats, ctx, stack, cb, method = 'prepend') => {
|
|
470
538
|
stagger(stack, method, ctx, cb)
|
471
539
|
}
|
472
540
|
}
|
541
|
+
const doOnce = (stats, ctx, stack, cb, method = 'prepend') => {
|
542
|
+
if (!stats.tried) {
|
543
|
+
stats.tried = true
|
544
|
+
stagger(stack, method, ctx, cb)
|
545
|
+
}
|
546
|
+
}
|
473
547
|
const retryArgs = (stats, ctx, stack, cb) => {
|
474
548
|
if (stats.counter < MAX_ARGUMENT_RETRY) {
|
475
549
|
stats.counter++
|
@@ -652,31 +726,29 @@ const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
|
|
652
726
|
const rec = resolveGetterRec(rem, env)
|
653
727
|
if (!rec) return true
|
654
728
|
const [times, level, type, types] = resolveGetterRec(rem, env)
|
655
|
-
const isUnknown =
|
729
|
+
const isUnknown =
|
730
|
+
types.at(-1) === UNKNOWN || types.at(-1) === COLLECTION
|
656
731
|
if (!isUnknown && times >= level)
|
657
732
|
throw new RangeError(
|
658
733
|
`(${caller}) is trying to access nested structure at level (${level}) which is deeper than it's (${
|
659
734
|
times - 1
|
660
735
|
}) levels at (${stringifyArgs(exp)}) (check #1003)`
|
661
736
|
)
|
662
|
-
if (times === level - 1)
|
737
|
+
if (times === level - 1)
|
663
738
|
setPropToType(env[name][STATS], prop, {
|
664
|
-
[TYPE_PROP]:
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
]
|
671
|
-
: [UNKNOWN]
|
739
|
+
[TYPE_PROP]:
|
740
|
+
types.length && !isUnknown
|
741
|
+
? [type, new SubType([types.at(-1)])]
|
742
|
+
: types.at(-1) === COLLECTION
|
743
|
+
? [COLLECTION]
|
744
|
+
: [UNKNOWN]
|
672
745
|
})
|
673
|
-
|
746
|
+
else
|
674
747
|
setPropToType(env[name][STATS], prop, {
|
675
748
|
[TYPE_PROP]: types.length
|
676
749
|
? [COLLECTION, new SubType(types.slice(times))]
|
677
750
|
: [UNKNOWN]
|
678
751
|
})
|
679
|
-
}
|
680
752
|
return true
|
681
753
|
}
|
682
754
|
if (
|
@@ -704,11 +776,10 @@ const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
|
|
704
776
|
setPropToReturn(env[name][STATS], prop, {
|
705
777
|
[RETURNS]: [f, new SubType(r)]
|
706
778
|
})
|
707
|
-
} else if (rightSub.has(APPLY))
|
779
|
+
} else if (rightSub.has(APPLY))
|
708
780
|
// TODOD: abstractions go here but what can we do with them
|
709
781
|
// perhaps show the signature?
|
710
782
|
setPropToAbstraction(env[name][STATS], prop)
|
711
|
-
}
|
712
783
|
}
|
713
784
|
break
|
714
785
|
case WORD:
|
@@ -739,11 +810,10 @@ const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
|
|
739
810
|
setPropToType(env[name][STATS], prop, {
|
740
811
|
[TYPE_PROP]: [f, new SubType(r)]
|
741
812
|
})
|
742
|
-
} else if (rightSub.has(APPLY))
|
813
|
+
} else if (rightSub.has(APPLY))
|
743
814
|
// TODOD: abstractions go here but what can we do with them
|
744
815
|
// perhaps show the signature?
|
745
816
|
setPropToAbstraction(env[name][STATS], prop)
|
746
|
-
}
|
747
817
|
}
|
748
818
|
}
|
749
819
|
break
|
@@ -874,6 +944,8 @@ const resolveSetter = (first, rest, env, stack) => {
|
|
874
944
|
// )
|
875
945
|
}
|
876
946
|
}
|
947
|
+
const countLevels = (arr, lvl = -1) =>
|
948
|
+
Array.isArray(arr[0]) ? countLevels(arr[0], ++lvl) : lvl
|
877
949
|
const initArrayTypeRec = ({ rem, env }) =>
|
878
950
|
rem.slice(1).map((x) => {
|
879
951
|
if (isLeaf(x))
|
@@ -906,14 +978,15 @@ const initArrayTypeRec = ({ rem, env }) =>
|
|
906
978
|
})
|
907
979
|
const initArrayType = ({ rem, env }) => {
|
908
980
|
const ret = initArrayTypeRec({ rem, env })
|
909
|
-
const
|
910
|
-
const
|
981
|
+
const flat = ret.flat(Infinity).filter((x) => !isSubType(x))
|
982
|
+
const subTypes = ret.flat(Infinity).filter((x) => isSubType(x))
|
983
|
+
const known = flat.find((x) => x !== ANY && x !== UNKNOWN)
|
984
|
+
const isCollection = ret.length && Array.isArray(ret[0])
|
911
985
|
if (
|
912
986
|
known &&
|
913
987
|
ret.length &&
|
914
|
-
|
915
|
-
|
916
|
-
: !ret.some((x) => known[0] !== x[0]))
|
988
|
+
!flat.some((x) => known !== x) &&
|
989
|
+
!subTypes.some((x) => subTypes[0].types[0] !== x.types[0])
|
917
990
|
) {
|
918
991
|
if (Array.isArray(ret[0][0])) {
|
919
992
|
let head = ret[0][0]
|
@@ -934,7 +1007,7 @@ const initArrayType = ({ rem, env }) => {
|
|
934
1007
|
[RETURNS]: [
|
935
1008
|
COLLECTION,
|
936
1009
|
isCollection
|
937
|
-
? new SubType(isSubType(sub) ? [
|
1010
|
+
? new SubType(isSubType(sub) ? [...sub] : [COLLECTION])
|
938
1011
|
: new SubType(isSubType(sub) ? [...sub] : [main])
|
939
1012
|
]
|
940
1013
|
}
|
@@ -944,7 +1017,10 @@ const initArrayType = ({ rem, env }) => {
|
|
944
1017
|
[RETURNS]: [
|
945
1018
|
COLLECTION,
|
946
1019
|
isCollection
|
947
|
-
? new SubType([
|
1020
|
+
? new SubType([
|
1021
|
+
...Array.from({ length: countLevels(ret) }).fill(COLLECTION),
|
1022
|
+
UNKNOWN
|
1023
|
+
])
|
948
1024
|
: new SubType([UNKNOWN])
|
949
1025
|
]
|
950
1026
|
}
|
@@ -1021,18 +1097,9 @@ const resolveReturnType = ({
|
|
1021
1097
|
// Here is upon application to store the result in the variable
|
1022
1098
|
if (isGenericReturn(env[returns[VALUE]][STATS])) {
|
1023
1099
|
// env[name][STATS][TYPE_PROP] =
|
1024
|
-
const [index, multiplier] = 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
|
1032
1100
|
|
1033
|
-
const head =
|
1034
|
-
|
1035
|
-
: genericReturn[0]
|
1101
|
+
const [genericReturn, head, nestGeneric, multiplier] =
|
1102
|
+
getGenericReturn(env[returns[VALUE]], rem)
|
1036
1103
|
|
1037
1104
|
switch (head[TYPE]) {
|
1038
1105
|
case ATOM:
|
@@ -1100,47 +1167,9 @@ const resolveReturnType = ({
|
|
1100
1167
|
setTypeToReturn(env[name][STATS], env[head[VALUE]][STATS])
|
1101
1168
|
break
|
1102
1169
|
}
|
1170
|
+
|
1103
1171
|
if (env[returns[VALUE]][STATS][RETURNS][0] === COLLECTION) {
|
1104
|
-
|
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
|
1120
|
-
}
|
1121
|
-
} 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][1] = new SubType([T.at(-1)])
|
1129
|
-
} else {
|
1130
|
-
env[name][STATS][prop][0] = APPLY
|
1131
|
-
env[name][STATS][prop].length = 1
|
1132
|
-
}
|
1133
|
-
}
|
1134
|
-
}
|
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
|
-
}
|
1172
|
+
resolveGenericNest(env[name], prop, nestGeneric, multiplier)
|
1144
1173
|
}
|
1145
1174
|
}
|
1146
1175
|
if (isUnknownType(env[name][STATS]))
|
@@ -1262,6 +1291,8 @@ export const typeCheck = (
|
|
1262
1291
|
const match1 = () => {
|
1263
1292
|
const actual = local[lambdaName]
|
1264
1293
|
const expected = args[i]
|
1294
|
+
if (isGenericReturn(expected[STATS])) return
|
1295
|
+
|
1265
1296
|
// if (
|
1266
1297
|
// isGenericReturn(args[i][STATS]) &&
|
1267
1298
|
// !isUnknownReturn(actual[STATS]) &&
|
@@ -1312,6 +1343,7 @@ export const typeCheck = (
|
|
1312
1343
|
for (let j = 0; j < args[i][STATS][ARGUMENTS].length; ++j) {
|
1313
1344
|
const actual = local[lambdaName][STATS][ARGUMENTS][j]
|
1314
1345
|
const expected = args[i][STATS][ARGUMENTS][j]
|
1346
|
+
if (isGenericType(expected[STATS])) continue
|
1315
1347
|
// TODO: after refactoring the generic nesting and unnesting logic
|
1316
1348
|
// apply it here to judge lambda arguments based on the signature
|
1317
1349
|
// if (
|
@@ -1322,7 +1354,6 @@ export const typeCheck = (
|
|
1322
1354
|
// expected[STATS][TYPE_PROP] = actual[STATS][TYPE_PROP]
|
1323
1355
|
// return
|
1324
1356
|
// }
|
1325
|
-
|
1326
1357
|
if (
|
1327
1358
|
!isUnknownType(actual[STATS]) &&
|
1328
1359
|
!isUnknownType(expected[STATS]) &&
|
@@ -1855,7 +1886,6 @@ export const typeCheck = (
|
|
1855
1886
|
}
|
1856
1887
|
// also type of arg
|
1857
1888
|
const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
|
1858
|
-
const generics = Array.from(args).fill(null)
|
1859
1889
|
for (let i = 0; i < args.length; ++i) {
|
1860
1890
|
// type check
|
1861
1891
|
// TODO get rof pred type
|
@@ -1959,8 +1989,6 @@ export const typeCheck = (
|
|
1959
1989
|
)}) (${stringifyArgs(exp)}) (check #203)`
|
1960
1990
|
)
|
1961
1991
|
}
|
1962
|
-
if (isGenericType(args[i][STATS]))
|
1963
|
-
generics[i] = [ATOM]
|
1964
1992
|
break
|
1965
1993
|
case APPLY:
|
1966
1994
|
{
|
@@ -2030,12 +2058,6 @@ export const typeCheck = (
|
|
2030
2058
|
setTypeRef(env[name][STATS], args[i][STATS])
|
2031
2059
|
else setStatsRef(env[rest[i][VALUE]], args[i])
|
2032
2060
|
}
|
2033
|
-
if (
|
2034
|
-
isGenericType(args[i][STATS]) &&
|
2035
|
-
!isUnknownNotAnyType(env[name][STATS])
|
2036
|
-
) {
|
2037
|
-
generics[i] = env[name][STATS][TYPE_PROP]
|
2038
|
-
}
|
2039
2061
|
}
|
2040
2062
|
if (isUnknownType(args[i][STATS])) {
|
2041
2063
|
retry(args[i][STATS], [first, env], stack, () =>
|
@@ -2081,46 +2103,162 @@ export const typeCheck = (
|
|
2081
2103
|
break
|
2082
2104
|
}
|
2083
2105
|
match({ rest, args, i, env, scope, exp })
|
2084
|
-
|
2085
|
-
if (
|
2086
|
-
isGenericType(args[i][STATS]) &&
|
2087
|
-
!isUnknownNotAnyReturn(env[name][STATS])
|
2088
|
-
)
|
2089
|
-
generics[i] = env[name][STATS][RETURNS]
|
2090
2106
|
}
|
2091
2107
|
}
|
2092
2108
|
}
|
2093
|
-
|
2109
|
+
// GENERICS CODE START
|
2110
|
+
if (
|
2111
|
+
first[VALUE][0] !== PLACEHOLDER &&
|
2112
|
+
env[first[VALUE]][STATS].source &&
|
2113
|
+
env[first[VALUE]][STATS][ARGUMENTS].length &&
|
2114
|
+
env[first[VALUE]][STATS][ARGUMENTS].some(
|
2115
|
+
(x) => isGenericType(x[STATS]) || isGenericReturn(x[STATS])
|
2116
|
+
)
|
2117
|
+
) {
|
2118
|
+
const rec = (ref) => {
|
2119
|
+
if (isGenericReturn(ref[STATS])) {
|
2120
|
+
const [index, multiplier] = ref[STATS][RETURNS][2]
|
2121
|
+
const desiredTypeIndex = env[first[VALUE]][STATS][
|
2122
|
+
ARGUMENTS
|
2123
|
+
].findIndex(
|
2124
|
+
(x) => x[STATS][TYPE_NAME] === ref[STATS][RETURN_NAME]
|
2125
|
+
)
|
2126
|
+
const isCollection = ref[STATS][RETURNS][0] === COLLECTION
|
2127
|
+
if (desiredTypeIndex !== -1) {
|
2128
|
+
const desiredType = isLeaf(rest[desiredTypeIndex])
|
2129
|
+
? rest[desiredTypeIndex]
|
2130
|
+
: rest[desiredTypeIndex][0]
|
2131
|
+
switch (desiredType[TYPE]) {
|
2132
|
+
case ATOM:
|
2133
|
+
ref[STATS][RETURNS] = [ATOM, NUMBER_SUBTYPE()]
|
2134
|
+
break
|
2135
|
+
case WORD:
|
2136
|
+
ref[STATS][RETURNS][0] =
|
2137
|
+
env[desiredType[VALUE]][STATS][TYPE_PROP][0]
|
2138
|
+
ref[STATS][RETURNS][1] =
|
2139
|
+
env[desiredType[VALUE]][STATS][TYPE_PROP][1]
|
2140
|
+
break
|
2141
|
+
case APPLY:
|
2142
|
+
switch (desiredType[VALUE]) {
|
2143
|
+
case KEYWORDS.CREATE_ARRAY:
|
2144
|
+
ref[STATS][RETURNS] = initArrayType({
|
2145
|
+
rem: rest[desiredTypeIndex],
|
2146
|
+
env
|
2147
|
+
})[RETURNS]
|
2148
|
+
break
|
2149
|
+
default:
|
2150
|
+
ref[STATS][RETURNS] =
|
2151
|
+
env[desiredType[VALUE]][STATS][RETURNS]
|
2152
|
+
break
|
2153
|
+
}
|
2154
|
+
break
|
2155
|
+
default:
|
2156
|
+
break
|
2157
|
+
}
|
2158
|
+
if (isCollection) {
|
2159
|
+
const nest = getGenericPropNest(
|
2160
|
+
env[desiredType[VALUE]],
|
2161
|
+
TYPE_PROP
|
2162
|
+
)
|
2163
|
+
resolveGenericNest(ref, RETURNS, nest, multiplier)
|
2164
|
+
}
|
2165
|
+
ref[STATS][RETURNS].length = 2
|
2166
|
+
}
|
2167
|
+
}
|
2168
|
+
const args = ref[STATS][ARGUMENTS]
|
2169
|
+
for (const expected of args) {
|
2170
|
+
if (isGenericType(expected[STATS])) {
|
2171
|
+
const [index, multiplier] =
|
2172
|
+
expected[STATS][TYPE_PROP][2]
|
2173
|
+
const desiredTypeIndex = env[first[VALUE]][STATS][
|
2174
|
+
ARGUMENTS
|
2175
|
+
].findIndex(
|
2176
|
+
(x) =>
|
2177
|
+
x[STATS][TYPE_NAME] === expected[STATS][TYPE_NAME]
|
2178
|
+
)
|
2179
|
+
if (desiredTypeIndex !== -1) {
|
2180
|
+
const desiredType = isLeaf(rest[desiredTypeIndex])
|
2181
|
+
? rest[desiredTypeIndex]
|
2182
|
+
: rest[desiredTypeIndex][0]
|
2183
|
+
|
2184
|
+
switch (desiredType[TYPE]) {
|
2185
|
+
case ATOM:
|
2186
|
+
expected[STATS][TYPE_PROP] = [
|
2187
|
+
ATOM,
|
2188
|
+
NUMBER_SUBTYPE()
|
2189
|
+
]
|
2190
|
+
break
|
2191
|
+
case WORD:
|
2192
|
+
expected[STATS][TYPE_PROP][0] =
|
2193
|
+
env[desiredType[VALUE]][STATS][TYPE_PROP][0]
|
2194
|
+
expected[STATS][TYPE_PROP][1] =
|
2195
|
+
env[desiredType[VALUE]][STATS][TYPE_PROP][1]
|
2196
|
+
break
|
2197
|
+
case APPLY:
|
2198
|
+
switch (desiredType[VALUE]) {
|
2199
|
+
case KEYWORDS.CREATE_ARRAY:
|
2200
|
+
expected[STATS][TYPE_PROP] = initArrayType({
|
2201
|
+
rem: rest[desiredTypeIndex],
|
2202
|
+
env
|
2203
|
+
})[RETURNS]
|
2204
|
+
break
|
2205
|
+
default:
|
2206
|
+
expected[STATS][ARG_COUNT] =
|
2207
|
+
env[desiredType[VALUE]][STATS][ARG_COUNT]
|
2208
|
+
expected[STATS][TYPE_PROP][0] =
|
2209
|
+
env[desiredType[VALUE]][STATS][RETURNS][0]
|
2210
|
+
expected[STATS][TYPE_PROP][1] =
|
2211
|
+
env[desiredType[VALUE]][STATS][RETURNS][1]
|
2212
|
+
break
|
2213
|
+
}
|
2214
|
+
break
|
2215
|
+
default:
|
2216
|
+
break
|
2217
|
+
}
|
2218
|
+
if (expected[STATS][TYPE_PROP][0] === COLLECTION) {
|
2219
|
+
const nest = getGenericPropNest(
|
2220
|
+
env[desiredType[VALUE]],
|
2221
|
+
TYPE_PROP
|
2222
|
+
)
|
2223
|
+
|
2224
|
+
resolveGenericNest(
|
2225
|
+
expected,
|
2226
|
+
TYPE_PROP,
|
2227
|
+
nest,
|
2228
|
+
multiplier === 1 ? 0 : multiplier
|
2229
|
+
)
|
2230
|
+
}
|
2231
|
+
expected[STATS][TYPE_PROP].length = 2
|
2232
|
+
}
|
2233
|
+
}
|
2234
|
+
if (expected[STATS][ARGUMENTS].length) rec(expected)
|
2235
|
+
}
|
2236
|
+
}
|
2094
2237
|
const copy = Object.create(env)
|
2095
2238
|
const newName = `${PLACEHOLDER}${first[VALUE]}`
|
2096
|
-
|
2239
|
+
copy[newName] = null
|
2097
2240
|
copy[newName] = {
|
2098
2241
|
[STATS]: structuredClone(env[first[VALUE]][STATS])
|
2099
2242
|
}
|
2100
|
-
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
[ARG_COUNT]: VARIADIC,
|
2105
|
-
[ARGUMENTS]: [],
|
2106
|
-
[TYPE_PROP]: generics[i],
|
2107
|
-
[RETURNS]: generics[i]
|
2108
|
-
}
|
2109
|
-
}
|
2110
|
-
}
|
2243
|
+
copy[newName][STATS][SIGNATURE] = newName
|
2244
|
+
|
2245
|
+
rec(copy[newName])
|
2246
|
+
|
2111
2247
|
const cexp = structuredClone(exp)
|
2112
2248
|
copy[newName][STATS].source = structuredClone(
|
2113
2249
|
copy[newName][STATS].source
|
2114
2250
|
)
|
2115
2251
|
cexp[0][VALUE] = newName
|
2116
2252
|
copy[newName][STATS].source[1][VALUE] = newName
|
2117
|
-
|
2253
|
+
|
2254
|
+
doOnce(copy[newName][STATS], cexp, stack, () => {
|
2118
2255
|
check(
|
2119
|
-
|
2256
|
+
wrapInArray([copy[newName][STATS].source, cexp]),
|
2120
2257
|
copy,
|
2121
2258
|
scope
|
2122
2259
|
)
|
2123
2260
|
})
|
2261
|
+
// GENERICS END END
|
2124
2262
|
return
|
2125
2263
|
}
|
2126
2264
|
}
|
package/src/types.js
CHANGED
@@ -23,6 +23,8 @@ export const RETURNS = 'returns'
|
|
23
23
|
export const SCOPE_NAME = '__scope__'
|
24
24
|
export const TYPE_PROP = 'type'
|
25
25
|
export const SIGNATURE = 'name'
|
26
|
+
export const TYPE_NAME = 'type_name'
|
27
|
+
export const RETURN_NAME = 'return_name'
|
26
28
|
export const UNBOUND_VARIABLE = '__unbound__'
|
27
29
|
export const UNKNOWN = -1
|
28
30
|
export const COLLECTION = 3
|
@@ -1508,6 +1510,8 @@ export const toArgType = (A, i) => {
|
|
1508
1510
|
[IS_ARGUMENT]: true,
|
1509
1511
|
[SIGNATURE]: PLACEHOLDER,
|
1510
1512
|
[TYPE_PROP]: [APPLY],
|
1513
|
+
[TYPE_NAME]: PLACEHOLDER,
|
1514
|
+
[RETURN_NAME]: returns[VALUE].replaceAll('[', '').replaceAll(']', ''),
|
1511
1515
|
[RETURNS]: toTypeCodes(returns[VALUE], i),
|
1512
1516
|
[ARGUMENTS]: args.map(toArgType).flat(1),
|
1513
1517
|
[ARG_COUNT]: args.length
|
@@ -1519,7 +1523,8 @@ export const toArgType = (A, i) => {
|
|
1519
1523
|
argIndex: i,
|
1520
1524
|
retried: Infinity,
|
1521
1525
|
[IS_ARGUMENT]: true,
|
1522
|
-
[SIGNATURE]:
|
1526
|
+
[SIGNATURE]: PLACEHOLDER,
|
1527
|
+
[TYPE_NAME]: arg[VALUE].replaceAll('[', '').replaceAll(']', ''),
|
1523
1528
|
[TYPE_PROP]: toTypeCodes(arg[VALUE], i),
|
1524
1529
|
[RETURNS]: toTypeCodes(arg[VALUE], i),
|
1525
1530
|
[ARGUMENTS]: [],
|
@@ -1539,6 +1544,8 @@ export const fromSourceToType = (T) => {
|
|
1539
1544
|
retried: Infinity,
|
1540
1545
|
[TYPE_PROP]: [APPLY],
|
1541
1546
|
[SIGNATURE]: name,
|
1547
|
+
[TYPE_NAME]: name,
|
1548
|
+
[RETURN_NAME]: returns[VALUE].replaceAll('[', '').replaceAll(']', ''),
|
1542
1549
|
[ARG_COUNT]: args.length,
|
1543
1550
|
[ARGUMENTS]: args.map(toArgType).flat(1),
|
1544
1551
|
[RETURNS]: toTypeCodes(
|
package/src/utils.js
CHANGED
@@ -297,6 +297,7 @@ export const dfs = (tree, callback) => {
|
|
297
297
|
if (!isLeaf(tree)) for (const leaf of tree) dfs(leaf)
|
298
298
|
else callback(tree)
|
299
299
|
}
|
300
|
+
export const wrapInArray = (ast) => [[APPLY, KEYWORDS.CREATE_ARRAY], ...ast]
|
300
301
|
export const wrapInBlock = (ast) => [
|
301
302
|
[APPLY, KEYWORDS.CALL_FUNCTION],
|
302
303
|
[
|
@@ -389,63 +390,63 @@ export const init = () => {
|
|
389
390
|
// console.log('Added file types.lisp in src')
|
390
391
|
writeFileSync(
|
391
392
|
'index.js',
|
392
|
-
`import { compile, enhance, parse, LISP, UTILS, verify } from '
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
}
|
402
|
-
UTILS.logResult(LISP.serialise(evaluated))
|
403
|
-
} else UTILS.logError(error.message)
|
404
|
-
} catch (error) {
|
405
|
-
UTILS.logError(error.message)
|
406
|
-
}
|
407
|
-
}
|
408
|
-
export const run = (source) => {
|
409
|
-
try {
|
410
|
-
const parsed = parse(source)
|
411
|
-
const { evaluated, error } = UTILS.debug(parsed, false)
|
412
|
-
if (error == null) {
|
413
|
-
UTILS.logResult(LISP.serialise(evaluated))
|
414
|
-
} else UTILS.logError(error.message)
|
415
|
-
} catch (error) {
|
416
|
-
UTILS.logError(error.message)
|
417
|
-
}
|
418
|
-
}
|
419
|
-
export const check = (source, types) => {
|
420
|
-
try {
|
421
|
-
const parsed = parse(source)
|
422
|
-
const error = verify(parsed, types)
|
423
|
-
if (error != null) UTILS.logError(error)
|
424
|
-
} catch (error) {
|
425
|
-
UTILS.logError(error.message)
|
426
|
-
}
|
393
|
+
`import { compile, enhance, parse, LISP, UTILS, verify } from 'fez-lisp'
|
394
|
+
import { readFileSync, writeFileSync } from 'fs'
|
395
|
+
export const dev = (source, types) => {
|
396
|
+
try {
|
397
|
+
const parsed = parse(source)
|
398
|
+
const { evaluated, type, error } = UTILS.debug(parsed, true, types)
|
399
|
+
if (error == null) {
|
400
|
+
if (type) {
|
401
|
+
UTILS.logType(type)
|
427
402
|
}
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
403
|
+
UTILS.logResult(LISP.serialise(evaluated))
|
404
|
+
} else UTILS.logError(error.message)
|
405
|
+
} catch (error) {
|
406
|
+
UTILS.logError(error.message)
|
407
|
+
}
|
408
|
+
}
|
409
|
+
export const run = (source) => {
|
410
|
+
try {
|
411
|
+
const parsed = parse(source)
|
412
|
+
const { evaluated, error } = UTILS.debug(parsed, false)
|
413
|
+
if (error == null) {
|
414
|
+
UTILS.logResult(LISP.serialise(evaluated))
|
415
|
+
} else UTILS.logError(error.message)
|
416
|
+
} catch (error) {
|
417
|
+
UTILS.logError(error.message)
|
418
|
+
}
|
419
|
+
}
|
420
|
+
export const check = (source, types) => {
|
421
|
+
try {
|
422
|
+
const parsed = parse(source)
|
423
|
+
const error = verify(parsed, types)
|
424
|
+
if (error != null) UTILS.logError(error)
|
425
|
+
} catch (error) {
|
426
|
+
UTILS.logError(error.message)
|
427
|
+
}
|
428
|
+
}
|
429
|
+
export const comp = (source) => compile(enhance(parse(source)))
|
430
|
+
const file = readFileSync('./src/main.lisp', 'utf-8')
|
431
|
+
const [src, typ] = UTILS.extractTypes(file)
|
432
|
+
switch (process.argv[2]) {
|
433
|
+
case 'check':
|
434
|
+
check(src, typ)
|
435
|
+
break
|
436
|
+
case 'run':
|
437
|
+
run(src, typ)
|
438
|
+
break
|
439
|
+
case 'comp':
|
440
|
+
writeFileSync(
|
441
|
+
'./src/main.js',
|
442
|
+
'var _ = ' + comp(src) + '; console.log(_)'
|
443
|
+
)
|
444
|
+
break
|
445
|
+
case 'dev':
|
446
|
+
default:
|
447
|
+
dev(src, typ)
|
448
|
+
break
|
449
|
+
}`
|
449
450
|
)
|
450
451
|
console.log('Added file index.js in root')
|
451
452
|
console.log(
|