@mark1russell7/coeval 0.26.1 → 0.27.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 +23 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +192 -70
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/errors.ts +1 -0
- package/src/evaluate.ts +113 -14
- package/src/formula.ts +7 -4
- package/src/index.ts +1 -0
- package/src/merge.ts +1 -1
- package/src/reference.ts +93 -38
- package/src/stdlib.ts +39 -14
package/build/index.js
CHANGED
|
@@ -2410,7 +2410,7 @@ function checkHidden(m, draft) {
|
|
|
2410
2410
|
* - A runner hides the evaluator of its name. Thus one part must give both, or the merge gives a conflict.
|
|
2411
2411
|
* - The hooks `known` compose in the order of the parts. A hook does not answer for a name that a later part replaces.
|
|
2412
2412
|
* The hooks `facts` compose the same way, and the first answer that is not `undefined` wins.
|
|
2413
|
-
* - Each other field, for example `permits`, `adopt`, `roots`, `plain` or `
|
|
2413
|
+
* - Each other field, for example `permits`, `adopt`, `roots`, `plain`, `maxDepth` or `maxWork`, is one value. Two different
|
|
2414
2414
|
* values are a conflict. An absent field has no value.
|
|
2415
2415
|
*
|
|
2416
2416
|
* A conflict stops the merge, unless the later part names its path in `replaces`. A part can be a function of the
|
|
@@ -4325,6 +4325,20 @@ function placeText(place) {
|
|
|
4325
4325
|
}
|
|
4326
4326
|
return text;
|
|
4327
4327
|
}
|
|
4328
|
+
/**
|
|
4329
|
+
* The most work of one evaluation for a machine without its own `maxWork` (WORK.LIMIT, D134). One application of a
|
|
4330
|
+
* closure is one point.
|
|
4331
|
+
*/
|
|
4332
|
+
const WORK_LIMIT = 2e5;
|
|
4333
|
+
/**
|
|
4334
|
+
* This function gives the error of the limit of work. Each tier gives this error (WORK.AGREES).
|
|
4335
|
+
*
|
|
4336
|
+
* @param limit - The limit of the machine.
|
|
4337
|
+
* @returns The error.
|
|
4338
|
+
*/
|
|
4339
|
+
function workFailure(limit) {
|
|
4340
|
+
return fail("#WORK!", `The work of one evaluation is more than ${limit} points. The field maxWork of the machine sets the limit.`).error;
|
|
4341
|
+
}
|
|
4328
4342
|
function selfLabel(self) {
|
|
4329
4343
|
try {
|
|
4330
4344
|
if (isHostThing(self)) return self.label;
|
|
@@ -4458,7 +4472,12 @@ var Session = class {
|
|
|
4458
4472
|
running;
|
|
4459
4473
|
traced;
|
|
4460
4474
|
perform;
|
|
4461
|
-
|
|
4475
|
+
/**
|
|
4476
|
+
* The runtime of the root, on the runtime of an equation of a tree (WORK.EQUATION). The runtime of a root holds
|
|
4477
|
+
* itself after the end of its evaluation (WORK.AFTER, WORK.KEEPS), thus the end mark adds no field to the object.
|
|
4478
|
+
* Each runtime has this field, thus a tree and its equations have one object shape.
|
|
4479
|
+
*/
|
|
4480
|
+
top;
|
|
4462
4481
|
/**
|
|
4463
4482
|
* The record of the reads. Without it, a resolution records nothing. A nested evaluation of an equation of a tree
|
|
4464
4483
|
* shares the record of the evaluation around it (READS.EQUATION).
|
|
@@ -4480,18 +4499,38 @@ var Session = class {
|
|
|
4480
4499
|
* root scope is made at the first effect or `all`, thus an evaluation without effects makes no scope.
|
|
4481
4500
|
*/
|
|
4482
4501
|
scope;
|
|
4483
|
-
constructor(machine, epoch, running, traced, perform,
|
|
4502
|
+
constructor(machine, epoch, running, traced, perform, top, effects, reading = void 0) {
|
|
4484
4503
|
this.machine = machine;
|
|
4485
4504
|
this.epoch = epoch;
|
|
4486
4505
|
this.running = running;
|
|
4487
4506
|
this.traced = traced;
|
|
4488
4507
|
this.perform = perform;
|
|
4489
|
-
this.
|
|
4508
|
+
this.top = top;
|
|
4490
4509
|
this.reading = reading;
|
|
4491
4510
|
this.list = effects;
|
|
4492
4511
|
this.holder = traced ? holderNode() : void 0;
|
|
4493
4512
|
this.current = this.holder;
|
|
4494
4513
|
}
|
|
4514
|
+
/** This getter gives `true` for the runtime of an equation of a tree (WORK.NODE). */
|
|
4515
|
+
get nested() {
|
|
4516
|
+
const top = this.top;
|
|
4517
|
+
return top !== void 0 && top !== this;
|
|
4518
|
+
}
|
|
4519
|
+
/**
|
|
4520
|
+
* This function adds work to the count of the evaluation (WORK.LIMIT). One count is on the runtime of the root, thus
|
|
4521
|
+
* each equation of a tree adds to it. After the end of the evaluation, each entry from the host starts a new count
|
|
4522
|
+
* (WORK.AFTER).
|
|
4523
|
+
*
|
|
4524
|
+
* @param points - The work.
|
|
4525
|
+
* @throws {Failure} The error `#WORK!`, when the count is over the limit of the machine.
|
|
4526
|
+
*/
|
|
4527
|
+
spend(points) {
|
|
4528
|
+
const root = this.top ?? this;
|
|
4529
|
+
const work = (root.top === root && (this.applying ?? 0) === 0 ? 0 : root.work ?? 0) + points;
|
|
4530
|
+
root.work = work;
|
|
4531
|
+
const limit = this.machine.maxWork ?? 2e5;
|
|
4532
|
+
if (work > limit) throw new Failure(workFailure(limit));
|
|
4533
|
+
}
|
|
4495
4534
|
/** The effects of the evaluation, in their order. */
|
|
4496
4535
|
get effects() {
|
|
4497
4536
|
return this.list ??= [];
|
|
@@ -5104,6 +5143,7 @@ function compileNode(c, value, place, declared, depth, address = false) {
|
|
|
5104
5143
|
...address ? { address: true } : {}
|
|
5105
5144
|
};
|
|
5106
5145
|
if (runner !== void 0) {
|
|
5146
|
+
c.keeps = true;
|
|
5107
5147
|
let inner;
|
|
5108
5148
|
try {
|
|
5109
5149
|
inner = isCompiledRunner(runner) ? runner.compileRun(input) : interpretRun(runner, input, split.fill, kind?.caps?.some((rule) => rule.rule === "grant") === true);
|
|
@@ -5114,6 +5154,7 @@ function compileNode(c, value, place, declared, depth, address = false) {
|
|
|
5114
5154
|
const run = placedRun(guard === void 0 ? inner : guardRun(inner, guard, c.machine.domains), place, name);
|
|
5115
5155
|
return finish$2(c, meta, runnerCode(run, place, kindText), run);
|
|
5116
5156
|
}
|
|
5157
|
+
if (!isCompiledEvaluator(evaluator) || evaluator.keeps === true) c.keeps = true;
|
|
5117
5158
|
let inner;
|
|
5118
5159
|
try {
|
|
5119
5160
|
inner = isCompiledEvaluator(evaluator) ? evaluator.compile(input) : interpret(evaluator, input, split.fill);
|
|
@@ -5187,6 +5228,8 @@ var Probe = class {
|
|
|
5187
5228
|
running = false;
|
|
5188
5229
|
/** `true` after the part asked for something that a fold cannot give. */
|
|
5189
5230
|
refused = false;
|
|
5231
|
+
/** A node in a fold costs work, thus a tree stops the fold before it evaluates an equation (WORK.PREPARE). */
|
|
5232
|
+
nested = true;
|
|
5190
5233
|
/** The count of the names that the part read. */
|
|
5191
5234
|
reads = 0;
|
|
5192
5235
|
/**
|
|
@@ -5254,6 +5297,11 @@ var Probe = class {
|
|
|
5254
5297
|
keepsContext() {
|
|
5255
5298
|
this.refused = true;
|
|
5256
5299
|
}
|
|
5300
|
+
/** This function stops the fold at the first point of work, thus `prepare` does no such work (WORK.PREPARE). */
|
|
5301
|
+
spend() {
|
|
5302
|
+
this.refused = true;
|
|
5303
|
+
throw new Failure(workFailure(0));
|
|
5304
|
+
}
|
|
5257
5305
|
};
|
|
5258
5306
|
/**
|
|
5259
5307
|
* 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
|
|
@@ -5585,8 +5633,8 @@ const RUNTIME = /* @__PURE__ */ Symbol("coeval.runtime");
|
|
|
5585
5633
|
/**
|
|
5586
5634
|
* This function evaluates a plan inside the evaluation of another runtime, for example an equation of a tree inside
|
|
5587
5635
|
* the evaluation of its tree (READS.EQUATION). The plan gets its own runtime, as in `plan.evaluate`. The reads of the
|
|
5588
|
-
* plan go in the record of the reads of `outer
|
|
5589
|
-
* (READS.FREE). Without
|
|
5636
|
+
* plan go in the record of the reads of `outer`, and its work goes in the count of `outer` (WORK.EQUATION). The context
|
|
5637
|
+
* at the root of `outer` tells which reads are free (READS.FREE). Without a session, the function gives `plan.evaluate(context)`.
|
|
5590
5638
|
*
|
|
5591
5639
|
* @param plan - The plan.
|
|
5592
5640
|
* @param context - The context of the plan.
|
|
@@ -5594,11 +5642,10 @@ const RUNTIME = /* @__PURE__ */ Symbol("coeval.runtime");
|
|
|
5594
5642
|
* @returns The result.
|
|
5595
5643
|
*/
|
|
5596
5644
|
function evaluateWithin(plan, context, outer) {
|
|
5597
|
-
|
|
5598
|
-
if (reading === void 0 || !(plan instanceof CompiledPlan)) return plan.evaluate(context);
|
|
5645
|
+
if (!(outer instanceof Session) || !(plan instanceof CompiledPlan)) return plan.evaluate(context);
|
|
5599
5646
|
const machine = plan.machine;
|
|
5600
5647
|
const ctx = rootContext(machine, context);
|
|
5601
|
-
return plan.code(ctx, new Session(machine, ctx.caps, false, plan.traced, void 0,
|
|
5648
|
+
return plan.code(ctx, new Session(machine, ctx.caps, false, plan.traced, void 0, outer.top ?? outer, void 0, outer.reading));
|
|
5602
5649
|
}
|
|
5603
5650
|
function interpret(fn, input, fill) {
|
|
5604
5651
|
const { kind, typePath, doc, data, place, machine } = input;
|
|
@@ -5761,7 +5808,22 @@ function prepare(machine, doc, options = {}) {
|
|
|
5761
5808
|
run: void 0
|
|
5762
5809
|
};
|
|
5763
5810
|
}
|
|
5764
|
-
return new CompiledPlan(machine, c.traced, root.code, root.run);
|
|
5811
|
+
return new CompiledPlan(machine, c.traced, c.keeps === true ? endingCode(root.code) : root.code, root.run);
|
|
5812
|
+
}
|
|
5813
|
+
/**
|
|
5814
|
+
* This function gives the code of a plan with a document that can use its runtime after the end of the evaluation. The
|
|
5815
|
+
* code marks that end (WORK.KEEPS). Each other plan has no such step, thus the count adds nothing to a read.
|
|
5816
|
+
*
|
|
5817
|
+
* @param code - The code of the root.
|
|
5818
|
+
* @returns The code that marks the end.
|
|
5819
|
+
*/
|
|
5820
|
+
function endingCode(code) {
|
|
5821
|
+
return (ctx, rt) => {
|
|
5822
|
+
const result = code(ctx, rt);
|
|
5823
|
+
const session = rt;
|
|
5824
|
+
session.top ??= session;
|
|
5825
|
+
return result;
|
|
5826
|
+
};
|
|
5765
5827
|
}
|
|
5766
5828
|
/**
|
|
5767
5829
|
* The object of a plan (PLAN.LEAN). The code of `evaluate` and `run` is on the class, thus a plan keeps only its
|
|
@@ -5796,8 +5858,10 @@ var CompiledPlan = class {
|
|
|
5796
5858
|
run(context = makeContext(), runOptions = {}) {
|
|
5797
5859
|
const machine = this.machine;
|
|
5798
5860
|
const ctx = rootContext(machine, context);
|
|
5799
|
-
const s = new Session(machine, ctx.caps, true, this.traced, runOptions.perform,
|
|
5800
|
-
return driveWaiting(this.runCode()(ctx, s), runOptions.signal)
|
|
5861
|
+
const s = new Session(machine, ctx.caps, true, this.traced, runOptions.perform, void 0, void 0, readingOf(runOptions.reads, ctx));
|
|
5862
|
+
return driveWaiting(this.runCode()(ctx, s), runOptions.signal).finally(() => {
|
|
5863
|
+
s.top = s;
|
|
5864
|
+
});
|
|
5801
5865
|
}
|
|
5802
5866
|
};
|
|
5803
5867
|
/**
|
|
@@ -5888,8 +5952,10 @@ async function run(machine, doc, context = makeContext(), options = {}) {
|
|
|
5888
5952
|
...options.verb === void 0 ? {} : { verb: options.verb }
|
|
5889
5953
|
});
|
|
5890
5954
|
const ctx = rootContext(machine, context);
|
|
5891
|
-
const s = new Session(machine, ctx.caps, true, true, options.perform,
|
|
5892
|
-
|
|
5955
|
+
const s = new Session(machine, ctx.caps, true, true, options.perform, void 0, void 0, readingOf(options.reads, ctx));
|
|
5956
|
+
const result = await driveWaiting(plan.runCode()(ctx, s), options.signal);
|
|
5957
|
+
s.top = s;
|
|
5958
|
+
return record(s, result);
|
|
5893
5959
|
}
|
|
5894
5960
|
/**
|
|
5895
5961
|
* This function finds a node of a trace by its path.
|
|
@@ -6437,9 +6503,13 @@ function allValues(results) {
|
|
|
6437
6503
|
const errors = results.filter((result) => !result.ok);
|
|
6438
6504
|
const first = errors[0];
|
|
6439
6505
|
if (first !== void 0 && errors.length === 1) return { error: first };
|
|
6440
|
-
if (errors.length > 1) return { error:
|
|
6506
|
+
if (errors.length > 1) return { error: partsFailed(errors) };
|
|
6441
6507
|
return { values: results.map((result) => result.ok ? result.value : null) };
|
|
6442
6508
|
}
|
|
6509
|
+
/** This function gives the error of more than one failed part. */
|
|
6510
|
+
function partsFailed(errors) {
|
|
6511
|
+
return errors.find((result) => !result.ok && result.error.code === "#WORK!") ?? fail("#ARGS", `${errors.length} parts failed.`);
|
|
6512
|
+
}
|
|
6443
6513
|
function numbers(values, kind) {
|
|
6444
6514
|
const bad = values.findIndex((value) => !isNumber(value));
|
|
6445
6515
|
if (bad !== -1) return fail("#VALUE!", `Part ${bad} of ${kind} is not a number.`);
|
|
@@ -6919,20 +6989,24 @@ function putField(target, key, value) {
|
|
|
6919
6989
|
* This function gives a value with the JSON of each node of a tree in it. A list or a plain record is new only when
|
|
6920
6990
|
* it holds a node. A container that holds itself stays as it is.
|
|
6921
6991
|
*/
|
|
6922
|
-
function plainOf(value, path) {
|
|
6992
|
+
function plainOf(value, path, runtime) {
|
|
6993
|
+
if (typeof value !== "object" || value === null) return ok(value);
|
|
6923
6994
|
const state = stateOf(value);
|
|
6995
|
+
const open = path.get(value);
|
|
6924
6996
|
if (state !== void 0) {
|
|
6925
|
-
if (
|
|
6997
|
+
if (open === true) return fail("#CYCLE!", `The JSON of the node ${state.type} at [${state.place.join(", ")}] holds the node itself.`);
|
|
6998
|
+
if (open === false) runtime?.spend?.(1);
|
|
6926
6999
|
return state.json(path);
|
|
6927
7000
|
}
|
|
6928
|
-
if (
|
|
7001
|
+
if (open === true || isHostThing(value)) return ok(value);
|
|
6929
7002
|
if (!Array.isArray(value) && !isRecord(value)) return ok(value);
|
|
6930
|
-
|
|
7003
|
+
if (open === false) runtime?.spend?.(1);
|
|
7004
|
+
path.set(value, true);
|
|
6931
7005
|
try {
|
|
6932
7006
|
if (Array.isArray(value)) {
|
|
6933
7007
|
let list;
|
|
6934
7008
|
for (let index = 0; index < value.length; index += 1) {
|
|
6935
|
-
const item = plainOf(value[index], path);
|
|
7009
|
+
const item = plainOf(value[index], path, runtime);
|
|
6936
7010
|
if (!item.ok) return item;
|
|
6937
7011
|
if (item.value !== value[index]) (list ??= [...value])[index] = item.value;
|
|
6938
7012
|
}
|
|
@@ -6941,7 +7015,7 @@ function plainOf(value, path) {
|
|
|
6941
7015
|
const record = value;
|
|
6942
7016
|
let out;
|
|
6943
7017
|
for (const key of Object.keys(record)) {
|
|
6944
|
-
const item = plainOf(record[key], path);
|
|
7018
|
+
const item = plainOf(record[key], path, runtime);
|
|
6945
7019
|
if (!item.ok) return item;
|
|
6946
7020
|
if (item.value === record[key]) continue;
|
|
6947
7021
|
if (out === void 0) {
|
|
@@ -6952,7 +7026,7 @@ function plainOf(value, path) {
|
|
|
6952
7026
|
}
|
|
6953
7027
|
return ok(out ?? value);
|
|
6954
7028
|
} finally {
|
|
6955
|
-
path.
|
|
7029
|
+
path.set(value, false);
|
|
6956
7030
|
}
|
|
6957
7031
|
}
|
|
6958
7032
|
/**
|
|
@@ -7404,19 +7478,19 @@ function treeThing(input, place, build, outer, host) {
|
|
|
7404
7478
|
};
|
|
7405
7479
|
},
|
|
7406
7480
|
json(path) {
|
|
7407
|
-
path.
|
|
7481
|
+
path.set(node, true);
|
|
7408
7482
|
try {
|
|
7409
7483
|
const out = {};
|
|
7410
7484
|
for (const part of parts) {
|
|
7411
7485
|
const result = read(part.key);
|
|
7412
7486
|
if (!result.ok) return result;
|
|
7413
|
-
const value = plainOf(result.value, path);
|
|
7487
|
+
const value = plainOf(result.value, path, runtime);
|
|
7414
7488
|
if (!value.ok) return value;
|
|
7415
7489
|
putField(out, part.key, value.value);
|
|
7416
7490
|
}
|
|
7417
7491
|
return ok(out);
|
|
7418
7492
|
} finally {
|
|
7419
|
-
path.
|
|
7493
|
+
path.set(node, false);
|
|
7420
7494
|
}
|
|
7421
7495
|
}
|
|
7422
7496
|
};
|
|
@@ -7439,7 +7513,7 @@ function treeThing(input, place, build, outer, host) {
|
|
|
7439
7513
|
return cell !== void 0 && !cell.busy && cell.result !== void 0;
|
|
7440
7514
|
},
|
|
7441
7515
|
toJson() {
|
|
7442
|
-
const result = state.json(/* @__PURE__ */ new
|
|
7516
|
+
const result = state.json(/* @__PURE__ */ new Map());
|
|
7443
7517
|
if (!result.ok) throw new Failure(result.error);
|
|
7444
7518
|
return result.value;
|
|
7445
7519
|
}
|
|
@@ -7479,6 +7553,8 @@ const NO_HOPS = /* @__PURE__ */ Object.freeze({ hops: false });
|
|
|
7479
7553
|
* The argument `host` gives the memo cells of the host (TREE.CELL), or `undefined` for the plain memo of each node.
|
|
7480
7554
|
*/
|
|
7481
7555
|
function treeNode(input, host) {
|
|
7556
|
+
const runtime = input[RUNTIME];
|
|
7557
|
+
if (runtime?.nested === true) runtime.spend?.(8);
|
|
7482
7558
|
const found = input.resolve(SELF_PATH, NO_HOPS);
|
|
7483
7559
|
const outer = found.ok ? found.thing : void 0;
|
|
7484
7560
|
const above = stateOf(outer);
|
|
@@ -7488,7 +7564,7 @@ function treeNode(input, host) {
|
|
|
7488
7564
|
build.open = true;
|
|
7489
7565
|
const root = treeThing(input, place, build, outer, host);
|
|
7490
7566
|
try {
|
|
7491
|
-
return stateOf(root).json(/* @__PURE__ */ new
|
|
7567
|
+
return stateOf(root).json(/* @__PURE__ */ new Map());
|
|
7492
7568
|
} finally {
|
|
7493
7569
|
build.open = false;
|
|
7494
7570
|
}
|
|
@@ -11280,8 +11356,11 @@ function setOwn$2(target, key, value) {
|
|
|
11280
11356
|
});
|
|
11281
11357
|
else target[key] = value;
|
|
11282
11358
|
}
|
|
11283
|
-
function compiled(compile) {
|
|
11284
|
-
return { compile }
|
|
11359
|
+
function compiled(compile, keeps) {
|
|
11360
|
+
return keeps === void 0 ? { compile } : {
|
|
11361
|
+
compile,
|
|
11362
|
+
keeps
|
|
11363
|
+
};
|
|
11285
11364
|
}
|
|
11286
11365
|
/** This function evaluates parts in order. It gives the value of each part, or the first error. */
|
|
11287
11366
|
function valuesOf(parts, ctx, rt) {
|
|
@@ -12009,7 +12088,7 @@ function makeEvaluators(profile) {
|
|
|
12009
12088
|
const evaluator = evaluators[name];
|
|
12010
12089
|
const type = Object.hasOwn(types, name) ? types[name] : void 0;
|
|
12011
12090
|
const made = Object.freeze(type === void 0 ? evaluator : {
|
|
12012
|
-
|
|
12091
|
+
...evaluator,
|
|
12013
12092
|
type
|
|
12014
12093
|
});
|
|
12015
12094
|
if (truth !== void 0 && TRUTH_READERS.includes(name)) truthByCode.set(made, truth);
|
|
@@ -12278,6 +12357,7 @@ function formulaCode(profile) {
|
|
|
12278
12357
|
const closure = (...args) => {
|
|
12279
12358
|
const level = (clock.applying ?? 0) + 1;
|
|
12280
12359
|
if (level > limit) throw new Failure(fail("#DEPTH!", `The applications of functions nest deeper than ${limit} levels.`).error);
|
|
12360
|
+
rt.spend?.(1);
|
|
12281
12361
|
clock.applying = level;
|
|
12282
12362
|
try {
|
|
12283
12363
|
const scope = { ...ctx.names };
|
|
@@ -12295,7 +12375,7 @@ function formulaCode(profile) {
|
|
|
12295
12375
|
Object.defineProperty(closure, CLOSURE$3, { value: { params: names } });
|
|
12296
12376
|
return ok(closure);
|
|
12297
12377
|
};
|
|
12298
|
-
}),
|
|
12378
|
+
}, true),
|
|
12299
12379
|
"formula.call": compiled(({ value }) => {
|
|
12300
12380
|
const record = partsOf$1(value);
|
|
12301
12381
|
const fnPart = record["fn"];
|
|
@@ -13081,22 +13161,35 @@ function* together(env, list, options = {}) {
|
|
|
13081
13161
|
* @returns The result.
|
|
13082
13162
|
*/
|
|
13083
13163
|
function reference(machine, doc, context = makeContext(), options = {}) {
|
|
13084
|
-
return evaluateRoot(machine, doc, context, options, void 0);
|
|
13164
|
+
return evaluateRoot(machine, doc, context, options, void 0, void 0);
|
|
13085
13165
|
}
|
|
13086
13166
|
/**
|
|
13087
|
-
* This function evaluates a document from its root. An equation of a tree gives the record of its tree
|
|
13088
|
-
*
|
|
13167
|
+
* This function evaluates a document from its root. An equation of a tree gives the record of its tree and the count
|
|
13168
|
+
* of its work. Thus its reads go in the list of the outer evaluation (REF.READS), and its work in the outer count
|
|
13169
|
+
* (WORK.EQUATION).
|
|
13089
13170
|
*/
|
|
13090
|
-
function evaluateRoot(machine, doc, context, options, outer) {
|
|
13171
|
+
function evaluateRoot(machine, doc, context, options, outer, meter) {
|
|
13091
13172
|
const at = rootAt(machine, doc, context, options);
|
|
13092
|
-
const env = envOf(machine, options, false, at.ctx, outer);
|
|
13173
|
+
const env = envOf(machine, options, false, at.ctx, outer, meter);
|
|
13093
13174
|
try {
|
|
13094
13175
|
return within(env, () => evaluateAt(env, at));
|
|
13095
13176
|
} catch (error) {
|
|
13096
13177
|
return placed(thrown(error, "the reference"), []);
|
|
13178
|
+
} finally {
|
|
13179
|
+
if (!env.nested) env.meter.ended = true;
|
|
13097
13180
|
}
|
|
13098
13181
|
}
|
|
13099
13182
|
/**
|
|
13183
|
+
* WORK.LIMIT: this function adds work to the count of an evaluation. After the end of the evaluation, each entry from
|
|
13184
|
+
* the host starts a new count (WORK.AFTER). A count over the limit throws `#WORK!`.
|
|
13185
|
+
*/
|
|
13186
|
+
function spend(env, points) {
|
|
13187
|
+
const meter = env.meter;
|
|
13188
|
+
if (meter.ended && env.applying === 0) meter.spent = 0;
|
|
13189
|
+
meter.spent += points;
|
|
13190
|
+
if (meter.spent > env.maxWork) throw new Failure(workFailure(env.maxWork));
|
|
13191
|
+
}
|
|
13192
|
+
/**
|
|
13100
13193
|
* This function starts a run of a document by the rules, without a compilation (REF.RUN). The host does each effect of a runner,
|
|
13101
13194
|
* and a step waits when the host waits (RUN.SEQ). `all` settles the waits in the order of the host, or in the order
|
|
13102
13195
|
* of the journal of a replay (RUN.REPLAY). An effect of an evaluator gives `#CALC!` (RUN.NEEDS-RUNNER). A signal that
|
|
@@ -13113,14 +13206,16 @@ function evaluateRoot(machine, doc, context, options, outer) {
|
|
|
13113
13206
|
*/
|
|
13114
13207
|
function referenceRun(machine, doc, context = makeContext(), options = {}) {
|
|
13115
13208
|
const at = rootAt(machine, doc, context, options);
|
|
13116
|
-
const env = envOf(machine, options, true, at.ctx, void 0);
|
|
13117
|
-
return driveRun(env, stepsAt(env, at), options.signal).catch((error) => placed(thrown(error, "the reference"), []))
|
|
13209
|
+
const env = envOf(machine, options, true, at.ctx, void 0, void 0);
|
|
13210
|
+
return driveRun(env, stepsAt(env, at), options.signal).catch((error) => placed(thrown(error, "the reference"), [])).finally(() => {
|
|
13211
|
+
env.meter.ended = true;
|
|
13212
|
+
});
|
|
13118
13213
|
}
|
|
13119
13214
|
/**
|
|
13120
13215
|
* This function makes the state of the reference for one evaluation or one run. The record of the reads comes from
|
|
13121
13216
|
* the evaluation around it, or from the list of the options.
|
|
13122
13217
|
*/
|
|
13123
|
-
function envOf(machine, options, running, root, outer) {
|
|
13218
|
+
function envOf(machine, options, running, root, outer, meter) {
|
|
13124
13219
|
const perform = options.perform;
|
|
13125
13220
|
return {
|
|
13126
13221
|
machine,
|
|
@@ -13138,6 +13233,12 @@ function envOf(machine, options, running, root, outer) {
|
|
|
13138
13233
|
},
|
|
13139
13234
|
held: 0,
|
|
13140
13235
|
applying: 0,
|
|
13236
|
+
maxWork: machine.maxWork ?? 2e5,
|
|
13237
|
+
meter: meter ?? {
|
|
13238
|
+
spent: 0,
|
|
13239
|
+
ended: false
|
|
13240
|
+
},
|
|
13241
|
+
nested: meter !== void 0,
|
|
13141
13242
|
reading: outer ?? (options.reads === void 0 ? void 0 : {
|
|
13142
13243
|
list: options.reads,
|
|
13143
13244
|
root
|
|
@@ -13231,7 +13332,7 @@ function equationOf(node, term, names) {
|
|
|
13231
13332
|
return evaluateRoot(env.machine, term, ctx, {
|
|
13232
13333
|
definitions: env.definitions,
|
|
13233
13334
|
...node.of === void 0 ? {} : { declaredType: node.of }
|
|
13234
|
-
}, env.reading);
|
|
13335
|
+
}, env.reading, env.meter);
|
|
13235
13336
|
}
|
|
13236
13337
|
function termIn(table, name) {
|
|
13237
13338
|
return table === void 0 || !Object.hasOwn(table, name) ? void 0 : table[name];
|
|
@@ -13581,42 +13682,55 @@ function instanceOf$1(node, attr, args) {
|
|
|
13581
13682
|
return result;
|
|
13582
13683
|
}
|
|
13583
13684
|
/** TREE.RESULT: the JSON of a node. `open` holds the nodes and the containers whose JSON is in progress. */
|
|
13584
|
-
function jsonOfNode(node, self, open) {
|
|
13585
|
-
|
|
13586
|
-
|
|
13587
|
-
const
|
|
13588
|
-
|
|
13589
|
-
|
|
13590
|
-
|
|
13591
|
-
|
|
13685
|
+
function jsonOfNode(node, self, open, seen) {
|
|
13686
|
+
try {
|
|
13687
|
+
const record = {};
|
|
13688
|
+
for (const part of node.parts) {
|
|
13689
|
+
const result = attributeOf(node, part.key);
|
|
13690
|
+
if (!result.ok) return result;
|
|
13691
|
+
const value = plainValue(node, result.value, [...open, self], seen);
|
|
13692
|
+
if (!value.ok) return value;
|
|
13693
|
+
setField$2(record, part.key, value.value);
|
|
13694
|
+
}
|
|
13695
|
+
return ok(record);
|
|
13696
|
+
} finally {
|
|
13697
|
+
seen.add(self);
|
|
13592
13698
|
}
|
|
13593
|
-
return ok(record);
|
|
13594
13699
|
}
|
|
13595
|
-
/**
|
|
13596
|
-
function
|
|
13700
|
+
/**
|
|
13701
|
+
* This function gives a copy of a value with the JSON of each node in it. The set `seen` holds each node, list and
|
|
13702
|
+
* record that the walk left. A second visit of one of them counts one point on the evaluation of `owner` (WORK.SHARED).
|
|
13703
|
+
*/
|
|
13704
|
+
function plainValue(owner, value, open, seen) {
|
|
13597
13705
|
const node = refNodeOf(value);
|
|
13598
13706
|
if (node !== void 0) {
|
|
13599
13707
|
if (open.includes(value)) return fail("#CYCLE!", `The JSON of the node ${node.kind} at [${node.place.join(", ")}] holds the node itself.`);
|
|
13600
|
-
|
|
13708
|
+
if (seen.has(value) && owner.env !== void 0) spend(owner.env, 1);
|
|
13709
|
+
return jsonOfNode(node, value, open, seen);
|
|
13601
13710
|
}
|
|
13602
13711
|
if (typeof value !== "object" || value === null || isHostThing(value) || open.includes(value)) return ok(value);
|
|
13603
|
-
if (Array.isArray(value))
|
|
13604
|
-
|
|
13605
|
-
|
|
13606
|
-
|
|
13712
|
+
if (!Array.isArray(value) && !isRecord(value)) return ok(value);
|
|
13713
|
+
if (seen.has(value) && owner.env !== void 0) spend(owner.env, 1);
|
|
13714
|
+
try {
|
|
13715
|
+
if (Array.isArray(value)) {
|
|
13716
|
+
const items = [];
|
|
13717
|
+
for (const item of value) {
|
|
13718
|
+
const plain = plainValue(owner, item, [...open, value], seen);
|
|
13719
|
+
if (!plain.ok) return plain;
|
|
13720
|
+
items.push(plain.value);
|
|
13721
|
+
}
|
|
13722
|
+
return ok(items);
|
|
13723
|
+
}
|
|
13724
|
+
const copy = {};
|
|
13725
|
+
for (const key of Object.keys(value)) {
|
|
13726
|
+
const plain = plainValue(owner, value[key], [...open, value], seen);
|
|
13607
13727
|
if (!plain.ok) return plain;
|
|
13608
|
-
|
|
13728
|
+
setField$2(copy, key, plain.value);
|
|
13609
13729
|
}
|
|
13610
|
-
return ok(
|
|
13611
|
-
}
|
|
13612
|
-
|
|
13613
|
-
const copy = {};
|
|
13614
|
-
for (const key of Object.keys(value)) {
|
|
13615
|
-
const plain = plainValue(value[key], [...open, value]);
|
|
13616
|
-
if (!plain.ok) return plain;
|
|
13617
|
-
setField$2(copy, key, plain.value);
|
|
13730
|
+
return ok(copy);
|
|
13731
|
+
} finally {
|
|
13732
|
+
seen.add(value);
|
|
13618
13733
|
}
|
|
13619
|
-
return ok(copy);
|
|
13620
13734
|
}
|
|
13621
13735
|
/**
|
|
13622
13736
|
* TREE.LAZY, TREE.PARENT, TREE.SIBLING and TREE.ERROR: a node of an open tree gives its thing, and the root of a new
|
|
@@ -13624,6 +13738,8 @@ function plainValue(value, open) {
|
|
|
13624
13738
|
* reads `self` only through `resolve` (C4, TREE.SELF).
|
|
13625
13739
|
*/
|
|
13626
13740
|
const treeDefinition = ({ parts, context, kind, place, machine, typePath, resolve: walk, doc }) => {
|
|
13741
|
+
const maker = activeEnvs[activeEnvs.length - 1];
|
|
13742
|
+
if (maker?.nested === true) spend(maker, 8);
|
|
13627
13743
|
const reached = walk(["self"]);
|
|
13628
13744
|
const parent = reached.ok ? reached.thing : void 0;
|
|
13629
13745
|
const outer = refNodeOf(parent);
|
|
@@ -13659,7 +13775,7 @@ const treeDefinition = ({ parts, context, kind, place, machine, typePath, resolv
|
|
|
13659
13775
|
},
|
|
13660
13776
|
has: (key) => key === "parent" || key === "type" || parts.some((part) => part.key === String(key)) || node.values.has(String(key)),
|
|
13661
13777
|
toJson: () => {
|
|
13662
|
-
const result = jsonOfNode(node, self, []);
|
|
13778
|
+
const result = jsonOfNode(node, self, [], /* @__PURE__ */ new Set());
|
|
13663
13779
|
if (result.ok) return result.value;
|
|
13664
13780
|
throw new Failure(result.error);
|
|
13665
13781
|
}
|
|
@@ -13669,7 +13785,7 @@ const treeDefinition = ({ parts, context, kind, place, machine, typePath, resolv
|
|
|
13669
13785
|
AT_READERS.set(self, (attr, args) => instanceOf$1(node, attr, args));
|
|
13670
13786
|
if (nested) return ok(self);
|
|
13671
13787
|
try {
|
|
13672
|
-
return jsonOfNode(node, self, []);
|
|
13788
|
+
return jsonOfNode(node, self, [], /* @__PURE__ */ new Set());
|
|
13673
13789
|
} finally {
|
|
13674
13790
|
node.tree.open = false;
|
|
13675
13791
|
}
|
|
@@ -13808,11 +13924,17 @@ function formulaDefinitions(profile = {}) {
|
|
|
13808
13924
|
const body = partNamed$1(parts, "body");
|
|
13809
13925
|
const clock = activeEnvs[activeEnvs.length - 1] ?? {
|
|
13810
13926
|
applying: 0,
|
|
13811
|
-
maxDepth: 1e3
|
|
13927
|
+
maxDepth: 1e3,
|
|
13928
|
+
maxWork: 2e5,
|
|
13929
|
+
meter: {
|
|
13930
|
+
spent: 0,
|
|
13931
|
+
ended: false
|
|
13932
|
+
}
|
|
13812
13933
|
};
|
|
13813
13934
|
const limit = Math.ceil(clock.maxDepth / 4);
|
|
13814
13935
|
const closure = (...args) => {
|
|
13815
13936
|
if (clock.applying >= limit) throw new Failure(fail("#DEPTH!", `The applications of functions nest deeper than ${limit} levels.`).error);
|
|
13937
|
+
spend(clock, 1);
|
|
13816
13938
|
clock.applying += 1;
|
|
13817
13939
|
try {
|
|
13818
13940
|
const scope = {};
|
|
@@ -22434,6 +22556,6 @@ function samplesAt(values, closed, depth) {
|
|
|
22434
22556
|
function typeFromSamples(values, options = {}) {
|
|
22435
22557
|
return samplesAt(values, options.closed === true, 0);
|
|
22436
22558
|
}
|
|
22437
|
-
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, compose, conforms, context, cycles, dataEdges, decodeDomain, decodeLog, decodeValue, defineLanguage, 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, stepper, stepperNext, stepperStart, stored, syntaxFormat, tag, thrown, toJson, treeNodeEvaluator, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
|
|
22559
|
+
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, WORK_LIMIT, 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, compose, conforms, context, cycles, dataEdges, decodeDomain, decodeLog, decodeValue, defineLanguage, 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, stepper, stepperNext, stepperStart, stored, syntaxFormat, tag, thrown, toJson, treeNodeEvaluator, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
|
|
22438
22560
|
|
|
22439
22561
|
//# sourceMappingURL=index.js.map
|