fez-lisp 1.5.129 → 1.5.131

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 +337 -435
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.129",
5
+ "version": "1.5.131",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
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) || getSubType(a).difference(getSubType(b)).size !== 0)
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) &&
@@ -727,11 +716,145 @@ const checkReturnType = ({ exp, stack, name, env }) => {
727
716
  stack
728
717
  })
729
718
  }
719
+
730
720
  export const typeCheck = (ast) => {
731
- let scopeIndex = 0
732
- const root = structuredClone(SPECIAL_FORM_TYPES)
733
721
  const Types = new Map()
734
722
  const stack = new Brr()
723
+ let scopeIndex = 0
724
+ // TODO also handle casting
725
+ const match = ({ rest, args, i, env, scope, exp }) => {
726
+ const first = exp[0]
727
+ const actual =
728
+ rest[i][0][VALUE] === KEYWORDS.CREATE_ARRAY
729
+ ? initArrayType({ rem: rest[i], env }) ?? env[rest[i][0][VALUE]][STATS]
730
+ : env[rest[i][0][VALUE]][STATS]
731
+ const expected = args[i][STATS]
732
+ retryArgs(args[i][STATS], stack, () =>
733
+ match({ rest, args, i, env, scope, exp })
734
+ )
735
+ if (!isUnknownType(expected) && !isUnknownReturn(actual))
736
+ if (!compareTypeWithReturn(expected, actual))
737
+ throw new TypeError(
738
+ `Incorrect type of argument (${i}) for (${
739
+ first[VALUE]
740
+ }). Expected (${toTypeNames(
741
+ getType(expected)
742
+ )}) but got (${toTypeNames(getReturn(actual))}) (${stringifyArgs(
743
+ exp
744
+ )}) (check #16)`
745
+ )
746
+ else if (notABooleanReturn(expected, actual)) {
747
+ throw new TypeError(
748
+ `Incorrect type of argument (${i}) for (${
749
+ first[VALUE]
750
+ }). Expected (${formatSubType(
751
+ getTypes(expected)
752
+ )}) but got (${formatSubType(getReturns(actual))}) (${stringifyArgs(
753
+ exp
754
+ )}) (check #206)`
755
+ )
756
+ } else {
757
+ switch (getType(expected)) {
758
+ // almost exclusively for anonymous lambdas
759
+ case APPLY:
760
+ {
761
+ const argsN = rest[i].length - 2
762
+ if (
763
+ env[rest[i][0][VALUE]][STATS][SIGNATURE] ===
764
+ KEYWORDS.ANONYMOUS_FUNCTION
765
+ ) {
766
+ if (argsN !== args[i][STATS][ARG_COUNT])
767
+ throw new TypeError(
768
+ `Incorrect number of arguments for (${
769
+ args[i][STATS][SIGNATURE]
770
+ }) the (${KEYWORDS.ANONYMOUS_FUNCTION}) argument of (${
771
+ first[VALUE]
772
+ }) at position (${i}). Expected (= ${
773
+ args[i][STATS][ARG_COUNT]
774
+ }) but got ${argsN} (${stringifyArgs(exp)}) (check #777)`
775
+ )
776
+ else {
777
+ // ANONYMOUS LAMBDAS TYPE CHECKING
778
+ const local = Object.create(env)
779
+ const lambdaName = `${ANONYMOUS_FUNCTION_TYPE_PREFIX}${i}::${++scopeIndex}`
780
+ check(
781
+ [
782
+ [APPLY, KEYWORDS.DEFINE_VARIABLE],
783
+ [WORD, lambdaName],
784
+ rest[i]
785
+ ],
786
+ local,
787
+ scope
788
+ )
789
+ // TODO delete this maybe
790
+ // #C2
791
+ // It will not be possilbe to know return type
792
+ const match1 = () => {
793
+ const actual = local[lambdaName]
794
+ const expected = args[i]
795
+ if (
796
+ !isUnknownReturn(expected[STATS]) &&
797
+ !isUnknownReturn(actual[STATS]) &&
798
+ !compareReturns(expected[STATS], actual[STATS])
799
+ )
800
+ throw new TypeError(
801
+ `Incorrect return type for (${
802
+ expected[STATS][SIGNATURE]
803
+ }) the (${KEYWORDS.ANONYMOUS_FUNCTION}) argument of (${
804
+ first[VALUE]
805
+ }) at position (${i}). Expected (${toTypeNames(
806
+ getReturn(expected[STATS])
807
+ )}) but got (${toTypeNames(
808
+ getReturn(actual[STATS])
809
+ )}) (${stringifyArgs(exp)}) (check #779)`
810
+ )
811
+ else retry(actual[STATS], stack, () => match1())
812
+ }
813
+ match1()
814
+ for (let j = 0; j < args[i][STATS][ARGUMENTS].length; ++j) {
815
+ const match2 = () => {
816
+ const actual = local[lambdaName][STATS][ARGUMENTS][j]
817
+ const expected = args[i][STATS][ARGUMENTS][j]
818
+ if (
819
+ !isUnknownType(actual[STATS]) &&
820
+ !isUnknownType(expected[STATS]) &&
821
+ !compareTypes(actual[STATS], expected[STATS])
822
+ )
823
+ throw new TypeError(
824
+ `Incorrect type for (${
825
+ KEYWORDS.ANONYMOUS_FUNCTION
826
+ }) (${
827
+ args[i][STATS][SIGNATURE]
828
+ }) argument at position (${j}) named as (${
829
+ local[lambdaName][STATS][ARGUMENTS][j][STATS][
830
+ SIGNATURE
831
+ ]
832
+ }). Expected (${toTypeNames(
833
+ getType(expected[STATS])
834
+ )}) but got (${toTypeNames(
835
+ getType(actual[STATS])
836
+ )}) (${stringifyArgs(exp)}) (check #780)`
837
+ )
838
+ else retry(actual[STATS], stack, () => match2())
839
+ }
840
+ match2()
841
+ }
842
+ }
843
+ } else {
844
+ // TODO fix curry: lambdas enter here as undefined
845
+ }
846
+ }
847
+ break
848
+ // case ATOM:
849
+ // case COLLECTION:
850
+ // break
851
+ }
852
+ }
853
+ else if (isUnknownType(expected))
854
+ retry(args[i][STATS], stack, () =>
855
+ match({ rest, args, i, env, scope, exp })
856
+ )
857
+ }
735
858
  const check = (exp, env, scope) => {
736
859
  const [first, ...rest] = isLeaf(exp) ? [exp] : exp
737
860
  if (first === undefined)
@@ -961,7 +1084,7 @@ export const typeCheck = (ast) => {
961
1084
  const ret = isLeaf(rest[0]) ? rest[0] : rest[0][0]
962
1085
  const ref = env[ret[VALUE]]
963
1086
  if (!ref) break
964
- const caster = root[first[VALUE]]
1087
+ const caster = SPECIAL_FORM_TYPES[first[VALUE]]
965
1088
  if (ret[TYPE] === APPLY && isUnknownReturn(ref[STATS]))
966
1089
  castReturn(ref[STATS], caster[STATS])
967
1090
  else if (isUnknownType(ref[STATS]))
@@ -1049,89 +1172,54 @@ export const typeCheck = (ast) => {
1049
1172
  // also type of arg
1050
1173
  const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
1051
1174
  for (let i = 0; i < args.length; ++i) {
1052
- const isResLeaf = isLeaf(rest[i])
1053
1175
  // type check
1054
1176
  // TODO get rof pred type
1055
1177
  // const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
1056
1178
  const MAIN_TYPE = getType(args[i][STATS])
1057
1179
  if (MAIN_TYPE === ANY) continue
1058
1180
  // TODO - try to merge special and non special
1059
- if (first[TYPE] === APPLY && isSpecial) {
1060
- if (!isResLeaf) {
1061
- const name = rest[i][0][VALUE]
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 {
1181
+ // REFACTORING
1182
+ if (first[TYPE] === APPLY) {
1183
+ if (isLeaf(rest[i])) {
1123
1184
  switch (rest[i][TYPE]) {
1124
1185
  case WORD:
1125
1186
  {
1126
1187
  const name = rest[i][VALUE]
1127
1188
  if (!env[name]) continue
1128
- if (
1189
+ const isKnown =
1129
1190
  !isUnknownType(args[i][STATS]) &&
1130
- !isUnknownType(env[name][STATS]) &&
1191
+ !isUnknownType(env[name][STATS])
1192
+ if (
1193
+ isKnown &&
1194
+ env[name][STATS][ARG_COUNT] !== VARIADIC
1195
+ ) {
1196
+ if (
1197
+ env[name][STATS][ARG_COUNT] !==
1198
+ args[i][STATS][ARG_COUNT]
1199
+ ) {
1200
+ // TODO: Investigate why there used to be and error called #111 with this condition if (args[i][STATS][ARG_COUNT] === undefined)
1201
+ if (getType(args[i][STATS]) === APPLY)
1202
+ throw new TypeError(
1203
+ `Incorrect number of arguments for (${
1204
+ args[i][STATS][SIGNATURE]
1205
+ }) the (${
1206
+ KEYWORDS.ANONYMOUS_FUNCTION
1207
+ }) argument of (${
1208
+ first[VALUE]
1209
+ }) at position (${i}). Expected (= ${
1210
+ args[i][STATS][ARG_COUNT]
1211
+ }) but got ${
1212
+ env[name][STATS][ARG_COUNT]
1213
+ } (${stringifyArgs(exp)}) (check #778)`
1214
+ )
1215
+ }
1216
+ }
1217
+ if (
1218
+ isKnown &&
1131
1219
  !compareTypes(args[i][STATS], env[name][STATS])
1132
1220
  )
1133
1221
  throw new TypeError(
1134
- `Incorrect type of argument (${i}) for special form (${
1222
+ `Incorrect type of argument (${i}) for (${
1135
1223
  first[VALUE]
1136
1224
  }). Expected (${toTypeNames(
1137
1225
  getType(args[i][STATS])
@@ -1140,12 +1228,12 @@ export const typeCheck = (ast) => {
1140
1228
  )}) (${stringifyArgs(exp)}) (check #3)`
1141
1229
  )
1142
1230
  else if (
1143
- !isUnknownType(args[i][STATS]) &&
1144
- !isUnknownType(env[name][STATS]) &&
1231
+ isKnown &&
1145
1232
  notABooleanType(args[i][STATS], env[name][STATS])
1233
+ // TODO: Add a check if subtype is a UKNOWN (for uknown array)
1146
1234
  )
1147
1235
  throw new TypeError(
1148
- `Incorrect type of argument (${i}) for special form (${
1236
+ `Incorrect type of argument (${i}) for (${
1149
1237
  first[VALUE]
1150
1238
  }). Expected (${formatSubType(
1151
1239
  getTypes(args[i][STATS])
@@ -1166,7 +1254,8 @@ export const typeCheck = (ast) => {
1166
1254
  // check(exp, env, scope)
1167
1255
  // )
1168
1256
  // } else
1169
- setType(env[name][STATS], args[i][STATS])
1257
+ if (isSpecial)
1258
+ setType(env[name][STATS], args[i][STATS])
1170
1259
  }
1171
1260
  }
1172
1261
  break
@@ -1176,7 +1265,7 @@ export const typeCheck = (ast) => {
1176
1265
  rest[i][TYPE] !== args[i][STATS][TYPE_PROP][0]
1177
1266
  )
1178
1267
  throw new TypeError(
1179
- `Incorrect type of argument (${i}) for special form (${
1268
+ `Incorrect type of argument (${i}) for (${
1180
1269
  first[VALUE]
1181
1270
  }). Expected (${toTypeNames(
1182
1271
  args[i][STATS][TYPE_PROP][0]
@@ -1190,371 +1279,184 @@ export const typeCheck = (ast) => {
1190
1279
  !isAtomABoolean(rest[i][VALUE])
1191
1280
  )
1192
1281
  throw new TypeError(
1193
- `Incorrect type of argument (${i}) for special form (${
1282
+ `Incorrect type of argument (${i}) for (${
1194
1283
  first[VALUE]
1195
1284
  }). Expected (${formatSubType(
1196
1285
  getTypes(args[i][STATS])
1197
- )}) but got (${rest[i][VALUE]}) (${stringifyArgs(
1198
- exp
1199
- )}) (check #203)`
1286
+ )}) but got (${
1287
+ rest[i][TYPE] === ATOM
1288
+ ? toTypeNames(rest[i][TYPE])
1289
+ : formatSubType(
1290
+ getTypes(env[rest[i][VALUE]][STATS])
1291
+ )
1292
+ }) (${stringifyArgs(exp)}) (check #203)`
1200
1293
  )
1201
1294
  break
1202
1295
  }
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]
1296
+ case APPLY: {
1297
+ const name = rest[i][VALUE]
1298
+ if (!env[name]) continue
1309
1299
  if (
1310
- !isUnknownReturn(expected[STATS]) &&
1311
- !isUnknownReturn(actual[STATS]) &&
1312
- !compareReturns(expected[STATS], actual[STATS])
1300
+ !isUnknownType(args[i][STATS]) &&
1301
+ !isUnknownType(env[name][STATS]) &&
1302
+ env[name][STATS][ARG_COUNT] !== VARIADIC
1313
1303
  ) {
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
1304
  if (
1340
- !isUnknownType(actual[STATS]) &&
1341
- !isUnknownType(expected[STATS]) &&
1342
- !compareTypes(actual[STATS], expected[STATS])
1343
- )
1305
+ env[name][STATS][ARG_COUNT] !==
1306
+ args[i][STATS][ARG_COUNT]
1307
+ ) {
1308
+ if (args[i][STATS][ARG_COUNT] === undefined)
1309
+ throw new TypeError(
1310
+ `Incorrect type for argument of (${
1311
+ first[VALUE]
1312
+ }) at position (${i}). Expected (${
1313
+ STATIC_TYPES.ABSTRACTION
1314
+ }) but got (${toTypeNames(
1315
+ getType(args[i][STATS])
1316
+ )}) (${stringifyArgs(exp)}) (check #111)`
1317
+ )
1318
+ else if (getType(args[i][STATS]) === APPLY)
1319
+ throw new TypeError(
1320
+ `Incorrect number of arguments for (${
1321
+ args[i][STATS][SIGNATURE]
1322
+ }) the (${
1323
+ KEYWORDS.ANONYMOUS_FUNCTION
1324
+ }) argument of (${
1325
+ first[VALUE]
1326
+ }) at position (${i}). Expected (= ${
1327
+ args[i][STATS][ARG_COUNT]
1328
+ }) but got ${
1329
+ env[name][STATS][ARG_COUNT]
1330
+ } (${stringifyArgs(exp)}) (check #778)`
1331
+ )
1332
+ }
1333
+ }
1334
+ // DEFINED LAMBDAS TYPE CHECKING
1335
+ // #C1
1336
+ // TODO delete this maybe
1337
+ // It will not be possilbe to know return type
1338
+ const match1 = () => {
1339
+ const actual = env[name]
1340
+ const expected = args[i]
1341
+ if (
1342
+ !isUnknownReturn(expected[STATS]) &&
1343
+ !isUnknownReturn(actual[STATS]) &&
1344
+ !compareReturns(expected[STATS], actual[STATS])
1345
+ ) {
1344
1346
  throw new TypeError(
1345
- `Incorrect type for (${
1347
+ `Incorrect return type for (${
1348
+ expected[STATS][SIGNATURE]
1349
+ }) the (${
1346
1350
  KEYWORDS.ANONYMOUS_FUNCTION
1347
- }) (${
1348
- args[i][STATS][SIGNATURE]
1349
- }) argument at position (${j}) named as (${
1350
- actual[STATS][SIGNATURE]
1351
- }). Expected (${toTypeNames(
1352
- getType(expected[STATS])
1351
+ }) argument of (${
1352
+ first[VALUE]
1353
+ }) at position (${i}). Expected (${toTypeNames(
1354
+ getReturn(expected[STATS])
1353
1355
  )}) but got (${toTypeNames(
1354
- getType(actual[STATS])
1355
- )}) (${stringifyArgs(exp)}) (check #781)`
1356
+ getReturn(actual[STATS])
1357
+ )}) (${stringifyArgs(exp)}) (check #782)`
1356
1358
  )
1357
- else retry(actual[STATS], stack, () => match2())
1359
+ } else retry(actual[STATS], stack, () => match1())
1360
+ }
1361
+ match1()
1362
+ for (
1363
+ let j = 0;
1364
+ j < args[i][STATS][ARGUMENTS].length;
1365
+ ++j
1366
+ ) {
1367
+ const match2 = () => {
1368
+ const actual = env[name][STATS][ARGUMENTS][j]
1369
+ const expected = args[i][STATS][ARGUMENTS][j]
1370
+ if (
1371
+ !isUnknownType(actual[STATS]) &&
1372
+ !isUnknownType(expected[STATS]) &&
1373
+ !compareTypes(actual[STATS], expected[STATS])
1374
+ )
1375
+ throw new TypeError(
1376
+ `Incorrect type for (${
1377
+ KEYWORDS.ANONYMOUS_FUNCTION
1378
+ }) (${
1379
+ args[i][STATS][SIGNATURE]
1380
+ }) argument at position (${j}) named as (${
1381
+ actual[STATS][SIGNATURE]
1382
+ }). Expected (${toTypeNames(
1383
+ getType(expected[STATS])
1384
+ )}) but got (${toTypeNames(
1385
+ getType(actual[STATS])
1386
+ )}) (${stringifyArgs(exp)}) (check #781)`
1387
+ )
1388
+ else retry(actual[STATS], stack, () => match2())
1389
+ }
1390
+ match2()
1358
1391
  }
1359
- match2()
1360
1392
  }
1361
1393
  }
1362
- }
1363
- if (
1364
- T === COLLECTION &&
1365
- env[rest[i][VALUE]] &&
1366
- !isUnknownType(env[rest[i][VALUE]][STATS]) &&
1367
- !isUnknownType(args[i][STATS]) &&
1368
- !compareTypes(env[rest[i][VALUE]][STATS], args[i][STATS])
1369
- ) {
1370
- throw new TypeError(
1371
- `Incorrect type of argument (${i}) for (${
1372
- first[VALUE]
1373
- }). Expected (${toTypeNames(
1374
- getType(args[i][STATS])
1375
- )}) but got (${toTypeNames(T)}) (${stringifyArgs(
1376
- exp
1377
- )}) (check #30)`
1378
- )
1379
- } else if (isUnknownType(args[i][STATS])) {
1380
- retry(args[i][STATS], stack, () => check(exp, env, scope))
1381
- }
1382
- // TOODO maybe we don't need this
1383
- else if (
1384
- env[rest[i][VALUE]] &&
1385
- !isUnknownType(args[i][STATS]) &&
1386
- isUnknownType(env[rest[i][VALUE]][STATS]) &&
1387
- getType(args[i][STATS]) !== APPLY
1388
- ) {
1389
- // REFF ASSIGMENT
1390
- setTypeRef(env[rest[i][VALUE]][STATS], args[i][STATS])
1391
- } else if (
1392
- env[rest[i][VALUE]] &&
1393
- !isUnknownType(args[i][STATS]) &&
1394
- isUnknownType(env[rest[i][VALUE]][STATS])
1395
- ) {
1396
- setStatsRef(env[rest[i][VALUE]], args[i])
1397
- }
1398
- } else if (env[rest[i][0][VALUE]]) {
1399
- const match = () => {
1400
- const actual =
1401
- rest[i][0][VALUE] === KEYWORDS.CREATE_ARRAY
1402
- ? initArrayType({ rem: rest[i], env }) ??
1403
- env[rest[i][0][VALUE]][STATS]
1404
- : env[rest[i][0][VALUE]][STATS]
1405
- const expected = args[i][STATS]
1406
- retryArgs(args[i][STATS], stack, () => match())
1407
- if (!isUnknownType(expected) && !isUnknownReturn(actual))
1408
- if (!compareTypeWithReturn(expected, actual))
1409
- throw new TypeError(
1410
- `Incorrect type of argument (${i}) for (${
1411
- first[VALUE]
1412
- }). Expected (${toTypeNames(
1413
- getType(expected)
1414
- )}) but got (${toTypeNames(
1415
- getReturn(actual)
1416
- )}) (${stringifyArgs(exp)}) (check #16)`
1417
- )
1418
- else if (notABooleanReturn(expected, actual)) {
1419
- throw new TypeError(
1420
- `Incorrect type of argument (${i}) for (${
1421
- first[VALUE]
1422
- }). Expected (${formatSubType(
1423
- getTypes(expected)
1424
- )}) but got (${formatSubType(
1425
- getReturns(actual)
1426
- )}) (${stringifyArgs(exp)}) (check #206)`
1394
+ if (!isSpecial) {
1395
+ const name = rest[i][VALUE]
1396
+ if (isUnknownType(args[i][STATS])) {
1397
+ retry(args[i][STATS], stack, () =>
1398
+ check(exp, env, scope)
1427
1399
  )
1428
- } else {
1429
- switch (getType(expected)) {
1430
- // almost exclusively for anonymous lambdas
1431
- case APPLY:
1432
- {
1433
- const argsN = rest[i].length - 2
1434
- if (
1435
- env[rest[i][0][VALUE]][STATS][SIGNATURE] ===
1436
- KEYWORDS.ANONYMOUS_FUNCTION
1437
- ) {
1438
- if (argsN !== args[i][STATS][ARG_COUNT])
1439
- throw new TypeError(
1440
- `Incorrect number of arguments for (${
1441
- args[i][STATS][SIGNATURE]
1442
- }) the (${
1443
- KEYWORDS.ANONYMOUS_FUNCTION
1444
- }) argument of (${
1445
- first[VALUE]
1446
- }) at position (${i}). Expected (= ${
1447
- args[i][STATS][ARG_COUNT]
1448
- }) but got ${argsN} (${stringifyArgs(
1449
- exp
1450
- )}) (check #777)`
1451
- )
1452
- else {
1453
- // ANONYMOUS LAMBDAS TYPE CHECKING
1454
- const local = Object.create(env)
1455
- const lambdaName = `${ANONYMOUS_FUNCTION_TYPE_PREFIX}${i}::${++scopeIndex}`
1456
- check(
1457
- [
1458
- [APPLY, KEYWORDS.DEFINE_VARIABLE],
1459
- [WORD, lambdaName],
1460
- rest[i]
1461
- ],
1462
- local,
1463
- scope
1464
- )
1465
- // TODO delete this maybe
1466
- // #C2
1467
- // It will not be possilbe to know return type
1468
- const match1 = () => {
1469
- const actual = local[lambdaName]
1470
- const expected = args[i]
1471
- if (
1472
- !isUnknownReturn(expected[STATS]) &&
1473
- !isUnknownReturn(actual[STATS]) &&
1474
- !compareReturns(
1475
- expected[STATS],
1476
- actual[STATS]
1477
- )
1478
- )
1479
- throw new TypeError(
1480
- `Incorrect return type for (${
1481
- expected[STATS][SIGNATURE]
1482
- }) the (${
1483
- KEYWORDS.ANONYMOUS_FUNCTION
1484
- }) argument of (${
1485
- first[VALUE]
1486
- }) at position (${i}). Expected (${toTypeNames(
1487
- getReturn(expected[STATS])
1488
- )}) but got (${toTypeNames(
1489
- getReturn(actual[STATS])
1490
- )}) (${stringifyArgs(
1491
- exp
1492
- )}) (check #779)`
1493
- )
1494
- else
1495
- retry(actual[STATS], stack, () =>
1496
- match1()
1497
- )
1498
- }
1499
- match1()
1500
- for (
1501
- let j = 0;
1502
- j < args[i][STATS][ARGUMENTS].length;
1503
- ++j
1504
- ) {
1505
- const match2 = () => {
1506
- const actual =
1507
- local[lambdaName][STATS][ARGUMENTS][j]
1508
- const expected =
1509
- args[i][STATS][ARGUMENTS][j]
1510
- if (
1511
- !isUnknownType(actual[STATS]) &&
1512
- !isUnknownType(expected[STATS]) &&
1513
- !compareTypes(
1514
- actual[STATS],
1515
- expected[STATS]
1516
- )
1517
- )
1518
- throw new TypeError(
1519
- `Incorrect type for (${
1520
- KEYWORDS.ANONYMOUS_FUNCTION
1521
- }) (${
1522
- args[i][STATS][SIGNATURE]
1523
- }) argument at position (${j}) named as (${
1524
- local[lambdaName][STATS][
1525
- ARGUMENTS
1526
- ][j][STATS][SIGNATURE]
1527
- }). Expected (${toTypeNames(
1528
- getType(expected[STATS])
1529
- )}) but got (${toTypeNames(
1530
- getType(actual[STATS])
1531
- )}) (${stringifyArgs(
1532
- exp
1533
- )}) (check #780)`
1534
- )
1535
- else
1536
- retry(actual[STATS], stack, () =>
1537
- match2()
1538
- )
1539
- }
1540
- match2()
1541
- }
1542
- }
1543
- } else {
1544
- // TODO fix curry: lambdas enter here as undefined
1545
- }
1546
- }
1547
- break
1548
- // case ATOM:
1549
- // case COLLECTION:
1550
- // break
1551
- }
1552
1400
  }
1553
- else if (isUnknownType(expected))
1554
- retry(args[i][STATS], stack, () => match())
1401
+ // TOODO maybe we don't need this
1402
+ else if (
1403
+ env[name] &&
1404
+ !isUnknownType(args[i][STATS]) &&
1405
+ isUnknownType(env[name][STATS]) &&
1406
+ getType(args[i][STATS]) !== APPLY
1407
+ ) {
1408
+ // REFF ASSIGMENT
1409
+ setTypeRef(env[name][STATS], args[i][STATS])
1410
+ } else if (
1411
+ env[name] &&
1412
+ !isUnknownType(args[i][STATS]) &&
1413
+ isUnknownType(env[name][STATS])
1414
+ ) {
1415
+ setStatsRef(env[rest[i][VALUE]], args[i])
1416
+ }
1417
+ }
1418
+ } else {
1419
+ const name = rest[i][0][VALUE]
1420
+ if (!env[name]) continue
1421
+ if (
1422
+ isUnknownReturn(env[name][STATS]) &&
1423
+ !env[name][STATS][IS_ARGUMENT]
1424
+ )
1425
+ return retry(env[name][STATS], stack, () =>
1426
+ check(exp, env, scope)
1427
+ )
1428
+
1429
+ if (isSpecial && name === KEYWORDS.IF) {
1430
+ const concequent = [...rest]
1431
+ const alternative = [...rest]
1432
+ concequent[i] = rest[i][1]
1433
+ alternative[i] = rest[i][2]
1434
+ check([first, ...concequent], env, scope)
1435
+ check([first, ...alternative], env, scope)
1436
+ }
1437
+
1438
+ if (
1439
+ env[name] &&
1440
+ getType(env[name][STATS]) === APPLY &&
1441
+ !SPECIAL_FORMS_SET.has(name)
1442
+ )
1443
+ switch (first[VALUE]) {
1444
+ case KEYWORDS.IF:
1445
+ break
1446
+ default:
1447
+ // TODO fix this assigment
1448
+ // It turns out it's not possible to determine return type of function here
1449
+ // what if it's a global function used elsewhere where the return type mwould be different
1450
+ // THIS willgive lambda return types but refactor is needed still
1451
+ // if (!SPECIAL_FORMS_SET.has(name))
1452
+ setReturnRef(env[name][STATS], args[i][STATS])
1453
+ break
1454
+ }
1455
+
1456
+ match({ rest, args, i, env, scope, exp })
1555
1457
  }
1556
- match()
1557
1458
  }
1459
+ // REFACTORING
1558
1460
  }
1559
1461
  }
1560
1462
  })
@@ -1577,7 +1479,7 @@ export const typeCheck = (ast) => {
1577
1479
  }
1578
1480
  }
1579
1481
  const copy = JSON.parse(JSON.stringify(ast))
1580
- check(copy, root, copy)
1482
+ check(copy, SPECIAL_FORM_TYPES, copy)
1581
1483
  while (stack.length) stack.cut()()
1582
1484
  return [ast, Types]
1583
1485
  }