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