fez-lisp 1.5.131 → 1.5.133

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.131",
5
+ "version": "1.5.133",
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,7 +726,10 @@ const checkReturnType = ({ exp, stack, name, env }) => {
716
726
  stack
717
727
  })
718
728
  }
719
-
729
+ const stagger = (stack, method, data, fn) => {
730
+ // console.log(data[0], data[1])
731
+ stack[method]({ data, fn })
732
+ }
720
733
  export const typeCheck = (ast) => {
721
734
  const Types = new Map()
722
735
  const stack = new Brr()
@@ -729,11 +742,11 @@ export const typeCheck = (ast) => {
729
742
  ? initArrayType({ rem: rest[i], env }) ?? env[rest[i][0][VALUE]][STATS]
730
743
  : env[rest[i][0][VALUE]][STATS]
731
744
  const expected = args[i][STATS]
732
- retryArgs(args[i][STATS], stack, () =>
745
+ retryArgs(args[i][STATS], exp, stack, () =>
733
746
  match({ rest, args, i, env, scope, exp })
734
747
  )
735
748
  if (!isUnknownType(expected) && !isUnknownReturn(actual))
736
- if (!compareTypeWithReturn(expected, actual))
749
+ if (!equalsTypeWithReturn(expected, actual))
737
750
  throw new TypeError(
738
751
  `Incorrect type of argument (${i}) for (${
739
752
  first[VALUE]
@@ -743,7 +756,7 @@ export const typeCheck = (ast) => {
743
756
  exp
744
757
  )}) (check #16)`
745
758
  )
746
- else if (notABooleanReturn(expected, actual)) {
759
+ else if (notABooleanTypeWithReturn(expected, actual)) {
747
760
  throw new TypeError(
748
761
  `Incorrect type of argument (${i}) for (${
749
762
  first[VALUE]
@@ -795,7 +808,7 @@ export const typeCheck = (ast) => {
795
808
  if (
796
809
  !isUnknownReturn(expected[STATS]) &&
797
810
  !isUnknownReturn(actual[STATS]) &&
798
- !compareReturns(expected[STATS], actual[STATS])
811
+ !equalsReturns(expected[STATS], actual[STATS])
799
812
  )
800
813
  throw new TypeError(
801
814
  `Incorrect return type for (${
@@ -808,7 +821,25 @@ export const typeCheck = (ast) => {
808
821
  getReturn(actual[STATS])
809
822
  )}) (${stringifyArgs(exp)}) (check #779)`
810
823
  )
811
- else retry(actual[STATS], stack, () => match1())
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
+ )
812
843
  }
813
844
  match1()
814
845
  for (let j = 0; j < args[i][STATS][ARGUMENTS].length; ++j) {
@@ -818,7 +849,7 @@ export const typeCheck = (ast) => {
818
849
  if (
819
850
  !isUnknownType(actual[STATS]) &&
820
851
  !isUnknownType(expected[STATS]) &&
821
- !compareTypes(actual[STATS], expected[STATS])
852
+ !equalsTypes(actual[STATS], expected[STATS])
822
853
  )
823
854
  throw new TypeError(
824
855
  `Incorrect type for (${
@@ -835,7 +866,29 @@ export const typeCheck = (ast) => {
835
866
  getType(actual[STATS])
836
867
  )}) (${stringifyArgs(exp)}) (check #780)`
837
868
  )
838
- else retry(actual[STATS], stack, () => match2())
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
+ )
839
892
  }
840
893
  match2()
841
894
  }
@@ -851,7 +904,7 @@ export const typeCheck = (ast) => {
851
904
  }
852
905
  }
853
906
  else if (isUnknownType(expected))
854
- retry(args[i][STATS], stack, () =>
907
+ retry(args[i][STATS], [first, env], stack, () =>
855
908
  match({ rest, args, i, env, scope, exp })
856
909
  )
857
910
  }
@@ -866,7 +919,7 @@ export const typeCheck = (ast) => {
866
919
  switch (first[TYPE]) {
867
920
  case WORD:
868
921
  if (!isSpecial)
869
- stack.append(() => {
922
+ stagger(stack, 'append', [first, env], () => {
870
923
  // Figure out how to determine if varible is define after it's used
871
924
  if (env[first[VALUE]] === undefined) {
872
925
  throw new TypeError(
@@ -921,7 +974,7 @@ export const typeCheck = (ast) => {
921
974
  }) ||
922
975
  isUnknownReturn(env[name][STATS])
923
976
  ) {
924
- retry(env[name][STATS], stack, () => {
977
+ retry(env[name][STATS], [first, env], stack, () => {
925
978
  checkReturnType({
926
979
  stack,
927
980
  exp,
@@ -1040,13 +1093,16 @@ export const typeCheck = (ast) => {
1040
1093
  // TODO figure out what we do here
1041
1094
  // this here is a variable WORD
1042
1095
  // so return type of that function is that varible type
1043
- stack.append(
1096
+ stagger(
1097
+ stack,
1098
+ 'append',
1099
+ [returns, copy],
1044
1100
  () =>
1045
1101
  copy[returns[VALUE]] &&
1046
1102
  setReturnToType(ref[STATS], copy[returns[VALUE]][STATS])
1047
1103
  )
1048
1104
  else {
1049
- stack.append(() => {
1105
+ stagger(stack, 'append', [returns, copy], () => {
1050
1106
  const ret = returns[0]
1051
1107
  switch (ret[VALUE]) {
1052
1108
  case KEYWORDS.IF:
@@ -1063,7 +1119,7 @@ export const typeCheck = (ast) => {
1063
1119
  if (copy[ret[VALUE]])
1064
1120
  setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
1065
1121
  else
1066
- stack.append(() => {
1122
+ stagger(stack, 'append', [ret, copy], () => {
1067
1123
  if (copy[ret[VALUE]])
1068
1124
  setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
1069
1125
  })
@@ -1097,9 +1153,8 @@ export const typeCheck = (ast) => {
1097
1153
  // So they MUST happen before Judgement
1098
1154
  resolveSetter(first, rest, env)
1099
1155
  // end of Var ---------------
1100
-
1101
1156
  // Judgement
1102
- stack.append(() => {
1157
+ stagger(stack, 'append', [first, env], () => {
1103
1158
  if (!isSpecial && env[first[VALUE]] === undefined)
1104
1159
  throw new TypeError(
1105
1160
  `Trying to call undefined (${KEYWORDS.ANONYMOUS_FUNCTION}) ${first[VALUE]} (check #9)`
@@ -1216,7 +1271,7 @@ export const typeCheck = (ast) => {
1216
1271
  }
1217
1272
  if (
1218
1273
  isKnown &&
1219
- !compareTypes(args[i][STATS], env[name][STATS])
1274
+ !equalsTypes(args[i][STATS], env[name][STATS])
1220
1275
  )
1221
1276
  throw new TypeError(
1222
1277
  `Incorrect type of argument (${i}) for (${
@@ -1248,12 +1303,16 @@ export const typeCheck = (ast) => {
1248
1303
  // (let xs [])
1249
1304
  // (let x (array:set-and-get! xs 0 100))
1250
1305
  // (length x)
1251
- //
1252
- // if (isUnknownType(env[name][STATS])) {
1253
- // 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, () =>
1254
1312
  // check(exp, env, scope)
1255
1313
  // )
1256
- // } else
1314
+ // }
1315
+
1257
1316
  if (isSpecial)
1258
1317
  setType(env[name][STATS], args[i][STATS])
1259
1318
  }
@@ -1341,7 +1400,7 @@ export const typeCheck = (ast) => {
1341
1400
  if (
1342
1401
  !isUnknownReturn(expected[STATS]) &&
1343
1402
  !isUnknownReturn(actual[STATS]) &&
1344
- !compareReturns(expected[STATS], actual[STATS])
1403
+ !equalsReturns(expected[STATS], actual[STATS])
1345
1404
  ) {
1346
1405
  throw new TypeError(
1347
1406
  `Incorrect return type for (${
@@ -1356,7 +1415,8 @@ export const typeCheck = (ast) => {
1356
1415
  getReturn(actual[STATS])
1357
1416
  )}) (${stringifyArgs(exp)}) (check #782)`
1358
1417
  )
1359
- } else retry(actual[STATS], stack, () => match1())
1418
+ } else
1419
+ retry(actual[STATS], [first, env], stack, match1)
1360
1420
  }
1361
1421
  match1()
1362
1422
  for (
@@ -1370,7 +1430,7 @@ export const typeCheck = (ast) => {
1370
1430
  if (
1371
1431
  !isUnknownType(actual[STATS]) &&
1372
1432
  !isUnknownType(expected[STATS]) &&
1373
- !compareTypes(actual[STATS], expected[STATS])
1433
+ !equalsTypes(actual[STATS], expected[STATS])
1374
1434
  )
1375
1435
  throw new TypeError(
1376
1436
  `Incorrect type for (${
@@ -1385,7 +1445,13 @@ export const typeCheck = (ast) => {
1385
1445
  getType(actual[STATS])
1386
1446
  )}) (${stringifyArgs(exp)}) (check #781)`
1387
1447
  )
1388
- else retry(actual[STATS], stack, () => match2())
1448
+ else
1449
+ retry(
1450
+ actual[STATS],
1451
+ [first, env],
1452
+ stack,
1453
+ match2
1454
+ )
1389
1455
  }
1390
1456
  match2()
1391
1457
  }
@@ -1394,7 +1460,7 @@ export const typeCheck = (ast) => {
1394
1460
  if (!isSpecial) {
1395
1461
  const name = rest[i][VALUE]
1396
1462
  if (isUnknownType(args[i][STATS])) {
1397
- retry(args[i][STATS], stack, () =>
1463
+ retry(args[i][STATS], [first, env], stack, () =>
1398
1464
  check(exp, env, scope)
1399
1465
  )
1400
1466
  }
@@ -1422,8 +1488,11 @@ export const typeCheck = (ast) => {
1422
1488
  isUnknownReturn(env[name][STATS]) &&
1423
1489
  !env[name][STATS][IS_ARGUMENT]
1424
1490
  )
1425
- return retry(env[name][STATS], stack, () =>
1426
- check(exp, env, scope)
1491
+ return retry(
1492
+ env[name][STATS],
1493
+ [first, env],
1494
+ stack,
1495
+ () => check(exp, env, scope)
1427
1496
  )
1428
1497
 
1429
1498
  if (isSpecial && name === KEYWORDS.IF) {
@@ -1480,7 +1549,7 @@ export const typeCheck = (ast) => {
1480
1549
  }
1481
1550
  const copy = JSON.parse(JSON.stringify(ast))
1482
1551
  check(copy, SPECIAL_FORM_TYPES, copy)
1483
- while (stack.length) stack.cut()()
1552
+ while (stack.length) stack.cut().fn()
1484
1553
  return [ast, Types]
1485
1554
  }
1486
1555
  export const type = (ast) => typeCheck(ast)[0]
package/src/macros.js CHANGED
@@ -26,6 +26,8 @@ export const SUGGAR = {
26
26
  REMAINDER_OF_DIVISION_1: '%',
27
27
  UNLESS: 'unless',
28
28
  CREATE_LIST: 'list',
29
+ CREATE_SET: 'new:set',
30
+ CREATE_MAP: 'new:map',
29
31
  POWER: '**',
30
32
  INTEGER_DEVISION: '//',
31
33
  CONDITION: 'cond'
@@ -683,6 +685,8 @@ export const seeIfProgramIsInvalid = (source) => {
683
685
  }
684
686
  export const replaceQuotes = (source) =>
685
687
  source
688
+ .replaceAll(/\(\[/g, `(${SUGGAR.CREATE_SET} [`)
689
+ .replaceAll(/\(\{/g, `(${SUGGAR.CREATE_MAP} [`)
686
690
  .replaceAll(/\[/g, `(${KEYWORDS.CREATE_ARRAY} `)
687
691
  .replaceAll(/\]/g, ')')
688
692
  .replaceAll(/\{/g, `(${SUGGAR.CREATE_LIST} `)
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