@mark1russell7/coeval 0.21.0 → 0.22.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 +62 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +421 -35
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/formula.ts +22 -5
- package/src/index.ts +6 -0
- package/src/instances.ts +45 -5
- package/src/reference.ts +68 -8
- package/src/static.ts +70 -9
- package/src/stdlib.ts +103 -2
- package/src/world.ts +85 -1
package/build/index.js
CHANGED
|
@@ -428,6 +428,92 @@ function collectOf(declared) {
|
|
|
428
428
|
};
|
|
429
429
|
}
|
|
430
430
|
/**
|
|
431
|
+
* This function reads an entry of the table `tree.at` (D124). The tree kit, the reference, `check` and the graph of
|
|
432
|
+
* attribute instances read it with this one function.
|
|
433
|
+
*
|
|
434
|
+
* @param declared - The entry.
|
|
435
|
+
* @returns The rule, or the reason when the entry has no correct form.
|
|
436
|
+
*/
|
|
437
|
+
function atRuleOf(declared) {
|
|
438
|
+
const params = isRecord(declared) ? field(declared, "params") : void 0;
|
|
439
|
+
if (!(Array.isArray(params) && params.every((name, index) => typeof name === "string" && params.indexOf(name) === index)) || !Object.hasOwn(declared, "equation")) return {
|
|
440
|
+
ok: false,
|
|
441
|
+
reason: "An entry of tree.at needs a list params of different texts and the field equation."
|
|
442
|
+
};
|
|
443
|
+
return {
|
|
444
|
+
ok: true,
|
|
445
|
+
params,
|
|
446
|
+
equation: field(declared, "equation")
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* This function examines the arguments of a step `tree.at` (D124). The step gives an argument for each parameter, and
|
|
451
|
+
* no other argument. Each argument is JSON data. The key is the text of `argsKey`, thus two equal arguments give one key.
|
|
452
|
+
*
|
|
453
|
+
* @param params - The parameters of the attribute.
|
|
454
|
+
* @param args - The field `args` of the step.
|
|
455
|
+
* @returns The names of the equation and the key, or the reason.
|
|
456
|
+
*/
|
|
457
|
+
function atArgsOf(params, args) {
|
|
458
|
+
if (!isRecord(args)) return {
|
|
459
|
+
ok: false,
|
|
460
|
+
reason: "The arguments are a record."
|
|
461
|
+
};
|
|
462
|
+
const extra = Object.keys(args).find((name) => !params.includes(name));
|
|
463
|
+
if (extra !== void 0) return {
|
|
464
|
+
ok: false,
|
|
465
|
+
reason: `The attribute has no parameter ${extra}.`
|
|
466
|
+
};
|
|
467
|
+
const names = {};
|
|
468
|
+
for (const name of params) {
|
|
469
|
+
if (!Object.hasOwn(args, name)) return {
|
|
470
|
+
ok: false,
|
|
471
|
+
reason: `The step gives no argument ${name}.`
|
|
472
|
+
};
|
|
473
|
+
const value = field(args, name);
|
|
474
|
+
if (argsKey(value) === void 0) return {
|
|
475
|
+
ok: false,
|
|
476
|
+
reason: `The argument ${name} is not JSON data.`
|
|
477
|
+
};
|
|
478
|
+
Object.defineProperty(names, name, {
|
|
479
|
+
value,
|
|
480
|
+
enumerable: true,
|
|
481
|
+
writable: true,
|
|
482
|
+
configurable: true
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
return {
|
|
486
|
+
ok: true,
|
|
487
|
+
names,
|
|
488
|
+
key: argsKey(names)
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* This function gives the key of a JSON value (D124). The fields of a record are in the order of their names. Two
|
|
493
|
+
* values have the same key only when they are equal by DOC.EQUALS, thus `-0` and `0` have different keys.
|
|
494
|
+
*
|
|
495
|
+
* @param value - The value.
|
|
496
|
+
* @returns The JSON text, or `undefined` for a value that is not JSON data: a number that is not finite, a host value or a cycle.
|
|
497
|
+
*/
|
|
498
|
+
function argsKey(value) {
|
|
499
|
+
return keyOf$1(value, /* @__PURE__ */ new Set());
|
|
500
|
+
}
|
|
501
|
+
function keyOf$1(value, open) {
|
|
502
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") return JSON.stringify(value);
|
|
503
|
+
if (typeof value === "number") return !Number.isFinite(value) ? void 0 : Object.is(value, -0) ? "-0" : JSON.stringify(value);
|
|
504
|
+
if (typeof value !== "object" || open.has(value) || !Array.isArray(value) && !isRecord(value)) return void 0;
|
|
505
|
+
open.add(value);
|
|
506
|
+
try {
|
|
507
|
+
const list = Array.isArray(value);
|
|
508
|
+
const names = list ? [] : Object.keys(value).sort();
|
|
509
|
+
const items = list ? value.map((item) => keyOf$1(item, open)) : names.map((name) => keyOf$1(field(value, name), open));
|
|
510
|
+
if (items.includes(void 0)) return void 0;
|
|
511
|
+
return list ? `[${items.join(",")}]` : `{${names.map((name, index) => `${JSON.stringify(name)}:${String(items[index])}`).join(",")}}`;
|
|
512
|
+
} finally {
|
|
513
|
+
open.delete(value);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
431
517
|
* 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
|
|
432
518
|
* else the type `of` of the shape `rest` of a record. The plan, the reference and `check` read it with this one function.
|
|
433
519
|
*
|
|
@@ -5484,14 +5570,24 @@ const STD_WORLD = {
|
|
|
5484
5570
|
pure: true,
|
|
5485
5571
|
summary: "A step of a path: it follows a key again and again, until it reaches a node of a type."
|
|
5486
5572
|
},
|
|
5487
|
-
tree: { kinds: {
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5573
|
+
tree: { kinds: {
|
|
5574
|
+
named: {
|
|
5575
|
+
verbs: {
|
|
5576
|
+
step: "walk.named",
|
|
5577
|
+
view: "view.card"
|
|
5578
|
+
},
|
|
5579
|
+
pure: true,
|
|
5580
|
+
summary: "A step of a path: it goes up to the nearest registry of names, and it gives the node with the name (TREE.NAMED)."
|
|
5491
5581
|
},
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5582
|
+
at: {
|
|
5583
|
+
verbs: {
|
|
5584
|
+
step: "walk.tree.at",
|
|
5585
|
+
view: "view.card"
|
|
5586
|
+
},
|
|
5587
|
+
pure: true,
|
|
5588
|
+
summary: "A step of a path: it reads an attribute with parameters of the node before it, with the arguments of the step (TREE.AT)."
|
|
5589
|
+
}
|
|
5590
|
+
} },
|
|
5495
5591
|
panel: {
|
|
5496
5592
|
verbs: {
|
|
5497
5593
|
eval: "tree.node",
|
|
@@ -5737,6 +5833,12 @@ const WORLD_SYNTAX = /* @__PURE__ */ Object.freeze({
|
|
|
5737
5833
|
args: "named",
|
|
5738
5834
|
fields: ["name", "in"]
|
|
5739
5835
|
},
|
|
5836
|
+
{
|
|
5837
|
+
name: "tree.at",
|
|
5838
|
+
kind: "tree.at",
|
|
5839
|
+
args: "named",
|
|
5840
|
+
fields: ["attr", "args"]
|
|
5841
|
+
},
|
|
5740
5842
|
{
|
|
5741
5843
|
name: "add",
|
|
5742
5844
|
kind: "add"
|
|
@@ -6328,6 +6430,80 @@ function collected(root, key, declared) {
|
|
|
6328
6430
|
return acc;
|
|
6329
6431
|
}
|
|
6330
6432
|
/**
|
|
6433
|
+
* The host things that answer the step `tree.at` with their own function (D124). A node of the reference is in it, and
|
|
6434
|
+
* its fields do not change. The walker reads the state of a node of the kit.
|
|
6435
|
+
*/
|
|
6436
|
+
const AT_READERS = /* @__PURE__ */ new WeakMap();
|
|
6437
|
+
/** The memo of the instances of the attributes with parameters of each node, without the cells of a host (TREE.AT). */
|
|
6438
|
+
const atMemos = /* @__PURE__ */ new WeakMap();
|
|
6439
|
+
/** The second key of each key of a node, for the cells of the attributes with parameters (TREE.AT-CELL). */
|
|
6440
|
+
const atPlaces = /* @__PURE__ */ new WeakMap();
|
|
6441
|
+
/**
|
|
6442
|
+
* This function gives an instance of an attribute with parameters of a node (TREE.AT, D124). The equation in
|
|
6443
|
+
* `tree.at` of the kind of the node evaluates with the arguments as names. The memo keeps one result for each key of
|
|
6444
|
+
* the arguments, and a demand of an instance in evaluation gives `#CYCLE!`. The function is outside the code of
|
|
6445
|
+
* `read`, thus a node without such attributes does no new work.
|
|
6446
|
+
*/
|
|
6447
|
+
function atRead(n, attr, args) {
|
|
6448
|
+
const declared = entryOf(n.tree?.at, attr);
|
|
6449
|
+
if (declared === void 0) return void 0;
|
|
6450
|
+
const rule = atRuleOf(declared);
|
|
6451
|
+
if (!rule.ok) return fail("#VALUE!", `The attribute ${attributeText(attr, n.type, n.place)} has a bad entry tree.at. ${rule.reason}`);
|
|
6452
|
+
const given = atArgsOf(rule.params, args);
|
|
6453
|
+
if (!given.ok) return fail("#VALUE!", `The step tree.at of ${attributeText(attr, n.type, n.place)} has bad arguments. ${given.reason}`);
|
|
6454
|
+
const host = openPoint === void 0 ? n.host : void 0;
|
|
6455
|
+
const place = n.host === void 0 ? n.place : keptAt(atPlaces, n.place, () => Object.freeze([...n.place]));
|
|
6456
|
+
let marks = n.host === void 0 ? atMemos.get(n) : keptAt(marksByPlace, place, () => /* @__PURE__ */ new Map());
|
|
6457
|
+
if (marks === void 0) {
|
|
6458
|
+
marks = /* @__PURE__ */ new Map();
|
|
6459
|
+
atMemos.set(n, marks);
|
|
6460
|
+
}
|
|
6461
|
+
const key = `[${JSON.stringify(attr)},${given.key}]`;
|
|
6462
|
+
const text = attributeText(`${attr} with ${given.key}`, n.type, n.place);
|
|
6463
|
+
const cell = marks.get(key);
|
|
6464
|
+
if (cell !== void 0) return cell.busy ? cycleAt(marks, key, text) : cell.result;
|
|
6465
|
+
const demand = {
|
|
6466
|
+
cells: marks,
|
|
6467
|
+
key,
|
|
6468
|
+
text
|
|
6469
|
+
};
|
|
6470
|
+
const loop = openPoint;
|
|
6471
|
+
const compute = () => ({
|
|
6472
|
+
result: n.equation(rule.equation, given.names),
|
|
6473
|
+
by: "kind"
|
|
6474
|
+
});
|
|
6475
|
+
marks.set(key, BUSY);
|
|
6476
|
+
demands.push(demand);
|
|
6477
|
+
let thrown = NOT_THROWN;
|
|
6478
|
+
let answer;
|
|
6479
|
+
try {
|
|
6480
|
+
answer = host === void 0 ? compute() : host(place, key, () => {
|
|
6481
|
+
try {
|
|
6482
|
+
return compute();
|
|
6483
|
+
} catch (error) {
|
|
6484
|
+
thrown = error;
|
|
6485
|
+
throw error;
|
|
6486
|
+
}
|
|
6487
|
+
});
|
|
6488
|
+
} catch (error) {
|
|
6489
|
+
marks.delete(key);
|
|
6490
|
+
if (host === void 0 || error === thrown) throw error;
|
|
6491
|
+
answer = {
|
|
6492
|
+
result: fail("#CYCLE!", `The cells of the host found a cycle in the demands: ${demands.map((item) => item.text).join(" -> ")}.`, { cause: error }),
|
|
6493
|
+
by: void 0
|
|
6494
|
+
};
|
|
6495
|
+
} finally {
|
|
6496
|
+
demands.pop();
|
|
6497
|
+
}
|
|
6498
|
+
if (n.host !== void 0 || loop?.tentative.has(demand) === true) marks.delete(key);
|
|
6499
|
+
else marks.set(key, {
|
|
6500
|
+
busy: false,
|
|
6501
|
+
result: answer.result,
|
|
6502
|
+
by: answer.by
|
|
6503
|
+
});
|
|
6504
|
+
return answer.result;
|
|
6505
|
+
}
|
|
6506
|
+
/**
|
|
6331
6507
|
* This function makes a node of the decorated tree. A step `parent` gives the self of the context of the node, and a
|
|
6332
6508
|
* step `type` gives its type. Another step reads an attribute through its ladder (TREE.LADDER). The rungs are a part of
|
|
6333
6509
|
* the node, an equation of its kind and an equation `down` of the kind of its parent. A copy from the parent, then a
|
|
@@ -6702,10 +6878,40 @@ const named$2 = ({ data, here, deref }) => {
|
|
|
6702
6878
|
reason: `No registry ${registry} is on the way.`
|
|
6703
6879
|
};
|
|
6704
6880
|
};
|
|
6881
|
+
/**
|
|
6882
|
+
* The walker of the step `tree.at` (TREE.AT, D124). The field `attr` names an attribute with parameters, and the
|
|
6883
|
+
* field `args` gives the arguments. The thing before the step is a node. A failed instance throws its own error.
|
|
6884
|
+
*/
|
|
6885
|
+
const at = ({ data, here }) => {
|
|
6886
|
+
const attr = isRecord(data) ? field(data, "attr") : void 0;
|
|
6887
|
+
if (typeof attr !== "string") return {
|
|
6888
|
+
ok: false,
|
|
6889
|
+
code: "#VALUE!",
|
|
6890
|
+
reason: "The step tree.at needs a text attr."
|
|
6891
|
+
};
|
|
6892
|
+
const args = isRecord(data) && Object.hasOwn(data, "args") ? field(data, "args") : {};
|
|
6893
|
+
const state = stateOf(here);
|
|
6894
|
+
const reader = state === void 0 && typeof here === "object" && here !== null ? AT_READERS.get(here) : void 0;
|
|
6895
|
+
if (state === void 0 && reader === void 0) return {
|
|
6896
|
+
ok: false,
|
|
6897
|
+
reason: `The step tree.at reads ${attr} of a thing that is not a node of a tree.`
|
|
6898
|
+
};
|
|
6899
|
+
const result = state === void 0 ? reader(attr, args) : atRead(state, attr, args);
|
|
6900
|
+
if (result === void 0) return {
|
|
6901
|
+
ok: false,
|
|
6902
|
+
reason: `No rung gives the attribute ${attr} with parameters.`
|
|
6903
|
+
};
|
|
6904
|
+
if (!result.ok) throw new Failure(result.error);
|
|
6905
|
+
return {
|
|
6906
|
+
ok: true,
|
|
6907
|
+
thing: result.value
|
|
6908
|
+
};
|
|
6909
|
+
};
|
|
6705
6910
|
/** The walkers of the standard world, by name. */
|
|
6706
6911
|
const STD_WALKERS = {
|
|
6707
6912
|
"walk.nearest": nearest,
|
|
6708
|
-
"walk.named": named$2
|
|
6913
|
+
"walk.named": named$2,
|
|
6914
|
+
"walk.tree.at": at
|
|
6709
6915
|
};
|
|
6710
6916
|
/** This function evaluates parts one after the other, and stops at the first error. */
|
|
6711
6917
|
function* inOrder(parts) {
|
|
@@ -8163,6 +8369,25 @@ function vertexOf(b, node, attribute) {
|
|
|
8163
8369
|
}
|
|
8164
8370
|
return id;
|
|
8165
8371
|
}
|
|
8372
|
+
/**
|
|
8373
|
+
* This function gives the vertex of an instance of an attribute with parameters (TREE.AT-CHECK, D124). Its name is the
|
|
8374
|
+
* name of a plain vertex with the key of the arguments after the name of the attribute.
|
|
8375
|
+
*/
|
|
8376
|
+
function atVertexOf(b, node, at) {
|
|
8377
|
+
const id = `${attributeVertexId(node.visit.place, at.attr).slice(0, -1)},${at.key}]`;
|
|
8378
|
+
if (!b.vertices.has(id)) {
|
|
8379
|
+
b.vertices.set(id, {
|
|
8380
|
+
id,
|
|
8381
|
+
place: node.visit.place,
|
|
8382
|
+
attribute: at.attr,
|
|
8383
|
+
type: node.text,
|
|
8384
|
+
args: at.names
|
|
8385
|
+
});
|
|
8386
|
+
b.nodes.set(id, node);
|
|
8387
|
+
b.work.push(id);
|
|
8388
|
+
}
|
|
8389
|
+
return id;
|
|
8390
|
+
}
|
|
8166
8391
|
function edge(b, from, r, lazy = false) {
|
|
8167
8392
|
b.edges.push({
|
|
8168
8393
|
from,
|
|
@@ -8252,6 +8477,14 @@ function follow(b, start, path, from, r) {
|
|
|
8252
8477
|
}
|
|
8253
8478
|
continue;
|
|
8254
8479
|
}
|
|
8480
|
+
if (isAtStep(b.machine, step)) {
|
|
8481
|
+
const at = atStepOf(node.kind, node.text, step.value);
|
|
8482
|
+
if (at.kind === "unknown") edge(b, void 0, r);
|
|
8483
|
+
if (at.kind !== "exact") return;
|
|
8484
|
+
edge(b, atVertexOf(b, node, at), r);
|
|
8485
|
+
here = "unknown";
|
|
8486
|
+
continue;
|
|
8487
|
+
}
|
|
8255
8488
|
if (walkerOf(b.machine, step) !== STD_WALKERS["walk.nearest"]) {
|
|
8256
8489
|
edge(b, void 0, r);
|
|
8257
8490
|
return;
|
|
@@ -8327,7 +8560,10 @@ function termReads(b, refs, self, names, r) {
|
|
|
8327
8560
|
const name = String(ref.path[1]);
|
|
8328
8561
|
let start;
|
|
8329
8562
|
if (ref.bound.has(name)) start = "unknown";
|
|
8330
|
-
else if (names?.
|
|
8563
|
+
else if (names?.params !== void 0) {
|
|
8564
|
+
if (!names.params.includes(name)) continue;
|
|
8565
|
+
start = "data";
|
|
8566
|
+
} else if (names?.child !== void 0 && name === "child") start = { node: names.child };
|
|
8331
8567
|
else if (names?.prev !== void 0 && name === "prev") start = names.prev;
|
|
8332
8568
|
else if (name === "index") start = "data";
|
|
8333
8569
|
else if (name === "acc" || name === "item") start = "unknown";
|
|
@@ -8351,7 +8587,8 @@ function prevOf(parent, child) {
|
|
|
8351
8587
|
*/
|
|
8352
8588
|
function rungReads(b, id) {
|
|
8353
8589
|
const node = b.nodes.get(id);
|
|
8354
|
-
const
|
|
8590
|
+
const vertex = b.vertices.get(id);
|
|
8591
|
+
const key = vertex.attribute;
|
|
8355
8592
|
const tree = node.kind.tree;
|
|
8356
8593
|
const r = {
|
|
8357
8594
|
to: id,
|
|
@@ -8359,6 +8596,14 @@ function rungReads(b, id) {
|
|
|
8359
8596
|
place: node.visit.place,
|
|
8360
8597
|
at: node.visit.at
|
|
8361
8598
|
};
|
|
8599
|
+
if (vertex.args !== void 0) {
|
|
8600
|
+
const at = atStepOf(node.kind, node.text, {
|
|
8601
|
+
attr: key,
|
|
8602
|
+
args: vertex.args
|
|
8603
|
+
});
|
|
8604
|
+
if (at.kind === "exact") termReads(b, termRefs(b, node.kind, `tree.at.${key}`, at.equation), node, { params: at.params }, r);
|
|
8605
|
+
return;
|
|
8606
|
+
}
|
|
8362
8607
|
const equation = hasOwnEntry(tree?.equations, key) ? tree?.equations?.[key] : void 0;
|
|
8363
8608
|
if (equation !== void 0) {
|
|
8364
8609
|
termReads(b, termRefs(b, node.kind, `tree.equations.${key}`, equation), node, void 0, r);
|
|
@@ -8622,7 +8867,7 @@ function allCircular(b, ids) {
|
|
|
8622
8867
|
return ids.every((id) => b.vertices.get(id)?.circular === true);
|
|
8623
8868
|
}
|
|
8624
8869
|
function vertexText(vertex) {
|
|
8625
|
-
return `${vertex.attribute} of ${vertex.type} at [${vertex.place.join(", ")}]`;
|
|
8870
|
+
return `${vertex.args === void 0 ? vertex.attribute : `${vertex.attribute} with ${String(argsKey(vertex.args))}`} of ${vertex.type} at [${vertex.place.join(", ")}]`;
|
|
8626
8871
|
}
|
|
8627
8872
|
/**
|
|
8628
8873
|
* This function finds each certain cycle of the attributes of a document before a run (TREE.GRAPH-CYCLE, D107). A run
|
|
@@ -9228,6 +9473,17 @@ function equationsOf(kind) {
|
|
|
9228
9473
|
down: false,
|
|
9229
9474
|
contributes: true
|
|
9230
9475
|
});
|
|
9476
|
+
for (const [name, declared] of Object.entries(tree.at ?? {})) {
|
|
9477
|
+
const rule = atRuleOf(declared);
|
|
9478
|
+
if (rule.ok) out.push({
|
|
9479
|
+
label: `tree.at.${name}`,
|
|
9480
|
+
term: rule.equation,
|
|
9481
|
+
names: rule.params,
|
|
9482
|
+
attribute: name,
|
|
9483
|
+
down: false,
|
|
9484
|
+
at: true
|
|
9485
|
+
});
|
|
9486
|
+
}
|
|
9231
9487
|
return out;
|
|
9232
9488
|
}
|
|
9233
9489
|
/**
|
|
@@ -9373,7 +9629,7 @@ function equationIssues(machine, kind, kindText, options, state) {
|
|
|
9373
9629
|
own: void 0,
|
|
9374
9630
|
parent: void 0
|
|
9375
9631
|
};
|
|
9376
|
-
for (const { label, term, names, attribute, down, contributes } of equationsOf(kind)) {
|
|
9632
|
+
for (const { label, term, names, attribute, down, contributes, at } of equationsOf(kind)) {
|
|
9377
9633
|
const inner = {
|
|
9378
9634
|
names,
|
|
9379
9635
|
...of === void 0 ? {} : { declaredType: of },
|
|
@@ -9383,7 +9639,7 @@ function equationIssues(machine, kind, kindText, options, state) {
|
|
|
9383
9639
|
needs.push({
|
|
9384
9640
|
name,
|
|
9385
9641
|
why: `the equation ${label} reads it`,
|
|
9386
|
-
hidden: down || contributes === true ? void 0 : attribute
|
|
9642
|
+
hidden: down || contributes === true || at === true ? void 0 : attribute
|
|
9387
9643
|
});
|
|
9388
9644
|
};
|
|
9389
9645
|
for (const issue of checkAll(machine, term, inner, void 0, state, {
|
|
@@ -9401,7 +9657,7 @@ function equationIssues(machine, kind, kindText, options, state) {
|
|
|
9401
9657
|
* This function finds the issues of the contract of a tree kind (TREE.CHECK-RESERVED). An attribute with the name of a
|
|
9402
9658
|
* structural step gets no read. A tree kind of the run side contradicts the evaluation on demand of its attributes. A
|
|
9403
9659
|
* declaration `circular` without a start value or with a bad limit gives `#VALUE!` (TREE.CIRCULAR-CHECK). A declaration
|
|
9404
|
-
* `collect` without its form gives `#VALUE!` too (TREE.COLLECT).
|
|
9660
|
+
* `collect` without its form gives `#VALUE!` too (TREE.COLLECT). So does an entry of `at` without its form (TREE.AT-CHECK).
|
|
9405
9661
|
*/
|
|
9406
9662
|
function contractIssues(kind, kindText) {
|
|
9407
9663
|
const out = [];
|
|
@@ -9410,7 +9666,8 @@ function contractIssues(kind, kindText) {
|
|
|
9410
9666
|
"equations",
|
|
9411
9667
|
"down",
|
|
9412
9668
|
"attributes",
|
|
9413
|
-
"contributes"
|
|
9669
|
+
"contributes",
|
|
9670
|
+
"at"
|
|
9414
9671
|
]) for (const name of Object.keys(tree?.[table] ?? {})) {
|
|
9415
9672
|
const why = Object.hasOwn(STRUCTURAL, name) ? STRUCTURAL[name] : void 0;
|
|
9416
9673
|
if (why !== void 0) out.push({
|
|
@@ -9433,6 +9690,14 @@ function contractIssues(kind, kindText) {
|
|
|
9433
9690
|
reason: `The kind ${kindText} has a bad declaration tree.attributes.${name}.collect. ${collect.reason}`
|
|
9434
9691
|
});
|
|
9435
9692
|
}
|
|
9693
|
+
for (const [name, declared] of Object.entries(tree?.at ?? {})) {
|
|
9694
|
+
const rule = atRuleOf(declared);
|
|
9695
|
+
if (!rule.ok) out.push({
|
|
9696
|
+
code: "#VALUE!",
|
|
9697
|
+
place: [],
|
|
9698
|
+
reason: `The kind ${kindText} has a bad entry tree.at.${name}. ${rule.reason}`
|
|
9699
|
+
});
|
|
9700
|
+
}
|
|
9436
9701
|
if (kind.side === "run") out.push({
|
|
9437
9702
|
code: "#CALC!",
|
|
9438
9703
|
place: [],
|
|
@@ -9478,7 +9743,7 @@ function nodeIssues(machine, node, state, v) {
|
|
|
9478
9743
|
* This function examines a reference from the root `self` (TREE.CHECK-UNKNOWN). The steps `parent` go up the known
|
|
9479
9744
|
* nodes. The first other key names an attribute of the node that they reach. When no rung answers the attribute, the
|
|
9480
9745
|
* function gives the index of the step and the reason. In an equation, a read of the node of the equation goes to the
|
|
9481
|
-
* needs of its kind.
|
|
9746
|
+
* needs of its kind. A step `tree.at` with literal arguments gets the checks of TREE.AT-CHECK.
|
|
9482
9747
|
*/
|
|
9483
9748
|
function readIssue(machine, self, path, rootSelf) {
|
|
9484
9749
|
let node = self;
|
|
@@ -9488,6 +9753,14 @@ function readIssue(machine, self, path, rootSelf) {
|
|
|
9488
9753
|
index += 1;
|
|
9489
9754
|
}
|
|
9490
9755
|
const step = path[index];
|
|
9756
|
+
if (node !== void 0 && isAtStep(machine, step)) {
|
|
9757
|
+
const at = atStepOf(node.kind, node.text, step.value);
|
|
9758
|
+
return at.kind === "issue" ? {
|
|
9759
|
+
index,
|
|
9760
|
+
reason: at.reason,
|
|
9761
|
+
code: at.code
|
|
9762
|
+
} : void 0;
|
|
9763
|
+
}
|
|
9491
9764
|
if (node === void 0 || !isKey(step) || Object.hasOwn(STRUCTURAL, String(step))) return void 0;
|
|
9492
9765
|
const name = String(step);
|
|
9493
9766
|
if (node.own === void 0) {
|
|
@@ -9499,6 +9772,52 @@ function readIssue(machine, self, path, rootSelf) {
|
|
|
9499
9772
|
reason: `No rung gives the attribute ${name} of the kind ${node.text}.`
|
|
9500
9773
|
};
|
|
9501
9774
|
}
|
|
9775
|
+
/** This function tells if a step of a path is a step `tree.at` of the standard walker (TREE.AT, D124). */
|
|
9776
|
+
function isAtStep(machine, step) {
|
|
9777
|
+
return isEnvelope(step) && walkerOf(machine, step) === STD_WALKERS["walk.tree.at"];
|
|
9778
|
+
}
|
|
9779
|
+
/**
|
|
9780
|
+
* This function examines the data of a step `tree.at` on a node of a known kind (TREE.AT-CHECK, D124). `check` and the
|
|
9781
|
+
* graph of attribute instances read the step with this one function.
|
|
9782
|
+
*/
|
|
9783
|
+
function atStepOf(kind, kindText, data) {
|
|
9784
|
+
if (holdsDocument(data)) return { kind: "unknown" };
|
|
9785
|
+
const attr = isRecord(data) ? field(data, "attr") : void 0;
|
|
9786
|
+
if (typeof attr !== "string") return {
|
|
9787
|
+
kind: "issue",
|
|
9788
|
+
code: "#VALUE!",
|
|
9789
|
+
reason: "The step tree.at needs a text attr."
|
|
9790
|
+
};
|
|
9791
|
+
const table = kind.tree?.at;
|
|
9792
|
+
const declared = table !== void 0 && Object.hasOwn(table, attr) ? table[attr] : void 0;
|
|
9793
|
+
if (declared === void 0) return {
|
|
9794
|
+
kind: "issue",
|
|
9795
|
+
code: "#N/A",
|
|
9796
|
+
reason: `No rung gives the attribute ${attr} with parameters of the kind ${kindText}.`
|
|
9797
|
+
};
|
|
9798
|
+
const rule = atRuleOf(declared);
|
|
9799
|
+
if (!rule.ok) return { kind: "unknown" };
|
|
9800
|
+
const given = atArgsOf(rule.params, isRecord(data) && Object.hasOwn(data, "args") ? field(data, "args") : {});
|
|
9801
|
+
if (!given.ok) return {
|
|
9802
|
+
kind: "issue",
|
|
9803
|
+
code: "#VALUE!",
|
|
9804
|
+
reason: `The step tree.at of ${attr} of the kind ${kindText} has bad arguments. ${given.reason}`
|
|
9805
|
+
};
|
|
9806
|
+
return {
|
|
9807
|
+
kind: "exact",
|
|
9808
|
+
attr,
|
|
9809
|
+
key: given.key,
|
|
9810
|
+
equation: rule.equation,
|
|
9811
|
+
params: rule.params,
|
|
9812
|
+
names: given.names
|
|
9813
|
+
};
|
|
9814
|
+
}
|
|
9815
|
+
/** This function tells if a value holds a document. A document in the data of a step can be a part, thus only the run knows its value. */
|
|
9816
|
+
function holdsDocument(value) {
|
|
9817
|
+
if (isEnvelope(value)) return true;
|
|
9818
|
+
if (Array.isArray(value)) return value.some(holdsDocument);
|
|
9819
|
+
return isRecord(value) && Object.values(value).some(holdsDocument);
|
|
9820
|
+
}
|
|
9502
9821
|
/**
|
|
9503
9822
|
* This function finds the issues of `check`. With a list of nodes, it also records each document that it visits for
|
|
9504
9823
|
* the pass of types. It marks each document with an issue. The state holds the kinds whose equations the check
|
|
@@ -9685,7 +10004,7 @@ function checkAll(machine, doc, options, nodes, state = {
|
|
|
9685
10004
|
if (attributes && root === "self" && v.address !== true && name === "ref.resolve") {
|
|
9686
10005
|
const issue = readIssue(machine, self, path, rootSelf);
|
|
9687
10006
|
if (issue !== void 0) push({
|
|
9688
|
-
code: "#N/A",
|
|
10007
|
+
code: issue.code ?? "#N/A",
|
|
9689
10008
|
place: v.place,
|
|
9690
10009
|
reason: issue.reason,
|
|
9691
10010
|
at: stepAt(issue.index)
|
|
@@ -10928,17 +11247,26 @@ function formulaCode(profile) {
|
|
|
10928
11247
|
}
|
|
10929
11248
|
return known;
|
|
10930
11249
|
};
|
|
11250
|
+
const limit = Math.ceil((machine.maxDepth ?? 1e3) / 4);
|
|
10931
11251
|
return (ctx, rt) => {
|
|
10932
11252
|
rt.keepsContext?.(ctx, reads);
|
|
11253
|
+
const clock = rt;
|
|
10933
11254
|
const closure = (...args) => {
|
|
10934
|
-
const
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
names
|
|
10939
|
-
|
|
10940
|
-
|
|
10941
|
-
|
|
11255
|
+
const level = (clock.applying ?? 0) + 1;
|
|
11256
|
+
if (level > limit) throw new Failure(fail("#DEPTH!", `The applications of functions nest deeper than ${limit} levels.`).error);
|
|
11257
|
+
clock.applying = level;
|
|
11258
|
+
try {
|
|
11259
|
+
const scope = { ...ctx.names };
|
|
11260
|
+
names.forEach((name, index) => setOwn$2(scope, name, args[index]));
|
|
11261
|
+
const result = body.code({
|
|
11262
|
+
...ctx,
|
|
11263
|
+
names: scope
|
|
11264
|
+
}, rt);
|
|
11265
|
+
if (!result.ok) throw new Failure(result.error);
|
|
11266
|
+
return result.value;
|
|
11267
|
+
} finally {
|
|
11268
|
+
clock.applying = level - 1;
|
|
11269
|
+
}
|
|
10942
11270
|
};
|
|
10943
11271
|
Object.defineProperty(closure, CLOSURE$2, { value: { params: names } });
|
|
10944
11272
|
return ok(closure);
|
|
@@ -12825,6 +13153,7 @@ function envOf(machine, options, running, root, outer) {
|
|
|
12825
13153
|
alls: 0
|
|
12826
13154
|
},
|
|
12827
13155
|
held: 0,
|
|
13156
|
+
applying: 0,
|
|
12828
13157
|
reading: outer ?? (options.reads === void 0 ? void 0 : {
|
|
12829
13158
|
list: options.reads,
|
|
12830
13159
|
root
|
|
@@ -13175,6 +13504,51 @@ function attributeOf(node, name) {
|
|
|
13175
13504
|
if (!entry.tentative && result !== void 0) node.values.set(name, result);
|
|
13176
13505
|
return result;
|
|
13177
13506
|
}
|
|
13507
|
+
/** TREE.AT: the instances of each node of the reference. Two arguments are the same instance by DOC.EQUALS. */
|
|
13508
|
+
const refInstances = /* @__PURE__ */ new WeakMap();
|
|
13509
|
+
/**
|
|
13510
|
+
* TREE.AT: the instance of an attribute with parameters, or `undefined` when the kind has no entry in `tree.at`. The
|
|
13511
|
+
* equation sees the arguments as names. A demand of an instance in evaluation gives `#CYCLE!`, also in a fixed point.
|
|
13512
|
+
*/
|
|
13513
|
+
function instanceOf$1(node, attr, args) {
|
|
13514
|
+
const declared = termIn(node.contract?.at, attr);
|
|
13515
|
+
if (declared === void 0) return void 0;
|
|
13516
|
+
const rule = atRuleOf(declared);
|
|
13517
|
+
if (!rule.ok) return fail("#VALUE!", `The attribute ${nameOfAttribute(node, attr)} has a bad entry tree.at. ${rule.reason}`);
|
|
13518
|
+
const given = atArgsOf(rule.params, args);
|
|
13519
|
+
if (!given.ok) return fail("#VALUE!", `The step tree.at of ${nameOfAttribute(node, attr)} has bad arguments. ${given.reason}`);
|
|
13520
|
+
const name = `${attr} with ${given.key}`;
|
|
13521
|
+
const list = refInstances.get(node) ?? [];
|
|
13522
|
+
refInstances.set(node, list);
|
|
13523
|
+
const found = list.find((item) => item.attr === attr && docEquals(item.names, given.names));
|
|
13524
|
+
if (found?.result !== void 0) return found.result;
|
|
13525
|
+
if (found !== void 0) {
|
|
13526
|
+
const from = inEvaluation.findIndex((entry) => entry.node === node && entry.name === name);
|
|
13527
|
+
return fail("#CYCLE!", `The attributes form a cycle: ${[...inEvaluation.slice(from).map((entry) => nameOfAttribute(entry.node, entry.name)), nameOfAttribute(node, name)].join(" -> ")}.`);
|
|
13528
|
+
}
|
|
13529
|
+
const item = {
|
|
13530
|
+
attr,
|
|
13531
|
+
names: given.names,
|
|
13532
|
+
result: void 0
|
|
13533
|
+
};
|
|
13534
|
+
list.push(item);
|
|
13535
|
+
const entry = {
|
|
13536
|
+
node,
|
|
13537
|
+
name,
|
|
13538
|
+
circular: false,
|
|
13539
|
+
tentative: false
|
|
13540
|
+
};
|
|
13541
|
+
inEvaluation.push(entry);
|
|
13542
|
+
let result;
|
|
13543
|
+
try {
|
|
13544
|
+
result = equationOf(node, rule.equation, given.names);
|
|
13545
|
+
} finally {
|
|
13546
|
+
inEvaluation.pop();
|
|
13547
|
+
if (result === void 0 || entry.tentative) list.splice(list.indexOf(item), 1);
|
|
13548
|
+
else item.result = result;
|
|
13549
|
+
}
|
|
13550
|
+
return result;
|
|
13551
|
+
}
|
|
13178
13552
|
/** TREE.RESULT: the JSON of a node. `open` holds the nodes and the containers whose JSON is in progress. */
|
|
13179
13553
|
function jsonOfNode(node, self, open) {
|
|
13180
13554
|
const record = {};
|
|
@@ -13261,6 +13635,7 @@ const treeDefinition = ({ parts, context, kind, place, machine, typePath, resolv
|
|
|
13261
13635
|
};
|
|
13262
13636
|
node.thing = self;
|
|
13263
13637
|
refNodes.set(self, node);
|
|
13638
|
+
AT_READERS.set(self, (attr, args) => instanceOf$1(node, attr, args));
|
|
13264
13639
|
if (nested) return ok(self);
|
|
13265
13640
|
try {
|
|
13266
13641
|
return jsonOfNode(node, self, []);
|
|
@@ -13387,16 +13762,27 @@ function formulaDefinitions(profile = {}) {
|
|
|
13387
13762
|
if (!Array.isArray(params) || !params.every((param) => typeof param === "string") || new Set(params).size !== params.length) return fail("#VALUE!", "The params of fn are a list of different texts.");
|
|
13388
13763
|
const names = params;
|
|
13389
13764
|
const body = partNamed(parts, "body");
|
|
13765
|
+
const clock = activeEnvs[activeEnvs.length - 1] ?? {
|
|
13766
|
+
applying: 0,
|
|
13767
|
+
maxDepth: 1e3
|
|
13768
|
+
};
|
|
13769
|
+
const limit = Math.ceil(clock.maxDepth / 4);
|
|
13390
13770
|
const closure = (...args) => {
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
names
|
|
13397
|
-
|
|
13398
|
-
|
|
13399
|
-
|
|
13771
|
+
if (clock.applying >= limit) throw new Failure(fail("#DEPTH!", `The applications of functions nest deeper than ${limit} levels.`).error);
|
|
13772
|
+
clock.applying += 1;
|
|
13773
|
+
try {
|
|
13774
|
+
const scope = {};
|
|
13775
|
+
for (const key of Object.keys(context.names)) setField$1(scope, key, context.names[key]);
|
|
13776
|
+
names.forEach((name, index) => setField$1(scope, name, args[index]));
|
|
13777
|
+
const result = body.evaluate({
|
|
13778
|
+
...context,
|
|
13779
|
+
names: scope
|
|
13780
|
+
});
|
|
13781
|
+
if (!result.ok) throw new Failure(result.error);
|
|
13782
|
+
return result.value;
|
|
13783
|
+
} finally {
|
|
13784
|
+
clock.applying -= 1;
|
|
13785
|
+
}
|
|
13400
13786
|
};
|
|
13401
13787
|
Object.defineProperty(closure, CLOSURE$1, { value: { params: names } });
|
|
13402
13788
|
return ok(closure);
|
|
@@ -18002,6 +18388,6 @@ function samplesAt(values, closed, depth) {
|
|
|
18002
18388
|
function typeFromSamples(values, options = {}) {
|
|
18003
18389
|
return samplesAt(values, options.closed === true, 0);
|
|
18004
18390
|
}
|
|
18005
|
-
export { ATTRIBUTE_RUNGS, CAPS_TYPE, CIRCULAR_LIMIT, 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, WORLD_SYNTAX, agree, agreeRun, agreeSchedule, ask, attributeGraph, attributeTrace, attributeVertexId, capKeys, check, checkLatent, checkStep, checkSteps, checkWorld, circularOf, classify, collectOf, components, conforms, context, cycles, dataEdges, decodeDomain, decodeLog, decodeValue, derefStep, describe, docEquals, 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, partsOf, pathMatches, permits, placeOf, placed, planner, prepare, print, printReads, random, recorder, ref, reference, referenceRun, refsOf, replayer, resolve, 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 };
|
|
18391
|
+
export { ATTRIBUTE_RUNGS, CAPS_TYPE, CIRCULAR_LIMIT, 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, WORLD_SYNTAX, agree, agreeRun, agreeSchedule, argsKey, ask, atArgsOf, atRuleOf, attributeGraph, attributeTrace, attributeVertexId, capKeys, check, checkLatent, checkStep, checkSteps, checkWorld, circularOf, classify, collectOf, components, conforms, context, cycles, dataEdges, decodeDomain, decodeLog, decodeValue, derefStep, describe, docEquals, 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, partsOf, pathMatches, permits, placeOf, placed, planner, prepare, print, printReads, random, recorder, ref, reference, referenceRun, refsOf, replayer, resolve, 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 };
|
|
18006
18392
|
|
|
18007
18393
|
//# sourceMappingURL=index.js.map
|