fez-lisp 1.6.81 → 1.6.83
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/lib/baked/std-T.js +1 -1
- package/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/check.js +188 -165
- package/src/debugger.js +6 -0
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -57,7 +57,8 @@ import {
|
|
57
57
|
log,
|
58
58
|
logExp,
|
59
59
|
stringifyArgs,
|
60
|
-
wrapInApplyLambda
|
60
|
+
wrapInApplyLambda,
|
61
|
+
wrapInBlock
|
61
62
|
} from './utils.js'
|
62
63
|
|
63
64
|
export const identity = (name) => [
|
@@ -661,7 +662,12 @@ const resolveGetter = ({ rem, prop, name, env, caller, exp }) => {
|
|
661
662
|
if (times === level - 1) {
|
662
663
|
setPropToType(env[name][STATS], prop, {
|
663
664
|
[TYPE_PROP]: types.length
|
664
|
-
? [
|
665
|
+
? [
|
666
|
+
type,
|
667
|
+
new SubType([
|
668
|
+
types.at(-1) === COLLECTION ? UNKNOWN : types.at(-1)
|
669
|
+
])
|
670
|
+
]
|
665
671
|
: [UNKNOWN]
|
666
672
|
})
|
667
673
|
} else {
|
@@ -923,15 +929,12 @@ const initArrayType = ({ rem, env }) => {
|
|
923
929
|
subT.add(head[1].types[0])
|
924
930
|
}
|
925
931
|
const [main, sub] = ret[0]
|
926
|
-
if (isSubType(sub) && sub.types.at(-1) === COLLECTION) sub.types.pop()
|
927
932
|
return {
|
928
933
|
[TYPE_PROP]: [APPLY],
|
929
934
|
[RETURNS]: [
|
930
935
|
COLLECTION,
|
931
936
|
isCollection
|
932
|
-
? new SubType(
|
933
|
-
isSubType(sub) ? [COLLECTION, ...sub] : [COLLECTION, main]
|
934
|
-
)
|
937
|
+
? new SubType(isSubType(sub) ? [COLLECTION, ...sub] : [COLLECTION])
|
935
938
|
: new SubType(isSubType(sub) ? [...sub] : [main])
|
936
939
|
]
|
937
940
|
}
|
@@ -1016,137 +1019,133 @@ const resolveReturnType = ({
|
|
1016
1019
|
// ALWAYS APPLY
|
1017
1020
|
// rest.at(-1)[0][TYPE] === APPLY
|
1018
1021
|
// Here is upon application to store the result in the variable
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
? env[returns[VALUE]][STATS][RETURNS][1].nestedLevels()
|
1030
|
-
: 0
|
1031
|
-
: 0
|
1022
|
+
if (isGenericReturn(env[returns[VALUE]][STATS])) {
|
1023
|
+
// 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
1032
|
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1033
|
+
const head = isLeaf(genericReturn)
|
1034
|
+
? genericReturn
|
1035
|
+
: genericReturn[0]
|
1036
1036
|
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1037
|
+
switch (head[TYPE]) {
|
1038
|
+
case ATOM:
|
1039
|
+
setTypeToAtom(env[name][STATS])
|
1040
|
+
break
|
1041
|
+
case WORD:
|
1042
|
+
if (env[head[VALUE]])
|
1043
|
+
setPropToType(
|
1044
|
+
env[name][STATS],
|
1045
|
+
prop,
|
1046
|
+
env[head[VALUE]][STATS]
|
1047
|
+
)
|
1048
|
+
break
|
1049
|
+
case APPLY:
|
1050
|
+
switch (head[VALUE]) {
|
1051
|
+
case KEYWORDS.ANONYMOUS_FUNCTION:
|
1052
|
+
{
|
1053
|
+
// TODO figure out a better way to do this
|
1054
|
+
// This is initialization of identity or any other
|
1055
|
+
// function that returns it's argument
|
1056
|
+
// Redefine the variable but since it's an error doing that
|
1057
|
+
// Delete it first
|
1058
|
+
delete env[name]
|
1059
|
+
check(
|
1060
|
+
[
|
1061
|
+
[APPLY, KEYWORDS.DEFINE_VARIABLE],
|
1062
|
+
[WORD, name],
|
1063
|
+
genericReturn
|
1064
|
+
],
|
1065
|
+
env,
|
1066
|
+
exp
|
1067
|
+
)
|
1065
1068
|
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
}
|
1080
|
-
break
|
1081
|
-
case KEYWORDS.CREATE_ARRAY:
|
1082
|
-
{
|
1083
|
-
setTypeToCollection(env[name][STATS])
|
1084
|
-
setPropToSubReturn(
|
1085
|
-
env[name][STATS],
|
1086
|
-
TYPE_PROP,
|
1087
|
-
initArrayType({ rem: genericReturn, env })
|
1088
|
-
)
|
1089
|
-
}
|
1090
|
-
break
|
1091
|
-
default:
|
1092
|
-
break
|
1069
|
+
// const n = genericReturn.length
|
1070
|
+
// setTypeToAbstraction(env[name][STATS])
|
1071
|
+
// env[name][STATS][ARG_COUNT] = n - 2
|
1072
|
+
// env[name][STATS][ARGUMENTS] = fillUnknownArgs(
|
1073
|
+
// n - 2
|
1074
|
+
// )
|
1075
|
+
// checkReturnType({
|
1076
|
+
// exp: [genericReturn],
|
1077
|
+
// stack,
|
1078
|
+
// name,
|
1079
|
+
// env,
|
1080
|
+
// check
|
1081
|
+
// })
|
1093
1082
|
}
|
1094
1083
|
break
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1084
|
+
case KEYWORDS.CREATE_ARRAY:
|
1085
|
+
{
|
1086
|
+
setTypeToCollection(env[name][STATS])
|
1087
|
+
setPropToSubReturn(
|
1098
1088
|
env[name][STATS],
|
1099
|
-
|
1089
|
+
TYPE_PROP,
|
1090
|
+
initArrayType({ rem: genericReturn, env })
|
1100
1091
|
)
|
1092
|
+
}
|
1093
|
+
break
|
1094
|
+
default:
|
1101
1095
|
break
|
1102
1096
|
}
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1097
|
+
break
|
1098
|
+
default:
|
1099
|
+
if (env[head[VALUE]])
|
1100
|
+
setTypeToReturn(env[name][STATS], env[head[VALUE]][STATS])
|
1101
|
+
break
|
1102
|
+
}
|
1103
|
+
if (env[returns[VALUE]][STATS][RETURNS][0] === COLLECTION) {
|
1104
|
+
const T = isSubType(env[name][STATS][prop][1])
|
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
|
1120
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)])
|
1121
1129
|
} else {
|
1122
|
-
|
1123
|
-
|
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][0] = T.at(-1)
|
1129
|
-
} else {
|
1130
|
-
env[name][STATS][prop][0] = APPLY
|
1131
|
-
env[name][STATS][prop].length = 1
|
1132
|
-
}
|
1133
|
-
}
|
1130
|
+
env[name][STATS][prop][0] = APPLY
|
1131
|
+
env[name][STATS][prop].length = 1
|
1134
1132
|
}
|
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
1133
|
}
|
1144
1134
|
}
|
1145
|
-
} else
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
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
|
+
}
|
1144
|
+
}
|
1145
|
+
}
|
1146
|
+
if (isUnknownType(env[name][STATS]))
|
1147
|
+
stagger(stack, 'prepend', exp, () => {
|
1148
|
+
setTypeToReturnRef(env[name][STATS], env[returns[VALUE]][STATS])
|
1150
1149
|
})
|
1151
1150
|
else {
|
1152
1151
|
// if (SPECIAL_FORMS_SET.has(returns[VALUE]))
|
@@ -1231,7 +1230,10 @@ export const typeCheck = (
|
|
1231
1230
|
env[rest[i][0][VALUE]][STATS][SIGNATURE] ===
|
1232
1231
|
KEYWORDS.ANONYMOUS_FUNCTION
|
1233
1232
|
) {
|
1234
|
-
if (
|
1233
|
+
if (
|
1234
|
+
args[i][STATS][ARG_COUNT] !== VARIADIC &&
|
1235
|
+
argsN !== args[i][STATS][ARG_COUNT]
|
1236
|
+
)
|
1235
1237
|
throw new TypeError(
|
1236
1238
|
`Incorrect number of arguments for (${
|
1237
1239
|
args[i][STATS][SIGNATURE]
|
@@ -1275,7 +1277,8 @@ export const typeCheck = (
|
|
1275
1277
|
)
|
1276
1278
|
throw new TypeError(
|
1277
1279
|
`Incorrect return type for (${
|
1278
|
-
expected[STATS][SIGNATURE]
|
1280
|
+
expected[STATS][SIGNATURE] ??
|
1281
|
+
ANONYMOUS_FUNCTION_TYPE_PREFIX
|
1279
1282
|
}) the (${KEYWORDS.ANONYMOUS_FUNCTION}) argument of (${
|
1280
1283
|
first[VALUE]
|
1281
1284
|
}) at position (${i}). Expected (${formatSubType(
|
@@ -1417,12 +1420,13 @@ export const typeCheck = (
|
|
1417
1420
|
)
|
1418
1421
|
// TODO check let define types
|
1419
1422
|
const name = rest[0][VALUE]
|
1420
|
-
if (name[0] !== PLACEHOLDER && env.hasOwnProperty(name))
|
1423
|
+
if (name[0] !== PLACEHOLDER && env.hasOwnProperty(name)) {
|
1421
1424
|
throw new ReferenceError(
|
1422
1425
|
`Attempting to redeclare (${name}) which was previously declared in this scope (${stringifyArgs(
|
1423
1426
|
exp
|
1424
1427
|
)})`
|
1425
1428
|
)
|
1429
|
+
}
|
1426
1430
|
const rightHand = rest.at(-1)
|
1427
1431
|
const isApply =
|
1428
1432
|
rightHand && rightHand[0] && rightHand[0][TYPE] === APPLY
|
@@ -1432,6 +1436,7 @@ export const typeCheck = (
|
|
1432
1436
|
// Types.set(withScope(name, env), () => formatType(name, env))
|
1433
1437
|
// If current scope is root then these are user defined types
|
1434
1438
|
if (isLambda) {
|
1439
|
+
env[name][STATS].source = exp
|
1435
1440
|
const lambdaName = `${PLACEHOLDER}${name}`
|
1436
1441
|
const fn = [
|
1437
1442
|
[APPLY, KEYWORDS.DEFINE_VARIABLE],
|
@@ -1445,8 +1450,8 @@ export const typeCheck = (
|
|
1445
1450
|
throw new RangeError(
|
1446
1451
|
`Incorrect number of arguments for (${
|
1447
1452
|
expected[STATS][SIGNATURE]
|
1448
|
-
}) Expected (${expected[ARG_COUNT]}) but got (${
|
1449
|
-
actual[ARG_COUNT]
|
1453
|
+
}) Expected (${expected[STATS][ARG_COUNT]}) but got (${
|
1454
|
+
actual[STATS][ARG_COUNT]
|
1450
1455
|
}) (${stringifyArgs(exp)}) (check #1004)`
|
1451
1456
|
)
|
1452
1457
|
}
|
@@ -1626,14 +1631,12 @@ export const typeCheck = (
|
|
1626
1631
|
: env[right[VALUE]] == undefined
|
1627
1632
|
? UNKNOWN
|
1628
1633
|
: env[right[VALUE]][STATS][RETURNS][0]
|
1629
|
-
|
1630
1634
|
if (
|
1631
1635
|
type !== UNKNOWN &&
|
1632
1636
|
type !== ANY &&
|
1633
1637
|
!isGenericReturn(env[right[VALUE]][STATS])
|
1634
1638
|
)
|
1635
1639
|
setTypeToReturn(env[name][STATS], env[right[VALUE]][STATS])
|
1636
|
-
|
1637
1640
|
const resolve = () => {
|
1638
1641
|
const body = rightHand
|
1639
1642
|
const rem = hasBlock(body) ? body.at(-1) : body
|
@@ -1650,9 +1653,9 @@ export const typeCheck = (
|
|
1650
1653
|
})
|
1651
1654
|
}
|
1652
1655
|
resolve()
|
1653
|
-
|
1654
|
-
if (isUnknownType(env[name][STATS]))
|
1656
|
+
if (isUnknownType(env[name][STATS])) {
|
1655
1657
|
once(env[name][STATS], exp, stack, () => resolve())
|
1658
|
+
}
|
1656
1659
|
}
|
1657
1660
|
check(rightHand, env, scope)
|
1658
1661
|
}
|
@@ -1850,7 +1853,7 @@ export const typeCheck = (
|
|
1850
1853
|
}
|
1851
1854
|
// also type of arg
|
1852
1855
|
const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
|
1853
|
-
|
1856
|
+
const generics = Array.from(args).fill(null)
|
1854
1857
|
for (let i = 0; i < args.length; ++i) {
|
1855
1858
|
// type check
|
1856
1859
|
// TODO get rof pred type
|
@@ -1869,7 +1872,8 @@ export const typeCheck = (
|
|
1869
1872
|
!isUnknownType(env[name][STATS])
|
1870
1873
|
if (
|
1871
1874
|
isKnown &&
|
1872
|
-
env[name][STATS][ARG_COUNT] !== VARIADIC
|
1875
|
+
env[name][STATS][ARG_COUNT] !== VARIADIC &&
|
1876
|
+
args[i][STATS][ARG_COUNT] !== VARIADIC
|
1873
1877
|
) {
|
1874
1878
|
if (
|
1875
1879
|
env[name][STATS][ARG_COUNT] !==
|
@@ -1892,9 +1896,6 @@ export const typeCheck = (
|
|
1892
1896
|
)
|
1893
1897
|
}
|
1894
1898
|
}
|
1895
|
-
// if (isGenericType(args[i][STATS])) {
|
1896
|
-
// generics[i] = env[name]
|
1897
|
-
// }
|
1898
1899
|
const eqTypes = equalTypes(
|
1899
1900
|
args[i][STATS],
|
1900
1901
|
env[name][STATS]
|
@@ -1956,6 +1957,8 @@ export const typeCheck = (
|
|
1956
1957
|
)}) (${stringifyArgs(exp)}) (check #203)`
|
1957
1958
|
)
|
1958
1959
|
}
|
1960
|
+
if (isGenericType(args[i][STATS]))
|
1961
|
+
generics[i] = [ATOM]
|
1959
1962
|
break
|
1960
1963
|
case APPLY:
|
1961
1964
|
{
|
@@ -2008,9 +2011,10 @@ export const typeCheck = (
|
|
2008
2011
|
isSpecial &&
|
2009
2012
|
(!equalTypes(args[i][STATS], env[name][STATS]) ||
|
2010
2013
|
!equalSubTypes(args[i][STATS], env[name][STATS]))
|
2011
|
-
)
|
2014
|
+
) {
|
2015
|
+
// CHECKPOINT
|
2012
2016
|
setType(env[name][STATS], args[i][STATS])
|
2013
|
-
else if (
|
2017
|
+
} else if (
|
2014
2018
|
isUnknownType(env[name][STATS]) &&
|
2015
2019
|
!isUnknownType(args[i][STATS])
|
2016
2020
|
) {
|
@@ -2020,11 +2024,16 @@ export const typeCheck = (
|
|
2020
2024
|
// (let range (math:range 1 10))
|
2021
2025
|
// (sum range)
|
2022
2026
|
// But it reduces good inference too
|
2023
|
-
|
2024
2027
|
if (getType(args[i][STATS]) !== APPLY)
|
2025
2028
|
setTypeRef(env[name][STATS], args[i][STATS])
|
2026
2029
|
else setStatsRef(env[rest[i][VALUE]], args[i])
|
2027
2030
|
}
|
2031
|
+
if (
|
2032
|
+
isGenericType(args[i][STATS]) &&
|
2033
|
+
!isUnknownNotAnyType(env[name][STATS])
|
2034
|
+
) {
|
2035
|
+
generics[i] = env[name][STATS][TYPE_PROP]
|
2036
|
+
}
|
2028
2037
|
}
|
2029
2038
|
if (isUnknownType(args[i][STATS])) {
|
2030
2039
|
retry(args[i][STATS], [first, env], stack, () =>
|
@@ -2070,34 +2079,48 @@ export const typeCheck = (
|
|
2070
2079
|
break
|
2071
2080
|
}
|
2072
2081
|
match({ rest, args, i, env, scope, exp })
|
2082
|
+
|
2083
|
+
if (
|
2084
|
+
isGenericType(args[i][STATS]) &&
|
2085
|
+
!isUnknownNotAnyReturn(env[name][STATS])
|
2086
|
+
)
|
2087
|
+
generics[i] = env[name][STATS][RETURNS]
|
2073
2088
|
}
|
2074
2089
|
}
|
2075
2090
|
}
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2100
|
-
|
2091
|
+
if (generics.some((x) => x !== null && x[0] !== UNKNOWN)) {
|
2092
|
+
const copy = Object.create(env)
|
2093
|
+
const newName = `${PLACEHOLDER}${first[VALUE]}`
|
2094
|
+
// copy[newName] = structuredClone(copy[first[VALUE]])
|
2095
|
+
copy[newName] = {
|
2096
|
+
[STATS]: structuredClone(env[first[VALUE]][STATS])
|
2097
|
+
}
|
2098
|
+
for (let i = 0; i < generics.length; ++i) {
|
2099
|
+
if (!generics[i]) continue
|
2100
|
+
copy[newName][STATS][ARGUMENTS][i] = {
|
2101
|
+
[STATS]: {
|
2102
|
+
[ARG_COUNT]: VARIADIC,
|
2103
|
+
[ARGUMENTS]: [],
|
2104
|
+
[TYPE_PROP]: generics[i],
|
2105
|
+
[RETURNS]: generics[i]
|
2106
|
+
}
|
2107
|
+
}
|
2108
|
+
}
|
2109
|
+
const cexp = structuredClone(exp)
|
2110
|
+
copy[newName][STATS].source = structuredClone(
|
2111
|
+
copy[newName][STATS].source
|
2112
|
+
)
|
2113
|
+
cexp[0][VALUE] = newName
|
2114
|
+
copy[newName][STATS].source[1][VALUE] = newName
|
2115
|
+
once(copy[newName][STATS], exp, stack, () => {
|
2116
|
+
check(
|
2117
|
+
wrapInBlock([copy[newName][STATS].source, cexp]),
|
2118
|
+
copy,
|
2119
|
+
scope
|
2120
|
+
)
|
2121
|
+
})
|
2122
|
+
return
|
2123
|
+
}
|
2101
2124
|
}
|
2102
2125
|
}
|
2103
2126
|
stagger(stack, 'append', [first, env], judge)
|
package/src/debugger.js
CHANGED
@@ -874,6 +874,12 @@ const evaluate = (exp, env = keywords) => {
|
|
874
874
|
KEYWORDS.ANONYMOUS_FUNCTION
|
875
875
|
}) (${value}) (${stringifyArgs(exp)})`
|
876
876
|
)
|
877
|
+
if (typeof apply !== 'function')
|
878
|
+
throw new TypeError(
|
879
|
+
`${value} is not a (${KEYWORDS.ANONYMOUS_FUNCTION}) (${stringifyArgs(
|
880
|
+
exp
|
881
|
+
)})`
|
882
|
+
)
|
877
883
|
res = apply(tail, env)
|
878
884
|
if (
|
879
885
|
isDebugging &&
|