@calcit/procs 0.28.0-alpha.3 → 0.28.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/lib/calcit-data.d.mts +2 -0
- package/lib/calcit-data.mjs +61 -15
- package/lib/calcit.procs.d.mts +2 -0
- package/lib/calcit.procs.mjs +17 -16
- package/lib/js-list.d.mts +4 -3
- package/lib/js-list.mjs +31 -25
- package/lib/js-primes.mjs +76 -1
- package/lib/js-struct-def.d.mts +4 -1
- package/lib/js-struct-def.mjs +12 -4
- package/lib/js-struct-value.mjs +1 -1
- package/lib/package.json +4 -3
- package/package.json +4 -3
package/lib/calcit-data.d.mts
CHANGED
|
@@ -27,6 +27,8 @@ export type CalcitFn = (...xs: CalcitValue[]) => CalcitValue;
|
|
|
27
27
|
export declare let getStringName: (x: CalcitValue) => string;
|
|
28
28
|
/** Compare tag names by Unicode scalar value, matching Rust `str` ordering. */
|
|
29
29
|
export declare function compareTagNames(x: CalcitTag, y: CalcitTag): number;
|
|
30
|
+
/** Compare scalar values, matching Rust string ordering rather than UTF-16. */
|
|
31
|
+
export declare function compareUnicodeStrings(x: string, y: string): number;
|
|
30
32
|
export declare function tagNamesAreCanonical(fields: CalcitTag[]): boolean;
|
|
31
33
|
export declare function canonicalizeTagPairs<T>(fields: CalcitTag[], values: T[], context: string): [CalcitTag[], T[]];
|
|
32
34
|
/** returns -1 when not found */
|
package/lib/calcit-data.mjs
CHANGED
|
@@ -107,11 +107,15 @@ export let getStringName = (x) => {
|
|
|
107
107
|
};
|
|
108
108
|
/** Compare tag names by Unicode scalar value, matching Rust `str` ordering. */
|
|
109
109
|
export function compareTagNames(x, y) {
|
|
110
|
+
return compareUnicodeStrings(x.value, y.value);
|
|
111
|
+
}
|
|
112
|
+
/** Compare scalar values, matching Rust string ordering rather than UTF-16. */
|
|
113
|
+
export function compareUnicodeStrings(x, y) {
|
|
110
114
|
let xIdx = 0;
|
|
111
115
|
let yIdx = 0;
|
|
112
|
-
while (xIdx < x.
|
|
113
|
-
const xCode = x.
|
|
114
|
-
const yCode = y.
|
|
116
|
+
while (xIdx < x.length && yIdx < y.length) {
|
|
117
|
+
const xCode = x.codePointAt(xIdx);
|
|
118
|
+
const yCode = y.codePointAt(yIdx);
|
|
115
119
|
if (xCode < yCode)
|
|
116
120
|
return -1;
|
|
117
121
|
if (xCode > yCode)
|
|
@@ -119,9 +123,9 @@ export function compareTagNames(x, y) {
|
|
|
119
123
|
xIdx += xCode > 0xffff ? 2 : 1;
|
|
120
124
|
yIdx += yCode > 0xffff ? 2 : 1;
|
|
121
125
|
}
|
|
122
|
-
if (xIdx < x.
|
|
126
|
+
if (xIdx < x.length)
|
|
123
127
|
return 1;
|
|
124
|
-
if (yIdx < y.
|
|
128
|
+
if (yIdx < y.length)
|
|
125
129
|
return -1;
|
|
126
130
|
return 0;
|
|
127
131
|
}
|
|
@@ -221,6 +225,9 @@ let defaultHash_struct = valueHash("struct:");
|
|
|
221
225
|
let defaultHash_enum = valueHash("enum:");
|
|
222
226
|
let defaultHash_cirru_quote = valueHash("cirru-quote:");
|
|
223
227
|
let defaultHash_unknown = valueHash("unknown:");
|
|
228
|
+
let defaultHash_buffer = valueHash("buffer:");
|
|
229
|
+
/** Identity hashes for host values, kept outside the objects so frozen or DOM objects are never mutated. */
|
|
230
|
+
let hostValueHashes = new WeakMap();
|
|
224
231
|
let fnHashCounter = 0;
|
|
225
232
|
let jsObjectHashCounter = 0;
|
|
226
233
|
export let hashFunction = (x) => {
|
|
@@ -261,15 +268,20 @@ export let hashFunction = (x) => {
|
|
|
261
268
|
if (typeof x === "function") {
|
|
262
269
|
// method values are closures created on the fly (see invoke_method_closure);
|
|
263
270
|
// hash by method name so equal methods share the same hash, matching isEqual
|
|
271
|
+
// cache in a WeakMap instead of writing onto the function, so frozen functions hash safely
|
|
272
|
+
const cachedFn = hostValueHashes.get(x);
|
|
273
|
+
if (cachedFn != null) {
|
|
274
|
+
return cachedFn;
|
|
275
|
+
}
|
|
264
276
|
const methodName = x.__calcitMethodName;
|
|
265
277
|
if (methodName != null) {
|
|
266
278
|
let h = mergeValueHash(defaultHash_fn, methodName);
|
|
267
|
-
x
|
|
279
|
+
hostValueHashes.set(x, h);
|
|
268
280
|
return h;
|
|
269
281
|
}
|
|
270
282
|
fnHashCounter = fnHashCounter + 1;
|
|
271
283
|
let h = mergeValueHash(defaultHash_fn, fnHashCounter);
|
|
272
|
-
x
|
|
284
|
+
hostValueHashes.set(x, h);
|
|
273
285
|
return h;
|
|
274
286
|
}
|
|
275
287
|
if (x instanceof CalcitRef) {
|
|
@@ -344,6 +356,8 @@ export let hashFunction = (x) => {
|
|
|
344
356
|
}
|
|
345
357
|
if (x instanceof CalcitStructValue) {
|
|
346
358
|
let base = defaultHash_record;
|
|
359
|
+
base = mergeValueHash(base, hashFunction(x.name));
|
|
360
|
+
base = mergeValueHash(base, hashFunction(x.structRef.definitionRef));
|
|
347
361
|
for (let idx = 0; idx < x.fields.length; idx++) {
|
|
348
362
|
base = mergeValueHash(base, hashFunction(x.fields[idx]));
|
|
349
363
|
base = mergeValueHash(base, hashFunction(x.values[idx]));
|
|
@@ -391,15 +405,28 @@ export let hashFunction = (x) => {
|
|
|
391
405
|
base = hashCirru(base, x.value);
|
|
392
406
|
return base;
|
|
393
407
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
408
|
+
if (x instanceof Uint8Array) {
|
|
409
|
+
// Buffers are values: equal bytes must hash equally, matching native Buffer equality.
|
|
410
|
+
let base = mergeValueHash(defaultHash_buffer, x.length);
|
|
411
|
+
for (let idx = 0; idx < x.length; idx++) {
|
|
412
|
+
base = mergeValueHash(base, x[idx]);
|
|
413
|
+
}
|
|
414
|
+
return base;
|
|
415
|
+
}
|
|
416
|
+
if (typeof x === "object" || typeof x === "function") {
|
|
417
|
+
// Host values compare by identity, so they hash by identity as well.
|
|
418
|
+
let cached = hostValueHashes.get(x);
|
|
419
|
+
if (cached != null) {
|
|
420
|
+
return cached;
|
|
421
|
+
}
|
|
422
|
+
jsObjectHashCounter = jsObjectHashCounter + 1;
|
|
423
|
+
let hashHostValue = mergeValueHash(defaultHash_unknown, jsObjectHashCounter);
|
|
424
|
+
hostValueHashes.set(x, hashHostValue);
|
|
425
|
+
return hashHostValue;
|
|
426
|
+
}
|
|
427
|
+
console.warn(`[warn] calcit-js has no method for hashing this: ${String(x)}`);
|
|
399
428
|
jsObjectHashCounter = jsObjectHashCounter + 1;
|
|
400
|
-
|
|
401
|
-
x[calcit_dirty_hash_key] = hashJsObject;
|
|
402
|
-
return hashJsObject;
|
|
429
|
+
return mergeValueHash(defaultHash_unknown, jsObjectHashCounter);
|
|
403
430
|
};
|
|
404
431
|
/// traverse Cirru tree to make unique hash
|
|
405
432
|
let hashCirru = (base, x) => {
|
|
@@ -758,6 +785,9 @@ export let _$n__$e_ = (x, y) => {
|
|
|
758
785
|
if (x.name !== y.name) {
|
|
759
786
|
return false;
|
|
760
787
|
}
|
|
788
|
+
if (x.structRef.definitionRef !== y.structRef.definitionRef) {
|
|
789
|
+
return false;
|
|
790
|
+
}
|
|
761
791
|
if (!fieldsEqual(x.fields, y.fields)) {
|
|
762
792
|
return false;
|
|
763
793
|
}
|
|
@@ -817,6 +847,22 @@ export let _$n__$e_ = (x, y) => {
|
|
|
817
847
|
}
|
|
818
848
|
return false;
|
|
819
849
|
}
|
|
850
|
+
if (x instanceof Uint8Array) {
|
|
851
|
+
if (!(y instanceof Uint8Array) || x.length !== y.length) {
|
|
852
|
+
return false;
|
|
853
|
+
}
|
|
854
|
+
for (let idx = 0; idx < x.length; idx++) {
|
|
855
|
+
if (x[idx] !== y[idx]) {
|
|
856
|
+
return false;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return true;
|
|
860
|
+
}
|
|
861
|
+
if (tx === "object") {
|
|
862
|
+
// Host objects (DOM nodes, JS class instances, BufList) compare by identity;
|
|
863
|
+
// identical references were accepted at the top of this function.
|
|
864
|
+
return false;
|
|
865
|
+
}
|
|
820
866
|
throw new Error("Missing handler for this type");
|
|
821
867
|
};
|
|
822
868
|
// overwrite internary comparator of ternary-tree
|
package/lib/calcit.procs.d.mts
CHANGED
|
@@ -48,6 +48,7 @@ export declare const calcit_package_json: {
|
|
|
48
48
|
url: string;
|
|
49
49
|
};
|
|
50
50
|
dependencies: {
|
|
51
|
+
"@calcit/finger-vec": string;
|
|
51
52
|
"@calcit/ternary-tree": string;
|
|
52
53
|
"@cirru/parser.ts": string;
|
|
53
54
|
"@cirru/writer.ts": string;
|
|
@@ -355,6 +356,7 @@ export declare function invoke_method_closure(p: string): (obj: CalcitValue, ...
|
|
|
355
356
|
export declare function invoke_method(p: string, obj: CalcitValue, ...args: CalcitValue[]): CalcitValue;
|
|
356
357
|
export declare function _$n_methods_of(obj: CalcitValue): CalcitSliceList;
|
|
357
358
|
export declare function _$n_inspect_methods(obj: CalcitValue, note: CalcitValue): CalcitValue;
|
|
359
|
+
/** Dispatch through one nominal origin; duplicate implementations never select by order. */
|
|
358
360
|
export declare function _$n_trait_call(traitDef: CalcitValue, method: CalcitValue, obj: CalcitValue, ...args: CalcitValue[]): CalcitValue;
|
|
359
361
|
export declare let _$n_map_$o_to_list: (m: CalcitValue) => CalcitSliceList;
|
|
360
362
|
export declare let _$n_map_$o_keys: (m: CalcitValue) => CalcitSet;
|
package/lib/calcit.procs.mjs
CHANGED
|
@@ -33,7 +33,7 @@ import { CalcitSet } from "./js-set.mjs";
|
|
|
33
33
|
import { CalcitEnumValue } from "./js-enum-value.mjs";
|
|
34
34
|
import { to_calcit_data, extract_cirru_edn, extract_cirru_edn_for_typed, CalcitCirruQuote } from "./js-cirru.mjs";
|
|
35
35
|
import { TypedEdnSetView } from "./typed-edn.mjs";
|
|
36
|
-
import {
|
|
36
|
+
import { FingerVec } from "@calcit/finger-vec";
|
|
37
37
|
let inNodeJs = typeof process !== "undefined" && process?.release?.name === "node";
|
|
38
38
|
export let type_of = (x) => {
|
|
39
39
|
if (typeof x === "string") {
|
|
@@ -733,7 +733,7 @@ export let _$n_struct_$o_impl_traits = function (xs, ...traits) {
|
|
|
733
733
|
if (!(xs instanceof CalcitStructValue))
|
|
734
734
|
throw new Error("&struct:impl-traits expected a struct value");
|
|
735
735
|
const impls = traits.map((trait) => coerce_impl(trait, "&struct:impl-traits"));
|
|
736
|
-
const nextStruct = new CalcitStructDef(xs.name, xs.fields, xs.structRef.fieldTypes, xs.structRef.impls.concat(impls));
|
|
736
|
+
const nextStruct = new CalcitStructDef(xs.name, xs.fields, xs.structRef.fieldTypes, xs.structRef.impls.concat(impls), xs.structRef.definitionRef);
|
|
737
737
|
return new CalcitStructValue(xs.name, xs.fields, xs.values, nextStruct);
|
|
738
738
|
};
|
|
739
739
|
export let _$n_struct_def_$o_impl_traits = function (xs, ...traits) {
|
|
@@ -743,7 +743,7 @@ export let _$n_struct_def_$o_impl_traits = function (xs, ...traits) {
|
|
|
743
743
|
throw new Error("&struct-def:impl-traits expected a struct definition");
|
|
744
744
|
const addedImpls = traits.map((trait) => coerce_impl(trait, "&struct-def:impl-traits"));
|
|
745
745
|
const baseImpls = xs.impls ?? [];
|
|
746
|
-
return new CalcitStructDef(xs.name, xs.fields, xs.fieldTypes, baseImpls.concat(addedImpls));
|
|
746
|
+
return new CalcitStructDef(xs.name, xs.fields, xs.fieldTypes, baseImpls.concat(addedImpls), xs.definitionRef);
|
|
747
747
|
};
|
|
748
748
|
export let _$n_enum_def_$o_impl_traits = function (xs, ...traits) {
|
|
749
749
|
if (traits.length < 1)
|
|
@@ -1476,7 +1476,7 @@ export let _$n_get_env = (name, v0) => {
|
|
|
1476
1476
|
export let get_env = _$n_get_env;
|
|
1477
1477
|
export let _$n_get_args = () => {
|
|
1478
1478
|
const args = inNodeJs ? process.argv : [];
|
|
1479
|
-
return new CalcitList(
|
|
1479
|
+
return new CalcitList(FingerVec.from(args));
|
|
1480
1480
|
};
|
|
1481
1481
|
export let get_args = _$n_get_args;
|
|
1482
1482
|
/** Block for an integral millisecond duration and preserve host failures as Result values. */
|
|
@@ -2679,6 +2679,7 @@ export function _$n_inspect_methods(obj, note) {
|
|
|
2679
2679
|
console.log("\n");
|
|
2680
2680
|
return obj;
|
|
2681
2681
|
}
|
|
2682
|
+
/** Dispatch through one nominal origin; duplicate implementations never select by order. */
|
|
2682
2683
|
export function _$n_trait_call(traitDef, method, obj, ...args) {
|
|
2683
2684
|
if (arguments.length < 3) {
|
|
2684
2685
|
throw new Error("&trait-call expected 3+ arguments (trait, method, receiver, & args)");
|
|
@@ -2697,20 +2698,20 @@ export function _$n_trait_call(traitDef, method, obj, ...args) {
|
|
|
2697
2698
|
throw new Error(`&trait-call cannot resolve impls for: ${toString(obj, true)}`);
|
|
2698
2699
|
}
|
|
2699
2700
|
const impls = pair[0];
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2701
|
+
// Explicit trait selection disambiguates origins, not implementations of
|
|
2702
|
+
// one origin. Check all candidates before invoking any method.
|
|
2703
|
+
const matchingImpls = impls.filter((impl) => impl != null && impl.origin === traitDef);
|
|
2704
|
+
if (matchingImpls.length > 1) {
|
|
2705
|
+
throw new Error(`[E_DUPLICATE_TRAIT_IMPL] &trait-call: trait ${traitDef.name.toString()} has ${matchingImpls.length} implementations attached to the same receiver; dispatch cannot choose between duplicate impls`);
|
|
2706
|
+
}
|
|
2707
|
+
if (matchingImpls.length === 1) {
|
|
2708
|
+
const fn = matchingImpls[0].getOrNil(methodName);
|
|
2709
|
+
if (fn != null) {
|
|
2710
|
+
if (typeof fn !== "function") {
|
|
2711
|
+
throw new Error(`&trait-call: method :${methodName} for trait ${traitDef.name.toString()} is not a function: ${toString(fn, true)}`);
|
|
2711
2712
|
}
|
|
2713
|
+
return fn(obj, ...args);
|
|
2712
2714
|
}
|
|
2713
|
-
idx += reverse ? -1 : 1;
|
|
2714
2715
|
}
|
|
2715
2716
|
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.`);
|
|
2716
2717
|
}
|
package/lib/js-list.d.mts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { FingerVec } from "@calcit/finger-vec";
|
|
2
|
+
import { Hash } from "@calcit/ternary-tree";
|
|
1
3
|
import { CalcitValue } from "./js-primes.mjs";
|
|
2
|
-
import { TernaryTreeList, Hash } from "@calcit/ternary-tree";
|
|
3
4
|
import { CalcitFn } from "./calcit-data.mjs";
|
|
4
5
|
export declare class CalcitList {
|
|
5
|
-
value:
|
|
6
|
+
value: FingerVec<CalcitValue>;
|
|
6
7
|
cachedHash: Hash;
|
|
7
|
-
constructor(value:
|
|
8
|
+
constructor(value: FingerVec<CalcitValue>);
|
|
8
9
|
len(): number;
|
|
9
10
|
get(idx: number): CalcitValue;
|
|
10
11
|
assoc(idx: number, v: CalcitValue): CalcitList;
|
package/lib/js-list.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FingerVec } from "@calcit/finger-vec";
|
|
2
2
|
import { isLiteral } from "./js-primes.mjs";
|
|
3
|
-
import { initTernaryTreeList, initTernaryTreeListFromRange, listLen, listGet, assocList, listToItems, dissocList, assocBefore, assocAfter, } from "@calcit/ternary-tree";
|
|
4
3
|
import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
|
|
5
4
|
import { CalcitSet } from "./js-set.mjs";
|
|
6
5
|
import { CalcitEnumValue } from "./js-enum-value.mjs";
|
|
@@ -10,35 +9,38 @@ export class CalcitList {
|
|
|
10
9
|
constructor(value) {
|
|
11
10
|
this.cachedHash = null;
|
|
12
11
|
if (value == null) {
|
|
13
|
-
this.value =
|
|
12
|
+
this.value = FingerVec.empty();
|
|
14
13
|
}
|
|
15
14
|
else {
|
|
16
15
|
this.value = value;
|
|
17
16
|
}
|
|
18
17
|
}
|
|
19
18
|
len() {
|
|
20
|
-
return
|
|
19
|
+
return this.value.size;
|
|
21
20
|
}
|
|
22
21
|
get(idx) {
|
|
23
|
-
if (this.
|
|
22
|
+
if (this.value.size === 0) {
|
|
24
23
|
return null;
|
|
25
24
|
}
|
|
26
|
-
|
|
25
|
+
if (idx < 0 || idx >= this.value.size) {
|
|
26
|
+
throw new Error(`Index ${idx} out of range for list of size ${this.value.size}`);
|
|
27
|
+
}
|
|
28
|
+
return this.value.get(idx);
|
|
27
29
|
}
|
|
28
30
|
assoc(idx, v) {
|
|
29
|
-
return new CalcitList(
|
|
31
|
+
return new CalcitList(this.value.assoc(idx, v));
|
|
30
32
|
}
|
|
31
33
|
assocBefore(idx, v) {
|
|
32
|
-
return new CalcitList(
|
|
34
|
+
return new CalcitList(this.value.assocBefore(idx, v));
|
|
33
35
|
}
|
|
34
36
|
assocAfter(idx, v) {
|
|
35
|
-
return new CalcitList(
|
|
37
|
+
return new CalcitList(this.value.assocAfter(idx, v));
|
|
36
38
|
}
|
|
37
39
|
dissoc(idx) {
|
|
38
|
-
return new CalcitList(
|
|
40
|
+
return new CalcitList(this.value.dissoc(idx));
|
|
39
41
|
}
|
|
40
42
|
slice(from, to) {
|
|
41
|
-
return new CalcitList(
|
|
43
|
+
return new CalcitList(this.value.slice(from, to));
|
|
42
44
|
}
|
|
43
45
|
toString(shorter = false, disableJsDataWarning = false) {
|
|
44
46
|
let result = "";
|
|
@@ -53,43 +55,46 @@ export class CalcitList {
|
|
|
53
55
|
return `([]${result})`;
|
|
54
56
|
}
|
|
55
57
|
isEmpty() {
|
|
56
|
-
return this.
|
|
58
|
+
return this.value.size === 0;
|
|
57
59
|
}
|
|
58
60
|
/** usage: `for of` */
|
|
59
61
|
items() {
|
|
60
|
-
return
|
|
62
|
+
return this.value.items();
|
|
61
63
|
}
|
|
62
64
|
append(v) {
|
|
63
|
-
return new CalcitList(
|
|
65
|
+
return new CalcitList(this.value.pushRight(v));
|
|
64
66
|
}
|
|
65
67
|
prepend(v) {
|
|
66
|
-
return new CalcitList(
|
|
68
|
+
return new CalcitList(this.value.pushLeft(v));
|
|
67
69
|
}
|
|
68
70
|
first() {
|
|
69
|
-
|
|
71
|
+
if (this.value.size === 0) {
|
|
72
|
+
throw new Error("Cannot get from empty list");
|
|
73
|
+
}
|
|
74
|
+
return this.value.first();
|
|
70
75
|
}
|
|
71
76
|
rest() {
|
|
72
|
-
return new CalcitList(
|
|
77
|
+
return new CalcitList(this.value.rest());
|
|
73
78
|
}
|
|
74
79
|
concat(ys) {
|
|
75
80
|
if (ys instanceof CalcitSliceList) {
|
|
76
|
-
return new CalcitList(
|
|
81
|
+
return new CalcitList(this.value.concat(ys.turnListMode().value));
|
|
77
82
|
}
|
|
78
83
|
else if (ys instanceof CalcitList) {
|
|
79
|
-
return new CalcitList(
|
|
84
|
+
return new CalcitList(this.value.concat(ys.value));
|
|
80
85
|
}
|
|
81
86
|
else {
|
|
82
87
|
throw new Error(`Unknown data to concat: ${ys}`);
|
|
83
88
|
}
|
|
84
89
|
}
|
|
85
90
|
map(f) {
|
|
86
|
-
return new CalcitList(
|
|
91
|
+
return new CalcitList(this.value.map(f));
|
|
87
92
|
}
|
|
88
93
|
toArray() {
|
|
89
|
-
return
|
|
94
|
+
return this.value.toArray();
|
|
90
95
|
}
|
|
91
96
|
reverse() {
|
|
92
|
-
return new CalcitList(
|
|
97
|
+
return new CalcitList(this.value.reverse());
|
|
93
98
|
}
|
|
94
99
|
nestedDataInChildren() {
|
|
95
100
|
let size = this.len();
|
|
@@ -98,6 +103,7 @@ export class CalcitList {
|
|
|
98
103
|
return true;
|
|
99
104
|
}
|
|
100
105
|
}
|
|
106
|
+
return false;
|
|
101
107
|
}
|
|
102
108
|
}
|
|
103
109
|
// represent append-only immutable list in Array slices
|
|
@@ -115,7 +121,7 @@ export class CalcitSliceList {
|
|
|
115
121
|
if (this.cachedTreeListRef != null) {
|
|
116
122
|
return this.cachedTreeListRef;
|
|
117
123
|
}
|
|
118
|
-
let ret = new CalcitList(
|
|
124
|
+
let ret = new CalcitList(FingerVec.fromRange(this.value, this.start, this.end));
|
|
119
125
|
this.cachedTreeListRef = ret;
|
|
120
126
|
return ret;
|
|
121
127
|
}
|
|
@@ -241,8 +247,8 @@ export class CalcitSliceList {
|
|
|
241
247
|
}
|
|
242
248
|
map(f) {
|
|
243
249
|
let ys = [];
|
|
244
|
-
for (let
|
|
245
|
-
ys.push(f(
|
|
250
|
+
for (let idx = this.start; idx < this.end; idx++) {
|
|
251
|
+
ys.push(f(this.value[idx]));
|
|
246
252
|
}
|
|
247
253
|
return new CalcitSliceList(ys);
|
|
248
254
|
}
|
package/lib/js-primes.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CalcitTag, CalcitSymbol, CalcitRecur } from "./calcit-data.mjs";
|
|
1
|
+
import { CalcitTag, CalcitSymbol, CalcitRecur, compareUnicodeStrings } from "./calcit-data.mjs";
|
|
2
2
|
import { CalcitRef } from "./js-ref.mjs";
|
|
3
3
|
import { CalcitList, CalcitSliceList } from "./js-list.mjs";
|
|
4
4
|
import { CalcitStructValue } from "./js-struct-value.mjs";
|
|
@@ -101,6 +101,17 @@ let rawCompare = (x, y) => {
|
|
|
101
101
|
return 0;
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
|
+
/** lexicographic order over two sequences of values, a shorter prefix sorts first (same as Rust `Vec::cmp`) */
|
|
105
|
+
let compareSequences = (xs, ys) => {
|
|
106
|
+
let n = Math.min(xs.length, ys.length);
|
|
107
|
+
for (let i = 0; i < n; i++) {
|
|
108
|
+
let order = _$n_compare(xs[i], ys[i]);
|
|
109
|
+
if (order !== 0)
|
|
110
|
+
return order;
|
|
111
|
+
}
|
|
112
|
+
return rawCompare(xs.length, ys.length);
|
|
113
|
+
};
|
|
114
|
+
let listToArray = (x) => Array.from(x.items());
|
|
104
115
|
export let _$n_compare = (a, b) => {
|
|
105
116
|
if (a === b)
|
|
106
117
|
return 0;
|
|
@@ -123,8 +134,72 @@ export let _$n_compare = (a, b) => {
|
|
|
123
134
|
return rawCompare(a, b);
|
|
124
135
|
case PseudoTypeIndex.ref:
|
|
125
136
|
return rawCompare(a.path, b.path);
|
|
137
|
+
case PseudoTypeIndex.struct_value: {
|
|
138
|
+
const left = a;
|
|
139
|
+
const right = b;
|
|
140
|
+
const nameOrder = compareUnicodeStrings(left.name.value, right.name.value);
|
|
141
|
+
if (nameOrder !== 0)
|
|
142
|
+
return nameOrder;
|
|
143
|
+
const leftRef = left.structRef.definitionRef;
|
|
144
|
+
const rightRef = right.structRef.definitionRef;
|
|
145
|
+
if (leftRef !== rightRef) {
|
|
146
|
+
if (leftRef == null)
|
|
147
|
+
return -1;
|
|
148
|
+
if (rightRef == null)
|
|
149
|
+
return 1;
|
|
150
|
+
return compareUnicodeStrings(leftRef, rightRef);
|
|
151
|
+
}
|
|
152
|
+
for (let index = 0; index < Math.min(left.fields.length, right.fields.length); index++) {
|
|
153
|
+
const fieldOrder = compareUnicodeStrings(left.fields[index].value, right.fields[index].value);
|
|
154
|
+
if (fieldOrder !== 0)
|
|
155
|
+
return fieldOrder;
|
|
156
|
+
}
|
|
157
|
+
const fieldCountOrder = rawCompare(left.fields.length, right.fields.length);
|
|
158
|
+
if (fieldCountOrder !== 0)
|
|
159
|
+
return fieldCountOrder;
|
|
160
|
+
for (let index = 0; index < Math.min(left.values.length, right.values.length); index++) {
|
|
161
|
+
const valueOrder = _$n_compare(left.values[index], right.values[index]);
|
|
162
|
+
if (valueOrder !== 0)
|
|
163
|
+
return valueOrder;
|
|
164
|
+
}
|
|
165
|
+
return rawCompare(left.values.length, right.values.length);
|
|
166
|
+
}
|
|
126
167
|
case PseudoTypeIndex.cirru_quote:
|
|
127
168
|
return rawCompare(a, b); // TODO not stable
|
|
169
|
+
case PseudoTypeIndex.list:
|
|
170
|
+
return compareSequences(listToArray(a), listToArray(b));
|
|
171
|
+
case PseudoTypeIndex.enum_value: {
|
|
172
|
+
const left = a;
|
|
173
|
+
const right = b;
|
|
174
|
+
const tagOrder = _$n_compare(left.tag, right.tag);
|
|
175
|
+
if (tagOrder !== 0)
|
|
176
|
+
return tagOrder;
|
|
177
|
+
return compareSequences(left.extra, right.extra);
|
|
178
|
+
}
|
|
179
|
+
case PseudoTypeIndex.set: {
|
|
180
|
+
// like native: smaller sets first, then the sorted elements
|
|
181
|
+
const left = Array.from(a.values());
|
|
182
|
+
const right = Array.from(b.values());
|
|
183
|
+
const sizeOrder = rawCompare(left.length, right.length);
|
|
184
|
+
if (sizeOrder !== 0)
|
|
185
|
+
return sizeOrder;
|
|
186
|
+
return compareSequences(left.sort(_$n_compare), right.sort(_$n_compare));
|
|
187
|
+
}
|
|
188
|
+
case PseudoTypeIndex.map: {
|
|
189
|
+
// like native: smaller maps first, then the (key, value) pairs sorted by key and value
|
|
190
|
+
const sortPairs = (pairs) => pairs.sort((x, y) => _$n_compare(x[0], y[0]) || _$n_compare(x[1], y[1]));
|
|
191
|
+
const left = sortPairs(a.pairs());
|
|
192
|
+
const right = sortPairs(b.pairs());
|
|
193
|
+
const sizeOrder = rawCompare(left.length, right.length);
|
|
194
|
+
if (sizeOrder !== 0)
|
|
195
|
+
return sizeOrder;
|
|
196
|
+
for (let i = 0; i < left.length; i++) {
|
|
197
|
+
const order = _$n_compare(left[i][0], right[i][0]) || _$n_compare(left[i][1], right[i][1]);
|
|
198
|
+
if (order !== 0)
|
|
199
|
+
return order;
|
|
200
|
+
}
|
|
201
|
+
return 0;
|
|
202
|
+
}
|
|
128
203
|
default:
|
|
129
204
|
// TODO, need more accurate solution
|
|
130
205
|
if (a < b) {
|
package/lib/js-struct-def.d.mts
CHANGED
|
@@ -7,7 +7,10 @@ export declare class CalcitStructDef {
|
|
|
7
7
|
fieldTypes: CalcitValue[];
|
|
8
8
|
impls: CalcitImpl[];
|
|
9
9
|
cachedHash: number;
|
|
10
|
-
|
|
10
|
+
readonly definitionRef: string | null;
|
|
11
|
+
constructor(name: CalcitTag, fields: CalcitTag[], fieldTypes: CalcitValue[], impls?: CalcitImpl[], definitionRef?: string | null);
|
|
11
12
|
withImpls(impls: CalcitImpl | CalcitImpl[]): CalcitStructDef;
|
|
12
13
|
toString(disableJsDataWarning?: boolean): string;
|
|
13
14
|
}
|
|
15
|
+
/** Match native definition binding without replacing an alias's existing identity. */
|
|
16
|
+
export declare function bind_struct_definition(value: CalcitValue, definitionRef: string): CalcitValue;
|
package/lib/js-struct-def.mjs
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { canonicalizeTagPairs, toString } from "./calcit-data.mjs";
|
|
2
2
|
import { CalcitImpl } from "./js-impl.mjs";
|
|
3
3
|
export class CalcitStructDef {
|
|
4
|
-
constructor(name, fields, fieldTypes, impls = []) {
|
|
4
|
+
constructor(name, fields, fieldTypes, impls = [], definitionRef = null) {
|
|
5
5
|
const [canonicalFields, canonicalTypes] = canonicalizeTagPairs(fields, fieldTypes, "CalcitStructDef");
|
|
6
6
|
this.name = name;
|
|
7
7
|
this.fields = canonicalFields;
|
|
8
8
|
this.fieldTypes = canonicalTypes;
|
|
9
|
-
this.impls = impls;
|
|
9
|
+
this.impls = impls ?? [];
|
|
10
10
|
this.cachedHash = null;
|
|
11
|
+
this.definitionRef = definitionRef;
|
|
11
12
|
}
|
|
12
13
|
withImpls(impls) {
|
|
13
14
|
if (impls instanceof CalcitImpl) {
|
|
14
|
-
return new CalcitStructDef(this.name, this.fields, this.fieldTypes, [impls]);
|
|
15
|
+
return new CalcitStructDef(this.name, this.fields, this.fieldTypes, [impls], this.definitionRef);
|
|
15
16
|
}
|
|
16
17
|
else if (Array.isArray(impls)) {
|
|
17
|
-
return new CalcitStructDef(this.name, this.fields, this.fieldTypes, impls);
|
|
18
|
+
return new CalcitStructDef(this.name, this.fields, this.fieldTypes, impls, this.definitionRef);
|
|
18
19
|
}
|
|
19
20
|
throw new Error("Expected an impl as implementation");
|
|
20
21
|
}
|
|
@@ -32,3 +33,10 @@ export class CalcitStructDef {
|
|
|
32
33
|
return parts.join("");
|
|
33
34
|
}
|
|
34
35
|
}
|
|
36
|
+
/** Match native definition binding without replacing an alias's existing identity. */
|
|
37
|
+
export function bind_struct_definition(value, definitionRef) {
|
|
38
|
+
if (value instanceof CalcitStructDef && value.definitionRef == null) {
|
|
39
|
+
return new CalcitStructDef(value.name, value.fields, value.fieldTypes, value.impls, definitionRef);
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
package/lib/js-struct-value.mjs
CHANGED
|
@@ -116,7 +116,7 @@ export class CalcitStructValue {
|
|
|
116
116
|
else {
|
|
117
117
|
throw new Error("Expected an impl or array of impls");
|
|
118
118
|
}
|
|
119
|
-
let nextStruct = new CalcitStructDef(this.name, this.fields, this.structRef.fieldTypes, this.structRef.impls.concat(nextImpls));
|
|
119
|
+
let nextStruct = new CalcitStructDef(this.name, this.fields, this.structRef.fieldTypes, this.structRef.impls.concat(nextImpls), this.structRef.definitionRef);
|
|
120
120
|
return new CalcitStructValue(this.name, this.fields, this.values, nextStruct);
|
|
121
121
|
}
|
|
122
122
|
}
|
package/lib/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calcit/procs",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.1",
|
|
4
4
|
"main": "./lib/calcit.procs.mjs",
|
|
5
5
|
"files": [
|
|
6
6
|
"lib/",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"bench-struct-index": "yarn compile && node scripts/bench-struct-index.mjs",
|
|
33
33
|
"check-smooth": "yarn fmt-rs && yarn lint-rs && yarn test-rs && yarn check-all",
|
|
34
34
|
"check-all": "yarn compile && yarn check-js-runtime && node scripts/check-file-read-names.mjs && node scripts/check-enum-impl-cycle.mjs && node scripts/check-typed-source-alias.mjs && node scripts/check-parse-boundary.mjs && yarn check-js-ffi-source && yarn check-strict-default && yarn check-agent-interface && node --test scripts/core-api-contract.test.mjs && node scripts/core-api-contract.mjs && yarn try-core-tests && yarn check-core-dynamic-classification && yarn try-rs && yarn try-js && node scripts/check-struct-field-js.mjs && yarn try-ir && yarn try-wasm && yarn check-literal-paths && yarn check-typed-method-rem",
|
|
35
|
-
"check-strict-default": "cargo build --bin calcit && node scripts/check-strict-default.mjs && node scripts/check-known-assertion.mjs",
|
|
35
|
+
"check-strict-default": "cargo build --bin calcit && node scripts/check-strict-default.mjs && node scripts/check-known-assertion.mjs && node scripts/check-spread-boundary.mjs",
|
|
36
36
|
"check-agent-interface": "cargo build --bin calcit && node scripts/check-agent-interface.mjs",
|
|
37
37
|
"try-all": "yarn check-all",
|
|
38
38
|
"try-core-tests": "cargo run --bin calcit -- src/cirru/calcit-core.cirru test --tag unit --summary-only --require-match",
|
|
@@ -50,8 +50,9 @@
|
|
|
50
50
|
"url": "git+https://github.com/calcit-lang/calcit.git"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
+
"@calcit/finger-vec": "0.1.1",
|
|
53
54
|
"@calcit/ternary-tree": "0.0.26",
|
|
54
|
-
"@cirru/parser.ts": "
|
|
55
|
+
"@cirru/parser.ts": "0.0.10",
|
|
55
56
|
"@cirru/writer.ts": "^0.1.9"
|
|
56
57
|
},
|
|
57
58
|
"packageManager": "yarn@4.12.0"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calcit/procs",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.1",
|
|
4
4
|
"main": "./lib/calcit.procs.mjs",
|
|
5
5
|
"files": [
|
|
6
6
|
"lib/",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"bench-struct-index": "yarn compile && node scripts/bench-struct-index.mjs",
|
|
33
33
|
"check-smooth": "yarn fmt-rs && yarn lint-rs && yarn test-rs && yarn check-all",
|
|
34
34
|
"check-all": "yarn compile && yarn check-js-runtime && node scripts/check-file-read-names.mjs && node scripts/check-enum-impl-cycle.mjs && node scripts/check-typed-source-alias.mjs && node scripts/check-parse-boundary.mjs && yarn check-js-ffi-source && yarn check-strict-default && yarn check-agent-interface && node --test scripts/core-api-contract.test.mjs && node scripts/core-api-contract.mjs && yarn try-core-tests && yarn check-core-dynamic-classification && yarn try-rs && yarn try-js && node scripts/check-struct-field-js.mjs && yarn try-ir && yarn try-wasm && yarn check-literal-paths && yarn check-typed-method-rem",
|
|
35
|
-
"check-strict-default": "cargo build --bin calcit && node scripts/check-strict-default.mjs && node scripts/check-known-assertion.mjs",
|
|
35
|
+
"check-strict-default": "cargo build --bin calcit && node scripts/check-strict-default.mjs && node scripts/check-known-assertion.mjs && node scripts/check-spread-boundary.mjs",
|
|
36
36
|
"check-agent-interface": "cargo build --bin calcit && node scripts/check-agent-interface.mjs",
|
|
37
37
|
"try-all": "yarn check-all",
|
|
38
38
|
"try-core-tests": "cargo run --bin calcit -- src/cirru/calcit-core.cirru test --tag unit --summary-only --require-match",
|
|
@@ -50,8 +50,9 @@
|
|
|
50
50
|
"url": "git+https://github.com/calcit-lang/calcit.git"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
+
"@calcit/finger-vec": "0.1.1",
|
|
53
54
|
"@calcit/ternary-tree": "0.0.26",
|
|
54
|
-
"@cirru/parser.ts": "
|
|
55
|
+
"@cirru/parser.ts": "0.0.10",
|
|
55
56
|
"@cirru/writer.ts": "^0.1.9"
|
|
56
57
|
},
|
|
57
58
|
"packageManager": "yarn@4.12.0"
|