@mark1russell7/coeval 0.24.0 → 0.24.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/README.md +2 -1
- package/build/index.d.ts +117 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +355 -73
- package/build/index.js.map +1 -1
- package/package.json +3 -3
- package/src/agree.ts +105 -2
- package/src/evaluate.ts +49 -5
- package/src/formula.ts +1 -0
- package/src/index.ts +5 -2
- package/src/schedule.ts +11 -2
- package/src/static.ts +51 -3
- package/src/stdlib.ts +29 -11
- package/src/syntax.ts +114 -19
- package/src/typing.ts +33 -3
package/build/index.js
CHANGED
|
@@ -1568,7 +1568,7 @@ const MAX_TEXT_VALUES = 8;
|
|
|
1568
1568
|
/** The most characters of one JSON value in the text of a type. */
|
|
1569
1569
|
const MAX_TEXT_VALUE = 40;
|
|
1570
1570
|
/** This function gives a short text of a JSON value for the text of a type. */
|
|
1571
|
-
function valueText$
|
|
1571
|
+
function valueText$2(value) {
|
|
1572
1572
|
let text;
|
|
1573
1573
|
try {
|
|
1574
1574
|
text = JSON.stringify(value) ?? String(value);
|
|
@@ -1590,7 +1590,7 @@ function textAt(type, depth, wrap) {
|
|
|
1590
1590
|
if (term === "one") {
|
|
1591
1591
|
if (!Array.isArray(type["one"])) return "unknown";
|
|
1592
1592
|
const values = type["one"];
|
|
1593
|
-
const shown = values.slice(0, MAX_TEXT_VALUES).map(valueText$
|
|
1593
|
+
const shown = values.slice(0, MAX_TEXT_VALUES).map(valueText$2);
|
|
1594
1594
|
return group(values.length > MAX_TEXT_VALUES ? [...shown, `… ${values.length - MAX_TEXT_VALUES} more`] : shown);
|
|
1595
1595
|
}
|
|
1596
1596
|
if (term === "fn") {
|
|
@@ -4812,7 +4812,8 @@ function compileNode(c, value, place, declared, depth, address = false) {
|
|
|
4812
4812
|
} catch (error) {
|
|
4813
4813
|
return failingWith(c, meta, placed(thrown(error, `the runner ${name}`), place));
|
|
4814
4814
|
}
|
|
4815
|
-
const
|
|
4815
|
+
const guard = guardOf(c, place);
|
|
4816
|
+
const run = placedRun(guard === void 0 ? inner : guardRun(inner, guard, c.machine.domains), place, name);
|
|
4816
4817
|
return finish$1(c, meta, runnerCode(run, place, kindText), run);
|
|
4817
4818
|
}
|
|
4818
4819
|
let inner;
|
|
@@ -4821,7 +4822,8 @@ function compileNode(c, value, place, declared, depth, address = false) {
|
|
|
4821
4822
|
} catch (error) {
|
|
4822
4823
|
return failingWith(c, meta, placed(thrown(error, `the evaluator ${name}`), place));
|
|
4823
4824
|
}
|
|
4824
|
-
const
|
|
4825
|
+
const guard = guardOf(c, place);
|
|
4826
|
+
const done = finish$1(c, meta, guard !== void 0 ? placedCode(guardCode(inner, guard, c.machine.domains), place, name) : TOTAL.has(inner) ? inner : placedCode(inner, place, name), void 0);
|
|
4825
4827
|
if (frees === void 0 || kind === void 0 || !pureCode(c, envelope, kind, typePath, name, quick)) return done;
|
|
4826
4828
|
const free = freeOf(doc, kind, split.parts, frees);
|
|
4827
4829
|
if (free === void 0) return done;
|
|
@@ -5217,6 +5219,29 @@ function gated(rules, part) {
|
|
|
5217
5219
|
* This function gives the steps of a runner, with the place of each error and of each exception. The steps get the
|
|
5218
5220
|
* context that its grant permits (CAP.NARROW-CODE).
|
|
5219
5221
|
*/
|
|
5222
|
+
/** This function gives the key of a place in the guards of a plan. */
|
|
5223
|
+
function guardKey(place) {
|
|
5224
|
+
return JSON.stringify(place.map(String));
|
|
5225
|
+
}
|
|
5226
|
+
/** This function gives the type of the boundary at a place, when the plan has one (PLAN.GUARD). */
|
|
5227
|
+
function guardOf(c, place) {
|
|
5228
|
+
return c.guards?.get(guardKey(place));
|
|
5229
|
+
}
|
|
5230
|
+
/** This function gives the result of a part of a boundary: a value that is not a member gives `#VALUE!` (PLAN.GUARD). */
|
|
5231
|
+
function guarded(result, type, domains) {
|
|
5232
|
+
if (!result.ok || member(result.value, type, domains)) return result;
|
|
5233
|
+
return fail("#VALUE!", `The value is not a member of ${typeText(type)}, the type of its boundary.`);
|
|
5234
|
+
}
|
|
5235
|
+
/** This function adds the test of a boundary to the code of a part. */
|
|
5236
|
+
function guardCode(inner, type, domains) {
|
|
5237
|
+
return (ctx, rt) => guarded(inner(ctx, rt), type, domains);
|
|
5238
|
+
}
|
|
5239
|
+
/** This function adds the test of a boundary to the steps of a part. */
|
|
5240
|
+
function guardRun(inner, type, domains) {
|
|
5241
|
+
return function* (ctx, rt) {
|
|
5242
|
+
return guarded(yield* inner(ctx, rt), type, domains);
|
|
5243
|
+
};
|
|
5244
|
+
}
|
|
5220
5245
|
function placedRun(inner, place, name) {
|
|
5221
5246
|
return function* (ctx, rt) {
|
|
5222
5247
|
try {
|
|
@@ -5417,6 +5442,7 @@ function prepare(machine, doc, options = {}) {
|
|
|
5417
5442
|
const traced = options.trace === true;
|
|
5418
5443
|
const fold = !traced && options.fold !== false;
|
|
5419
5444
|
const fixed = fold ? fixedNamesOf(options.fixed?.names) : void 0;
|
|
5445
|
+
const guards = options.guards === void 0 || options.guards.length === 0 ? void 0 : new Map(options.guards.map((each) => [guardKey(each.place), each.type]));
|
|
5420
5446
|
const c = {
|
|
5421
5447
|
machine,
|
|
5422
5448
|
traced,
|
|
@@ -5424,7 +5450,8 @@ function prepare(machine, doc, options = {}) {
|
|
|
5424
5450
|
verb,
|
|
5425
5451
|
noAnswer,
|
|
5426
5452
|
fold,
|
|
5427
|
-
fixed
|
|
5453
|
+
fixed,
|
|
5454
|
+
guards
|
|
5428
5455
|
};
|
|
5429
5456
|
let root;
|
|
5430
5457
|
try {
|
|
@@ -5537,7 +5564,8 @@ function evaluate(machine, doc, context = makeContext(), options) {
|
|
|
5537
5564
|
const plan = prepare(machine, doc, {
|
|
5538
5565
|
trace: true,
|
|
5539
5566
|
...declaredType === void 0 ? {} : { declaredType },
|
|
5540
|
-
...given.verb === void 0 ? {} : { verb: given.verb }
|
|
5567
|
+
...given.verb === void 0 ? {} : { verb: given.verb },
|
|
5568
|
+
...given.guards === void 0 ? {} : { guards: given.guards }
|
|
5541
5569
|
});
|
|
5542
5570
|
const ctx = rootContext(machine, context);
|
|
5543
5571
|
const s = new Session(machine, ctx.caps, false, true, given.perform, void 0, void 0, readingOf(given.reads, ctx));
|
|
@@ -5558,6 +5586,7 @@ async function run(machine, doc, context = makeContext(), options = {}) {
|
|
|
5558
5586
|
const plan = prepare(machine, doc, {
|
|
5559
5587
|
trace: true,
|
|
5560
5588
|
...options.declaredType === void 0 ? {} : { declaredType: options.declaredType },
|
|
5589
|
+
...options.guards === void 0 ? {} : { guards: options.guards },
|
|
5561
5590
|
...options.verb === void 0 ? {} : { verb: options.verb }
|
|
5562
5591
|
});
|
|
5563
5592
|
const ctx = rootContext(machine, context);
|
|
@@ -5928,7 +5957,8 @@ const STD_WORLD = {
|
|
|
5928
5957
|
* A literal in a place that takes a document gets its data envelope (K159, D65). Such a place is a part of `if`,
|
|
5929
5958
|
* `list`, `seq` or `pure`, the value of `write`, or the whole text. The document after a header name is such a place
|
|
5930
5959
|
* too. Thus `list(1, "a")` evaluates to `[1, "a"]`. The forms `add`, `multiply` and `greater` write an operator document that its operator
|
|
5931
|
-
* does not write, for example `add(5)` (K163).
|
|
5960
|
+
* does not write, for example `add(5)` (K163). The field `with` of `handle` is a field of data, thus each clause is a
|
|
5961
|
+
* record between braces in a list between brackets (D177).
|
|
5932
5962
|
*
|
|
5933
5963
|
* A host with more kinds spreads this profile and adds its forms to `calls.forms`. `STD_SYNTAX` stays the profile of
|
|
5934
5964
|
* the formula kit.
|
|
@@ -6068,6 +6098,18 @@ const WORLD_SYNTAX = /* @__PURE__ */ Object.freeze({
|
|
|
6068
6098
|
kind: "tree.quote",
|
|
6069
6099
|
args: "literal"
|
|
6070
6100
|
},
|
|
6101
|
+
{
|
|
6102
|
+
name: "handle",
|
|
6103
|
+
kind: "handle",
|
|
6104
|
+
args: "named",
|
|
6105
|
+
fields: [
|
|
6106
|
+
"with",
|
|
6107
|
+
"return",
|
|
6108
|
+
"body"
|
|
6109
|
+
],
|
|
6110
|
+
data: ["with"],
|
|
6111
|
+
wrap: ["return", "body"]
|
|
6112
|
+
},
|
|
6071
6113
|
{
|
|
6072
6114
|
name: "add",
|
|
6073
6115
|
kind: "add"
|
|
@@ -6524,6 +6566,7 @@ function leaderOnHost(n, key, rule, host) {
|
|
|
6524
6566
|
/**
|
|
6525
6567
|
* This function gives an attribute of a node with circular attributes, or an attribute in an open fixed point (D113).
|
|
6526
6568
|
* The memo and the marks of the node do not hold the attribute. An open fixed point does not use the cells of the host.
|
|
6569
|
+
* With the cells of a host, only a circular attribute comes here outside a fixed point. A plain attribute takes its cell.
|
|
6527
6570
|
*/
|
|
6528
6571
|
function circularRead(n, key) {
|
|
6529
6572
|
const rule = circularRule(n.tree, key);
|
|
@@ -6938,7 +6981,7 @@ function treeThing(input, place, build, outer, host) {
|
|
|
6938
6981
|
const text = attributeText(key, type, place);
|
|
6939
6982
|
if (marks.has(key)) return busyAt(state, key);
|
|
6940
6983
|
if (tree === void 0 && up?.tree === void 0 && !parts.some((item) => item.key === key)) return void 0;
|
|
6941
|
-
if (
|
|
6984
|
+
if (openPoint !== void 0 || circular && circularRule(tree, key) !== void 0) return circularRead(state, key);
|
|
6942
6985
|
marks.set(key, BUSY);
|
|
6943
6986
|
demands.push({
|
|
6944
6987
|
cells: marks,
|
|
@@ -7270,6 +7313,26 @@ function isOp(value) {
|
|
|
7270
7313
|
return typeof value === "string" || Array.isArray(value) && value.every(isKey);
|
|
7271
7314
|
}
|
|
7272
7315
|
/**
|
|
7316
|
+
* This function gives the runner of an `if` with its own truth (RUN.IF-TRUTH). A branch can wait for the host, thus a
|
|
7317
|
+
* language with the function `truthy` of a profile does not need a copy of `if`. A missing test and a test without a
|
|
7318
|
+
* truth give `#VALUE!`, a failed test gives its failure, and a missing branch gives `null`.
|
|
7319
|
+
*
|
|
7320
|
+
* @param truth - The function that gives the truth of a value, or `undefined` for a value without a truth.
|
|
7321
|
+
* @returns The runner.
|
|
7322
|
+
*/
|
|
7323
|
+
function ifRunner(truth) {
|
|
7324
|
+
return function* ({ parts }) {
|
|
7325
|
+
const test = parts.find((part) => part.key === "test");
|
|
7326
|
+
if (test === void 0) return fail("#VALUE!", "if needs a test.");
|
|
7327
|
+
const chosen = yield* test.evaluate();
|
|
7328
|
+
if (!chosen.ok) return chosen;
|
|
7329
|
+
const held = truth(chosen.value);
|
|
7330
|
+
if (held === void 0) return fail("#VALUE!", "The test of if must give a truth value.");
|
|
7331
|
+
const branch = parts.find((part) => part.key === (held ? "then" : "else"));
|
|
7332
|
+
return branch === void 0 ? ok(null) : yield* branch.evaluate();
|
|
7333
|
+
};
|
|
7334
|
+
}
|
|
7335
|
+
/**
|
|
7273
7336
|
* The runners of the standard world, by name: the kinds that can hold effects. Each one evaluates its parts in
|
|
7274
7337
|
* order. In a run, an effect ends before the next step starts.
|
|
7275
7338
|
*/
|
|
@@ -7337,15 +7400,7 @@ const STD_RUNNERS = {
|
|
|
7337
7400
|
}
|
|
7338
7401
|
});
|
|
7339
7402
|
},
|
|
7340
|
-
"control.if":
|
|
7341
|
-
const test = parts.find((part) => part.key === "test");
|
|
7342
|
-
if (test === void 0) return fail("#VALUE!", "if needs a test.");
|
|
7343
|
-
const chosen = yield* test.evaluate();
|
|
7344
|
-
if (!chosen.ok) return chosen;
|
|
7345
|
-
if (typeof chosen.value !== "boolean") return fail("#VALUE!", "The test of if must give a truth value.");
|
|
7346
|
-
const branch = parts.find((part) => part.key === (chosen.value === true ? "then" : "else"));
|
|
7347
|
-
return branch === void 0 ? ok(null) : yield* branch.evaluate();
|
|
7348
|
-
},
|
|
7403
|
+
"control.if": /* @__PURE__ */ ifRunner((value) => typeof value === "boolean" ? value : void 0),
|
|
7349
7404
|
"list.all": function* ({ parts }) {
|
|
7350
7405
|
const all = yield* inOrder(parts);
|
|
7351
7406
|
return "error" in all ? all.error : ok(all.values);
|
|
@@ -7768,6 +7823,26 @@ const CONSTRUCTS = [
|
|
|
7768
7823
|
* narrows the capabilities for each part, thus the host does not give this type.
|
|
7769
7824
|
*/
|
|
7770
7825
|
const CAPS_TYPE = { list: { union: ["text", { list: { union: ["text", "number"] } }] } };
|
|
7826
|
+
/**
|
|
7827
|
+
* This function gives the boundaries of a check. A part with an imprecise type at a position that needs a type is a
|
|
7828
|
+
* boundary. A read of a known type is a boundary too, because the check trusts the root types (PLAN.GUARD-BOUNDARY).
|
|
7829
|
+
*
|
|
7830
|
+
* @param typing - The places of a check of types.
|
|
7831
|
+
* @param domains - The domains of the machine.
|
|
7832
|
+
* @returns The boundaries, in the order of the document.
|
|
7833
|
+
*/
|
|
7834
|
+
function boundariesOf(typing, domains) {
|
|
7835
|
+
const found = [];
|
|
7836
|
+
for (const item of typing.places) if (item.expected !== void 0 && item.expected !== "unknown" && !isPrecise(item.type, domains)) found.push({
|
|
7837
|
+
place: item.place,
|
|
7838
|
+
type: item.expected
|
|
7839
|
+
});
|
|
7840
|
+
else if (item.read === true && item.type !== "unknown") found.push({
|
|
7841
|
+
place: item.place,
|
|
7842
|
+
type: item.type
|
|
7843
|
+
});
|
|
7844
|
+
return found;
|
|
7845
|
+
}
|
|
7771
7846
|
/** The roots that can change, as a rule gives them in `PartType.roots`. */
|
|
7772
7847
|
const CHANGING = [
|
|
7773
7848
|
"self",
|
|
@@ -7787,7 +7862,7 @@ function pathKey(path) {
|
|
|
7787
7862
|
function ruleOf(machine, name) {
|
|
7788
7863
|
if (name === void 0 || machine.runners !== void 0 && Object.hasOwn(machine.runners, name)) return void 0;
|
|
7789
7864
|
const evaluator = Object.hasOwn(machine.evaluators, name) ? machine.evaluators[name] : void 0;
|
|
7790
|
-
const rule = typeof evaluator === "object" && evaluator !== null ? evaluator.type : void 0;
|
|
7865
|
+
const rule = typeof evaluator === "object" && evaluator !== null || typeof evaluator === "function" ? evaluator.type : void 0;
|
|
7791
7866
|
return typeof rule === "object" && rule !== null && typeof rule.synth === "function" ? rule : void 0;
|
|
7792
7867
|
}
|
|
7793
7868
|
/** This function gives the order of the parts of a document: first the parts that give the names of a rule `keysAt`. */
|
|
@@ -7968,9 +8043,11 @@ function typePass(machine, nodes, verb, expect, rootTypes = {}) {
|
|
|
7968
8043
|
}
|
|
7969
8044
|
const places = nodes.map((node, index) => {
|
|
7970
8045
|
const want = needed[index];
|
|
8046
|
+
const read = !node.marked && ruleOf(machine, node.evaluator)?.read === true;
|
|
7971
8047
|
const entry = {
|
|
7972
8048
|
type: types[index] ?? "unknown",
|
|
7973
|
-
...want === void 0 ? {} : { expected: want }
|
|
8049
|
+
...want === void 0 ? {} : { expected: want },
|
|
8050
|
+
...read ? { read } : {}
|
|
7974
8051
|
};
|
|
7975
8052
|
Object.defineProperty(entry, "place", {
|
|
7976
8053
|
enumerable: true,
|
|
@@ -9482,11 +9559,13 @@ function walk(world, doc, visit, options = {}) {
|
|
|
9482
9559
|
continue;
|
|
9483
9560
|
}
|
|
9484
9561
|
const { sees, later } = scopesOf(kind.scope, doc.value, split.parts);
|
|
9562
|
+
const grantRules = kind.caps !== void 0 && kind.caps.some((rule) => rule.rule === "grant") ? kind.caps : void 0;
|
|
9485
9563
|
for (let index = split.parts.length - 1; index >= 0; index -= 1) {
|
|
9486
9564
|
const slot = split.parts[index];
|
|
9487
9565
|
const extra = sees[index] ?? [];
|
|
9488
9566
|
const hidden = later[index] ?? [];
|
|
9489
|
-
const grants = partGrants(
|
|
9567
|
+
const grants = grantRules === void 0 ? void 0 : partGrants(grantRules, slot.path, doc.value);
|
|
9568
|
+
const granted = grants !== void 0 && grants.length > 0 ? grants : void 0;
|
|
9490
9569
|
stack.push({
|
|
9491
9570
|
value: slot.item,
|
|
9492
9571
|
place: slot.path.length === 0 ? item.place : {
|
|
@@ -9504,8 +9583,8 @@ function walk(world, doc, visit, options = {}) {
|
|
|
9504
9583
|
address: slot.address === true,
|
|
9505
9584
|
slot: slot.path,
|
|
9506
9585
|
parent: here,
|
|
9507
|
-
caps: item.caps === void 0 || kind.caps === void 0 ? item.caps : [...partCaps(kind.caps, slot.path, item.caps), ...
|
|
9508
|
-
handled:
|
|
9586
|
+
caps: item.caps === void 0 || kind.caps === void 0 ? item.caps : granted === void 0 ? partCaps(kind.caps, slot.path, item.caps) : [...partCaps(kind.caps, slot.path, item.caps), ...granted],
|
|
9587
|
+
handled: granted === void 0 ? item.handled : [...item.handled ?? [], ...granted],
|
|
9509
9588
|
bound: extra,
|
|
9510
9589
|
expect: slot.expect
|
|
9511
9590
|
});
|
|
@@ -9595,6 +9674,28 @@ function mapRefs(world, doc, change, options = {}) {
|
|
|
9595
9674
|
return out;
|
|
9596
9675
|
}
|
|
9597
9676
|
/**
|
|
9677
|
+
* This function changes the documents of a document, from the root to the parts (STATIC.MAPDOCS). The function
|
|
9678
|
+
* `change` reads only the original documents. It decides at each node, and it can stop at a node. The kinds of a
|
|
9679
|
+
* position come from the world, thus this function names no kind. The document is not changed: the function gives a
|
|
9680
|
+
* new document that shares each part without a change.
|
|
9681
|
+
*
|
|
9682
|
+
* @param world - The world of the kinds.
|
|
9683
|
+
* @param doc - The document, as JSON.
|
|
9684
|
+
* @param change - The function that gives the answer for each visit. See `DocChange`.
|
|
9685
|
+
* @param options - The type of a bare root value, and the names that the host binds at the root.
|
|
9686
|
+
* @returns The new document, or `doc` itself when no document changes.
|
|
9687
|
+
*/
|
|
9688
|
+
function mapDocs(world, doc, change, options = {}) {
|
|
9689
|
+
let out = doc;
|
|
9690
|
+
walk(world, doc, (visit) => {
|
|
9691
|
+
const next = change(visit);
|
|
9692
|
+
if (next === void 0 || next === "skip") return next;
|
|
9693
|
+
out = setAt(out, visit.at, next.to);
|
|
9694
|
+
return next.into === true ? void 0 : "skip";
|
|
9695
|
+
}, options);
|
|
9696
|
+
return out;
|
|
9697
|
+
}
|
|
9698
|
+
/**
|
|
9598
9699
|
* This function gives the parts that the code of a runner evaluates itself, without a wait (RUN.DRIVES, D119). The
|
|
9599
9700
|
* answer of the hook `facts` for the code wins over the contract. The contract describes only the code of its kind for
|
|
9600
9701
|
* `eval`. Without a declaration, the runner passes each wait of its parts through.
|
|
@@ -11161,39 +11262,42 @@ function formulaTypes(profile) {
|
|
|
11161
11262
|
});
|
|
11162
11263
|
return {
|
|
11163
11264
|
"formula.lit": { synth: (input) => valueType(input.doc.value) },
|
|
11164
|
-
"formula.ref": {
|
|
11165
|
-
|
|
11166
|
-
|
|
11167
|
-
|
|
11168
|
-
|
|
11169
|
-
|
|
11170
|
-
|
|
11171
|
-
|
|
11172
|
-
|
|
11173
|
-
if (
|
|
11174
|
-
|
|
11175
|
-
|
|
11176
|
-
|
|
11177
|
-
|
|
11178
|
-
|
|
11179
|
-
|
|
11180
|
-
|
|
11181
|
-
if (isUnknown(type, domains) || !plain && holdsEnvelope(type, domains)) return "unknown";
|
|
11182
|
-
if (index >= path.length) return type;
|
|
11183
|
-
const step = path[index];
|
|
11184
|
-
if (!isKey(step)) {
|
|
11185
|
-
type = walkType(input, step, type);
|
|
11186
|
-
continue;
|
|
11265
|
+
"formula.ref": {
|
|
11266
|
+
read: true,
|
|
11267
|
+
synth: (input, report) => {
|
|
11268
|
+
const path = input.doc.value;
|
|
11269
|
+
if (input.address || !Array.isArray(path) || path.length === 0) return "unknown";
|
|
11270
|
+
const domains = input.machine.domains;
|
|
11271
|
+
const plain = input.machine.plain === true;
|
|
11272
|
+
let type;
|
|
11273
|
+
let start;
|
|
11274
|
+
if (path[0] === "names") {
|
|
11275
|
+
const name = path[1];
|
|
11276
|
+
if (!isKey(name) || !plain && HEADER_KEYS.has(String(name))) return "unknown";
|
|
11277
|
+
type = input.nameType(String(name)) ?? "unknown";
|
|
11278
|
+
start = 2;
|
|
11279
|
+
} else {
|
|
11280
|
+
type = input.rootType(String(path[0]));
|
|
11281
|
+
start = 1;
|
|
11187
11282
|
}
|
|
11188
|
-
|
|
11189
|
-
|
|
11190
|
-
|
|
11191
|
-
|
|
11192
|
-
|
|
11283
|
+
for (let index = start;; index += 1) {
|
|
11284
|
+
if (isUnknown(type, domains) || !plain && holdsEnvelope(type, domains)) return "unknown";
|
|
11285
|
+
if (index >= path.length) return type;
|
|
11286
|
+
const step = path[index];
|
|
11287
|
+
if (!isKey(step)) {
|
|
11288
|
+
type = walkType(input, step, type);
|
|
11289
|
+
continue;
|
|
11290
|
+
}
|
|
11291
|
+
const next = stepType(type, step, domains, input.contract);
|
|
11292
|
+
if ("missing" in next) {
|
|
11293
|
+
const fields = next.missing.length === 0 ? "" : ` Its fields are ${listText(next.missing)}.`;
|
|
11294
|
+
report({ reason: `The value at ${path.slice(0, index).map(stepText).join(".")} has no field ${String(step)}.${fields}` });
|
|
11295
|
+
return "unknown";
|
|
11296
|
+
}
|
|
11297
|
+
type = next.type;
|
|
11193
11298
|
}
|
|
11194
|
-
type = next.type;
|
|
11195
11299
|
}
|
|
11196
|
-
}
|
|
11300
|
+
},
|
|
11197
11301
|
"formula.record": {
|
|
11198
11302
|
part: (input, path) => {
|
|
11199
11303
|
const want = fieldOf(input.expected, String(path[0]), input.machine.domains);
|
|
@@ -14702,6 +14806,14 @@ function readsUnknown(reads) {
|
|
|
14702
14806
|
function resolutions(reads) {
|
|
14703
14807
|
return reads.filter((read) => read.free && read.kept !== true);
|
|
14704
14808
|
}
|
|
14809
|
+
/** This function gives the text of a value of a trace. It does not throw for a bigint or a record with a cycle. */
|
|
14810
|
+
function valueText$1(value) {
|
|
14811
|
+
try {
|
|
14812
|
+
return JSON.stringify(value) ?? describe(value);
|
|
14813
|
+
} catch {
|
|
14814
|
+
return describe(value);
|
|
14815
|
+
}
|
|
14816
|
+
}
|
|
14705
14817
|
function pathText(path) {
|
|
14706
14818
|
if (path === void 0) return "no read";
|
|
14707
14819
|
try {
|
|
@@ -14857,6 +14969,96 @@ async function agreeRun(machine, doc, context = makeContext(), options = {}) {
|
|
|
14857
14969
|
reads: compared
|
|
14858
14970
|
};
|
|
14859
14971
|
}
|
|
14972
|
+
/** The type errors of the kernel, by the evaluator that gives them (STATIC.TYPES-AGREE). */
|
|
14973
|
+
const TYPE_ERRORS = {
|
|
14974
|
+
"formula.op": "#NAME?",
|
|
14975
|
+
"formula.if": "#VALUE!",
|
|
14976
|
+
"formula.and": "#VALUE!",
|
|
14977
|
+
"formula.or": "#VALUE!"
|
|
14978
|
+
};
|
|
14979
|
+
/**
|
|
14980
|
+
* This function examines the agreement rule for types (STATIC.TYPES-AGREE, D148). A document with no issue evaluates
|
|
14981
|
+
* with a trace. Each value of the trace is a member of the type of its place. A value of a precise type is also a member
|
|
14982
|
+
* of the type that its position needs. No document with precise parts gives a type error of the kernel.
|
|
14983
|
+
*
|
|
14984
|
+
* A language imports this function for its own property tests, with `agree`. A failure tells that a signature, a type
|
|
14985
|
+
* rule, a cover or a root type does not hold. A value that breaks a position of an imprecise type ends the promise, and
|
|
14986
|
+
* the result then has `checked: false` (TYPE.GRADUAL).
|
|
14987
|
+
*
|
|
14988
|
+
* @param machine - The world and the code of the evaluators, with their type rules.
|
|
14989
|
+
* @param doc - The document.
|
|
14990
|
+
* @param context - The context. Its roots are members of the root types.
|
|
14991
|
+
* @param options - The options of `check`, with the root types, and `guards`.
|
|
14992
|
+
* @returns The agreement, or the first place that breaks it.
|
|
14993
|
+
*/
|
|
14994
|
+
function agreeTypes(machine, doc, context = makeContext(), options = {}) {
|
|
14995
|
+
const typing = typeCheck(machine, doc, options);
|
|
14996
|
+
if (typing.issues.length > 0) return {
|
|
14997
|
+
ok: true,
|
|
14998
|
+
checked: false,
|
|
14999
|
+
values: 0
|
|
15000
|
+
};
|
|
15001
|
+
const keyOf = (path) => JSON.stringify(path.map(String));
|
|
15002
|
+
const places = new Map(typing.places.map((item) => [keyOf(item.place), item]));
|
|
15003
|
+
const domains = machine.domains;
|
|
15004
|
+
const guards = options.guards === true ? boundariesOf(typing, domains) : void 0;
|
|
15005
|
+
const stack = [evaluate(machine, doc, context, {
|
|
15006
|
+
...options.declaredType === void 0 ? {} : { declaredType: options.declaredType },
|
|
15007
|
+
...guards === void 0 ? {} : { guards }
|
|
15008
|
+
}).trace];
|
|
15009
|
+
const nodes = [];
|
|
15010
|
+
while (stack.length > 0) {
|
|
15011
|
+
const node = stack.pop();
|
|
15012
|
+
nodes.push(node);
|
|
15013
|
+
stack.push(...node.children);
|
|
15014
|
+
}
|
|
15015
|
+
for (const node of nodes) {
|
|
15016
|
+
const place = places.get(keyOf(node.path));
|
|
15017
|
+
if (place?.expected === void 0 || !node.result.ok || isPrecise(place.type, domains)) continue;
|
|
15018
|
+
if (!member(node.result.value, place.expected, domains)) return {
|
|
15019
|
+
ok: true,
|
|
15020
|
+
checked: false,
|
|
15021
|
+
values: 0
|
|
15022
|
+
};
|
|
15023
|
+
}
|
|
15024
|
+
let values = 0;
|
|
15025
|
+
for (const node of nodes.reverse()) {
|
|
15026
|
+
const place = places.get(keyOf(node.path));
|
|
15027
|
+
if (place === void 0) continue;
|
|
15028
|
+
const at = node.path.map(String);
|
|
15029
|
+
if (!node.result.ok) {
|
|
15030
|
+
const parts = node.children.map((child) => places.get(keyOf(child.path)));
|
|
15031
|
+
const decided = node.children.every((child) => child.result.ok) && parts.every((part) => part?.expected !== void 0 && isPrecise(part.type, domains));
|
|
15032
|
+
const code = TYPE_ERRORS[node.answer.evaluator ?? ""];
|
|
15033
|
+
if (decided && node.result.error.code === code) return {
|
|
15034
|
+
ok: false,
|
|
15035
|
+
clause: "error",
|
|
15036
|
+
place: at,
|
|
15037
|
+
reason: `The document gives ${code}, but it checks with no issue.`
|
|
15038
|
+
};
|
|
15039
|
+
continue;
|
|
15040
|
+
}
|
|
15041
|
+
const value = node.result.value;
|
|
15042
|
+
values += 1;
|
|
15043
|
+
if (!member(value, place.type, domains)) return {
|
|
15044
|
+
ok: false,
|
|
15045
|
+
clause: "value",
|
|
15046
|
+
place: at,
|
|
15047
|
+
reason: `The value ${valueText$1(value)} is not a member of ${typeText(place.type)}.`
|
|
15048
|
+
};
|
|
15049
|
+
if (place.expected !== void 0 && !member(value, place.expected, domains)) return {
|
|
15050
|
+
ok: false,
|
|
15051
|
+
clause: "argument",
|
|
15052
|
+
place: at,
|
|
15053
|
+
reason: `The value ${valueText$1(value)} is not a member of the needed type ${typeText(place.expected)}.`
|
|
15054
|
+
};
|
|
15055
|
+
}
|
|
15056
|
+
return {
|
|
15057
|
+
ok: true,
|
|
15058
|
+
checked: true,
|
|
15059
|
+
values
|
|
15060
|
+
};
|
|
15061
|
+
}
|
|
14860
15062
|
// src/codec-laws.ts
|
|
14861
15063
|
/** The order of the laws in the list of findings. */
|
|
14862
15064
|
const ORDER$1 = [
|
|
@@ -15280,6 +15482,13 @@ function compileConstructs(given, ops) {
|
|
|
15280
15482
|
constructKinds
|
|
15281
15483
|
};
|
|
15282
15484
|
}
|
|
15485
|
+
/** This function examines the field `domain` of a call form (D141). A form `literal` of `ext.domain` needs a name, and each other form refuses it. */
|
|
15486
|
+
function compileDomain(given, args) {
|
|
15487
|
+
const writes = args === "literal" && given.kind === "ext.domain";
|
|
15488
|
+
if (writes && (typeof given.domain !== "string" || given.domain === "")) throw new TypeError(`The call form "${given.name}" of ext.domain needs the name of its domain.`);
|
|
15489
|
+
if (!writes && given.domain !== void 0) throw new TypeError(`The call form "${given.name}" takes no domain: only a form literal of ext.domain has one.`);
|
|
15490
|
+
return given.domain;
|
|
15491
|
+
}
|
|
15283
15492
|
/** This function examines the field `wrap` of a call form (K159). A name that is not a field of the form throws. */
|
|
15284
15493
|
function compileWrap(given, args) {
|
|
15285
15494
|
const wrap = given.wrap;
|
|
@@ -15291,6 +15500,16 @@ function compileWrap(given, args) {
|
|
|
15291
15500
|
return new Set(wrap);
|
|
15292
15501
|
}
|
|
15293
15502
|
/** This function gives the types of the data envelopes of a profile (K159), or `undefined` without them. */
|
|
15503
|
+
/** This function examines the field `data` of a call form (D177). Each name is a field of the form, and no name is in `wrap`. */
|
|
15504
|
+
function compileData(given, wrap) {
|
|
15505
|
+
const data = given.data ?? [];
|
|
15506
|
+
if (data.length > 0 && given.fields === void 0) throw new TypeError(`The call form "${given.name}" takes data only with fields.`);
|
|
15507
|
+
for (const name of data) {
|
|
15508
|
+
if (given.fields?.includes(name) !== true) throw new TypeError(`The call form "${given.name}" has no field ${name} for its data.`);
|
|
15509
|
+
if (wrap === true || wrap !== false && wrap.has(name)) throw new TypeError(`The call form "${given.name}" has the field ${name} in wrap and in data.`);
|
|
15510
|
+
}
|
|
15511
|
+
return new Set(data);
|
|
15512
|
+
}
|
|
15294
15513
|
function compileEnvelopes(given) {
|
|
15295
15514
|
if (given === void 0) return void 0;
|
|
15296
15515
|
const out = {};
|
|
@@ -15327,17 +15546,22 @@ function compileProfile(profile) {
|
|
|
15327
15546
|
if (!FORM_ARGS.includes(args)) throw new TypeError(`The call form "${given.name}" has the unknown arguments ${String(args)}.`);
|
|
15328
15547
|
if (args === "fields" !== (given.fields !== void 0) && args !== "named") throw new TypeError(`The call form "${given.name}" with the arguments ${args} ${args === "fields" ? "needs" : "takes no"} fields.`);
|
|
15329
15548
|
if (given.min !== void 0 && (args === "named" || args === "literal")) throw new TypeError(`The call form "${given.name}" with the arguments ${args} takes no min.`);
|
|
15549
|
+
const wrap = compileWrap(given, args);
|
|
15330
15550
|
const form = {
|
|
15331
15551
|
name: given.name,
|
|
15332
15552
|
type,
|
|
15333
15553
|
args,
|
|
15334
15554
|
fields: given.fields,
|
|
15335
15555
|
min: given.min ?? given.fields?.length ?? 0,
|
|
15336
|
-
wrap
|
|
15556
|
+
wrap,
|
|
15557
|
+
domain: compileDomain(given, args),
|
|
15558
|
+
data: compileData(given, wrap)
|
|
15337
15559
|
};
|
|
15338
15560
|
forms.set(form.name, form);
|
|
15339
15561
|
addTo(formsByKind, key, form);
|
|
15340
15562
|
}
|
|
15563
|
+
const brackets = [...forms.values()].some((form) => form.data.size > 0);
|
|
15564
|
+
for (const symbol of brackets ? [...ops.prefixSymbols, ...ops.binarySymbols] : []) if (/^[[\]{}]/.test(symbol)) throw new TypeError(`The operator "${symbol}" reads the text of a field of data.`);
|
|
15341
15565
|
const compiled = {
|
|
15342
15566
|
...ops,
|
|
15343
15567
|
numbers: literals.numbers ?? true,
|
|
@@ -15369,7 +15593,8 @@ function compileProfile(profile) {
|
|
|
15369
15593
|
...ops.opWords,
|
|
15370
15594
|
...roots
|
|
15371
15595
|
]),
|
|
15372
|
-
maxDepth: profile.maxDepth ?? 256
|
|
15596
|
+
maxDepth: profile.maxDepth ?? 256,
|
|
15597
|
+
brackets
|
|
15373
15598
|
};
|
|
15374
15599
|
compiledProfiles.set(profile, compiled);
|
|
15375
15600
|
return compiled;
|
|
@@ -15828,7 +16053,7 @@ var Parser = class {
|
|
|
15828
16053
|
}
|
|
15829
16054
|
/** This method stops at a token where a group or a list must end. A list can also continue with its separator. */
|
|
15830
16055
|
noEnd(close, list) {
|
|
15831
|
-
const closer = close
|
|
16056
|
+
const closer = closerName(close);
|
|
15832
16057
|
const before = list ? `"${this.syn.separator}" or a ` : "";
|
|
15833
16058
|
return this.stop(`A ${before}closing ${closer} is missing.`, this.pos, this.tokenLength());
|
|
15834
16059
|
}
|
|
@@ -15853,16 +16078,31 @@ var Parser = class {
|
|
|
15853
16078
|
this.pos += 1;
|
|
15854
16079
|
return args;
|
|
15855
16080
|
}
|
|
15856
|
-
if (this.pos >= this.text.length) this.stop(`A closing ${close
|
|
16081
|
+
if (this.pos >= this.text.length) this.stop(`A closing ${closerName(close)} is missing.`, open, 1);
|
|
15857
16082
|
this.noEnd(close, true);
|
|
15858
16083
|
}
|
|
15859
16084
|
}
|
|
15860
16085
|
/**
|
|
15861
|
-
* This method reads the
|
|
15862
|
-
*
|
|
16086
|
+
* This method reads the argument of a field of data (D177): a list between brackets, a record between braces, or a
|
|
16087
|
+
* document. A literal in it stays its data.
|
|
16088
|
+
*/
|
|
16089
|
+
data() {
|
|
16090
|
+
this.skip();
|
|
16091
|
+
const start = this.pos;
|
|
16092
|
+
const c = this.text[start];
|
|
16093
|
+
if (c !== "[" && c !== "{") return this.bound();
|
|
16094
|
+
this.depth += 1;
|
|
16095
|
+
if (this.depth > this.syn.maxDepth) this.stop(`The text is deeper than ${String(this.syn.maxDepth)} levels.`, start, 0);
|
|
16096
|
+
const value = c === "[" ? this.argumentsOf(() => this.data(), "]") : this.entries(void 0, true);
|
|
16097
|
+
this.depth -= 1;
|
|
16098
|
+
return value;
|
|
16099
|
+
}
|
|
16100
|
+
/**
|
|
16101
|
+
* This method reads the entries `key: expr` into a record. The record is the arguments of a form `named`
|
|
16102
|
+
* (SYNTAX.RECORD), or the entries between braces (SYNTAX.RECORD-TEXT). It is also a record of data (D177).
|
|
15863
16103
|
*/
|
|
15864
|
-
entries(form) {
|
|
15865
|
-
const owner = form === void 0 ? "record" : `form ${form.name}`;
|
|
16104
|
+
entries(form, data = false) {
|
|
16105
|
+
const owner = data ? "record of data" : form === void 0 ? "record" : `form ${form.name}`;
|
|
15866
16106
|
const value = {};
|
|
15867
16107
|
const entry = () => {
|
|
15868
16108
|
this.skip();
|
|
@@ -15872,9 +16112,10 @@ var Parser = class {
|
|
|
15872
16112
|
this.skip();
|
|
15873
16113
|
if (key === void 0 || this.text[this.pos] !== ":") this.stop(`Each ${form === void 0 ? "entry" : "argument"} of the ${owner} is a key, a ":" and a document.`, at, Math.max(end - at, this.tokenLength()));
|
|
15874
16114
|
if (form?.fields !== void 0 && !form.fields.includes(key)) this.stop(`The form ${form.name} has no field ${key}.`, at, end - at);
|
|
16115
|
+
if (data && key === "type") this.stop("A record of data has no key type, because the key type makes a document.", at, end - at);
|
|
15875
16116
|
if (Object.hasOwn(value, key)) this.stop(`The ${owner} has the field ${key} two times.`, at, end - at);
|
|
15876
16117
|
this.pos += 1;
|
|
15877
|
-
const arg = this.bound();
|
|
16118
|
+
const arg = data || form?.data.has(key) === true ? this.data() : this.bound();
|
|
15878
16119
|
setOwn$1(value, key, form !== void 0 && wraps(form, key) ? envelop(this.syn, arg) : arg);
|
|
15879
16120
|
};
|
|
15880
16121
|
this.argumentsOf(entry, form === void 0 ? "}" : ")");
|
|
@@ -15883,11 +16124,19 @@ var Parser = class {
|
|
|
15883
16124
|
call(name, start, nameLength) {
|
|
15884
16125
|
const form = this.syn.forms.get(name);
|
|
15885
16126
|
if (form?.args === "named") return opDoc(form, this.entries(form));
|
|
15886
|
-
|
|
16127
|
+
let index = 0;
|
|
16128
|
+
const args = this.argumentsOf(() => {
|
|
16129
|
+
const key = form?.fields?.[index];
|
|
16130
|
+
index += 1;
|
|
16131
|
+
return key !== void 0 && form?.data.has(key) === true ? this.data() : this.bound();
|
|
16132
|
+
});
|
|
15887
16133
|
if (form?.args === "literal") {
|
|
15888
16134
|
const [only] = args;
|
|
15889
16135
|
if (args.length !== 1 || !isScalar(only)) this.stop(`The form ${name} takes one literal that JSON writes.`, start, this.pos - start);
|
|
15890
|
-
return opDoc(form, only
|
|
16136
|
+
return opDoc(form, form.domain === void 0 ? only : {
|
|
16137
|
+
domain: form.domain,
|
|
16138
|
+
data: only
|
|
16139
|
+
});
|
|
15891
16140
|
}
|
|
15892
16141
|
if (form !== void 0) {
|
|
15893
16142
|
const most = form.fields?.length ?? Number.POSITIVE_INFINITY;
|
|
@@ -15913,15 +16162,20 @@ var Parser = class {
|
|
|
15913
16162
|
/** The end of a recovery. The class `Recovery` throws it, and its method `run` catches it. */
|
|
15914
16163
|
var End = class {};
|
|
15915
16164
|
function hasBraces(syn) {
|
|
15916
|
-
return syn.constructs.record !== void 0 || syn.constructs.let !== void 0;
|
|
16165
|
+
return syn.constructs.record !== void 0 || syn.constructs.let !== void 0 || syn.brackets;
|
|
16166
|
+
}
|
|
16167
|
+
/** This function gives the name of a closer in a message. */
|
|
16168
|
+
function closerName(close) {
|
|
16169
|
+
return close === ")" ? "parenthesis" : close === "]" ? "bracket" : "brace";
|
|
15917
16170
|
}
|
|
15918
16171
|
/** This function gives the closer of an opening bracket of a profile, or `undefined` for each other character. */
|
|
15919
16172
|
function closerOf(syn, c) {
|
|
15920
16173
|
if (c === "(") return ")";
|
|
16174
|
+
if (c === "[" && syn.brackets) return "]";
|
|
15921
16175
|
return c === "{" && hasBraces(syn) ? "}" : void 0;
|
|
15922
16176
|
}
|
|
15923
16177
|
function isCloser(syn, c) {
|
|
15924
|
-
return c === ")" || c === "}" && hasBraces(syn);
|
|
16178
|
+
return c === ")" || c === "]" && syn.brackets || c === "}" && hasBraces(syn);
|
|
15925
16179
|
}
|
|
15926
16180
|
/** This function gives the position after a quoted text at `at`, or after one other character. An open quote gives `Infinity`. */
|
|
15927
16181
|
function pastToken(syn, text, at) {
|
|
@@ -16164,6 +16418,7 @@ function refShape(syn, value) {
|
|
|
16164
16418
|
}
|
|
16165
16419
|
function callName(syn, keys) {
|
|
16166
16420
|
if (keys.length === 0 || !keys.every((key) => typeof key === "string" && NAME.test(key))) return void 0;
|
|
16421
|
+
if (keys.length > 1 && !syn.fields) return void 0;
|
|
16167
16422
|
const name = keys.join(".");
|
|
16168
16423
|
if (syn.forms.has(name) || syn.opWords.has(keys[0])) return void 0;
|
|
16169
16424
|
return syn.ops === true || syn.ops.has(name) ? name : void 0;
|
|
@@ -16186,10 +16441,16 @@ function wrappedShape(syn, doc) {
|
|
|
16186
16441
|
const literal = literalShape(syn, doc.value);
|
|
16187
16442
|
return literal.tag === "text" ? literal : void 0;
|
|
16188
16443
|
}
|
|
16444
|
+
/** This function tells if a value of `ext.domain` is a record with this domain and its data, and no other key. */
|
|
16445
|
+
function holdsDomain(value, domain) {
|
|
16446
|
+
return isRecord(value) && value["domain"] === domain && Object.hasOwn(value, "data") && Object.keys(value).length === 2;
|
|
16447
|
+
}
|
|
16189
16448
|
function formShape(syn, form, value) {
|
|
16190
16449
|
if (form.args === "literal") {
|
|
16191
|
-
if (!
|
|
16192
|
-
const
|
|
16450
|
+
if (form.domain !== void 0 && !holdsDomain(value, form.domain)) return void 0;
|
|
16451
|
+
const data = form.domain === void 0 ? value : value["data"];
|
|
16452
|
+
if (!isScalar(data)) return void 0;
|
|
16453
|
+
const literal = literalShape(syn, data);
|
|
16193
16454
|
return literal.tag === "text" ? {
|
|
16194
16455
|
tag: "text",
|
|
16195
16456
|
text: `${form.name}(${literal.text})`
|
|
@@ -16205,7 +16466,8 @@ function formShape(syn, form, value) {
|
|
|
16205
16466
|
args: keys.map((key) => [
|
|
16206
16467
|
key,
|
|
16207
16468
|
value[key],
|
|
16208
|
-
wraps(form, key)
|
|
16469
|
+
wraps(form, key),
|
|
16470
|
+
form.data.has(key)
|
|
16209
16471
|
]),
|
|
16210
16472
|
named: true
|
|
16211
16473
|
};
|
|
@@ -16232,7 +16494,8 @@ function formShape(syn, form, value) {
|
|
|
16232
16494
|
args: present.map((key) => [
|
|
16233
16495
|
key,
|
|
16234
16496
|
value[key],
|
|
16235
|
-
wraps(form, key)
|
|
16497
|
+
wraps(form, key),
|
|
16498
|
+
form.data.has(key)
|
|
16236
16499
|
])
|
|
16237
16500
|
};
|
|
16238
16501
|
}
|
|
@@ -16368,6 +16631,18 @@ function bracesText(syn, record, path, sub) {
|
|
|
16368
16631
|
if (!texts.ok) return texts;
|
|
16369
16632
|
return ok(`{${texts.value.map((text, index) => `${keyText(keys[index])}: ${text}`).join(`${syn.separator} `)}}`);
|
|
16370
16633
|
}
|
|
16634
|
+
/**
|
|
16635
|
+
* This function writes the argument of a field of data (D177): a list between brackets, or a record between braces.
|
|
16636
|
+
* The function `sub` writes a literal and a document. A record that is an envelope is a document.
|
|
16637
|
+
*/
|
|
16638
|
+
function dataText(syn, value, path, sub) {
|
|
16639
|
+
const each = (child, at) => dataText(syn, child, at, sub);
|
|
16640
|
+
if (Array.isArray(value)) {
|
|
16641
|
+
const texts = partTexts(value.map((item, index) => [index, item]), path, each);
|
|
16642
|
+
return texts.ok ? ok(`[${texts.value.join(`${syn.separator} `)}]`) : texts;
|
|
16643
|
+
}
|
|
16644
|
+
return isRecord(value) && !isEnvelope(value) && !Object.hasOwn(value, "type") ? bracesText(syn, value, path, each) : sub(value, path);
|
|
16645
|
+
}
|
|
16371
16646
|
/** This function writes a construct form (K145). */
|
|
16372
16647
|
function constructText(syn, shape, sub) {
|
|
16373
16648
|
if (shape.tag === "record") return bracesText(syn, shape.entries, [], sub);
|
|
@@ -16410,8 +16685,8 @@ function printNode(syn, doc, sub) {
|
|
|
16410
16685
|
return ok(texts.join("."));
|
|
16411
16686
|
}
|
|
16412
16687
|
const texts = [];
|
|
16413
|
-
for (const [key, arg, wrapped] of shape.args) {
|
|
16414
|
-
const result = sub(arg, [key], wrapped);
|
|
16688
|
+
for (const [key, arg, wrapped, data] of shape.args) {
|
|
16689
|
+
const result = data === true ? dataText(syn, arg, [key], sub) : sub(arg, [key], wrapped);
|
|
16415
16690
|
if (!result.ok) return result;
|
|
16416
16691
|
texts.push(shape.named === true ? `${keyText(String(key))}: ${result.value}` : result.value);
|
|
16417
16692
|
}
|
|
@@ -19286,6 +19561,7 @@ function schedule(machine, options = {}) {
|
|
|
19286
19561
|
let keptAt = -1;
|
|
19287
19562
|
const keptNodes = [];
|
|
19288
19563
|
let keptMet = false;
|
|
19564
|
+
let keptFrom = 0;
|
|
19289
19565
|
let count = 0;
|
|
19290
19566
|
let ahead = 0;
|
|
19291
19567
|
let wanted;
|
|
@@ -19356,7 +19632,10 @@ function schedule(machine, options = {}) {
|
|
|
19356
19632
|
const reader = stack[stack.length - 1];
|
|
19357
19633
|
const known = epoch.values.get(id);
|
|
19358
19634
|
if (known !== void 0) {
|
|
19359
|
-
if (reader !== void 0 && onOpen.has(id))
|
|
19635
|
+
if (reader !== void 0 && onOpen.has(id)) {
|
|
19636
|
+
if (keptAt >= 0 && order.get(id) < keptFrom) keptMet = true;
|
|
19637
|
+
else lower(reader, order.get(id));
|
|
19638
|
+
}
|
|
19360
19639
|
return known;
|
|
19361
19640
|
}
|
|
19362
19641
|
if (busy.has(id)) {
|
|
@@ -19560,9 +19839,11 @@ function schedule(machine, options = {}) {
|
|
|
19560
19839
|
keeping(read) {
|
|
19561
19840
|
const outer = keptAt;
|
|
19562
19841
|
const outerMet = keptMet;
|
|
19842
|
+
const outerFrom = keptFrom;
|
|
19563
19843
|
const from = keptNodes.length;
|
|
19564
19844
|
keptAt = stack.length;
|
|
19565
19845
|
keptMet = false;
|
|
19846
|
+
keptFrom = count;
|
|
19566
19847
|
try {
|
|
19567
19848
|
return read();
|
|
19568
19849
|
} finally {
|
|
@@ -19573,6 +19854,7 @@ function schedule(machine, options = {}) {
|
|
|
19573
19854
|
}
|
|
19574
19855
|
keptAt = outer;
|
|
19575
19856
|
keptMet = outerMet;
|
|
19857
|
+
keptFrom = outerFrom;
|
|
19576
19858
|
}
|
|
19577
19859
|
}
|
|
19578
19860
|
});
|
|
@@ -20556,6 +20838,6 @@ function samplesAt(values, closed, depth) {
|
|
|
20556
20838
|
function typeFromSamples(values, options = {}) {
|
|
20557
20839
|
return samplesAt(values, options.closed === true, 0);
|
|
20558
20840
|
}
|
|
20559
|
-
export { ATTRIBUTE_RUNGS, CAPS_TYPE, CIRCULAR_LIMIT, CONSTRUCTS, ENVELOPE_KEYS, Failure, GENERATION_LIMIT, Held, JOURNAL, MAX_SYNTAX_ISSUES, 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, WORLD_SYNTAX, agree, agreeRun, agreeSchedule, argsKey, ask, atArgsOf, atRuleOf, attributeGraph, attributeTrace, attributeVertexId, capKeys, check, checkCycles, checkLatent, checkStep, checkSteps, checkSyntax, checkWorld, circularOf, classify, codecLaws, collectOf, compilePath, components, conforms, context, cycles, dataEdges, decodeDomain, decodeLog, decodeValue, derefStep, describe, docEquals, documentKey, durable, edgesOf, effectEdges, effectsOf, effectsOfVerb, encodeLog, 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, isStep, isTypeRef, join, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapRefs, member, mergeMachines, mergeWorlds, narrow, nearestWalker, necessary, nodeAt, nodeLayers, ok, parse, partCaps, partGrants, partsOf, pathMatches, permits, placeOf, placed, planner, prepare, print, printReads, random, recorder, ref, reference, referenceRun, refsOf, replayer, resolve, resolveCompiled, restrictMachine, restrictWorld, run, sameResult, sameValue, schedule, splitParts, stepLadder, stepOf, stepRank, stored, syntaxFormat, tag, thrown, toJson, treeNodeEvaluator, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
|
|
20841
|
+
export { ATTRIBUTE_RUNGS, CAPS_TYPE, CIRCULAR_LIMIT, CONSTRUCTS, ENVELOPE_KEYS, Failure, GENERATION_LIMIT, Held, JOURNAL, MAX_SYNTAX_ISSUES, 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, WORLD_SYNTAX, agree, agreeRun, agreeSchedule, agreeTypes, argsKey, ask, atArgsOf, atRuleOf, attributeGraph, attributeTrace, attributeVertexId, boundariesOf, capKeys, check, checkCycles, checkLatent, checkStep, checkSteps, checkSyntax, checkWorld, circularOf, classify, codecLaws, collectOf, compilePath, components, conforms, context, cycles, dataEdges, decodeDomain, decodeLog, decodeValue, derefStep, describe, docEquals, documentKey, durable, edgesOf, effectEdges, effectsOf, effectsOfVerb, encodeLog, encodeValue, entriesAsJson, equationType, evaluate, extendDomain, factsOf, fail, failures, field, fits, flatten, formulaDefinitions, formulaEvaluators, formulaFacts, formulaKinds, formulaKnown, formulaMachine, fromJson, generate, heights, ifRunner, intersectCaps, isAlias, isAllowedOrder, isClosure, isEnvelope, isHostThing, isKey, isKind, isNamespace, isRecord, isRef, isStackOverflow, isStep, isTypeRef, join, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapDocs, mapRefs, member, mergeMachines, mergeWorlds, narrow, nearestWalker, necessary, nodeAt, nodeLayers, ok, parse, partCaps, partGrants, partsOf, pathMatches, permits, placeOf, placed, planner, prepare, print, printReads, random, recorder, ref, reference, referenceRun, refsOf, replayer, resolve, resolveCompiled, restrictMachine, restrictWorld, run, sameResult, sameValue, schedule, splitParts, stepLadder, stepOf, stepRank, stored, syntaxFormat, tag, thrown, toJson, treeNodeEvaluator, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
|
|
20560
20842
|
|
|
20561
20843
|
//# sourceMappingURL=index.js.map
|