@mark1russell7/coeval 0.7.1 → 0.8.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/build/index.d.ts +175 -96
- package/build/index.d.ts.map +1 -1
- package/build/index.js +762 -127
- package/build/index.js.map +1 -1
- package/package.json +2 -2
- package/src/agree.ts +26 -5
- package/src/conform.ts +1 -2
- package/src/doc.ts +2 -2
- package/src/evaluate.ts +273 -7
- package/src/index.ts +17 -1
- package/src/parts.ts +70 -1
- package/src/reference.ts +139 -16
- package/src/static.ts +54 -74
- package/src/stdlib.ts +220 -18
- package/src/world.ts +50 -0
package/build/index.js
CHANGED
|
@@ -357,6 +357,17 @@ function describe(value) {
|
|
|
357
357
|
//#endregion
|
|
358
358
|
//#region src/world.ts
|
|
359
359
|
/**
|
|
360
|
+
* This function gives the type of a bare equation of a kind (D42). It is the type `of` of the shape of its parts, or
|
|
361
|
+
* else the type `of` of the shape `rest` of a record. The plan, the reference and `check` read it with this one function.
|
|
362
|
+
*
|
|
363
|
+
* @param kind - The kind.
|
|
364
|
+
* @returns The type, or `undefined` when the shape declares none.
|
|
365
|
+
*/
|
|
366
|
+
function equationType(kind) {
|
|
367
|
+
const parts = kind.parts;
|
|
368
|
+
return parts?.of ?? parts?.rest?.of;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
360
371
|
* This function tells if an entry of the world is a kind.
|
|
361
372
|
*
|
|
362
373
|
* @param entry - The entry.
|
|
@@ -1694,7 +1705,7 @@ const RUNGS = [
|
|
|
1694
1705
|
"kind",
|
|
1695
1706
|
"default"
|
|
1696
1707
|
];
|
|
1697
|
-
function entryOf(verbs, verb) {
|
|
1708
|
+
function entryOf$1(verbs, verb) {
|
|
1698
1709
|
return verbs !== void 0 && Object.hasOwn(verbs, verb) ? verbs[verb] : void 0;
|
|
1699
1710
|
}
|
|
1700
1711
|
/**
|
|
@@ -1735,18 +1746,18 @@ const EACH_NAME = () => true;
|
|
|
1735
1746
|
* @returns The evaluator name and its rung, or `undefined` when no rung answers.
|
|
1736
1747
|
*/
|
|
1737
1748
|
function answerOf(world, own, kind, verb, has = EACH_NAME) {
|
|
1738
|
-
const ownName = entryOf(own, verb);
|
|
1749
|
+
const ownName = entryOf$1(own, verb);
|
|
1739
1750
|
if (ownName !== void 0 && has(ownName)) return {
|
|
1740
1751
|
name: ownName,
|
|
1741
1752
|
rung: "own"
|
|
1742
1753
|
};
|
|
1743
1754
|
if (kind === null) return void 0;
|
|
1744
|
-
const kindName = kind === void 0 ? void 0 : entryOf(kind.verbs, verb);
|
|
1755
|
+
const kindName = kind === void 0 ? void 0 : entryOf$1(kind.verbs, verb);
|
|
1745
1756
|
if (kindName !== void 0 && has(kindName)) return {
|
|
1746
1757
|
name: kindName,
|
|
1747
1758
|
rung: "kind"
|
|
1748
1759
|
};
|
|
1749
|
-
const fallback = entryOf(world.defaults, verb);
|
|
1760
|
+
const fallback = entryOf$1(world.defaults, verb);
|
|
1750
1761
|
return fallback !== void 0 && has(fallback) ? {
|
|
1751
1762
|
name: fallback,
|
|
1752
1763
|
rung: "default"
|
|
@@ -1768,7 +1779,7 @@ function answerOf(world, own, kind, verb, has = EACH_NAME) {
|
|
|
1768
1779
|
*/
|
|
1769
1780
|
function ask(world, doc, verb, options = {}) {
|
|
1770
1781
|
const steps = [];
|
|
1771
|
-
const own = entryOf(doc.own, verb);
|
|
1782
|
+
const own = entryOf$1(doc.own, verb);
|
|
1772
1783
|
if (own !== void 0) {
|
|
1773
1784
|
steps.push({
|
|
1774
1785
|
rung: "own",
|
|
@@ -1808,7 +1819,7 @@ function ask(world, doc, verb, options = {}) {
|
|
|
1808
1819
|
steps
|
|
1809
1820
|
};
|
|
1810
1821
|
}
|
|
1811
|
-
const entry = entryOf(kind.verbs, verb);
|
|
1822
|
+
const entry = entryOf$1(kind.verbs, verb);
|
|
1812
1823
|
if (entry !== void 0) {
|
|
1813
1824
|
steps.push({
|
|
1814
1825
|
rung: "kind",
|
|
@@ -1831,7 +1842,7 @@ function ask(world, doc, verb, options = {}) {
|
|
|
1831
1842
|
source
|
|
1832
1843
|
});
|
|
1833
1844
|
}
|
|
1834
|
-
const fallback = entryOf(world.defaults, verb);
|
|
1845
|
+
const fallback = entryOf$1(world.defaults, verb);
|
|
1835
1846
|
if (fallback !== void 0) {
|
|
1836
1847
|
steps.push({
|
|
1837
1848
|
rung: "default",
|
|
@@ -2667,6 +2678,75 @@ function pathMatches(path, pattern) {
|
|
|
2667
2678
|
}
|
|
2668
2679
|
return true;
|
|
2669
2680
|
}
|
|
2681
|
+
function valueAt(value, path) {
|
|
2682
|
+
let here = value;
|
|
2683
|
+
for (const key of path) if (Array.isArray(here)) here = here[Number(key)];
|
|
2684
|
+
else if (isRecord(here) && Object.hasOwn(here, String(key))) here = here[String(key)];
|
|
2685
|
+
else return void 0;
|
|
2686
|
+
return here;
|
|
2687
|
+
}
|
|
2688
|
+
function headerName(item) {
|
|
2689
|
+
return isEnvelope(item) && typeof item.name === "string" ? item.name : void 0;
|
|
2690
|
+
}
|
|
2691
|
+
function namesOf(source, value, covered) {
|
|
2692
|
+
if ("fixed" in source) return source.fixed;
|
|
2693
|
+
if ("keysAt" in source) {
|
|
2694
|
+
const at = valueAt(value, source.keysAt);
|
|
2695
|
+
return isRecord(at) ? Object.keys(at) : [];
|
|
2696
|
+
}
|
|
2697
|
+
if ("listAt" in source) {
|
|
2698
|
+
const at = valueAt(value, source.listAt);
|
|
2699
|
+
return Array.isArray(at) ? at.filter((item) => typeof item === "string") : [];
|
|
2700
|
+
}
|
|
2701
|
+
if ("textAt" in source) {
|
|
2702
|
+
const at = valueAt(value, source.textAt);
|
|
2703
|
+
if (typeof at === "string") return [at];
|
|
2704
|
+
return source.otherwise === void 0 ? [] : [source.otherwise];
|
|
2705
|
+
}
|
|
2706
|
+
return covered.map((slot) => headerName(slot.item)).filter((name) => name !== void 0);
|
|
2707
|
+
}
|
|
2708
|
+
/**
|
|
2709
|
+
* This function gives the names that the scope rules of a kind give each part, and the names that only later parts
|
|
2710
|
+
* see. `check`, `conforms` and the plan read the scope rules with it.
|
|
2711
|
+
*
|
|
2712
|
+
* @param rules - The scope rules of the kind.
|
|
2713
|
+
* @param value - The value of the document.
|
|
2714
|
+
* @param slots - The parts of the value, in order.
|
|
2715
|
+
* @returns The names that each part sees, and the names that only the later parts see, by the index of the part.
|
|
2716
|
+
*/
|
|
2717
|
+
function scopesOf(rules, value, slots) {
|
|
2718
|
+
const sees = slots.map(() => []);
|
|
2719
|
+
const later = slots.map(() => []);
|
|
2720
|
+
for (const rule of rules ?? []) {
|
|
2721
|
+
const covered = slots.map((slot, index) => ({
|
|
2722
|
+
slot,
|
|
2723
|
+
index
|
|
2724
|
+
})).filter(({ slot }) => rule.in.some((pattern) => pathMatches(slot.path, pattern)));
|
|
2725
|
+
if (rule.sequential !== true) {
|
|
2726
|
+
const names = namesOf(rule.names, value, covered.map(({ slot }) => slot));
|
|
2727
|
+
for (const { index } of covered) sees[index]?.push(...names);
|
|
2728
|
+
continue;
|
|
2729
|
+
}
|
|
2730
|
+
if ("headers" in rule.names) {
|
|
2731
|
+
covered.forEach(({ index }, position) => {
|
|
2732
|
+
const before = covered.slice(0, position).map(({ slot }) => headerName(slot.item)).filter((name) => name !== void 0);
|
|
2733
|
+
const after = covered.slice(position).map(({ slot }) => headerName(slot.item)).filter((name) => name !== void 0);
|
|
2734
|
+
sees[index]?.push(...before);
|
|
2735
|
+
later[index]?.push(...after);
|
|
2736
|
+
});
|
|
2737
|
+
continue;
|
|
2738
|
+
}
|
|
2739
|
+
const names = namesOf(rule.names, value, covered.map(({ slot }) => slot));
|
|
2740
|
+
covered.forEach(({ index }, position) => {
|
|
2741
|
+
if (position > 0) sees[index]?.push(...names);
|
|
2742
|
+
else later[index]?.push(...names);
|
|
2743
|
+
});
|
|
2744
|
+
}
|
|
2745
|
+
return {
|
|
2746
|
+
sees,
|
|
2747
|
+
later
|
|
2748
|
+
};
|
|
2749
|
+
}
|
|
2670
2750
|
//#endregion
|
|
2671
2751
|
//#region src/evaluate.ts
|
|
2672
2752
|
/**
|
|
@@ -2727,7 +2807,7 @@ function narrow(parent, next) {
|
|
|
2727
2807
|
};
|
|
2728
2808
|
}
|
|
2729
2809
|
/** No capabilities. One list serves each masked part. */
|
|
2730
|
-
const NO_CAPS$
|
|
2810
|
+
const NO_CAPS$2 = /* @__PURE__ */ Object.freeze([]);
|
|
2731
2811
|
/** No capability rules. One list serves each part that no rule narrows. */
|
|
2732
2812
|
const NO_RULES = /* @__PURE__ */ Object.freeze([]);
|
|
2733
2813
|
/**
|
|
@@ -2755,7 +2835,7 @@ function rulesFor(rules, path) {
|
|
|
2755
2835
|
function capsUnder(rules, caps) {
|
|
2756
2836
|
let out = caps;
|
|
2757
2837
|
for (const rule of rules) {
|
|
2758
|
-
if (rule.rule === "mask") return NO_CAPS$
|
|
2838
|
+
if (rule.rule === "mask") return NO_CAPS$2;
|
|
2759
2839
|
if (rule.rule === "only") out = intersectCaps(out, rule.caps);
|
|
2760
2840
|
}
|
|
2761
2841
|
return out;
|
|
@@ -2786,7 +2866,7 @@ const GRANT = /* @__PURE__ */ Symbol("coeval.grant");
|
|
|
2786
2866
|
function granted(ctx) {
|
|
2787
2867
|
const grant = ctx[GRANT];
|
|
2788
2868
|
if (grant === ctx.caps) return ctx;
|
|
2789
|
-
const caps = grant === void 0 ? NO_CAPS$
|
|
2869
|
+
const caps = grant === void 0 ? NO_CAPS$2 : ctx.caps.every((cap) => permits(grant, cap)) ? ctx.caps : ctx.caps.filter((cap) => permits(grant, cap));
|
|
2790
2870
|
return {
|
|
2791
2871
|
...ctx,
|
|
2792
2872
|
caps,
|
|
@@ -2952,6 +3032,10 @@ var Session = class {
|
|
|
2952
3032
|
get effects() {
|
|
2953
3033
|
return this.list ??= [];
|
|
2954
3034
|
}
|
|
3035
|
+
/** `true` when the evaluation records its reads. Then folded code evaluates again, thus each read goes in the list (PLAN.FOLD). */
|
|
3036
|
+
get recording() {
|
|
3037
|
+
return this.reading !== void 0;
|
|
3038
|
+
}
|
|
2955
3039
|
resolve(ctx, path, options) {
|
|
2956
3040
|
return this.read(ctx, path, void 0, options);
|
|
2957
3041
|
}
|
|
@@ -3416,6 +3500,7 @@ function compileNode(c, value, place, declared, depth, address = false) {
|
|
|
3416
3500
|
let meta = meta0;
|
|
3417
3501
|
let name;
|
|
3418
3502
|
let unknown;
|
|
3503
|
+
let quick;
|
|
3419
3504
|
if (c.traced) {
|
|
3420
3505
|
const answer = ask(world, envelope ?? {}, c.verb, declared === void 0 ? {} : { declaredType: declared });
|
|
3421
3506
|
meta = {
|
|
@@ -3426,7 +3511,7 @@ function compileNode(c, value, place, declared, depth, address = false) {
|
|
|
3426
3511
|
name = answer.evaluator;
|
|
3427
3512
|
unknown = answer.error === "unknown-kind";
|
|
3428
3513
|
} else {
|
|
3429
|
-
|
|
3514
|
+
quick = answerOf(world, envelope?.own, kind ?? null, c.verb);
|
|
3430
3515
|
name = quick?.name;
|
|
3431
3516
|
unknown = quick === void 0 && kind === void 0;
|
|
3432
3517
|
}
|
|
@@ -3437,9 +3522,11 @@ function compileNode(c, value, place, declared, depth, address = false) {
|
|
|
3437
3522
|
const evaluator = name !== void 0 && Object.hasOwn(c.machine.evaluators, name) ? c.machine.evaluators[name] : void 0;
|
|
3438
3523
|
if (name === void 0 || runner === void 0 && evaluator === void 0) return failing(c, meta, place, "#NOEVAL", `No rung gives an evaluator for ${kindText}.`);
|
|
3439
3524
|
if (!split.ok) return failing(c, meta, place, "#VALUE!", split.reason);
|
|
3525
|
+
const frees = c.fold ? [] : void 0;
|
|
3440
3526
|
const parts = split.parts.map((slot) => {
|
|
3441
3527
|
const item = slot.item;
|
|
3442
3528
|
const own = compileNode(c, item, place.concat(slot.path), slot.of, depth + 1, slot.address === true);
|
|
3529
|
+
frees?.push(own.free);
|
|
3443
3530
|
const rules = rulesFor(kind?.caps, slot.path);
|
|
3444
3531
|
const compiled = rules.length === 0 ? own : gated(rules, own);
|
|
3445
3532
|
const header = typeof item?.name === "string" && isEnvelope(item) ? item.name : void 0;
|
|
@@ -3457,9 +3544,10 @@ function compileNode(c, value, place, declared, depth, address = false) {
|
|
|
3457
3544
|
run
|
|
3458
3545
|
};
|
|
3459
3546
|
});
|
|
3547
|
+
const typePath = read.typePath ?? [];
|
|
3460
3548
|
const input = {
|
|
3461
3549
|
kind: kindText,
|
|
3462
|
-
typePath
|
|
3550
|
+
typePath,
|
|
3463
3551
|
doc,
|
|
3464
3552
|
value: split.parts.length === 0 ? doc.value : split.fill(parts),
|
|
3465
3553
|
data: split.data,
|
|
@@ -3485,7 +3573,238 @@ function compileNode(c, value, place, declared, depth, address = false) {
|
|
|
3485
3573
|
} catch (error) {
|
|
3486
3574
|
return failingWith(c, meta, placed(thrown(error, `the evaluator ${name}`), place));
|
|
3487
3575
|
}
|
|
3488
|
-
|
|
3576
|
+
const done = finish$1(c, meta, placedCode(inner, place, name), void 0);
|
|
3577
|
+
if (frees === void 0 || kind === void 0 || !pureCode(c, envelope, kind, typePath, name, quick)) return done;
|
|
3578
|
+
const free = freeOf(doc, kind, split.parts, frees);
|
|
3579
|
+
if (free === void 0) return done;
|
|
3580
|
+
return free.length === 0 ? folded(c, done) : {
|
|
3581
|
+
code: done.code,
|
|
3582
|
+
run: done.run,
|
|
3583
|
+
free
|
|
3584
|
+
};
|
|
3585
|
+
}
|
|
3586
|
+
/** The free names of a closed part. */
|
|
3587
|
+
const CLOSED = /* @__PURE__ */ Object.freeze([]);
|
|
3588
|
+
/**
|
|
3589
|
+
* This function tells if the code of a document is pure, by the facts of D24 (FACTS.PURE). It reads the facts as
|
|
3590
|
+
* `factsOf` reads them. A kind with a run side, with declared effects or with volatile code is not pure here.
|
|
3591
|
+
*/
|
|
3592
|
+
function pureCode(c, envelope, kind, typePath, name, quick) {
|
|
3593
|
+
if (kind.side === "run" || kind.effects !== void 0 && kind.effects.length > 0) return false;
|
|
3594
|
+
let answer;
|
|
3595
|
+
try {
|
|
3596
|
+
answer = c.machine.facts?.(typePath, name);
|
|
3597
|
+
} catch {
|
|
3598
|
+
return false;
|
|
3599
|
+
}
|
|
3600
|
+
const described = c.verb === "eval" && (envelope === void 0 || quick?.rung !== "own" || name === answerOf(c.machine.world, void 0, kind, c.verb)?.name);
|
|
3601
|
+
const pure = described ? answer?.pure ?? kind.pure : answer?.pure;
|
|
3602
|
+
const volatile = described ? answer?.volatile ?? kind.volatile : answer?.volatile;
|
|
3603
|
+
return pure === true && volatile !== true;
|
|
3604
|
+
}
|
|
3605
|
+
/**
|
|
3606
|
+
* This function gives the names that a document reads and does not bind, or `undefined` when the document can read
|
|
3607
|
+
* other roots. A reference reads the name of its path. Each other document reads the free names of its parts, less
|
|
3608
|
+
* the names that its scope rules give each part (STATIC.REFS).
|
|
3609
|
+
*/
|
|
3610
|
+
function freeOf(doc, kind, slots, frees) {
|
|
3611
|
+
if (isRef(doc)) {
|
|
3612
|
+
const path = doc.value;
|
|
3613
|
+
if (path.length < 2 || path[0] !== "names" || !path.every((step, index) => index === 0 || isKey(step))) return void 0;
|
|
3614
|
+
return [String(path[1])];
|
|
3615
|
+
}
|
|
3616
|
+
let sees;
|
|
3617
|
+
let out;
|
|
3618
|
+
for (let index = 0; index < frees.length; index += 1) {
|
|
3619
|
+
const free = frees[index];
|
|
3620
|
+
if (free === void 0) return void 0;
|
|
3621
|
+
if (free.length === 0) continue;
|
|
3622
|
+
if (sees === void 0) sees = kind.scope === void 0 || kind.scope.length === 0 ? [] : scopesOf(kind.scope, doc.value, slots).sees;
|
|
3623
|
+
const bound = sees[index] ?? CLOSED;
|
|
3624
|
+
for (const name of free) {
|
|
3625
|
+
if (bound.includes(name)) continue;
|
|
3626
|
+
out ??= [];
|
|
3627
|
+
if (!out.includes(name)) out.push(name);
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
return out ?? CLOSED;
|
|
3631
|
+
}
|
|
3632
|
+
/** This class is the runtime of a fold. It reads only the names that the folded part binds, and it causes no effect. */
|
|
3633
|
+
var Probe = class {
|
|
3634
|
+
machine;
|
|
3635
|
+
running = false;
|
|
3636
|
+
/** `true` after the part asked for something that a fold cannot give. */
|
|
3637
|
+
refused = false;
|
|
3638
|
+
/** The count of the names that the part read. */
|
|
3639
|
+
reads = 0;
|
|
3640
|
+
/**
|
|
3641
|
+
* The context of the folded part. Its roots `self`, `event` and `names` are traps: a direct read of a field
|
|
3642
|
+
* refuses the fold, as a resolution of these roots does. A copy of the record of the names reads no field.
|
|
3643
|
+
*/
|
|
3644
|
+
root;
|
|
3645
|
+
constructor(machine) {
|
|
3646
|
+
this.machine = machine;
|
|
3647
|
+
const refuse = () => {
|
|
3648
|
+
this.refused = true;
|
|
3649
|
+
};
|
|
3650
|
+
const root = {
|
|
3651
|
+
self: trap(refuse, false),
|
|
3652
|
+
event: trap(refuse, false),
|
|
3653
|
+
names: trap(refuse, true),
|
|
3654
|
+
world: worldThing(machine.world),
|
|
3655
|
+
caps: NO_CAPS$2,
|
|
3656
|
+
[GRANT]: NO_CAPS$2
|
|
3657
|
+
};
|
|
3658
|
+
this.root = root;
|
|
3659
|
+
}
|
|
3660
|
+
resolve(ctx, path) {
|
|
3661
|
+
const name = path[1];
|
|
3662
|
+
if (path[0] === "names" && isKey(name) && Object.hasOwn(ctx.names, String(name))) {
|
|
3663
|
+
this.reads += 1;
|
|
3664
|
+
const found = resolve(this.machine, ctx, path, WITH_HOPS);
|
|
3665
|
+
if (found.hops.some((hop) => hop.by === "collapse" || isRef(hop.thing))) this.refused = true;
|
|
3666
|
+
return found;
|
|
3667
|
+
}
|
|
3668
|
+
this.refused = true;
|
|
3669
|
+
return {
|
|
3670
|
+
ok: false,
|
|
3671
|
+
code: "#REF!",
|
|
3672
|
+
reason: "A folded part reads only the names that it binds.",
|
|
3673
|
+
hops: []
|
|
3674
|
+
};
|
|
3675
|
+
}
|
|
3676
|
+
effect() {
|
|
3677
|
+
this.refused = true;
|
|
3678
|
+
return fail("#CAP!", "A folded part causes no effect.");
|
|
3679
|
+
}
|
|
3680
|
+
*runEffect() {
|
|
3681
|
+
return this.effect();
|
|
3682
|
+
}
|
|
3683
|
+
*all() {
|
|
3684
|
+
this.refused = true;
|
|
3685
|
+
return [];
|
|
3686
|
+
}
|
|
3687
|
+
keepsContext() {
|
|
3688
|
+
this.refused = true;
|
|
3689
|
+
}
|
|
3690
|
+
};
|
|
3691
|
+
/**
|
|
3692
|
+
* This function makes a trap for a root of the context of a fold. Each read of a field calls `refuse`. A trap of the
|
|
3693
|
+
* names gives no keys, thus a copy of the names reads no field.
|
|
3694
|
+
*/
|
|
3695
|
+
function trap(refuse, copies) {
|
|
3696
|
+
const no = () => {
|
|
3697
|
+
refuse();
|
|
3698
|
+
};
|
|
3699
|
+
return new Proxy({}, {
|
|
3700
|
+
get: no,
|
|
3701
|
+
getOwnPropertyDescriptor: no,
|
|
3702
|
+
has: () => (refuse(), false),
|
|
3703
|
+
ownKeys: () => {
|
|
3704
|
+
if (!copies) refuse();
|
|
3705
|
+
return [];
|
|
3706
|
+
},
|
|
3707
|
+
getPrototypeOf: () => (refuse(), null),
|
|
3708
|
+
set: () => (refuse(), false),
|
|
3709
|
+
defineProperty: () => (refuse(), false),
|
|
3710
|
+
deleteProperty: () => (refuse(), false)
|
|
3711
|
+
});
|
|
3712
|
+
}
|
|
3713
|
+
/**
|
|
3714
|
+
* This function folds the code of a closed pure part. The part evaluates one time with the probe. Its result becomes
|
|
3715
|
+
* one deeply frozen copy, and the code gives that copy at each evaluation (PLAN.SHARED). A fold that the probe cancels
|
|
3716
|
+
* gives the code without free names, thus no parent tries the fold again.
|
|
3717
|
+
*/
|
|
3718
|
+
function folded(c, done) {
|
|
3719
|
+
const probe = c.probe ??= new Probe(c.machine);
|
|
3720
|
+
probe.refused = false;
|
|
3721
|
+
probe.reads = 0;
|
|
3722
|
+
let constant;
|
|
3723
|
+
try {
|
|
3724
|
+
const result = done.code(probe.root, probe);
|
|
3725
|
+
if (!probe.refused && (result.ok || result.error.code !== "#DEPTH!")) constant = sharedCopy(result);
|
|
3726
|
+
} catch {
|
|
3727
|
+
constant = void 0;
|
|
3728
|
+
}
|
|
3729
|
+
if (constant === void 0) return {
|
|
3730
|
+
code: done.code,
|
|
3731
|
+
run: done.run
|
|
3732
|
+
};
|
|
3733
|
+
const value = constant;
|
|
3734
|
+
if (probe.reads === 0) return {
|
|
3735
|
+
code: () => value,
|
|
3736
|
+
run: void 0,
|
|
3737
|
+
free: CLOSED
|
|
3738
|
+
};
|
|
3739
|
+
const original = done.code;
|
|
3740
|
+
return {
|
|
3741
|
+
code: (ctx, rt) => rt instanceof Session && !rt.traced && !rt.recording ? value : original(ctx, rt),
|
|
3742
|
+
run: void 0,
|
|
3743
|
+
free: CLOSED
|
|
3744
|
+
};
|
|
3745
|
+
}
|
|
3746
|
+
/** The objects that a fold made. Each one is deeply frozen, thus a later fold uses it again and does not copy it. */
|
|
3747
|
+
const SHARED = /* @__PURE__ */ new WeakSet();
|
|
3748
|
+
/** The mark of a value that is not plain data. */
|
|
3749
|
+
const NOT_PLAIN = /* @__PURE__ */ Symbol("not plain");
|
|
3750
|
+
/**
|
|
3751
|
+
* This function gives a deeply frozen copy of plain data, or `undefined` for other values. Plain data is a primitive or
|
|
3752
|
+
* an array without holes and extra keys. It is also a record of enumerable data fields with the prototype of an object
|
|
3753
|
+
* or no prototype. The copy keeps cycles and shared objects. The objects of the host do not change.
|
|
3754
|
+
*/
|
|
3755
|
+
function sharedCopy(value) {
|
|
3756
|
+
try {
|
|
3757
|
+
const out = copyPlain(value, /* @__PURE__ */ new Map());
|
|
3758
|
+
return out === NOT_PLAIN ? void 0 : out;
|
|
3759
|
+
} catch {
|
|
3760
|
+
return;
|
|
3761
|
+
}
|
|
3762
|
+
}
|
|
3763
|
+
/** This function copies one value for `sharedCopy`. The map holds the copy of each object that the copy saw. */
|
|
3764
|
+
function copyPlain(value, memo) {
|
|
3765
|
+
if (typeof value === "function") return NOT_PLAIN;
|
|
3766
|
+
if (typeof value !== "object" || value === null) return value;
|
|
3767
|
+
if (SHARED.has(value)) return value;
|
|
3768
|
+
const seen = memo.get(value);
|
|
3769
|
+
if (seen !== void 0) return seen;
|
|
3770
|
+
const proto = Object.getPrototypeOf(value);
|
|
3771
|
+
const keys = Reflect.ownKeys(value);
|
|
3772
|
+
let out;
|
|
3773
|
+
if (Array.isArray(value)) {
|
|
3774
|
+
if (proto !== Array.prototype || keys.length !== value.length + 1) return NOT_PLAIN;
|
|
3775
|
+
const list = [];
|
|
3776
|
+
memo.set(value, list);
|
|
3777
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
3778
|
+
const field = Object.getOwnPropertyDescriptor(value, index);
|
|
3779
|
+
if (field === void 0 || !("value" in field) || field.enumerable !== true) return NOT_PLAIN;
|
|
3780
|
+
const item = copyPlain(field.value, memo);
|
|
3781
|
+
if (item === NOT_PLAIN) return NOT_PLAIN;
|
|
3782
|
+
list.push(item);
|
|
3783
|
+
}
|
|
3784
|
+
out = list;
|
|
3785
|
+
} else {
|
|
3786
|
+
if (proto !== Object.prototype && proto !== null) return NOT_PLAIN;
|
|
3787
|
+
const record = proto === null ? Object.create(null) : {};
|
|
3788
|
+
memo.set(value, record);
|
|
3789
|
+
for (const key of keys) {
|
|
3790
|
+
if (typeof key !== "string") return NOT_PLAIN;
|
|
3791
|
+
const field = Object.getOwnPropertyDescriptor(value, key);
|
|
3792
|
+
if (field === void 0 || !("value" in field) || field.enumerable !== true) return NOT_PLAIN;
|
|
3793
|
+
const item = copyPlain(field.value, memo);
|
|
3794
|
+
if (item === NOT_PLAIN) return NOT_PLAIN;
|
|
3795
|
+
if (key === "__proto__") Object.defineProperty(record, key, {
|
|
3796
|
+
value: item,
|
|
3797
|
+
enumerable: true,
|
|
3798
|
+
writable: true,
|
|
3799
|
+
configurable: true
|
|
3800
|
+
});
|
|
3801
|
+
else record[key] = item;
|
|
3802
|
+
}
|
|
3803
|
+
out = record;
|
|
3804
|
+
}
|
|
3805
|
+
Object.freeze(out);
|
|
3806
|
+
SHARED.add(out);
|
|
3807
|
+
return out;
|
|
3489
3808
|
}
|
|
3490
3809
|
/**
|
|
3491
3810
|
* This function gives the code of a document: the code of its evaluator, with the place of each error and of each
|
|
@@ -3650,12 +3969,14 @@ function prepare(machine, doc, options = {}) {
|
|
|
3650
3969
|
error: "no-answer",
|
|
3651
3970
|
steps: []
|
|
3652
3971
|
};
|
|
3972
|
+
const traced = options.trace === true;
|
|
3653
3973
|
const c = {
|
|
3654
3974
|
machine,
|
|
3655
|
-
traced
|
|
3975
|
+
traced,
|
|
3656
3976
|
maxDepth: machine.maxDepth ?? 1e3,
|
|
3657
3977
|
verb,
|
|
3658
|
-
noAnswer
|
|
3978
|
+
noAnswer,
|
|
3979
|
+
fold: !traced && options.fold !== false
|
|
3659
3980
|
};
|
|
3660
3981
|
let root;
|
|
3661
3982
|
try {
|
|
@@ -3753,8 +4074,8 @@ function record(s, result) {
|
|
|
3753
4074
|
* tells where its parts are. The evaluator gets each part sealed: it can evaluate the part, and it cannot read its
|
|
3754
4075
|
* value.
|
|
3755
4076
|
*
|
|
3756
|
-
* A failure gives an error value, and the function does not throw.
|
|
3757
|
-
* does not do it. A mock can answer each effect at once (RUN.MOCK).
|
|
4077
|
+
* A failure gives an error value, and the function does not throw. The function records each effect in its order,
|
|
4078
|
+
* and the host does not do it. A mock can answer each effect at once (RUN.MOCK).
|
|
3758
4079
|
*
|
|
3759
4080
|
* @param machine - The world and the code of the evaluators.
|
|
3760
4081
|
* @param doc - The document, as JSON.
|
|
@@ -4112,6 +4433,56 @@ const STD_EVALUATORS = {
|
|
|
4112
4433
|
};
|
|
4113
4434
|
/** The brand of a node of the decorated tree. Its value is the state that the kit reads. */
|
|
4114
4435
|
const TREE_NODE = /* @__PURE__ */ Symbol.for("coeval.tree.node");
|
|
4436
|
+
/** The rungs of the ladder of an attribute, in their order (TREE.LADDER, D42). */
|
|
4437
|
+
const ATTRIBUTE_RUNGS = /* @__PURE__ */ Object.freeze([
|
|
4438
|
+
"own",
|
|
4439
|
+
"kind",
|
|
4440
|
+
"parent",
|
|
4441
|
+
"copy",
|
|
4442
|
+
"default"
|
|
4443
|
+
]);
|
|
4444
|
+
/** The capabilities of an equation: none (CAP.PURE). */
|
|
4445
|
+
const NO_CAPS$1 = /* @__PURE__ */ Object.freeze([]);
|
|
4446
|
+
/** The names of an equation of `equations`, of a `unit` and of a `default`. */
|
|
4447
|
+
const NO_NAMES$1 = /* @__PURE__ */ Object.freeze({});
|
|
4448
|
+
/** The planners of equations, for each machine and each type of a bare equation (TREE.PLAN). */
|
|
4449
|
+
const equationPlanners = /* @__PURE__ */ new WeakMap();
|
|
4450
|
+
/**
|
|
4451
|
+
* This function gives the plan of an equation. Each equation compiles one time for each machine (PLAN.CACHE). The
|
|
4452
|
+
* plan of the document does not keep it (PLAN.LEAN).
|
|
4453
|
+
*/
|
|
4454
|
+
function equationPlan(machine, of, term) {
|
|
4455
|
+
let byType = equationPlanners.get(machine);
|
|
4456
|
+
if (byType === void 0) {
|
|
4457
|
+
byType = /* @__PURE__ */ new Map();
|
|
4458
|
+
equationPlanners.set(machine, byType);
|
|
4459
|
+
}
|
|
4460
|
+
const key = of ?? "";
|
|
4461
|
+
let plans = byType.get(key);
|
|
4462
|
+
if (plans === void 0) {
|
|
4463
|
+
plans = planner(machine, of === void 0 ? {} : { declaredType: of });
|
|
4464
|
+
byType.set(key, plans);
|
|
4465
|
+
}
|
|
4466
|
+
return plans(term);
|
|
4467
|
+
}
|
|
4468
|
+
/** This function gives the own entry of a table of a tree contract, or `undefined`. */
|
|
4469
|
+
function entryOf(table, key) {
|
|
4470
|
+
return table !== void 0 && Object.hasOwn(table, key) ? table[key] : void 0;
|
|
4471
|
+
}
|
|
4472
|
+
const NO_CONTRACT = /* @__PURE__ */ Object.freeze({
|
|
4473
|
+
tree: void 0,
|
|
4474
|
+
of: void 0
|
|
4475
|
+
});
|
|
4476
|
+
/** This function finds the tree contract of the kind of a node in the world of the machine. */
|
|
4477
|
+
function contractOf$1(machine, typePath) {
|
|
4478
|
+
if (machine === void 0 || typePath.length === 0) return NO_CONTRACT;
|
|
4479
|
+
const found = lookupKind(machine.world, typePath);
|
|
4480
|
+
if (!found.ok || found.kind.tree === void 0) return NO_CONTRACT;
|
|
4481
|
+
return {
|
|
4482
|
+
tree: found.kind.tree,
|
|
4483
|
+
of: equationType(found.kind)
|
|
4484
|
+
};
|
|
4485
|
+
}
|
|
4115
4486
|
const BUSY = /* @__PURE__ */ Object.freeze({ busy: true });
|
|
4116
4487
|
/** The attributes in evaluation, in the order of their demands. An evaluation does not wait, thus one list serves. */
|
|
4117
4488
|
const demands = [];
|
|
@@ -4179,28 +4550,92 @@ function plainOf(value, path) {
|
|
|
4179
4550
|
}
|
|
4180
4551
|
/**
|
|
4181
4552
|
* This function makes a node of the decorated tree. A step `parent` gives the self of the context of the node, and a
|
|
4182
|
-
* step `type` gives its type.
|
|
4183
|
-
*
|
|
4553
|
+
* step `type` gives its type. Another step reads an attribute through its ladder (TREE.LADDER). The rungs are a part of
|
|
4554
|
+
* the node, an equation of its kind and an equation `down` of the kind of its parent. A copy from the parent, then a
|
|
4555
|
+
* fold or a default, come last. A failed attribute throws `Failure` with its own error, thus a reference to it gives that error.
|
|
4184
4556
|
*/
|
|
4185
|
-
function treeThing(
|
|
4557
|
+
function treeThing(input, build) {
|
|
4558
|
+
const { parts, context, kind: type, place, machine } = input;
|
|
4559
|
+
const { tree, of } = contractOf$1(machine, input.typePath);
|
|
4560
|
+
const above = stateOf(context.self);
|
|
4561
|
+
const up = above !== void 0 && above.build === build ? above : void 0;
|
|
4186
4562
|
const cells = /* @__PURE__ */ new Map();
|
|
4563
|
+
/** The positions of the items of the list `children`, for the names of the children. */
|
|
4564
|
+
let positions;
|
|
4565
|
+
const fold = (key, declared) => {
|
|
4566
|
+
let acc = state.equation(declared.unit, NO_NAMES$1);
|
|
4567
|
+
if (!acc.ok) return acc;
|
|
4568
|
+
const children = read("children");
|
|
4569
|
+
if (children === void 0) return acc;
|
|
4570
|
+
if (!children.ok) return children;
|
|
4571
|
+
if (!Array.isArray(children.value)) return fail("#VALUE!", `The fold of ${key} needs a list in children.`);
|
|
4572
|
+
for (const item of children.value) {
|
|
4573
|
+
const child = stateOf(item);
|
|
4574
|
+
if (child === void 0 || child.build !== build) continue;
|
|
4575
|
+
const value = child.read(key);
|
|
4576
|
+
if (value === void 0) return fail("#N/A", `No rung gives ${attributeText(key, child.type, child.place)}.`);
|
|
4577
|
+
if (!value.ok) return value;
|
|
4578
|
+
acc = state.equation(declared.combine, {
|
|
4579
|
+
acc: acc.value,
|
|
4580
|
+
item: value.value
|
|
4581
|
+
});
|
|
4582
|
+
if (!acc.ok) return acc;
|
|
4583
|
+
}
|
|
4584
|
+
return acc;
|
|
4585
|
+
};
|
|
4586
|
+
/** This function visits the rungs of the ladder of an attribute in their order, until one answers. */
|
|
4587
|
+
const climb = (key) => {
|
|
4588
|
+
const part = parts.find((item) => item.key === key);
|
|
4589
|
+
if (part !== void 0) return {
|
|
4590
|
+
result: part.evaluate({
|
|
4591
|
+
...context,
|
|
4592
|
+
self: node
|
|
4593
|
+
}),
|
|
4594
|
+
by: "own"
|
|
4595
|
+
};
|
|
4596
|
+
const equation = entryOf(tree?.equations, key);
|
|
4597
|
+
if (equation !== void 0) return {
|
|
4598
|
+
result: state.equation(equation, NO_NAMES$1),
|
|
4599
|
+
by: "kind"
|
|
4600
|
+
};
|
|
4601
|
+
const down = up === void 0 ? void 0 : entryOf(up.tree?.down, key);
|
|
4602
|
+
if (up !== void 0 && down !== void 0) {
|
|
4603
|
+
const names = up.childNames(node);
|
|
4604
|
+
return {
|
|
4605
|
+
result: names.ok ? up.equation(down, names.value) : names,
|
|
4606
|
+
by: "parent"
|
|
4607
|
+
};
|
|
4608
|
+
}
|
|
4609
|
+
const declared = entryOf(tree?.attributes, key);
|
|
4610
|
+
if (declared?.copy === true && up !== void 0) {
|
|
4611
|
+
const copied = up.read(key);
|
|
4612
|
+
if (copied !== void 0) return {
|
|
4613
|
+
result: copied,
|
|
4614
|
+
by: "copy"
|
|
4615
|
+
};
|
|
4616
|
+
}
|
|
4617
|
+
if (declared?.fold !== void 0) return {
|
|
4618
|
+
result: fold(key, declared.fold),
|
|
4619
|
+
by: "default"
|
|
4620
|
+
};
|
|
4621
|
+
if (declared?.default !== void 0) return {
|
|
4622
|
+
result: state.equation(declared.default, NO_NAMES$1),
|
|
4623
|
+
by: "default"
|
|
4624
|
+
};
|
|
4625
|
+
};
|
|
4187
4626
|
const read = (key) => {
|
|
4188
4627
|
const cell = cells.get(key);
|
|
4189
4628
|
if (cell !== void 0) return cell.busy ? cycleAt(cells, key, attributeText(key, type, place)) : cell.result;
|
|
4190
|
-
|
|
4191
|
-
if (part === void 0) return void 0;
|
|
4629
|
+
if (tree === void 0 && up?.tree === void 0 && !parts.some((item) => item.key === key)) return void 0;
|
|
4192
4630
|
cells.set(key, BUSY);
|
|
4193
4631
|
demands.push({
|
|
4194
4632
|
cells,
|
|
4195
4633
|
key,
|
|
4196
4634
|
text: attributeText(key, type, place)
|
|
4197
4635
|
});
|
|
4198
|
-
let
|
|
4636
|
+
let answer;
|
|
4199
4637
|
try {
|
|
4200
|
-
|
|
4201
|
-
...context,
|
|
4202
|
-
self: node
|
|
4203
|
-
});
|
|
4638
|
+
answer = climb(key);
|
|
4204
4639
|
} catch (error) {
|
|
4205
4640
|
cells.delete(key);
|
|
4206
4641
|
throw error;
|
|
@@ -4209,14 +4644,60 @@ function treeThing(parts, context, type, place, build) {
|
|
|
4209
4644
|
}
|
|
4210
4645
|
cells.set(key, {
|
|
4211
4646
|
busy: false,
|
|
4212
|
-
result
|
|
4647
|
+
result: answer?.result,
|
|
4648
|
+
by: answer?.by
|
|
4213
4649
|
});
|
|
4214
|
-
return result;
|
|
4650
|
+
return answer?.result;
|
|
4215
4651
|
};
|
|
4216
4652
|
const state = {
|
|
4217
4653
|
build,
|
|
4218
4654
|
type,
|
|
4219
4655
|
place,
|
|
4656
|
+
tree,
|
|
4657
|
+
read,
|
|
4658
|
+
equation(term, names) {
|
|
4659
|
+
if (machine === void 0) return fail("#NOEVAL", "The evaluation of an equation needs the machine.");
|
|
4660
|
+
return equationPlan(machine, of, term).evaluate({
|
|
4661
|
+
...context,
|
|
4662
|
+
names,
|
|
4663
|
+
caps: NO_CAPS$1,
|
|
4664
|
+
self: node
|
|
4665
|
+
});
|
|
4666
|
+
},
|
|
4667
|
+
childNames(child) {
|
|
4668
|
+
const children = read("children");
|
|
4669
|
+
if (children !== void 0 && !children.ok) return children;
|
|
4670
|
+
const list = children !== void 0 && Array.isArray(children.value) ? children.value : [];
|
|
4671
|
+
if (positions?.list !== list) {
|
|
4672
|
+
const at = /* @__PURE__ */ new Map();
|
|
4673
|
+
list.forEach((item, index) => {
|
|
4674
|
+
if (!at.has(item)) at.set(item, index);
|
|
4675
|
+
});
|
|
4676
|
+
positions = {
|
|
4677
|
+
list,
|
|
4678
|
+
at
|
|
4679
|
+
};
|
|
4680
|
+
}
|
|
4681
|
+
const index = positions.at.get(child);
|
|
4682
|
+
return ok({
|
|
4683
|
+
child,
|
|
4684
|
+
index: index ?? null,
|
|
4685
|
+
prev: index === void 0 || index === 0 ? null : list[index - 1]
|
|
4686
|
+
});
|
|
4687
|
+
},
|
|
4688
|
+
trace(key) {
|
|
4689
|
+
const cell = cells.get(key);
|
|
4690
|
+
if (cell === void 0 || cell.busy) return void 0;
|
|
4691
|
+
const rungs = cell.by === void 0 ? ATTRIBUTE_RUNGS : ATTRIBUTE_RUNGS.slice(0, ATTRIBUTE_RUNGS.indexOf(cell.by) + 1);
|
|
4692
|
+
return cell.by === void 0 ? {
|
|
4693
|
+
attribute: key,
|
|
4694
|
+
rungs
|
|
4695
|
+
} : {
|
|
4696
|
+
attribute: key,
|
|
4697
|
+
rungs,
|
|
4698
|
+
by: cell.by
|
|
4699
|
+
};
|
|
4700
|
+
},
|
|
4220
4701
|
json(path) {
|
|
4221
4702
|
path.add(node);
|
|
4222
4703
|
try {
|
|
@@ -4248,7 +4729,9 @@ function treeThing(parts, context, type, place, build) {
|
|
|
4248
4729
|
return result.value;
|
|
4249
4730
|
},
|
|
4250
4731
|
has(key) {
|
|
4251
|
-
|
|
4732
|
+
if (key === "parent" || key === "type" || parts.some((part) => part.key === String(key))) return true;
|
|
4733
|
+
const cell = cells.get(String(key));
|
|
4734
|
+
return cell !== void 0 && !cell.busy && cell.result !== void 0;
|
|
4252
4735
|
},
|
|
4253
4736
|
toJson() {
|
|
4254
4737
|
const result = state.json(/* @__PURE__ */ new Set());
|
|
@@ -4259,14 +4742,25 @@ function treeThing(parts, context, type, place, build) {
|
|
|
4259
4742
|
return node;
|
|
4260
4743
|
}
|
|
4261
4744
|
/**
|
|
4745
|
+
* This function gives the record of the demand of an attribute of a node of the decorated tree (TREE.RUNGS). The
|
|
4746
|
+
* record holds the rungs that the demand visited, and the rung that answered. An explorer draws the ladder with it.
|
|
4747
|
+
*
|
|
4748
|
+
* @param node - The thing of a node.
|
|
4749
|
+
* @param attribute - The name of the attribute.
|
|
4750
|
+
* @returns The record, or `undefined` for a thing that is not a node or an attribute that no demand reached.
|
|
4751
|
+
*/
|
|
4752
|
+
function attributeTrace(node, attribute) {
|
|
4753
|
+
return stateOf(node)?.trace(attribute);
|
|
4754
|
+
}
|
|
4755
|
+
/**
|
|
4262
4756
|
* This function evaluates a node of the decorated tree. Inside an attribute of an open tree, the node gives its host
|
|
4263
4757
|
* thing, and no attribute evaluates. Else the node is the root of a new tree, and it gives the JSON of the tree.
|
|
4264
4758
|
*/
|
|
4265
|
-
function treeNode(
|
|
4266
|
-
const above = stateOf(context.self);
|
|
4267
|
-
if (above !== void 0 && above.build.open) return ok(treeThing(
|
|
4759
|
+
function treeNode(input) {
|
|
4760
|
+
const above = stateOf(input.context.self);
|
|
4761
|
+
if (above !== void 0 && above.build.open) return ok(treeThing(input, above.build));
|
|
4268
4762
|
const build = { open: true };
|
|
4269
|
-
const root = treeThing(
|
|
4763
|
+
const root = treeThing(input, build);
|
|
4270
4764
|
try {
|
|
4271
4765
|
return stateOf(root).json(/* @__PURE__ */ new Set());
|
|
4272
4766
|
} finally {
|
|
@@ -5009,75 +5503,6 @@ function typePass(machine, nodes, verb, expect, rootTypes = {}) {
|
|
|
5009
5503
|
}
|
|
5010
5504
|
//#endregion
|
|
5011
5505
|
//#region src/static.ts
|
|
5012
|
-
function valueAt(value, path) {
|
|
5013
|
-
let here = value;
|
|
5014
|
-
for (const key of path) if (Array.isArray(here)) here = here[Number(key)];
|
|
5015
|
-
else if (isRecord(here) && Object.hasOwn(here, String(key))) here = here[String(key)];
|
|
5016
|
-
else return void 0;
|
|
5017
|
-
return here;
|
|
5018
|
-
}
|
|
5019
|
-
function headerName(item) {
|
|
5020
|
-
return isEnvelope(item) && typeof item.name === "string" ? item.name : void 0;
|
|
5021
|
-
}
|
|
5022
|
-
function namesOf(source, value, covered) {
|
|
5023
|
-
if ("fixed" in source) return source.fixed;
|
|
5024
|
-
if ("keysAt" in source) {
|
|
5025
|
-
const at = valueAt(value, source.keysAt);
|
|
5026
|
-
return isRecord(at) ? Object.keys(at) : [];
|
|
5027
|
-
}
|
|
5028
|
-
if ("listAt" in source) {
|
|
5029
|
-
const at = valueAt(value, source.listAt);
|
|
5030
|
-
return Array.isArray(at) ? at.filter((item) => typeof item === "string") : [];
|
|
5031
|
-
}
|
|
5032
|
-
if ("textAt" in source) {
|
|
5033
|
-
const at = valueAt(value, source.textAt);
|
|
5034
|
-
if (typeof at === "string") return [at];
|
|
5035
|
-
return source.otherwise === void 0 ? [] : [source.otherwise];
|
|
5036
|
-
}
|
|
5037
|
-
return covered.map((slot) => headerName(slot.item)).filter((name) => name !== void 0);
|
|
5038
|
-
}
|
|
5039
|
-
/**
|
|
5040
|
-
* This function gives the names that the scope rules of a kind give each part, and the names that only later parts
|
|
5041
|
-
* see. `check` and `conforms` read the scope rules with it.
|
|
5042
|
-
*
|
|
5043
|
-
* @param rules - The scope rules of the kind.
|
|
5044
|
-
* @param value - The value of the document.
|
|
5045
|
-
* @param slots - The parts of the value, in order.
|
|
5046
|
-
* @returns The names that each part sees, and the names that only the later parts see, by the index of the part.
|
|
5047
|
-
*/
|
|
5048
|
-
function scopesOf(rules, value, slots) {
|
|
5049
|
-
const sees = slots.map(() => []);
|
|
5050
|
-
const later = slots.map(() => []);
|
|
5051
|
-
for (const rule of rules ?? []) {
|
|
5052
|
-
const covered = slots.map((slot, index) => ({
|
|
5053
|
-
slot,
|
|
5054
|
-
index
|
|
5055
|
-
})).filter(({ slot }) => rule.in.some((pattern) => pathMatches(slot.path, pattern)));
|
|
5056
|
-
if (rule.sequential !== true) {
|
|
5057
|
-
const names = namesOf(rule.names, value, covered.map(({ slot }) => slot));
|
|
5058
|
-
for (const { index } of covered) sees[index]?.push(...names);
|
|
5059
|
-
continue;
|
|
5060
|
-
}
|
|
5061
|
-
if ("headers" in rule.names) {
|
|
5062
|
-
covered.forEach(({ index }, position) => {
|
|
5063
|
-
const before = covered.slice(0, position).map(({ slot }) => headerName(slot.item)).filter((name) => name !== void 0);
|
|
5064
|
-
const after = covered.slice(position).map(({ slot }) => headerName(slot.item)).filter((name) => name !== void 0);
|
|
5065
|
-
sees[index]?.push(...before);
|
|
5066
|
-
later[index]?.push(...after);
|
|
5067
|
-
});
|
|
5068
|
-
continue;
|
|
5069
|
-
}
|
|
5070
|
-
const names = namesOf(rule.names, value, covered.map(({ slot }) => slot));
|
|
5071
|
-
covered.forEach(({ index }, position) => {
|
|
5072
|
-
if (position > 0) sees[index]?.push(...names);
|
|
5073
|
-
else later[index]?.push(...names);
|
|
5074
|
-
});
|
|
5075
|
-
}
|
|
5076
|
-
return {
|
|
5077
|
-
sees,
|
|
5078
|
-
later
|
|
5079
|
-
};
|
|
5080
|
-
}
|
|
5081
5506
|
/** The names of a walk without names. A walk does not change a set at any time: it makes a new set to add names. */
|
|
5082
5507
|
const NO_NAMES = /* @__PURE__ */ new Set();
|
|
5083
5508
|
/** This function gives the options of a walk without the names of the host. */
|
|
@@ -5422,11 +5847,81 @@ function typeCheck(machine, doc, options = {}) {
|
|
|
5422
5847
|
places: pass.places
|
|
5423
5848
|
};
|
|
5424
5849
|
}
|
|
5850
|
+
/** The names that an equation of `down` sees (TREE.DOWN). */
|
|
5851
|
+
const DOWN_NAMES = /* @__PURE__ */ Object.freeze([
|
|
5852
|
+
"child",
|
|
5853
|
+
"index",
|
|
5854
|
+
"prev"
|
|
5855
|
+
]);
|
|
5856
|
+
/** The names that the term `combine` of a fold sees (TREE.FOLD). */
|
|
5857
|
+
const FOLD_NAMES = /* @__PURE__ */ Object.freeze(["acc", "item"]);
|
|
5858
|
+
/**
|
|
5859
|
+
* This function gives each equation of the tree contract of a kind, with the names that it sees (D42). An equation of
|
|
5860
|
+
* `equations`, a `unit` and a `default` see no names.
|
|
5861
|
+
*/
|
|
5862
|
+
function equationsOf(kind) {
|
|
5863
|
+
const tree = kind.tree;
|
|
5864
|
+
if (tree === void 0) return [];
|
|
5865
|
+
const out = [];
|
|
5866
|
+
for (const [name, term] of Object.entries(tree.equations ?? {})) out.push({
|
|
5867
|
+
label: `tree.equations.${name}`,
|
|
5868
|
+
term,
|
|
5869
|
+
names: []
|
|
5870
|
+
});
|
|
5871
|
+
for (const [name, term] of Object.entries(tree.down ?? {})) out.push({
|
|
5872
|
+
label: `tree.down.${name}`,
|
|
5873
|
+
term,
|
|
5874
|
+
names: DOWN_NAMES
|
|
5875
|
+
});
|
|
5876
|
+
for (const [name, declared] of Object.entries(tree.attributes ?? {})) {
|
|
5877
|
+
if (declared.fold !== void 0) {
|
|
5878
|
+
out.push({
|
|
5879
|
+
label: `tree.attributes.${name}.fold.unit`,
|
|
5880
|
+
term: declared.fold.unit,
|
|
5881
|
+
names: []
|
|
5882
|
+
});
|
|
5883
|
+
out.push({
|
|
5884
|
+
label: `tree.attributes.${name}.fold.combine`,
|
|
5885
|
+
term: declared.fold.combine,
|
|
5886
|
+
names: FOLD_NAMES
|
|
5887
|
+
});
|
|
5888
|
+
}
|
|
5889
|
+
if (declared.default !== void 0) out.push({
|
|
5890
|
+
label: `tree.attributes.${name}.default`,
|
|
5891
|
+
term: declared.default,
|
|
5892
|
+
names: []
|
|
5893
|
+
});
|
|
5894
|
+
}
|
|
5895
|
+
return out;
|
|
5896
|
+
}
|
|
5897
|
+
/**
|
|
5898
|
+
* This function checks the equations of the tree contract of a kind, each with the names of its rung (TREE.DOWN-NAMES).
|
|
5899
|
+
* An equation evaluates without capabilities, thus a check with capabilities gives it none. Each issue gets the place
|
|
5900
|
+
* of the document of the kind, and its reason names the equation.
|
|
5901
|
+
*/
|
|
5902
|
+
function equationIssues(machine, kind, kindText, options, seen) {
|
|
5903
|
+
const of = equationType(kind);
|
|
5904
|
+
const out = [];
|
|
5905
|
+
for (const { label, term, names } of equationsOf(kind)) {
|
|
5906
|
+
const inner = {
|
|
5907
|
+
names,
|
|
5908
|
+
...of === void 0 ? {} : { declaredType: of },
|
|
5909
|
+
...options.caps === void 0 ? {} : { caps: [] }
|
|
5910
|
+
};
|
|
5911
|
+
for (const issue of checkAll(machine, term, inner, void 0, seen)) out.push({
|
|
5912
|
+
code: issue.code,
|
|
5913
|
+
place: [],
|
|
5914
|
+
reason: `In the equation ${label} of the kind ${kindText}: ${issue.reason}`
|
|
5915
|
+
});
|
|
5916
|
+
}
|
|
5917
|
+
return out;
|
|
5918
|
+
}
|
|
5425
5919
|
/**
|
|
5426
5920
|
* This function finds the issues of `check`. With a list of nodes, it also records each document that it visits for
|
|
5427
|
-
* the pass of types. It marks each document with an issue.
|
|
5921
|
+
* the pass of types. It marks each document with an issue. The set `seen` holds the kinds whose equations the check
|
|
5922
|
+
* walked, thus it walks the equations of each kind one time.
|
|
5428
5923
|
*/
|
|
5429
|
-
function checkAll(machine, doc, options, nodes) {
|
|
5924
|
+
function checkAll(machine, doc, options, nodes, seen = /* @__PURE__ */ new Set()) {
|
|
5430
5925
|
const issues = [];
|
|
5431
5926
|
const verb = options.verb ?? "eval";
|
|
5432
5927
|
const indices = nodes === void 0 ? void 0 : /* @__PURE__ */ new Map();
|
|
@@ -5478,6 +5973,14 @@ function checkAll(machine, doc, options, nodes) {
|
|
|
5478
5973
|
});
|
|
5479
5974
|
return "skip";
|
|
5480
5975
|
}
|
|
5976
|
+
if (v.kind?.tree !== void 0 && !seen.has(v.kind)) {
|
|
5977
|
+
seen.add(v.kind);
|
|
5978
|
+
for (const issue of equationIssues(machine, v.kind, typeName(v.doc.type), options, seen)) push({
|
|
5979
|
+
...issue,
|
|
5980
|
+
place: v.place,
|
|
5981
|
+
at: v.at
|
|
5982
|
+
});
|
|
5983
|
+
}
|
|
5481
5984
|
const name = answer.evaluator;
|
|
5482
5985
|
if (current !== void 0) current.evaluator = name;
|
|
5483
5986
|
const runner = name !== void 0 && has(machine.runners, name);
|
|
@@ -7857,13 +8360,22 @@ function examine$1(env, at) {
|
|
|
7857
8360
|
split
|
|
7858
8361
|
};
|
|
7859
8362
|
}
|
|
8363
|
+
/**
|
|
8364
|
+
* This function gives the effects that two lists of capabilities both permit (CAP.ONLY). The reference reads the rule
|
|
8365
|
+
* from SPEC directly, and not from the intersection of the plan. Thus `agree` finds a bug in either one (D15).
|
|
8366
|
+
*/
|
|
8367
|
+
function bothPermit(a, b) {
|
|
8368
|
+
const out = [];
|
|
8369
|
+
for (const cap of [...a, ...b]) if (permits(a, cap) && permits(b, cap) && !permits(out, cap)) out.push(cap);
|
|
8370
|
+
return out;
|
|
8371
|
+
}
|
|
7860
8372
|
/** This function gives the capabilities that the rules of a kind give one part (D14, CAP.CONTRACT, CAP.ONLY). */
|
|
7861
8373
|
function capsOfPart(rules, path, caps) {
|
|
7862
8374
|
let out = caps;
|
|
7863
8375
|
for (const rule of rules ?? []) {
|
|
7864
8376
|
if (rule.in !== void 0 && !rule.in.some((pattern) => pathMatches(path, pattern))) continue;
|
|
7865
8377
|
if (rule.rule === "mask") return [];
|
|
7866
|
-
if (rule.rule === "only") out =
|
|
8378
|
+
if (rule.rule === "only") out = bothPermit(out, rule.caps);
|
|
7867
8379
|
}
|
|
7868
8380
|
return out;
|
|
7869
8381
|
}
|
|
@@ -8135,6 +8647,7 @@ function reference(machine, doc, context = makeContext(), options = {}) {
|
|
|
8135
8647
|
...context,
|
|
8136
8648
|
world: worldThing(machine.world)
|
|
8137
8649
|
} : context;
|
|
8650
|
+
activeEnvs.push(env);
|
|
8138
8651
|
try {
|
|
8139
8652
|
return evaluateAt(env, {
|
|
8140
8653
|
value: doc,
|
|
@@ -8146,8 +8659,12 @@ function reference(machine, doc, context = makeContext(), options = {}) {
|
|
|
8146
8659
|
});
|
|
8147
8660
|
} catch (error) {
|
|
8148
8661
|
return placed(thrown(error, "the reference"), []);
|
|
8662
|
+
} finally {
|
|
8663
|
+
activeEnvs.pop();
|
|
8149
8664
|
}
|
|
8150
8665
|
}
|
|
8666
|
+
/** The evaluations of the reference that run at this time, the innermost last. */
|
|
8667
|
+
const activeEnvs = [];
|
|
8151
8668
|
const refNodes = /* @__PURE__ */ new WeakMap();
|
|
8152
8669
|
/** The attributes in evaluation in the reference, in the order of their demands (TREE.CYCLE). */
|
|
8153
8670
|
const inEvaluation = [];
|
|
@@ -8157,28 +8674,109 @@ function nameOfAttribute(node, name) {
|
|
|
8157
8674
|
function refNodeOf(thing) {
|
|
8158
8675
|
return typeof thing === "object" && thing !== null ? refNodes.get(thing) : void 0;
|
|
8159
8676
|
}
|
|
8160
|
-
/**
|
|
8161
|
-
|
|
8677
|
+
/**
|
|
8678
|
+
* TREE.LADDER: an equation of the kind of a node evaluates in the reference. It gets the node as `self`, the names of
|
|
8679
|
+
* its rung and no capabilities. A bare equation gets the type `of` of the parts of the kind.
|
|
8680
|
+
*/
|
|
8681
|
+
function equationOf(node, term, names) {
|
|
8682
|
+
const env = node.env;
|
|
8683
|
+
if (env === void 0) return fail("#NOEVAL", "The evaluation of an equation needs the machine.");
|
|
8684
|
+
const ctx = {
|
|
8685
|
+
...node.ctx,
|
|
8686
|
+
names,
|
|
8687
|
+
caps: [],
|
|
8688
|
+
self: node.thing
|
|
8689
|
+
};
|
|
8690
|
+
return reference(env.machine, term, ctx, {
|
|
8691
|
+
definitions: env.definitions,
|
|
8692
|
+
...node.of === void 0 ? {} : { declaredType: node.of }
|
|
8693
|
+
});
|
|
8694
|
+
}
|
|
8695
|
+
function termIn(table, name) {
|
|
8696
|
+
return table === void 0 || !Object.hasOwn(table, name) ? void 0 : table[name];
|
|
8697
|
+
}
|
|
8698
|
+
/** TREE.DOWN: the names of a child for an equation of `down` of its parent: `child`, `index` and `prev`. */
|
|
8699
|
+
function namesOfChild(up, child) {
|
|
8700
|
+
const children = attributeOf(up, "children");
|
|
8701
|
+
if (children !== void 0 && !children.ok) return children;
|
|
8702
|
+
const list = children !== void 0 && Array.isArray(children.value) ? children.value : [];
|
|
8703
|
+
const index = list.indexOf(child.thing);
|
|
8704
|
+
return ok({
|
|
8705
|
+
child: child.thing,
|
|
8706
|
+
index: index < 0 ? null : index,
|
|
8707
|
+
prev: index > 0 ? list[index - 1] : null
|
|
8708
|
+
});
|
|
8709
|
+
}
|
|
8710
|
+
/** TREE.FOLD: the unit, then `combine` with the attribute of each node of this tree in the list `children`. */
|
|
8711
|
+
function foldOf(node, name, fold) {
|
|
8712
|
+
let acc = equationOf(node, fold.unit, {});
|
|
8713
|
+
if (!acc.ok) return acc;
|
|
8714
|
+
const children = attributeOf(node, "children");
|
|
8715
|
+
if (children === void 0) return acc;
|
|
8716
|
+
if (!children.ok) return children;
|
|
8717
|
+
if (!Array.isArray(children.value)) return fail("#VALUE!", `The fold of ${name} needs a list in children.`);
|
|
8718
|
+
for (const item of children.value) {
|
|
8719
|
+
const child = refNodeOf(item);
|
|
8720
|
+
if (child === void 0 || child.tree !== node.tree) continue;
|
|
8721
|
+
const value = attributeOf(child, name);
|
|
8722
|
+
if (value === void 0) return fail("#N/A", `No rung gives ${nameOfAttribute(child, name)}.`);
|
|
8723
|
+
if (!value.ok) return value;
|
|
8724
|
+
acc = equationOf(node, fold.combine, {
|
|
8725
|
+
acc: acc.value,
|
|
8726
|
+
item: value.value
|
|
8727
|
+
});
|
|
8728
|
+
if (!acc.ok) return acc;
|
|
8729
|
+
}
|
|
8730
|
+
return acc;
|
|
8731
|
+
}
|
|
8732
|
+
/**
|
|
8733
|
+
* TREE.LADDER: the rungs of the ladder of an attribute, in their order. A rung gives `undefined` when it does not
|
|
8734
|
+
* answer, and the next rung then tries.
|
|
8735
|
+
*/
|
|
8736
|
+
const REF_RUNGS = [
|
|
8737
|
+
["own", (node, name) => node.parts.find((item) => item.key === name)?.evaluate({
|
|
8738
|
+
...node.ctx,
|
|
8739
|
+
self: node.thing
|
|
8740
|
+
})],
|
|
8741
|
+
["kind", (node, name) => {
|
|
8742
|
+
const term = termIn(node.contract?.equations, name);
|
|
8743
|
+
return term === void 0 ? void 0 : equationOf(node, term, {});
|
|
8744
|
+
}],
|
|
8745
|
+
["parent", (node, name) => {
|
|
8746
|
+
const up = node.up;
|
|
8747
|
+
const term = up === void 0 ? void 0 : termIn(up.contract?.down, name);
|
|
8748
|
+
if (up === void 0 || term === void 0) return void 0;
|
|
8749
|
+
const names = namesOfChild(up, node);
|
|
8750
|
+
return names.ok ? equationOf(up, term, names.value) : names;
|
|
8751
|
+
}],
|
|
8752
|
+
["copy", (node, name) => node.up !== void 0 && termIn(node.contract?.attributes, name)?.copy === true ? attributeOf(node.up, name) : void 0],
|
|
8753
|
+
["default", (node, name) => {
|
|
8754
|
+
const declared = termIn(node.contract?.attributes, name);
|
|
8755
|
+
if (declared?.fold !== void 0) return foldOf(node, name, declared.fold);
|
|
8756
|
+
return declared?.default === void 0 ? void 0 : equationOf(node, declared.default, {});
|
|
8757
|
+
}]
|
|
8758
|
+
];
|
|
8759
|
+
/** TREE.ONCE, TREE.MEMO and TREE.CYCLE: the result of one attribute, or `undefined` when no rung of its ladder answers. */
|
|
8760
|
+
function attributeOf(node, name) {
|
|
8162
8761
|
const done = node.values.get(name);
|
|
8163
8762
|
if (done !== void 0) return done;
|
|
8164
8763
|
if (node.pending.has(name)) {
|
|
8165
8764
|
const from = inEvaluation.findIndex((entry) => entry.node === node && entry.name === name);
|
|
8166
8765
|
return fail("#CYCLE!", `The attributes form a cycle: ${[...from < 0 ? [nameOfAttribute(node, name)] : inEvaluation.slice(from).map((entry) => nameOfAttribute(entry.node, entry.name)), nameOfAttribute(node, name)].join(" -> ")}.`);
|
|
8167
8766
|
}
|
|
8168
|
-
const part = node.parts.find((item) => item.key === name);
|
|
8169
|
-
if (part === void 0) return void 0;
|
|
8170
8767
|
node.pending.add(name);
|
|
8171
8768
|
inEvaluation.push({
|
|
8172
8769
|
node,
|
|
8173
8770
|
name
|
|
8174
8771
|
});
|
|
8175
8772
|
try {
|
|
8176
|
-
const
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8773
|
+
for (const [, rung] of REF_RUNGS) {
|
|
8774
|
+
const result = rung(node, name);
|
|
8775
|
+
if (result === void 0) continue;
|
|
8776
|
+
node.values.set(name, result);
|
|
8777
|
+
return result;
|
|
8778
|
+
}
|
|
8779
|
+
return;
|
|
8182
8780
|
} finally {
|
|
8183
8781
|
node.pending.delete(name);
|
|
8184
8782
|
inEvaluation.pop();
|
|
@@ -8188,7 +8786,7 @@ function attributeOf(node, self, name) {
|
|
|
8188
8786
|
function jsonOfNode(node, self, open) {
|
|
8189
8787
|
const record = {};
|
|
8190
8788
|
for (const part of node.parts) {
|
|
8191
|
-
const result = attributeOf(node,
|
|
8789
|
+
const result = attributeOf(node, part.key);
|
|
8192
8790
|
if (!result.ok) return result;
|
|
8193
8791
|
const value = plainValue(result.value, [...open, self]);
|
|
8194
8792
|
if (!value.ok) return value;
|
|
@@ -8226,15 +8824,23 @@ function plainValue(value, open) {
|
|
|
8226
8824
|
* TREE.LAZY, TREE.PARENT, TREE.SIBLING and TREE.ERROR: a node of an open tree gives its thing, and the root of a new
|
|
8227
8825
|
* tree gives its JSON. A step on the thing reads an attribute, and a failed attribute throws its own error.
|
|
8228
8826
|
*/
|
|
8229
|
-
const treeDefinition = ({ parts, context, kind, place }) => {
|
|
8827
|
+
const treeDefinition = ({ parts, context, kind, place, machine, typePath }) => {
|
|
8230
8828
|
const outer = refNodeOf(context.self);
|
|
8231
8829
|
const nested = outer !== void 0 && outer.tree.open;
|
|
8830
|
+
const found = machine === void 0 || typePath.length === 0 ? void 0 : lookupKind(machine.world, typePath);
|
|
8831
|
+
const contract = found?.ok === true ? found.kind.tree : void 0;
|
|
8832
|
+
const of = contract === void 0 || found?.ok !== true ? void 0 : equationType(found.kind);
|
|
8232
8833
|
const node = {
|
|
8233
8834
|
tree: nested ? outer.tree : { open: true },
|
|
8234
8835
|
kind,
|
|
8235
8836
|
place,
|
|
8236
8837
|
parts,
|
|
8237
8838
|
ctx: context,
|
|
8839
|
+
contract,
|
|
8840
|
+
of,
|
|
8841
|
+
up: nested ? outer : void 0,
|
|
8842
|
+
env: activeEnvs[activeEnvs.length - 1],
|
|
8843
|
+
thing: null,
|
|
8238
8844
|
values: /* @__PURE__ */ new Map(),
|
|
8239
8845
|
pending: /* @__PURE__ */ new Set()
|
|
8240
8846
|
};
|
|
@@ -8245,17 +8851,18 @@ const treeDefinition = ({ parts, context, kind, place }) => {
|
|
|
8245
8851
|
deref: (key) => {
|
|
8246
8852
|
if (key === "parent") return context.self;
|
|
8247
8853
|
if (key === "type") return kind;
|
|
8248
|
-
const result = attributeOf(node,
|
|
8854
|
+
const result = attributeOf(node, String(key));
|
|
8249
8855
|
if (result === void 0 || result.ok) return result?.ok === true ? result.value : void 0;
|
|
8250
8856
|
throw new Failure(result.error);
|
|
8251
8857
|
},
|
|
8252
|
-
has: (key) => key === "parent" || key === "type" || parts.some((part) => part.key === String(key)),
|
|
8858
|
+
has: (key) => key === "parent" || key === "type" || parts.some((part) => part.key === String(key)) || node.values.has(String(key)),
|
|
8253
8859
|
toJson: () => {
|
|
8254
8860
|
const result = jsonOfNode(node, self, []);
|
|
8255
8861
|
if (result.ok) return result.value;
|
|
8256
8862
|
throw new Failure(result.error);
|
|
8257
8863
|
}
|
|
8258
8864
|
};
|
|
8865
|
+
node.thing = self;
|
|
8259
8866
|
refNodes.set(self, node);
|
|
8260
8867
|
if (nested) return ok(self);
|
|
8261
8868
|
try {
|
|
@@ -8487,6 +9094,13 @@ function valuesOfStrict(parts) {
|
|
|
8487
9094
|
}
|
|
8488
9095
|
//#endregion
|
|
8489
9096
|
//#region src/agree.ts
|
|
9097
|
+
/** The tiers that `agree` compares when its options name none. */
|
|
9098
|
+
const DEFAULT_TIERS = /* @__PURE__ */ Object.freeze([
|
|
9099
|
+
"reference",
|
|
9100
|
+
"traced",
|
|
9101
|
+
"again",
|
|
9102
|
+
"folds"
|
|
9103
|
+
]);
|
|
8490
9104
|
/**
|
|
8491
9105
|
* This function tells if two values are the same for `agree`. Lists and plain records compare item by item and field
|
|
8492
9106
|
* by field, and the order of the fields does not matter. Each other leaf compares with `Object.is`, thus `-0` is not
|
|
@@ -8576,7 +9190,11 @@ function agree(machine, doc, context = makeContext(), options = {}) {
|
|
|
8576
9190
|
};
|
|
8577
9191
|
const observe = options.observe;
|
|
8578
9192
|
observe?.();
|
|
8579
|
-
const
|
|
9193
|
+
const folds = observe === void 0;
|
|
9194
|
+
const plan = prepare(machine, doc, {
|
|
9195
|
+
...declared,
|
|
9196
|
+
fold: folds
|
|
9197
|
+
});
|
|
8580
9198
|
const effects = [];
|
|
8581
9199
|
const result = plan.evaluate(context, {
|
|
8582
9200
|
effects,
|
|
@@ -8589,11 +9207,7 @@ function agree(machine, doc, context = makeContext(), options = {}) {
|
|
|
8589
9207
|
if (why !== void 0 || observe === void 0) return why;
|
|
8590
9208
|
return sameValue(saw, observe(), options.equal) ? void 0 : "The host saw other calls in the tier.";
|
|
8591
9209
|
};
|
|
8592
|
-
for (const tier of options.tiers ??
|
|
8593
|
-
"reference",
|
|
8594
|
-
"traced",
|
|
8595
|
-
"again"
|
|
8596
|
-
]) {
|
|
9210
|
+
for (const tier of options.tiers ?? DEFAULT_TIERS) {
|
|
8597
9211
|
let other;
|
|
8598
9212
|
let otherEffects = [];
|
|
8599
9213
|
if (tier === "reference") other = reference(machine, doc, context, {
|
|
@@ -8609,6 +9223,27 @@ function agree(machine, doc, context = makeContext(), options = {}) {
|
|
|
8609
9223
|
});
|
|
8610
9224
|
other = traced.result;
|
|
8611
9225
|
otherEffects = [...traced.effects];
|
|
9226
|
+
} else if (tier === "folds") {
|
|
9227
|
+
other = prepare(machine, doc, {
|
|
9228
|
+
...declared,
|
|
9229
|
+
fold: !folds
|
|
9230
|
+
}).evaluate(context, {
|
|
9231
|
+
effects: otherEffects,
|
|
9232
|
+
...mock
|
|
9233
|
+
});
|
|
9234
|
+
if (observe !== void 0) {
|
|
9235
|
+
observe();
|
|
9236
|
+
if (overflowed(result) || overflowed(other)) continue;
|
|
9237
|
+
const why = resultDiffers(result, other, options) ?? effectsDiffer(effects, otherEffects, options);
|
|
9238
|
+
if (why !== void 0) return {
|
|
9239
|
+
ok: false,
|
|
9240
|
+
tier,
|
|
9241
|
+
plan: result,
|
|
9242
|
+
other,
|
|
9243
|
+
reason: why
|
|
9244
|
+
};
|
|
9245
|
+
continue;
|
|
9246
|
+
}
|
|
8612
9247
|
} else other = plan.evaluate(context, {
|
|
8613
9248
|
effects: otherEffects,
|
|
8614
9249
|
...mock
|
|
@@ -11255,6 +11890,6 @@ function typeFromSamples(values, options = {}) {
|
|
|
11255
11890
|
return samplesAt(values, options.closed === true, 0);
|
|
11256
11891
|
}
|
|
11257
11892
|
//#endregion
|
|
11258
|
-
export { CAPS_TYPE, CONSTRUCTS, ENVELOPE_KEYS, Failure, Held, JOURNAL, MergeError, PARTS, PART_INFO, ROOTS, RUNGS, STD_CAPS, STD_DEFINITIONS, STD_DOMAINS, STD_EVALUATORS, STD_EXT, STD_MACHINE, STD_RUNNERS, STD_SYNTAX, STD_WALKERS, STD_WORLD, THING, agree, ask, capKeys, check, checkLatent, checkSteps, classify, components, conforms, context, cycles, dataEdges, decodeDomain, decodeValue, derefStep, describe, docEquals, durable, edgesOf, effectEdges, effectsOf, encodeValue, entriesAsJson, evaluate, extendDomain, factsOf, fail, failures, field, fits, flatten, formulaDefinitions, formulaEvaluators, formulaFacts, formulaKinds, formulaKnown, formulaMachine, fromJson, generate, heights, intersectCaps, isAlias, isAllowedOrder, isClosure, isEnvelope, isHostThing, isKey, isKind, isNamespace, isRecord, isRef, isStackOverflow, isTypeRef, join, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapRefs, member, mergeMachines, mergeWorlds, narrow, nearestWalker, necessary, nodeAt, nodeLayers, ok, parse, partCaps, partsOf, pathMatches, permits, placed, planner, prepare, print, random, recorder, ref, reference, refsOf, replayer, resolve, restrictMachine, restrictWorld, run, sameResult, sameValue, schedule, splitParts, stored, syntaxFormat, tag, thrown, toJson, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
|
|
11893
|
+
export { ATTRIBUTE_RUNGS, CAPS_TYPE, CONSTRUCTS, ENVELOPE_KEYS, Failure, Held, JOURNAL, MergeError, PARTS, PART_INFO, ROOTS, RUNGS, STD_CAPS, STD_DEFINITIONS, STD_DOMAINS, STD_EVALUATORS, STD_EXT, STD_MACHINE, STD_RUNNERS, STD_SYNTAX, STD_WALKERS, STD_WORLD, THING, agree, ask, attributeTrace, capKeys, check, checkLatent, checkSteps, classify, components, conforms, context, cycles, dataEdges, decodeDomain, decodeValue, derefStep, describe, docEquals, durable, edgesOf, effectEdges, effectsOf, encodeValue, entriesAsJson, equationType, evaluate, extendDomain, factsOf, fail, failures, field, fits, flatten, formulaDefinitions, formulaEvaluators, formulaFacts, formulaKinds, formulaKnown, formulaMachine, fromJson, generate, heights, intersectCaps, isAlias, isAllowedOrder, isClosure, isEnvelope, isHostThing, isKey, isKind, isNamespace, isRecord, isRef, isStackOverflow, isTypeRef, join, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapRefs, member, mergeMachines, mergeWorlds, narrow, nearestWalker, necessary, nodeAt, nodeLayers, ok, parse, partCaps, partsOf, pathMatches, permits, placed, planner, prepare, print, random, recorder, ref, reference, refsOf, replayer, resolve, restrictMachine, restrictWorld, run, sameResult, sameValue, schedule, splitParts, stored, syntaxFormat, tag, thrown, toJson, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
|
|
11259
11894
|
|
|
11260
11895
|
//# sourceMappingURL=index.js.map
|