fez-lisp 1.5.130 → 1.5.132

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 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.130",
5
+ "version": "1.5.132",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -116,13 +116,13 @@ export const isUnknownNotAnyReturn = (stats) =>
116
116
  export const castType = (stats, type) => {
117
117
  return (
118
118
  (stats[TYPE_PROP][0] = type[RETURNS][0]),
119
- (stats[TYPE_PROP][1] = type[RETURNS][1])
119
+ type[RETURNS][1] && (stats[TYPE_PROP][1] = type[RETURNS][1])
120
120
  )
121
121
  }
122
122
  export const castReturn = (stats, type) => {
123
123
  return (
124
124
  (stats[RETURNS][0] = type[RETURNS][0]),
125
- (stats[RETURNS][1] = type[RETURNS][1])
125
+ stats[RETURNS][1] && (stats[RETURNS][1] = type[RETURNS][1])
126
126
  )
127
127
  }
128
128
  export const isTypeAbstraction = (stats) => stats[TYPE_PROP] === APPLY
@@ -285,7 +285,7 @@ export const isAtomType = (stats) =>
285
285
  isAnyType(stats) || stats[TYPE_PROP][0] === ATOM
286
286
  export const isAtomReturn = (stats) =>
287
287
  isAnyType(stats) || stats[RETURNS][0] === ATOM
288
- export const compareTypes = (a, b) => {
288
+ export const equalsTypes = (a, b) => {
289
289
  const isAnyAny = isAnyType(a) || isAnyType(b)
290
290
  if (isAnyAny) return true
291
291
  const isSameType = a[TYPE_PROP][0] === b[TYPE_PROP][0]
@@ -293,9 +293,9 @@ export const compareTypes = (a, b) => {
293
293
  return true
294
294
  }
295
295
 
296
- export const compareReturns = (a, b) =>
296
+ export const equalsReturns = (a, b) =>
297
297
  isAnyReturn(a) || isAnyReturn(b) || a[RETURNS][0] === b[RETURNS][0]
298
- export const compareTypeWithReturn = (a, b) =>
298
+ export const equalsTypeWithReturn = (a, b) =>
299
299
  isAnyType(a) || isAnyReturn(b) || a[TYPE_PROP][0] === b[RETURNS][0]
300
300
  const IsPredicate = (leaf) =>
301
301
  (leaf[TYPE] === ATOM && (leaf[VALUE] === TRUE || leaf[VALUE] === FALSE)) ||
@@ -319,7 +319,7 @@ const notABooleanType = (a, b) => {
319
319
  (hasSubType(b) && getSubType(a).difference(getSubType(b)).size !== 0))
320
320
  )
321
321
  }
322
- const notABooleanReturn = (a, b) => {
322
+ const notABooleanTypeWithReturn = (a, b) => {
323
323
  return (
324
324
  hasSubType(a) &&
325
325
  getSubType(a).has(PREDICATE) &&
@@ -328,6 +328,15 @@ const notABooleanReturn = (a, b) => {
328
328
  (!hasSubReturn(b) || getSubType(a).difference(getSubReturn(b)).size !== 0)
329
329
  )
330
330
  }
331
+ const notABooleanReturn = (a, b) => {
332
+ return (
333
+ hasSubReturn(a) &&
334
+ getSubReturn(a).has(PREDICATE) &&
335
+ !isUnknownReturn(b) &&
336
+ !isAnyReturn(b) &&
337
+ (!hasSubReturn(b) || getSubReturn(a).difference(getSubReturn(b)).size !== 0)
338
+ )
339
+ }
331
340
  const isAtomABoolean = (atom) => atom === TRUE || atom === FALSE
332
341
  const checkPredicateName = (exp, rest) => {
333
342
  if (getSuffix(rest[0][VALUE]) === PREDICATE_SUFFIX) {
@@ -406,19 +415,20 @@ const withScope = (name, scope) => {
406
415
  const chain = getScopeNames(scope)
407
416
  return `${chain.length === 1 ? '; ' : ''}${chain.join(' ')} ${name}`
408
417
  }
409
- const retry = (stats, stack, cb) => {
418
+ const retry = (stats, ctx, stack, cb) => {
410
419
  if (
411
420
  (isUnknownNotAnyType(stats) || isUnknownNotAnyReturn(stats)) &&
412
421
  stats.retried < MAX_RETRY_DEFINITION
413
422
  ) {
414
423
  stats.retried += 1
415
- stack.prepend(() => cb())
424
+ stagger(stack, 'prepend', ctx, cb)
416
425
  }
417
426
  }
418
- const retryArgs = (stats, stack, cb) => {
427
+
428
+ const retryArgs = (stats, ctx, stack, cb) => {
419
429
  if (stats.counter < MAX_ARGUMENT_RETRY) {
420
430
  stats.counter++
421
- stack.prepend(cb)
431
+ stagger(stack, 'prepend', ctx, cb)
422
432
  }
423
433
  }
424
434
  const IfApplyBranch = ({ leaf, branch, re, prop, ref, env }) => {
@@ -521,7 +531,7 @@ const resolveCondition = ({ rem, name, env, exp, prop }) => {
521
531
  default:
522
532
  if (env[ret[VALUE]]) setPropRef(ref[STATS], prop, env[ret[VALUE]][STATS])
523
533
  else
524
- stack.append(() => {
534
+ stagger(stack, 'append', exp, () => {
525
535
  if (env[ret[VALUE]])
526
536
  setPropRef(ref[STATS], prop, env[ret[VALUE]][STATS])
527
537
  })
@@ -665,7 +675,7 @@ const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
665
675
  GETTERS_SET.has(returns[VALUE]) &&
666
676
  !resolveGetter({ rem, prop, name, env })
667
677
  )
668
- return retry(env[name][STATS], stack, () => {
678
+ return retry(env[name][STATS], [returns, env], stack, () => {
669
679
  resolveRetunType({
670
680
  returns,
671
681
  rem,
@@ -686,7 +696,7 @@ const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
686
696
  // rest.at(-1)[0][TYPE] === APPLY
687
697
  // Here is upon application to store the result in the variable
688
698
  if (isUnknownType(env[name][STATS]))
689
- stack.prepend(() => {
699
+ stagger(stack, 'prepend', exp, () => {
690
700
  setTypeToReturnRef(
691
701
  env[name][STATS],
692
702
  env[returns[VALUE]][STATS]
@@ -716,11 +726,188 @@ const checkReturnType = ({ exp, stack, name, env }) => {
716
726
  stack
717
727
  })
718
728
  }
729
+ const stagger = (stack, method, data, fn) => {
730
+ // console.log(data[0], data[1])
731
+ stack[method]({ data, fn })
732
+ }
719
733
  export const typeCheck = (ast) => {
720
- let scopeIndex = 0
721
- const root = structuredClone(SPECIAL_FORM_TYPES)
722
734
  const Types = new Map()
723
735
  const stack = new Brr()
736
+ let scopeIndex = 0
737
+ // TODO also handle casting
738
+ const match = ({ rest, args, i, env, scope, exp }) => {
739
+ const first = exp[0]
740
+ const actual =
741
+ rest[i][0][VALUE] === KEYWORDS.CREATE_ARRAY
742
+ ? initArrayType({ rem: rest[i], env }) ?? env[rest[i][0][VALUE]][STATS]
743
+ : env[rest[i][0][VALUE]][STATS]
744
+ const expected = args[i][STATS]
745
+ retryArgs(args[i][STATS], exp, stack, () =>
746
+ match({ rest, args, i, env, scope, exp })
747
+ )
748
+ if (!isUnknownType(expected) && !isUnknownReturn(actual))
749
+ if (!equalsTypeWithReturn(expected, actual))
750
+ throw new TypeError(
751
+ `Incorrect type of argument (${i}) for (${
752
+ first[VALUE]
753
+ }). Expected (${toTypeNames(
754
+ getType(expected)
755
+ )}) but got (${toTypeNames(getReturn(actual))}) (${stringifyArgs(
756
+ exp
757
+ )}) (check #16)`
758
+ )
759
+ else if (notABooleanTypeWithReturn(expected, actual)) {
760
+ throw new TypeError(
761
+ `Incorrect type of argument (${i}) for (${
762
+ first[VALUE]
763
+ }). Expected (${formatSubType(
764
+ getTypes(expected)
765
+ )}) but got (${formatSubType(getReturns(actual))}) (${stringifyArgs(
766
+ exp
767
+ )}) (check #206)`
768
+ )
769
+ } else {
770
+ switch (getType(expected)) {
771
+ // almost exclusively for anonymous lambdas
772
+ case APPLY:
773
+ {
774
+ const argsN = rest[i].length - 2
775
+ if (
776
+ env[rest[i][0][VALUE]][STATS][SIGNATURE] ===
777
+ KEYWORDS.ANONYMOUS_FUNCTION
778
+ ) {
779
+ if (argsN !== args[i][STATS][ARG_COUNT])
780
+ throw new TypeError(
781
+ `Incorrect number of arguments for (${
782
+ args[i][STATS][SIGNATURE]
783
+ }) the (${KEYWORDS.ANONYMOUS_FUNCTION}) argument of (${
784
+ first[VALUE]
785
+ }) at position (${i}). Expected (= ${
786
+ args[i][STATS][ARG_COUNT]
787
+ }) but got ${argsN} (${stringifyArgs(exp)}) (check #777)`
788
+ )
789
+ else {
790
+ // ANONYMOUS LAMBDAS TYPE CHECKING
791
+ const local = Object.create(env)
792
+ const lambdaName = `${ANONYMOUS_FUNCTION_TYPE_PREFIX}${i}::${++scopeIndex}`
793
+ check(
794
+ [
795
+ [APPLY, KEYWORDS.DEFINE_VARIABLE],
796
+ [WORD, lambdaName],
797
+ rest[i]
798
+ ],
799
+ local,
800
+ scope
801
+ )
802
+ // TODO delete this maybe
803
+ // #C2
804
+ // It will not be possilbe to know return type
805
+ const match1 = () => {
806
+ const actual = local[lambdaName]
807
+ const expected = args[i]
808
+ if (
809
+ !isUnknownReturn(expected[STATS]) &&
810
+ !isUnknownReturn(actual[STATS]) &&
811
+ !equalsReturns(expected[STATS], actual[STATS])
812
+ )
813
+ throw new TypeError(
814
+ `Incorrect return type for (${
815
+ expected[STATS][SIGNATURE]
816
+ }) the (${KEYWORDS.ANONYMOUS_FUNCTION}) argument of (${
817
+ first[VALUE]
818
+ }) at position (${i}). Expected (${toTypeNames(
819
+ getReturn(expected[STATS])
820
+ )}) but got (${toTypeNames(
821
+ getReturn(actual[STATS])
822
+ )}) (${stringifyArgs(exp)}) (check #779)`
823
+ )
824
+ else if (notABooleanReturn(expected[STATS], actual[STATS]))
825
+ throw new TypeError(
826
+ `Incorrect return type for (${
827
+ expected[STATS][SIGNATURE]
828
+ }) the (${KEYWORDS.ANONYMOUS_FUNCTION}) argument of (${
829
+ first[VALUE]
830
+ }) at position (${i}). Expected (${toTypeNames(
831
+ getReturn(expected[STATS])
832
+ )}) but got (${toTypeNames(
833
+ getReturn(actual[STATS])
834
+ )}) (${stringifyArgs(exp)}) (check #783)`
835
+ )
836
+ else
837
+ retry(
838
+ actual[STATS],
839
+ [[WORD, lambdaName], local],
840
+ stack,
841
+ match1
842
+ )
843
+ }
844
+ match1()
845
+ for (let j = 0; j < args[i][STATS][ARGUMENTS].length; ++j) {
846
+ const match2 = () => {
847
+ const actual = local[lambdaName][STATS][ARGUMENTS][j]
848
+ const expected = args[i][STATS][ARGUMENTS][j]
849
+ if (
850
+ !isUnknownType(actual[STATS]) &&
851
+ !isUnknownType(expected[STATS]) &&
852
+ !equalsTypes(actual[STATS], expected[STATS])
853
+ )
854
+ throw new TypeError(
855
+ `Incorrect type for (${
856
+ KEYWORDS.ANONYMOUS_FUNCTION
857
+ }) (${
858
+ args[i][STATS][SIGNATURE]
859
+ }) argument at position (${j}) named as (${
860
+ local[lambdaName][STATS][ARGUMENTS][j][STATS][
861
+ SIGNATURE
862
+ ]
863
+ }). Expected (${toTypeNames(
864
+ getType(expected[STATS])
865
+ )}) but got (${toTypeNames(
866
+ getType(actual[STATS])
867
+ )}) (${stringifyArgs(exp)}) (check #780)`
868
+ )
869
+ else if (
870
+ notABooleanReturn(expected[STATS], actual[STATS])
871
+ )
872
+ throw new TypeError(
873
+ `Incorrect return type for (${
874
+ expected[STATS][SIGNATURE]
875
+ }) the (${
876
+ KEYWORDS.ANONYMOUS_FUNCTION
877
+ }) argument of (${
878
+ first[VALUE]
879
+ }) at position (${i}). Expected (${toTypeNames(
880
+ getReturn(expected[STATS])
881
+ )}) but got (${toTypeNames(
882
+ getReturn(actual[STATS])
883
+ )}) (${stringifyArgs(exp)}) (check #784)`
884
+ )
885
+ else
886
+ retry(
887
+ actual[STATS],
888
+ [[WORD, lambdaName], local],
889
+ stack,
890
+ match2
891
+ )
892
+ }
893
+ match2()
894
+ }
895
+ }
896
+ } else {
897
+ // TODO fix curry: lambdas enter here as undefined
898
+ }
899
+ }
900
+ break
901
+ // case ATOM:
902
+ // case COLLECTION:
903
+ // break
904
+ }
905
+ }
906
+ else if (isUnknownType(expected))
907
+ retry(args[i][STATS], [first, env], stack, () =>
908
+ match({ rest, args, i, env, scope, exp })
909
+ )
910
+ }
724
911
  const check = (exp, env, scope) => {
725
912
  const [first, ...rest] = isLeaf(exp) ? [exp] : exp
726
913
  if (first === undefined)
@@ -732,7 +919,7 @@ export const typeCheck = (ast) => {
732
919
  switch (first[TYPE]) {
733
920
  case WORD:
734
921
  if (!isSpecial)
735
- stack.append(() => {
922
+ stagger(stack, 'append', [first, env], () => {
736
923
  // Figure out how to determine if varible is define after it's used
737
924
  if (env[first[VALUE]] === undefined) {
738
925
  throw new TypeError(
@@ -787,7 +974,7 @@ export const typeCheck = (ast) => {
787
974
  }) ||
788
975
  isUnknownReturn(env[name][STATS])
789
976
  ) {
790
- retry(env[name][STATS], stack, () => {
977
+ retry(env[name][STATS], [first, env], stack, () => {
791
978
  checkReturnType({
792
979
  stack,
793
980
  exp,
@@ -906,13 +1093,16 @@ export const typeCheck = (ast) => {
906
1093
  // TODO figure out what we do here
907
1094
  // this here is a variable WORD
908
1095
  // so return type of that function is that varible type
909
- stack.append(
1096
+ stagger(
1097
+ stack,
1098
+ 'append',
1099
+ [returns, copy],
910
1100
  () =>
911
1101
  copy[returns[VALUE]] &&
912
1102
  setReturnToType(ref[STATS], copy[returns[VALUE]][STATS])
913
1103
  )
914
1104
  else {
915
- stack.append(() => {
1105
+ stagger(stack, 'append', [returns, copy], () => {
916
1106
  const ret = returns[0]
917
1107
  switch (ret[VALUE]) {
918
1108
  case KEYWORDS.IF:
@@ -929,7 +1119,7 @@ export const typeCheck = (ast) => {
929
1119
  if (copy[ret[VALUE]])
930
1120
  setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
931
1121
  else
932
- stack.append(() => {
1122
+ stagger(stack, 'append', [ret, copy], () => {
933
1123
  if (copy[ret[VALUE]])
934
1124
  setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
935
1125
  })
@@ -950,7 +1140,7 @@ export const typeCheck = (ast) => {
950
1140
  const ret = isLeaf(rest[0]) ? rest[0] : rest[0][0]
951
1141
  const ref = env[ret[VALUE]]
952
1142
  if (!ref) break
953
- const caster = root[first[VALUE]]
1143
+ const caster = SPECIAL_FORM_TYPES[first[VALUE]]
954
1144
  if (ret[TYPE] === APPLY && isUnknownReturn(ref[STATS]))
955
1145
  castReturn(ref[STATS], caster[STATS])
956
1146
  else if (isUnknownType(ref[STATS]))
@@ -963,9 +1153,8 @@ export const typeCheck = (ast) => {
963
1153
  // So they MUST happen before Judgement
964
1154
  resolveSetter(first, rest, env)
965
1155
  // end of Var ---------------
966
-
967
1156
  // Judgement
968
- stack.append(() => {
1157
+ stagger(stack, 'append', [first, env], () => {
969
1158
  if (!isSpecial && env[first[VALUE]] === undefined)
970
1159
  throw new TypeError(
971
1160
  `Trying to call undefined (${KEYWORDS.ANONYMOUS_FUNCTION}) ${first[VALUE]} (check #9)`
@@ -1082,7 +1271,7 @@ export const typeCheck = (ast) => {
1082
1271
  }
1083
1272
  if (
1084
1273
  isKnown &&
1085
- !compareTypes(args[i][STATS], env[name][STATS])
1274
+ !equalsTypes(args[i][STATS], env[name][STATS])
1086
1275
  )
1087
1276
  throw new TypeError(
1088
1277
  `Incorrect type of argument (${i}) for (${
@@ -1114,12 +1303,16 @@ export const typeCheck = (ast) => {
1114
1303
  // (let xs [])
1115
1304
  // (let x (array:set-and-get! xs 0 100))
1116
1305
  // (length x)
1117
- //
1118
- // if (isUnknownType(env[name][STATS])) {
1119
- // retry(env[name][STATS], stack, () =>
1306
+
1307
+ // if (
1308
+ // isUnknownType(env[name][STATS]) &&
1309
+ // !env[name][STATS].tried
1310
+ // ) {
1311
+ // once(env[name][STATS], stack, () =>
1120
1312
  // check(exp, env, scope)
1121
1313
  // )
1122
- // } else
1314
+ // }
1315
+
1123
1316
  if (isSpecial)
1124
1317
  setType(env[name][STATS], args[i][STATS])
1125
1318
  }
@@ -1207,7 +1400,7 @@ export const typeCheck = (ast) => {
1207
1400
  if (
1208
1401
  !isUnknownReturn(expected[STATS]) &&
1209
1402
  !isUnknownReturn(actual[STATS]) &&
1210
- !compareReturns(expected[STATS], actual[STATS])
1403
+ !equalsReturns(expected[STATS], actual[STATS])
1211
1404
  ) {
1212
1405
  throw new TypeError(
1213
1406
  `Incorrect return type for (${
@@ -1222,7 +1415,8 @@ export const typeCheck = (ast) => {
1222
1415
  getReturn(actual[STATS])
1223
1416
  )}) (${stringifyArgs(exp)}) (check #782)`
1224
1417
  )
1225
- } else retry(actual[STATS], stack, () => match1())
1418
+ } else
1419
+ retry(actual[STATS], [first, env], stack, match1)
1226
1420
  }
1227
1421
  match1()
1228
1422
  for (
@@ -1236,7 +1430,7 @@ export const typeCheck = (ast) => {
1236
1430
  if (
1237
1431
  !isUnknownType(actual[STATS]) &&
1238
1432
  !isUnknownType(expected[STATS]) &&
1239
- !compareTypes(actual[STATS], expected[STATS])
1433
+ !equalsTypes(actual[STATS], expected[STATS])
1240
1434
  )
1241
1435
  throw new TypeError(
1242
1436
  `Incorrect type for (${
@@ -1251,7 +1445,13 @@ export const typeCheck = (ast) => {
1251
1445
  getType(actual[STATS])
1252
1446
  )}) (${stringifyArgs(exp)}) (check #781)`
1253
1447
  )
1254
- else retry(actual[STATS], stack, () => match2())
1448
+ else
1449
+ retry(
1450
+ actual[STATS],
1451
+ [first, env],
1452
+ stack,
1453
+ match2
1454
+ )
1255
1455
  }
1256
1456
  match2()
1257
1457
  }
@@ -1260,7 +1460,7 @@ export const typeCheck = (ast) => {
1260
1460
  if (!isSpecial) {
1261
1461
  const name = rest[i][VALUE]
1262
1462
  if (isUnknownType(args[i][STATS])) {
1263
- retry(args[i][STATS], stack, () =>
1463
+ retry(args[i][STATS], [first, env], stack, () =>
1264
1464
  check(exp, env, scope)
1265
1465
  )
1266
1466
  }
@@ -1284,235 +1484,45 @@ export const typeCheck = (ast) => {
1284
1484
  } else {
1285
1485
  const name = rest[i][0][VALUE]
1286
1486
  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
- )
1311
- throw new TypeError(
1312
- `Incorrect type of argument (${i}) for (${
1313
- first[VALUE]
1314
- }). Expected (${toTypeNames(
1315
- getType(args[i][STATS])
1316
- )}) but got (${toTypeNames(
1317
- getReturn(env[name][STATS])
1318
- )}) (${stringifyArgs(exp)}) (check #1)`
1319
- )
1320
- else if (
1321
- !isUnknownReturn(args[i][STATS]) &&
1322
- !isUnknownReturn(env[name][STATS]) &&
1323
- notABooleanReturn(args[i][STATS], env[name][STATS])
1487
+ if (
1488
+ isUnknownReturn(env[name][STATS]) &&
1489
+ !env[name][STATS][IS_ARGUMENT]
1490
+ )
1491
+ return retry(
1492
+ env[name][STATS],
1493
+ [first, env],
1494
+ stack,
1495
+ () => check(exp, env, scope)
1324
1496
  )
1325
- throw new TypeError(
1326
- `Incorrect type of argument (${i}) for (${
1327
- first[VALUE]
1328
- }). Expected (${formatSubType(
1329
- getTypes(args[i][STATS])
1330
- )}) but got (${formatSubType(
1331
- getReturns(env[name][STATS])
1332
- )}) (${stringifyArgs(exp)}) (check #201)`
1333
- )
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])
1395
- throw new TypeError(
1396
- `Incorrect number of arguments for (${
1397
- args[i][STATS][SIGNATURE]
1398
- }) the (${
1399
- KEYWORDS.ANONYMOUS_FUNCTION
1400
- }) argument of (${
1401
- first[VALUE]
1402
- }) at position (${i}). Expected (= ${
1403
- args[i][STATS][ARG_COUNT]
1404
- }) but got ${argsN} (${stringifyArgs(
1405
- exp
1406
- )}) (check #777)`
1407
- )
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
1420
- )
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
- )
1434
- )
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 =
1463
- local[lambdaName][STATS][
1464
- ARGUMENTS
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
- }
1500
- }
1501
- } else {
1502
- // TODO fix curry: lambdas enter here as undefined
1503
- }
1504
- }
1505
- break
1506
- // case ATOM:
1507
- // case COLLECTION:
1508
- // break
1509
- }
1510
- }
1511
- else if (isUnknownType(expected))
1512
- retry(args[i][STATS], stack, () => match())
1513
- }
1514
- match()
1497
+
1498
+ if (isSpecial && name === KEYWORDS.IF) {
1499
+ const concequent = [...rest]
1500
+ const alternative = [...rest]
1501
+ concequent[i] = rest[i][1]
1502
+ alternative[i] = rest[i][2]
1503
+ check([first, ...concequent], env, scope)
1504
+ check([first, ...alternative], env, scope)
1515
1505
  }
1506
+
1507
+ if (
1508
+ env[name] &&
1509
+ getType(env[name][STATS]) === APPLY &&
1510
+ !SPECIAL_FORMS_SET.has(name)
1511
+ )
1512
+ switch (first[VALUE]) {
1513
+ case KEYWORDS.IF:
1514
+ break
1515
+ default:
1516
+ // TODO fix this assigment
1517
+ // It turns out it's not possible to determine return type of function here
1518
+ // what if it's a global function used elsewhere where the return type mwould be different
1519
+ // THIS willgive lambda return types but refactor is needed still
1520
+ // if (!SPECIAL_FORMS_SET.has(name))
1521
+ setReturnRef(env[name][STATS], args[i][STATS])
1522
+ break
1523
+ }
1524
+
1525
+ match({ rest, args, i, env, scope, exp })
1516
1526
  }
1517
1527
  }
1518
1528
  // REFACTORING
@@ -1538,8 +1548,8 @@ export const typeCheck = (ast) => {
1538
1548
  }
1539
1549
  }
1540
1550
  const copy = JSON.parse(JSON.stringify(ast))
1541
- check(copy, root, copy)
1542
- while (stack.length) stack.cut()()
1551
+ check(copy, SPECIAL_FORM_TYPES, copy)
1552
+ while (stack.length) stack.cut().fn()
1543
1553
  return [ast, Types]
1544
1554
  }
1545
1555
  export const type = (ast) => typeCheck(ast)[0]
package/src/types.js CHANGED
@@ -419,7 +419,7 @@ export const SPECIAL_FORM_TYPES = {
419
419
  }
420
420
  }
421
421
  ],
422
- [RETURNS]: [ATOM]
422
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
423
423
  }
424
424
  },
425
425
  [KEYWORDS.MULTIPLICATION]: {
@@ -452,7 +452,7 @@ export const SPECIAL_FORM_TYPES = {
452
452
  }
453
453
  }
454
454
  ],
455
- [RETURNS]: [ATOM]
455
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
456
456
  }
457
457
  },
458
458
  [KEYWORDS.SUBTRACTION]: {
@@ -485,7 +485,7 @@ export const SPECIAL_FORM_TYPES = {
485
485
  }
486
486
  }
487
487
  ],
488
- [RETURNS]: [ATOM]
488
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
489
489
  }
490
490
  },
491
491
  [KEYWORDS.DIVISION]: {
@@ -518,7 +518,7 @@ export const SPECIAL_FORM_TYPES = {
518
518
  }
519
519
  }
520
520
  ],
521
- [RETURNS]: [ATOM]
521
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
522
522
  }
523
523
  },
524
524
  [KEYWORDS.REMAINDER_OF_DIVISION]: {
@@ -550,7 +550,7 @@ export const SPECIAL_FORM_TYPES = {
550
550
  }
551
551
  }
552
552
  ],
553
- [RETURNS]: [ATOM]
553
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
554
554
  }
555
555
  },
556
556
  [KEYWORDS.BITWISE_AND]: {
@@ -583,7 +583,7 @@ export const SPECIAL_FORM_TYPES = {
583
583
  }
584
584
  }
585
585
  ],
586
- [RETURNS]: [ATOM]
586
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
587
587
  }
588
588
  },
589
589
  [KEYWORDS.BITWISE_NOT]: {
@@ -605,7 +605,7 @@ export const SPECIAL_FORM_TYPES = {
605
605
  }
606
606
  }
607
607
  ],
608
- [RETURNS]: [ATOM]
608
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
609
609
  }
610
610
  },
611
611
  [KEYWORDS.BITWISE_OR]: {
@@ -638,7 +638,7 @@ export const SPECIAL_FORM_TYPES = {
638
638
  }
639
639
  }
640
640
  ],
641
- [RETURNS]: [ATOM]
641
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
642
642
  }
643
643
  },
644
644
  [KEYWORDS.BITWISE_XOR]: {
@@ -671,7 +671,7 @@ export const SPECIAL_FORM_TYPES = {
671
671
  }
672
672
  }
673
673
  ],
674
- [RETURNS]: [ATOM]
674
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
675
675
  }
676
676
  },
677
677
  [KEYWORDS.BITWISE_LEFT_SHIFT]: {
@@ -704,7 +704,7 @@ export const SPECIAL_FORM_TYPES = {
704
704
  }
705
705
  }
706
706
  ],
707
- [RETURNS]: [ATOM]
707
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
708
708
  }
709
709
  },
710
710
  [KEYWORDS.BITWISE_RIGHT_SHIFT]: {
@@ -737,7 +737,7 @@ export const SPECIAL_FORM_TYPES = {
737
737
  }
738
738
  }
739
739
  ],
740
- [RETURNS]: [ATOM]
740
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
741
741
  }
742
742
  },
743
743
  [KEYWORDS.GET_ARRAY]: {
@@ -859,7 +859,7 @@ export const SPECIAL_FORM_TYPES = {
859
859
  }
860
860
  }
861
861
  ],
862
- [RETURNS]: [ATOM]
862
+ [RETURNS]: [ATOM, NUMBER_SUBTYPE()]
863
863
  }
864
864
  },
865
865
  [KEYWORDS.IF]: {
package/src/utils.js CHANGED
@@ -462,6 +462,27 @@ export class Brr {
462
462
  for (let i = half; i < initial.length; ++i) this._addToRight(initial[i])
463
463
  return this
464
464
  }
465
+ static from(iterable) {
466
+ const out = new Brr()
467
+ const half = (iterable.length / 2) | 0.5
468
+ for (let i = half - 1; i >= 0; --i) out._addToLeft(iterable[i])
469
+ for (let i = half; i < iterable.length; ++i) out._addToRight(iterable[i])
470
+ return out
471
+ }
472
+ /**
473
+ * Returns the elements of an array that meet the condition specified in a callback function.
474
+ * @param predicate — A function that accepts up to three arguments.
475
+ * The filter method calls the predicate function one time for each element in the array.
476
+ */
477
+ filter(callback = _Identity) {
478
+ const out = []
479
+ for (let i = 0, len = this.length; i < len; ++i) {
480
+ const current = this.get(i)
481
+ const predicat = callback(current, i, this)
482
+ if (predicat) out.push(current)
483
+ }
484
+ return Brr.from(out)
485
+ }
465
486
  // reverse() {
466
487
  // const left = this._left
467
488
  // const right = this._right