@calcit/procs 0.11.0-a9 → 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 +9 -0
- package/lib/calcit.procs.mjs +39 -18
- package/lib/custom-formatter.mjs +2 -2
- package/lib/js-cirru.mjs +3 -3
- package/lib/js-enum.mjs +11 -5
- package/lib/js-impl.mjs +2 -1
- package/lib/js-record.mjs +17 -8
- package/lib/js-tuple.mjs +12 -10
- package/lib/package.json +1 -1
- package/package.json +1 -1
- package/ts-src/calcit-data.mts +9 -0
- package/ts-src/calcit.procs.mts +42 -19
- package/ts-src/custom-formatter.mts +2 -2
- package/ts-src/js-cirru.mts +2 -4
- package/ts-src/js-enum.mts +11 -6
- package/ts-src/js-impl.mts +4 -1
- package/ts-src/js-primes.mts +2 -0
- package/ts-src/js-record.mts +19 -10
- package/ts-src/js-tuple.mts +14 -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
|
@@ -291,6 +291,9 @@ export let hashFunction = (x) => {
|
|
|
291
291
|
if (x instanceof CalcitImpl) {
|
|
292
292
|
let base = defaultHash_impl;
|
|
293
293
|
base = mergeValueHash(base, hashFunction(x.name));
|
|
294
|
+
if (x.origin != null) {
|
|
295
|
+
base = mergeValueHash(base, hashFunction(x.origin));
|
|
296
|
+
}
|
|
294
297
|
for (let idx = 0; idx < x.fields.length; idx++) {
|
|
295
298
|
base = mergeValueHash(base, hashFunction(x.fields[idx]));
|
|
296
299
|
base = mergeValueHash(base, hashFunction(x.values[idx]));
|
|
@@ -670,6 +673,12 @@ export let _$n__$e_ = (x, y) => {
|
|
|
670
673
|
if (x.name !== y.name) {
|
|
671
674
|
return false;
|
|
672
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
|
+
}
|
|
673
682
|
if (!fieldsEqual(x.fields, y.fields)) {
|
|
674
683
|
return false;
|
|
675
684
|
}
|
package/lib/calcit.procs.mjs
CHANGED
|
@@ -198,14 +198,15 @@ export let defenum = (name, ...variants) => {
|
|
|
198
198
|
const tags = entries.map((entry) => entry.tag);
|
|
199
199
|
const values = entries.map((entry) => entry.payload);
|
|
200
200
|
const prototype = new CalcitRecord(enumName, tags, values, null);
|
|
201
|
-
return new CalcitEnum(prototype
|
|
201
|
+
return new CalcitEnum(prototype);
|
|
202
202
|
};
|
|
203
203
|
export let _$n_impl_$o__$o_new = (name, ...pairs) => {
|
|
204
204
|
if (name === undefined)
|
|
205
205
|
throw new Error("&impl::new expected arguments");
|
|
206
|
-
const
|
|
206
|
+
const origin = name instanceof CalcitTrait ? name : null;
|
|
207
|
+
const implName = origin ? origin.name : castTag(name);
|
|
207
208
|
if (pairs.length === 0) {
|
|
208
|
-
return new CalcitImpl(implName, [], []);
|
|
209
|
+
return new CalcitImpl(implName, [], [], origin);
|
|
209
210
|
}
|
|
210
211
|
const entries = [];
|
|
211
212
|
for (let idx = 0; idx < pairs.length; idx++) {
|
|
@@ -237,7 +238,7 @@ export let _$n_impl_$o__$o_new = (name, ...pairs) => {
|
|
|
237
238
|
}
|
|
238
239
|
const fields = entries.map((entry) => entry.tag);
|
|
239
240
|
const values = entries.map((entry) => entry.value);
|
|
240
|
-
return new CalcitImpl(implName, fields, values);
|
|
241
|
+
return new CalcitImpl(implName, fields, values, origin);
|
|
241
242
|
};
|
|
242
243
|
export let _$n_struct_$o__$o_new = (name, ...entries) => {
|
|
243
244
|
return defstruct(name, ...entries);
|
|
@@ -451,7 +452,11 @@ export let _$n_tuple_$o_with_impls = function (x, y) {
|
|
|
451
452
|
if (!(x instanceof CalcitTuple))
|
|
452
453
|
throw new Error("&tuple:with-impls expects a tuple");
|
|
453
454
|
const impl = coerce_impl(y, "&tuple:with-impls");
|
|
454
|
-
|
|
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));
|
|
455
460
|
};
|
|
456
461
|
export let _$n_tuple_$o_impl_traits = function (x, ...traits) {
|
|
457
462
|
if (traits.length < 1)
|
|
@@ -459,7 +464,13 @@ export let _$n_tuple_$o_impl_traits = function (x, ...traits) {
|
|
|
459
464
|
if (!(x instanceof CalcitTuple))
|
|
460
465
|
throw new Error("&tuple:impl-traits expects a tuple");
|
|
461
466
|
const impls = traits.map((trait) => coerce_impl(trait, "&tuple:impl-traits"));
|
|
462
|
-
|
|
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])));
|
|
472
|
+
}
|
|
473
|
+
return new CalcitTuple(x.tag, x.extra, proto.withImpls(impls));
|
|
463
474
|
};
|
|
464
475
|
export let _$n_tuple_$o_enum = function (x) {
|
|
465
476
|
if (arguments.length !== 1)
|
|
@@ -472,7 +483,7 @@ export let _$n_tuple_$o_enum = function (x) {
|
|
|
472
483
|
if (x.enumPrototype instanceof CalcitEnum) {
|
|
473
484
|
return x.enumPrototype;
|
|
474
485
|
}
|
|
475
|
-
return new CalcitEnum(x.enumPrototype
|
|
486
|
+
return new CalcitEnum(x.enumPrototype);
|
|
476
487
|
};
|
|
477
488
|
const unwrap_enum_prototype = (enumPrototype, procName) => {
|
|
478
489
|
if (enumPrototype instanceof CalcitEnum) {
|
|
@@ -584,7 +595,7 @@ export let _$n_record_$o_impls = function (xs) {
|
|
|
584
595
|
if (arguments.length !== 1)
|
|
585
596
|
throw new Error("&record:impls takes 1 argument");
|
|
586
597
|
if (xs instanceof CalcitRecord)
|
|
587
|
-
return new CalcitSliceList(xs.impls);
|
|
598
|
+
return new CalcitSliceList(xs.structRef.impls);
|
|
588
599
|
throw new Error("&record:impls expected a record");
|
|
589
600
|
};
|
|
590
601
|
export let _$n_record_$o_impl_traits = function (xs, ...traits) {
|
|
@@ -593,7 +604,8 @@ export let _$n_record_$o_impl_traits = function (xs, ...traits) {
|
|
|
593
604
|
if (!(xs instanceof CalcitRecord))
|
|
594
605
|
throw new Error("&record:impl-traits expected a record");
|
|
595
606
|
const impls = traits.map((trait) => coerce_impl(trait, "&record:impl-traits"));
|
|
596
|
-
|
|
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);
|
|
597
609
|
};
|
|
598
610
|
export let _$n_struct_$o_impl_traits = function (xs, ...traits) {
|
|
599
611
|
if (traits.length < 1)
|
|
@@ -609,14 +621,22 @@ export let _$n_enum_$o_impl_traits = function (xs, ...traits) {
|
|
|
609
621
|
throw new Error("&enum:impl-traits takes 2+ arguments");
|
|
610
622
|
const addedImpls = traits.map((trait) => coerce_impl(trait, "&enum:impl-traits"));
|
|
611
623
|
if (xs instanceof CalcitEnum) {
|
|
612
|
-
|
|
613
|
-
return new CalcitEnum(xs.prototype, baseImpls.concat(addedImpls));
|
|
624
|
+
return xs.withImpls(addedImpls);
|
|
614
625
|
}
|
|
615
626
|
if (xs instanceof CalcitRecord) {
|
|
616
|
-
|
|
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);
|
|
617
629
|
}
|
|
618
630
|
throw new Error("&enum:impl-traits expected an enum or enum record");
|
|
619
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
|
+
};
|
|
620
640
|
export let _$n_list_$o_assoc_before = function (xs, k, v) {
|
|
621
641
|
if (arguments.length !== 3) {
|
|
622
642
|
throw new Error("assoc takes 3 arguments");
|
|
@@ -1485,7 +1505,7 @@ export let _$n_js_object = (...xs) => {
|
|
|
1485
1505
|
return ret;
|
|
1486
1506
|
};
|
|
1487
1507
|
export let _$o__$o_ = (tagName, ...extra) => {
|
|
1488
|
-
return new CalcitTuple(tagName, extra,
|
|
1508
|
+
return new CalcitTuple(tagName, extra, null);
|
|
1489
1509
|
};
|
|
1490
1510
|
export let _PCT__$o__$o_ = (enumPrototype, tag, ...extra) => {
|
|
1491
1511
|
const proto = assert_enum_tag_args("%::", enumPrototype, tag);
|
|
@@ -1505,7 +1525,7 @@ export let _PCT__$o__$o_ = (enumPrototype, tag, ...extra) => {
|
|
|
1505
1525
|
throw new Error(`Expected variant definition to be a list, got ${variantDefinition}`);
|
|
1506
1526
|
}
|
|
1507
1527
|
const tupleEnumPrototype = enumPrototype instanceof CalcitEnum ? enumPrototype : proto;
|
|
1508
|
-
return new CalcitTuple(tag, extra,
|
|
1528
|
+
return new CalcitTuple(tag, extra, tupleEnumPrototype);
|
|
1509
1529
|
};
|
|
1510
1530
|
export let _PCT__PCT__$o__$o_ = (impl, enumPrototype, tag, ...extra) => {
|
|
1511
1531
|
// Runtime validation: check if tag exists in enum and arity matches
|
|
@@ -1527,7 +1547,7 @@ export let _PCT__PCT__$o__$o_ = (impl, enumPrototype, tag, ...extra) => {
|
|
|
1527
1547
|
}
|
|
1528
1548
|
const tupleEnumPrototype = enumPrototype instanceof CalcitEnum ? enumPrototype : proto;
|
|
1529
1549
|
const implValue = coerce_impl(impl, "%:: with impl");
|
|
1530
|
-
return new CalcitTuple(tag, extra,
|
|
1550
|
+
return new CalcitTuple(tag, extra, tupleEnumPrototype.withImpls(implValue));
|
|
1531
1551
|
};
|
|
1532
1552
|
let calcit_builtin_impls = {
|
|
1533
1553
|
number: null,
|
|
@@ -1574,7 +1594,7 @@ function lookup_impls(obj) {
|
|
|
1574
1594
|
}
|
|
1575
1595
|
else if (obj instanceof CalcitRecord) {
|
|
1576
1596
|
tag = obj.name.toString();
|
|
1577
|
-
impls = obj.impls;
|
|
1597
|
+
impls = obj.structRef.impls;
|
|
1578
1598
|
}
|
|
1579
1599
|
else if (obj instanceof CalcitTuple) {
|
|
1580
1600
|
tag = obj.tag.toString();
|
|
@@ -1686,7 +1706,8 @@ export function _$n_inspect_methods(obj, note) {
|
|
|
1686
1706
|
for (let k = 0; k < impl.fields.length; k++) {
|
|
1687
1707
|
names.push("." + impl.fields[k].value);
|
|
1688
1708
|
}
|
|
1689
|
-
|
|
1709
|
+
const originName = impl.origin != null ? impl.origin.name.toString() : impl.name.toString();
|
|
1710
|
+
console.log(` #${i}: ${originName} (${names.join(" ")})`);
|
|
1690
1711
|
}
|
|
1691
1712
|
let ms = _$n_methods_of(obj);
|
|
1692
1713
|
console.log(`\nAll methods (unique, high → low): ${ms.len()}`);
|
|
@@ -1716,7 +1737,7 @@ export function _$n_trait_call(traitDef, method, obj, ...args) {
|
|
|
1716
1737
|
let idx = reverse ? impls.length - 1 : 0;
|
|
1717
1738
|
while (reverse ? idx >= 0 : idx < impls.length) {
|
|
1718
1739
|
const impl = impls[idx];
|
|
1719
|
-
if (impl != null && impl.name.value === traitDef.name.value) {
|
|
1740
|
+
if (impl != null && impl.origin != null && impl.origin.name.value === traitDef.name.value) {
|
|
1720
1741
|
const fn = impl.getOrNil(methodName);
|
|
1721
1742
|
if (fn != null) {
|
|
1722
1743
|
if (typeof fn !== "function") {
|
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
|
@@ -360,7 +360,7 @@ export let extract_cirru_edn = (x, options) => {
|
|
|
360
360
|
if (!deepEqual(v.fields, fields)) {
|
|
361
361
|
throw new Error(`Fields mismatch for ${name}, expected ${fields}, got ${v.fields}`);
|
|
362
362
|
}
|
|
363
|
-
return new CalcitRecord(extractFieldTag(name), fields, values, v.
|
|
363
|
+
return new CalcitRecord(extractFieldTag(name), fields, values, v.structRef);
|
|
364
364
|
}
|
|
365
365
|
}
|
|
366
366
|
return new CalcitRecord(extractFieldTag(name), fields, values);
|
|
@@ -399,7 +399,7 @@ export let extract_cirru_edn = (x, options) => {
|
|
|
399
399
|
return new CalcitTuple(extract_cirru_edn(x[1], options), x
|
|
400
400
|
.slice(2)
|
|
401
401
|
.filter(notComment)
|
|
402
|
-
.map((x) => extract_cirru_edn(x, options))
|
|
402
|
+
.map((x) => extract_cirru_edn(x, options)));
|
|
403
403
|
}
|
|
404
404
|
if (x[0] === "%::") {
|
|
405
405
|
if (x.length < 3) {
|
|
@@ -416,7 +416,7 @@ export let extract_cirru_edn = (x, options) => {
|
|
|
416
416
|
return new CalcitTuple(extract_cirru_edn(x[2], options), x
|
|
417
417
|
.slice(3)
|
|
418
418
|
.filter(notComment)
|
|
419
|
-
.map((x) => extract_cirru_edn(x, options)),
|
|
419
|
+
.map((x) => extract_cirru_edn(x, options)), enumPrototype);
|
|
420
420
|
}
|
|
421
421
|
if (x[0] === "atom") {
|
|
422
422
|
if (x.length !== 2) {
|
package/lib/js-enum.mjs
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
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) {
|
|
14
|
+
let nextImpls;
|
|
12
15
|
if (impls instanceof CalcitImpl) {
|
|
13
|
-
|
|
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
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { castTag, findInFields, toString } from "./calcit-data.mjs";
|
|
2
2
|
export class CalcitImpl {
|
|
3
|
-
constructor(name, fields, values) {
|
|
3
|
+
constructor(name, fields, values, origin = null) {
|
|
4
4
|
this.name = name;
|
|
5
|
+
this.origin = origin;
|
|
5
6
|
this.fields = fields;
|
|
6
7
|
this.values = values;
|
|
7
8
|
this.cachedHash = null;
|
package/lib/js-record.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { CalcitImpl } from "./js-impl.mjs";
|
|
2
2
|
import { castTag, toString, findInFields } from "./calcit-data.mjs";
|
|
3
3
|
import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
|
|
4
|
+
import { CalcitStruct } from "./js-struct.mjs";
|
|
4
5
|
export class CalcitRecord {
|
|
5
|
-
constructor(name, fields, values,
|
|
6
|
+
constructor(name, fields, values, structRef) {
|
|
6
7
|
this.name = name;
|
|
7
8
|
let fieldNames = fields.map(castTag);
|
|
8
9
|
this.fields = fields;
|
|
@@ -16,7 +17,7 @@ export class CalcitRecord {
|
|
|
16
17
|
this.values = new Array(fieldNames.length);
|
|
17
18
|
}
|
|
18
19
|
this.cachedHash = null;
|
|
19
|
-
this.
|
|
20
|
+
this.structRef = structRef || new CalcitStruct(name, fields, new Array(fields.length).fill(null));
|
|
20
21
|
}
|
|
21
22
|
get(k) {
|
|
22
23
|
let field = castTag(k);
|
|
@@ -49,7 +50,7 @@ export class CalcitRecord {
|
|
|
49
50
|
values[idx] = this.values[idx];
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
|
-
return new CalcitRecord(this.name, this.fields, values, this.
|
|
53
|
+
return new CalcitRecord(this.name, this.fields, values, this.structRef);
|
|
53
54
|
}
|
|
54
55
|
/** return -1 for missing */
|
|
55
56
|
findIndex(k) {
|
|
@@ -71,12 +72,18 @@ export class CalcitRecord {
|
|
|
71
72
|
return parts.join("");
|
|
72
73
|
}
|
|
73
74
|
withImpls(impl) {
|
|
75
|
+
let nextImpls;
|
|
74
76
|
if (impl instanceof CalcitImpl) {
|
|
75
|
-
|
|
77
|
+
nextImpls = [impl];
|
|
78
|
+
}
|
|
79
|
+
else if (Array.isArray(impl)) {
|
|
80
|
+
nextImpls = impl;
|
|
76
81
|
}
|
|
77
82
|
else {
|
|
78
|
-
throw new Error("Expected an impl");
|
|
83
|
+
throw new Error("Expected an impl or array of impls");
|
|
79
84
|
}
|
|
85
|
+
let nextStruct = new CalcitStruct(this.name, this.fields, this.structRef.fieldTypes, this.structRef.impls.concat(nextImpls));
|
|
86
|
+
return new CalcitRecord(this.name, this.fields, this.values, nextStruct);
|
|
80
87
|
}
|
|
81
88
|
}
|
|
82
89
|
export let new_record = (name, ...fields) => {
|
|
@@ -105,7 +112,9 @@ export let new_impl_record = (impl, name, ...fields) => {
|
|
|
105
112
|
throw new Error(`Unexpected duplication in record fields: ${x.toString()}`);
|
|
106
113
|
}
|
|
107
114
|
});
|
|
108
|
-
|
|
115
|
+
let nameTag = castTag(name);
|
|
116
|
+
let structRef = new CalcitStruct(nameTag, fieldNames, new Array(fieldNames.length).fill(null), [impl]);
|
|
117
|
+
return new CalcitRecord(nameTag, fieldNames, undefined, structRef);
|
|
109
118
|
};
|
|
110
119
|
export let fieldsEqual = (xs, ys) => {
|
|
111
120
|
if (xs === ys) {
|
|
@@ -147,7 +156,7 @@ export let _$n__PCT__$M_ = (proto, ...xs) => {
|
|
|
147
156
|
}
|
|
148
157
|
values[i] = xs[idx * 2 + 1];
|
|
149
158
|
}
|
|
150
|
-
return new CalcitRecord(proto.name, proto.fields, values, proto.
|
|
159
|
+
return new CalcitRecord(proto.name, proto.fields, values, proto.structRef);
|
|
151
160
|
}
|
|
152
161
|
else {
|
|
153
162
|
throw new Error("Expected prototype to be a record");
|
|
@@ -169,7 +178,7 @@ export let _$n_record_$o_with = (proto, ...xs) => {
|
|
|
169
178
|
}
|
|
170
179
|
values[idx] = v;
|
|
171
180
|
}
|
|
172
|
-
return new CalcitRecord(proto.name, proto.fields, values, proto.
|
|
181
|
+
return new CalcitRecord(proto.name, proto.fields, values, proto.structRef);
|
|
173
182
|
}
|
|
174
183
|
else {
|
|
175
184
|
throw new Error("Expected prototype to be a record");
|
package/lib/js-tuple.mjs
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { _$n__$e_, toString } from "./calcit-data.mjs";
|
|
2
2
|
import { CalcitEnum } from "./js-enum.mjs";
|
|
3
3
|
export class CalcitTuple {
|
|
4
|
-
constructor(tagName, extra,
|
|
4
|
+
constructor(tagName, extra, enumPrototype = null) {
|
|
5
5
|
this.tag = tagName;
|
|
6
6
|
this.extra = extra;
|
|
7
|
-
this.impls = impls;
|
|
8
7
|
this.enumPrototype = enumPrototype;
|
|
9
8
|
this.cachedHash = null;
|
|
10
9
|
}
|
|
10
|
+
get impls() {
|
|
11
|
+
if (this.enumPrototype == null) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
if (this.enumPrototype instanceof CalcitEnum) {
|
|
15
|
+
return this.enumPrototype.impls;
|
|
16
|
+
}
|
|
17
|
+
return this.enumPrototype.structRef.impls;
|
|
18
|
+
}
|
|
11
19
|
get(n) {
|
|
12
20
|
if (n === 0) {
|
|
13
21
|
return this.tag;
|
|
@@ -21,12 +29,12 @@ export class CalcitTuple {
|
|
|
21
29
|
}
|
|
22
30
|
assoc(n, v) {
|
|
23
31
|
if (n === 0) {
|
|
24
|
-
return new CalcitTuple(v, this.extra, this.
|
|
32
|
+
return new CalcitTuple(v, this.extra, this.enumPrototype);
|
|
25
33
|
}
|
|
26
34
|
else if (n - 1 < this.extra.length) {
|
|
27
35
|
let next_extra = this.extra.slice();
|
|
28
36
|
next_extra[n - 1] = v;
|
|
29
|
-
return new CalcitTuple(this.tag, next_extra, this.
|
|
37
|
+
return new CalcitTuple(this.tag, next_extra, this.enumPrototype);
|
|
30
38
|
}
|
|
31
39
|
else {
|
|
32
40
|
throw new Error(`Tuple only have ${this.extra.length} elements`);
|
|
@@ -60,15 +68,9 @@ export class CalcitTuple {
|
|
|
60
68
|
}
|
|
61
69
|
const hasEnum = this.enumPrototype != null;
|
|
62
70
|
const enumName = hasEnum ? (this.enumPrototype instanceof CalcitEnum ? this.enumPrototype.prototype.name.value : this.enumPrototype.name.value) : null;
|
|
63
|
-
if (this.impls.length > 0 && hasEnum) {
|
|
64
|
-
return `(%:: ${content} (:impls ${this.impls[0].name.value}) (:enum ${enumName}))`;
|
|
65
|
-
}
|
|
66
71
|
if (hasEnum) {
|
|
67
72
|
return `(%:: ${content} (:enum ${enumName}))`;
|
|
68
73
|
}
|
|
69
|
-
if (this.impls.length > 0) {
|
|
70
|
-
return `(:: ${content} (:impls ${this.impls[0].name.value}))`;
|
|
71
|
-
}
|
|
72
74
|
return `(:: ${content})`;
|
|
73
75
|
}
|
|
74
76
|
}
|
package/lib/package.json
CHANGED
package/package.json
CHANGED
package/ts-src/calcit-data.mts
CHANGED
|
@@ -320,6 +320,9 @@ export let hashFunction = (x: CalcitValue): Hash => {
|
|
|
320
320
|
if (x instanceof CalcitImpl) {
|
|
321
321
|
let base = defaultHash_impl;
|
|
322
322
|
base = mergeValueHash(base, hashFunction(x.name));
|
|
323
|
+
if (x.origin != null) {
|
|
324
|
+
base = mergeValueHash(base, hashFunction(x.origin));
|
|
325
|
+
}
|
|
323
326
|
for (let idx = 0; idx < x.fields.length; idx++) {
|
|
324
327
|
base = mergeValueHash(base, hashFunction(x.fields[idx]));
|
|
325
328
|
base = mergeValueHash(base, hashFunction(x.values[idx]));
|
|
@@ -708,6 +711,12 @@ export let _$n__$e_ = (x: CalcitValue, y: CalcitValue): boolean => {
|
|
|
708
711
|
if (x.name !== y.name) {
|
|
709
712
|
return false;
|
|
710
713
|
}
|
|
714
|
+
if ((x.origin == null) !== (y.origin == null)) {
|
|
715
|
+
return false;
|
|
716
|
+
}
|
|
717
|
+
if (x.origin != null && y.origin != null && x.origin.name.value !== y.origin.name.value) {
|
|
718
|
+
return false;
|
|
719
|
+
}
|
|
711
720
|
if (!fieldsEqual(x.fields, y.fields)) {
|
|
712
721
|
return false;
|
|
713
722
|
}
|
package/ts-src/calcit.procs.mts
CHANGED
|
@@ -230,14 +230,15 @@ export let defenum = (name: CalcitValue, ...variants: CalcitValue[]): CalcitEnum
|
|
|
230
230
|
const tags = entries.map((entry) => entry.tag);
|
|
231
231
|
const values = entries.map((entry) => entry.payload);
|
|
232
232
|
const prototype = new CalcitRecord(enumName, tags, values, null);
|
|
233
|
-
return new CalcitEnum(prototype
|
|
233
|
+
return new CalcitEnum(prototype);
|
|
234
234
|
};
|
|
235
235
|
|
|
236
236
|
export let _$n_impl_$o__$o_new = (name: CalcitValue, ...pairs: CalcitValue[]): CalcitImpl => {
|
|
237
237
|
if (name === undefined) throw new Error("&impl::new expected arguments");
|
|
238
|
-
const
|
|
238
|
+
const origin = name instanceof CalcitTrait ? name : null;
|
|
239
|
+
const implName = origin ? origin.name : castTag(name);
|
|
239
240
|
if (pairs.length === 0) {
|
|
240
|
-
return new CalcitImpl(implName, [], []);
|
|
241
|
+
return new CalcitImpl(implName, [], [], origin);
|
|
241
242
|
}
|
|
242
243
|
const entries: Array<{ tag: CalcitTag; value: CalcitValue }> = [];
|
|
243
244
|
for (let idx = 0; idx < pairs.length; idx++) {
|
|
@@ -268,7 +269,7 @@ export let _$n_impl_$o__$o_new = (name: CalcitValue, ...pairs: CalcitValue[]): C
|
|
|
268
269
|
}
|
|
269
270
|
const fields = entries.map((entry) => entry.tag);
|
|
270
271
|
const values = entries.map((entry) => entry.value);
|
|
271
|
-
return new CalcitImpl(implName, fields, values);
|
|
272
|
+
return new CalcitImpl(implName, fields, values, origin);
|
|
272
273
|
};
|
|
273
274
|
|
|
274
275
|
export let _$n_struct_$o__$o_new = (name: CalcitValue, ...entries: CalcitValue[]): CalcitStruct => {
|
|
@@ -508,14 +509,26 @@ export let _$n_tuple_$o_with_impls = function (x: CalcitTuple, y: CalcitValue) {
|
|
|
508
509
|
if (arguments.length !== 2) throw new Error("&tuple:with-impls takes 2 arguments");
|
|
509
510
|
if (!(x instanceof CalcitTuple)) throw new Error("&tuple:with-impls expects a tuple");
|
|
510
511
|
const impl = coerce_impl(y, "&tuple:with-impls");
|
|
511
|
-
|
|
512
|
+
let proto = x.enumPrototype;
|
|
513
|
+
if (proto == null) {
|
|
514
|
+
proto = new CalcitEnum(new CalcitRecord(newTag("anonymous-tuple"), [], [], new CalcitStruct(newTag("anonymous-tuple"), [], [])));
|
|
515
|
+
}
|
|
516
|
+
return new CalcitTuple(x.tag, x.extra, proto.withImpls(impl));
|
|
512
517
|
};
|
|
513
518
|
|
|
514
519
|
export let _$n_tuple_$o_impl_traits = function (x: CalcitValue, ...traits: CalcitValue[]) {
|
|
515
520
|
if (traits.length < 1) throw new Error("&tuple:impl-traits takes 2+ arguments");
|
|
516
521
|
if (!(x instanceof CalcitTuple)) throw new Error("&tuple:impl-traits expects a tuple");
|
|
517
522
|
const impls = traits.map((trait) => coerce_impl(trait, "&tuple:impl-traits"));
|
|
518
|
-
|
|
523
|
+
let proto = x.enumPrototype;
|
|
524
|
+
if (proto == null) {
|
|
525
|
+
const tagName = x.tag instanceof CalcitTag ? x.tag : newTag("tag");
|
|
526
|
+
const anyTypes = new CalcitSliceList(new Array(x.extra.length).fill(newTag("any")));
|
|
527
|
+
proto = new CalcitEnum(
|
|
528
|
+
new CalcitRecord(newTag("anonymous-tuple"), [tagName], [anyTypes], new CalcitStruct(newTag("anonymous-tuple"), [tagName], [anyTypes]))
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
return new CalcitTuple(x.tag, x.extra, proto.withImpls(impls));
|
|
519
532
|
};
|
|
520
533
|
|
|
521
534
|
export let _$n_tuple_$o_enum = function (x: CalcitTuple) {
|
|
@@ -527,7 +540,7 @@ export let _$n_tuple_$o_enum = function (x: CalcitTuple) {
|
|
|
527
540
|
if (x.enumPrototype instanceof CalcitEnum) {
|
|
528
541
|
return x.enumPrototype;
|
|
529
542
|
}
|
|
530
|
-
return new CalcitEnum(x.enumPrototype as CalcitRecord
|
|
543
|
+
return new CalcitEnum(x.enumPrototype as CalcitRecord);
|
|
531
544
|
};
|
|
532
545
|
|
|
533
546
|
const unwrap_enum_prototype = (enumPrototype: CalcitValue, procName: string): CalcitRecord => {
|
|
@@ -649,7 +662,7 @@ export let _$n_record_$o_assoc = function (xs: CalcitValue, k: CalcitValue, v: C
|
|
|
649
662
|
|
|
650
663
|
export let _$n_record_$o_impls = function (xs: CalcitValue) {
|
|
651
664
|
if (arguments.length !== 1) throw new Error("&record:impls takes 1 argument");
|
|
652
|
-
if (xs instanceof CalcitRecord) return new CalcitSliceList(xs.impls);
|
|
665
|
+
if (xs instanceof CalcitRecord) return new CalcitSliceList(xs.structRef.impls);
|
|
653
666
|
throw new Error("&record:impls expected a record");
|
|
654
667
|
};
|
|
655
668
|
|
|
@@ -657,7 +670,8 @@ export let _$n_record_$o_impl_traits = function (xs: CalcitValue, ...traits: Cal
|
|
|
657
670
|
if (traits.length < 1) throw new Error("&record:impl-traits takes 2+ arguments");
|
|
658
671
|
if (!(xs instanceof CalcitRecord)) throw new Error("&record:impl-traits expected a record");
|
|
659
672
|
const impls = traits.map((trait) => coerce_impl(trait, "&record:impl-traits"));
|
|
660
|
-
|
|
673
|
+
const nextStruct = new CalcitStruct(xs.name, xs.fields, xs.structRef.fieldTypes, xs.structRef.impls.concat(impls));
|
|
674
|
+
return new CalcitRecord(xs.name, xs.fields, xs.values, nextStruct);
|
|
661
675
|
};
|
|
662
676
|
|
|
663
677
|
export let _$n_struct_$o_impl_traits = function (xs: CalcitValue, ...traits: CalcitValue[]) {
|
|
@@ -672,15 +686,23 @@ export let _$n_enum_$o_impl_traits = function (xs: CalcitValue, ...traits: Calci
|
|
|
672
686
|
if (traits.length < 1) throw new Error("&enum:impl-traits takes 2+ arguments");
|
|
673
687
|
const addedImpls = traits.map((trait) => coerce_impl(trait, "&enum:impl-traits"));
|
|
674
688
|
if (xs instanceof CalcitEnum) {
|
|
675
|
-
|
|
676
|
-
return new CalcitEnum(xs.prototype, baseImpls.concat(addedImpls));
|
|
689
|
+
return xs.withImpls(addedImpls);
|
|
677
690
|
}
|
|
678
691
|
if (xs instanceof CalcitRecord) {
|
|
679
|
-
|
|
692
|
+
const nextStruct = new CalcitStruct(xs.name, xs.fields, xs.structRef.fieldTypes, xs.structRef.impls.concat(addedImpls));
|
|
693
|
+
return new CalcitRecord(xs.name, xs.fields, xs.values, nextStruct);
|
|
680
694
|
}
|
|
681
695
|
throw new Error("&enum:impl-traits expected an enum or enum record");
|
|
682
696
|
};
|
|
683
697
|
|
|
698
|
+
export let _$n_impl_$o_origin = function (impl: CalcitValue): CalcitValue {
|
|
699
|
+
if (arguments.length !== 1) throw new Error("&impl:origin expected 1 argument");
|
|
700
|
+
if (impl instanceof CalcitImpl) {
|
|
701
|
+
return impl.origin ?? null;
|
|
702
|
+
}
|
|
703
|
+
throw new Error(`&impl:origin expected an impl, but received: ${toString(impl, true)}`);
|
|
704
|
+
};
|
|
705
|
+
|
|
684
706
|
export let _$n_list_$o_assoc_before = function (xs: CalcitList | CalcitSliceList, k: number, v: CalcitValue): CalcitList {
|
|
685
707
|
if (arguments.length !== 3) {
|
|
686
708
|
throw new Error("assoc takes 3 arguments");
|
|
@@ -1601,7 +1623,7 @@ export let _$n_js_object = (...xs: CalcitValue[]): Record<string, CalcitValue> =
|
|
|
1601
1623
|
};
|
|
1602
1624
|
|
|
1603
1625
|
export let _$o__$o_ = (tagName: CalcitValue, ...extra: CalcitValue[]): CalcitTuple => {
|
|
1604
|
-
return new CalcitTuple(tagName, extra,
|
|
1626
|
+
return new CalcitTuple(tagName, extra, null);
|
|
1605
1627
|
};
|
|
1606
1628
|
|
|
1607
1629
|
export let _PCT__$o__$o_ = (enumPrototype: CalcitValue, tag: CalcitValue, ...extra: CalcitValue[]): CalcitTuple => {
|
|
@@ -1624,7 +1646,7 @@ export let _PCT__$o__$o_ = (enumPrototype: CalcitValue, tag: CalcitValue, ...ext
|
|
|
1624
1646
|
}
|
|
1625
1647
|
|
|
1626
1648
|
const tupleEnumPrototype = enumPrototype instanceof CalcitEnum ? enumPrototype : proto;
|
|
1627
|
-
return new CalcitTuple(tag, extra,
|
|
1649
|
+
return new CalcitTuple(tag, extra, tupleEnumPrototype);
|
|
1628
1650
|
};
|
|
1629
1651
|
|
|
1630
1652
|
export let _PCT__PCT__$o__$o_ = (impl: CalcitValue, enumPrototype: CalcitValue, tag: CalcitValue, ...extra: CalcitValue[]): CalcitTuple => {
|
|
@@ -1647,9 +1669,9 @@ export let _PCT__PCT__$o__$o_ = (impl: CalcitValue, enumPrototype: CalcitValue,
|
|
|
1647
1669
|
throw new Error(`Expected variant definition to be a list, got ${variantDefinition}`);
|
|
1648
1670
|
}
|
|
1649
1671
|
|
|
1650
|
-
const tupleEnumPrototype = enumPrototype instanceof CalcitEnum ? enumPrototype : proto;
|
|
1672
|
+
const tupleEnumPrototype = enumPrototype instanceof CalcitEnum ? enumPrototype : (proto as any);
|
|
1651
1673
|
const implValue = coerce_impl(impl, "%:: with impl");
|
|
1652
|
-
return new CalcitTuple(tag, extra,
|
|
1674
|
+
return new CalcitTuple(tag, extra, tupleEnumPrototype.withImpls(implValue));
|
|
1653
1675
|
};
|
|
1654
1676
|
|
|
1655
1677
|
// mutable place for core to register
|
|
@@ -1699,7 +1721,7 @@ function lookup_impls(obj: CalcitValue): [CalcitImpl[], string] {
|
|
|
1699
1721
|
impls = normalize_builtin_impls(calcit_builtin_impls.map);
|
|
1700
1722
|
} else if (obj instanceof CalcitRecord) {
|
|
1701
1723
|
tag = obj.name.toString();
|
|
1702
|
-
impls = obj.impls;
|
|
1724
|
+
impls = obj.structRef.impls;
|
|
1703
1725
|
} else if (obj instanceof CalcitTuple) {
|
|
1704
1726
|
tag = obj.tag.toString();
|
|
1705
1727
|
impls = obj.impls;
|
|
@@ -1808,7 +1830,8 @@ export function _$n_inspect_methods(obj: CalcitValue, note: CalcitValue): Calcit
|
|
|
1808
1830
|
for (let k = 0; k < impl.fields.length; k++) {
|
|
1809
1831
|
names.push("." + impl.fields[k].value);
|
|
1810
1832
|
}
|
|
1811
|
-
|
|
1833
|
+
const originName = impl.origin != null ? impl.origin.name.toString() : impl.name.toString();
|
|
1834
|
+
console.log(` #${i}: ${originName} (${names.join(" ")})`);
|
|
1812
1835
|
}
|
|
1813
1836
|
|
|
1814
1837
|
let ms = _$n_methods_of(obj);
|
|
@@ -1841,7 +1864,7 @@ export function _$n_trait_call(traitDef: CalcitValue, method: CalcitValue, obj:
|
|
|
1841
1864
|
let idx = reverse ? impls.length - 1 : 0;
|
|
1842
1865
|
while (reverse ? idx >= 0 : idx < impls.length) {
|
|
1843
1866
|
const impl = impls[idx];
|
|
1844
|
-
if (impl != null && impl.name.value === traitDef.name.value) {
|
|
1867
|
+
if (impl != null && impl.origin != null && impl.origin.name.value === traitDef.name.value) {
|
|
1845
1868
|
const fn = impl.getOrNil(methodName);
|
|
1846
1869
|
if (fn != null) {
|
|
1847
1870
|
if (typeof fn !== "function") {
|
|
@@ -180,11 +180,11 @@ export let load_console_formatter_$x_ = () => {
|
|
|
180
180
|
);
|
|
181
181
|
}
|
|
182
182
|
if (obj instanceof CalcitRecord) {
|
|
183
|
-
if (obj.impls.length > 0) {
|
|
183
|
+
if (obj.structRef.impls.length > 0) {
|
|
184
184
|
let ret: any[] = div(
|
|
185
185
|
{ color: hsl(280, 80, 60, 0.4), maxWidth: "100%" },
|
|
186
186
|
span({}, "%{}"),
|
|
187
|
-
span({ marginLeft: "6px" }, embedObject(obj.impls[0])),
|
|
187
|
+
span({ marginLeft: "6px" }, embedObject(obj.structRef.impls[0])),
|
|
188
188
|
span({ marginLeft: "6px" }, embedObject(obj.name)),
|
|
189
189
|
span({ marginLeft: "6px" }, `...`)
|
|
190
190
|
);
|
package/ts-src/js-cirru.mts
CHANGED
|
@@ -351,7 +351,7 @@ export let extract_cirru_edn = (x: CirruEdnFormat, options: CalcitValue): Calcit
|
|
|
351
351
|
if (!deepEqual(v.fields, fields)) {
|
|
352
352
|
throw new Error(`Fields mismatch for ${name}, expected ${fields}, got ${v.fields}`);
|
|
353
353
|
}
|
|
354
|
-
return new CalcitRecord(extractFieldTag(name), fields, values, v.
|
|
354
|
+
return new CalcitRecord(extractFieldTag(name), fields, values, v.structRef);
|
|
355
355
|
}
|
|
356
356
|
}
|
|
357
357
|
|
|
@@ -397,8 +397,7 @@ export let extract_cirru_edn = (x: CirruEdnFormat, options: CalcitValue): Calcit
|
|
|
397
397
|
x
|
|
398
398
|
.slice(2)
|
|
399
399
|
.filter(notComment)
|
|
400
|
-
.map((x) => extract_cirru_edn(x, options))
|
|
401
|
-
[]
|
|
400
|
+
.map((x) => extract_cirru_edn(x, options))
|
|
402
401
|
);
|
|
403
402
|
}
|
|
404
403
|
if (x[0] === "%::") {
|
|
@@ -419,7 +418,6 @@ export let extract_cirru_edn = (x: CirruEdnFormat, options: CalcitValue): Calcit
|
|
|
419
418
|
.slice(3)
|
|
420
419
|
.filter(notComment)
|
|
421
420
|
.map((x) => extract_cirru_edn(x, options)),
|
|
422
|
-
[],
|
|
423
421
|
enumPrototype
|
|
424
422
|
);
|
|
425
423
|
}
|
package/ts-src/js-enum.mts
CHANGED
|
@@ -3,12 +3,10 @@ import { CalcitImpl } from "./js-impl.mjs";
|
|
|
3
3
|
|
|
4
4
|
export class CalcitEnum {
|
|
5
5
|
prototype: CalcitRecord;
|
|
6
|
-
impls: CalcitImpl[];
|
|
7
6
|
cachedHash: number;
|
|
8
7
|
|
|
9
|
-
constructor(prototype: CalcitRecord
|
|
8
|
+
constructor(prototype: CalcitRecord) {
|
|
10
9
|
this.prototype = prototype;
|
|
11
|
-
this.impls = impls;
|
|
12
10
|
this.cachedHash = null;
|
|
13
11
|
}
|
|
14
12
|
|
|
@@ -16,13 +14,20 @@ export class CalcitEnum {
|
|
|
16
14
|
return this.prototype.name.value;
|
|
17
15
|
}
|
|
18
16
|
|
|
17
|
+
get impls(): CalcitImpl[] {
|
|
18
|
+
return this.prototype.structRef.impls;
|
|
19
|
+
}
|
|
20
|
+
|
|
19
21
|
withImpls(impls: CalcitImpl | CalcitImpl[]): CalcitEnum {
|
|
22
|
+
let nextImpls: CalcitImpl[];
|
|
20
23
|
if (impls instanceof CalcitImpl) {
|
|
21
|
-
|
|
24
|
+
nextImpls = [impls];
|
|
22
25
|
} else if (Array.isArray(impls)) {
|
|
23
|
-
|
|
26
|
+
nextImpls = impls;
|
|
27
|
+
} else {
|
|
28
|
+
throw new Error("Expected an impl as implementation");
|
|
24
29
|
}
|
|
25
|
-
|
|
30
|
+
return new CalcitEnum(this.prototype.withImpls(nextImpls));
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
toString(): string {
|
package/ts-src/js-impl.mts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { Hash } from "@calcit/ternary-tree";
|
|
2
2
|
import { CalcitValue } from "./js-primes.mjs";
|
|
3
3
|
import { CalcitTag, castTag, findInFields, toString } from "./calcit-data.mjs";
|
|
4
|
+
import type { CalcitTrait } from "./js-trait.mjs";
|
|
4
5
|
|
|
5
6
|
export class CalcitImpl {
|
|
6
7
|
name: CalcitTag;
|
|
8
|
+
origin: CalcitTrait | null;
|
|
7
9
|
fields: Array<CalcitTag>;
|
|
8
10
|
values: Array<CalcitValue>;
|
|
9
11
|
cachedHash: Hash;
|
|
10
12
|
|
|
11
|
-
constructor(name: CalcitTag, fields: Array<CalcitTag>, values: Array<CalcitValue
|
|
13
|
+
constructor(name: CalcitTag, fields: Array<CalcitTag>, values: Array<CalcitValue>, origin: CalcitTrait | null = null) {
|
|
12
14
|
this.name = name;
|
|
15
|
+
this.origin = origin;
|
|
13
16
|
this.fields = fields;
|
|
14
17
|
this.values = values;
|
|
15
18
|
this.cachedHash = null;
|
package/ts-src/js-primes.mts
CHANGED
|
@@ -9,6 +9,7 @@ import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
|
|
|
9
9
|
import { CalcitSet as CalcitSet } from "./js-set.mjs";
|
|
10
10
|
import { CalcitTuple } from "./js-tuple.mjs";
|
|
11
11
|
import { CalcitCirruQuote, cirru_deep_equal } from "./js-cirru.mjs";
|
|
12
|
+
import { CalcitTrait } from "./js-trait.mjs";
|
|
12
13
|
|
|
13
14
|
export type CalcitValue =
|
|
14
15
|
| string
|
|
@@ -27,6 +28,7 @@ export type CalcitValue =
|
|
|
27
28
|
| CalcitRecur // should not be exposed to function
|
|
28
29
|
| CalcitRecord
|
|
29
30
|
| CalcitImpl
|
|
31
|
+
| CalcitTrait
|
|
30
32
|
| CalcitStruct
|
|
31
33
|
| CalcitEnum
|
|
32
34
|
| CalcitCirruQuote
|
package/ts-src/js-record.mts
CHANGED
|
@@ -5,13 +5,15 @@ import { newTag, castTag, toString, CalcitTag, getStringName, findInFields } fro
|
|
|
5
5
|
|
|
6
6
|
import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
|
|
7
7
|
|
|
8
|
+
import { CalcitStruct } from "./js-struct.mjs";
|
|
9
|
+
|
|
8
10
|
export class CalcitRecord {
|
|
9
11
|
name: CalcitTag;
|
|
10
12
|
fields: Array<CalcitTag>;
|
|
11
13
|
values: Array<CalcitValue>;
|
|
12
|
-
|
|
14
|
+
structRef: CalcitStruct;
|
|
13
15
|
cachedHash: Hash;
|
|
14
|
-
constructor(name: CalcitTag, fields: Array<CalcitTag>, values?: Array<CalcitValue>,
|
|
16
|
+
constructor(name: CalcitTag, fields: Array<CalcitTag>, values?: Array<CalcitValue>, structRef?: CalcitStruct) {
|
|
15
17
|
this.name = name;
|
|
16
18
|
let fieldNames = fields.map(castTag);
|
|
17
19
|
this.fields = fields;
|
|
@@ -24,7 +26,7 @@ export class CalcitRecord {
|
|
|
24
26
|
this.values = new Array(fieldNames.length);
|
|
25
27
|
}
|
|
26
28
|
this.cachedHash = null;
|
|
27
|
-
this.
|
|
29
|
+
this.structRef = structRef || new CalcitStruct(name, fields, new Array(fields.length).fill(null));
|
|
28
30
|
}
|
|
29
31
|
get(k: CalcitValue) {
|
|
30
32
|
let field = castTag(k);
|
|
@@ -54,7 +56,7 @@ export class CalcitRecord {
|
|
|
54
56
|
values[idx] = this.values[idx];
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
|
-
return new CalcitRecord(this.name, this.fields, values, this.
|
|
59
|
+
return new CalcitRecord(this.name, this.fields, values, this.structRef);
|
|
58
60
|
}
|
|
59
61
|
/** return -1 for missing */
|
|
60
62
|
findIndex(k: CalcitValue) {
|
|
@@ -75,12 +77,17 @@ export class CalcitRecord {
|
|
|
75
77
|
parts.push(")");
|
|
76
78
|
return parts.join("");
|
|
77
79
|
}
|
|
78
|
-
withImpls(impl: CalcitValue): CalcitRecord {
|
|
80
|
+
withImpls(impl: CalcitValue | CalcitImpl[]): CalcitRecord {
|
|
81
|
+
let nextImpls: CalcitImpl[];
|
|
79
82
|
if (impl instanceof CalcitImpl) {
|
|
80
|
-
|
|
83
|
+
nextImpls = [impl];
|
|
84
|
+
} else if (Array.isArray(impl)) {
|
|
85
|
+
nextImpls = impl;
|
|
81
86
|
} else {
|
|
82
|
-
throw new Error("Expected an impl");
|
|
87
|
+
throw new Error("Expected an impl or array of impls");
|
|
83
88
|
}
|
|
89
|
+
let nextStruct = new CalcitStruct(this.name, this.fields, this.structRef.fieldTypes, this.structRef.impls.concat(nextImpls));
|
|
90
|
+
return new CalcitRecord(this.name, this.fields, this.values, nextStruct);
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
|
|
@@ -107,7 +114,9 @@ export let new_impl_record = (impl: CalcitImpl, name: CalcitValue, ...fields: Ar
|
|
|
107
114
|
throw new Error(`Unexpected duplication in record fields: ${x.toString()}`);
|
|
108
115
|
}
|
|
109
116
|
});
|
|
110
|
-
|
|
117
|
+
let nameTag = castTag(name);
|
|
118
|
+
let structRef = new CalcitStruct(nameTag, fieldNames, new Array(fieldNames.length).fill(null), [impl]);
|
|
119
|
+
return new CalcitRecord(nameTag, fieldNames, undefined, structRef);
|
|
111
120
|
};
|
|
112
121
|
|
|
113
122
|
export let fieldsEqual = (xs: Array<CalcitTag>, ys: Array<CalcitTag>): boolean => {
|
|
@@ -155,7 +164,7 @@ export let _$n__PCT__$M_ = (proto: CalcitValue, ...xs: Array<CalcitValue>): Calc
|
|
|
155
164
|
values[i] = xs[idx * 2 + 1];
|
|
156
165
|
}
|
|
157
166
|
|
|
158
|
-
return new CalcitRecord(proto.name, proto.fields, values, proto.
|
|
167
|
+
return new CalcitRecord(proto.name, proto.fields, values, proto.structRef);
|
|
159
168
|
} else {
|
|
160
169
|
throw new Error("Expected prototype to be a record");
|
|
161
170
|
}
|
|
@@ -177,7 +186,7 @@ export let _$n_record_$o_with = (proto: CalcitValue, ...xs: Array<CalcitValue>):
|
|
|
177
186
|
}
|
|
178
187
|
values[idx] = v;
|
|
179
188
|
}
|
|
180
|
-
return new CalcitRecord(proto.name, proto.fields, values, proto.
|
|
189
|
+
return new CalcitRecord(proto.name, proto.fields, values, proto.structRef);
|
|
181
190
|
} else {
|
|
182
191
|
throw new Error("Expected prototype to be a record");
|
|
183
192
|
}
|
package/ts-src/js-tuple.mts
CHANGED
|
@@ -9,16 +9,25 @@ import { CalcitEnum } from "./js-enum.mjs";
|
|
|
9
9
|
export class CalcitTuple {
|
|
10
10
|
tag: CalcitValue;
|
|
11
11
|
extra: CalcitValue[];
|
|
12
|
-
impls: CalcitImpl[];
|
|
13
12
|
enumPrototype: CalcitRecord | CalcitEnum;
|
|
14
13
|
cachedHash: Hash;
|
|
15
|
-
constructor(tagName: CalcitValue, extra: CalcitValue[],
|
|
14
|
+
constructor(tagName: CalcitValue, extra: CalcitValue[], enumPrototype: CalcitRecord | CalcitEnum = null) {
|
|
16
15
|
this.tag = tagName;
|
|
17
16
|
this.extra = extra;
|
|
18
|
-
this.impls = impls;
|
|
19
17
|
this.enumPrototype = enumPrototype;
|
|
20
18
|
this.cachedHash = null;
|
|
21
19
|
}
|
|
20
|
+
|
|
21
|
+
get impls(): CalcitImpl[] {
|
|
22
|
+
if (this.enumPrototype == null) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
if (this.enumPrototype instanceof CalcitEnum) {
|
|
26
|
+
return this.enumPrototype.impls;
|
|
27
|
+
}
|
|
28
|
+
return this.enumPrototype.structRef.impls;
|
|
29
|
+
}
|
|
30
|
+
|
|
22
31
|
get(n: number) {
|
|
23
32
|
if (n === 0) {
|
|
24
33
|
return this.tag;
|
|
@@ -30,11 +39,11 @@ export class CalcitTuple {
|
|
|
30
39
|
}
|
|
31
40
|
assoc(n: number, v: CalcitValue) {
|
|
32
41
|
if (n === 0) {
|
|
33
|
-
return new CalcitTuple(v, this.extra, this.
|
|
42
|
+
return new CalcitTuple(v, this.extra, this.enumPrototype);
|
|
34
43
|
} else if (n - 1 < this.extra.length) {
|
|
35
44
|
let next_extra = this.extra.slice();
|
|
36
45
|
next_extra[n - 1] = v;
|
|
37
|
-
return new CalcitTuple(this.tag, next_extra, this.
|
|
46
|
+
return new CalcitTuple(this.tag, next_extra, this.enumPrototype);
|
|
38
47
|
} else {
|
|
39
48
|
throw new Error(`Tuple only have ${this.extra.length} elements`);
|
|
40
49
|
}
|
|
@@ -68,15 +77,9 @@ export class CalcitTuple {
|
|
|
68
77
|
const hasEnum = this.enumPrototype != null;
|
|
69
78
|
const enumName = hasEnum ? (this.enumPrototype instanceof CalcitEnum ? this.enumPrototype.prototype.name.value : this.enumPrototype.name.value) : null;
|
|
70
79
|
|
|
71
|
-
if (this.impls.length > 0 && hasEnum) {
|
|
72
|
-
return `(%:: ${content} (:impls ${this.impls[0].name.value}) (:enum ${enumName}))`;
|
|
73
|
-
}
|
|
74
80
|
if (hasEnum) {
|
|
75
81
|
return `(%:: ${content} (:enum ${enumName}))`;
|
|
76
82
|
}
|
|
77
|
-
if (this.impls.length > 0) {
|
|
78
|
-
return `(:: ${content} (:impls ${this.impls[0].name.value}))`;
|
|
79
|
-
}
|
|
80
83
|
return `(:: ${content})`;
|
|
81
84
|
}
|
|
82
85
|
}
|