fez-lisp 1.6.52 → 1.6.54

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.6.52",
5
+ "version": "1.6.54",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -45,7 +45,8 @@ import {
45
45
  IS_ARGUMENT,
46
46
  NUMBER,
47
47
  NUMBER_SUBTYPE,
48
- UNKNOWN_SUBTYPE
48
+ UNKNOWN_SUBTYPE,
49
+ SubType
49
50
  } from './types.js'
50
51
  import {
51
52
  Brr,
@@ -56,32 +57,7 @@ import {
56
57
  logExp,
57
58
  stringifyArgs
58
59
  } from './utils.js'
59
- Set.prototype.union = function (B) {
60
- const A = this
61
- const out = new Set()
62
- A.forEach((element) => out.add(element))
63
- B.forEach((element) => out.add(element))
64
- return out
65
- }
66
- Set.prototype.xor = function (B) {
67
- const A = this
68
- const out = new Set()
69
- B.forEach((element) => !A.has(element) && out.add(element))
70
- A.forEach((element) => !B.has(element) && out.add(element))
71
- return out
72
- }
73
- Set.prototype.intersection = function (B) {
74
- const A = this
75
- const out = new Set()
76
- B.forEach((element) => A.has(element) && out.add(element))
77
- return out
78
- }
79
- Set.prototype.difference = function (B) {
80
- const A = this
81
- const out = new Set()
82
- A.forEach((element) => !B.has(element) && out.add(element))
83
- return out
84
- }
60
+
85
61
  export const identity = (name) => [
86
62
  [0, 'let'],
87
63
  [1, name],
@@ -289,30 +265,36 @@ export const isUnknownType = (stats) => stats && stats[TYPE_PROP][0] === UNKNOWN
289
265
  export const isUnknownProp = (stats, prop) => {
290
266
  return stats && stats[prop][0] === UNKNOWN
291
267
  }
292
-
268
+ export const isSubType = (subtype) => subtype instanceof SubType
269
+ export const isSubTypeUknown = (subtype) =>
270
+ subtype.size === 1 && subtype.has(UNKNOWN)
271
+ export const matchSub = (a, b) =>
272
+ a.has(UNKNOWN) ||
273
+ b.has(UNKNOWN) ||
274
+ a.has(ANY) ||
275
+ b.has(ANY) ||
276
+ a.isMatching(b)
293
277
  export const isUnknownReturn = (stats) => stats[RETURNS][0] === UNKNOWN
294
278
  export const getType = (stats) => stats && stats[TYPE_PROP][0]
295
279
  export const getTypes = (stats) => stats && stats[TYPE_PROP]
296
280
  export const getReturn = (stats) => stats && stats[RETURNS][0]
297
281
  export const getReturns = (stats) => stats && stats[RETURNS]
298
282
  export const getSubType = (stats) => stats && stats[TYPE_PROP][1]
299
- export const hasSubType = (stats) => stats && stats[TYPE_PROP][1] instanceof Set
283
+ export const hasSubType = (stats) => stats && isSubType(stats[TYPE_PROP][1])
300
284
  export const getSubReturn = (stats) => stats && stats[RETURNS][1]
301
- export const hasSubReturn = (stats) => stats && stats[RETURNS][1] instanceof Set
285
+ export const hasSubReturn = (stats) => stats && isSubType(stats[RETURNS][1])
302
286
  export const isUnknownSubReturn = (stats) =>
303
287
  !hasSubReturn(stats) ||
304
288
  (stats &&
305
289
  stats[RETURNS] &&
306
290
  stats[RETURNS][1] &&
307
- stats[RETURNS][1].size === 1 &&
308
- stats[RETURNS][1].has(UNKNOWN))
291
+ isSubTypeUknown(stats[RETURNS][1]))
309
292
  export const isUnknownSubType = (stats) =>
310
293
  hasSubType(stats) &&
311
294
  stats &&
312
295
  stats[TYPE_PROP] &&
313
296
  stats[TYPE_PROP][1] &&
314
- stats[TYPE_PROP][1].size === 1 &&
315
- stats[TYPE_PROP][1].has(UNKNOWN)
297
+ isSubTypeUknown(stats[TYPE_PROP][1])
316
298
  export const isAtomType = (stats) =>
317
299
  isAnyType(stats) || stats[TYPE_PROP][0] === ATOM
318
300
  export const isAtomReturn = (stats) =>
@@ -357,35 +339,21 @@ const IsPredicate = (leaf) =>
357
339
 
358
340
  const equalSubTypes = (a, b) => {
359
341
  return (
360
- !hasSubType(a) ||
361
- !hasSubType(b) ||
362
- getSubType(a).has(UNKNOWN) ||
363
- getSubType(b).has(UNKNOWN) ||
364
- getSubType(a).has(ANY) ||
365
- getSubType(b).has(ANY) ||
366
- getSubType(a).difference(getSubType(b)).size === 0
342
+ !hasSubType(a) || !hasSubType(b) || matchSub(getSubType(a), getSubType(b))
367
343
  )
368
344
  }
369
345
  const equalSubReturns = (a, b) => {
370
346
  return (
371
347
  !hasSubReturn(a) ||
372
348
  !hasSubReturn(b) ||
373
- getSubReturn(a).has(UNKNOWN) ||
374
- getSubReturn(b).has(UNKNOWN) ||
375
- getSubReturn(a).has(ANY) ||
376
- getSubReturn(b).has(ANY) ||
377
- getSubReturn(a).difference(getSubReturn(b)).size === 0
349
+ matchSub(getSubReturn(a), getSubReturn(b))
378
350
  )
379
351
  }
380
352
  const equalSubTypesWithSubReturn = (a, b) => {
381
353
  return (
382
354
  !hasSubType(a) ||
383
355
  !hasSubReturn(b) ||
384
- getSubType(a).has(UNKNOWN) ||
385
- getSubReturn(b).has(UNKNOWN) ||
386
- getSubType(a).has(ANY) ||
387
- getSubReturn(b).has(ANY) ||
388
- getSubType(a).difference(getSubReturn(b)).size === 0
356
+ matchSub(getSubType(a), getSubReturn(b))
389
357
  )
390
358
  }
391
359
  const isAtomABoolean = (atom) => atom === TRUE || atom === FALSE
@@ -542,7 +510,16 @@ const IfApplyBranch = ({
542
510
  }
543
511
  break
544
512
  default:
545
- return setPropToReturnRef(ref[STATS], prop, branch[STATS])
513
+ if (
514
+ getType(ref[STATS]) === UNKNOWN &&
515
+ getReturn(branch[STATS]) === UNKNOWN
516
+ ) {
517
+ retry(ref[STATS], exp, stack, () =>
518
+ setPropToReturn(ref[STATS], prop, branch[STATS])
519
+ )
520
+ return true
521
+ }
522
+ return setPropToReturn(ref[STATS], prop, branch[STATS])
546
523
  }
547
524
  }
548
525
  const ifExpression = ({ re, env, ref, prop, stack, exp, check }) => {
@@ -554,6 +531,7 @@ const ifExpression = ({ re, env, ref, prop, stack, exp, check }) => {
554
531
  const alt = isLeaf(re[1]) ? re[1] : re[1][0]
555
532
  const concequent = env[conc[VALUE]]
556
533
  const alternative = env[alt[VALUE]]
534
+
557
535
  // TODO make this more simple - it's so many different things just because types are functions or not
558
536
  // WHY not consider making return types for everything
559
537
  if (concequent)
@@ -621,6 +599,56 @@ const resolveCondition = ({ rem, name, env, exp, prop, stack, check }) => {
621
599
  break
622
600
  }
623
601
  }
602
+ const resolveGetter = ({ rem, prop, name, env }) => {
603
+ const array = isLeaf(rem[1]) ? rem[1] : rem[1][0]
604
+ if (!env[array[VALUE]] || !env[name]) return true
605
+
606
+ switch (array[TYPE]) {
607
+ case APPLY:
608
+ if (hasSubType(env[array[VALUE]][STATS])) {
609
+ const rightSub = getSubReturn(env[array[VALUE]][STATS])
610
+ const isAtom = rightSub.has(NUMBER) || rightSub.has(BOOLEAN)
611
+ const isCollection = rightSub.has(COLLECTION)
612
+ if (isAtom && !isCollection) {
613
+ setPropToAtom(env[name][STATS], prop)
614
+ setPropToSubReturn(env[name][STATS], prop, env[array[VALUE]][STATS])
615
+ } else if (!isAtom && isCollection) {
616
+ setPropToReturn(env[name][STATS], prop, env[array[VALUE]][STATS])
617
+ // TODO: handle this nested array overwrite better
618
+ if (getSubReturn(env[array[VALUE]][STATS]).has(COLLECTION))
619
+ setPropToSubReturn(env[name][STATS], prop, {
620
+ [RETURNS]: [COLLECTION, UNKNOWN_SUBTYPE()]
621
+ })
622
+ } else return false
623
+ } else return false
624
+ break
625
+ case WORD:
626
+ {
627
+ if (hasSubType(env[array[VALUE]][STATS])) {
628
+ const rightSub = getSubType(env[array[VALUE]][STATS])
629
+ const isAtom =
630
+ rightSub.has(ATOM) || rightSub.has(NUMBER) || rightSub.has(BOOLEAN)
631
+ const isCollection = rightSub.has(COLLECTION)
632
+ if (isAtom && !isCollection) {
633
+ setPropToAtom(env[name][STATS], prop)
634
+ setPropToSubType(env[name][STATS], prop, env[array[VALUE]][STATS])
635
+ } else if (!isAtom && isCollection) {
636
+ setPropToType(env[name][STATS], prop, {
637
+ [TYPE_PROP]: [
638
+ env[array[VALUE]][STATS][TYPE_PROP][1].types[0],
639
+ new SubType(
640
+ env[array[VALUE]][STATS][TYPE_PROP][1].types.slice(1)
641
+ )
642
+ ]
643
+ })
644
+ } else return false
645
+ } else return false
646
+ }
647
+ break
648
+ }
649
+ return true
650
+ }
651
+
624
652
  const resolveSetter = (first, rest, env, stack) => {
625
653
  if (
626
654
  getSuffix(first[VALUE]) === MUTATION_SUFFIX &&
@@ -635,7 +663,7 @@ const resolveSetter = (first, rest, env, stack) => {
635
663
  const right = isLeaf(rest.at(-1)) ? rest.at(-1) : rest.at(-1)[0]
636
664
  const currentSubType = hasSubType(current[STATS])
637
665
  ? getSubType(current[STATS])
638
- : new Set([UNKNOWN])
666
+ : new SubType([UNKNOWN])
639
667
  switch (right[TYPE]) {
640
668
  case ATOM:
641
669
  if (
@@ -659,7 +687,7 @@ const resolveSetter = (first, rest, env, stack) => {
659
687
  if (env[right[VALUE]]) {
660
688
  if (hasSubType(env[right[VALUE]][STATS])) {
661
689
  if (currentSubType.has(UNKNOWN))
662
- current[STATS][TYPE_PROP][1] = new Set([
690
+ current[STATS][TYPE_PROP][1] = new SubType([
663
691
  ...getSubType(env[right[VALUE]][STATS])
664
692
  ])
665
693
  else if (!equalSubTypes(current[STATS], env[right[VALUE]][STATS]))
@@ -672,7 +700,7 @@ const resolveSetter = (first, rest, env, stack) => {
672
700
  getTypes(env[right[VALUE]][STATS])
673
701
  )}) (${stringifyArgs([first, rest])}) (check #198)`
674
702
  )
675
- current[STATS][TYPE_PROP][1] = new Set(
703
+ current[STATS][TYPE_PROP][1] = new SubType(
676
704
  getSubType(env[right[VALUE]][STATS])
677
705
  )
678
706
  } else
@@ -683,7 +711,7 @@ const resolveSetter = (first, rest, env, stack) => {
683
711
  break
684
712
  case APPLY:
685
713
  if (env[right[VALUE]]) {
686
- if (right[VALUE] === KEYWORDS.CREATE_ARRAY) {
714
+ if (right[VALUE] === 'array:get') {
687
715
  current[STATS][TYPE_PROP][1] = initArrayType({
688
716
  rem: rest.at(-1),
689
717
  env
@@ -692,7 +720,7 @@ const resolveSetter = (first, rest, env, stack) => {
692
720
  }
693
721
  if (hasSubReturn(env[right[VALUE]][STATS])) {
694
722
  if (currentSubType.has(UNKNOWN))
695
- current[STATS][TYPE_PROP][1] = new Set([
723
+ current[STATS][TYPE_PROP][1] = new SubType([
696
724
  ...getSubReturn(env[right[VALUE]][STATS])
697
725
  ])
698
726
  else if (
@@ -710,7 +738,7 @@ const resolveSetter = (first, rest, env, stack) => {
710
738
  getReturns(env[right[VALUE]][STATS])
711
739
  )}) (${stringifyArgs([first, rest])}) (check #198)`
712
740
  )
713
- current[STATS][TYPE_PROP][1] = new Set([
741
+ current[STATS][TYPE_PROP][1] = new SubType([
714
742
  ...getSubReturn(env[right[VALUE]][STATS])
715
743
  ])
716
744
  }
@@ -729,81 +757,52 @@ const resolveSetter = (first, rest, env, stack) => {
729
757
  // )
730
758
  }
731
759
  }
732
- const resolveGetter = ({ rem, prop, name, env }) => {
733
- const array = isLeaf(rem[1]) ? rem[1] : rem[1][0]
734
- if (!env[array[VALUE]] || !env[name]) return true
735
- switch (array[TYPE]) {
736
- case APPLY:
737
- if (hasSubType(env[array[VALUE]][STATS])) {
738
- const rightSub = getSubReturn(env[array[VALUE]][STATS])
739
- const isAtom = rightSub.has(NUMBER) || rightSub.has(BOOLEAN)
740
- const isCollection = rightSub.has(COLLECTION)
741
- if (isAtom && !isCollection) {
742
- setPropToAtom(env[name][STATS], prop)
743
- setPropToSubReturn(env[name][STATS], prop, env[array[VALUE]][STATS])
744
- } else if (!isAtom && isCollection) {
745
- setPropToReturn(env[name][STATS], prop, env[array[VALUE]][STATS])
746
- // TODO: handle this nested array overwrite better
747
- if (getSubReturn(env[array[VALUE]][STATS]).has(COLLECTION))
748
- setPropToSubReturn(env[name][STATS], prop, {
749
- [RETURNS]: [COLLECTION, UNKNOWN_SUBTYPE()]
750
- })
751
- } else return false
752
- } else return false
753
- break
754
- case WORD:
755
- {
756
- if (hasSubType(env[array[VALUE]][STATS])) {
757
- const rightSub = getSubType(env[array[VALUE]][STATS])
758
- const isAtom =
759
- rightSub.has(ATOM) || rightSub.has(NUMBER) || rightSub.has(BOOLEAN)
760
- const isCollection = rightSub.has(COLLECTION)
761
- if (isAtom && !isCollection) {
762
- setPropToAtom(env[name][STATS], prop)
763
- setPropToSubType(env[name][STATS], prop, env[array[VALUE]][STATS])
764
- } else if (!isAtom && isCollection) {
765
- setPropToType(env[name][STATS], prop, env[array[VALUE]][STATS])
766
- // TODO: handle this nested array overwrite better
767
- if (getSubType(env[array[VALUE]][STATS]).has(COLLECTION))
768
- setPropToSubType(env[name][STATS], prop, {
769
- [TYPE_PROP]: [COLLECTION, UNKNOWN_SUBTYPE()]
770
- })
771
- } else return false
772
- } else return false
773
- }
774
- break
775
- }
776
- return true
760
+ const initArrayTypeRec = ({ rem, env }) => {
761
+ return rem.slice(1).map((x) =>
762
+ isLeaf(x)
763
+ ? x[TYPE] === WORD
764
+ ? env[x[VALUE]]
765
+ ? // env[x[VALUE]][STATS][TYPE_PROP][0] === COLLECTION
766
+ // ? initArrayTypeRec({ rem: x, env })
767
+ // :
768
+ getTypes(env[x[VALUE]][STATS])
769
+ : [UNKNOWN]
770
+ : [
771
+ x[TYPE],
772
+ x[TYPE] === ATOM ? NUMBER_SUBTYPE() : new SubType([UNKNOWN])
773
+ ]
774
+ : env[x[0][VALUE]]
775
+ ? x.length > 1 && env[x[0][VALUE]][STATS][RETURNS][0] === COLLECTION
776
+ ? initArrayTypeRec({ rem: x, env })
777
+ : getReturns(env[x[0][VALUE]][STATS])
778
+ : [UNKNOWN]
779
+ )
777
780
  }
778
781
  const initArrayType = ({ rem, env }) => {
779
- const ret = rem
780
- .slice(1)
781
- .map((x) =>
782
- isLeaf(x)
783
- ? x[TYPE] === WORD
784
- ? env[x[VALUE]]
785
- ? getTypes(env[x[VALUE]][STATS])
786
- : [UNKNOWN]
787
- : [x[TYPE], x[TYPE] === ATOM ? NUMBER_SUBTYPE() : new Set([UNKNOWN])]
788
- : env[x[0][VALUE]]
789
- ? getReturns(env[x[0][VALUE]][STATS])
790
- : [UNKNOWN]
791
- )
782
+ const ret = initArrayTypeRec({ rem, env })
792
783
  const known = ret.find((x) => x[0] !== ANY && x[0] !== UNKNOWN)
793
- if (
794
- known &&
795
- ret.length &&
796
- !ret.some((x) => known[0] !== x[0] || known.length !== x.length)
797
- ) {
784
+ // console.log(known[0], ret[0])
785
+ if (known && ret.length) {
786
+ if (Array.isArray(ret[0][0])) {
787
+ let head = ret[0][0]
788
+ ret[0].length = 0
789
+ const subT = new SubType([COLLECTION])
790
+ ret[0].push(COLLECTION, subT)
791
+ while (head && !isSubType(head[1])) {
792
+ subT.add(COLLECTION)
793
+ head = head[0]
794
+ }
795
+ if (head) subT.add(head[1].types[0])
796
+ }
798
797
  const [main, sub] = ret[0]
799
798
  return {
800
799
  [TYPE_PROP]: [APPLY],
801
- [RETURNS]: [COLLECTION, new Set(sub ? [...sub] : [main])]
800
+ [RETURNS]: [COLLECTION, new SubType(isSubType(sub) ? [...sub] : [main])]
802
801
  }
803
802
  } else
804
803
  return {
805
804
  [TYPE_PROP]: [APPLY],
806
- [RETURNS]: [COLLECTION, new Set([UNKNOWN])]
805
+ [RETURNS]: [COLLECTION, new SubType([UNKNOWN])]
807
806
  }
808
807
  }
809
808
  const resolveReturnType = ({
@@ -849,6 +848,8 @@ const resolveReturnType = ({
849
848
  break
850
849
  default:
851
850
  {
851
+ if (returns[VALUE] === KEYWORDS.GET_ARRAY)
852
+ resolveGetter({ rem, prop, name, env })
852
853
  // if (
853
854
  // !GETTERS_SET.has(name) &&
854
855
  // GETTERS_SET.has(returns[VALUE]) &&
@@ -1386,8 +1387,11 @@ export const typeCheck = (
1386
1387
  : env[right[VALUE]] == undefined
1387
1388
  ? UNKNOWN
1388
1389
  : env[right[VALUE]][STATS][RETURNS][0]
1389
- if (type !== UNKNOWN)
1390
+
1391
+ if (type !== UNKNOWN && type !== ANY) {
1390
1392
  setTypeToReturn(env[name][STATS], env[right[VALUE]][STATS])
1393
+ }
1394
+
1391
1395
  const resolve = () => {
1392
1396
  const body = rightHand
1393
1397
  const rem = hasBlock(body) ? body.at(-1) : body
@@ -1404,6 +1408,7 @@ export const typeCheck = (
1404
1408
  })
1405
1409
  }
1406
1410
  resolve()
1411
+
1407
1412
  if (isUnknownType(env[name][STATS]))
1408
1413
  once(env[name][STATS], exp, stack, () => resolve())
1409
1414
  }
@@ -1530,6 +1535,14 @@ export const typeCheck = (
1530
1535
  // Setters are just like DEFINE_VARIABLE as they are essentially the Var case for Collections
1531
1536
  // So they MUST happen before Judgement
1532
1537
  resolveSetter(first, rest, env, stack)
1538
+ if (first[VALUE] === 'array:get-infer' && first[TYPE] === APPLY) {
1539
+ resolveGetter({
1540
+ rem: rest[0],
1541
+ prop: TYPE_PROP,
1542
+ name: rest[0],
1543
+ env
1544
+ })
1545
+ }
1533
1546
  // end of Var ---------------
1534
1547
  // Judgement
1535
1548
  const judge = () => {
package/src/types.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import stdT from '../lib/baked/std-T.js'
2
2
  import std from '../lib/baked/std.js'
3
- import { getReturn, getReturns, getType, getTypes } from './check.js'
3
+ import { getReturn, getReturns, getType, getTypes, isSubType } from './check.js'
4
4
  import {
5
5
  APPLY,
6
6
  ATOM,
@@ -36,11 +36,45 @@ export const IS_ARGUMENT = 'is_arg'
36
36
  export const NIL = 'nil'
37
37
  export const TRUE_WORD = 'true'
38
38
  export const FALSE_WORD = 'false'
39
- export const BOOLEAN_SUBTYPE = () => new Set([BOOLEAN])
40
- export const COLLECTION_SUBTYPE = () => new Set([COLLECTION])
41
- export const NUMBER_SUBTYPE = () => new Set([NUMBER])
42
- export const ABSTRACTION_SUBTYPE = () => new Set([APPLY])
43
- export const UNKNOWN_SUBTYPE = () => new Set([UNKNOWN])
39
+ export class SubType {
40
+ constructor(args) {
41
+ this.types = []
42
+ this.types.push(...args)
43
+ }
44
+ add(type) {
45
+ this.types.push(type)
46
+ return this
47
+ }
48
+ has(type) {
49
+ return this.types[0] === type
50
+ }
51
+ isMatching(b) {
52
+ for (let i = 0; i < this.types.length; ++i) {
53
+ if (
54
+ this.types[i] == undefined ||
55
+ b.types[i] == undefined ||
56
+ this.types[i] === UNKNOWN ||
57
+ b.types[i] === UNKNOWN ||
58
+ this.types[i] === ANY ||
59
+ b.types[i] === ANY
60
+ )
61
+ return true
62
+ if (this.types[i] !== b.types[i]) return false
63
+ }
64
+ return true
65
+ }
66
+ get size() {
67
+ return this.types.length
68
+ }
69
+ *[Symbol.iterator]() {
70
+ for (let i = 0, len = this.size; i < len; ++i) yield this.types[i]
71
+ }
72
+ }
73
+ export const BOOLEAN_SUBTYPE = () => new SubType([BOOLEAN])
74
+ export const COLLECTION_SUBTYPE = () => new SubType([COLLECTION])
75
+ export const NUMBER_SUBTYPE = () => new SubType([NUMBER])
76
+ export const ABSTRACTION_SUBTYPE = () => new SubType([APPLY])
77
+ export const UNKNOWN_SUBTYPE = () => new SubType([UNKNOWN])
44
78
 
45
79
  const SPECIAL_BOOLEAN = BOOLEAN_SUBTYPE()
46
80
  const SPECIAL_COLLECTION = COLLECTION_SUBTYPE()
@@ -82,18 +116,22 @@ export const toTypeCodes = (type) => {
82
116
  return [UNKNOWN]
83
117
  case 'Unknown[]':
84
118
  case 'Unknowns':
85
- case 'Collection':
86
- return [COLLECTION, new Set([ANY])]
119
+ // case 'Collection':
120
+ return [COLLECTION, new SubType([ANY])]
87
121
  case 'Numbers':
88
122
  case 'Number[]':
89
123
  return [COLLECTION, NUMBER_SUBTYPE()]
90
124
  case 'Booleans':
91
125
  case 'Boolean[]':
92
126
  return [COLLECTION, BOOLEAN_SUBTYPE()]
93
- case 'Collections':
94
- case 'Collection[]':
127
+ // case 'Collections':
128
+ // case 'Collection[]':
95
129
  case 'Unknown[][]':
96
130
  return [COLLECTION, COLLECTION_SUBTYPE()]
131
+ case 'Boolean[][]':
132
+ return [COLLECTION, new SubType([COLLECTION, BOOLEAN])]
133
+ case 'Number[][]':
134
+ return [COLLECTION, new SubType([COLLECTION, NUMBER])]
97
135
  case 'Any':
98
136
  return [ANY]
99
137
  default:
@@ -954,7 +992,7 @@ export const SPECIAL_FORM_TYPES = {
954
992
  }
955
993
  }
956
994
  ],
957
- // [GENERIC, new Set([PLACEHOLDER]), 0]
995
+ // [GENERIC, new SubType([PLACEHOLDER]), 0]
958
996
  [RETURNS]: [COLLECTION]
959
997
  }
960
998
  },
@@ -1307,20 +1345,18 @@ export const formatSubType = (T) => {
1307
1345
  switch (T[0]) {
1308
1346
  case COLLECTION:
1309
1347
  return `${
1310
- T[1] instanceof Set
1311
- ? [...T[1]]
1312
- .map((x) =>
1313
- x === COLLECTION
1314
- ? formatSubType([x])
1315
- : toTypeNamesAnyToUknown(x)
1316
- )
1317
- .join(' ') || toTypeNames(UNKNOWN)
1348
+ isSubType(T[1])
1349
+ ? T[1].has(COLLECTION)
1350
+ ? `${toTypeNamesAnyToUknown(T[1].types.at(-1))}${'[]'.repeat(
1351
+ T[1].types.length - 1
1352
+ )}`
1353
+ : toTypeNamesAnyToUknown(T[1].types[0]) || toTypeNames(UNKNOWN)
1318
1354
  : toTypeNames(UNKNOWN)
1319
1355
  }[]`
1320
1356
  case ATOM:
1321
1357
  return `${
1322
- T[1] instanceof Set
1323
- ? [...T[1]].map((x) => toTypeNamesAnyToUknown(x)).join(' ')
1358
+ isSubType(T[1])
1359
+ ? toTypeNamesAnyToUknown(T[1].types[0])
1324
1360
  : toTypeNamesAnyToUknown(NUMBER)
1325
1361
  }`
1326
1362
  default:
@@ -1378,7 +1414,7 @@ export const formatAstSubType = (T) => {
1378
1414
  switch (T[0]) {
1379
1415
  case COLLECTION:
1380
1416
  return `${
1381
- T[1] instanceof Set
1417
+ isSubType(T[1])
1382
1418
  ? [...T[1]]
1383
1419
  .map((x) =>
1384
1420
  x === COLLECTION
@@ -1390,7 +1426,7 @@ export const formatAstSubType = (T) => {
1390
1426
  }[]`
1391
1427
  case ATOM:
1392
1428
  return `${
1393
- T[1] instanceof Set
1429
+ isSubType(T[1])
1394
1430
  ? [...T[1]].map((x) => toTypeNamesAnyToUknown(x)).join(' ')
1395
1431
  : toTypeNamesAnyToUknown(NUMBER)
1396
1432
  }`