fez-lisp 1.5.129 → 1.5.130
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 +366 -405
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -315,21 +315,10 @@ const notABooleanType = (a, b) => {
|
|
315
315
|
getSubType(a).has(PREDICATE) &&
|
316
316
|
!isUnknownType(b) &&
|
317
317
|
!isAnyType(b) &&
|
318
|
-
(!hasSubType(b)
|
318
|
+
((!hasSubType(b) && getType(b) !== COLLECTION) ||
|
319
|
+
(hasSubType(b) && getSubType(a).difference(getSubType(b)).size !== 0))
|
319
320
|
)
|
320
321
|
}
|
321
|
-
// const notABooleanReturn = (a, b) => {
|
322
|
-
// return (
|
323
|
-
// hasSubType(a) &&
|
324
|
-
// getSubType(a).has(PREDICATE) &&
|
325
|
-
// !isUnknownReturn(b) &&
|
326
|
-
// !isAnyReturn(b) &&
|
327
|
-
// (
|
328
|
-
// !isAtomReturn(b) ||
|
329
|
-
// !hasSubReturn(b) ||
|
330
|
-
// getSubType(a).difference(getSubReturn(b)).size !== 0)
|
331
|
-
// )
|
332
|
-
// }
|
333
322
|
const notABooleanReturn = (a, b) => {
|
334
323
|
return (
|
335
324
|
hasSubType(a) &&
|
@@ -1049,89 +1038,54 @@ export const typeCheck = (ast) => {
|
|
1049
1038
|
// also type of arg
|
1050
1039
|
const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
|
1051
1040
|
for (let i = 0; i < args.length; ++i) {
|
1052
|
-
const isResLeaf = isLeaf(rest[i])
|
1053
1041
|
// type check
|
1054
1042
|
// TODO get rof pred type
|
1055
1043
|
// const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
|
1056
1044
|
const MAIN_TYPE = getType(args[i][STATS])
|
1057
1045
|
if (MAIN_TYPE === ANY) continue
|
1058
1046
|
// TODO - try to merge special and non special
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
if (!env[name]) continue
|
1063
|
-
// there is a problem here with cond pr when passed as an argument
|
1064
|
-
if (name === KEYWORDS.IF) {
|
1065
|
-
const concequent = [...rest]
|
1066
|
-
const alternative = [...rest]
|
1067
|
-
concequent[i] = rest[i][1]
|
1068
|
-
alternative[i] = rest[i][2]
|
1069
|
-
check([first, ...concequent], env, scope)
|
1070
|
-
check([first, ...alternative], env, scope)
|
1071
|
-
} else if (
|
1072
|
-
isUnknownReturn(env[name][STATS]) &&
|
1073
|
-
!env[name][STATS][IS_ARGUMENT]
|
1074
|
-
) {
|
1075
|
-
return retry(env[name][STATS], stack, () =>
|
1076
|
-
check(exp, env, scope)
|
1077
|
-
)
|
1078
|
-
} else if (
|
1079
|
-
!isUnknownType(args[i][STATS]) &&
|
1080
|
-
!isUnknownReturn(env[name][STATS]) &&
|
1081
|
-
!compareTypeWithReturn(args[i][STATS], env[name][STATS])
|
1082
|
-
)
|
1083
|
-
throw new TypeError(
|
1084
|
-
`Incorrect type of argument (${i}) for special form (${
|
1085
|
-
first[VALUE]
|
1086
|
-
}). Expected (${toTypeNames(
|
1087
|
-
getType(args[i][STATS])
|
1088
|
-
)}) but got (${toTypeNames(
|
1089
|
-
getReturn(env[name][STATS])
|
1090
|
-
)}) (${stringifyArgs(exp)}) (check #1)`
|
1091
|
-
)
|
1092
|
-
else if (
|
1093
|
-
!isUnknownReturn(args[i][STATS]) &&
|
1094
|
-
!isUnknownReturn(env[name][STATS]) &&
|
1095
|
-
notABooleanReturn(args[i][STATS], env[name][STATS])
|
1096
|
-
)
|
1097
|
-
throw new TypeError(
|
1098
|
-
`Incorrect type of argument (${i}) for special form (${
|
1099
|
-
first[VALUE]
|
1100
|
-
}). Expected (${formatSubType(
|
1101
|
-
getTypes(args[i][STATS])
|
1102
|
-
)}) but got (${formatSubType(
|
1103
|
-
getReturns(env[name][STATS])
|
1104
|
-
)}) (${stringifyArgs(exp)}) (check #201)`
|
1105
|
-
)
|
1106
|
-
else {
|
1107
|
-
if (env[name] && getType(env[name][STATS]) === APPLY)
|
1108
|
-
switch (first[VALUE]) {
|
1109
|
-
case KEYWORDS.IF:
|
1110
|
-
break
|
1111
|
-
default:
|
1112
|
-
// TODO fix this assigment
|
1113
|
-
// It turns out it's not possible to determine return type of function here
|
1114
|
-
// what if it's a global function used elsewhere where the return type mwould be different
|
1115
|
-
// THIS willgive lambda return types but refactor is needed still
|
1116
|
-
if (!SPECIAL_FORMS_SET.has(name))
|
1117
|
-
setReturnRef(env[name][STATS], args[i][STATS])
|
1118
|
-
break
|
1119
|
-
}
|
1120
|
-
// TODO also handle casting
|
1121
|
-
}
|
1122
|
-
} else {
|
1047
|
+
// REFACTORING
|
1048
|
+
if (first[TYPE] === APPLY) {
|
1049
|
+
if (isLeaf(rest[i])) {
|
1123
1050
|
switch (rest[i][TYPE]) {
|
1124
1051
|
case WORD:
|
1125
1052
|
{
|
1126
1053
|
const name = rest[i][VALUE]
|
1127
1054
|
if (!env[name]) continue
|
1128
|
-
|
1055
|
+
const isKnown =
|
1129
1056
|
!isUnknownType(args[i][STATS]) &&
|
1130
|
-
!isUnknownType(env[name][STATS])
|
1057
|
+
!isUnknownType(env[name][STATS])
|
1058
|
+
if (
|
1059
|
+
isKnown &&
|
1060
|
+
env[name][STATS][ARG_COUNT] !== VARIADIC
|
1061
|
+
) {
|
1062
|
+
if (
|
1063
|
+
env[name][STATS][ARG_COUNT] !==
|
1064
|
+
args[i][STATS][ARG_COUNT]
|
1065
|
+
) {
|
1066
|
+
// TODO: Investigate why there used to be and error called #111 with this condition if (args[i][STATS][ARG_COUNT] === undefined)
|
1067
|
+
if (getType(args[i][STATS]) === APPLY)
|
1068
|
+
throw new TypeError(
|
1069
|
+
`Incorrect number of arguments for (${
|
1070
|
+
args[i][STATS][SIGNATURE]
|
1071
|
+
}) the (${
|
1072
|
+
KEYWORDS.ANONYMOUS_FUNCTION
|
1073
|
+
}) argument of (${
|
1074
|
+
first[VALUE]
|
1075
|
+
}) at position (${i}). Expected (= ${
|
1076
|
+
args[i][STATS][ARG_COUNT]
|
1077
|
+
}) but got ${
|
1078
|
+
env[name][STATS][ARG_COUNT]
|
1079
|
+
} (${stringifyArgs(exp)}) (check #778)`
|
1080
|
+
)
|
1081
|
+
}
|
1082
|
+
}
|
1083
|
+
if (
|
1084
|
+
isKnown &&
|
1131
1085
|
!compareTypes(args[i][STATS], env[name][STATS])
|
1132
1086
|
)
|
1133
1087
|
throw new TypeError(
|
1134
|
-
`Incorrect type of argument (${i}) for
|
1088
|
+
`Incorrect type of argument (${i}) for (${
|
1135
1089
|
first[VALUE]
|
1136
1090
|
}). Expected (${toTypeNames(
|
1137
1091
|
getType(args[i][STATS])
|
@@ -1140,12 +1094,12 @@ export const typeCheck = (ast) => {
|
|
1140
1094
|
)}) (${stringifyArgs(exp)}) (check #3)`
|
1141
1095
|
)
|
1142
1096
|
else if (
|
1143
|
-
|
1144
|
-
!isUnknownType(env[name][STATS]) &&
|
1097
|
+
isKnown &&
|
1145
1098
|
notABooleanType(args[i][STATS], env[name][STATS])
|
1099
|
+
// TODO: Add a check if subtype is a UKNOWN (for uknown array)
|
1146
1100
|
)
|
1147
1101
|
throw new TypeError(
|
1148
|
-
`Incorrect type of argument (${i}) for
|
1102
|
+
`Incorrect type of argument (${i}) for (${
|
1149
1103
|
first[VALUE]
|
1150
1104
|
}). Expected (${formatSubType(
|
1151
1105
|
getTypes(args[i][STATS])
|
@@ -1166,7 +1120,8 @@ export const typeCheck = (ast) => {
|
|
1166
1120
|
// check(exp, env, scope)
|
1167
1121
|
// )
|
1168
1122
|
// } else
|
1169
|
-
|
1123
|
+
if (isSpecial)
|
1124
|
+
setType(env[name][STATS], args[i][STATS])
|
1170
1125
|
}
|
1171
1126
|
}
|
1172
1127
|
break
|
@@ -1176,7 +1131,7 @@ export const typeCheck = (ast) => {
|
|
1176
1131
|
rest[i][TYPE] !== args[i][STATS][TYPE_PROP][0]
|
1177
1132
|
)
|
1178
1133
|
throw new TypeError(
|
1179
|
-
`Incorrect type of argument (${i}) for
|
1134
|
+
`Incorrect type of argument (${i}) for (${
|
1180
1135
|
first[VALUE]
|
1181
1136
|
}). Expected (${toTypeNames(
|
1182
1137
|
args[i][STATS][TYPE_PROP][0]
|
@@ -1190,371 +1145,377 @@ export const typeCheck = (ast) => {
|
|
1190
1145
|
!isAtomABoolean(rest[i][VALUE])
|
1191
1146
|
)
|
1192
1147
|
throw new TypeError(
|
1193
|
-
`Incorrect type of argument (${i}) for
|
1148
|
+
`Incorrect type of argument (${i}) for (${
|
1194
1149
|
first[VALUE]
|
1195
1150
|
}). Expected (${formatSubType(
|
1196
1151
|
getTypes(args[i][STATS])
|
1197
|
-
)}) but got (${
|
1198
|
-
|
1199
|
-
|
1152
|
+
)}) but got (${
|
1153
|
+
rest[i][TYPE] === ATOM
|
1154
|
+
? toTypeNames(rest[i][TYPE])
|
1155
|
+
: formatSubType(
|
1156
|
+
getTypes(env[rest[i][VALUE]][STATS])
|
1157
|
+
)
|
1158
|
+
}) (${stringifyArgs(exp)}) (check #203)`
|
1200
1159
|
)
|
1201
1160
|
break
|
1202
1161
|
}
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
// type checking
|
1207
|
-
else if (isResLeaf) {
|
1208
|
-
const T =
|
1209
|
-
rest[i][TYPE] === WORD
|
1210
|
-
? env[rest[i][VALUE]]
|
1211
|
-
? getType(env[rest[i][VALUE]][STATS])
|
1212
|
-
: UNKNOWN
|
1213
|
-
: rest[i][TYPE]
|
1214
|
-
|
1215
|
-
if (T === ATOM && !isUnknownType(args[i][STATS])) {
|
1216
|
-
if (getType(args[i][STATS]) !== ATOM)
|
1217
|
-
throw new TypeError(
|
1218
|
-
`Incorrect type of argument (${i}) for (${
|
1219
|
-
first[VALUE]
|
1220
|
-
}). Expected (${toTypeNames(
|
1221
|
-
getType(args[i][STATS])
|
1222
|
-
)}) but got (${toTypeNames(T)}) (${stringifyArgs(
|
1223
|
-
exp
|
1224
|
-
)}) (check #10)`
|
1225
|
-
)
|
1226
|
-
else if (
|
1227
|
-
rest[i][TYPE] === ATOM
|
1228
|
-
? hasSubType(args[i][STATS]) &&
|
1229
|
-
getSubType(args[i][STATS]).has(PREDICATE) &&
|
1230
|
-
!isAtomABoolean(rest[i][VALUE])
|
1231
|
-
: notABooleanType(
|
1232
|
-
args[i][STATS],
|
1233
|
-
env[rest[i][VALUE]][STATS]
|
1234
|
-
)
|
1235
|
-
)
|
1236
|
-
throw new TypeError(
|
1237
|
-
`Incorrect type of argument (${i}) for special form (${
|
1238
|
-
first[VALUE]
|
1239
|
-
}). Expected (${formatSubType(
|
1240
|
-
getTypes(args[i][STATS])
|
1241
|
-
)}) but got (${
|
1242
|
-
rest[i][TYPE] === ATOM
|
1243
|
-
? toTypeNames(rest[i][TYPE])
|
1244
|
-
: formatSubType(
|
1245
|
-
getTypes(env[rest[i][VALUE]][STATS])
|
1246
|
-
)
|
1247
|
-
}) (${stringifyArgs(exp)}) (check #205)`
|
1248
|
-
)
|
1249
|
-
} else if (
|
1250
|
-
T === APPLY &&
|
1251
|
-
!isUnknownType(args[i][STATS]) &&
|
1252
|
-
!isUnknownType(env[rest[i][VALUE]][STATS]) &&
|
1253
|
-
env[rest[i][VALUE]][STATS][ARG_COUNT] !== VARIADIC
|
1254
|
-
) {
|
1255
|
-
// if (
|
1256
|
-
// getType(args[i][STATS]) !==
|
1257
|
-
// getType(env[rest[i][VALUE]][STATS][ARGUMENTS][i][STATS])
|
1258
|
-
// )
|
1259
|
-
// // TODO this should really happen in 10 or 16
|
1260
|
-
// throw new TypeError(
|
1261
|
-
// `Incorrect type for argument of (${
|
1262
|
-
// first[VALUE]
|
1263
|
-
// }) at position (${i}). Expected (${
|
1264
|
-
// STATIC_TYPES.ABSTRACTION
|
1265
|
-
// }) but got (${toTypeNames(
|
1266
|
-
// getType(
|
1267
|
-
// env[rest[i][VALUE]][STATS][ARGUMENTS][i][STATS]
|
1268
|
-
// )
|
1269
|
-
// )}) (${stringifyArgs(exp)}) (check #111)`
|
1270
|
-
// )
|
1271
|
-
// // Handles words that are Lambdas
|
1272
|
-
// else
|
1273
|
-
if (
|
1274
|
-
env[rest[i][VALUE]][STATS][ARG_COUNT] !==
|
1275
|
-
args[i][STATS][ARG_COUNT]
|
1276
|
-
) {
|
1277
|
-
if (args[i][STATS][ARG_COUNT] === undefined)
|
1278
|
-
throw new TypeError(
|
1279
|
-
`Incorrect type for argument of (${
|
1280
|
-
first[VALUE]
|
1281
|
-
}) at position (${i}). Expected (${
|
1282
|
-
STATIC_TYPES.ABSTRACTION
|
1283
|
-
}) but got (${toTypeNames(
|
1284
|
-
getType(args[i][STATS])
|
1285
|
-
)}) (${stringifyArgs(exp)}) (check #111)`
|
1286
|
-
)
|
1287
|
-
else if (getType(args[i][STATS]) === APPLY)
|
1288
|
-
throw new TypeError(
|
1289
|
-
`Incorrect number of arguments for (${
|
1290
|
-
args[i][STATS][SIGNATURE]
|
1291
|
-
}) the (${
|
1292
|
-
KEYWORDS.ANONYMOUS_FUNCTION
|
1293
|
-
}) argument of (${
|
1294
|
-
first[VALUE]
|
1295
|
-
}) at position (${i}). Expected (= ${
|
1296
|
-
args[i][STATS][ARG_COUNT]
|
1297
|
-
}) but got ${
|
1298
|
-
env[rest[i][VALUE]][STATS][ARG_COUNT]
|
1299
|
-
} (${stringifyArgs(exp)}) (check #778)`
|
1300
|
-
)
|
1301
|
-
} else {
|
1302
|
-
// DEFINED LAMBDAS TYPE CHECKING
|
1303
|
-
// #C1
|
1304
|
-
// TODO delete this maybe
|
1305
|
-
// It will not be possilbe to know return type
|
1306
|
-
const match1 = () => {
|
1307
|
-
const actual = env[rest[i][VALUE]]
|
1308
|
-
const expected = args[i]
|
1162
|
+
case APPLY: {
|
1163
|
+
const name = rest[i][VALUE]
|
1164
|
+
if (!env[name]) continue
|
1309
1165
|
if (
|
1310
|
-
!
|
1311
|
-
!
|
1312
|
-
|
1166
|
+
!isUnknownType(args[i][STATS]) &&
|
1167
|
+
!isUnknownType(env[name][STATS]) &&
|
1168
|
+
env[name][STATS][ARG_COUNT] !== VARIADIC
|
1313
1169
|
) {
|
1314
|
-
throw new TypeError(
|
1315
|
-
`Incorrect return type for (${
|
1316
|
-
expected[STATS][SIGNATURE]
|
1317
|
-
}) the (${
|
1318
|
-
KEYWORDS.ANONYMOUS_FUNCTION
|
1319
|
-
}) argument of (${
|
1320
|
-
first[VALUE]
|
1321
|
-
}) at position (${i}). Expected (${toTypeNames(
|
1322
|
-
getReturn(expected[STATS])
|
1323
|
-
)}) but got (${toTypeNames(
|
1324
|
-
getReturn(actual[STATS])
|
1325
|
-
)}) (${stringifyArgs(exp)}) (check #782)`
|
1326
|
-
)
|
1327
|
-
} else retry(actual[STATS], stack, () => match1())
|
1328
|
-
}
|
1329
|
-
match1()
|
1330
|
-
for (
|
1331
|
-
let j = 0;
|
1332
|
-
j < args[i][STATS][ARGUMENTS].length;
|
1333
|
-
++j
|
1334
|
-
) {
|
1335
|
-
const match2 = () => {
|
1336
|
-
const actual =
|
1337
|
-
env[rest[i][VALUE]][STATS][ARGUMENTS][j]
|
1338
|
-
const expected = args[i][STATS][ARGUMENTS][j]
|
1339
1170
|
if (
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1171
|
+
env[name][STATS][ARG_COUNT] !==
|
1172
|
+
args[i][STATS][ARG_COUNT]
|
1173
|
+
) {
|
1174
|
+
if (args[i][STATS][ARG_COUNT] === undefined)
|
1175
|
+
throw new TypeError(
|
1176
|
+
`Incorrect type for argument of (${
|
1177
|
+
first[VALUE]
|
1178
|
+
}) at position (${i}). Expected (${
|
1179
|
+
STATIC_TYPES.ABSTRACTION
|
1180
|
+
}) but got (${toTypeNames(
|
1181
|
+
getType(args[i][STATS])
|
1182
|
+
)}) (${stringifyArgs(exp)}) (check #111)`
|
1183
|
+
)
|
1184
|
+
else if (getType(args[i][STATS]) === APPLY)
|
1185
|
+
throw new TypeError(
|
1186
|
+
`Incorrect number of arguments for (${
|
1187
|
+
args[i][STATS][SIGNATURE]
|
1188
|
+
}) the (${
|
1189
|
+
KEYWORDS.ANONYMOUS_FUNCTION
|
1190
|
+
}) argument of (${
|
1191
|
+
first[VALUE]
|
1192
|
+
}) at position (${i}). Expected (= ${
|
1193
|
+
args[i][STATS][ARG_COUNT]
|
1194
|
+
}) but got ${
|
1195
|
+
env[name][STATS][ARG_COUNT]
|
1196
|
+
} (${stringifyArgs(exp)}) (check #778)`
|
1197
|
+
)
|
1198
|
+
}
|
1199
|
+
}
|
1200
|
+
// DEFINED LAMBDAS TYPE CHECKING
|
1201
|
+
// #C1
|
1202
|
+
// TODO delete this maybe
|
1203
|
+
// It will not be possilbe to know return type
|
1204
|
+
const match1 = () => {
|
1205
|
+
const actual = env[name]
|
1206
|
+
const expected = args[i]
|
1207
|
+
if (
|
1208
|
+
!isUnknownReturn(expected[STATS]) &&
|
1209
|
+
!isUnknownReturn(actual[STATS]) &&
|
1210
|
+
!compareReturns(expected[STATS], actual[STATS])
|
1211
|
+
) {
|
1344
1212
|
throw new TypeError(
|
1345
|
-
`Incorrect type for (${
|
1213
|
+
`Incorrect return type for (${
|
1214
|
+
expected[STATS][SIGNATURE]
|
1215
|
+
}) the (${
|
1346
1216
|
KEYWORDS.ANONYMOUS_FUNCTION
|
1347
|
-
}) (${
|
1348
|
-
|
1349
|
-
})
|
1350
|
-
|
1351
|
-
}). Expected (${toTypeNames(
|
1352
|
-
getType(expected[STATS])
|
1217
|
+
}) argument of (${
|
1218
|
+
first[VALUE]
|
1219
|
+
}) at position (${i}). Expected (${toTypeNames(
|
1220
|
+
getReturn(expected[STATS])
|
1353
1221
|
)}) but got (${toTypeNames(
|
1354
|
-
|
1355
|
-
)}) (${stringifyArgs(exp)}) (check #
|
1222
|
+
getReturn(actual[STATS])
|
1223
|
+
)}) (${stringifyArgs(exp)}) (check #782)`
|
1356
1224
|
)
|
1357
|
-
else retry(actual[STATS], stack, () =>
|
1225
|
+
} else retry(actual[STATS], stack, () => match1())
|
1226
|
+
}
|
1227
|
+
match1()
|
1228
|
+
for (
|
1229
|
+
let j = 0;
|
1230
|
+
j < args[i][STATS][ARGUMENTS].length;
|
1231
|
+
++j
|
1232
|
+
) {
|
1233
|
+
const match2 = () => {
|
1234
|
+
const actual = env[name][STATS][ARGUMENTS][j]
|
1235
|
+
const expected = args[i][STATS][ARGUMENTS][j]
|
1236
|
+
if (
|
1237
|
+
!isUnknownType(actual[STATS]) &&
|
1238
|
+
!isUnknownType(expected[STATS]) &&
|
1239
|
+
!compareTypes(actual[STATS], expected[STATS])
|
1240
|
+
)
|
1241
|
+
throw new TypeError(
|
1242
|
+
`Incorrect type for (${
|
1243
|
+
KEYWORDS.ANONYMOUS_FUNCTION
|
1244
|
+
}) (${
|
1245
|
+
args[i][STATS][SIGNATURE]
|
1246
|
+
}) argument at position (${j}) named as (${
|
1247
|
+
actual[STATS][SIGNATURE]
|
1248
|
+
}). Expected (${toTypeNames(
|
1249
|
+
getType(expected[STATS])
|
1250
|
+
)}) but got (${toTypeNames(
|
1251
|
+
getType(actual[STATS])
|
1252
|
+
)}) (${stringifyArgs(exp)}) (check #781)`
|
1253
|
+
)
|
1254
|
+
else retry(actual[STATS], stack, () => match2())
|
1255
|
+
}
|
1256
|
+
match2()
|
1358
1257
|
}
|
1359
|
-
match2()
|
1360
1258
|
}
|
1361
1259
|
}
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
getType(args[i][STATS])
|
1375
|
-
)
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
env
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1260
|
+
if (!isSpecial) {
|
1261
|
+
const name = rest[i][VALUE]
|
1262
|
+
if (isUnknownType(args[i][STATS])) {
|
1263
|
+
retry(args[i][STATS], stack, () =>
|
1264
|
+
check(exp, env, scope)
|
1265
|
+
)
|
1266
|
+
}
|
1267
|
+
// TOODO maybe we don't need this
|
1268
|
+
else if (
|
1269
|
+
env[name] &&
|
1270
|
+
!isUnknownType(args[i][STATS]) &&
|
1271
|
+
isUnknownType(env[name][STATS]) &&
|
1272
|
+
getType(args[i][STATS]) !== APPLY
|
1273
|
+
) {
|
1274
|
+
// REFF ASSIGMENT
|
1275
|
+
setTypeRef(env[name][STATS], args[i][STATS])
|
1276
|
+
} else if (
|
1277
|
+
env[name] &&
|
1278
|
+
!isUnknownType(args[i][STATS]) &&
|
1279
|
+
isUnknownType(env[name][STATS])
|
1280
|
+
) {
|
1281
|
+
setStatsRef(env[rest[i][VALUE]], args[i])
|
1282
|
+
}
|
1283
|
+
}
|
1284
|
+
} else {
|
1285
|
+
const name = rest[i][0][VALUE]
|
1286
|
+
if (!env[name]) continue
|
1287
|
+
if (isSpecial) {
|
1288
|
+
// there is a problem here with cond pr when passed as an argument
|
1289
|
+
if (name === KEYWORDS.IF) {
|
1290
|
+
const concequent = [...rest]
|
1291
|
+
const alternative = [...rest]
|
1292
|
+
concequent[i] = rest[i][1]
|
1293
|
+
alternative[i] = rest[i][2]
|
1294
|
+
check([first, ...concequent], env, scope)
|
1295
|
+
check([first, ...alternative], env, scope)
|
1296
|
+
} else if (
|
1297
|
+
isUnknownReturn(env[name][STATS]) &&
|
1298
|
+
!env[name][STATS][IS_ARGUMENT]
|
1299
|
+
) {
|
1300
|
+
return retry(env[name][STATS], stack, () =>
|
1301
|
+
check(exp, env, scope)
|
1302
|
+
)
|
1303
|
+
} else if (
|
1304
|
+
!isUnknownType(args[i][STATS]) &&
|
1305
|
+
!isUnknownReturn(env[name][STATS]) &&
|
1306
|
+
!compareTypeWithReturn(
|
1307
|
+
args[i][STATS],
|
1308
|
+
env[name][STATS]
|
1309
|
+
)
|
1310
|
+
)
|
1409
1311
|
throw new TypeError(
|
1410
1312
|
`Incorrect type of argument (${i}) for (${
|
1411
1313
|
first[VALUE]
|
1412
1314
|
}). Expected (${toTypeNames(
|
1413
|
-
getType(
|
1315
|
+
getType(args[i][STATS])
|
1414
1316
|
)}) but got (${toTypeNames(
|
1415
|
-
getReturn(
|
1416
|
-
)}) (${stringifyArgs(exp)}) (check #
|
1317
|
+
getReturn(env[name][STATS])
|
1318
|
+
)}) (${stringifyArgs(exp)}) (check #1)`
|
1417
1319
|
)
|
1418
|
-
else if (
|
1320
|
+
else if (
|
1321
|
+
!isUnknownReturn(args[i][STATS]) &&
|
1322
|
+
!isUnknownReturn(env[name][STATS]) &&
|
1323
|
+
notABooleanReturn(args[i][STATS], env[name][STATS])
|
1324
|
+
)
|
1419
1325
|
throw new TypeError(
|
1420
1326
|
`Incorrect type of argument (${i}) for (${
|
1421
1327
|
first[VALUE]
|
1422
1328
|
}). Expected (${formatSubType(
|
1423
|
-
getTypes(
|
1329
|
+
getTypes(args[i][STATS])
|
1424
1330
|
)}) but got (${formatSubType(
|
1425
|
-
getReturns(
|
1426
|
-
)}) (${stringifyArgs(exp)}) (check #
|
1331
|
+
getReturns(env[name][STATS])
|
1332
|
+
)}) (${stringifyArgs(exp)}) (check #201)`
|
1427
1333
|
)
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1334
|
+
else {
|
1335
|
+
if (env[name] && getType(env[name][STATS]) === APPLY)
|
1336
|
+
switch (first[VALUE]) {
|
1337
|
+
case KEYWORDS.IF:
|
1338
|
+
break
|
1339
|
+
default:
|
1340
|
+
// TODO fix this assigment
|
1341
|
+
// It turns out it's not possible to determine return type of function here
|
1342
|
+
// what if it's a global function used elsewhere where the return type mwould be different
|
1343
|
+
// THIS willgive lambda return types but refactor is needed still
|
1344
|
+
if (!SPECIAL_FORMS_SET.has(name))
|
1345
|
+
setReturnRef(env[name][STATS], args[i][STATS])
|
1346
|
+
break
|
1347
|
+
}
|
1348
|
+
// TODO also handle casting
|
1349
|
+
}
|
1350
|
+
} else {
|
1351
|
+
const match = () => {
|
1352
|
+
const actual =
|
1353
|
+
rest[i][0][VALUE] === KEYWORDS.CREATE_ARRAY
|
1354
|
+
? initArrayType({ rem: rest[i], env }) ??
|
1355
|
+
env[rest[i][0][VALUE]][STATS]
|
1356
|
+
: env[rest[i][0][VALUE]][STATS]
|
1357
|
+
const expected = args[i][STATS]
|
1358
|
+
retryArgs(args[i][STATS], stack, () => match())
|
1359
|
+
if (
|
1360
|
+
!isUnknownType(expected) &&
|
1361
|
+
!isUnknownReturn(actual)
|
1362
|
+
)
|
1363
|
+
if (!compareTypeWithReturn(expected, actual))
|
1364
|
+
throw new TypeError(
|
1365
|
+
`Incorrect type of argument (${i}) for (${
|
1366
|
+
first[VALUE]
|
1367
|
+
}). Expected (${toTypeNames(
|
1368
|
+
getType(expected)
|
1369
|
+
)}) but got (${toTypeNames(
|
1370
|
+
getReturn(actual)
|
1371
|
+
)}) (${stringifyArgs(exp)}) (check #16)`
|
1372
|
+
)
|
1373
|
+
else if (notABooleanReturn(expected, actual)) {
|
1374
|
+
throw new TypeError(
|
1375
|
+
`Incorrect type of argument (${i}) for (${
|
1376
|
+
first[VALUE]
|
1377
|
+
}). Expected (${formatSubType(
|
1378
|
+
getTypes(expected)
|
1379
|
+
)}) but got (${formatSubType(
|
1380
|
+
getReturns(actual)
|
1381
|
+
)}) (${stringifyArgs(exp)}) (check #206)`
|
1382
|
+
)
|
1383
|
+
} else {
|
1384
|
+
switch (getType(expected)) {
|
1385
|
+
// almost exclusively for anonymous lambdas
|
1386
|
+
case APPLY:
|
1387
|
+
{
|
1388
|
+
const argsN = rest[i].length - 2
|
1389
|
+
if (
|
1390
|
+
env[rest[i][0][VALUE]][STATS][
|
1391
|
+
SIGNATURE
|
1392
|
+
] === KEYWORDS.ANONYMOUS_FUNCTION
|
1393
|
+
) {
|
1394
|
+
if (argsN !== args[i][STATS][ARG_COUNT])
|
1479
1395
|
throw new TypeError(
|
1480
|
-
`Incorrect
|
1481
|
-
|
1396
|
+
`Incorrect number of arguments for (${
|
1397
|
+
args[i][STATS][SIGNATURE]
|
1482
1398
|
}) the (${
|
1483
1399
|
KEYWORDS.ANONYMOUS_FUNCTION
|
1484
1400
|
}) argument of (${
|
1485
1401
|
first[VALUE]
|
1486
|
-
}) at position (${i}). Expected (${
|
1487
|
-
|
1488
|
-
|
1489
|
-
getReturn(actual[STATS])
|
1490
|
-
)}) (${stringifyArgs(
|
1402
|
+
}) at position (${i}). Expected (= ${
|
1403
|
+
args[i][STATS][ARG_COUNT]
|
1404
|
+
}) but got ${argsN} (${stringifyArgs(
|
1491
1405
|
exp
|
1492
|
-
)}) (check #
|
1406
|
+
)}) (check #777)`
|
1493
1407
|
)
|
1494
|
-
else
|
1495
|
-
|
1496
|
-
|
1408
|
+
else {
|
1409
|
+
// ANONYMOUS LAMBDAS TYPE CHECKING
|
1410
|
+
const local = Object.create(env)
|
1411
|
+
const lambdaName = `${ANONYMOUS_FUNCTION_TYPE_PREFIX}${i}::${++scopeIndex}`
|
1412
|
+
check(
|
1413
|
+
[
|
1414
|
+
[APPLY, KEYWORDS.DEFINE_VARIABLE],
|
1415
|
+
[WORD, lambdaName],
|
1416
|
+
rest[i]
|
1417
|
+
],
|
1418
|
+
local,
|
1419
|
+
scope
|
1497
1420
|
)
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
!isUnknownType(actual[STATS]) &&
|
1512
|
-
!isUnknownType(expected[STATS]) &&
|
1513
|
-
!compareTypes(
|
1514
|
-
actual[STATS],
|
1515
|
-
expected[STATS]
|
1421
|
+
// TODO delete this maybe
|
1422
|
+
// #C2
|
1423
|
+
// It will not be possilbe to know return type
|
1424
|
+
const match1 = () => {
|
1425
|
+
const actual = local[lambdaName]
|
1426
|
+
const expected = args[i]
|
1427
|
+
if (
|
1428
|
+
!isUnknownReturn(expected[STATS]) &&
|
1429
|
+
!isUnknownReturn(actual[STATS]) &&
|
1430
|
+
!compareReturns(
|
1431
|
+
expected[STATS],
|
1432
|
+
actual[STATS]
|
1433
|
+
)
|
1516
1434
|
)
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1435
|
+
throw new TypeError(
|
1436
|
+
`Incorrect return type for (${
|
1437
|
+
expected[STATS][SIGNATURE]
|
1438
|
+
}) the (${
|
1439
|
+
KEYWORDS.ANONYMOUS_FUNCTION
|
1440
|
+
}) argument of (${
|
1441
|
+
first[VALUE]
|
1442
|
+
}) at position (${i}). Expected (${toTypeNames(
|
1443
|
+
getReturn(expected[STATS])
|
1444
|
+
)}) but got (${toTypeNames(
|
1445
|
+
getReturn(actual[STATS])
|
1446
|
+
)}) (${stringifyArgs(
|
1447
|
+
exp
|
1448
|
+
)}) (check #779)`
|
1449
|
+
)
|
1450
|
+
else
|
1451
|
+
retry(actual[STATS], stack, () =>
|
1452
|
+
match1()
|
1453
|
+
)
|
1454
|
+
}
|
1455
|
+
match1()
|
1456
|
+
for (
|
1457
|
+
let j = 0;
|
1458
|
+
j < args[i][STATS][ARGUMENTS].length;
|
1459
|
+
++j
|
1460
|
+
) {
|
1461
|
+
const match2 = () => {
|
1462
|
+
const actual =
|
1524
1463
|
local[lambdaName][STATS][
|
1525
1464
|
ARGUMENTS
|
1526
|
-
][j]
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1465
|
+
][j]
|
1466
|
+
const expected =
|
1467
|
+
args[i][STATS][ARGUMENTS][j]
|
1468
|
+
if (
|
1469
|
+
!isUnknownType(actual[STATS]) &&
|
1470
|
+
!isUnknownType(expected[STATS]) &&
|
1471
|
+
!compareTypes(
|
1472
|
+
actual[STATS],
|
1473
|
+
expected[STATS]
|
1474
|
+
)
|
1475
|
+
)
|
1476
|
+
throw new TypeError(
|
1477
|
+
`Incorrect type for (${
|
1478
|
+
KEYWORDS.ANONYMOUS_FUNCTION
|
1479
|
+
}) (${
|
1480
|
+
args[i][STATS][SIGNATURE]
|
1481
|
+
}) argument at position (${j}) named as (${
|
1482
|
+
local[lambdaName][STATS][
|
1483
|
+
ARGUMENTS
|
1484
|
+
][j][STATS][SIGNATURE]
|
1485
|
+
}). Expected (${toTypeNames(
|
1486
|
+
getType(expected[STATS])
|
1487
|
+
)}) but got (${toTypeNames(
|
1488
|
+
getType(actual[STATS])
|
1489
|
+
)}) (${stringifyArgs(
|
1490
|
+
exp
|
1491
|
+
)}) (check #780)`
|
1492
|
+
)
|
1493
|
+
else
|
1494
|
+
retry(actual[STATS], stack, () =>
|
1495
|
+
match2()
|
1496
|
+
)
|
1497
|
+
}
|
1498
|
+
match2()
|
1499
|
+
}
|
1539
1500
|
}
|
1540
|
-
|
1501
|
+
} else {
|
1502
|
+
// TODO fix curry: lambdas enter here as undefined
|
1541
1503
|
}
|
1542
1504
|
}
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1505
|
+
break
|
1506
|
+
// case ATOM:
|
1507
|
+
// case COLLECTION:
|
1508
|
+
// break
|
1546
1509
|
}
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
// break
|
1551
|
-
}
|
1510
|
+
}
|
1511
|
+
else if (isUnknownType(expected))
|
1512
|
+
retry(args[i][STATS], stack, () => match())
|
1552
1513
|
}
|
1553
|
-
|
1554
|
-
|
1514
|
+
match()
|
1515
|
+
}
|
1555
1516
|
}
|
1556
|
-
match()
|
1557
1517
|
}
|
1518
|
+
// REFACTORING
|
1558
1519
|
}
|
1559
1520
|
}
|
1560
1521
|
})
|