@calcit/procs 0.11.0-a8 → 0.11.0
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/.yarn/install-state.gz +0 -0
- package/build.rs +74 -0
- package/lib/calcit-data.mjs +50 -0
- package/lib/calcit.procs.mjs +101 -42
- package/lib/custom-formatter.mjs +2 -2
- package/lib/js-cirru.mjs +10 -3
- package/lib/js-enum.mjs +13 -7
- package/lib/js-impl.mjs +34 -0
- package/lib/js-primes.mjs +8 -4
- package/lib/js-record.mjs +19 -9
- package/lib/js-struct.mjs +3 -3
- package/lib/js-tuple.mjs +12 -10
- package/lib/package.json +1 -1
- package/package.json +1 -1
- package/ts-src/calcit-data.mts +50 -0
- package/ts-src/calcit.procs.mts +110 -49
- package/ts-src/custom-formatter.mts +2 -2
- package/ts-src/js-cirru.mts +7 -4
- package/ts-src/js-enum.mts +14 -8
- package/ts-src/js-impl.mts +47 -0
- package/ts-src/js-primes.mts +6 -0
- package/ts-src/js-record.mts +22 -12
- package/ts-src/js-struct.mts +6 -6
- package/ts-src/js-tuple.mts +15 -11
package/.yarn/install-state.gz
CHANGED
|
Binary file
|
package/build.rs
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
use cirru_edn::{Edn, from_edn};
|
|
2
|
+
use cirru_parser::Cirru;
|
|
3
|
+
use serde::{Deserialize, Serialize};
|
|
4
|
+
use std::collections::HashMap;
|
|
5
|
+
use std::env;
|
|
6
|
+
use std::fs;
|
|
7
|
+
use std::path::Path;
|
|
8
|
+
|
|
9
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
10
|
+
pub struct SnapshotConfigs {
|
|
11
|
+
#[serde(rename = "init-fn")]
|
|
12
|
+
pub init_fn: String,
|
|
13
|
+
#[serde(rename = "reload-fn")]
|
|
14
|
+
pub reload_fn: String,
|
|
15
|
+
#[serde(default)]
|
|
16
|
+
pub modules: Vec<String>,
|
|
17
|
+
#[serde(default)]
|
|
18
|
+
pub version: String,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
22
|
+
pub struct CodeEntry {
|
|
23
|
+
pub doc: String,
|
|
24
|
+
#[serde(default)]
|
|
25
|
+
pub examples: Vec<Cirru>,
|
|
26
|
+
pub code: Cirru,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
30
|
+
pub struct FileInSnapShot {
|
|
31
|
+
pub ns: CodeEntry,
|
|
32
|
+
pub defs: HashMap<String, CodeEntry>,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
36
|
+
pub struct Snapshot {
|
|
37
|
+
pub package: String,
|
|
38
|
+
pub about: Option<String>,
|
|
39
|
+
pub configs: SnapshotConfigs,
|
|
40
|
+
pub entries: HashMap<String, SnapshotConfigs>,
|
|
41
|
+
pub files: HashMap<String, FileInSnapShot>,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fn main() {
|
|
45
|
+
println!("cargo:rerun-if-changed=src/cirru/calcit-core.cirru");
|
|
46
|
+
|
|
47
|
+
let out_dir = env::var_os("OUT_DIR").unwrap();
|
|
48
|
+
let dest_path = Path::new(&out_dir).join("calcit-core.rmp");
|
|
49
|
+
|
|
50
|
+
let core_content = fs::read_to_string("src/cirru/calcit-core.cirru").expect("read core");
|
|
51
|
+
let core_data = cirru_edn::parse(&core_content).expect("parse core");
|
|
52
|
+
|
|
53
|
+
// Minimal logic to convert Edn to Snapshot as in src/snapshot.rs
|
|
54
|
+
let data = core_data.view_map().expect("map");
|
|
55
|
+
let pkg: String = from_edn(data.get_or_nil("package")).expect("pkg");
|
|
56
|
+
let about = match data.get_or_nil("about") {
|
|
57
|
+
Edn::Nil => None,
|
|
58
|
+
value => Some(from_edn::<String>(value).expect("about")),
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
let files: HashMap<String, FileInSnapShot> = from_edn(data.get_or_nil("files")).expect("files");
|
|
62
|
+
|
|
63
|
+
let snapshot = Snapshot {
|
|
64
|
+
package: pkg,
|
|
65
|
+
about,
|
|
66
|
+
configs: from_edn(data.get_or_nil("configs")).expect("configs"),
|
|
67
|
+
entries: from_edn(data.get_or_nil("entries")).expect("entries"),
|
|
68
|
+
files,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
let mut buf = Vec::new();
|
|
72
|
+
snapshot.serialize(&mut rmp_serde::Serializer::new(&mut buf)).expect("serialize");
|
|
73
|
+
fs::write(dest_path, buf).expect("write");
|
|
74
|
+
}
|
package/lib/calcit-data.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { overwriteComparator } from "@calcit/ternary-tree";
|
|
|
3
3
|
import { overwriteMapComparator } from "./js-map.mjs";
|
|
4
4
|
import { disableListStructureCheck } from "@calcit/ternary-tree";
|
|
5
5
|
import { CalcitRecord, fieldsEqual } from "./js-record.mjs";
|
|
6
|
+
import { CalcitImpl } from "./js-impl.mjs";
|
|
6
7
|
import { CalcitStruct } from "./js-struct.mjs";
|
|
7
8
|
import { CalcitEnum } from "./js-enum.mjs";
|
|
8
9
|
import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
|
|
@@ -66,6 +67,9 @@ export let isNestedCalcitData = (x) => {
|
|
|
66
67
|
if (x instanceof CalcitRecord) {
|
|
67
68
|
return x.fields.length > 0;
|
|
68
69
|
}
|
|
70
|
+
if (x instanceof CalcitImpl) {
|
|
71
|
+
return x.fields.length > 0;
|
|
72
|
+
}
|
|
69
73
|
if (x instanceof CalcitSet) {
|
|
70
74
|
return false;
|
|
71
75
|
}
|
|
@@ -81,6 +85,9 @@ export let tipNestedCalcitData = (x) => {
|
|
|
81
85
|
if (x instanceof CalcitRecord) {
|
|
82
86
|
return "'%{}...";
|
|
83
87
|
}
|
|
88
|
+
if (x instanceof CalcitImpl) {
|
|
89
|
+
return "'%impl...";
|
|
90
|
+
}
|
|
84
91
|
if (x instanceof CalcitSet) {
|
|
85
92
|
return "'#{}...";
|
|
86
93
|
}
|
|
@@ -156,6 +163,7 @@ let defaultHash_set = valueHash("set:");
|
|
|
156
163
|
let defaultHash_list = valueHash("list:");
|
|
157
164
|
let defaultHash_map = valueHash("map:");
|
|
158
165
|
let defaultHash_record = valueHash("record:");
|
|
166
|
+
let defaultHash_impl = valueHash("impl:");
|
|
159
167
|
let defaultHash_struct = valueHash("struct:");
|
|
160
168
|
let defaultHash_enum = valueHash("enum:");
|
|
161
169
|
let defaultHash_cirru_quote = valueHash("cirru-quote:");
|
|
@@ -280,6 +288,19 @@ export let hashFunction = (x) => {
|
|
|
280
288
|
x.cachedHash = base;
|
|
281
289
|
return base;
|
|
282
290
|
}
|
|
291
|
+
if (x instanceof CalcitImpl) {
|
|
292
|
+
let base = defaultHash_impl;
|
|
293
|
+
base = mergeValueHash(base, hashFunction(x.name));
|
|
294
|
+
if (x.origin != null) {
|
|
295
|
+
base = mergeValueHash(base, hashFunction(x.origin));
|
|
296
|
+
}
|
|
297
|
+
for (let idx = 0; idx < x.fields.length; idx++) {
|
|
298
|
+
base = mergeValueHash(base, hashFunction(x.fields[idx]));
|
|
299
|
+
base = mergeValueHash(base, hashFunction(x.values[idx]));
|
|
300
|
+
}
|
|
301
|
+
x.cachedHash = base;
|
|
302
|
+
return base;
|
|
303
|
+
}
|
|
283
304
|
if (x instanceof CalcitStruct) {
|
|
284
305
|
let base = defaultHash_struct;
|
|
285
306
|
base = mergeValueHash(base, hashFunction(x.name));
|
|
@@ -376,6 +397,9 @@ export let toString = (x, escaped, disableJsDataWarning = false) => {
|
|
|
376
397
|
if (x instanceof CalcitRecord) {
|
|
377
398
|
return x.toString(disableJsDataWarning);
|
|
378
399
|
}
|
|
400
|
+
if (x instanceof CalcitImpl) {
|
|
401
|
+
return x.toString(disableJsDataWarning);
|
|
402
|
+
}
|
|
379
403
|
if (x instanceof CalcitStruct) {
|
|
380
404
|
return x.toString(disableJsDataWarning);
|
|
381
405
|
}
|
|
@@ -644,6 +668,32 @@ export let _$n__$e_ = (x, y) => {
|
|
|
644
668
|
}
|
|
645
669
|
return false;
|
|
646
670
|
}
|
|
671
|
+
if (x instanceof CalcitImpl) {
|
|
672
|
+
if (y instanceof CalcitImpl) {
|
|
673
|
+
if (x.name !== y.name) {
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
if ((x.origin == null) !== (y.origin == null)) {
|
|
677
|
+
return false;
|
|
678
|
+
}
|
|
679
|
+
if (x.origin != null && y.origin != null && x.origin.name.value !== y.origin.name.value) {
|
|
680
|
+
return false;
|
|
681
|
+
}
|
|
682
|
+
if (!fieldsEqual(x.fields, y.fields)) {
|
|
683
|
+
return false;
|
|
684
|
+
}
|
|
685
|
+
if (x.values.length !== y.values.length) {
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
688
|
+
for (let idx = 0; idx < x.fields.length; idx++) {
|
|
689
|
+
if (!_$n__$e_(x.values[idx], y.values[idx])) {
|
|
690
|
+
return false;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return true;
|
|
694
|
+
}
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
647
697
|
if (x instanceof CalcitStruct) {
|
|
648
698
|
if (y instanceof CalcitStruct) {
|
|
649
699
|
return x.name === y.name && fieldsEqual(x.fields, y.fields);
|
package/lib/calcit.procs.mjs
CHANGED
|
@@ -6,11 +6,13 @@ import { writeCirruCode } from "@cirru/writer.ts";
|
|
|
6
6
|
import { CalcitSymbol, CalcitTag, CalcitRecur, castTag, newTag, refsRegistry, toString, getStringName, _$n__$e_, hashFunction, } from "./calcit-data.mjs";
|
|
7
7
|
import { CalcitRef } from "./js-ref.mjs";
|
|
8
8
|
import { CalcitRecord } from "./js-record.mjs";
|
|
9
|
+
import { CalcitImpl } from "./js-impl.mjs";
|
|
9
10
|
import { CalcitStruct } from "./js-struct.mjs";
|
|
10
11
|
import { CalcitEnum } from "./js-enum.mjs";
|
|
11
12
|
import { CalcitTrait } from "./js-trait.mjs";
|
|
12
13
|
export * from "./calcit-data.mjs";
|
|
13
14
|
export * from "./js-record.mjs";
|
|
15
|
+
export * from "./js-impl.mjs";
|
|
14
16
|
export * from "./js-struct.mjs";
|
|
15
17
|
export * from "./js-enum.mjs";
|
|
16
18
|
export * from "./js-map.mjs";
|
|
@@ -62,6 +64,9 @@ export let type_of = (x) => {
|
|
|
62
64
|
if (x instanceof CalcitRecord) {
|
|
63
65
|
return newTag("record");
|
|
64
66
|
}
|
|
67
|
+
if (x instanceof CalcitImpl) {
|
|
68
|
+
return newTag("impl");
|
|
69
|
+
}
|
|
65
70
|
if (x instanceof CalcitStruct) {
|
|
66
71
|
return newTag("struct");
|
|
67
72
|
}
|
|
@@ -193,7 +198,47 @@ export let defenum = (name, ...variants) => {
|
|
|
193
198
|
const tags = entries.map((entry) => entry.tag);
|
|
194
199
|
const values = entries.map((entry) => entry.payload);
|
|
195
200
|
const prototype = new CalcitRecord(enumName, tags, values, null);
|
|
196
|
-
return new CalcitEnum(prototype
|
|
201
|
+
return new CalcitEnum(prototype);
|
|
202
|
+
};
|
|
203
|
+
export let _$n_impl_$o__$o_new = (name, ...pairs) => {
|
|
204
|
+
if (name === undefined)
|
|
205
|
+
throw new Error("&impl::new expected arguments");
|
|
206
|
+
const origin = name instanceof CalcitTrait ? name : null;
|
|
207
|
+
const implName = origin ? origin.name : castTag(name);
|
|
208
|
+
if (pairs.length === 0) {
|
|
209
|
+
return new CalcitImpl(implName, [], [], origin);
|
|
210
|
+
}
|
|
211
|
+
const entries = [];
|
|
212
|
+
for (let idx = 0; idx < pairs.length; idx++) {
|
|
213
|
+
const pairValue = pairs[idx];
|
|
214
|
+
let fieldTag;
|
|
215
|
+
let value;
|
|
216
|
+
if (pairValue instanceof CalcitTuple) {
|
|
217
|
+
if (pairValue.extra.length !== 1) {
|
|
218
|
+
throw new Error(`&impl::new expects (field value) pairs, got: ${toString(pairValue, true)}`);
|
|
219
|
+
}
|
|
220
|
+
fieldTag = castTag(pairValue.tag);
|
|
221
|
+
value = pairValue.extra[0];
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
const pair = list_items(pairValue);
|
|
225
|
+
if (pair.length !== 2) {
|
|
226
|
+
throw new Error(`&impl::new expects (field value) pairs, got: ${toString(pairValue, true)}`);
|
|
227
|
+
}
|
|
228
|
+
fieldTag = castTag(pair[0]);
|
|
229
|
+
value = pair[1];
|
|
230
|
+
}
|
|
231
|
+
entries.push({ tag: fieldTag, value });
|
|
232
|
+
}
|
|
233
|
+
entries.sort((a, b) => a.tag.idx - b.tag.idx);
|
|
234
|
+
for (let i = 1; i < entries.length; i++) {
|
|
235
|
+
if (entries[i - 1].tag.value === entries[i].tag.value) {
|
|
236
|
+
throw new Error(`&impl::new duplicated field: ${entries[i].tag.toString()}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const fields = entries.map((entry) => entry.tag);
|
|
240
|
+
const values = entries.map((entry) => entry.value);
|
|
241
|
+
return new CalcitImpl(implName, fields, values, origin);
|
|
197
242
|
};
|
|
198
243
|
export let _$n_struct_$o__$o_new = (name, ...entries) => {
|
|
199
244
|
return defstruct(name, ...entries);
|
|
@@ -385,6 +430,12 @@ export let _$n_tuple_$o_count = function (xs) {
|
|
|
385
430
|
return xs.count();
|
|
386
431
|
throw new Error("Does not support `count` on this type");
|
|
387
432
|
};
|
|
433
|
+
const coerce_impl = (value, procName) => {
|
|
434
|
+
if (value instanceof CalcitImpl) {
|
|
435
|
+
return value;
|
|
436
|
+
}
|
|
437
|
+
throw new Error(`${procName} expects trait impls as impls`);
|
|
438
|
+
};
|
|
388
439
|
export let _$n_tuple_$o_impls = function (x) {
|
|
389
440
|
if (arguments.length !== 1)
|
|
390
441
|
throw new Error("&tuple:impls takes 1 argument");
|
|
@@ -400,21 +451,26 @@ export let _$n_tuple_$o_with_impls = function (x, y) {
|
|
|
400
451
|
throw new Error("&tuple:with-impls takes 2 arguments");
|
|
401
452
|
if (!(x instanceof CalcitTuple))
|
|
402
453
|
throw new Error("&tuple:with-impls expects a tuple");
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
454
|
+
const impl = coerce_impl(y, "&tuple:with-impls");
|
|
455
|
+
let proto = x.enumPrototype;
|
|
456
|
+
if (proto == null) {
|
|
457
|
+
proto = new CalcitEnum(new CalcitRecord(newTag("anonymous-tuple"), [], [], new CalcitStruct(newTag("anonymous-tuple"), [], [])));
|
|
458
|
+
}
|
|
459
|
+
return new CalcitTuple(x.tag, x.extra, proto.withImpls(impl));
|
|
406
460
|
};
|
|
407
461
|
export let _$n_tuple_$o_impl_traits = function (x, ...traits) {
|
|
408
462
|
if (traits.length < 1)
|
|
409
463
|
throw new Error("&tuple:impl-traits takes 2+ arguments");
|
|
410
464
|
if (!(x instanceof CalcitTuple))
|
|
411
465
|
throw new Error("&tuple:impl-traits expects a tuple");
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
466
|
+
const impls = traits.map((trait) => coerce_impl(trait, "&tuple:impl-traits"));
|
|
467
|
+
let proto = x.enumPrototype;
|
|
468
|
+
if (proto == null) {
|
|
469
|
+
const tagName = x.tag instanceof CalcitTag ? x.tag : newTag("tag");
|
|
470
|
+
const anyTypes = new CalcitSliceList(new Array(x.extra.length).fill(newTag("any")));
|
|
471
|
+
proto = new CalcitEnum(new CalcitRecord(newTag("anonymous-tuple"), [tagName], [anyTypes], new CalcitStruct(newTag("anonymous-tuple"), [tagName], [anyTypes])));
|
|
416
472
|
}
|
|
417
|
-
return new CalcitTuple(x.tag, x.extra,
|
|
473
|
+
return new CalcitTuple(x.tag, x.extra, proto.withImpls(impls));
|
|
418
474
|
};
|
|
419
475
|
export let _$n_tuple_$o_enum = function (x) {
|
|
420
476
|
if (arguments.length !== 1)
|
|
@@ -427,7 +483,7 @@ export let _$n_tuple_$o_enum = function (x) {
|
|
|
427
483
|
if (x.enumPrototype instanceof CalcitEnum) {
|
|
428
484
|
return x.enumPrototype;
|
|
429
485
|
}
|
|
430
|
-
return new CalcitEnum(x.enumPrototype
|
|
486
|
+
return new CalcitEnum(x.enumPrototype);
|
|
431
487
|
};
|
|
432
488
|
const unwrap_enum_prototype = (enumPrototype, procName) => {
|
|
433
489
|
if (enumPrototype instanceof CalcitEnum) {
|
|
@@ -539,7 +595,7 @@ export let _$n_record_$o_impls = function (xs) {
|
|
|
539
595
|
if (arguments.length !== 1)
|
|
540
596
|
throw new Error("&record:impls takes 1 argument");
|
|
541
597
|
if (xs instanceof CalcitRecord)
|
|
542
|
-
return new CalcitSliceList(xs.impls);
|
|
598
|
+
return new CalcitSliceList(xs.structRef.impls);
|
|
543
599
|
throw new Error("&record:impls expected a record");
|
|
544
600
|
};
|
|
545
601
|
export let _$n_record_$o_impl_traits = function (xs, ...traits) {
|
|
@@ -547,43 +603,40 @@ export let _$n_record_$o_impl_traits = function (xs, ...traits) {
|
|
|
547
603
|
throw new Error("&record:impl-traits takes 2+ arguments");
|
|
548
604
|
if (!(xs instanceof CalcitRecord))
|
|
549
605
|
throw new Error("&record:impl-traits expected a record");
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
return new CalcitRecord(xs.name, xs.fields, xs.values, xs.impls.concat(traits));
|
|
606
|
+
const impls = traits.map((trait) => coerce_impl(trait, "&record:impl-traits"));
|
|
607
|
+
const nextStruct = new CalcitStruct(xs.name, xs.fields, xs.structRef.fieldTypes, xs.structRef.impls.concat(impls));
|
|
608
|
+
return new CalcitRecord(xs.name, xs.fields, xs.values, nextStruct);
|
|
556
609
|
};
|
|
557
610
|
export let _$n_struct_$o_impl_traits = function (xs, ...traits) {
|
|
558
611
|
if (traits.length < 1)
|
|
559
612
|
throw new Error("&struct:impl-traits takes 2+ arguments");
|
|
560
613
|
if (!(xs instanceof CalcitStruct))
|
|
561
614
|
throw new Error("&struct:impl-traits expected a struct");
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
const impls = xs.impls ?? [];
|
|
568
|
-
return new CalcitStruct(xs.name, xs.fields, xs.fieldTypes, impls.concat(traits));
|
|
615
|
+
const addedImpls = traits.map((trait) => coerce_impl(trait, "&struct:impl-traits"));
|
|
616
|
+
const baseImpls = xs.impls ?? [];
|
|
617
|
+
return new CalcitStruct(xs.name, xs.fields, xs.fieldTypes, baseImpls.concat(addedImpls));
|
|
569
618
|
};
|
|
570
619
|
export let _$n_enum_$o_impl_traits = function (xs, ...traits) {
|
|
571
620
|
if (traits.length < 1)
|
|
572
621
|
throw new Error("&enum:impl-traits takes 2+ arguments");
|
|
573
|
-
|
|
574
|
-
if (!(traits[idx] instanceof CalcitRecord)) {
|
|
575
|
-
throw new Error("&enum:impl-traits expects trait impls as records");
|
|
576
|
-
}
|
|
577
|
-
}
|
|
622
|
+
const addedImpls = traits.map((trait) => coerce_impl(trait, "&enum:impl-traits"));
|
|
578
623
|
if (xs instanceof CalcitEnum) {
|
|
579
|
-
|
|
580
|
-
return new CalcitEnum(xs.prototype, impls.concat(traits));
|
|
624
|
+
return xs.withImpls(addedImpls);
|
|
581
625
|
}
|
|
582
626
|
if (xs instanceof CalcitRecord) {
|
|
583
|
-
|
|
627
|
+
const nextStruct = new CalcitStruct(xs.name, xs.fields, xs.structRef.fieldTypes, xs.structRef.impls.concat(addedImpls));
|
|
628
|
+
return new CalcitRecord(xs.name, xs.fields, xs.values, nextStruct);
|
|
584
629
|
}
|
|
585
630
|
throw new Error("&enum:impl-traits expected an enum or enum record");
|
|
586
631
|
};
|
|
632
|
+
export let _$n_impl_$o_origin = function (impl) {
|
|
633
|
+
if (arguments.length !== 1)
|
|
634
|
+
throw new Error("&impl:origin expected 1 argument");
|
|
635
|
+
if (impl instanceof CalcitImpl) {
|
|
636
|
+
return impl.origin ?? null;
|
|
637
|
+
}
|
|
638
|
+
throw new Error(`&impl:origin expected an impl, but received: ${toString(impl, true)}`);
|
|
639
|
+
};
|
|
587
640
|
export let _$n_list_$o_assoc_before = function (xs, k, v) {
|
|
588
641
|
if (arguments.length !== 3) {
|
|
589
642
|
throw new Error("assoc takes 3 arguments");
|
|
@@ -1452,7 +1505,7 @@ export let _$n_js_object = (...xs) => {
|
|
|
1452
1505
|
return ret;
|
|
1453
1506
|
};
|
|
1454
1507
|
export let _$o__$o_ = (tagName, ...extra) => {
|
|
1455
|
-
return new CalcitTuple(tagName, extra,
|
|
1508
|
+
return new CalcitTuple(tagName, extra, null);
|
|
1456
1509
|
};
|
|
1457
1510
|
export let _PCT__$o__$o_ = (enumPrototype, tag, ...extra) => {
|
|
1458
1511
|
const proto = assert_enum_tag_args("%::", enumPrototype, tag);
|
|
@@ -1472,7 +1525,7 @@ export let _PCT__$o__$o_ = (enumPrototype, tag, ...extra) => {
|
|
|
1472
1525
|
throw new Error(`Expected variant definition to be a list, got ${variantDefinition}`);
|
|
1473
1526
|
}
|
|
1474
1527
|
const tupleEnumPrototype = enumPrototype instanceof CalcitEnum ? enumPrototype : proto;
|
|
1475
|
-
return new CalcitTuple(tag, extra,
|
|
1528
|
+
return new CalcitTuple(tag, extra, tupleEnumPrototype);
|
|
1476
1529
|
};
|
|
1477
1530
|
export let _PCT__PCT__$o__$o_ = (impl, enumPrototype, tag, ...extra) => {
|
|
1478
1531
|
// Runtime validation: check if tag exists in enum and arity matches
|
|
@@ -1493,7 +1546,8 @@ export let _PCT__PCT__$o__$o_ = (impl, enumPrototype, tag, ...extra) => {
|
|
|
1493
1546
|
throw new Error(`Expected variant definition to be a list, got ${variantDefinition}`);
|
|
1494
1547
|
}
|
|
1495
1548
|
const tupleEnumPrototype = enumPrototype instanceof CalcitEnum ? enumPrototype : proto;
|
|
1496
|
-
|
|
1549
|
+
const implValue = coerce_impl(impl, "%:: with impl");
|
|
1550
|
+
return new CalcitTuple(tag, extra, tupleEnumPrototype.withImpls(implValue));
|
|
1497
1551
|
};
|
|
1498
1552
|
let calcit_builtin_impls = {
|
|
1499
1553
|
number: null,
|
|
@@ -1516,10 +1570,14 @@ export function invoke_method_closure(p) {
|
|
|
1516
1570
|
function normalize_builtin_impls(entry) {
|
|
1517
1571
|
if (entry == null)
|
|
1518
1572
|
return null;
|
|
1519
|
-
if (entry instanceof
|
|
1573
|
+
if (entry instanceof CalcitImpl)
|
|
1520
1574
|
return [entry];
|
|
1521
1575
|
if (entry instanceof CalcitList || entry instanceof CalcitSliceList) {
|
|
1522
|
-
return list_items(entry)
|
|
1576
|
+
return list_items(entry).map((item) => {
|
|
1577
|
+
if (item instanceof CalcitImpl)
|
|
1578
|
+
return item;
|
|
1579
|
+
throw new Error(`invoke-method expects impls in list, but received: ${toString(item, true)}`);
|
|
1580
|
+
});
|
|
1523
1581
|
}
|
|
1524
1582
|
return null;
|
|
1525
1583
|
}
|
|
@@ -1536,7 +1594,7 @@ function lookup_impls(obj) {
|
|
|
1536
1594
|
}
|
|
1537
1595
|
else if (obj instanceof CalcitRecord) {
|
|
1538
1596
|
tag = obj.name.toString();
|
|
1539
|
-
impls = obj.impls;
|
|
1597
|
+
impls = obj.structRef.impls;
|
|
1540
1598
|
}
|
|
1541
1599
|
else if (obj instanceof CalcitTuple) {
|
|
1542
1600
|
tag = obj.tag.toString();
|
|
@@ -1641,14 +1699,15 @@ export function _$n_inspect_methods(obj, note) {
|
|
|
1641
1699
|
implsInOrder.push(impl);
|
|
1642
1700
|
idx += reverse ? -1 : 1;
|
|
1643
1701
|
}
|
|
1644
|
-
console.log(`
|
|
1702
|
+
console.log(`Impls (high → low precedence): ${implsInOrder.length}`);
|
|
1645
1703
|
for (let i = 0; i < implsInOrder.length; i++) {
|
|
1646
1704
|
let impl = implsInOrder[i];
|
|
1647
1705
|
let names = [];
|
|
1648
1706
|
for (let k = 0; k < impl.fields.length; k++) {
|
|
1649
1707
|
names.push("." + impl.fields[k].value);
|
|
1650
1708
|
}
|
|
1651
|
-
|
|
1709
|
+
const originName = impl.origin != null ? impl.origin.name.toString() : impl.name.toString();
|
|
1710
|
+
console.log(` #${i}: ${originName} (${names.join(" ")})`);
|
|
1652
1711
|
}
|
|
1653
1712
|
let ms = _$n_methods_of(obj);
|
|
1654
1713
|
console.log(`\nAll methods (unique, high → low): ${ms.len()}`);
|
|
@@ -1678,7 +1737,7 @@ export function _$n_trait_call(traitDef, method, obj, ...args) {
|
|
|
1678
1737
|
let idx = reverse ? impls.length - 1 : 0;
|
|
1679
1738
|
while (reverse ? idx >= 0 : idx < impls.length) {
|
|
1680
1739
|
const impl = impls[idx];
|
|
1681
|
-
if (impl != null && impl.name.value === traitDef.name.value) {
|
|
1740
|
+
if (impl != null && impl.origin != null && impl.origin.name.value === traitDef.name.value) {
|
|
1682
1741
|
const fn = impl.getOrNil(methodName);
|
|
1683
1742
|
if (fn != null) {
|
|
1684
1743
|
if (typeof fn !== "function") {
|
|
@@ -1689,7 +1748,7 @@ export function _$n_trait_call(traitDef, method, obj, ...args) {
|
|
|
1689
1748
|
}
|
|
1690
1749
|
idx += reverse ? -1 : 1;
|
|
1691
1750
|
}
|
|
1692
|
-
throw new Error(`&trait-call: cannot find impl for trait ${traitDef.name.toString()} on ${toString(obj, true)}. Hint: use defimpl to create
|
|
1751
|
+
throw new Error(`&trait-call: cannot find impl for trait ${traitDef.name.toString()} on ${toString(obj, true)}. Hint: use defimpl to create impls tagged by trait.`);
|
|
1693
1752
|
}
|
|
1694
1753
|
export let _$n_map_$o_to_list = (m) => {
|
|
1695
1754
|
if (m instanceof CalcitMap || m instanceof CalcitSliceMap) {
|
package/lib/custom-formatter.mjs
CHANGED
|
@@ -149,8 +149,8 @@ export let load_console_formatter_$x_ = () => {
|
|
|
149
149
|
}, `${obj.len()}`), preview);
|
|
150
150
|
}
|
|
151
151
|
if (obj instanceof CalcitRecord) {
|
|
152
|
-
if (obj.impls.length > 0) {
|
|
153
|
-
let ret = div({ color: hsl(280, 80, 60, 0.4), maxWidth: "100%" }, span({}, "%{}"), span({ marginLeft: "6px" }, embedObject(obj.impls[0])), span({ marginLeft: "6px" }, embedObject(obj.name)), span({ marginLeft: "6px" }, `...`));
|
|
152
|
+
if (obj.structRef.impls.length > 0) {
|
|
153
|
+
let ret = div({ color: hsl(280, 80, 60, 0.4), maxWidth: "100%" }, span({}, "%{}"), span({ marginLeft: "6px" }, embedObject(obj.structRef.impls[0])), span({ marginLeft: "6px" }, embedObject(obj.name)), span({ marginLeft: "6px" }, `...`));
|
|
154
154
|
return ret;
|
|
155
155
|
}
|
|
156
156
|
else {
|
package/lib/js-cirru.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import { CalcitSet } from "./js-set.mjs";
|
|
|
7
7
|
import { CalcitTag, CalcitSymbol, CalcitRecur, newTag } from "./calcit-data.mjs";
|
|
8
8
|
import { CalcitTuple } from "./js-tuple.mjs";
|
|
9
9
|
import { CalcitEnum } from "./js-enum.mjs";
|
|
10
|
+
import { CalcitImpl } from "./js-impl.mjs";
|
|
10
11
|
import { CalcitRef } from "./js-ref.mjs";
|
|
11
12
|
import { deepEqual } from "@calcit/ternary-tree/lib/utils.mjs";
|
|
12
13
|
import { atom } from "./js-ref.mjs";
|
|
@@ -182,6 +183,9 @@ export let to_cirru_edn = (x) => {
|
|
|
182
183
|
else if (x.tag instanceof CalcitRecord) {
|
|
183
184
|
return ["%::", enumTag, x.tag.name.toString(), ...x.extra.map(to_cirru_edn)];
|
|
184
185
|
}
|
|
186
|
+
else if (x.tag instanceof CalcitImpl) {
|
|
187
|
+
return ["%::", enumTag, x.tag.name.toString(), ...x.extra.map(to_cirru_edn)];
|
|
188
|
+
}
|
|
185
189
|
else {
|
|
186
190
|
throw new Error(`Unsupported tag for EDN: ${x.tag}`);
|
|
187
191
|
}
|
|
@@ -192,6 +196,9 @@ export let to_cirru_edn = (x) => {
|
|
|
192
196
|
else if (x.tag instanceof CalcitRecord) {
|
|
193
197
|
return ["::", x.tag.name.toString(), ...x.extra.map(to_cirru_edn)];
|
|
194
198
|
}
|
|
199
|
+
else if (x.tag instanceof CalcitImpl) {
|
|
200
|
+
return ["::", x.tag.name.toString(), ...x.extra.map(to_cirru_edn)];
|
|
201
|
+
}
|
|
195
202
|
else {
|
|
196
203
|
throw new Error(`Unsupported tag for EDN: ${x.tag}`);
|
|
197
204
|
}
|
|
@@ -353,7 +360,7 @@ export let extract_cirru_edn = (x, options) => {
|
|
|
353
360
|
if (!deepEqual(v.fields, fields)) {
|
|
354
361
|
throw new Error(`Fields mismatch for ${name}, expected ${fields}, got ${v.fields}`);
|
|
355
362
|
}
|
|
356
|
-
return new CalcitRecord(extractFieldTag(name), fields, values, v.
|
|
363
|
+
return new CalcitRecord(extractFieldTag(name), fields, values, v.structRef);
|
|
357
364
|
}
|
|
358
365
|
}
|
|
359
366
|
return new CalcitRecord(extractFieldTag(name), fields, values);
|
|
@@ -392,7 +399,7 @@ export let extract_cirru_edn = (x, options) => {
|
|
|
392
399
|
return new CalcitTuple(extract_cirru_edn(x[1], options), x
|
|
393
400
|
.slice(2)
|
|
394
401
|
.filter(notComment)
|
|
395
|
-
.map((x) => extract_cirru_edn(x, options))
|
|
402
|
+
.map((x) => extract_cirru_edn(x, options)));
|
|
396
403
|
}
|
|
397
404
|
if (x[0] === "%::") {
|
|
398
405
|
if (x.length < 3) {
|
|
@@ -409,7 +416,7 @@ export let extract_cirru_edn = (x, options) => {
|
|
|
409
416
|
return new CalcitTuple(extract_cirru_edn(x[2], options), x
|
|
410
417
|
.slice(3)
|
|
411
418
|
.filter(notComment)
|
|
412
|
-
.map((x) => extract_cirru_edn(x, options)),
|
|
419
|
+
.map((x) => extract_cirru_edn(x, options)), enumPrototype);
|
|
413
420
|
}
|
|
414
421
|
if (x[0] === "atom") {
|
|
415
422
|
if (x.length !== 2) {
|
package/lib/js-enum.mjs
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CalcitImpl } from "./js-impl.mjs";
|
|
2
2
|
export class CalcitEnum {
|
|
3
|
-
constructor(prototype
|
|
3
|
+
constructor(prototype) {
|
|
4
4
|
this.prototype = prototype;
|
|
5
|
-
this.impls = impls;
|
|
6
5
|
this.cachedHash = null;
|
|
7
6
|
}
|
|
8
7
|
name() {
|
|
9
8
|
return this.prototype.name.value;
|
|
10
9
|
}
|
|
10
|
+
get impls() {
|
|
11
|
+
return this.prototype.structRef.impls;
|
|
12
|
+
}
|
|
11
13
|
withImpls(impls) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
let nextImpls;
|
|
15
|
+
if (impls instanceof CalcitImpl) {
|
|
16
|
+
nextImpls = [impls];
|
|
14
17
|
}
|
|
15
18
|
else if (Array.isArray(impls)) {
|
|
16
|
-
|
|
19
|
+
nextImpls = impls;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
throw new Error("Expected an impl as implementation");
|
|
17
23
|
}
|
|
18
|
-
|
|
24
|
+
return new CalcitEnum(this.prototype.withImpls(nextImpls));
|
|
19
25
|
}
|
|
20
26
|
toString() {
|
|
21
27
|
return `(%enum :${this.prototype.name.value})`;
|
package/lib/js-impl.mjs
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { castTag, findInFields, toString } from "./calcit-data.mjs";
|
|
2
|
+
export class CalcitImpl {
|
|
3
|
+
constructor(name, fields, values, origin = null) {
|
|
4
|
+
this.name = name;
|
|
5
|
+
this.origin = origin;
|
|
6
|
+
this.fields = fields;
|
|
7
|
+
this.values = values;
|
|
8
|
+
this.cachedHash = null;
|
|
9
|
+
}
|
|
10
|
+
get(k) {
|
|
11
|
+
let field = castTag(k);
|
|
12
|
+
let idx = findInFields(this.fields, field);
|
|
13
|
+
if (idx >= 0) {
|
|
14
|
+
return this.values[idx];
|
|
15
|
+
}
|
|
16
|
+
throw new Error(`Cannot find :${field} among (${this.fields.join(",")})`);
|
|
17
|
+
}
|
|
18
|
+
getOrNil(k) {
|
|
19
|
+
let field = castTag(k);
|
|
20
|
+
let idx = findInFields(this.fields, field);
|
|
21
|
+
if (idx >= 0) {
|
|
22
|
+
return this.values[idx];
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
toString(disableJsDataWarning = false) {
|
|
27
|
+
const parts = ["(%impl ", this.name.toString()];
|
|
28
|
+
for (let idx = 0; idx < this.fields.length; idx++) {
|
|
29
|
+
parts.push(" (", this.fields[idx].toString(), " ", toString(this.values[idx], true, disableJsDataWarning), ")");
|
|
30
|
+
}
|
|
31
|
+
parts.push(")");
|
|
32
|
+
return parts.join("");
|
|
33
|
+
}
|
|
34
|
+
}
|
package/lib/js-primes.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { CalcitTag, CalcitSymbol, CalcitRecur } from "./calcit-data.mjs";
|
|
|
2
2
|
import { CalcitRef } from "./js-ref.mjs";
|
|
3
3
|
import { CalcitList, CalcitSliceList } from "./js-list.mjs";
|
|
4
4
|
import { CalcitRecord } from "./js-record.mjs";
|
|
5
|
+
import { CalcitImpl } from "./js-impl.mjs";
|
|
5
6
|
import { CalcitStruct } from "./js-struct.mjs";
|
|
6
7
|
import { CalcitEnum } from "./js-enum.mjs";
|
|
7
8
|
import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
|
|
@@ -38,10 +39,11 @@ var PseudoTypeIndex;
|
|
|
38
39
|
PseudoTypeIndex[PseudoTypeIndex["set"] = 10] = "set";
|
|
39
40
|
PseudoTypeIndex[PseudoTypeIndex["map"] = 11] = "map";
|
|
40
41
|
PseudoTypeIndex[PseudoTypeIndex["record"] = 12] = "record";
|
|
41
|
-
PseudoTypeIndex[PseudoTypeIndex["
|
|
42
|
-
PseudoTypeIndex[PseudoTypeIndex["
|
|
43
|
-
PseudoTypeIndex[PseudoTypeIndex["
|
|
44
|
-
PseudoTypeIndex[PseudoTypeIndex["
|
|
42
|
+
PseudoTypeIndex[PseudoTypeIndex["impl"] = 13] = "impl";
|
|
43
|
+
PseudoTypeIndex[PseudoTypeIndex["struct"] = 14] = "struct";
|
|
44
|
+
PseudoTypeIndex[PseudoTypeIndex["enum_type"] = 15] = "enum_type";
|
|
45
|
+
PseudoTypeIndex[PseudoTypeIndex["fn"] = 16] = "fn";
|
|
46
|
+
PseudoTypeIndex[PseudoTypeIndex["cirru_quote"] = 17] = "cirru_quote";
|
|
45
47
|
})(PseudoTypeIndex || (PseudoTypeIndex = {}));
|
|
46
48
|
let typeAsInt = (x) => {
|
|
47
49
|
// based on order used in Ord trait
|
|
@@ -72,6 +74,8 @@ let typeAsInt = (x) => {
|
|
|
72
74
|
return PseudoTypeIndex.map;
|
|
73
75
|
if (x instanceof CalcitRecord)
|
|
74
76
|
return PseudoTypeIndex.record;
|
|
77
|
+
if (x instanceof CalcitImpl)
|
|
78
|
+
return PseudoTypeIndex.impl;
|
|
75
79
|
if (x instanceof CalcitStruct)
|
|
76
80
|
return PseudoTypeIndex.struct;
|
|
77
81
|
if (x instanceof CalcitEnum)
|