squint-cljs 0.14.201 → 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 -1367
- 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 +743 -51
- package/src/squint/multi.js +9 -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,12 +242,28 @@ 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
|
}
|
|
225
249
|
|
|
250
|
+
function validateArrayKeys(o, k, kvs) {
|
|
251
|
+
// like CLJS: a vector key is an index in [0, count], count appends
|
|
252
|
+
let len = o.length;
|
|
253
|
+
for (let i = 0; i < kvs.length + 2; i += 2) {
|
|
254
|
+
const key = i === 0 ? k : kvs[i - 2];
|
|
255
|
+
if (!Number.isInteger(key)) {
|
|
256
|
+
throw new Error("Vector's key for assoc must be a number.");
|
|
257
|
+
}
|
|
258
|
+
if (key < 0 || key > len) {
|
|
259
|
+
throw new Error(`Index ${key} out of bounds [0,${len}]`);
|
|
260
|
+
}
|
|
261
|
+
if (key === len) len++;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
226
265
|
export function assoc_BANG_(m, k, v, ...kvs) {
|
|
227
|
-
if (kvs.length % 2 !== 0) {
|
|
266
|
+
if (arguments.length < 3 || kvs.length % 2 !== 0) {
|
|
228
267
|
throw new Error('Illegal argument: assoc expects an odd number of arguments.');
|
|
229
268
|
}
|
|
230
269
|
switch (typeConst(m)) {
|
|
@@ -236,6 +275,24 @@ export function assoc_BANG_(m, k, v, ...kvs) {
|
|
|
236
275
|
}
|
|
237
276
|
break;
|
|
238
277
|
case ARRAY_TYPE:
|
|
278
|
+
validateArrayKeys(m, k, kvs);
|
|
279
|
+
m[k] = v;
|
|
280
|
+
|
|
281
|
+
for (let i = 0; i < kvs.length; i += 2) {
|
|
282
|
+
m[kvs[i]] = kvs[i + 1];
|
|
283
|
+
}
|
|
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
|
|
239
296
|
case OBJECT_TYPE:
|
|
240
297
|
m[k] = v;
|
|
241
298
|
|
|
@@ -252,16 +309,14 @@ export function assoc_BANG_(m, k, v, ...kvs) {
|
|
|
252
309
|
return m;
|
|
253
310
|
}
|
|
254
311
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
// Copies metadata from `from` onto `to` (when present) and returns `to`. Used
|
|
258
|
-
// to make value-producing operations (copy, empty, conj, into) carry metadata
|
|
259
|
-
// like Clojure does, instead of dropping it on the freshly built structure.
|
|
260
|
-
// Kept branch-light for the hot path: reads an absent symbol property (cheap,
|
|
261
|
-
// 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
|
|
262
314
|
function copyMeta(from, to) {
|
|
263
|
-
const
|
|
264
|
-
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
|
+
}
|
|
265
320
|
return to;
|
|
266
321
|
}
|
|
267
322
|
|
|
@@ -274,6 +329,7 @@ function copy(o) {
|
|
|
274
329
|
return copyMeta(o, new o.constructor(o));
|
|
275
330
|
case ARRAY_TYPE:
|
|
276
331
|
return copyMeta(o, [...o]);
|
|
332
|
+
case INSTANCE_TYPE:
|
|
277
333
|
case OBJECT_TYPE:
|
|
278
334
|
return copyMeta(o, { ...o });
|
|
279
335
|
case LIST_TYPE:
|
|
@@ -284,23 +340,19 @@ function copy(o) {
|
|
|
284
340
|
}
|
|
285
341
|
|
|
286
342
|
export function assoc(o, k, v, ...kvs) {
|
|
343
|
+
if (arguments.length < 3 || kvs.length % 2 !== 0) {
|
|
344
|
+
throw new Error('Illegal argument: assoc expects an odd number of arguments.');
|
|
345
|
+
}
|
|
287
346
|
// only nil puns to an empty map; assoc on false throws, like CLJS
|
|
288
347
|
if (o == null) {
|
|
289
348
|
o = {};
|
|
290
349
|
}
|
|
291
|
-
if (
|
|
292
|
-
|
|
293
|
-
let
|
|
294
|
-
|
|
295
|
-
const key = i === 0 ? k : kvs[i - 2];
|
|
296
|
-
if (!Number.isInteger(key)) {
|
|
297
|
-
throw new Error("Vector's key for assoc must be a number.");
|
|
298
|
-
}
|
|
299
|
-
if (key < 0 || key > len) {
|
|
300
|
-
throw new Error(`Index ${key} out of bounds [0,${len}]`);
|
|
301
|
-
}
|
|
302
|
-
if (key === len) len++;
|
|
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]);
|
|
303
354
|
}
|
|
355
|
+
return ret;
|
|
304
356
|
}
|
|
305
357
|
const ret = copy(o);
|
|
306
358
|
assoc_BANG_(ret, k, v, ...kvs);
|
|
@@ -324,6 +376,9 @@ const OBJECT_TYPE = 3;
|
|
|
324
376
|
const LIST_TYPE = 4;
|
|
325
377
|
const SET_TYPE = 5;
|
|
326
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;
|
|
327
382
|
|
|
328
383
|
// type tag set in each collection ctor, read by typeConst (DCE: no instanceof).
|
|
329
384
|
const TYPE_TAG = Symbol('squint.lang.type');
|
|
@@ -387,7 +442,7 @@ function typeConst(obj) {
|
|
|
387
442
|
if (tag !== undefined) return tag;
|
|
388
443
|
if (isVectorArray(obj)) return ARRAY_TYPE;
|
|
389
444
|
// any remaining object (class instance, null-proto) is associative
|
|
390
|
-
if (typeof obj === 'object') return
|
|
445
|
+
if (typeof obj === 'object') return INSTANCE_TYPE;
|
|
391
446
|
|
|
392
447
|
return undefined;
|
|
393
448
|
}
|
|
@@ -396,7 +451,7 @@ function assoc_in_with(f, fname, o, keys, value) {
|
|
|
396
451
|
keys = vec(keys);
|
|
397
452
|
o = o || {}; // default nil behavior is JS object
|
|
398
453
|
const baseType = typeConst(o);
|
|
399
|
-
if (baseType !== MAP_TYPE && baseType !== ARRAY_TYPE && baseType !== OBJECT_TYPE)
|
|
454
|
+
if (baseType !== MAP_TYPE && baseType !== ARRAY_TYPE && baseType !== OBJECT_TYPE && baseType !== INSTANCE_TYPE)
|
|
400
455
|
throw new Error(
|
|
401
456
|
`Illegal argument: ${fname} expects the first argument to be a Map, Array, or Object.`
|
|
402
457
|
);
|
|
@@ -408,9 +463,12 @@ function assoc_in_with(f, fname, o, keys, value) {
|
|
|
408
463
|
const k = keys[i];
|
|
409
464
|
let chainValue;
|
|
410
465
|
if (lastInChain instanceof Map) chainValue = lastInChain.get(k);
|
|
411
|
-
else
|
|
466
|
+
else if (lastInChain != null && lastInChain[ILookup__lookup] !== undefined) {
|
|
467
|
+
chainValue = lastInChain[ILookup__lookup](lastInChain, k, undefined);
|
|
468
|
+
} else chainValue = lastInChain[k];
|
|
412
469
|
if (!chainValue) {
|
|
413
|
-
|
|
470
|
+
// an instance root has no empty-of-type: missing levels become plain maps
|
|
471
|
+
chainValue = emptyOfType(baseType) ?? {};
|
|
414
472
|
}
|
|
415
473
|
chain.push(chainValue);
|
|
416
474
|
lastInChain = chainValue;
|
|
@@ -515,6 +573,14 @@ export function conj_BANG_(...xs) {
|
|
|
515
573
|
else for (const kv of mapEntriesOf(x)) o.set(kv[0], kv[1]);
|
|
516
574
|
}
|
|
517
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
|
|
518
584
|
case OBJECT_TYPE:
|
|
519
585
|
for (const x of rest) {
|
|
520
586
|
if (isVectorArray(x)) { asMapEntry(x); o[x[0]] = x[1]; }
|
|
@@ -593,6 +659,14 @@ export function conj(...xs) {
|
|
|
593
659
|
yield* rest;
|
|
594
660
|
yield* o;
|
|
595
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
|
|
596
670
|
case OBJECT_TYPE:
|
|
597
671
|
o2 = { ...o };
|
|
598
672
|
|
|
@@ -610,6 +684,13 @@ export function conj(...xs) {
|
|
|
610
684
|
}
|
|
611
685
|
|
|
612
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
|
+
}
|
|
613
694
|
for (const x of xs) {
|
|
614
695
|
s.delete(x);
|
|
615
696
|
}
|
|
@@ -618,6 +699,12 @@ export function disj_BANG_(s, ...xs) {
|
|
|
618
699
|
|
|
619
700
|
export function disj(s, ...xs) {
|
|
620
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
|
+
}
|
|
621
708
|
// pass s itself (not a spread) so a SortedSet keeps its comparator
|
|
622
709
|
const s1 = new s.constructor(s);
|
|
623
710
|
return copyMeta(s, disj_BANG_(s1, ...xs));
|
|
@@ -633,12 +720,22 @@ export function contains_QMARK_(coll, v) {
|
|
|
633
720
|
return coll.has(v);
|
|
634
721
|
case undefined:
|
|
635
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
|
|
636
728
|
default:
|
|
637
729
|
return v in coll;
|
|
638
730
|
}
|
|
639
731
|
}
|
|
640
732
|
|
|
641
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
|
+
}
|
|
642
739
|
for (const k of ks) {
|
|
643
740
|
delete m[k];
|
|
644
741
|
}
|
|
@@ -650,9 +747,18 @@ export function dissoc(m, ...ks) {
|
|
|
650
747
|
if (!m) return;
|
|
651
748
|
if (ks.length === 0) return m;
|
|
652
749
|
const tc = typeConst(m);
|
|
653
|
-
if (tc !== MAP_TYPE && tc !== OBJECT_TYPE) {
|
|
750
|
+
if (tc !== MAP_TYPE && tc !== OBJECT_TYPE && tc !== INSTANCE_TYPE) {
|
|
654
751
|
throw new Error('dissoc expects a map, got: ' + typeof m);
|
|
655
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
|
+
}
|
|
656
762
|
if (tc === MAP_TYPE) {
|
|
657
763
|
let present = false;
|
|
658
764
|
for (const k of ks) if (m.has(k)) { present = true; break; }
|
|
@@ -690,6 +796,14 @@ export function println(...args) {
|
|
|
690
796
|
if (_STAR_print_newline_STAR_.val) _STAR_print_fn_STAR_.val('\n');
|
|
691
797
|
}
|
|
692
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
|
+
|
|
693
807
|
export function pr(...xs) {
|
|
694
808
|
_STAR_print_fn_STAR_.val(pr_str(...xs));
|
|
695
809
|
}
|
|
@@ -707,6 +821,8 @@ export function nth(coll, idx, orElse) {
|
|
|
707
821
|
if (idx >= 0 && idx < coll.length) {
|
|
708
822
|
return coll[idx];
|
|
709
823
|
}
|
|
824
|
+
} else if (coll[IIndexed__nth] !== undefined) {
|
|
825
|
+
return hasDefault ? coll[IIndexed__nth](coll, idx, orElse) : coll[IIndexed__nth](coll, idx);
|
|
710
826
|
} else if (idx >= 0) {
|
|
711
827
|
// non-array: skip whole chunks instead of counting elements (handles
|
|
712
828
|
// infinite seqs since it stops once idx is reached)
|
|
@@ -749,6 +865,10 @@ export function get(coll, key, otherwise = undefined) {
|
|
|
749
865
|
v = coll[key];
|
|
750
866
|
break;
|
|
751
867
|
default:
|
|
868
|
+
if (coll[ILookup__lookup] !== undefined) {
|
|
869
|
+
v = coll[ILookup__lookup](coll, key, otherwise);
|
|
870
|
+
return v === undefined ? otherwise : v;
|
|
871
|
+
}
|
|
752
872
|
// we choose .get as the default implementation, e.g. fetch Headers are not Maps, but do implement a .get method
|
|
753
873
|
g = coll['get'];
|
|
754
874
|
if (typeof g === 'function') {
|
|
@@ -772,7 +892,7 @@ export function seq_QMARK_(x) {
|
|
|
772
892
|
export function sequential_QMARK_(x) {
|
|
773
893
|
// vectors and lists are arrays; lazy seqs and cons carry the lazy brand.
|
|
774
894
|
// Sets, maps and strings are iterable but not sequential.
|
|
775
|
-
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);
|
|
776
896
|
}
|
|
777
897
|
|
|
778
898
|
export function seqable_QMARK_(x) {
|
|
@@ -817,7 +937,10 @@ export function iterable(x) {
|
|
|
817
937
|
}
|
|
818
938
|
// a type extended to ISeqable seqs through its -seq method
|
|
819
939
|
if (x[ISeqable__seq] !== undefined) return iterable(x[ISeqable__seq](x));
|
|
820
|
-
|
|
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);
|
|
821
944
|
throw new TypeError(`${x} is not iterable`);
|
|
822
945
|
}
|
|
823
946
|
|
|
@@ -841,10 +964,19 @@ export function seq(x) {
|
|
|
841
964
|
if (iter.length === 0 || iter.size === 0) {
|
|
842
965
|
return null;
|
|
843
966
|
}
|
|
844
|
-
// 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
|
|
845
969
|
if (iter instanceof Set || iter[TYPE_TAG] === SET_TYPE) {
|
|
846
970
|
return [...iter];
|
|
847
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
|
+
}
|
|
848
980
|
const _i = iter[Symbol.iterator]();
|
|
849
981
|
if (_i.next().done) return null;
|
|
850
982
|
return iter;
|
|
@@ -877,6 +1009,14 @@ export function ffirst(coll) {
|
|
|
877
1009
|
return first(first(coll));
|
|
878
1010
|
}
|
|
879
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
|
+
|
|
880
1020
|
export function rest(coll) {
|
|
881
1021
|
// chunk-aware: drop the first element of the first chunk, keep the rest of
|
|
882
1022
|
// the chain chunked (preserves chunkedness, unlike re-iterating element-wise)
|
|
@@ -1274,6 +1414,13 @@ export function filterv(pred, coll) {
|
|
|
1274
1414
|
return pushAll([], filter(pred, coll));
|
|
1275
1415
|
}
|
|
1276
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
|
+
|
|
1277
1424
|
export function remove(pred, coll) {
|
|
1278
1425
|
if (arguments.length === 1) {
|
|
1279
1426
|
return filter1(complement(pred));
|
|
@@ -1371,10 +1518,326 @@ export function _deref(o) {
|
|
|
1371
1518
|
}
|
|
1372
1519
|
export const ISeqable = { __sym: ISEQABLE_SYM };
|
|
1373
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
|
+
}
|
|
1374
1809
|
export function _seq(o) {
|
|
1375
1810
|
if (o != null && o[ISeqable__seq] !== undefined) return o[ISeqable__seq](o);
|
|
1376
1811
|
return nilImpl(_seq, 'ISeqable.-seq', o)(o);
|
|
1377
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
|
+
}
|
|
1378
1841
|
|
|
1379
1842
|
// an extend-type on nil stores the impl on the dispatch fn under null,
|
|
1380
1843
|
// the same convention the generated protocol dispatch fns use
|
|
@@ -1470,12 +1933,28 @@ export class Atom {
|
|
|
1470
1933
|
export function atom(init, ...opts) {
|
|
1471
1934
|
const a = new Atom(init);
|
|
1472
1935
|
for (let i = 0; i < opts.length; i += 2) {
|
|
1473
|
-
|
|
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
|
+
}
|
|
1474
1941
|
else if (opts[i] === 'validator') a._validator = opts[i + 1];
|
|
1475
1942
|
}
|
|
1476
1943
|
return a;
|
|
1477
1944
|
}
|
|
1478
1945
|
|
|
1946
|
+
export function get_validator(ref) {
|
|
1947
|
+
return ref._validator ?? null;
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
export function set_validator_BANG_(ref, f) {
|
|
1951
|
+
if (f != null && !truth_(f(deref(ref)))) {
|
|
1952
|
+
throw new Error('Validator rejected reference state');
|
|
1953
|
+
}
|
|
1954
|
+
ref._validator = f;
|
|
1955
|
+
return null;
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1479
1958
|
// the CLJS missing-protocol error, used by every protocol dispatch miss
|
|
1480
1959
|
export function missing_protocol(proto, obj) {
|
|
1481
1960
|
let ty;
|
|
@@ -1613,6 +2092,21 @@ export function re_pattern(s) {
|
|
|
1613
2092
|
}
|
|
1614
2093
|
|
|
1615
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
|
+
}
|
|
1616
2110
|
if (!isVectorArray(arr)) {
|
|
1617
2111
|
throw new Error('subvec: argument must be a vector');
|
|
1618
2112
|
}
|
|
@@ -1636,7 +2130,8 @@ export function vector(...args) {
|
|
|
1636
2130
|
export const array = vector;
|
|
1637
2131
|
|
|
1638
2132
|
export function vector_QMARK_(x) {
|
|
1639
|
-
|
|
2133
|
+
if (x == null) return false;
|
|
2134
|
+
return isVectorArray(x) || x[IVector.__sym] !== undefined;
|
|
1640
2135
|
}
|
|
1641
2136
|
|
|
1642
2137
|
export function mapv(...args) {
|
|
@@ -1690,6 +2185,7 @@ function toArray(coll) {
|
|
|
1690
2185
|
|
|
1691
2186
|
export function vec(x) {
|
|
1692
2187
|
if (isVectorArray(x)) return x;
|
|
2188
|
+
if (x != null && x[IVector.__sym] !== undefined) return x;
|
|
1693
2189
|
return pushAll([], x);
|
|
1694
2190
|
}
|
|
1695
2191
|
|
|
@@ -1698,7 +2194,8 @@ export function set(coll) {
|
|
|
1698
2194
|
}
|
|
1699
2195
|
|
|
1700
2196
|
export function set_QMARK_(x) {
|
|
1701
|
-
|
|
2197
|
+
if (x == null) return false;
|
|
2198
|
+
return typeConst(x) === SET_TYPE || x[ISet.__sym] !== undefined;
|
|
1702
2199
|
}
|
|
1703
2200
|
|
|
1704
2201
|
export function hash_set(...xs) {
|
|
@@ -1713,6 +2210,12 @@ export function char_QMARK_(x) {
|
|
|
1713
2210
|
return typeof x === 'string' && x.length === 1;
|
|
1714
2211
|
}
|
|
1715
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
|
+
|
|
1716
2219
|
export function apply(f, ...args) {
|
|
1717
2220
|
f = __toFn(f);
|
|
1718
2221
|
const xs = args.slice(0, args.length - 1);
|
|
@@ -2087,10 +2590,16 @@ export function partition_by(f, coll) {
|
|
|
2087
2590
|
export function empty(coll) {
|
|
2088
2591
|
const type = typeConst(coll);
|
|
2089
2592
|
if (type != null) {
|
|
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
|
+
}
|
|
2090
2599
|
return copyMeta(coll, emptyOfType(type));
|
|
2091
|
-
} else {
|
|
2092
|
-
throw new Error(`Can't create empty of ${typeof coll}`);
|
|
2093
2600
|
}
|
|
2601
|
+
// non-collections give nil, like CLJS
|
|
2602
|
+
return null;
|
|
2094
2603
|
}
|
|
2095
2604
|
|
|
2096
2605
|
export function merge(...args) {
|
|
@@ -2104,9 +2613,22 @@ export function merge(...args) {
|
|
|
2104
2613
|
} else if (typeConst(firstArg) === undefined) {
|
|
2105
2614
|
// a non-collection passes through; conj! throws when maps follow, like CLJS
|
|
2106
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;
|
|
2107
2620
|
} else {
|
|
2108
2621
|
obj = into(empty(firstArg), firstArg);
|
|
2109
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
|
+
}
|
|
2110
2632
|
return conj_BANG_(obj, ...args.slice(1));
|
|
2111
2633
|
}
|
|
2112
2634
|
|
|
@@ -2164,17 +2686,31 @@ export function into(...args) {
|
|
|
2164
2686
|
if (isVectorArray(to)) {
|
|
2165
2687
|
return pushAll(copy(to), args[1]);
|
|
2166
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
|
+
}
|
|
2167
2701
|
return reduce(conj_BANG_, copy(to), args[1]);
|
|
2168
2702
|
case 3:
|
|
2169
2703
|
to = args[0];
|
|
2170
2704
|
xform = args[1];
|
|
2171
2705
|
from = args[2];
|
|
2172
|
-
c = copy(to);
|
|
2706
|
+
c = to != null && to[ICollection__conj] !== undefined ? to : copy(to);
|
|
2173
2707
|
rf = (coll, v) => {
|
|
2174
2708
|
if (v === undefined) {
|
|
2175
2709
|
return coll;
|
|
2176
2710
|
}
|
|
2177
|
-
return
|
|
2711
|
+
return coll != null && coll[ICollection__conj] !== undefined
|
|
2712
|
+
? coll[ICollection__conj](coll, v)
|
|
2713
|
+
: conj_BANG_(coll, v);
|
|
2178
2714
|
};
|
|
2179
2715
|
return transduce(xform, rf, c, from);
|
|
2180
2716
|
default:
|
|
@@ -2296,6 +2832,7 @@ function take_nth1(n) {
|
|
|
2296
2832
|
}
|
|
2297
2833
|
|
|
2298
2834
|
export function take_nth(n, coll) {
|
|
2835
|
+
assertNumber(n);
|
|
2299
2836
|
if (arguments.length === 1) return take_nth1(n);
|
|
2300
2837
|
if (n <= 0) {
|
|
2301
2838
|
return repeat(first(coll));
|
|
@@ -2504,6 +3041,10 @@ export function reverse(coll) {
|
|
|
2504
3041
|
return toArray(coll).reverse();
|
|
2505
3042
|
}
|
|
2506
3043
|
|
|
3044
|
+
export function reversible_QMARK_(x) {
|
|
3045
|
+
return isVectorArray(x) || (x != null && x[SORTED_TAG] === true);
|
|
3046
|
+
}
|
|
3047
|
+
|
|
2507
3048
|
export function rseq(x) {
|
|
2508
3049
|
// vectors and sorted maps/sets are reversible, like CLJS
|
|
2509
3050
|
if (isVectorArray(x)) {
|
|
@@ -2717,6 +3258,7 @@ export function count(coll) {
|
|
|
2717
3258
|
if (typeof len === 'number') {
|
|
2718
3259
|
return len;
|
|
2719
3260
|
}
|
|
3261
|
+
if (coll[ICounted__count] !== undefined) return coll[ICounted__count](coll);
|
|
2720
3262
|
// sum chunk lengths instead of counting elements one by one
|
|
2721
3263
|
const next = chunkCursor(coll);
|
|
2722
3264
|
let ret = 0;
|
|
@@ -2741,6 +3283,15 @@ export function boolean$(x) {
|
|
|
2741
3283
|
return truth_(x);
|
|
2742
3284
|
}
|
|
2743
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
|
+
|
|
2744
3295
|
export function zero_QMARK_(x) {
|
|
2745
3296
|
return x === 0;
|
|
2746
3297
|
}
|
|
@@ -2867,6 +3418,7 @@ export function reduce_kv(f, init, m) {
|
|
|
2867
3418
|
if (!m) {
|
|
2868
3419
|
return init;
|
|
2869
3420
|
}
|
|
3421
|
+
if (m[IKVReduce__kv_reduce] !== undefined) return m[IKVReduce__kv_reduce](m, f, init);
|
|
2870
3422
|
var ret = init;
|
|
2871
3423
|
for (const o of iterable(m)) {
|
|
2872
3424
|
ret = f(ret, o[0], o[1]);
|
|
@@ -2888,11 +3440,25 @@ export function min(x, ...more) {
|
|
|
2888
3440
|
return m;
|
|
2889
3441
|
}
|
|
2890
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
|
+
|
|
2891
3456
|
export function map_QMARK_(coll) {
|
|
2892
3457
|
if (coll == null) return false;
|
|
2893
3458
|
if (isObj(coll)) return true;
|
|
2894
3459
|
if (coll instanceof Map) return true;
|
|
2895
3460
|
if (coll[TYPE_TAG] === MAP_TYPE) return true;
|
|
3461
|
+
if (coll[IMap.__sym] !== undefined) return true;
|
|
2896
3462
|
return false;
|
|
2897
3463
|
}
|
|
2898
3464
|
|
|
@@ -2967,6 +3533,24 @@ export function nnext(x) {
|
|
|
2967
3533
|
return next(next(x));
|
|
2968
3534
|
}
|
|
2969
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
|
+
|
|
2970
3554
|
export function compare(x, y) {
|
|
2971
3555
|
if (x === y) {
|
|
2972
3556
|
return 0;
|
|
@@ -3076,6 +3660,14 @@ export function keys(obj) {
|
|
|
3076
3660
|
if (obj == null) return null;
|
|
3077
3661
|
const t = typeConst(obj);
|
|
3078
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
|
|
3079
3671
|
case OBJECT_TYPE: {
|
|
3080
3672
|
const ks = Object.keys(obj);
|
|
3081
3673
|
if (ks.length) return ks;
|
|
@@ -3100,6 +3692,13 @@ export function vals(obj) {
|
|
|
3100
3692
|
if (obj == null) return null;
|
|
3101
3693
|
const t = typeConst(obj);
|
|
3102
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
|
|
3103
3702
|
case OBJECT_TYPE: {
|
|
3104
3703
|
const vs = Object.values(obj);
|
|
3105
3704
|
if (vs.length) return vs;
|
|
@@ -3183,6 +3782,26 @@ export function qualified_keyword_QMARK_(x) {
|
|
|
3183
3782
|
return typeof x === 'string' && x.includes('/');
|
|
3184
3783
|
}
|
|
3185
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
|
+
|
|
3186
3805
|
export function coll_QMARK_(coll) {
|
|
3187
3806
|
return typeConst(coll) != undefined;
|
|
3188
3807
|
}
|
|
@@ -3226,6 +3845,11 @@ export function double_QMARK_(x) {
|
|
|
3226
3845
|
return typeof x === 'number';
|
|
3227
3846
|
}
|
|
3228
3847
|
|
|
3848
|
+
// like CLJS: every number is a float
|
|
3849
|
+
export function float_QMARK_(x) {
|
|
3850
|
+
return double_QMARK_(x);
|
|
3851
|
+
}
|
|
3852
|
+
|
|
3229
3853
|
export const integer_QMARK_ = int_QMARK_;
|
|
3230
3854
|
|
|
3231
3855
|
export function pos_int_QMARK_(x) {
|
|
@@ -3241,30 +3865,41 @@ export function neg_int_QMARK_(x) {
|
|
|
3241
3865
|
}
|
|
3242
3866
|
|
|
3243
3867
|
export function meta(x) {
|
|
3244
|
-
if (x
|
|
3245
|
-
return x[
|
|
3246
|
-
}
|
|
3868
|
+
if (x != null && x[IMeta__meta] !== undefined) {
|
|
3869
|
+
return x[IMeta__meta](x);
|
|
3870
|
+
}
|
|
3871
|
+
return null;
|
|
3247
3872
|
}
|
|
3248
3873
|
|
|
3249
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) {
|
|
3250
3889
|
// For functions, wrap in a new callable that forwards to the original
|
|
3251
3890
|
// so fn? stays true and the original isn't mutated. copy() can't handle
|
|
3252
3891
|
// functions - a {...x} spread loses the call signature.
|
|
3253
3892
|
if (typeof x === 'function') {
|
|
3254
3893
|
const wrapped = function (...args) { return x.apply(this, args); };
|
|
3255
|
-
wrapped
|
|
3256
|
-
return wrapped;
|
|
3894
|
+
return installMeta(wrapped, m);
|
|
3257
3895
|
}
|
|
3258
3896
|
// A lazy seq or cons is not copied element-wise: clone the head so the new
|
|
3259
3897
|
// value carries its own metadata without forcing realization.
|
|
3260
3898
|
if (x?.[TYPE_TAG] === LAZY_ITERABLE_TYPE) {
|
|
3261
3899
|
const ret = Object.assign(Object.create(Object.getPrototypeOf(x)), x);
|
|
3262
|
-
ret
|
|
3263
|
-
return ret;
|
|
3900
|
+
return installMeta(ret, m);
|
|
3264
3901
|
}
|
|
3265
|
-
|
|
3266
|
-
ret[_metaSym] = m;
|
|
3267
|
-
return ret;
|
|
3902
|
+
return installMeta(copy(x), m);
|
|
3268
3903
|
}
|
|
3269
3904
|
|
|
3270
3905
|
export function vary_meta(x, f, ...args) {
|
|
@@ -3281,6 +3916,7 @@ export function counted_QMARK_(x) {
|
|
|
3281
3916
|
case ARRAY_TYPE:
|
|
3282
3917
|
case MAP_TYPE:
|
|
3283
3918
|
case OBJECT_TYPE:
|
|
3919
|
+
case INSTANCE_TYPE:
|
|
3284
3920
|
case LIST_TYPE:
|
|
3285
3921
|
case SET_TYPE:
|
|
3286
3922
|
return true;
|
|
@@ -3454,10 +4090,12 @@ export function flatten(x) {
|
|
|
3454
4090
|
}
|
|
3455
4091
|
|
|
3456
4092
|
export function transient$(x) {
|
|
4093
|
+
if (x != null && x[IEditableCollection__as_transient] !== undefined) return x[IEditableCollection__as_transient](x);
|
|
3457
4094
|
return copy(x);
|
|
3458
4095
|
}
|
|
3459
4096
|
|
|
3460
4097
|
export function persistent_BANG_(x) {
|
|
4098
|
+
if (x != null && x[ITransientCollection__persistent_BANG_] !== undefined) return x[ITransientCollection__persistent_BANG_](x);
|
|
3461
4099
|
// no Object.freeze: persistent structures stay extensible so symbol-keyed
|
|
3462
4100
|
// metadata can be attached
|
|
3463
4101
|
return x;
|
|
@@ -3691,6 +4329,18 @@ export function double$(x) {
|
|
|
3691
4329
|
return x;
|
|
3692
4330
|
}
|
|
3693
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
|
+
|
|
3694
4344
|
export function type(x) {
|
|
3695
4345
|
return x != null && x.constructor;
|
|
3696
4346
|
}
|
|
@@ -3744,6 +4394,8 @@ export function peek(vec) {
|
|
|
3744
4394
|
return first(vec);
|
|
3745
4395
|
} else if (array_QMARK_(vec)) {
|
|
3746
4396
|
return vec[vec.length - 1];
|
|
4397
|
+
} else if (vec[IStack__peek] !== undefined) {
|
|
4398
|
+
return vec[IStack__peek](vec);
|
|
3747
4399
|
} else {
|
|
3748
4400
|
throw missing_protocol('IStack.-peek', vec);
|
|
3749
4401
|
}
|
|
@@ -3759,13 +4411,30 @@ export function pop(vec) {
|
|
|
3759
4411
|
const ret = [...vec];
|
|
3760
4412
|
ret.pop();
|
|
3761
4413
|
return ret;
|
|
4414
|
+
} else if (vec[IStack__pop] !== undefined) {
|
|
4415
|
+
return vec[IStack__pop](vec);
|
|
3762
4416
|
} else {
|
|
3763
4417
|
throw missing_protocol('IStack.-pop', vec);
|
|
3764
4418
|
}
|
|
3765
4419
|
}
|
|
3766
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
|
+
|
|
3767
4433
|
export function update_keys(m, f) {
|
|
3768
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
|
+
}
|
|
3769
4438
|
const assocFn = getAssocMut(m) || assoc_BANG_;
|
|
3770
4439
|
reduce_kv(
|
|
3771
4440
|
(acc, k, v) => {
|
|
@@ -3779,6 +4448,9 @@ export function update_keys(m, f) {
|
|
|
3779
4448
|
|
|
3780
4449
|
export function update_vals(m, f) {
|
|
3781
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
|
+
}
|
|
3782
4454
|
const assocFn = getAssocMut(m) || assoc_BANG_;
|
|
3783
4455
|
reduce_kv(
|
|
3784
4456
|
(acc, k, v) => {
|
|
@@ -3859,12 +4531,15 @@ function clj__GT_js_(x, seen) {
|
|
|
3859
4531
|
// we need to protect against circular objects
|
|
3860
4532
|
if (seen.has(x)) return x;
|
|
3861
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
|
+
}
|
|
3862
4537
|
if (map_QMARK_(x)) {
|
|
3863
4538
|
return update_vals(x, (x) => clj__GT_js_(x, seen));
|
|
3864
4539
|
}
|
|
3865
4540
|
|
|
3866
4541
|
const tc = typeConst(x);
|
|
3867
|
-
if (tc && tc != OBJECT_TYPE) {
|
|
4542
|
+
if (tc && tc != OBJECT_TYPE && tc != INSTANCE_TYPE) {
|
|
3868
4543
|
return mapv((x) => clj__GT_js_(x, seen), x);
|
|
3869
4544
|
}
|
|
3870
4545
|
return x;
|
|
@@ -3940,6 +4615,18 @@ function toEDN(value, seen = new WeakSet(), readably = true) {
|
|
|
3940
4615
|
result = `(${mapv((v) => `${toEDN(v, seen, readably)}`, value).join(', ')})`;
|
|
3941
4616
|
break;
|
|
3942
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
|
+
}
|
|
3943
4630
|
// Non-plain objects (Promise, Error, Date, class instances, ...) have a
|
|
3944
4631
|
// constructor other than Object. Print them as #<Name> rather than {}
|
|
3945
4632
|
// (which is what Object.keys would yield for opaque values like a
|
|
@@ -3966,3 +4653,8 @@ export function prn(...xs) {
|
|
|
3966
4653
|
_STAR_print_fn_STAR_.val(pr_str(...xs));
|
|
3967
4654
|
if (_STAR_print_newline_STAR_.val) _STAR_print_fn_STAR_.val('\n');
|
|
3968
4655
|
}
|
|
4656
|
+
|
|
4657
|
+
export function prn_str(...xs) {
|
|
4658
|
+
return pr_str(...xs) + '\n';
|
|
4659
|
+
}
|
|
4660
|
+
|