squint-cljs 0.14.202 → 0.14.203
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/README.md +3 -0
- package/lib/cli.js +115 -113
- package/lib/cljs.pprint.js +262 -262
- package/lib/compiler.js +1400 -1370
- package/lib/compiler.node.js +45 -45
- package/lib/compiler.sci.js +1280 -1281
- package/lib/node.nrepl_server.js +29 -29
- package/lib/squint.core.umd.js +5 -3
- package/package.json +3 -1
- package/src/squint/core.js +704 -39
- package/src/squint/multi.js +7 -1
- package/src/squint/record.js +103 -0
- package/src/squint/set.js +142 -46
package/src/squint/core.js
CHANGED
|
@@ -5,9 +5,19 @@
|
|
|
5
5
|
// (e.g. multi.js). Signature and semantics may change without notice.
|
|
6
6
|
export function __toFn(x) {
|
|
7
7
|
if (x == null || typeof x === 'function') return x;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
if (typeof x === 'string') return (coll, d) => get(coll, x, d);
|
|
9
|
+
// a value is callable as a lookup only if it is a collection or a custom
|
|
10
|
+
// type implementing ILookup; a seq, list or opaque object throws when
|
|
11
|
+
// called, like a non-IFn in CLJS
|
|
12
|
+
switch (typeConst(x)) {
|
|
13
|
+
case MAP_TYPE:
|
|
14
|
+
case ARRAY_TYPE:
|
|
15
|
+
case OBJECT_TYPE:
|
|
16
|
+
case SET_TYPE:
|
|
17
|
+
return (k, d) => get(x, k, d);
|
|
18
|
+
case INSTANCE_TYPE:
|
|
19
|
+
if (x[ILookup__lookup] !== undefined) return (k, d) => get(x, k, d);
|
|
20
|
+
}
|
|
11
21
|
return x;
|
|
12
22
|
}
|
|
13
23
|
|
|
@@ -51,6 +61,12 @@ function dequal(foo, bar) {
|
|
|
51
61
|
if (foo === bar) return true;
|
|
52
62
|
// null and undefined are both nil in CLJS, so they compare equal
|
|
53
63
|
if (foo == null) return bar == null;
|
|
64
|
+
if (bar == null) return false;
|
|
65
|
+
// -equiv dispatches on the left argument, like CLJS =
|
|
66
|
+
if (typeof foo === 'object' && foo[IEquiv__equiv] !== undefined) return !!foo[IEquiv__equiv](foo, bar);
|
|
67
|
+
// when only the right side has -equiv (the left is e.g. a plain object),
|
|
68
|
+
// dispatch on it so = stays symmetric
|
|
69
|
+
if (typeof bar === 'object' && bar[IEquiv__equiv] !== undefined) return !!bar[IEquiv__equiv](bar, foo);
|
|
54
70
|
var ctor, len, tmp;
|
|
55
71
|
|
|
56
72
|
// A sorted map compares by entries against any map type (object, Map, sorted).
|
|
@@ -193,6 +209,13 @@ export function _(...xs) {
|
|
|
193
209
|
return xs.reduce((x, y) => x - y);
|
|
194
210
|
}
|
|
195
211
|
|
|
212
|
+
export function _SLASH_(...xs) {
|
|
213
|
+
if (xs.length === 1) {
|
|
214
|
+
return 1 / xs[0];
|
|
215
|
+
}
|
|
216
|
+
return xs.reduce((x, y) => x / y);
|
|
217
|
+
}
|
|
218
|
+
|
|
196
219
|
export const __protocol_satisfies = {};
|
|
197
220
|
|
|
198
221
|
export function satisfies_QMARK_(protocol, x) {
|
|
@@ -219,6 +242,7 @@ function getAssocMut(m) {
|
|
|
219
242
|
return mapAssocMut;
|
|
220
243
|
case ARRAY_TYPE:
|
|
221
244
|
case OBJECT_TYPE:
|
|
245
|
+
case INSTANCE_TYPE:
|
|
222
246
|
return objAssocMut;
|
|
223
247
|
}
|
|
224
248
|
}
|
|
@@ -258,6 +282,17 @@ export function assoc_BANG_(m, k, v, ...kvs) {
|
|
|
258
282
|
m[kvs[i]] = kvs[i + 1];
|
|
259
283
|
}
|
|
260
284
|
break;
|
|
285
|
+
case INSTANCE_TYPE:
|
|
286
|
+
if (m[ITransientAssociative__assoc_BANG_] !== undefined) {
|
|
287
|
+
// re-read the slot off the current value: an -assoc! impl may return a
|
|
288
|
+
// different handle
|
|
289
|
+
let ret = m[ITransientAssociative__assoc_BANG_](m, k, v);
|
|
290
|
+
for (let i = 0; i < kvs.length; i += 2) {
|
|
291
|
+
ret = ret[ITransientAssociative__assoc_BANG_](ret, kvs[i], kvs[i + 1]);
|
|
292
|
+
}
|
|
293
|
+
return ret;
|
|
294
|
+
}
|
|
295
|
+
// fall through: an instance without -assoc! keeps the object behavior
|
|
261
296
|
case OBJECT_TYPE:
|
|
262
297
|
m[k] = v;
|
|
263
298
|
|
|
@@ -274,16 +309,14 @@ export function assoc_BANG_(m, k, v, ...kvs) {
|
|
|
274
309
|
return m;
|
|
275
310
|
}
|
|
276
311
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
// Copies metadata from `from` onto `to` (when present) and returns `to`. Used
|
|
280
|
-
// to make value-producing operations (copy, empty, conj, into) carry metadata
|
|
281
|
-
// like Clojure does, instead of dropping it on the freshly built structure.
|
|
282
|
-
// Kept branch-light for the hot path: reads an absent symbol property (cheap,
|
|
283
|
-
// no hidden-class change) and only writes when metadata is actually present.
|
|
312
|
+
// value-producing ops (copy, empty, conj, into) carry metadata by
|
|
313
|
+
// forwarding the instance-level meta slots onto the fresh structure
|
|
284
314
|
function copyMeta(from, to) {
|
|
285
|
-
const
|
|
286
|
-
if (
|
|
315
|
+
const f = from?.[IMeta__meta];
|
|
316
|
+
if (f !== undefined) {
|
|
317
|
+
to[IMeta__meta] = f;
|
|
318
|
+
to[IWithMeta__with_meta] = from[IWithMeta__with_meta];
|
|
319
|
+
}
|
|
287
320
|
return to;
|
|
288
321
|
}
|
|
289
322
|
|
|
@@ -296,6 +329,7 @@ function copy(o) {
|
|
|
296
329
|
return copyMeta(o, new o.constructor(o));
|
|
297
330
|
case ARRAY_TYPE:
|
|
298
331
|
return copyMeta(o, [...o]);
|
|
332
|
+
case INSTANCE_TYPE:
|
|
299
333
|
case OBJECT_TYPE:
|
|
300
334
|
return copyMeta(o, { ...o });
|
|
301
335
|
case LIST_TYPE:
|
|
@@ -313,6 +347,13 @@ export function assoc(o, k, v, ...kvs) {
|
|
|
313
347
|
if (o == null) {
|
|
314
348
|
o = {};
|
|
315
349
|
}
|
|
350
|
+
if (o[IAssociative__assoc] !== undefined) {
|
|
351
|
+
let ret = o[IAssociative__assoc](o, k, v);
|
|
352
|
+
for (let i = 0; i < kvs.length; i += 2) {
|
|
353
|
+
ret = ret[IAssociative__assoc](ret, kvs[i], kvs[i + 1]);
|
|
354
|
+
}
|
|
355
|
+
return ret;
|
|
356
|
+
}
|
|
316
357
|
const ret = copy(o);
|
|
317
358
|
assoc_BANG_(ret, k, v, ...kvs);
|
|
318
359
|
return ret;
|
|
@@ -335,6 +376,9 @@ const OBJECT_TYPE = 3;
|
|
|
335
376
|
const LIST_TYPE = 4;
|
|
336
377
|
const SET_TYPE = 5;
|
|
337
378
|
const LAZY_ITERABLE_TYPE = 6;
|
|
379
|
+
// a class instance or null-prototype object: the extension point for the
|
|
380
|
+
// map-facing protocols. Plain objects keep the OBJECT_TYPE fast path.
|
|
381
|
+
const INSTANCE_TYPE = 7;
|
|
338
382
|
|
|
339
383
|
// type tag set in each collection ctor, read by typeConst (DCE: no instanceof).
|
|
340
384
|
const TYPE_TAG = Symbol('squint.lang.type');
|
|
@@ -398,7 +442,7 @@ function typeConst(obj) {
|
|
|
398
442
|
if (tag !== undefined) return tag;
|
|
399
443
|
if (isVectorArray(obj)) return ARRAY_TYPE;
|
|
400
444
|
// any remaining object (class instance, null-proto) is associative
|
|
401
|
-
if (typeof obj === 'object') return
|
|
445
|
+
if (typeof obj === 'object') return INSTANCE_TYPE;
|
|
402
446
|
|
|
403
447
|
return undefined;
|
|
404
448
|
}
|
|
@@ -407,7 +451,7 @@ function assoc_in_with(f, fname, o, keys, value) {
|
|
|
407
451
|
keys = vec(keys);
|
|
408
452
|
o = o || {}; // default nil behavior is JS object
|
|
409
453
|
const baseType = typeConst(o);
|
|
410
|
-
if (baseType !== MAP_TYPE && baseType !== ARRAY_TYPE && baseType !== OBJECT_TYPE)
|
|
454
|
+
if (baseType !== MAP_TYPE && baseType !== ARRAY_TYPE && baseType !== OBJECT_TYPE && baseType !== INSTANCE_TYPE)
|
|
411
455
|
throw new Error(
|
|
412
456
|
`Illegal argument: ${fname} expects the first argument to be a Map, Array, or Object.`
|
|
413
457
|
);
|
|
@@ -419,9 +463,12 @@ function assoc_in_with(f, fname, o, keys, value) {
|
|
|
419
463
|
const k = keys[i];
|
|
420
464
|
let chainValue;
|
|
421
465
|
if (lastInChain instanceof Map) chainValue = lastInChain.get(k);
|
|
422
|
-
else
|
|
466
|
+
else if (lastInChain != null && lastInChain[ILookup__lookup] !== undefined) {
|
|
467
|
+
chainValue = lastInChain[ILookup__lookup](lastInChain, k, undefined);
|
|
468
|
+
} else chainValue = lastInChain[k];
|
|
423
469
|
if (!chainValue) {
|
|
424
|
-
|
|
470
|
+
// an instance root has no empty-of-type: missing levels become plain maps
|
|
471
|
+
chainValue = emptyOfType(baseType) ?? {};
|
|
425
472
|
}
|
|
426
473
|
chain.push(chainValue);
|
|
427
474
|
lastInChain = chainValue;
|
|
@@ -526,6 +573,14 @@ export function conj_BANG_(...xs) {
|
|
|
526
573
|
else for (const kv of mapEntriesOf(x)) o.set(kv[0], kv[1]);
|
|
527
574
|
}
|
|
528
575
|
break;
|
|
576
|
+
case INSTANCE_TYPE:
|
|
577
|
+
if (o[ITransientCollection__conj_BANG_] !== undefined) {
|
|
578
|
+
// re-dispatch per element: a -conj! impl may return a different handle
|
|
579
|
+
let acc = o[ITransientCollection__conj_BANG_](o, rest[0]);
|
|
580
|
+
for (let i = 1; i < rest.length; i++) acc = conj_BANG_(acc, rest[i]);
|
|
581
|
+
return acc;
|
|
582
|
+
}
|
|
583
|
+
// fall through: an instance without -conj! keeps the object behavior
|
|
529
584
|
case OBJECT_TYPE:
|
|
530
585
|
for (const x of rest) {
|
|
531
586
|
if (isVectorArray(x)) { asMapEntry(x); o[x[0]] = x[1]; }
|
|
@@ -604,6 +659,14 @@ export function conj(...xs) {
|
|
|
604
659
|
yield* rest;
|
|
605
660
|
yield* o;
|
|
606
661
|
});
|
|
662
|
+
case INSTANCE_TYPE:
|
|
663
|
+
if (o[ICollection__conj] !== undefined) {
|
|
664
|
+
// re-dispatch per element: a -conj impl may return a different type
|
|
665
|
+
o2 = o[ICollection__conj](o, rest[0]);
|
|
666
|
+
for (let i = 1; i < rest.length; i++) o2 = conj(o2, rest[i]);
|
|
667
|
+
return o2;
|
|
668
|
+
}
|
|
669
|
+
// fall through: an instance without -conj keeps the object behavior
|
|
607
670
|
case OBJECT_TYPE:
|
|
608
671
|
o2 = { ...o };
|
|
609
672
|
|
|
@@ -621,6 +684,13 @@ export function conj(...xs) {
|
|
|
621
684
|
}
|
|
622
685
|
|
|
623
686
|
export function disj_BANG_(s, ...xs) {
|
|
687
|
+
if (s != null && s[ITransientSet__disjoin_BANG_] !== undefined) {
|
|
688
|
+
let ret = s;
|
|
689
|
+
for (const x of xs) {
|
|
690
|
+
ret = ret != null && ret[ITransientSet__disjoin_BANG_] !== undefined ? ret[ITransientSet__disjoin_BANG_](ret, x) : disj_BANG_(ret, x);
|
|
691
|
+
}
|
|
692
|
+
return ret;
|
|
693
|
+
}
|
|
624
694
|
for (const x of xs) {
|
|
625
695
|
s.delete(x);
|
|
626
696
|
}
|
|
@@ -629,6 +699,12 @@ export function disj_BANG_(s, ...xs) {
|
|
|
629
699
|
|
|
630
700
|
export function disj(s, ...xs) {
|
|
631
701
|
if (s == null) return s;
|
|
702
|
+
if (xs.length === 0) return s;
|
|
703
|
+
if (s[ISet__disjoin] !== undefined) {
|
|
704
|
+
let ret = s[ISet__disjoin](s, xs[0]);
|
|
705
|
+
for (let i = 1; i < xs.length; i++) ret = disj(ret, xs[i]);
|
|
706
|
+
return ret;
|
|
707
|
+
}
|
|
632
708
|
// pass s itself (not a spread) so a SortedSet keeps its comparator
|
|
633
709
|
const s1 = new s.constructor(s);
|
|
634
710
|
return copyMeta(s, disj_BANG_(s1, ...xs));
|
|
@@ -644,12 +720,22 @@ export function contains_QMARK_(coll, v) {
|
|
|
644
720
|
return coll.has(v);
|
|
645
721
|
case undefined:
|
|
646
722
|
return false;
|
|
723
|
+
case INSTANCE_TYPE:
|
|
724
|
+
if (coll[IAssociative__contains_key_QMARK_] !== undefined) {
|
|
725
|
+
return coll[IAssociative__contains_key_QMARK_](coll, v);
|
|
726
|
+
}
|
|
727
|
+
// fall through
|
|
647
728
|
default:
|
|
648
729
|
return v in coll;
|
|
649
730
|
}
|
|
650
731
|
}
|
|
651
732
|
|
|
652
733
|
export function dissoc_BANG_(m, ...ks) {
|
|
734
|
+
if (m != null && m[ITransientMap__dissoc_BANG_] !== undefined) {
|
|
735
|
+
let ret = m;
|
|
736
|
+
for (const k of ks) ret = ret != null && ret[ITransientMap__dissoc_BANG_] !== undefined ? ret[ITransientMap__dissoc_BANG_](ret, k) : dissoc_BANG_(ret, k);
|
|
737
|
+
return ret;
|
|
738
|
+
}
|
|
653
739
|
for (const k of ks) {
|
|
654
740
|
delete m[k];
|
|
655
741
|
}
|
|
@@ -661,9 +747,18 @@ export function dissoc(m, ...ks) {
|
|
|
661
747
|
if (!m) return;
|
|
662
748
|
if (ks.length === 0) return m;
|
|
663
749
|
const tc = typeConst(m);
|
|
664
|
-
if (tc !== MAP_TYPE && tc !== OBJECT_TYPE) {
|
|
750
|
+
if (tc !== MAP_TYPE && tc !== OBJECT_TYPE && tc !== INSTANCE_TYPE) {
|
|
665
751
|
throw new Error('dissoc expects a map, got: ' + typeof m);
|
|
666
752
|
}
|
|
753
|
+
if (tc === INSTANCE_TYPE && m[IMap__dissoc] !== undefined) {
|
|
754
|
+
let ret = m;
|
|
755
|
+
// re-dispatch per key: a -dissoc impl may return a different type
|
|
756
|
+
for (const k of ks) {
|
|
757
|
+
if (ret == null) return ret;
|
|
758
|
+
ret = ret[IMap__dissoc] !== undefined ? ret[IMap__dissoc](ret, k) : dissoc(ret, k);
|
|
759
|
+
}
|
|
760
|
+
return ret;
|
|
761
|
+
}
|
|
667
762
|
if (tc === MAP_TYPE) {
|
|
668
763
|
let present = false;
|
|
669
764
|
for (const k of ks) if (m.has(k)) { present = true; break; }
|
|
@@ -701,6 +796,14 @@ export function println(...args) {
|
|
|
701
796
|
if (_STAR_print_newline_STAR_.val) _STAR_print_fn_STAR_.val('\n');
|
|
702
797
|
}
|
|
703
798
|
|
|
799
|
+
export function print_str(...args) {
|
|
800
|
+
return args.map((v) => toEDN(v, undefined, false)).join(' ');
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
export function println_str(...args) {
|
|
804
|
+
return print_str(...args) + '\n';
|
|
805
|
+
}
|
|
806
|
+
|
|
704
807
|
export function pr(...xs) {
|
|
705
808
|
_STAR_print_fn_STAR_.val(pr_str(...xs));
|
|
706
809
|
}
|
|
@@ -718,6 +821,8 @@ export function nth(coll, idx, orElse) {
|
|
|
718
821
|
if (idx >= 0 && idx < coll.length) {
|
|
719
822
|
return coll[idx];
|
|
720
823
|
}
|
|
824
|
+
} else if (coll[IIndexed__nth] !== undefined) {
|
|
825
|
+
return hasDefault ? coll[IIndexed__nth](coll, idx, orElse) : coll[IIndexed__nth](coll, idx);
|
|
721
826
|
} else if (idx >= 0) {
|
|
722
827
|
// non-array: skip whole chunks instead of counting elements (handles
|
|
723
828
|
// infinite seqs since it stops once idx is reached)
|
|
@@ -760,6 +865,10 @@ export function get(coll, key, otherwise = undefined) {
|
|
|
760
865
|
v = coll[key];
|
|
761
866
|
break;
|
|
762
867
|
default:
|
|
868
|
+
if (coll[ILookup__lookup] !== undefined) {
|
|
869
|
+
v = coll[ILookup__lookup](coll, key, otherwise);
|
|
870
|
+
return v === undefined ? otherwise : v;
|
|
871
|
+
}
|
|
763
872
|
// we choose .get as the default implementation, e.g. fetch Headers are not Maps, but do implement a .get method
|
|
764
873
|
g = coll['get'];
|
|
765
874
|
if (typeof g === 'function') {
|
|
@@ -783,7 +892,7 @@ export function seq_QMARK_(x) {
|
|
|
783
892
|
export function sequential_QMARK_(x) {
|
|
784
893
|
// vectors and lists are arrays; lazy seqs and cons carry the lazy brand.
|
|
785
894
|
// Sets, maps and strings are iterable but not sequential.
|
|
786
|
-
return Array.isArray(x) || x?.[TYPE_TAG] === LAZY_ITERABLE_TYPE;
|
|
895
|
+
return Array.isArray(x) || x?.[TYPE_TAG] === LAZY_ITERABLE_TYPE || (x != null && x[IVector.__sym] !== undefined);
|
|
787
896
|
}
|
|
788
897
|
|
|
789
898
|
export function seqable_QMARK_(x) {
|
|
@@ -828,7 +937,10 @@ export function iterable(x) {
|
|
|
828
937
|
}
|
|
829
938
|
// a type extended to ISeqable seqs through its -seq method
|
|
830
939
|
if (x[ISeqable__seq] !== undefined) return iterable(x[ISeqable__seq](x));
|
|
831
|
-
|
|
940
|
+
// only a plain object is a squint map; a class instance without a native
|
|
941
|
+
// iterator or ISeqable is not iterable, matching seqable? and CLJS, and
|
|
942
|
+
// never leaks its internal fields
|
|
943
|
+
if (isObj(x)) return Object.entries(x).map(tagMapEntry);
|
|
832
944
|
throw new TypeError(`${x} is not iterable`);
|
|
833
945
|
}
|
|
834
946
|
|
|
@@ -852,10 +964,19 @@ export function seq(x) {
|
|
|
852
964
|
if (iter.length === 0 || iter.size === 0) {
|
|
853
965
|
return null;
|
|
854
966
|
}
|
|
855
|
-
// a set is iterable but not
|
|
967
|
+
// a set or map is iterable but not a sequence; materialize its entries
|
|
968
|
+
// into a distinct seq so the result is not itself a set or map, like CLJS
|
|
856
969
|
if (iter instanceof Set || iter[TYPE_TAG] === SET_TYPE) {
|
|
857
970
|
return [...iter];
|
|
858
971
|
}
|
|
972
|
+
if (iter instanceof Map || iter[TYPE_TAG] === MAP_TYPE) {
|
|
973
|
+
return [...iter].map(tagMapEntry);
|
|
974
|
+
}
|
|
975
|
+
// an instance with -dissoc is a map rep: same distinct entry seq
|
|
976
|
+
if (iter[IMap__dissoc] !== undefined) {
|
|
977
|
+
const entries = [...iter].map(tagMapEntry);
|
|
978
|
+
return entries.length === 0 ? null : entries;
|
|
979
|
+
}
|
|
859
980
|
const _i = iter[Symbol.iterator]();
|
|
860
981
|
if (_i.next().done) return null;
|
|
861
982
|
return iter;
|
|
@@ -888,6 +1009,14 @@ export function ffirst(coll) {
|
|
|
888
1009
|
return first(first(coll));
|
|
889
1010
|
}
|
|
890
1011
|
|
|
1012
|
+
export function fnext(coll) {
|
|
1013
|
+
return first(next(coll));
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
export function nfirst(coll) {
|
|
1017
|
+
return next(first(coll));
|
|
1018
|
+
}
|
|
1019
|
+
|
|
891
1020
|
export function rest(coll) {
|
|
892
1021
|
// chunk-aware: drop the first element of the first chunk, keep the rest of
|
|
893
1022
|
// the chain chunked (preserves chunkedness, unlike re-iterating element-wise)
|
|
@@ -1285,6 +1414,13 @@ export function filterv(pred, coll) {
|
|
|
1285
1414
|
return pushAll([], filter(pred, coll));
|
|
1286
1415
|
}
|
|
1287
1416
|
|
|
1417
|
+
export function random_sample(prob, coll) {
|
|
1418
|
+
if (arguments.length === 1) {
|
|
1419
|
+
return filter((_) => rand() < prob);
|
|
1420
|
+
}
|
|
1421
|
+
return filter((_) => rand() < prob, coll);
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1288
1424
|
export function remove(pred, coll) {
|
|
1289
1425
|
if (arguments.length === 1) {
|
|
1290
1426
|
return filter1(complement(pred));
|
|
@@ -1382,10 +1518,326 @@ export function _deref(o) {
|
|
|
1382
1518
|
}
|
|
1383
1519
|
export const ISeqable = { __sym: ISEQABLE_SYM };
|
|
1384
1520
|
export const ISeqable__seq = Symbol('ISeqable_-seq');
|
|
1521
|
+
|
|
1522
|
+
// map-facing protocols. Each dispatches through its slot in the extension
|
|
1523
|
+
// path (INSTANCE_TYPE) of the corresponding core fn, so plain objects and
|
|
1524
|
+
// arrays never pay for them. Slot symbols are separate consts so a bundle
|
|
1525
|
+
// using only e.g. conj pulls one symbol, not the whole protocol set.
|
|
1526
|
+
export const ILookup = { __sym: Symbol('squint.core.ILookup') };
|
|
1527
|
+
export const ILookup__lookup = Symbol('ILookup_-lookup');
|
|
1528
|
+
export const IAssociative = { __sym: Symbol('squint.core.IAssociative') };
|
|
1529
|
+
export const IAssociative__assoc = Symbol('IAssociative_-assoc');
|
|
1530
|
+
export const IAssociative__contains_key_QMARK_ = Symbol('IAssociative_-contains-key?');
|
|
1531
|
+
export const IMap = { __sym: Symbol('squint.core.IMap') };
|
|
1532
|
+
export const IMap__dissoc = Symbol('IMap_-dissoc');
|
|
1533
|
+
export const ICounted = { __sym: Symbol('squint.core.ICounted') };
|
|
1534
|
+
export const ICounted__count = Symbol('ICounted_-count');
|
|
1535
|
+
export const IKVReduce = { __sym: Symbol('squint.core.IKVReduce') };
|
|
1536
|
+
export const IKVReduce__kv_reduce = Symbol('IKVReduce_-kv-reduce');
|
|
1537
|
+
export const ICollection = { __sym: Symbol('squint.core.ICollection') };
|
|
1538
|
+
export const ICollection__conj = Symbol('ICollection_-conj');
|
|
1539
|
+
export const IEmptyableCollection = { __sym: Symbol('squint.core.IEmptyableCollection') };
|
|
1540
|
+
export const IEmptyableCollection__empty = Symbol('IEmptyableCollection_-empty');
|
|
1541
|
+
export const IEquiv = { __sym: Symbol('squint.core.IEquiv') };
|
|
1542
|
+
export const IEquiv__equiv = Symbol('IEquiv_-equiv');
|
|
1543
|
+
// set and transient protocols, same extension-path dispatch as the map-facing
|
|
1544
|
+
// protocols above
|
|
1545
|
+
export const ISet = { __sym: Symbol('squint.core.ISet') };
|
|
1546
|
+
export const ISet__disjoin = Symbol('ISet_-disjoin');
|
|
1547
|
+
export const IEditableCollection = { __sym: Symbol('squint.core.IEditableCollection') };
|
|
1548
|
+
export const IEditableCollection__as_transient = Symbol('IEditableCollection_-as-transient');
|
|
1549
|
+
export const ITransientCollection = { __sym: Symbol('squint.core.ITransientCollection') };
|
|
1550
|
+
export const ITransientCollection__conj_BANG_ = Symbol('ITransientCollection_-conj!');
|
|
1551
|
+
export const ITransientCollection__persistent_BANG_ = Symbol('ITransientCollection_-persistent!');
|
|
1552
|
+
export const ITransientAssociative = { __sym: Symbol('squint.core.ITransientAssociative') };
|
|
1553
|
+
export const ITransientAssociative__assoc_BANG_ = Symbol('ITransientAssociative_-assoc!');
|
|
1554
|
+
export const ITransientMap = { __sym: Symbol('squint.core.ITransientMap') };
|
|
1555
|
+
export const ITransientMap__dissoc_BANG_ = Symbol('ITransientMap_-dissoc!');
|
|
1556
|
+
export const ITransientSet = { __sym: Symbol('squint.core.ITransientSet') };
|
|
1557
|
+
export const ITransientSet__disjoin_BANG_ = Symbol('ITransientSet_-disjoin!');
|
|
1558
|
+
// metadata protocols, like CLJS: types implement the slots, plain values
|
|
1559
|
+
// get instance-level impls installed by with-meta
|
|
1560
|
+
export const IMeta = { __sym: Symbol('squint.core.IMeta') };
|
|
1561
|
+
export const IMeta__meta = Symbol('IMeta_-meta');
|
|
1562
|
+
export const IWithMeta = { __sym: Symbol('squint.core.IWithMeta') };
|
|
1563
|
+
export const IWithMeta__with_meta = Symbol('IWithMeta_-with-meta');
|
|
1564
|
+
// hashing (Murmur3, like CLJS). The contract: (= a b) implies (hash a) ===
|
|
1565
|
+
// (hash b), where = is dequal. None of this is referenced by =, so bundles
|
|
1566
|
+
// that only compare pay nothing.
|
|
1567
|
+
// Ported from ClojureScript (cljs/core.cljs), Copyright (c) Rich Hickey and
|
|
1568
|
+
// contributors, Eclipse Public License 1.0. MurmurHash3 by Austin Appleby
|
|
1569
|
+
// (public domain).
|
|
1570
|
+
|
|
1571
|
+
// IHash: a custom type opts into value hashing
|
|
1572
|
+
export const IHash = { __sym: Symbol('squint.core.IHash') };
|
|
1573
|
+
export const IHash__hash = Symbol('IHash_-hash');
|
|
1574
|
+
|
|
1575
|
+
// the equality hashed collections key by: identical or -equiv, never a
|
|
1576
|
+
// deep compare like =
|
|
1577
|
+
export function equiv(x, y) {
|
|
1578
|
+
if (x === y) return true;
|
|
1579
|
+
if (x == null) return y == null;
|
|
1580
|
+
if (y == null) return false;
|
|
1581
|
+
if (x[IEquiv__equiv] !== undefined) return !!x[IEquiv__equiv](x, y);
|
|
1582
|
+
if (y[IEquiv__equiv] !== undefined) return !!y[IEquiv__equiv](y, x);
|
|
1583
|
+
if (x instanceof Date && y instanceof Date) return x.getTime() === y.getTime();
|
|
1584
|
+
return false;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
// identity uid for reference-keyed values, like CLJS goog/getUid
|
|
1588
|
+
const UIDS = /* @__PURE__ */ new WeakMap();
|
|
1589
|
+
let uidCounter = 0;
|
|
1590
|
+
|
|
1591
|
+
function uid(o) {
|
|
1592
|
+
let id = UIDS.get(o);
|
|
1593
|
+
if (id === undefined) {
|
|
1594
|
+
id = ++uidCounter;
|
|
1595
|
+
UIDS.set(o, id);
|
|
1596
|
+
}
|
|
1597
|
+
return id;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
const imul = Math.imul;
|
|
1601
|
+
const M3_C1 = 0xcc9e2d51 | 0;
|
|
1602
|
+
const M3_C2 = 0x1b873593 | 0;
|
|
1603
|
+
|
|
1604
|
+
function rotl(x, n) {
|
|
1605
|
+
return (x << n) | (x >>> (32 - n));
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
function m3MixK1(k1) {
|
|
1609
|
+
return imul(rotl(imul(k1 | 0, M3_C1), 15), M3_C2);
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
function m3MixH1(h1, k1) {
|
|
1613
|
+
return (imul(rotl((h1 | 0) ^ (k1 | 0), 13), 5) + (0xe6546b64 | 0)) | 0;
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
function m3Fmix(h1, len) {
|
|
1617
|
+
h1 = (h1 ^ len) | 0;
|
|
1618
|
+
h1 = (h1 ^ (h1 >>> 16)) | 0;
|
|
1619
|
+
h1 = imul(h1, 0x85ebca6b | 0);
|
|
1620
|
+
h1 = (h1 ^ (h1 >>> 13)) | 0;
|
|
1621
|
+
h1 = imul(h1, 0xc2b2ae35 | 0);
|
|
1622
|
+
return (h1 ^ (h1 >>> 16)) | 0;
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
function m3HashInt(x) {
|
|
1626
|
+
return x === 0 ? 0 : m3Fmix(m3MixH1(0, m3MixK1(x)), 4);
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
let stringHashCache = /* @__PURE__ */ Object.create(null);
|
|
1630
|
+
let stringHashCacheCount = 0;
|
|
1631
|
+
|
|
1632
|
+
function hashStringRaw(s) {
|
|
1633
|
+
let h = 0;
|
|
1634
|
+
for (let i = 0; i < s.length; i++) h = (imul(31, h) + s.charCodeAt(i)) | 0;
|
|
1635
|
+
return h;
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
function hashString(s) {
|
|
1639
|
+
if (stringHashCacheCount > 8192) {
|
|
1640
|
+
stringHashCache = Object.create(null);
|
|
1641
|
+
stringHashCacheCount = 0;
|
|
1642
|
+
}
|
|
1643
|
+
let h = stringHashCache[s];
|
|
1644
|
+
if (typeof h !== 'number') {
|
|
1645
|
+
h = hashStringRaw(s);
|
|
1646
|
+
stringHashCache[s] = h;
|
|
1647
|
+
stringHashCacheCount++;
|
|
1648
|
+
}
|
|
1649
|
+
return h;
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
// one IIFE, not two consts: `new Int32Array(F64.buffer)` reads a property,
|
|
1653
|
+
// which pins F64 into bundles even under a pure annotation
|
|
1654
|
+
const HASH_BUF = /* @__PURE__ */ (() => {
|
|
1655
|
+
const f64 = new Float64Array(1);
|
|
1656
|
+
return { f64, i32: new Int32Array(f64.buffer) };
|
|
1657
|
+
})();
|
|
1658
|
+
|
|
1659
|
+
function hashDouble(n) {
|
|
1660
|
+
HASH_BUF.f64[0] = n;
|
|
1661
|
+
return (HASH_BUF.i32[0] ^ HASH_BUF.i32[1]) | 0;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
function mixCollectionHash(hashBasis, count) {
|
|
1665
|
+
return m3Fmix(m3MixH1(0, m3MixK1(hashBasis)), count);
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
export function hash_ordered_coll(coll) {
|
|
1669
|
+
let n = 0;
|
|
1670
|
+
let h = 1;
|
|
1671
|
+
for (const x of coll) {
|
|
1672
|
+
h = (imul(31, h) + hash(x)) | 0;
|
|
1673
|
+
n++;
|
|
1674
|
+
}
|
|
1675
|
+
return mixCollectionHash(h, n);
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
export function hash_unordered_coll(coll) {
|
|
1679
|
+
let n = 0;
|
|
1680
|
+
let h = 0;
|
|
1681
|
+
for (const x of coll) {
|
|
1682
|
+
h = (h + hash(x)) | 0;
|
|
1683
|
+
n++;
|
|
1684
|
+
}
|
|
1685
|
+
return mixCollectionHash(h, n);
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
// a map entry hashes as (hash-ordered-coll [k v])
|
|
1689
|
+
function hashEntry(k, v) {
|
|
1690
|
+
return mixCollectionHash((imul(31, (imul(31, 1) + hash(k)) | 0) + hash(v)) | 0, 2);
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
function hashMapEntries(entries) {
|
|
1694
|
+
let n = 0;
|
|
1695
|
+
let h = 0;
|
|
1696
|
+
for (const [k, v] of entries) {
|
|
1697
|
+
h = (h + hashEntry(k, v)) | 0;
|
|
1698
|
+
n++;
|
|
1699
|
+
}
|
|
1700
|
+
return mixCollectionHash(h, n);
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
// (equiv a b) implies (hash a) === (hash b): plain mutable data hashes by
|
|
1704
|
+
// uid, a type with -equiv but no -hash gets a structural entry hash
|
|
1705
|
+
export function hash(o) {
|
|
1706
|
+
if (o == null) return 0;
|
|
1707
|
+
switch (typeof o) {
|
|
1708
|
+
case 'number':
|
|
1709
|
+
if (Number.isFinite(o)) {
|
|
1710
|
+
return Number.isSafeInteger(o) ? o % 2147483647 | 0 : hashDouble(o);
|
|
1711
|
+
}
|
|
1712
|
+
if (o === Infinity) return 2146435072;
|
|
1713
|
+
if (o === -Infinity) return -1048576;
|
|
1714
|
+
return 2146959360; // NaN
|
|
1715
|
+
case 'boolean':
|
|
1716
|
+
return o ? 1231 : 1237;
|
|
1717
|
+
case 'string':
|
|
1718
|
+
return m3HashInt(hashString(o));
|
|
1719
|
+
case 'bigint':
|
|
1720
|
+
return Number(o % 2147483647n) | 0;
|
|
1721
|
+
case 'function':
|
|
1722
|
+
return uid(o) | 0;
|
|
1723
|
+
case 'object':
|
|
1724
|
+
break;
|
|
1725
|
+
default:
|
|
1726
|
+
// JS symbols compare by identity; a constant hash is consistent
|
|
1727
|
+
return 0;
|
|
1728
|
+
}
|
|
1729
|
+
if (o[IHash__hash] !== undefined) return o[IHash__hash](o) | 0;
|
|
1730
|
+
if (o instanceof Date) return o.valueOf() | 0;
|
|
1731
|
+
if (o[IEquiv__equiv] !== undefined) return hashMapEntries(Object.entries(o));
|
|
1732
|
+
return uid(o) | 0;
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
// printing protocols, like CLJS: a type prints itself through
|
|
1736
|
+
// (-pr-writer [obj writer opts]), writing strings via (-write writer s)
|
|
1737
|
+
export const IWriter = { __sym: Symbol('squint.core.IWriter') };
|
|
1738
|
+
export const IWriter__write = Symbol('IWriter_-write');
|
|
1739
|
+
export const IPrintWithWriter = { __sym: Symbol('squint.core.IPrintWithWriter') };
|
|
1740
|
+
export const IPrintWithWriter__pr_writer = Symbol('IPrintWithWriter_-pr-writer');
|
|
1741
|
+
export function _write(writer, s) {
|
|
1742
|
+
if (writer != null && writer[IWriter__write] !== undefined) return writer[IWriter__write](writer, s);
|
|
1743
|
+
return nilImpl(_write, 'IWriter.-write', writer)(writer, s);
|
|
1744
|
+
}
|
|
1745
|
+
export function write_all(writer, ...ss) {
|
|
1746
|
+
for (const s of ss) _write(writer, s);
|
|
1747
|
+
}
|
|
1748
|
+
// vector-facing protocols, dispatched like the map-facing set above
|
|
1749
|
+
export const IStack = { __sym: Symbol('squint.core.IStack') };
|
|
1750
|
+
export const IStack__peek = Symbol('IStack_-peek');
|
|
1751
|
+
export const IStack__pop = Symbol('IStack_-pop');
|
|
1752
|
+
export const IIndexed = { __sym: Symbol('squint.core.IIndexed') };
|
|
1753
|
+
export const IIndexed__nth = Symbol('IIndexed_-nth');
|
|
1754
|
+
export const ITransientVector = { __sym: Symbol('squint.core.ITransientVector') };
|
|
1755
|
+
export const ITransientVector__pop_BANG_ = Symbol('ITransientVector_-pop!');
|
|
1756
|
+
// marker protocol: a non-array type that counts as a vector (vector?,
|
|
1757
|
+
// sequential?, vec, subvec route through it)
|
|
1758
|
+
export const IVector = { __sym: Symbol('squint.core.IVector') };
|
|
1759
|
+
// a type converts itself in clj->js through this slot, like CLJS IEncodeJS;
|
|
1760
|
+
// the impl receives (x, recur) with recur a cycle-safe clj->js
|
|
1761
|
+
export const IEncodeJS = { __sym: Symbol('squint.core.IEncodeJS') };
|
|
1762
|
+
export const IEncodeJS__clj__GT_js = Symbol('IEncodeJS_-clj->js');
|
|
1763
|
+
// marker protocol set by defrecord
|
|
1764
|
+
export const IRecord = { __sym: Symbol('squint.core.IRecord') };
|
|
1765
|
+
|
|
1766
|
+
export function record_QMARK_(x) {
|
|
1767
|
+
return x != null && x[IRecord.__sym] !== undefined;
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
// The protocol-method fns below share one shape but stay hand-written on
|
|
1771
|
+
// purpose: a shared factory makes V8 share type feedback across all of them,
|
|
1772
|
+
// turning every slot access megamorphic (measured 1.8 -> 11 ns per call).
|
|
1773
|
+
export function _lookup(o, k, nf) {
|
|
1774
|
+
if (o != null && o[ILookup__lookup] !== undefined) return o[ILookup__lookup](o, k, nf);
|
|
1775
|
+
return nilImpl(_lookup, 'ILookup.-lookup', o)(o, k, nf);
|
|
1776
|
+
}
|
|
1777
|
+
export function _assoc(o, k, v) {
|
|
1778
|
+
if (o != null && o[IAssociative__assoc] !== undefined) return o[IAssociative__assoc](o, k, v);
|
|
1779
|
+
return nilImpl(_assoc, 'IAssociative.-assoc', o)(o, k, v);
|
|
1780
|
+
}
|
|
1781
|
+
export function _contains_key_QMARK_(o, k) {
|
|
1782
|
+
if (o != null && o[IAssociative__contains_key_QMARK_] !== undefined) return o[IAssociative__contains_key_QMARK_](o, k);
|
|
1783
|
+
return nilImpl(_contains_key_QMARK_, 'IAssociative.-contains-key?', o)(o, k);
|
|
1784
|
+
}
|
|
1785
|
+
export function _dissoc(o, k) {
|
|
1786
|
+
if (o != null && o[IMap__dissoc] !== undefined) return o[IMap__dissoc](o, k);
|
|
1787
|
+
return nilImpl(_dissoc, 'IMap.-dissoc', o)(o, k);
|
|
1788
|
+
}
|
|
1789
|
+
export function _count(o) {
|
|
1790
|
+
if (o != null && o[ICounted__count] !== undefined) return o[ICounted__count](o);
|
|
1791
|
+
return nilImpl(_count, 'ICounted.-count', o)(o);
|
|
1792
|
+
}
|
|
1793
|
+
export function _kv_reduce(o, f, init) {
|
|
1794
|
+
if (o != null && o[IKVReduce__kv_reduce] !== undefined) return o[IKVReduce__kv_reduce](o, f, init);
|
|
1795
|
+
return nilImpl(_kv_reduce, 'IKVReduce.-kv-reduce', o)(o, f, init);
|
|
1796
|
+
}
|
|
1797
|
+
export function _conj(o, x) {
|
|
1798
|
+
if (o != null && o[ICollection__conj] !== undefined) return o[ICollection__conj](o, x);
|
|
1799
|
+
return nilImpl(_conj, 'ICollection.-conj', o)(o, x);
|
|
1800
|
+
}
|
|
1801
|
+
export function _empty(o) {
|
|
1802
|
+
if (o != null && o[IEmptyableCollection__empty] !== undefined) return o[IEmptyableCollection__empty](o);
|
|
1803
|
+
return nilImpl(_empty, 'IEmptyableCollection.-empty', o)(o);
|
|
1804
|
+
}
|
|
1805
|
+
export function _equiv(o, other) {
|
|
1806
|
+
if (o != null && o[IEquiv__equiv] !== undefined) return o[IEquiv__equiv](o, other);
|
|
1807
|
+
return nilImpl(_equiv, 'IEquiv.-equiv', o)(o, other);
|
|
1808
|
+
}
|
|
1385
1809
|
export function _seq(o) {
|
|
1386
1810
|
if (o != null && o[ISeqable__seq] !== undefined) return o[ISeqable__seq](o);
|
|
1387
1811
|
return nilImpl(_seq, 'ISeqable.-seq', o)(o);
|
|
1388
1812
|
}
|
|
1813
|
+
export function _disjoin(o, x) {
|
|
1814
|
+
if (o != null && o[ISet__disjoin] !== undefined) return o[ISet__disjoin](o, x);
|
|
1815
|
+
return nilImpl(_disjoin, 'ISet.-disjoin', o)(o, x);
|
|
1816
|
+
}
|
|
1817
|
+
export function _as_transient(o) {
|
|
1818
|
+
if (o != null && o[IEditableCollection__as_transient] !== undefined) return o[IEditableCollection__as_transient](o);
|
|
1819
|
+
return nilImpl(_as_transient, 'IEditableCollection.-as-transient', o)(o);
|
|
1820
|
+
}
|
|
1821
|
+
export function _conj_BANG_(o, x) {
|
|
1822
|
+
if (o != null && o[ITransientCollection__conj_BANG_] !== undefined) return o[ITransientCollection__conj_BANG_](o, x);
|
|
1823
|
+
return nilImpl(_conj_BANG_, 'ITransientCollection.-conj!', o)(o, x);
|
|
1824
|
+
}
|
|
1825
|
+
export function _persistent_BANG_(o) {
|
|
1826
|
+
if (o != null && o[ITransientCollection__persistent_BANG_] !== undefined) return o[ITransientCollection__persistent_BANG_](o);
|
|
1827
|
+
return nilImpl(_persistent_BANG_, 'ITransientCollection.-persistent!', o)(o);
|
|
1828
|
+
}
|
|
1829
|
+
export function _assoc_BANG_(o, k, v) {
|
|
1830
|
+
if (o != null && o[ITransientAssociative__assoc_BANG_] !== undefined) return o[ITransientAssociative__assoc_BANG_](o, k, v);
|
|
1831
|
+
return nilImpl(_assoc_BANG_, 'ITransientAssociative.-assoc!', o)(o, k, v);
|
|
1832
|
+
}
|
|
1833
|
+
export function _dissoc_BANG_(o, k) {
|
|
1834
|
+
if (o != null && o[ITransientMap__dissoc_BANG_] !== undefined) return o[ITransientMap__dissoc_BANG_](o, k);
|
|
1835
|
+
return nilImpl(_dissoc_BANG_, 'ITransientMap.-dissoc!', o)(o, k);
|
|
1836
|
+
}
|
|
1837
|
+
export function _disjoin_BANG_(o, x) {
|
|
1838
|
+
if (o != null && o[ITransientSet__disjoin_BANG_] !== undefined) return o[ITransientSet__disjoin_BANG_](o, x);
|
|
1839
|
+
return nilImpl(_disjoin_BANG_, 'ITransientSet.-disjoin!', o)(o, x);
|
|
1840
|
+
}
|
|
1389
1841
|
|
|
1390
1842
|
// an extend-type on nil stores the impl on the dispatch fn under null,
|
|
1391
1843
|
// the same convention the generated protocol dispatch fns use
|
|
@@ -1481,7 +1933,11 @@ export class Atom {
|
|
|
1481
1933
|
export function atom(init, ...opts) {
|
|
1482
1934
|
const a = new Atom(init);
|
|
1483
1935
|
for (let i = 0; i < opts.length; i += 2) {
|
|
1484
|
-
|
|
1936
|
+
// IMeta only, like CLJS Atom: keeps with-meta's copy machinery out of atom-only bundles
|
|
1937
|
+
if (opts[i] === 'meta') {
|
|
1938
|
+
const mv = opts[i + 1];
|
|
1939
|
+
a[IMeta__meta] = () => mv;
|
|
1940
|
+
}
|
|
1485
1941
|
else if (opts[i] === 'validator') a._validator = opts[i + 1];
|
|
1486
1942
|
}
|
|
1487
1943
|
return a;
|
|
@@ -1636,6 +2092,21 @@ export function re_pattern(s) {
|
|
|
1636
2092
|
}
|
|
1637
2093
|
|
|
1638
2094
|
export function subvec(arr, start, end) {
|
|
2095
|
+
// an IVector type slices through its own slots (bounds-checked nth + conj)
|
|
2096
|
+
if (arr != null && arr[IVector.__sym] !== undefined) {
|
|
2097
|
+
if (end === undefined) end = _count(arr);
|
|
2098
|
+
if (start == null || end == null) {
|
|
2099
|
+
throw new Error('subvec: start and end must not be nil');
|
|
2100
|
+
}
|
|
2101
|
+
start = start | 0;
|
|
2102
|
+
end = end | 0;
|
|
2103
|
+
if (start < 0 || end < start || end > _count(arr)) {
|
|
2104
|
+
throw new Error('subvec: index out of bounds');
|
|
2105
|
+
}
|
|
2106
|
+
let ret = arr[IEmptyableCollection__empty](arr);
|
|
2107
|
+
for (let i = start; i < end; i++) ret = ret[ICollection__conj](ret, arr[IIndexed__nth](arr, i));
|
|
2108
|
+
return ret;
|
|
2109
|
+
}
|
|
1639
2110
|
if (!isVectorArray(arr)) {
|
|
1640
2111
|
throw new Error('subvec: argument must be a vector');
|
|
1641
2112
|
}
|
|
@@ -1659,7 +2130,8 @@ export function vector(...args) {
|
|
|
1659
2130
|
export const array = vector;
|
|
1660
2131
|
|
|
1661
2132
|
export function vector_QMARK_(x) {
|
|
1662
|
-
|
|
2133
|
+
if (x == null) return false;
|
|
2134
|
+
return isVectorArray(x) || x[IVector.__sym] !== undefined;
|
|
1663
2135
|
}
|
|
1664
2136
|
|
|
1665
2137
|
export function mapv(...args) {
|
|
@@ -1713,6 +2185,7 @@ function toArray(coll) {
|
|
|
1713
2185
|
|
|
1714
2186
|
export function vec(x) {
|
|
1715
2187
|
if (isVectorArray(x)) return x;
|
|
2188
|
+
if (x != null && x[IVector.__sym] !== undefined) return x;
|
|
1716
2189
|
return pushAll([], x);
|
|
1717
2190
|
}
|
|
1718
2191
|
|
|
@@ -1721,7 +2194,8 @@ export function set(coll) {
|
|
|
1721
2194
|
}
|
|
1722
2195
|
|
|
1723
2196
|
export function set_QMARK_(x) {
|
|
1724
|
-
|
|
2197
|
+
if (x == null) return false;
|
|
2198
|
+
return typeConst(x) === SET_TYPE || x[ISet.__sym] !== undefined;
|
|
1725
2199
|
}
|
|
1726
2200
|
|
|
1727
2201
|
export function hash_set(...xs) {
|
|
@@ -1736,6 +2210,12 @@ export function char_QMARK_(x) {
|
|
|
1736
2210
|
return typeof x === 'string' && x.length === 1;
|
|
1737
2211
|
}
|
|
1738
2212
|
|
|
2213
|
+
export function char$(x) {
|
|
2214
|
+
if (typeof x === 'string' && x.length === 1) return x;
|
|
2215
|
+
if (typeof x === 'number') return String.fromCharCode(x);
|
|
2216
|
+
throw new Error('Argument to char must be a character or number: ' + x);
|
|
2217
|
+
}
|
|
2218
|
+
|
|
1739
2219
|
export function apply(f, ...args) {
|
|
1740
2220
|
f = __toFn(f);
|
|
1741
2221
|
const xs = args.slice(0, args.length - 1);
|
|
@@ -2110,9 +2590,12 @@ export function partition_by(f, coll) {
|
|
|
2110
2590
|
export function empty(coll) {
|
|
2111
2591
|
const type = typeConst(coll);
|
|
2112
2592
|
if (type != null) {
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2593
|
+
if (type === INSTANCE_TYPE) {
|
|
2594
|
+
if (coll[IEmptyableCollection__empty] !== undefined) return coll[IEmptyableCollection__empty](coll);
|
|
2595
|
+
// a null-prototype object is a map rep; any other instance is not an
|
|
2596
|
+
// emptyable collection, like CLJS
|
|
2597
|
+
return coll.constructor === undefined ? copyMeta(coll, {}) : null;
|
|
2598
|
+
}
|
|
2116
2599
|
return copyMeta(coll, emptyOfType(type));
|
|
2117
2600
|
}
|
|
2118
2601
|
// non-collections give nil, like CLJS
|
|
@@ -2130,9 +2613,22 @@ export function merge(...args) {
|
|
|
2130
2613
|
} else if (typeConst(firstArg) === undefined) {
|
|
2131
2614
|
// a non-collection passes through; conj! throws when maps follow, like CLJS
|
|
2132
2615
|
obj = firstArg;
|
|
2616
|
+
} else if (firstArg[ICollection__conj] !== undefined) {
|
|
2617
|
+
// a -conj type is immutable: no defensive copy needed, and a record has
|
|
2618
|
+
// no empty to rebuild from
|
|
2619
|
+
obj = firstArg;
|
|
2133
2620
|
} else {
|
|
2134
2621
|
obj = into(empty(firstArg), firstArg);
|
|
2135
2622
|
}
|
|
2623
|
+
// an ICollection target merges through -conj instead of mutation
|
|
2624
|
+
if (obj != null && obj[ICollection__conj] !== undefined) {
|
|
2625
|
+
for (let i = 1; i < args.length; i++) {
|
|
2626
|
+
obj = obj != null && obj[ICollection__conj] !== undefined
|
|
2627
|
+
? obj[ICollection__conj](obj, args[i])
|
|
2628
|
+
: conj_BANG_(obj, args[i]);
|
|
2629
|
+
}
|
|
2630
|
+
return obj;
|
|
2631
|
+
}
|
|
2136
2632
|
return conj_BANG_(obj, ...args.slice(1));
|
|
2137
2633
|
}
|
|
2138
2634
|
|
|
@@ -2190,17 +2686,31 @@ export function into(...args) {
|
|
|
2190
2686
|
if (isVectorArray(to)) {
|
|
2191
2687
|
return pushAll(copy(to), args[1]);
|
|
2192
2688
|
}
|
|
2689
|
+
// a type with -conj is immutable: fold through the slot instead of
|
|
2690
|
+
// mutating a copy. Direct slot calls keep conj out of the bundle.
|
|
2691
|
+
if (to[ICollection__conj] !== undefined) {
|
|
2692
|
+
return reduce(
|
|
2693
|
+
(acc, x) =>
|
|
2694
|
+
acc != null && acc[ICollection__conj] !== undefined
|
|
2695
|
+
? acc[ICollection__conj](acc, x)
|
|
2696
|
+
: conj_BANG_(acc, x),
|
|
2697
|
+
to,
|
|
2698
|
+
args[1]
|
|
2699
|
+
);
|
|
2700
|
+
}
|
|
2193
2701
|
return reduce(conj_BANG_, copy(to), args[1]);
|
|
2194
2702
|
case 3:
|
|
2195
2703
|
to = args[0];
|
|
2196
2704
|
xform = args[1];
|
|
2197
2705
|
from = args[2];
|
|
2198
|
-
c = copy(to);
|
|
2706
|
+
c = to != null && to[ICollection__conj] !== undefined ? to : copy(to);
|
|
2199
2707
|
rf = (coll, v) => {
|
|
2200
2708
|
if (v === undefined) {
|
|
2201
2709
|
return coll;
|
|
2202
2710
|
}
|
|
2203
|
-
return
|
|
2711
|
+
return coll != null && coll[ICollection__conj] !== undefined
|
|
2712
|
+
? coll[ICollection__conj](coll, v)
|
|
2713
|
+
: conj_BANG_(coll, v);
|
|
2204
2714
|
};
|
|
2205
2715
|
return transduce(xform, rf, c, from);
|
|
2206
2716
|
default:
|
|
@@ -2531,6 +3041,10 @@ export function reverse(coll) {
|
|
|
2531
3041
|
return toArray(coll).reverse();
|
|
2532
3042
|
}
|
|
2533
3043
|
|
|
3044
|
+
export function reversible_QMARK_(x) {
|
|
3045
|
+
return isVectorArray(x) || (x != null && x[SORTED_TAG] === true);
|
|
3046
|
+
}
|
|
3047
|
+
|
|
2534
3048
|
export function rseq(x) {
|
|
2535
3049
|
// vectors and sorted maps/sets are reversible, like CLJS
|
|
2536
3050
|
if (isVectorArray(x)) {
|
|
@@ -2744,6 +3258,7 @@ export function count(coll) {
|
|
|
2744
3258
|
if (typeof len === 'number') {
|
|
2745
3259
|
return len;
|
|
2746
3260
|
}
|
|
3261
|
+
if (coll[ICounted__count] !== undefined) return coll[ICounted__count](coll);
|
|
2747
3262
|
// sum chunk lengths instead of counting elements one by one
|
|
2748
3263
|
const next = chunkCursor(coll);
|
|
2749
3264
|
let ret = 0;
|
|
@@ -2768,6 +3283,15 @@ export function boolean$(x) {
|
|
|
2768
3283
|
return truth_(x);
|
|
2769
3284
|
}
|
|
2770
3285
|
|
|
3286
|
+
export function parse_boolean(s) {
|
|
3287
|
+
if (typeof s !== 'string') {
|
|
3288
|
+
throw new Error('Argument must be a string');
|
|
3289
|
+
}
|
|
3290
|
+
if (s === 'true') return true;
|
|
3291
|
+
if (s === 'false') return false;
|
|
3292
|
+
return null;
|
|
3293
|
+
}
|
|
3294
|
+
|
|
2771
3295
|
export function zero_QMARK_(x) {
|
|
2772
3296
|
return x === 0;
|
|
2773
3297
|
}
|
|
@@ -2894,6 +3418,7 @@ export function reduce_kv(f, init, m) {
|
|
|
2894
3418
|
if (!m) {
|
|
2895
3419
|
return init;
|
|
2896
3420
|
}
|
|
3421
|
+
if (m[IKVReduce__kv_reduce] !== undefined) return m[IKVReduce__kv_reduce](m, f, init);
|
|
2897
3422
|
var ret = init;
|
|
2898
3423
|
for (const o of iterable(m)) {
|
|
2899
3424
|
ret = f(ret, o[0], o[1]);
|
|
@@ -2915,11 +3440,25 @@ export function min(x, ...more) {
|
|
|
2915
3440
|
return m;
|
|
2916
3441
|
}
|
|
2917
3442
|
|
|
3443
|
+
export function associative_QMARK_(x) {
|
|
3444
|
+
switch (typeConst(x)) {
|
|
3445
|
+
case MAP_TYPE:
|
|
3446
|
+
case ARRAY_TYPE:
|
|
3447
|
+
case OBJECT_TYPE:
|
|
3448
|
+
return true;
|
|
3449
|
+
case INSTANCE_TYPE:
|
|
3450
|
+
return x[IAssociative__assoc] !== undefined;
|
|
3451
|
+
default:
|
|
3452
|
+
return false;
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
|
|
2918
3456
|
export function map_QMARK_(coll) {
|
|
2919
3457
|
if (coll == null) return false;
|
|
2920
3458
|
if (isObj(coll)) return true;
|
|
2921
3459
|
if (coll instanceof Map) return true;
|
|
2922
3460
|
if (coll[TYPE_TAG] === MAP_TYPE) return true;
|
|
3461
|
+
if (coll[IMap.__sym] !== undefined) return true;
|
|
2923
3462
|
return false;
|
|
2924
3463
|
}
|
|
2925
3464
|
|
|
@@ -2994,6 +3533,24 @@ export function nnext(x) {
|
|
|
2994
3533
|
return next(next(x));
|
|
2995
3534
|
}
|
|
2996
3535
|
|
|
3536
|
+
export function nthnext(coll, n) {
|
|
3537
|
+
let xs = seq(coll);
|
|
3538
|
+
while (xs != null && n > 0) {
|
|
3539
|
+
xs = next(xs);
|
|
3540
|
+
n = n - 1;
|
|
3541
|
+
}
|
|
3542
|
+
return xs;
|
|
3543
|
+
}
|
|
3544
|
+
|
|
3545
|
+
export function nthrest(coll, n) {
|
|
3546
|
+
let xs = coll;
|
|
3547
|
+
while (n > 0 && seq(xs) != null) {
|
|
3548
|
+
xs = rest(xs);
|
|
3549
|
+
n = n - 1;
|
|
3550
|
+
}
|
|
3551
|
+
return xs;
|
|
3552
|
+
}
|
|
3553
|
+
|
|
2997
3554
|
export function compare(x, y) {
|
|
2998
3555
|
if (x === y) {
|
|
2999
3556
|
return 0;
|
|
@@ -3103,6 +3660,14 @@ export function keys(obj) {
|
|
|
3103
3660
|
if (obj == null) return null;
|
|
3104
3661
|
const t = typeConst(obj);
|
|
3105
3662
|
switch (t) {
|
|
3663
|
+
case INSTANCE_TYPE:
|
|
3664
|
+
// Object.keys on an instance would leak internals: go through -kv-reduce
|
|
3665
|
+
if (obj[IKVReduce__kv_reduce] !== undefined) {
|
|
3666
|
+
const ks = obj[IKVReduce__kv_reduce](obj, (acc, k, _) => (acc.push(k), acc), []);
|
|
3667
|
+
if (ks.length) return ks;
|
|
3668
|
+
return;
|
|
3669
|
+
}
|
|
3670
|
+
// fall through
|
|
3106
3671
|
case OBJECT_TYPE: {
|
|
3107
3672
|
const ks = Object.keys(obj);
|
|
3108
3673
|
if (ks.length) return ks;
|
|
@@ -3127,6 +3692,13 @@ export function vals(obj) {
|
|
|
3127
3692
|
if (obj == null) return null;
|
|
3128
3693
|
const t = typeConst(obj);
|
|
3129
3694
|
switch (t) {
|
|
3695
|
+
case INSTANCE_TYPE:
|
|
3696
|
+
if (obj[IKVReduce__kv_reduce] !== undefined) {
|
|
3697
|
+
const vs = obj[IKVReduce__kv_reduce](obj, (acc, _, v) => (acc.push(v), acc), []);
|
|
3698
|
+
if (vs.length) return vs;
|
|
3699
|
+
return;
|
|
3700
|
+
}
|
|
3701
|
+
// fall through
|
|
3130
3702
|
case OBJECT_TYPE: {
|
|
3131
3703
|
const vs = Object.values(obj);
|
|
3132
3704
|
if (vs.length) return vs;
|
|
@@ -3210,6 +3782,26 @@ export function qualified_keyword_QMARK_(x) {
|
|
|
3210
3782
|
return typeof x === 'string' && x.includes('/');
|
|
3211
3783
|
}
|
|
3212
3784
|
|
|
3785
|
+
export function ident_QMARK_(x) {
|
|
3786
|
+
return typeof x === 'string';
|
|
3787
|
+
}
|
|
3788
|
+
|
|
3789
|
+
export function simple_ident_QMARK_(x) {
|
|
3790
|
+
return typeof x === 'string' && namespace(x) == null;
|
|
3791
|
+
}
|
|
3792
|
+
|
|
3793
|
+
export function qualified_ident_QMARK_(x) {
|
|
3794
|
+
return typeof x === 'string' && namespace(x) != null;
|
|
3795
|
+
}
|
|
3796
|
+
|
|
3797
|
+
export function simple_symbol_QMARK_(x) {
|
|
3798
|
+
return symbol_QMARK_(x) && namespace(x) == null;
|
|
3799
|
+
}
|
|
3800
|
+
|
|
3801
|
+
export function qualified_symbol_QMARK_(x) {
|
|
3802
|
+
return symbol_QMARK_(x) && namespace(x) != null;
|
|
3803
|
+
}
|
|
3804
|
+
|
|
3213
3805
|
export function coll_QMARK_(coll) {
|
|
3214
3806
|
return typeConst(coll) != undefined;
|
|
3215
3807
|
}
|
|
@@ -3253,6 +3845,11 @@ export function double_QMARK_(x) {
|
|
|
3253
3845
|
return typeof x === 'number';
|
|
3254
3846
|
}
|
|
3255
3847
|
|
|
3848
|
+
// like CLJS: every number is a float
|
|
3849
|
+
export function float_QMARK_(x) {
|
|
3850
|
+
return double_QMARK_(x);
|
|
3851
|
+
}
|
|
3852
|
+
|
|
3256
3853
|
export const integer_QMARK_ = int_QMARK_;
|
|
3257
3854
|
|
|
3258
3855
|
export function pos_int_QMARK_(x) {
|
|
@@ -3268,30 +3865,41 @@ export function neg_int_QMARK_(x) {
|
|
|
3268
3865
|
}
|
|
3269
3866
|
|
|
3270
3867
|
export function meta(x) {
|
|
3271
|
-
if (x
|
|
3272
|
-
return x[
|
|
3273
|
-
}
|
|
3868
|
+
if (x != null && x[IMeta__meta] !== undefined) {
|
|
3869
|
+
return x[IMeta__meta](x);
|
|
3870
|
+
}
|
|
3871
|
+
return null;
|
|
3274
3872
|
}
|
|
3275
3873
|
|
|
3276
3874
|
export function with_meta(x, m) {
|
|
3875
|
+
if (x != null && x[IWithMeta__with_meta] !== undefined) {
|
|
3876
|
+
return x[IWithMeta__with_meta](x, m);
|
|
3877
|
+
}
|
|
3878
|
+
return with_meta_copy(x, m);
|
|
3879
|
+
}
|
|
3880
|
+
|
|
3881
|
+
// instance-level impls for a plain value; the meta lives in the closure
|
|
3882
|
+
function installMeta(x, m) {
|
|
3883
|
+
x[IMeta__meta] = () => m;
|
|
3884
|
+
x[IWithMeta__with_meta] = with_meta_copy;
|
|
3885
|
+
return x;
|
|
3886
|
+
}
|
|
3887
|
+
|
|
3888
|
+
function with_meta_copy(x, m) {
|
|
3277
3889
|
// For functions, wrap in a new callable that forwards to the original
|
|
3278
3890
|
// so fn? stays true and the original isn't mutated. copy() can't handle
|
|
3279
3891
|
// functions - a {...x} spread loses the call signature.
|
|
3280
3892
|
if (typeof x === 'function') {
|
|
3281
3893
|
const wrapped = function (...args) { return x.apply(this, args); };
|
|
3282
|
-
wrapped
|
|
3283
|
-
return wrapped;
|
|
3894
|
+
return installMeta(wrapped, m);
|
|
3284
3895
|
}
|
|
3285
3896
|
// A lazy seq or cons is not copied element-wise: clone the head so the new
|
|
3286
3897
|
// value carries its own metadata without forcing realization.
|
|
3287
3898
|
if (x?.[TYPE_TAG] === LAZY_ITERABLE_TYPE) {
|
|
3288
3899
|
const ret = Object.assign(Object.create(Object.getPrototypeOf(x)), x);
|
|
3289
|
-
ret
|
|
3290
|
-
return ret;
|
|
3900
|
+
return installMeta(ret, m);
|
|
3291
3901
|
}
|
|
3292
|
-
|
|
3293
|
-
ret[_metaSym] = m;
|
|
3294
|
-
return ret;
|
|
3902
|
+
return installMeta(copy(x), m);
|
|
3295
3903
|
}
|
|
3296
3904
|
|
|
3297
3905
|
export function vary_meta(x, f, ...args) {
|
|
@@ -3308,6 +3916,7 @@ export function counted_QMARK_(x) {
|
|
|
3308
3916
|
case ARRAY_TYPE:
|
|
3309
3917
|
case MAP_TYPE:
|
|
3310
3918
|
case OBJECT_TYPE:
|
|
3919
|
+
case INSTANCE_TYPE:
|
|
3311
3920
|
case LIST_TYPE:
|
|
3312
3921
|
case SET_TYPE:
|
|
3313
3922
|
return true;
|
|
@@ -3481,10 +4090,12 @@ export function flatten(x) {
|
|
|
3481
4090
|
}
|
|
3482
4091
|
|
|
3483
4092
|
export function transient$(x) {
|
|
4093
|
+
if (x != null && x[IEditableCollection__as_transient] !== undefined) return x[IEditableCollection__as_transient](x);
|
|
3484
4094
|
return copy(x);
|
|
3485
4095
|
}
|
|
3486
4096
|
|
|
3487
4097
|
export function persistent_BANG_(x) {
|
|
4098
|
+
if (x != null && x[ITransientCollection__persistent_BANG_] !== undefined) return x[ITransientCollection__persistent_BANG_](x);
|
|
3488
4099
|
// no Object.freeze: persistent structures stay extensible so symbol-keyed
|
|
3489
4100
|
// metadata can be attached
|
|
3490
4101
|
return x;
|
|
@@ -3718,6 +4329,18 @@ export function double$(x) {
|
|
|
3718
4329
|
return x;
|
|
3719
4330
|
}
|
|
3720
4331
|
|
|
4332
|
+
export function num(x) {
|
|
4333
|
+
return x;
|
|
4334
|
+
}
|
|
4335
|
+
|
|
4336
|
+
export function byte$(x) {
|
|
4337
|
+
return x;
|
|
4338
|
+
}
|
|
4339
|
+
|
|
4340
|
+
export function short$(x) {
|
|
4341
|
+
return x;
|
|
4342
|
+
}
|
|
4343
|
+
|
|
3721
4344
|
export function type(x) {
|
|
3722
4345
|
return x != null && x.constructor;
|
|
3723
4346
|
}
|
|
@@ -3771,6 +4394,8 @@ export function peek(vec) {
|
|
|
3771
4394
|
return first(vec);
|
|
3772
4395
|
} else if (array_QMARK_(vec)) {
|
|
3773
4396
|
return vec[vec.length - 1];
|
|
4397
|
+
} else if (vec[IStack__peek] !== undefined) {
|
|
4398
|
+
return vec[IStack__peek](vec);
|
|
3774
4399
|
} else {
|
|
3775
4400
|
throw missing_protocol('IStack.-peek', vec);
|
|
3776
4401
|
}
|
|
@@ -3786,13 +4411,30 @@ export function pop(vec) {
|
|
|
3786
4411
|
const ret = [...vec];
|
|
3787
4412
|
ret.pop();
|
|
3788
4413
|
return ret;
|
|
4414
|
+
} else if (vec[IStack__pop] !== undefined) {
|
|
4415
|
+
return vec[IStack__pop](vec);
|
|
3789
4416
|
} else {
|
|
3790
4417
|
throw missing_protocol('IStack.-pop', vec);
|
|
3791
4418
|
}
|
|
3792
4419
|
}
|
|
3793
4420
|
|
|
4421
|
+
export function pop_BANG_(v) {
|
|
4422
|
+
if (v != null && isVectorArray(v)) {
|
|
4423
|
+
if (v.length === 0) throw new Error("Can't pop empty vector");
|
|
4424
|
+
v.pop();
|
|
4425
|
+
return v;
|
|
4426
|
+
}
|
|
4427
|
+
if (v != null && v[ITransientVector__pop_BANG_] !== undefined) {
|
|
4428
|
+
return v[ITransientVector__pop_BANG_](v);
|
|
4429
|
+
}
|
|
4430
|
+
throw missing_protocol('ITransientVector.-pop!', v);
|
|
4431
|
+
}
|
|
4432
|
+
|
|
3794
4433
|
export function update_keys(m, f) {
|
|
3795
4434
|
const m2 = empty(m);
|
|
4435
|
+
if (m2 != null && m2[IAssociative__assoc] !== undefined) {
|
|
4436
|
+
return reduce_kv((acc, k, v) => acc[IAssociative__assoc](acc, f(k), v), m2, m);
|
|
4437
|
+
}
|
|
3796
4438
|
const assocFn = getAssocMut(m) || assoc_BANG_;
|
|
3797
4439
|
reduce_kv(
|
|
3798
4440
|
(acc, k, v) => {
|
|
@@ -3806,6 +4448,9 @@ export function update_keys(m, f) {
|
|
|
3806
4448
|
|
|
3807
4449
|
export function update_vals(m, f) {
|
|
3808
4450
|
const m2 = empty(m);
|
|
4451
|
+
if (m2 != null && m2[IAssociative__assoc] !== undefined) {
|
|
4452
|
+
return reduce_kv((acc, k, v) => acc[IAssociative__assoc](acc, k, f(v)), m2, m);
|
|
4453
|
+
}
|
|
3809
4454
|
const assocFn = getAssocMut(m) || assoc_BANG_;
|
|
3810
4455
|
reduce_kv(
|
|
3811
4456
|
(acc, k, v) => {
|
|
@@ -3886,12 +4531,15 @@ function clj__GT_js_(x, seen) {
|
|
|
3886
4531
|
// we need to protect against circular objects
|
|
3887
4532
|
if (seen.has(x)) return x;
|
|
3888
4533
|
seen.add(x);
|
|
4534
|
+
if (x != null && x[IEncodeJS__clj__GT_js] !== undefined) {
|
|
4535
|
+
return x[IEncodeJS__clj__GT_js](x, (v) => clj__GT_js_(v, seen));
|
|
4536
|
+
}
|
|
3889
4537
|
if (map_QMARK_(x)) {
|
|
3890
4538
|
return update_vals(x, (x) => clj__GT_js_(x, seen));
|
|
3891
4539
|
}
|
|
3892
4540
|
|
|
3893
4541
|
const tc = typeConst(x);
|
|
3894
|
-
if (tc && tc != OBJECT_TYPE) {
|
|
4542
|
+
if (tc && tc != OBJECT_TYPE && tc != INSTANCE_TYPE) {
|
|
3895
4543
|
return mapv((x) => clj__GT_js_(x, seen), x);
|
|
3896
4544
|
}
|
|
3897
4545
|
return x;
|
|
@@ -3967,6 +4615,18 @@ function toEDN(value, seen = new WeakSet(), readably = true) {
|
|
|
3967
4615
|
result = `(${mapv((v) => `${toEDN(v, seen, readably)}`, value).join(', ')})`;
|
|
3968
4616
|
break;
|
|
3969
4617
|
default:
|
|
4618
|
+
if (value[IPrintWithWriter__pr_writer] !== undefined) {
|
|
4619
|
+
let buf = '';
|
|
4620
|
+
const writer = { [IWriter__write]: (_w, s) => (buf += s), [IWriter.__sym]: true };
|
|
4621
|
+
value[IPrintWithWriter__pr_writer](value, writer, { readably: readably });
|
|
4622
|
+
result = buf;
|
|
4623
|
+
break;
|
|
4624
|
+
}
|
|
4625
|
+
if (value[IRecord.__sym] !== undefined) {
|
|
4626
|
+
keys = Object.keys(value);
|
|
4627
|
+
result = `#${value.constructor.name}{${keys.map((k) => `:${k} ${toEDN(value[k], seen, readably)}`).join(', ')}}`;
|
|
4628
|
+
break;
|
|
4629
|
+
}
|
|
3970
4630
|
// Non-plain objects (Promise, Error, Date, class instances, ...) have a
|
|
3971
4631
|
// constructor other than Object. Print them as #<Name> rather than {}
|
|
3972
4632
|
// (which is what Object.keys would yield for opaque values like a
|
|
@@ -3993,3 +4653,8 @@ export function prn(...xs) {
|
|
|
3993
4653
|
_STAR_print_fn_STAR_.val(pr_str(...xs));
|
|
3994
4654
|
if (_STAR_print_newline_STAR_.val) _STAR_print_fn_STAR_.val('\n');
|
|
3995
4655
|
}
|
|
4656
|
+
|
|
4657
|
+
export function prn_str(...xs) {
|
|
4658
|
+
return pr_str(...xs) + '\n';
|
|
4659
|
+
}
|
|
4660
|
+
|