@calcit/procs 0.11.0-a9 → 0.11.1
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/.gitattributes +1 -0
- package/.yarn/install-state.gz +0 -0
- package/build.rs +74 -0
- package/editing-history/2026-0213-1841-trait-origin-structural-eq.md +91 -0
- package/editing-history/2026-0213-1926-docs-tests-followup.md +33 -0
- package/editing-history/2026-0214-2050-js-codegen-recursion-tag-migration.md +39 -0
- package/editing-history/2026-0214-2358-emit-js-modularization-shift-left.md +63 -0
- package/editing-history/2026-0215-1941-macro-diagnostics-refinement.md +39 -0
- package/editing-history/2026-0215-diagnostics-consolidated.md +35 -0
- package/editing-history/2026-0216-2043-core-api-docs-cleanup.md +40 -0
- package/editing-history/2026-0216-2128-docs-smoke-and-trait-errors.md +20 -0
- package/lib/calcit-data.mjs +9 -0
- package/lib/calcit.procs.mjs +60 -21
- package/lib/custom-formatter.mjs +2 -2
- package/lib/js-arity-helpers.mjs +9 -0
- 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 +32 -16
- package/lib/js-tag-helpers.mjs +15 -0
- package/lib/js-tuple.mjs +12 -10
- package/lib/package.json +9 -2
- package/package.json +9 -2
- package/ts-src/calcit-data.mts +9 -0
- package/ts-src/calcit.procs.mts +63 -23
- package/ts-src/custom-formatter.mts +2 -2
- package/ts-src/js-arity-helpers.mts +11 -0
- 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 +32 -17
- package/ts-src/js-tag-helpers.mts +17 -0
- package/ts-src/js-tuple.mts +14 -11
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 {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export let _args_throw = (name, expected, got) => {
|
|
2
|
+
return new Error(`\`${name}\` expected ${expected} params, got ${got}`);
|
|
3
|
+
};
|
|
4
|
+
export let _args_fewer_throw = (name, min, got) => {
|
|
5
|
+
return new Error(`\`${name}\` expected at least ${min} params, got ${got}`);
|
|
6
|
+
};
|
|
7
|
+
export let _args_between_throw = (name, min, max, got) => {
|
|
8
|
+
return new Error(`\`${name}\` expected ${min}-${max} params, got ${got}`);
|
|
9
|
+
};
|
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) {
|
|
@@ -122,18 +131,28 @@ export let fieldsEqual = (xs, ys) => {
|
|
|
122
131
|
return true;
|
|
123
132
|
};
|
|
124
133
|
export let _$n__PCT__$M_ = (proto, ...xs) => {
|
|
134
|
+
let recordProto;
|
|
125
135
|
if (proto instanceof CalcitRecord) {
|
|
136
|
+
recordProto = proto;
|
|
137
|
+
}
|
|
138
|
+
else if (proto instanceof CalcitStruct) {
|
|
139
|
+
recordProto = new CalcitRecord(proto.name, proto.fields, new Array(proto.fields.length).fill(null), proto);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
throw new Error("Expected prototype to be a record");
|
|
143
|
+
}
|
|
144
|
+
{
|
|
126
145
|
if (xs.length % 2 !== 0) {
|
|
127
146
|
throw new Error("Expected even number of key/value");
|
|
128
147
|
}
|
|
129
|
-
if (xs.length !==
|
|
148
|
+
if (xs.length !== recordProto.fields.length * 2) {
|
|
130
149
|
throw new Error("fields size does not match");
|
|
131
150
|
}
|
|
132
|
-
let values = new Array(
|
|
133
|
-
for (let i = 0; i <
|
|
151
|
+
let values = new Array(recordProto.fields.length);
|
|
152
|
+
for (let i = 0; i < recordProto.fields.length; i++) {
|
|
134
153
|
let idx = -1;
|
|
135
|
-
let k =
|
|
136
|
-
for (let j = 0; j <
|
|
154
|
+
let k = recordProto.fields[i];
|
|
155
|
+
for (let j = 0; j < recordProto.fields.length; j++) {
|
|
137
156
|
if (k === castTag(xs[j * 2])) {
|
|
138
157
|
idx = j;
|
|
139
158
|
break;
|
|
@@ -147,10 +166,7 @@ export let _$n__PCT__$M_ = (proto, ...xs) => {
|
|
|
147
166
|
}
|
|
148
167
|
values[i] = xs[idx * 2 + 1];
|
|
149
168
|
}
|
|
150
|
-
return new CalcitRecord(
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
throw new Error("Expected prototype to be a record");
|
|
169
|
+
return new CalcitRecord(recordProto.name, recordProto.fields, values, recordProto.structRef);
|
|
154
170
|
}
|
|
155
171
|
};
|
|
156
172
|
/// update record with new values
|
|
@@ -169,7 +185,7 @@ export let _$n_record_$o_with = (proto, ...xs) => {
|
|
|
169
185
|
}
|
|
170
186
|
values[idx] = v;
|
|
171
187
|
}
|
|
172
|
-
return new CalcitRecord(proto.name, proto.fields, values, proto.
|
|
188
|
+
return new CalcitRecord(proto.name, proto.fields, values, proto.structRef);
|
|
173
189
|
}
|
|
174
190
|
else {
|
|
175
191
|
throw new Error("Expected prototype to be a record");
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { newTag } from "./calcit-data.mjs";
|
|
2
|
+
let _tag_cache = {};
|
|
3
|
+
export let init_tags = (arr) => {
|
|
4
|
+
let tags = {};
|
|
5
|
+
for (let idx = 0; idx < arr.length; idx++) {
|
|
6
|
+
let name = arr[idx];
|
|
7
|
+
let item = _tag_cache[name];
|
|
8
|
+
if (item === undefined) {
|
|
9
|
+
item = newTag(name);
|
|
10
|
+
_tag_cache[name] = item;
|
|
11
|
+
}
|
|
12
|
+
tags[name] = item;
|
|
13
|
+
}
|
|
14
|
+
return tags;
|
|
15
|
+
};
|
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calcit/procs",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"main": "./lib/calcit.procs.mjs",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@types/node": "^25.0.9",
|
|
@@ -8,11 +8,18 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"compile": "rm -rfv lib/* && tsc",
|
|
11
|
-
"procs-link": "ln -
|
|
11
|
+
"procs-link": "ln -sfn ../../ node_modules/@calcit/procs",
|
|
12
12
|
"cp-mac": "cargo build --release && rm -rfv builds/* && node scripts/cp-version.js && scp builds/* rsync-user@calcit-lang.org:/web-assets/repo/calcit-lang/binaries/macos/",
|
|
13
13
|
"eval": "cargo run --bin cr -- eval",
|
|
14
|
+
"fmt-rs": "cargo fmt --all",
|
|
15
|
+
"lint-rs": "cargo clippy --all-targets -- -D warnings",
|
|
16
|
+
"test-rs": "cargo test -q",
|
|
17
|
+
"test-snippets": "cargo test -q snippets::tests",
|
|
18
|
+
"bench-recur-smoke": "cargo run --bin cr -- calcit/test.cirru -1 js && node --input-type=module -e \"import { test_loop } from './js-out/test-recursion.main.mjs'; const n=3000; const t0=process.hrtime.bigint(); for(let i=0;i<n;i++) test_loop(); const dt=Number(process.hrtime.bigint()-t0)/1e6; console.log('test_loop_ms='+dt.toFixed(3));\"",
|
|
19
|
+
"check-smooth": "yarn fmt-rs && yarn lint-rs && yarn test-rs && yarn check-all",
|
|
14
20
|
"check-all": "yarn compile && yarn try-rs && yarn try-js && yarn try-ir",
|
|
15
21
|
"try-rs": "cargo run --bin cr -- calcit/test.cirru -1",
|
|
22
|
+
"warn-dyn-method": "cargo run --bin cr -- calcit/test.cirru -1 --warn-dyn-method",
|
|
16
23
|
"try-js-brk": "cargo run --bin cr -- calcit/test.cirru -1 js && node --inspect-brk js-out/main.mjs",
|
|
17
24
|
"try-js": "cargo run --bin cr -- calcit/test.cirru -1 js && node js-out/main.mjs",
|
|
18
25
|
"try-ir": "cargo run --bin cr -- calcit/test.cirru -1 js"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calcit/procs",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"main": "./lib/calcit.procs.mjs",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@types/node": "^25.0.9",
|
|
@@ -8,11 +8,18 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"compile": "rm -rfv lib/* && tsc",
|
|
11
|
-
"procs-link": "ln -
|
|
11
|
+
"procs-link": "ln -sfn ../../ node_modules/@calcit/procs",
|
|
12
12
|
"cp-mac": "cargo build --release && rm -rfv builds/* && node scripts/cp-version.js && scp builds/* rsync-user@calcit-lang.org:/web-assets/repo/calcit-lang/binaries/macos/",
|
|
13
13
|
"eval": "cargo run --bin cr -- eval",
|
|
14
|
+
"fmt-rs": "cargo fmt --all",
|
|
15
|
+
"lint-rs": "cargo clippy --all-targets -- -D warnings",
|
|
16
|
+
"test-rs": "cargo test -q",
|
|
17
|
+
"test-snippets": "cargo test -q snippets::tests",
|
|
18
|
+
"bench-recur-smoke": "cargo run --bin cr -- calcit/test.cirru -1 js && node --input-type=module -e \"import { test_loop } from './js-out/test-recursion.main.mjs'; const n=3000; const t0=process.hrtime.bigint(); for(let i=0;i<n;i++) test_loop(); const dt=Number(process.hrtime.bigint()-t0)/1e6; console.log('test_loop_ms='+dt.toFixed(3));\"",
|
|
19
|
+
"check-smooth": "yarn fmt-rs && yarn lint-rs && yarn test-rs && yarn check-all",
|
|
14
20
|
"check-all": "yarn compile && yarn try-rs && yarn try-js && yarn try-ir",
|
|
15
21
|
"try-rs": "cargo run --bin cr -- calcit/test.cirru -1",
|
|
22
|
+
"warn-dyn-method": "cargo run --bin cr -- calcit/test.cirru -1 --warn-dyn-method",
|
|
16
23
|
"try-js-brk": "cargo run --bin cr -- calcit/test.cirru -1 js && node --inspect-brk js-out/main.mjs",
|
|
17
24
|
"try-js": "cargo run --bin cr -- calcit/test.cirru -1 js && node js-out/main.mjs",
|
|
18
25
|
"try-ir": "cargo run --bin cr -- calcit/test.cirru -1 js"
|
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
|
@@ -41,6 +41,8 @@ export * from "./js-tuple.mjs";
|
|
|
41
41
|
export * from "./js-trait.mjs";
|
|
42
42
|
export * from "./custom-formatter.mjs";
|
|
43
43
|
export * from "./js-cirru.mjs";
|
|
44
|
+
export * from "./js-arity-helpers.mjs";
|
|
45
|
+
export * from "./js-tag-helpers.mjs";
|
|
44
46
|
export { _$n_compare } from "./js-primes.mjs";
|
|
45
47
|
|
|
46
48
|
import { CalcitList, CalcitSliceList, foldl } from "./js-list.mjs";
|
|
@@ -230,14 +232,15 @@ export let defenum = (name: CalcitValue, ...variants: CalcitValue[]): CalcitEnum
|
|
|
230
232
|
const tags = entries.map((entry) => entry.tag);
|
|
231
233
|
const values = entries.map((entry) => entry.payload);
|
|
232
234
|
const prototype = new CalcitRecord(enumName, tags, values, null);
|
|
233
|
-
return new CalcitEnum(prototype
|
|
235
|
+
return new CalcitEnum(prototype);
|
|
234
236
|
};
|
|
235
237
|
|
|
236
238
|
export let _$n_impl_$o__$o_new = (name: CalcitValue, ...pairs: CalcitValue[]): CalcitImpl => {
|
|
237
239
|
if (name === undefined) throw new Error("&impl::new expected arguments");
|
|
238
|
-
const
|
|
240
|
+
const origin = name instanceof CalcitTrait ? name : null;
|
|
241
|
+
const implName = origin ? origin.name : castTag(name);
|
|
239
242
|
if (pairs.length === 0) {
|
|
240
|
-
return new CalcitImpl(implName, [], []);
|
|
243
|
+
return new CalcitImpl(implName, [], [], origin);
|
|
241
244
|
}
|
|
242
245
|
const entries: Array<{ tag: CalcitTag; value: CalcitValue }> = [];
|
|
243
246
|
for (let idx = 0; idx < pairs.length; idx++) {
|
|
@@ -268,7 +271,7 @@ export let _$n_impl_$o__$o_new = (name: CalcitValue, ...pairs: CalcitValue[]): C
|
|
|
268
271
|
}
|
|
269
272
|
const fields = entries.map((entry) => entry.tag);
|
|
270
273
|
const values = entries.map((entry) => entry.value);
|
|
271
|
-
return new CalcitImpl(implName, fields, values);
|
|
274
|
+
return new CalcitImpl(implName, fields, values, origin);
|
|
272
275
|
};
|
|
273
276
|
|
|
274
277
|
export let _$n_struct_$o__$o_new = (name: CalcitValue, ...entries: CalcitValue[]): CalcitStruct => {
|
|
@@ -508,14 +511,26 @@ export let _$n_tuple_$o_with_impls = function (x: CalcitTuple, y: CalcitValue) {
|
|
|
508
511
|
if (arguments.length !== 2) throw new Error("&tuple:with-impls takes 2 arguments");
|
|
509
512
|
if (!(x instanceof CalcitTuple)) throw new Error("&tuple:with-impls expects a tuple");
|
|
510
513
|
const impl = coerce_impl(y, "&tuple:with-impls");
|
|
511
|
-
|
|
514
|
+
let proto = x.enumPrototype;
|
|
515
|
+
if (proto == null) {
|
|
516
|
+
proto = new CalcitEnum(new CalcitRecord(newTag("anonymous-tuple"), [], [], new CalcitStruct(newTag("anonymous-tuple"), [], [])));
|
|
517
|
+
}
|
|
518
|
+
return new CalcitTuple(x.tag, x.extra, proto.withImpls(impl));
|
|
512
519
|
};
|
|
513
520
|
|
|
514
521
|
export let _$n_tuple_$o_impl_traits = function (x: CalcitValue, ...traits: CalcitValue[]) {
|
|
515
522
|
if (traits.length < 1) throw new Error("&tuple:impl-traits takes 2+ arguments");
|
|
516
523
|
if (!(x instanceof CalcitTuple)) throw new Error("&tuple:impl-traits expects a tuple");
|
|
517
524
|
const impls = traits.map((trait) => coerce_impl(trait, "&tuple:impl-traits"));
|
|
518
|
-
|
|
525
|
+
let proto = x.enumPrototype;
|
|
526
|
+
if (proto == null) {
|
|
527
|
+
const tagName = x.tag instanceof CalcitTag ? x.tag : newTag("tag");
|
|
528
|
+
const anyTypes = new CalcitSliceList(new Array(x.extra.length).fill(newTag("any")));
|
|
529
|
+
proto = new CalcitEnum(
|
|
530
|
+
new CalcitRecord(newTag("anonymous-tuple"), [tagName], [anyTypes], new CalcitStruct(newTag("anonymous-tuple"), [tagName], [anyTypes]))
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
return new CalcitTuple(x.tag, x.extra, proto.withImpls(impls));
|
|
519
534
|
};
|
|
520
535
|
|
|
521
536
|
export let _$n_tuple_$o_enum = function (x: CalcitTuple) {
|
|
@@ -527,7 +542,7 @@ export let _$n_tuple_$o_enum = function (x: CalcitTuple) {
|
|
|
527
542
|
if (x.enumPrototype instanceof CalcitEnum) {
|
|
528
543
|
return x.enumPrototype;
|
|
529
544
|
}
|
|
530
|
-
return new CalcitEnum(x.enumPrototype as CalcitRecord
|
|
545
|
+
return new CalcitEnum(x.enumPrototype as CalcitRecord);
|
|
531
546
|
};
|
|
532
547
|
|
|
533
548
|
const unwrap_enum_prototype = (enumPrototype: CalcitValue, procName: string): CalcitRecord => {
|
|
@@ -649,7 +664,7 @@ export let _$n_record_$o_assoc = function (xs: CalcitValue, k: CalcitValue, v: C
|
|
|
649
664
|
|
|
650
665
|
export let _$n_record_$o_impls = function (xs: CalcitValue) {
|
|
651
666
|
if (arguments.length !== 1) throw new Error("&record:impls takes 1 argument");
|
|
652
|
-
if (xs instanceof CalcitRecord) return new CalcitSliceList(xs.impls);
|
|
667
|
+
if (xs instanceof CalcitRecord) return new CalcitSliceList(xs.structRef.impls);
|
|
653
668
|
throw new Error("&record:impls expected a record");
|
|
654
669
|
};
|
|
655
670
|
|
|
@@ -657,7 +672,8 @@ export let _$n_record_$o_impl_traits = function (xs: CalcitValue, ...traits: Cal
|
|
|
657
672
|
if (traits.length < 1) throw new Error("&record:impl-traits takes 2+ arguments");
|
|
658
673
|
if (!(xs instanceof CalcitRecord)) throw new Error("&record:impl-traits expected a record");
|
|
659
674
|
const impls = traits.map((trait) => coerce_impl(trait, "&record:impl-traits"));
|
|
660
|
-
|
|
675
|
+
const nextStruct = new CalcitStruct(xs.name, xs.fields, xs.structRef.fieldTypes, xs.structRef.impls.concat(impls));
|
|
676
|
+
return new CalcitRecord(xs.name, xs.fields, xs.values, nextStruct);
|
|
661
677
|
};
|
|
662
678
|
|
|
663
679
|
export let _$n_struct_$o_impl_traits = function (xs: CalcitValue, ...traits: CalcitValue[]) {
|
|
@@ -672,15 +688,42 @@ export let _$n_enum_$o_impl_traits = function (xs: CalcitValue, ...traits: Calci
|
|
|
672
688
|
if (traits.length < 1) throw new Error("&enum:impl-traits takes 2+ arguments");
|
|
673
689
|
const addedImpls = traits.map((trait) => coerce_impl(trait, "&enum:impl-traits"));
|
|
674
690
|
if (xs instanceof CalcitEnum) {
|
|
675
|
-
|
|
676
|
-
return new CalcitEnum(xs.prototype, baseImpls.concat(addedImpls));
|
|
691
|
+
return xs.withImpls(addedImpls);
|
|
677
692
|
}
|
|
678
693
|
if (xs instanceof CalcitRecord) {
|
|
679
|
-
|
|
694
|
+
const nextStruct = new CalcitStruct(xs.name, xs.fields, xs.structRef.fieldTypes, xs.structRef.impls.concat(addedImpls));
|
|
695
|
+
return new CalcitRecord(xs.name, xs.fields, xs.values, nextStruct);
|
|
680
696
|
}
|
|
681
697
|
throw new Error("&enum:impl-traits expected an enum or enum record");
|
|
682
698
|
};
|
|
683
699
|
|
|
700
|
+
export let _$n_impl_$o_origin = function (impl: CalcitValue): CalcitValue {
|
|
701
|
+
if (arguments.length !== 1) throw new Error("&impl:origin expected 1 argument");
|
|
702
|
+
if (impl instanceof CalcitImpl) {
|
|
703
|
+
return impl.origin ?? null;
|
|
704
|
+
}
|
|
705
|
+
throw new Error(`&impl:origin expected an impl, but received: ${toString(impl, true)}`);
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
export let _$n_impl_$o_get = function (impl: CalcitValue, name: CalcitValue): CalcitValue {
|
|
709
|
+
if (arguments.length !== 2) throw new Error("&impl:get expected 2 arguments");
|
|
710
|
+
if (!(impl instanceof CalcitImpl)) {
|
|
711
|
+
throw new Error(`&impl:get expected an impl as first argument, but received: ${toString(impl, true)}`);
|
|
712
|
+
}
|
|
713
|
+
return impl.get(name);
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
export let _$n_impl_$o_nth = function (impl: CalcitValue, index: CalcitValue): CalcitValue {
|
|
717
|
+
if (arguments.length !== 2) throw new Error("&impl:nth expected 2 arguments");
|
|
718
|
+
if (!(impl instanceof CalcitImpl)) {
|
|
719
|
+
throw new Error(`&impl:nth expected an impl as first argument, but received: ${toString(impl, true)}`);
|
|
720
|
+
}
|
|
721
|
+
if (typeof index !== "number" || !Number.isInteger(index) || index < 0) {
|
|
722
|
+
throw new Error(`&impl:nth expected a non-negative integer index, but received: ${toString(index, true)}`);
|
|
723
|
+
}
|
|
724
|
+
return impl.values[index];
|
|
725
|
+
};
|
|
726
|
+
|
|
684
727
|
export let _$n_list_$o_assoc_before = function (xs: CalcitList | CalcitSliceList, k: number, v: CalcitValue): CalcitList {
|
|
685
728
|
if (arguments.length !== 3) {
|
|
686
729
|
throw new Error("assoc takes 3 arguments");
|
|
@@ -1601,7 +1644,7 @@ export let _$n_js_object = (...xs: CalcitValue[]): Record<string, CalcitValue> =
|
|
|
1601
1644
|
};
|
|
1602
1645
|
|
|
1603
1646
|
export let _$o__$o_ = (tagName: CalcitValue, ...extra: CalcitValue[]): CalcitTuple => {
|
|
1604
|
-
return new CalcitTuple(tagName, extra,
|
|
1647
|
+
return new CalcitTuple(tagName, extra, null);
|
|
1605
1648
|
};
|
|
1606
1649
|
|
|
1607
1650
|
export let _PCT__$o__$o_ = (enumPrototype: CalcitValue, tag: CalcitValue, ...extra: CalcitValue[]): CalcitTuple => {
|
|
@@ -1624,7 +1667,7 @@ export let _PCT__$o__$o_ = (enumPrototype: CalcitValue, tag: CalcitValue, ...ext
|
|
|
1624
1667
|
}
|
|
1625
1668
|
|
|
1626
1669
|
const tupleEnumPrototype = enumPrototype instanceof CalcitEnum ? enumPrototype : proto;
|
|
1627
|
-
return new CalcitTuple(tag, extra,
|
|
1670
|
+
return new CalcitTuple(tag, extra, tupleEnumPrototype);
|
|
1628
1671
|
};
|
|
1629
1672
|
|
|
1630
1673
|
export let _PCT__PCT__$o__$o_ = (impl: CalcitValue, enumPrototype: CalcitValue, tag: CalcitValue, ...extra: CalcitValue[]): CalcitTuple => {
|
|
@@ -1647,9 +1690,9 @@ export let _PCT__PCT__$o__$o_ = (impl: CalcitValue, enumPrototype: CalcitValue,
|
|
|
1647
1690
|
throw new Error(`Expected variant definition to be a list, got ${variantDefinition}`);
|
|
1648
1691
|
}
|
|
1649
1692
|
|
|
1650
|
-
const tupleEnumPrototype = enumPrototype instanceof CalcitEnum ? enumPrototype : proto;
|
|
1693
|
+
const tupleEnumPrototype = enumPrototype instanceof CalcitEnum ? enumPrototype : (proto as any);
|
|
1651
1694
|
const implValue = coerce_impl(impl, "%:: with impl");
|
|
1652
|
-
return new CalcitTuple(tag, extra,
|
|
1695
|
+
return new CalcitTuple(tag, extra, tupleEnumPrototype.withImpls(implValue));
|
|
1653
1696
|
};
|
|
1654
1697
|
|
|
1655
1698
|
// mutable place for core to register
|
|
@@ -1699,7 +1742,7 @@ function lookup_impls(obj: CalcitValue): [CalcitImpl[], string] {
|
|
|
1699
1742
|
impls = normalize_builtin_impls(calcit_builtin_impls.map);
|
|
1700
1743
|
} else if (obj instanceof CalcitRecord) {
|
|
1701
1744
|
tag = obj.name.toString();
|
|
1702
|
-
impls = obj.impls;
|
|
1745
|
+
impls = obj.structRef.impls;
|
|
1703
1746
|
} else if (obj instanceof CalcitTuple) {
|
|
1704
1747
|
tag = obj.tag.toString();
|
|
1705
1748
|
impls = obj.impls;
|
|
@@ -1808,7 +1851,8 @@ export function _$n_inspect_methods(obj: CalcitValue, note: CalcitValue): Calcit
|
|
|
1808
1851
|
for (let k = 0; k < impl.fields.length; k++) {
|
|
1809
1852
|
names.push("." + impl.fields[k].value);
|
|
1810
1853
|
}
|
|
1811
|
-
|
|
1854
|
+
const originName = impl.origin != null ? impl.origin.name.toString() : impl.name.toString();
|
|
1855
|
+
console.log(` #${i}: ${originName} (${names.join(" ")})`);
|
|
1812
1856
|
}
|
|
1813
1857
|
|
|
1814
1858
|
let ms = _$n_methods_of(obj);
|
|
@@ -1841,7 +1885,7 @@ export function _$n_trait_call(traitDef: CalcitValue, method: CalcitValue, obj:
|
|
|
1841
1885
|
let idx = reverse ? impls.length - 1 : 0;
|
|
1842
1886
|
while (reverse ? idx >= 0 : idx < impls.length) {
|
|
1843
1887
|
const impl = impls[idx];
|
|
1844
|
-
if (impl != null && impl.name.value === traitDef.name.value) {
|
|
1888
|
+
if (impl != null && impl.origin != null && impl.origin.name.value === traitDef.name.value) {
|
|
1845
1889
|
const fn = impl.getOrNil(methodName);
|
|
1846
1890
|
if (fn != null) {
|
|
1847
1891
|
if (typeof fn !== "function") {
|
|
@@ -2004,9 +2048,5 @@ export let macroexpand = unavailableProc;
|
|
|
2004
2048
|
export let macroexpand_all = unavailableProc;
|
|
2005
2049
|
export let _$n_get_calcit_running_mode = unavailableProc;
|
|
2006
2050
|
|
|
2007
|
-
export let _args_throw = (name: string, expected: number, got: number) => {
|
|
2008
|
-
return new Error(`\`${name}\` expected ${expected} params, got ${got}`);
|
|
2009
|
-
};
|
|
2010
|
-
|
|
2011
2051
|
// already handled in code emitter
|
|
2012
2052
|
export let raise = unavailableProc;
|
|
@@ -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
|
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export let _args_throw = (name: string, expected: number, got: number) => {
|
|
2
|
+
return new Error(`\`${name}\` expected ${expected} params, got ${got}`);
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
export let _args_fewer_throw = (name: string, min: number, got: number) => {
|
|
6
|
+
return new Error(`\`${name}\` expected at least ${min} params, got ${got}`);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export let _args_between_throw = (name: string, min: number, max: number, got: number) => {
|
|
10
|
+
return new Error(`\`${name}\` expected ${min}-${max} params, got ${got}`);
|
|
11
|
+
};
|
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 {
|