@mojir/dvala 0.0.13 → 0.0.14
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 +10 -14
- package/dist/cli/cli.js +1550 -1252
- package/package.json +2 -1
package/dist/cli/cli.js
CHANGED
|
@@ -68,6 +68,17 @@ var DvalaError = class DvalaError extends Error {
|
|
|
68
68
|
getCodeMarker() {
|
|
69
69
|
return this.sourceCodeInfo && getCodeMarker(this.sourceCodeInfo);
|
|
70
70
|
}
|
|
71
|
+
toJSON() {
|
|
72
|
+
return {
|
|
73
|
+
name: this.name,
|
|
74
|
+
message: this.message,
|
|
75
|
+
shortMessage: this.shortMessage,
|
|
76
|
+
line: this.sourceCodeInfo?.position.line,
|
|
77
|
+
column: this.sourceCodeInfo?.position.column,
|
|
78
|
+
code: this.sourceCodeInfo?.code,
|
|
79
|
+
filePath: this.sourceCodeInfo?.filePath
|
|
80
|
+
};
|
|
81
|
+
}
|
|
71
82
|
};
|
|
72
83
|
var UserDefinedError = class UserDefinedError extends DvalaError {
|
|
73
84
|
userMessage;
|
|
@@ -466,7 +477,7 @@ function findAllOccurrences(input, pattern) {
|
|
|
466
477
|
}
|
|
467
478
|
//#endregion
|
|
468
479
|
//#region package.json
|
|
469
|
-
var version = "0.0.
|
|
480
|
+
var version = "0.0.14";
|
|
470
481
|
//#endregion
|
|
471
482
|
//#region src/typeGuards/string.ts
|
|
472
483
|
function isString(value, options = {}) {
|
|
@@ -5571,7 +5582,7 @@ If all expressions evaluate to truthy values, the value of the last expression i
|
|
|
5571
5582
|
}
|
|
5572
5583
|
return value;
|
|
5573
5584
|
},
|
|
5574
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
5585
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => getUndefinedSymbols(node[1][1], contextStack, builtin)
|
|
5575
5586
|
};
|
|
5576
5587
|
const condSpecialExpression = {
|
|
5577
5588
|
arity: {},
|
|
@@ -5614,7 +5625,7 @@ cond
|
|
|
5614
5625
|
end ?? "TRUE"`
|
|
5615
5626
|
]
|
|
5616
5627
|
},
|
|
5617
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
5628
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => getUndefinedSymbols(node[1][1].flat(), contextStack, builtin)
|
|
5618
5629
|
};
|
|
5619
5630
|
//#endregion
|
|
5620
5631
|
//#region src/parser/types.ts
|
|
@@ -5627,79 +5638,6 @@ const bindingTargetTypes = {
|
|
|
5627
5638
|
wildcard: 16
|
|
5628
5639
|
};
|
|
5629
5640
|
//#endregion
|
|
5630
|
-
//#region src/utils/maybePromise.ts
|
|
5631
|
-
/**
|
|
5632
|
-
* Chain a value that might be a Promise. If the value is sync, calls fn synchronously.
|
|
5633
|
-
* If it's a Promise, chains with .then().
|
|
5634
|
-
*/
|
|
5635
|
-
function chain(value, fn) {
|
|
5636
|
-
if (value instanceof Promise) return value.then(fn);
|
|
5637
|
-
return fn(value);
|
|
5638
|
-
}
|
|
5639
|
-
/**
|
|
5640
|
-
* Like Array.map but handles MaybePromise callbacks sequentially.
|
|
5641
|
-
* In the sync case, runs as a simple loop. Switches to async only when needed.
|
|
5642
|
-
*/
|
|
5643
|
-
function mapSequential(arr, fn) {
|
|
5644
|
-
const results = [];
|
|
5645
|
-
for (let i = 0; i < arr.length; i++) {
|
|
5646
|
-
const result = fn(arr[i], i);
|
|
5647
|
-
if (result instanceof Promise) return chainRemainingMap(result, results, arr, fn, i);
|
|
5648
|
-
results.push(result);
|
|
5649
|
-
}
|
|
5650
|
-
return results;
|
|
5651
|
-
}
|
|
5652
|
-
async function chainRemainingMap(currentPromise, results, arr, fn, startIndex) {
|
|
5653
|
-
results.push(await currentPromise);
|
|
5654
|
-
for (let i = startIndex + 1; i < arr.length; i++) results.push(await fn(arr[i], i));
|
|
5655
|
-
return results;
|
|
5656
|
-
}
|
|
5657
|
-
/**
|
|
5658
|
-
* Like Array.reduce but handles MaybePromise callbacks sequentially.
|
|
5659
|
-
* In the sync case, runs as a simple loop. Switches to async only when needed.
|
|
5660
|
-
*/
|
|
5661
|
-
function reduceSequential(arr, fn, initial) {
|
|
5662
|
-
let result = initial;
|
|
5663
|
-
for (let i = 0; i < arr.length; i++) {
|
|
5664
|
-
const next = fn(result, arr[i], i);
|
|
5665
|
-
if (next instanceof Promise) return chainRemainingReduce(next, arr, fn, i);
|
|
5666
|
-
result = next;
|
|
5667
|
-
}
|
|
5668
|
-
return result;
|
|
5669
|
-
}
|
|
5670
|
-
async function chainRemainingReduce(currentPromise, arr, fn, startIndex) {
|
|
5671
|
-
let result = await currentPromise;
|
|
5672
|
-
for (let i = startIndex + 1; i < arr.length; i++) result = await fn(result, arr[i], i);
|
|
5673
|
-
return result;
|
|
5674
|
-
}
|
|
5675
|
-
/**
|
|
5676
|
-
* Like Array.forEach but handles MaybePromise callbacks sequentially.
|
|
5677
|
-
* In the sync case, runs as a simple loop. Switches to async only when needed.
|
|
5678
|
-
*/
|
|
5679
|
-
function forEachSequential(arr, fn) {
|
|
5680
|
-
for (let i = 0; i < arr.length; i++) {
|
|
5681
|
-
const result = fn(arr[i], i);
|
|
5682
|
-
if (result instanceof Promise) return chainRemainingForEach(result, arr, fn, i);
|
|
5683
|
-
}
|
|
5684
|
-
}
|
|
5685
|
-
async function chainRemainingForEach(currentPromise, arr, fn, startIndex) {
|
|
5686
|
-
await currentPromise;
|
|
5687
|
-
for (let i = startIndex + 1; i < arr.length; i++) await fn(arr[i], i);
|
|
5688
|
-
}
|
|
5689
|
-
/**
|
|
5690
|
-
* Try/catch that handles MaybePromise values correctly.
|
|
5691
|
-
* If tryFn returns a Promise, catches both sync throws and Promise rejections.
|
|
5692
|
-
*/
|
|
5693
|
-
function tryCatch(tryFn, catchFn) {
|
|
5694
|
-
try {
|
|
5695
|
-
const result = tryFn();
|
|
5696
|
-
if (result instanceof Promise) return result.catch(catchFn);
|
|
5697
|
-
return result;
|
|
5698
|
-
} catch (error) {
|
|
5699
|
-
return catchFn(error);
|
|
5700
|
-
}
|
|
5701
|
-
}
|
|
5702
|
-
//#endregion
|
|
5703
5641
|
//#region src/builtin/bindingNode.ts
|
|
5704
5642
|
function walkDefaults(bindingTarget, onDefault) {
|
|
5705
5643
|
if (bindingTarget[0] === bindingTargetTypes.object) Object.values(bindingTarget[1][0]).forEach((element) => {
|
|
@@ -5714,70 +5652,6 @@ function walkDefaults(bindingTarget, onDefault) {
|
|
|
5714
5652
|
walkDefaults(element, onDefault);
|
|
5715
5653
|
}
|
|
5716
5654
|
}
|
|
5717
|
-
function evaluateBindingNodeValues(target, value, evaluate) {
|
|
5718
|
-
const sourceCodeInfo = target[2];
|
|
5719
|
-
const record = {};
|
|
5720
|
-
return chain(createRecord(target, value, evaluate, sourceCodeInfo, record), () => record);
|
|
5721
|
-
}
|
|
5722
|
-
function createRecord(bindingTarget, value, evaluate, sourceCodeInfo, record) {
|
|
5723
|
-
if (bindingTarget[0] === bindingTargetTypes.object) {
|
|
5724
|
-
assertUnknownRecord(value, sourceCodeInfo);
|
|
5725
|
-
const capturedKeys = /* @__PURE__ */ new Set();
|
|
5726
|
-
let restElement;
|
|
5727
|
-
return chain(forEachSequential(Object.entries(bindingTarget[1][0]), ([key, element]) => {
|
|
5728
|
-
if (element[0] === bindingTargetTypes.rest) {
|
|
5729
|
-
restElement = element;
|
|
5730
|
-
return;
|
|
5731
|
-
}
|
|
5732
|
-
capturedKeys.add(key);
|
|
5733
|
-
const existingVal = value[key];
|
|
5734
|
-
return chain(existingVal !== void 0 ? existingVal : element[1][1] ? evaluate(element[1][1]) : null, (resolvedVal) => {
|
|
5735
|
-
const val = resolvedVal ?? null;
|
|
5736
|
-
assertAny(val, sourceCodeInfo);
|
|
5737
|
-
return createRecord(element, val, evaluate, sourceCodeInfo, record);
|
|
5738
|
-
});
|
|
5739
|
-
}), () => {
|
|
5740
|
-
if (restElement) {
|
|
5741
|
-
const restValues = Object.entries(value).filter(([key]) => !capturedKeys.has(key)).reduce((acc, [key, val]) => {
|
|
5742
|
-
acc[key] = asAny(val);
|
|
5743
|
-
return acc;
|
|
5744
|
-
}, {});
|
|
5745
|
-
record[restElement[1][0]] = restValues;
|
|
5746
|
-
}
|
|
5747
|
-
});
|
|
5748
|
-
} else if (bindingTarget[0] === bindingTargetTypes.array) {
|
|
5749
|
-
let restIndex = null;
|
|
5750
|
-
assertArray(value, sourceCodeInfo);
|
|
5751
|
-
const elements = [];
|
|
5752
|
-
for (let index = 0; index < bindingTarget[1][0].length; index += 1) {
|
|
5753
|
-
const element = bindingTarget[1][0][index] ?? null;
|
|
5754
|
-
if (element === null) continue;
|
|
5755
|
-
if (element[0] === bindingTargetTypes.rest) {
|
|
5756
|
-
restIndex = index;
|
|
5757
|
-
break;
|
|
5758
|
-
}
|
|
5759
|
-
elements.push({
|
|
5760
|
-
element,
|
|
5761
|
-
index
|
|
5762
|
-
});
|
|
5763
|
-
}
|
|
5764
|
-
return chain(forEachSequential(elements, ({ element, index }) => {
|
|
5765
|
-
const existingVal = value[index];
|
|
5766
|
-
return chain(existingVal !== void 0 ? existingVal : element[1][1] ? evaluate(element[1][1]) : null, (resolvedVal) => {
|
|
5767
|
-
const val = resolvedVal ?? null;
|
|
5768
|
-
assertAny(val, sourceCodeInfo);
|
|
5769
|
-
return createRecord(element, val, evaluate, sourceCodeInfo, record);
|
|
5770
|
-
});
|
|
5771
|
-
}), () => {
|
|
5772
|
-
if (restIndex !== null) {
|
|
5773
|
-
const restValues = value.slice(restIndex);
|
|
5774
|
-
const restElement = bindingTarget[1][0][restIndex];
|
|
5775
|
-
record[restElement[1][0]] = restValues;
|
|
5776
|
-
}
|
|
5777
|
-
});
|
|
5778
|
-
} else if (bindingTarget[0] === bindingTargetTypes.rest) record[bindingTarget[1][0]] = asAny(value);
|
|
5779
|
-
else record[bindingTarget[1][0][1]] = asAny(value);
|
|
5780
|
-
}
|
|
5781
5655
|
function getAllBindingTargetNames(bindingTarget) {
|
|
5782
5656
|
const names = {};
|
|
5783
5657
|
getNamesFromBindingTarget(bindingTarget, names);
|
|
@@ -5795,98 +5669,6 @@ function getNamesFromBindingTarget(target, names) {
|
|
|
5795
5669
|
names[target[1][0][1]] = true;
|
|
5796
5670
|
}
|
|
5797
5671
|
}
|
|
5798
|
-
/**
|
|
5799
|
-
* Non-throwing pattern matching. Returns bindings on match, null on mismatch.
|
|
5800
|
-
* Used by `switch` pattern matching.
|
|
5801
|
-
*/
|
|
5802
|
-
function tryMatch(target, value, evaluate) {
|
|
5803
|
-
const record = {};
|
|
5804
|
-
return chain(tryMatchRecord(target, value, evaluate, record), (matched) => {
|
|
5805
|
-
if (!matched) return null;
|
|
5806
|
-
return record;
|
|
5807
|
-
});
|
|
5808
|
-
}
|
|
5809
|
-
function tryMatchRecord(bindingTarget, value, evaluate, record) {
|
|
5810
|
-
if (bindingTarget[0] === bindingTargetTypes.wildcard) return true;
|
|
5811
|
-
else if (bindingTarget[0] === bindingTargetTypes.literal) {
|
|
5812
|
-
const literalNode = bindingTarget[1][0];
|
|
5813
|
-
return chain(evaluate(literalNode), (literalValue) => {
|
|
5814
|
-
return deepEqual$1(value, literalValue);
|
|
5815
|
-
});
|
|
5816
|
-
} else if (bindingTarget[0] === bindingTargetTypes.symbol) {
|
|
5817
|
-
const symbolNode = bindingTarget[1][0];
|
|
5818
|
-
const defaultNode = bindingTarget[1][1];
|
|
5819
|
-
if (value === void 0 || value === null) {
|
|
5820
|
-
if (defaultNode) return chain(evaluate(defaultNode), (defaultValue) => {
|
|
5821
|
-
record[symbolNode[1]] = asAny(defaultValue);
|
|
5822
|
-
return true;
|
|
5823
|
-
});
|
|
5824
|
-
record[symbolNode[1]] = value ?? null;
|
|
5825
|
-
} else record[symbolNode[1]] = asAny(value);
|
|
5826
|
-
return true;
|
|
5827
|
-
} else if (bindingTarget[0] === bindingTargetTypes.object) {
|
|
5828
|
-
if (!isUnknownRecord(value)) return false;
|
|
5829
|
-
const capturedKeys = /* @__PURE__ */ new Set();
|
|
5830
|
-
let restElement;
|
|
5831
|
-
const entries = Object.entries(bindingTarget[1][0]);
|
|
5832
|
-
let result = true;
|
|
5833
|
-
for (const [key, element] of entries) result = chain(result, (matched) => {
|
|
5834
|
-
if (!matched) return false;
|
|
5835
|
-
if (element[0] === bindingTargetTypes.rest) {
|
|
5836
|
-
restElement = element;
|
|
5837
|
-
return true;
|
|
5838
|
-
}
|
|
5839
|
-
capturedKeys.add(key);
|
|
5840
|
-
const existingVal = value[key];
|
|
5841
|
-
if (existingVal === void 0 && element[0] === bindingTargetTypes.literal) return chain(evaluate(element[1][0]), (literalValue) => {
|
|
5842
|
-
return deepEqual$1(void 0, literalValue);
|
|
5843
|
-
});
|
|
5844
|
-
return chain(existingVal !== void 0 ? existingVal : element[1] && element[1][1] ? evaluate(element[1][1]) : null, (resolvedVal) => {
|
|
5845
|
-
return tryMatchRecord(element, resolvedVal ?? null, evaluate, record);
|
|
5846
|
-
});
|
|
5847
|
-
});
|
|
5848
|
-
return chain(result, (matched) => {
|
|
5849
|
-
if (!matched) return false;
|
|
5850
|
-
if (restElement) {
|
|
5851
|
-
const restValues = Object.entries(value).filter(([key]) => !capturedKeys.has(key)).reduce((acc, [key, val]) => {
|
|
5852
|
-
acc[key] = asAny(val);
|
|
5853
|
-
return acc;
|
|
5854
|
-
}, {});
|
|
5855
|
-
record[restElement[1][0]] = restValues;
|
|
5856
|
-
}
|
|
5857
|
-
return true;
|
|
5858
|
-
});
|
|
5859
|
-
} else {
|
|
5860
|
-
const arrayTarget = bindingTarget;
|
|
5861
|
-
if (!Array.isArray(value)) return false;
|
|
5862
|
-
const elements = arrayTarget[1][0];
|
|
5863
|
-
let restIndex = null;
|
|
5864
|
-
for (let i = 0; i < elements.length; i += 1) {
|
|
5865
|
-
const element = elements[i];
|
|
5866
|
-
if (element !== null && element[0] === bindingTargetTypes.rest) {
|
|
5867
|
-
restIndex = i;
|
|
5868
|
-
break;
|
|
5869
|
-
}
|
|
5870
|
-
}
|
|
5871
|
-
if (restIndex === null && value.length !== elements.length) return false;
|
|
5872
|
-
if (restIndex !== null && value.length < restIndex) return false;
|
|
5873
|
-
let result = true;
|
|
5874
|
-
for (let i = 0; i < elements.length; i += 1) {
|
|
5875
|
-
const element = elements[i];
|
|
5876
|
-
if (element === null) continue;
|
|
5877
|
-
if (element[0] === bindingTargetTypes.rest) {
|
|
5878
|
-
record[element[1][0]] = value.slice(i);
|
|
5879
|
-
break;
|
|
5880
|
-
}
|
|
5881
|
-
const el = element;
|
|
5882
|
-
result = chain(result, (matched) => {
|
|
5883
|
-
if (!matched) return false;
|
|
5884
|
-
return tryMatchRecord(el, asAny(value[i]), evaluate, record);
|
|
5885
|
-
});
|
|
5886
|
-
}
|
|
5887
|
-
return result;
|
|
5888
|
-
}
|
|
5889
|
-
}
|
|
5890
5672
|
const matchSpecialExpression = {
|
|
5891
5673
|
arity: {},
|
|
5892
5674
|
docs: {
|
|
@@ -5946,15 +5728,15 @@ match { role: "admin", name: "Alice" }
|
|
|
5946
5728
|
end`
|
|
5947
5729
|
]
|
|
5948
5730
|
},
|
|
5949
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
5731
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => {
|
|
5950
5732
|
const result = /* @__PURE__ */ new Set();
|
|
5951
|
-
getUndefinedSymbols([node[1][1]], contextStack, builtin
|
|
5733
|
+
getUndefinedSymbols([node[1][1]], contextStack, builtin).forEach((s) => result.add(s));
|
|
5952
5734
|
for (const [pattern, body, guard] of node[1][2]) {
|
|
5953
5735
|
const newContext = {};
|
|
5954
5736
|
Object.assign(newContext, getAllBindingTargetNames(pattern));
|
|
5955
5737
|
const caseContextStack = contextStack.create(newContext);
|
|
5956
|
-
if (guard) getUndefinedSymbols([guard], caseContextStack, builtin
|
|
5957
|
-
getUndefinedSymbols([body], caseContextStack, builtin
|
|
5738
|
+
if (guard) getUndefinedSymbols([guard], caseContextStack, builtin).forEach((s) => result.add(s));
|
|
5739
|
+
getUndefinedSymbols([body], caseContextStack, builtin).forEach((s) => result.add(s));
|
|
5958
5740
|
}
|
|
5959
5741
|
return result;
|
|
5960
5742
|
}
|
|
@@ -5975,7 +5757,7 @@ Built-in symbols are always considered defined. For user-defined symbols, checks
|
|
|
5975
5757
|
"defined?(+)"
|
|
5976
5758
|
]
|
|
5977
5759
|
},
|
|
5978
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
5760
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => getUndefinedSymbols([node[1][1]], contextStack, builtin)
|
|
5979
5761
|
};
|
|
5980
5762
|
const doSpecialExpression = {
|
|
5981
5763
|
arity: {},
|
|
@@ -6012,14 +5794,14 @@ with
|
|
|
6012
5794
|
case effect(dvala.io.println) then ([msg]) -> null
|
|
6013
5795
|
end`]
|
|
6014
5796
|
},
|
|
6015
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6016
|
-
const bodyResult = getUndefinedSymbols(node[1][1], contextStack.create({}), builtin
|
|
5797
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => {
|
|
5798
|
+
const bodyResult = getUndefinedSymbols(node[1][1], contextStack.create({}), builtin);
|
|
6017
5799
|
const withHandlers = node[1][2];
|
|
6018
5800
|
if (!withHandlers || withHandlers.length === 0) return bodyResult;
|
|
6019
5801
|
let withResult = /* @__PURE__ */ new Set();
|
|
6020
5802
|
for (const [effectExpr, handlerFn] of withHandlers) {
|
|
6021
|
-
const effectResult = getUndefinedSymbols([effectExpr], contextStack, builtin
|
|
6022
|
-
const handlerResult = getUndefinedSymbols([handlerFn], contextStack, builtin
|
|
5803
|
+
const effectResult = getUndefinedSymbols([effectExpr], contextStack, builtin);
|
|
5804
|
+
const handlerResult = getUndefinedSymbols([handlerFn], contextStack, builtin);
|
|
6023
5805
|
withResult = joinSets(withResult, effectResult, handlerResult);
|
|
6024
5806
|
}
|
|
6025
5807
|
return joinSets(bodyResult, withResult);
|
|
@@ -6029,22 +5811,22 @@ end`]
|
|
|
6029
5811
|
//#region src/builtin/specialExpressions/functions.ts
|
|
6030
5812
|
const lambdaSpecialExpression = {
|
|
6031
5813
|
arity: {},
|
|
6032
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
5814
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => {
|
|
6033
5815
|
const fn = node[1][1];
|
|
6034
|
-
return getFunctionUnresolvedSymbols(fn, contextStack, getUndefinedSymbols, builtin
|
|
5816
|
+
return getFunctionUnresolvedSymbols(fn, contextStack, getUndefinedSymbols, builtin);
|
|
6035
5817
|
}
|
|
6036
5818
|
};
|
|
6037
|
-
function getFunctionUnresolvedSymbols(fn, contextStack, getUndefinedSymbols, builtin
|
|
5819
|
+
function getFunctionUnresolvedSymbols(fn, contextStack, getUndefinedSymbols, builtin) {
|
|
6038
5820
|
const result = /* @__PURE__ */ new Set();
|
|
6039
5821
|
const newContext = { self: { value: null } };
|
|
6040
5822
|
fn[0].forEach((arg) => {
|
|
6041
5823
|
Object.assign(newContext, getAllBindingTargetNames(arg));
|
|
6042
5824
|
walkDefaults(arg, (defaultNode) => {
|
|
6043
|
-
addToSet(result, getUndefinedSymbols([defaultNode], contextStack, builtin
|
|
5825
|
+
addToSet(result, getUndefinedSymbols([defaultNode], contextStack, builtin));
|
|
6044
5826
|
});
|
|
6045
5827
|
});
|
|
6046
5828
|
const newContextStack = contextStack.create(newContext);
|
|
6047
|
-
addToSet(result, getUndefinedSymbols(fn[1], newContextStack, builtin
|
|
5829
|
+
addToSet(result, getUndefinedSymbols(fn[1], newContextStack, builtin));
|
|
6048
5830
|
return result;
|
|
6049
5831
|
}
|
|
6050
5832
|
const ifSpecialExpression = {
|
|
@@ -6085,7 +5867,7 @@ end`,
|
|
|
6085
5867
|
"if false then \"TRUE\" end"
|
|
6086
5868
|
]
|
|
6087
5869
|
},
|
|
6088
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
5870
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => getUndefinedSymbols(node[1][1].filter((n) => !!n), contextStack, builtin)
|
|
6089
5871
|
};
|
|
6090
5872
|
const unlessSpecialExpression = {
|
|
6091
5873
|
arity: {},
|
|
@@ -6122,7 +5904,7 @@ end`,
|
|
|
6122
5904
|
"unless false then \"TRUE\" end"
|
|
6123
5905
|
]
|
|
6124
5906
|
},
|
|
6125
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
5907
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => getUndefinedSymbols(node[1][1].filter((n) => !!n), contextStack, builtin)
|
|
6126
5908
|
};
|
|
6127
5909
|
const letSpecialExpression = {
|
|
6128
5910
|
arity: toFixedArity(0),
|
|
@@ -6145,13 +5927,13 @@ let a = 1 + 2 + 3 + 4;
|
|
|
6145
5927
|
let b = -> $ * ( $ + 1 );
|
|
6146
5928
|
b(a)`]
|
|
6147
5929
|
},
|
|
6148
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
5930
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => {
|
|
6149
5931
|
const bindingNode = node[1][1];
|
|
6150
5932
|
const target = bindingNode[1][0];
|
|
6151
5933
|
const value = bindingNode[1][1];
|
|
6152
|
-
const bindingResult = getUndefinedSymbols([value], contextStack, builtin
|
|
5934
|
+
const bindingResult = getUndefinedSymbols([value], contextStack, builtin);
|
|
6153
5935
|
walkDefaults(target, (defaultNode) => {
|
|
6154
|
-
addToSet(bindingResult, getUndefinedSymbols([defaultNode], contextStack, builtin
|
|
5936
|
+
addToSet(bindingResult, getUndefinedSymbols([defaultNode], contextStack, builtin));
|
|
6155
5937
|
});
|
|
6156
5938
|
contextStack.addValues(getAllBindingTargetNames(target), target[2]);
|
|
6157
5939
|
return bindingResult;
|
|
@@ -6188,7 +5970,7 @@ end`, `loop (n = 5, acc = 1) -> do
|
|
|
6188
5970
|
end
|
|
6189
5971
|
end`]
|
|
6190
5972
|
},
|
|
6191
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
5973
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => {
|
|
6192
5974
|
const bindingNodes = node[1][1];
|
|
6193
5975
|
const newContext = bindingNodes.reduce((context, bindingNode) => {
|
|
6194
5976
|
const names = getAllBindingTargetNames(bindingNode[1][0]);
|
|
@@ -6197,30 +5979,30 @@ end`]
|
|
|
6197
5979
|
});
|
|
6198
5980
|
return context;
|
|
6199
5981
|
}, {});
|
|
6200
|
-
return joinSets(getUndefinedSymbols(bindingNodes.map((bindingNode) => bindingNode[1][1]), contextStack, builtin
|
|
5982
|
+
return joinSets(getUndefinedSymbols(bindingNodes.map((bindingNode) => bindingNode[1][1]), contextStack, builtin), getUndefinedSymbols([node[1][2]], contextStack.create(newContext), builtin));
|
|
6201
5983
|
}
|
|
6202
5984
|
};
|
|
6203
5985
|
//#endregion
|
|
6204
5986
|
//#region src/builtin/specialExpressions/loops.ts
|
|
6205
|
-
function analyze(loopNode, contextStack, getUndefinedSymbols, builtin
|
|
5987
|
+
function analyze(loopNode, contextStack, getUndefinedSymbols, builtin) {
|
|
6206
5988
|
const result = /* @__PURE__ */ new Set();
|
|
6207
5989
|
const newContext = {};
|
|
6208
5990
|
const [, loopBindings, body] = loopNode[1];
|
|
6209
5991
|
loopBindings.forEach((loopBindingNode) => {
|
|
6210
5992
|
const [bindingNode, letBindings, whenNode, whileNode] = loopBindingNode;
|
|
6211
5993
|
const [target, value] = bindingNode[1];
|
|
6212
|
-
getUndefinedSymbols([value], contextStack.create(newContext), builtin
|
|
5994
|
+
getUndefinedSymbols([value], contextStack.create(newContext), builtin).forEach((symbol) => result.add(symbol));
|
|
6213
5995
|
Object.assign(newContext, getAllBindingTargetNames(target));
|
|
6214
5996
|
/* v8 ignore next */
|
|
6215
5997
|
if (letBindings) letBindings.forEach((letBindingNode) => {
|
|
6216
5998
|
const [letTarget, letValue] = letBindingNode[1];
|
|
6217
|
-
getUndefinedSymbols([letValue], contextStack.create(newContext), builtin
|
|
5999
|
+
getUndefinedSymbols([letValue], contextStack.create(newContext), builtin).forEach((symbol) => result.add(symbol));
|
|
6218
6000
|
Object.assign(newContext, getAllBindingTargetNames(letTarget));
|
|
6219
6001
|
});
|
|
6220
|
-
if (whenNode) getUndefinedSymbols([whenNode], contextStack.create(newContext), builtin
|
|
6221
|
-
if (whileNode) getUndefinedSymbols([whileNode], contextStack.create(newContext), builtin
|
|
6002
|
+
if (whenNode) getUndefinedSymbols([whenNode], contextStack.create(newContext), builtin).forEach((symbol) => result.add(symbol));
|
|
6003
|
+
if (whileNode) getUndefinedSymbols([whileNode], contextStack.create(newContext), builtin).forEach((symbol) => result.add(symbol));
|
|
6222
6004
|
});
|
|
6223
|
-
getUndefinedSymbols([body], contextStack.create(newContext), builtin
|
|
6005
|
+
getUndefinedSymbols([body], contextStack.create(newContext), builtin).forEach((symbol) => result.add(symbol));
|
|
6224
6006
|
return result;
|
|
6225
6007
|
}
|
|
6226
6008
|
const forSpecialExpression = {
|
|
@@ -6279,7 +6061,7 @@ for (
|
|
|
6279
6061
|
) -> ii + j
|
|
6280
6062
|
`]
|
|
6281
6063
|
},
|
|
6282
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6064
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => analyze(node, contextStack, getUndefinedSymbols, builtin)
|
|
6283
6065
|
};
|
|
6284
6066
|
const doseqSpecialExpression = {
|
|
6285
6067
|
arity: toFixedArity(1),
|
|
@@ -6329,7 +6111,7 @@ const doseqSpecialExpression = {
|
|
|
6329
6111
|
doseq (i in [1, 2, 3]) -> perform(effect(dvala.io.println), i * 2)
|
|
6330
6112
|
`]
|
|
6331
6113
|
},
|
|
6332
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6114
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => analyze(node, contextStack, getUndefinedSymbols, builtin)
|
|
6333
6115
|
};
|
|
6334
6116
|
const orSpecialExpression = {
|
|
6335
6117
|
arity: {},
|
|
@@ -6372,7 +6154,7 @@ const orSpecialExpression = {
|
|
|
6372
6154
|
}
|
|
6373
6155
|
return value;
|
|
6374
6156
|
},
|
|
6375
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6157
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => getUndefinedSymbols(node[1][1], contextStack, builtin)
|
|
6376
6158
|
};
|
|
6377
6159
|
const qqSpecialExpression = {
|
|
6378
6160
|
arity: { min: 1 },
|
|
@@ -6420,7 +6202,7 @@ Also works with undefined symbols — if a symbol is undefined, it is treated as
|
|
|
6420
6202
|
}
|
|
6421
6203
|
return null;
|
|
6422
6204
|
},
|
|
6423
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6205
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => getUndefinedSymbols(node[1][1], contextStack, builtin)
|
|
6424
6206
|
};
|
|
6425
6207
|
const recurSpecialExpression = {
|
|
6426
6208
|
arity: {},
|
|
@@ -6459,7 +6241,7 @@ end`
|
|
|
6459
6241
|
evaluateAsNormalExpression: (params) => {
|
|
6460
6242
|
throw new RecurSignal(params);
|
|
6461
6243
|
},
|
|
6462
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6244
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => getUndefinedSymbols(node[1][1], contextStack, builtin)
|
|
6463
6245
|
};
|
|
6464
6246
|
const arraySpecialExpression = {
|
|
6465
6247
|
arity: {},
|
|
@@ -6491,7 +6273,7 @@ const arraySpecialExpression = {
|
|
|
6491
6273
|
for (const param of params) result.push(asAny(param, sourceCodeInfo));
|
|
6492
6274
|
return result;
|
|
6493
6275
|
},
|
|
6494
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6276
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => getUndefinedSymbols(node[1][1], contextStack, builtin)
|
|
6495
6277
|
};
|
|
6496
6278
|
const effectSpecialExpression = {
|
|
6497
6279
|
arity: {},
|
|
@@ -6550,7 +6332,7 @@ let default = {
|
|
|
6550
6332
|
}
|
|
6551
6333
|
return result;
|
|
6552
6334
|
},
|
|
6553
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6335
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => getUndefinedSymbols(node[1][1], contextStack, builtin)
|
|
6554
6336
|
};
|
|
6555
6337
|
const importSpecialExpression = {
|
|
6556
6338
|
arity: toFixedArity(1),
|
|
@@ -6580,8 +6362,8 @@ const parallelSpecialExpression = {
|
|
|
6580
6362
|
description: "Evaluates all branch expressions concurrently and returns an array of results in order. Each branch runs as an independent trampoline invocation. If any branch suspends, the entire `parallel` suspends with a composite blob. On resume, branches are resumed one at a time. Only available in async mode (`run()`). Requires at least one branch.",
|
|
6581
6363
|
examples: []
|
|
6582
6364
|
},
|
|
6583
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6584
|
-
return joinSets(...node[1][1].map((branch) => getUndefinedSymbols([branch], contextStack, builtin
|
|
6365
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => {
|
|
6366
|
+
return joinSets(...node[1][1].map((branch) => getUndefinedSymbols([branch], contextStack, builtin)));
|
|
6585
6367
|
}
|
|
6586
6368
|
};
|
|
6587
6369
|
const performSpecialExpression = {
|
|
@@ -6612,9 +6394,9 @@ end
|
|
|
6612
6394
|
`],
|
|
6613
6395
|
seeAlso: ["effect?"]
|
|
6614
6396
|
},
|
|
6615
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6397
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => {
|
|
6616
6398
|
const [, effectExpr, argExprs] = node[1];
|
|
6617
|
-
return joinSets(getUndefinedSymbols([effectExpr], contextStack, builtin
|
|
6399
|
+
return joinSets(getUndefinedSymbols([effectExpr], contextStack, builtin), getUndefinedSymbols(argExprs, contextStack, builtin));
|
|
6618
6400
|
}
|
|
6619
6401
|
};
|
|
6620
6402
|
const raceSpecialExpression = {
|
|
@@ -6630,8 +6412,8 @@ const raceSpecialExpression = {
|
|
|
6630
6412
|
description: "Races all branch expressions concurrently. The first branch to complete wins — its value becomes the result. Losing branches are cancelled via AbortSignal. Errored branches are silently dropped. If all branches error, throws an aggregate error. If no branch completes but some suspend, the race suspends. On resume, the host provides the winner value directly. Only available in async mode (`run()`). Requires at least one branch.",
|
|
6631
6413
|
examples: []
|
|
6632
6414
|
},
|
|
6633
|
-
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin
|
|
6634
|
-
return joinSets(...node[1][1].map((branch) => getUndefinedSymbols([branch], contextStack, builtin
|
|
6415
|
+
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin }) => {
|
|
6416
|
+
return joinSets(...node[1][1].map((branch) => getUndefinedSymbols([branch], contextStack, builtin)));
|
|
6635
6417
|
}
|
|
6636
6418
|
};
|
|
6637
6419
|
//#endregion
|
|
@@ -6697,6 +6479,9 @@ function isFunctionDocs(docs) {
|
|
|
6697
6479
|
return "args" in docs && "variants" in docs;
|
|
6698
6480
|
}
|
|
6699
6481
|
//#endregion
|
|
6482
|
+
//#region src/builtin/modules/assertion/assertion.dvala
|
|
6483
|
+
var assertion_default = "{\n assert-fails: (fn, ...args) -> do\n let message = first(args);\n assert(function?(fn), \"First argument must be a function\");\n if not(null?(message)) then assert(string?(message), \"Second argument must be a string\") end;\n let failed-sentinel = effect(dvala.assertion.failed);\n let result = do fn() with case effect(dvala.error) then ([msg]) -> failed-sentinel end;\n if effect?(result) && result == failed-sentinel then\n null\n else\n assert(false, message ?? \"Expected function to fail\")\n end\n end,\n\n assert-fails-with: (fn, expected-error, ...args) -> do\n let message = first(args);\n assert(function?(fn), \"First argument must be a function\");\n assert(string?(expected-error), \"Second argument must be a string\");\n if not(null?(message)) then assert(string?(message), \"Third argument must be a string\") end;\n let failed-sentinel = effect(dvala.assertion.failed);\n let result = do fn() with case effect(dvala.error) then ([msg]) -> [failed-sentinel, msg] end;\n if array?(result) && first(result) == failed-sentinel then do\n let actual-error = second(result);\n if actual-error == expected-error then\n null\n else\n assert(false, message ?? (\"Expected function to fail with \\\"\" ++ expected-error ++ \"\\\" but got \\\"\" ++ actual-error ++ \"\\\"\"))\n end\n end\n else\n assert(false, message ?? (\"Expected function to fail with \\\"\" ++ expected-error ++ \"\\\"\"))\n end\n end,\n\n assert-succeeds: (fn, ...args) -> do\n let message = first(args);\n assert(function?(fn), \"First argument must be a function\");\n if not(null?(message)) then assert(string?(message), \"Second argument must be a string\") end;\n let failed-sentinel = effect(dvala.assertion.failed);\n let result = do fn() with case effect(dvala.error) then ([msg]) -> failed-sentinel end;\n if effect?(result) && result == failed-sentinel then\n assert(false, message ?? \"Expected function to succeed\")\n else\n null\n end\n end\n}\n";
|
|
6484
|
+
//#endregion
|
|
6700
6485
|
//#region src/builtin/modules/assertion/docs.ts
|
|
6701
6486
|
const moduleDocs$5 = {
|
|
6702
6487
|
"assert!=": {
|
|
@@ -6974,22 +6759,22 @@ const moduleDocs$5 = {
|
|
|
6974
6759
|
seeAlso: ["assertion.assert-truthy", "assertion.assert-falsy"],
|
|
6975
6760
|
hideOperatorForm: true
|
|
6976
6761
|
},
|
|
6977
|
-
"assert-
|
|
6762
|
+
"assert-fails": {
|
|
6978
6763
|
category: "assertion",
|
|
6979
|
-
description: "If $fun does not
|
|
6764
|
+
description: "If $fun does not fail (perform `dvala.error`), it throws `AssertionError`.",
|
|
6980
6765
|
returns: { type: "null" },
|
|
6981
6766
|
args: {
|
|
6982
6767
|
fun: { type: "function" },
|
|
6983
6768
|
message: { type: "string" }
|
|
6984
6769
|
},
|
|
6985
6770
|
variants: [{ argumentNames: ["fun"] }, { argumentNames: ["fun", "message"] }],
|
|
6986
|
-
examples: ["let { assert-
|
|
6987
|
-
seeAlso: ["assertion.assert-
|
|
6771
|
+
examples: ["let { assert-fails } = import(assertion);\nassert-fails(-> perform(effect(dvala.error), \"Error\"))", "let { assert-fails } = import(assertion);\ndo assert-fails(-> identity(\"Error\")) with case effect(dvala.error) then ([msg]) -> msg end"],
|
|
6772
|
+
seeAlso: ["assertion.assert-fails-with", "assertion.assert-succeeds"],
|
|
6988
6773
|
hideOperatorForm: true
|
|
6989
6774
|
},
|
|
6990
|
-
"assert-
|
|
6775
|
+
"assert-fails-with": {
|
|
6991
6776
|
category: "assertion",
|
|
6992
|
-
description: "If $fun does not
|
|
6777
|
+
description: "If $fun does not fail with $error-message, it throws `AssertionError`.",
|
|
6993
6778
|
returns: { type: "null" },
|
|
6994
6779
|
args: {
|
|
6995
6780
|
"fun": { type: "function" },
|
|
@@ -7001,21 +6786,21 @@ const moduleDocs$5 = {
|
|
|
7001
6786
|
"error-message",
|
|
7002
6787
|
"message"
|
|
7003
6788
|
] }],
|
|
7004
|
-
examples: ["let { assert-
|
|
7005
|
-
seeAlso: ["assertion.assert-
|
|
6789
|
+
examples: ["let { assert-fails-with } = import(assertion);\ndo assert-fails-with(-> perform(effect(dvala.error), \"Error\"), \"Error\") with case effect(dvala.error) then ([msg]) -> msg end", "let { assert-fails-with } = import(assertion);\ndo assert-fails-with(-> identity(\"Error\"), \"Error\") with case effect(dvala.error) then ([msg]) -> msg end"],
|
|
6790
|
+
seeAlso: ["assertion.assert-fails", "assertion.assert-succeeds"],
|
|
7006
6791
|
hideOperatorForm: true
|
|
7007
6792
|
},
|
|
7008
|
-
"assert-
|
|
6793
|
+
"assert-succeeds": {
|
|
7009
6794
|
category: "assertion",
|
|
7010
|
-
description: "If $fun
|
|
6795
|
+
description: "If $fun fails (performs `dvala.error`), it throws `AssertionError`.",
|
|
7011
6796
|
returns: { type: "null" },
|
|
7012
6797
|
args: {
|
|
7013
6798
|
fun: { type: "function" },
|
|
7014
6799
|
message: { type: "string" }
|
|
7015
6800
|
},
|
|
7016
6801
|
variants: [{ argumentNames: ["fun"] }, { argumentNames: ["fun", "message"] }],
|
|
7017
|
-
examples: ["let { assert-
|
|
7018
|
-
seeAlso: ["assertion.assert-
|
|
6802
|
+
examples: ["let { assert-succeeds } = import(assertion);\ndo assert-succeeds(-> identity(\"OK\")) with case effect(dvala.error) then ([msg]) -> msg end", "let { assert-succeeds } = import(assertion);\ndo assert-succeeds(-> perform(effect(dvala.error), \"Error\")) with case effect(dvala.error) then ([msg]) -> msg end"],
|
|
6803
|
+
seeAlso: ["assertion.assert-fails", "assertion.assert-fails-with"],
|
|
7019
6804
|
hideOperatorForm: true
|
|
7020
6805
|
},
|
|
7021
6806
|
"assert-array": {
|
|
@@ -7404,57 +7189,22 @@ const assertNormalExpression = {
|
|
|
7404
7189
|
max: 2
|
|
7405
7190
|
}
|
|
7406
7191
|
},
|
|
7407
|
-
"assert-
|
|
7408
|
-
evaluate: (
|
|
7409
|
-
if (message !== void 0) {
|
|
7410
|
-
assertString(message, sourceCodeInfo);
|
|
7411
|
-
message = ` ${message}`;
|
|
7412
|
-
}
|
|
7413
|
-
message ??= "";
|
|
7414
|
-
assertFunctionLike(func, sourceCodeInfo);
|
|
7415
|
-
return tryCatch(() => chain(executeFunction(func, [], contextStack, sourceCodeInfo), () => {
|
|
7416
|
-
throw new AssertionError(`Expected function to throw.${message}`, sourceCodeInfo);
|
|
7417
|
-
}), () => null);
|
|
7418
|
-
},
|
|
7192
|
+
"assert-fails": {
|
|
7193
|
+
evaluate: () => null,
|
|
7419
7194
|
arity: {
|
|
7420
7195
|
min: 1,
|
|
7421
7196
|
max: 2
|
|
7422
7197
|
}
|
|
7423
7198
|
},
|
|
7424
|
-
"assert-
|
|
7425
|
-
evaluate: (
|
|
7426
|
-
if (message !== void 0) {
|
|
7427
|
-
assertString(message, sourceCodeInfo);
|
|
7428
|
-
message = ` ${message}`;
|
|
7429
|
-
}
|
|
7430
|
-
message ??= "";
|
|
7431
|
-
assertString(throwMessage, sourceCodeInfo);
|
|
7432
|
-
assertFunctionLike(func, sourceCodeInfo);
|
|
7433
|
-
return tryCatch(() => chain(executeFunction(func, [], contextStack, sourceCodeInfo), () => {
|
|
7434
|
-
throw new AssertionError(`Expected function to throw "${throwMessage}".${message}`, sourceCodeInfo);
|
|
7435
|
-
}), (error) => {
|
|
7436
|
-
const errorMessage = error.shortMessage;
|
|
7437
|
-
if (errorMessage !== throwMessage) throw new AssertionError(`Expected function to throw "${throwMessage}", but thrown "${errorMessage}".${message}`, sourceCodeInfo);
|
|
7438
|
-
return null;
|
|
7439
|
-
});
|
|
7440
|
-
},
|
|
7199
|
+
"assert-fails-with": {
|
|
7200
|
+
evaluate: () => null,
|
|
7441
7201
|
arity: {
|
|
7442
7202
|
min: 2,
|
|
7443
7203
|
max: 3
|
|
7444
7204
|
}
|
|
7445
7205
|
},
|
|
7446
|
-
"assert-
|
|
7447
|
-
evaluate: (
|
|
7448
|
-
if (message !== void 0) {
|
|
7449
|
-
assertString(message, sourceCodeInfo);
|
|
7450
|
-
message = ` ${message}`;
|
|
7451
|
-
}
|
|
7452
|
-
message ??= "";
|
|
7453
|
-
assertFunctionLike(func, sourceCodeInfo);
|
|
7454
|
-
return tryCatch(() => chain(executeFunction(func, [], contextStack, sourceCodeInfo), () => null), () => {
|
|
7455
|
-
throw new AssertionError(`Expected function not to throw.${message}`, sourceCodeInfo);
|
|
7456
|
-
});
|
|
7457
|
-
},
|
|
7206
|
+
"assert-succeeds": {
|
|
7207
|
+
evaluate: () => null,
|
|
7458
7208
|
arity: {
|
|
7459
7209
|
min: 1,
|
|
7460
7210
|
max: 2
|
|
@@ -7662,7 +7412,7 @@ if (assertNormalExpression[key]) assertNormalExpression[key].docs = docs;
|
|
|
7662
7412
|
const assertModule = {
|
|
7663
7413
|
name: "assertion",
|
|
7664
7414
|
functions: assertNormalExpression,
|
|
7665
|
-
source:
|
|
7415
|
+
source: assertion_default,
|
|
7666
7416
|
docs: moduleDocs$5
|
|
7667
7417
|
};
|
|
7668
7418
|
//#endregion
|
|
@@ -17203,6 +16953,9 @@ const moduleDocs$1 = {
|
|
|
17203
16953
|
}
|
|
17204
16954
|
};
|
|
17205
16955
|
//#endregion
|
|
16956
|
+
//#region src/builtin/modules/number-theory/number-theory.dvala
|
|
16957
|
+
var number_theory_default = "do\n // Helper predicates\n let is-prime = (n) ->\n if n < 2 then false\n else if n == 2 then true\n else if n % 2 == 0 then false\n else loop (i = 3) ->\n if i * i > n then true\n else if n % i == 0 then false\n else recur(i + 2) end\n end\n end\n end\n end;\n\n let is-perfect-square = (n) ->\n if n < 0 then false\n else do\n let s = floor(sqrt(n));\n s * s == n\n end end;\n\n let is-perfect-cube = (n) -> do\n let c = round(sign(n) * (abs(n) ^ (1 / 3)));\n c * c * c == n\n end;\n\n let sum-proper-divisors = (n) ->\n if n <= 1 then 0\n else loop (i = 2, acc = 1) ->\n if i * i > n then acc\n else if n % i == 0 then\n if i * i == n then recur(i + 1, acc + i)\n else recur(i + 1, acc + i + n / i) end\n else recur(i + 1, acc) end\n end end;\n\n let is-abundant = (n) -> n > 0 && sum-proper-divisors(n) > n;\n let is-deficient = (n) -> n > 0 && sum-proper-divisors(n) < n;\n let is-composite = (n) -> n > 1 && not(is-prime(n));\n\n let is-happy = (n) -> do\n let sum-of-squared-digits = (x) ->\n loop (num = x, acc = 0) ->\n if num == 0 then acc\n else do\n let d = num % 10;\n recur(floor(num / 10), acc + d * d)\n end end;\n loop (slow = n, fast = sum-of-squared-digits(n)) ->\n if fast == 1 then true\n else if slow == fast then false\n else recur(sum-of-squared-digits(slow), sum-of-squared-digits(sum-of-squared-digits(fast))) end\n end\n end;\n\n let count-bits = (n) ->\n loop (x = n, acc = 0) ->\n if x == 0 then acc\n else recur(floor(x / 2), acc + x % 2) end;\n\n let is-perfect-power = (n) ->\n if n == 1 then true\n else if n < 2 then false\n else loop (k = 2) ->\n if 2 ^ k > n then false\n else do\n let b = round(n ^ (1 / k));\n if b ^ k == n then true\n else recur(k + 1) end\n end\n end end end;\n\n let binom = (n, k) ->\n if k == 0 || k == n then 1\n else loop (i = 0, k2 = min(k, n - k), acc = 1) ->\n if i >= k2 then acc\n else recur(i + 1, k2, acc * (n - i) / (i + 1)) end\n end;\n\n let bell-numbers = [1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597, 27644437, 190899322, 1382958545, 10480142147, 82864869804, 682076806159, 5832742205057, 51724158235372, 474869816156751, 4506715738447323];\n\n let catalan-numbers = [1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, 18367353072152, 69533550916004, 263747951750360, 1002242216651368, 3814986502092304];\n\n let mersenne-numbers = [3, 7, 31, 127, 2047, 8191, 131071, 524287, 2147483647];\n\n let perfect-numbers = [6, 28, 496, 8128, 33550336, 8589869056, 137438691328];\n\n let sylvester-numbers = [2, 6, 42, 1806, 3263442, 10650056950806];\n\n let lucky-numbers = [1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, 87, 93, 99, 105, 111, 115, 127, 129, 133, 135, 141, 151, 159, 163, 169, 171, 189, 193, 195, 201, 205, 211, 219, 223, 231, 235, 237, 241, 259, 261, 267, 273, 283, 285, 289, 297, 303, 307, 319, 321, 327, 331, 339, 349, 357, 361, 367, 385, 391, 393, 399, 409, 415, 421, 427, 429, 433, 451, 463, 475, 477, 483, 487, 489, 495, 511, 517, 519, 529, 535, 537, 541, 553, 559, 577, 579, 583, 591, 601, 613, 615, 619, 621, 631, 639, 643, 645, 651, 655, 673, 679, 685, 693, 699, 717, 723, 727, 729, 735, 739, 741, 745, 769, 777, 781, 787, 801, 805, 819, 823, 831, 841, 855, 867, 873, 883, 885, 895, 897, 903, 925, 927, 931, 933, 937, 957, 961, 975, 979, 981, 991, 993, 997, 1009, 1011, 1021, 1023, 1029, 1039, 1041, 1053, 1057, 1087, 1093, 1095, 1101, 1105, 1107, 1117, 1123, 1147, 1155, 1167, 1179, 1183, 1189, 1197, 1201, 1203, 1209, 1219, 1231, 1233, 1245, 1249, 1251, 1261, 1263, 1275, 1281, 1285, 1291, 1303, 1309, 1323, 1329, 1339, 1357, 1365, 1369, 1387, 1389, 1395, 1401, 1417, 1419, 1435, 1441, 1455, 1459, 1471, 1473, 1485, 1491, 1495, 1497, 1501, 1503, 1519, 1533, 1543, 1545, 1563, 1567, 1575, 1579, 1585, 1587, 1597, 1599, 1611, 1639, 1641, 1645, 1659, 1663, 1675, 1693, 1701, 1705, 1711, 1723, 1731, 1737, 1749, 1765, 1767, 1771, 1773, 1777, 1797, 1801, 1809, 1819, 1827, 1831, 1833, 1839, 1857, 1869, 1879, 1893, 1899, 1915, 1921, 1923, 1933, 1941, 1945, 1959, 1963, 1965, 1977, 1983, 1987, 1995, 2001, 2019, 2023, 2031, 2053, 2059, 2065, 2067, 2079, 2083, 2085, 2095, 2113, 2115, 2121, 2125, 2127, 2133, 2163, 2173, 2187, 2209, 2211, 2215, 2217, 2221, 2239, 2251, 2253, 2257, 2271, 2277, 2281, 2283, 2301, 2311, 2317, 2323, 2335, 2343, 2355, 2365, 2379, 2395, 2403, 2407, 2409, 2415, 2419, 2427, 2439, 2445, 2461, 2467, 2473, 2479, 2491, 2493, 2505, 2511, 2523, 2527, 2545, 2557, 2563, 2571, 2575, 2587, 2589, 2593, 2599, 2607, 2625, 2635, 2647, 2649, 2653, 2661, 2667, 2671, 2689, 2697, 2715, 2725, 2755, 2763, 2773, 2781, 2785, 2787, 2797, 2815, 2817, 2821, 2823, 2827, 2835, 2841, 2845, 2851, 2877, 2887, 2899, 2901, 2905, 2913, 2923, 2943, 2953, 2961, 2971, 2973, 2977, 2983, 3003, 3007, 3027, 3031, 3037, 3039, 3049, 3055, 3073, 3075, 3091, 3097, 3099, 3109, 3111, 3121, 3123, 3133, 3153, 3163, 3171, 3175, 3183, 3187, 3199, 3213, 3223, 3229, 3235, 3243, 3259, 3261, 3289, 3297, 3301, 3307, 3313, 3325, 3339, 3351, 3355, 3363, 3381, 3403, 3405, 3409, 3411, 3427, 3433, 3439, 3451, 3453, 3465, 3477, 3481, 3487, 3489, 3495, 3499, 3507, 3559, 3565, 3571, 3579, 3595, 3597, 3603, 3607, 3613, 3621, 3625, 3633, 3655, 3661, 3663, 3669, 3675, 3685, 3687, 3697, 3709, 3717, 3721, 3727, 3747, 3753, 3763, 3771, 3781, 3789, 3793, 3795, 3811, 3843, 3847, 3849, 3865, 3873, 3879, 3889, 3891, 3897, 3909, 3915, 3931, 3943, 3951, 3955, 3969, 3975, 3981, 3991, 3999, 4003, 4015, 4023, 4033, 4035, 4041, 4045, 4063, 4069, 4081, 4095, 4105, 4107, 4129, 4131, 4161, 4165, 4173, 4179, 4189, 4195, 4201, 4203, 4207, 4227, 4237, 4251, 4255, 4257, 4263, 4269, 4285, 4287, 4315, 4321, 4329, 4335, 4363, 4377, 4383, 4389, 4399, 4413, 4431, 4441, 4443, 4455, 4461, 4465, 4483, 4485, 4495, 4509, 4519, 4521, 4539, 4551, 4561, 4567, 4569, 4573, 4587, 4609, 4611, 4621, 4623, 4629, 4645, 4647, 4653, 4663, 4671, 4675, 4695, 4699, 4713, 4717, 4725, 4741, 4761, 4767, 4773, 4797, 4801, 4809, 4813, 4819, 4833, 4837, 4839, 4843, 4851, 4863, 4867, 4881, 4887, 4893, 4929, 4951, 4963, 4965, 4969, 4977, 4987, 4989, 4993, 4999, 5001, 5007, 5019, 5029, 5041, 5043, 5049, 5053, 5089, 5103, 5127, 5137, 5139, 5149, 5151, 5157, 5169, 5179, 5181, 5191, 5211, 5217, 5229, 5233, 5235, 5253, 5259, 5277, 5283, 5293, 5295, 5299, 5325, 5335, 5341, 5343, 5371, 5377, 5379, 5385, 5409, 5419, 5427, 5433, 5449, 5455, 5463, 5473, 5487, 5491, 5503, 5515, 5527, 5547, 5551, 5559, 5569, 5577, 5587, 5589, 5593, 5599, 5613, 5617, 5637, 5641, 5649, 5655, 5661, 5671, 5673, 5679, 5691, 5701, 5707, 5713, 5719, 5737, 5755, 5763, 5767, 5769, 5803, 5809, 5817, 5827, 5833, 5839, 5851, 5869, 5883, 5889, 5893, 5901, 5905, 5911, 5913, 5923, 5959, 5965, 5967, 5971, 5973, 5977, 5991, 5997, 6009, 6019, 6031, 6049, 6055, 6061, 6079, 6093, 6111, 6115, 6123, 6141, 6147, 6159, 6163, 6175, 6177, 6195, 6211, 6229, 6237, 6243, 6249, 6253, 6271, 6273, 6279, 6301, 6309, 6331, 6345, 6351, 6355, 6363, 6367, 6369, 6373, 6379, 6385, 6399, 6411, 6415, 6427, 6433, 6435, 6447, 6463, 6471, 6475, 6477, 6501, 6505, 6523, 6531, 6535, 6541, 6553, 6559, 6567, 6573, 6601, 6621, 6625, 6631, 6661, 6663, 6667, 6669, 6679, 6687, 6693, 6715, 6723, 6733, 6741, 6745, 6747, 6753, 6757, 6763, 6765, 6783, 6787, 6789, 6841, 6849, 6867, 6871, 6883, 6891, 6909, 6915, 6921, 6931, 6933, 6937, 6951, 6981, 6985, 6999, 7003, 7009, 7035, 7041, 7045, 7047, 7069, 7077, 7081, 7087, 7101, 7111, 7129, 7135, 7153, 7167, 7171, 7173, 7183, 7191, 7195, 7197, 7207, 7215, 7231, 7233, 7237, 7245, 7249, 7279, 7293, 7299, 7311, 7321, 7333, 7339, 7341, 7345, 7357, 7359, 7371, 7377, 7395, 7401, 7405, 7419, 7435, 7437, 7443, 7447, 7459, 7471, 7489, 7501, 7503, 7507, 7531, 7533, 7549, 7551, 7563, 7567, 7575, 7585, 7591, 7593, 7603, 7609, 7629, 7633, 7639, 7645, 7677, 7687, 7689, 7701, 7711, 7717, 7737, 7755, 7779, 7791, 7795, 7801, 7803, 7813, 7827, 7833, 7837, 7855, 7881, 7885, 7897, 7899, 7909, 7917, 7921, 7929, 7939, 7947, 7951, 7963, 7969, 7971, 8001, 8005, 8007, 8013, 8037, 8047, 8071, 8073, 8085, 8089, 8107, 8109, 8127, 8131, 8139, 8151, 8161, 8169, 8173, 8175, 8191, 8193, 8221, 8223, 8227, 8233, 8253, 8257, 8263, 8269, 8283, 8289, 8299, 8325, 8331, 8347, 8359, 8365, 8367, 8379, 8409, 8413, 8421, 8445, 8449, 8467, 8473, 8475, 8479, 8487, 8493, 8515, 8535, 8539, 8551, 8553, 8575, 8577, 8583, 8589, 8601, 8605, 8611, 8617, 8635, 8637, 8641, 8647, 8655, 8661, 8673, 8683, 8719, 8757, 8769, 8773, 8787, 8793, 8805, 8809, 8827, 8829, 8833, 8835, 8841, 8869, 8871, 8895, 8913, 8931, 8937, 8947, 8955, 8961, 8977, 8979, 8989, 8995, 8997, 9009, 9031, 9033, 9061, 9063, 9073, 9075, 9081, 9085, 9115, 9117, 9121, 9123, 9135, 9139, 9145, 9151, 9177, 9181, 9211, 9213, 9223, 9231, 9235, 9249, 9253, 9267, 9273, 9277, 9285, 9291, 9303, 9315, 9331, 9339, 9349, 9373, 9387, 9399, 9403, 9409, 9421, 9423, 9429, 9441, 9451, 9457, 9471, 9475, 9481, 9483, 9487, 9501, 9535, 9537, 9543, 9547, 9549, 9555, 9561, 9567, 9613, 9621, 9625, 9631, 9643, 9649, 9661, 9663, 9675, 9687, 9691, 9703, 9727, 9733, 9751, 9753, 9775, 9787, 9789, 9795, 9801, 9807, 9811, 9813, 9837, 9841, 9883, 9895, 9915, 9927, 9937, 9957, 9961, 9979, 9985, 9987, 9997, 9999, 10003, 10009, 10017, 10041, 10051, 10059, 10069, 10071, 10083, 10087, 10089, 10095, 10111, 10117, 10125, 10131, 10143, 10147, 10149, 10153, 10173, 10191, 10195, 10197, 10221, 10239, 10255, 10261, 10275, 10279, 10291, 10311, 10315, 10317, 10321, 10341, 10363, 10365, 10387, 10399, 10411, 10417, 10431, 10441, 10443, 10459, 10461, 10471, 10501, 10507, 10509, 10525, 10531, 10533, 10555, 10563, 10569, 10575, 10585, 10587, 10597, 10599, 10605, 10609, 10635, 10651, 10653, 10659, 10671, 10683, 10723, 10725, 10731, 10747, 10753, 10755, 10759, 10773, 10785, 10789, 10797, 10809, 10843, 10849, 10873, 10881, 10891, 10903, 10909, 10911, 10921, 10923, 10945, 10953, 10965, 10975, 10977, 11005, 11011, 11017, 11047, 11055, 11059, 11073, 11077, 11089, 11091, 11097, 11113, 11137, 11157, 11163, 11173, 11181, 11193, 11197, 11205, 11217, 11223, 11227, 11239, 11245, 11247, 11259, 11263, 11269, 11283, 11289, 11301, 11323, 11341, 11343, 11371, 11373, 11377, 11389, 11391, 11395, 11407, 11419, 11425, 11427, 11437, 11439, 11475, 11479, 11487, 11491, 11521, 11529, 11535, 11539, 11541, 11577, 11581, 11583, 11599, 11617, 11623, 11629, 11641, 11643, 11659, 11667, 11677, 11679, 11707, 11721, 11725, 11731, 11769, 11781, 11797, 11803, 11811, 11815, 11823, 11827, 11833, 11835, 11845, 11847, 11853, 11865, 11877, 11887, 11911, 11923, 11929, 11943, 11953, 11959, 11961, 11991, 11995, 12007, 12015, 12025, 12049, 12057, 12063, 12069, 12079, 12097, 12103, 12117, 12121, 12133, 12139, 12141, 12151, 12159, 12163, 12165, 12193, 12201, 12207, 12223, 12237, 12243, 12265, 12267, 12285, 12295, 12301, 12307, 12315, 12319, 12321, 12333, 12337, 12357, 12363, 12373, 12379, 12391, 12399, 12411, 12417, 12427, 12435, 12457, 12481, 12487, 12495, 12499, 12519, 12543, 12547, 12553, 12567, 12579, 12589, 12607, 12609, 12621, 12631, 12645, 12649, 12651, 12673, 12679, 12699, 12709, 12711, 12729, 12735, 12741, 12759, 12763, 12777, 12781, 12799, 12801, 12813, 12819, 12861, 12867, 12877, 12885, 12903, 12907, 12925, 12937, 12951, 12957, 12961, 12969, 12991, 12999, 13009, 13011, 13021, 13027, 13029, 13053, 13057, 13063, 13077, 13083, 13113, 13117, 13119, 13125, 13129, 13135, 13141, 13167, 13177, 13179, 13203, 13209, 13215, 13219, 13243, 13245, 13267, 13273, 13279, 13281, 13285, 13293, 13309, 13317, 13323, 13327, 13335, 13345, 13347, 13359, 13363, 13371, 13387, 13419, 13441, 13443, 13465, 13473, 13485, 13489, 13513, 13515, 13519, 13527, 13531, 13533, 13537, 13551, 13567, 13575, 13581, 13587, 13599, 13609, 13633, 13657, 13677, 13681, 13693, 13695, 13707, 13723, 13725, 13737, 13741, 13743, 13759, 13801, 13803, 13821, 13831, 13833, 13849, 13851, 13861, 13873, 13893, 13897, 13929, 13947, 13953, 13957, 13995, 14007, 14017, 14031, 14035, 14037, 14041, 14049, 14053, 14059, 14073, 14079, 14091, 14095, 14113, 14115, 14119, 14137, 14163, 14179, 14181, 14185, 14199, 14205, 14209, 14211, 14217, 14229, 14245, 14247, 14253, 14281, 14287, 14293, 14307, 14313, 14317, 14331, 14347, 14349, 14353, 14367, 14395, 14407, 14419, 14427, 14437, 14439, 14443, 14449, 14457, 14461, 14473, 14491, 14493, 14505, 14521, 14523, 14539, 14541, 14565, 14587, 14595, 14599, 14601, 14607, 14625, 14661, 14667, 14689, 14691, 14713, 14715, 14721, 14731, 14749, 14751, 14755, 14775, 14779, 14785, 14793, 14797, 14817, 14841, 14875, 14881, 14883, 14899, 14905, 14919, 14923, 14931, 14935, 14943, 14947, 14973, 14977, 14997, 15003, 15007, 15009, 15025, 15031, 15049, 15057, 15063, 15069, 15073, 15081, 15103, 15109, 15121, 15129, 15133, 15141, 15165, 15169, 15175, 15183, 15187, 15189, 15193, 15205, 15213, 15217, 15229, 15231, 15235, 15237, 15247, 15255, 15259, 15261, 15271, 15291, 15301, 15313, 15333, 15355, 15379, 15381, 15385, 15397, 15417, 15445, 15457, 15469, 15471, 15481, 15487, 15489, 15511, 15519, 15523, 15531, 15543, 15547, 15567, 15573, 15577, 15585, 15597, 15609, 15645, 15655, 15661, 15673, 15675, 15693, 15697, 15717, 15735, 15763, 15771, 15783, 15793, 15805, 15817, 15819, 15835, 15843, 15847, 15855, 15879, 15883, 15891, 15901, 15907, 15919, 15927, 15939, 15955, 15969, 15975, 15981, 15993, 16003, 16009, 16023, 16045, 16047, 16053, 16057, 16077, 16081, 16095, 16101, 16135, 16153, 16191, 16195, 16197, 16203, 16213, 16227, 16237, 16245, 16255, 16267, 16275, 16279, 16287, 16297, 16309, 16329, 16333, 16341, 16353, 16359, 16365, 16381, 16387, 16389, 16393, 16395, 16413, 16417, 16429, 16431, 16447, 16449, 16467, 16473, 16479, 16491, 16507, 16521, 16539, 16557, 16573, 16591, 16611, 16615, 16617, 16621, 16635, 16639, 16657, 16665, 16677, 16701, 16707, 16725, 16747, 16765, 16771, 16773, 16791, 16795, 16825, 16827, 16845, 16863, 16867, 16893, 16915, 16917, 16921, 16933, 16939, 16947, 16953, 16957, 16959, 16969, 16971, 16981, 16995, 17001, 17011, 17017, 17019, 17035, 17047, 17053, 17061, 17083, 17085, 17103, 17115, 17119, 17125, 17127, 17151, 17157, 17173, 17181, 17209, 17211, 17215, 17221, 17223, 17229, 17251, 17253, 17283, 17287, 17305, 17313, 17329, 17335, 17341, 17355, 17359, 17367, 17389, 17391, 17401, 17409, 17431, 17433, 17455, 17463, 17467, 17473, 17485, 17497, 17517, 17527, 17535, 17545, 17547, 17563, 17565, 17581, 17589, 17619, 17625, 17671, 17677, 17689, 17695, 17703, 17713, 17725, 17733, 17737, 17749, 17767, 17769, 17775, 17781, 17787, 17797, 17811, 17829, 17851, 17875, 17883, 17893, 17913, 17925, 17935, 17943, 17947, 17965, 17977, 17991, 17997, 18001, 18007, 18019, 18025, 18043, 18049, 18055, 18067, 18085, 18087, 18123, 18127, 18145, 18147, 18151, 18153, 18169, 18175, 18181, 18187, 18189, 18195, 18207, 18211, 18237, 18253, 18261, 18279, 18283, 18285, 18295, 18303, 18315, 18333, 18375, 18381, 18397, 18399, 18403, 18409, 18441, 18445, 18451, 18459, 18465, 18469, 18475, 18493, 18495, 18501, 18513, 18523, 18535, 18543, 18589, 18591, 18597, 18615, 18619, 18621, 18633, 18639, 18655, 18661, 18681, 18693, 18715, 18717, 18723, 18745, 18747, 18757, 18759, 18765, 18775, 18777, 18783, 18787, 18817, 18819, 18825, 18837, 18849, 18853, 18871, 18873, 18879, 18915, 18937, 18943, 18951, 18967, 18969, 18975, 18979, 18987, 19009, 19015, 19017, 19033, 19051, 19081, 19113, 19119, 19125, 19131, 19153, 19155, 19159, 19161, 19173, 19195, 19197, 19207, 19225, 19237, 19261, 19263, 19269, 19285, 19309, 19323, 19327, 19329, 19333, 19341, 19347, 19351, 19357, 19363, 19365, 19371, 19389, 19395, 19405, 19411, 19417, 19435, 19455, 19467, 19477, 19479, 19503, 19521, 19533, 19543, 19551, 19579, 19581, 19603, 19609, 19615, 19627, 19629, 19657, 19659, 19687, 19693, 19705, 19707, 19711, 19719, 19723, 19725, 19731, 19735, 19755, 19767, 19771, 19773, 19783, 19791, 19807, 19825, 19851, 19861, 19869, 19875, 19893, 19917, 19921, 19929, 19939, 19963, 19981, 19993, 20005, 20013, 20017, 20043, 20067, 20071, 20077, 20085, 20089, 20101, 20103, 20121, 20133, 20149, 20151, 20169, 20181, 20185, 20197, 20203, 20215, 20227, 20253, 20257, 20271, 20295, 20307, 20319, 20341, 20349, 20353, 20355, 20359, 20371, 20379, 20385, 20397, 20403, 20425, 20445, 20449, 20455, 20461, 20475, 20485, 20487, 20509, 20511, 20539, 20551, 20563, 20581, 20583, 20587, 20605, 20611, 20613, 20649, 20665, 20679, 20697, 20713, 20731, 20733, 20739, 20757, 20763, 20769, 20773, 20793, 20797, 20805, 20811, 20821, 20823, 20833, 20835, 20839, 20845, 20859, 20875, 20887, 20889, 20899, 20905, 20923, 20937, 20941, 20953, 20959, 20965, 20991, 21013, 21015, 21021, 21027, 21043, 21049, 21051, 21055, 21073, 21075, 21111, 21115, 21129, 21139, 21147, 21153, 21169, 21175, 21177, 21189, 21193, 21199, 21205, 21211, 21223, 21231, 21253, 21255, 21307, 21309, 21315, 21327, 21331, 21337, 21345, 21373, 21381, 21405, 21409, 21411, 21421, 21433, 21445, 21451, 21453, 21469, 21471, 21475, 21499, 21505, 21529, 21531, 21537, 21549, 21567, 21571, 21591, 21597, 21609, 21613, 21615, 21621, 21655, 21663, 21687, 21693, 21703, 21709, 21717, 21721, 21735, 21739, 21751, 21757, 21759, 21771, 21787, 21819, 21841, 21847, 21867, 21885, 21891, 21897, 21913, 21915, 21925, 21927, 21931, 21933, 21957, 21967, 21987, 21993, 22009, 22017, 22035, 22039, 22075, 22087, 22093, 22095, 22099, 22113, 22119, 22125, 22147, 22155, 22165, 22167, 22177, 22185, 22197, 22225, 22227, 22231, 22269, 22281, 22305, 22327, 22333, 22339, 22369, 22371, 22377, 22381, 22399, 22401, 22411, 22417, 22431, 22437, 22461, 22471, 22473, 22479, 22503, 22507, 22521, 22525, 22527, 22533, 22555, 22569, 22585, 22587, 22591, 22597, 22603, 22617, 22627, 22629, 22651, 22683, 22687, 22689, 22701, 22711, 22743, 22779, 22789, 22791, 22795, 22807, 22827, 22839, 22843, 22851, 22855, 22869, 22879, 22881, 22885, 22893, 22911, 22921, 22941, 22947, 22953, 22957, 22965, 22969, 22975, 22981, 22987, 22999, 23007, 23031, 23037, 23041, 23061, 23067, 23083, 23089, 23095, 23101, 23109, 23137, 23145, 23163, 23169, 23173, 23191, 23193, 23199, 23205, 23269, 23271, 23293, 23295, 23311, 23323, 23341, 23343, 23353, 23355, 23361, 23365, 23373, 23377, 23397, 23419, 23421, 23427, 23445, 23449, 23451, 23457, 23469, 23479, 23499, 23515, 23523, 23529, 23533, 23551, 23563, 23565, 23569, 23571, 23577, 23607, 23613, 23649, 23671, 23677, 23689, 23701, 23709, 23721, 23767, 23775, 23781, 23799, 23805, 23815, 23829, 23835, 23851, 23857, 23881, 23889, 23893, 23913, 23919, 23925, 23929, 23943, 23953, 23955, 23961, 23965, 23971, 23973, 23991, 24013, 24015, 24025, 24033, 24037, 24069, 24073, 24117, 24121, 24129, 24133, 24145, 24151, 24181, 24183, 24213, 24217, 24237, 24247, 24255, 24261, 24277, 24285, 24289, 24301, 24309, 24321, 24327, 24331, 24333, 24343, 24363, 24381, 24387, 24397, 24403, 24405, 24423, 24429, 24447, 24451, 24481, 24499, 24523, 24531, 24571, 24573, 24585, 24591, 24603, 24619, 24633, 24637, 24639, 24643, 24645, 24649, 24663, 24669, 24709, 24711, 24727, 24729, 24733, 24739, 24741, 24759, 24763, 24771, 24783, 24789, 24805, 24811, 24829, 24831, 24843, 24855, 24865, 24873, 24877, 24895, 24907, 24909, 24933, 24951, 24957, 24963, 24985, 24991, 25015, 25017, 25021, 25033, 25057, 25063, 25095, 25099, 25107, 25117, 25119, 25129, 25147, 25153, 25159, 25167, 25171, 25185, 25189, 25201, 25213, 25215, 25225, 25237, 25255, 25263, 25285, 25287, 25293, 25309, 25317, 25335, 25341, 25347, 25377, 25389, 25413, 25425, 25431, 25441, 25455, 25461, 25477, 25483, 25489, 25497, 25503, 25525, 25549, 25561, 25567, 25569, 25581, 25591, 25593, 25611, 25621, 25623, 25645, 25647, 25657, 25671, 25677, 25687, 25737, 25753, 25759, 25771, 25773, 25803, 25815, 25819, 25821, 25833, 25837, 25845, 25855, 25861, 25875, 25893, 25909, 25917, 25923, 25929, 25939, 25959, 25963, 25971, 25977, 25987, 26005, 26007, 26011, 26025, 26035, 26041, 26071, 26085, 26103, 26107, 26115, 26119, 26149, 26155, 26167, 26169, 26179, 26209, 26215, 26217, 26221, 26229, 26251, 26263, 26281, 26293, 26295, 26301, 26313, 26319, 26343, 26347, 26359, 26365, 26385, 26397, 26409, 26413, 26431, 26445, 26467, 26505, 26523, 26529, 26533, 26547, 26553, 26565, 26595, 26599, 26617, 26629, 26641, 26649, 26655, 26659, 26665, 26683, 26695, 26697, 26703, 26719, 26721, 26727, 26733, 26749, 26755, 26757, 26781, 26797, 26805, 26841, 26845, 26847, 26881, 26883, 26893, 26905, 26907, 26913, 26923, 26925, 26935, 26943, 26997, 27001, 27007, 27009, 27013, 27027, 27031, 27033, 27037, 27039, 27061, 27063, 27075, 27079, 27091, 27093, 27097, 27105, 27141, 27157, 27189, 27195, 27199, 27201, 27205, 27207, 27217, 27237, 27265, 27271, 27283, 27301, 27309, 27315, 27321, 27325, 27331, 27333, 27349, 27357, 27363, 27387, 27393, 27409, 27415, 27417, 27427, 27435, 27453, 27457, 27469, 27475, 27477, 27483, 27489, 27493, 27501, 27511, 27531, 27541, 27561, 27585, 27595, 27597, 27603, 27639, 27663, 27667, 27691, 27693, 27705, 27711, 27741, 27751, 27757, 27765, 27783, 27793, 27805, 27807, 27813, 27829, 27831, 27847, 27855, 27859, 27871, 27879, 27913, 27915, 27951, 27961, 27963, 27975, 28021, 28023, 28027, 28039, 28069, 28071, 28083, 28087, 28089, 28101, 28105, 28119, 28123, 28129, 28131, 28141, 28161, 28167, 28191, 28195, 28203, 28233, 28239, 28245, 28293, 28311, 28321, 28329, 28339, 28351, 28359, 28365, 28375, 28393, 28405, 28417, 28429, 28435, 28437, 28459, 28467, 28483, 28509, 28513, 28525, 28563, 28569, 28581, 28593, 28605, 28633, 28639, 28677, 28689, 28701, 28707, 28735, 28759, 28765, 28771, 28791, 28797, 28801, 28803, 28815, 28825, 28827, 28837, 28843, 28855, 28857, 28867, 28869, 28887, 28891, 28905, 28921, 28923, 28933, 28951, 28963, 28969, 28987, 28989, 28993, 28995, 29005, 29025, 29031, 29035, 29049, 29055, 29065, 29089, 29091, 29095, 29113, 29121, 29127, 29137, 29143, 29149, 29157, 29175, 29185, 29193, 29203, 29205, 29239, 29253, 29281, 29283, 29287, 29295, 29311, 29317, 29319, 29329, 29341, 29349, 29371, 29391, 29413, 29437, 29451, 29457, 29467, 29473, 29485, 29487, 29493, 29497, 29515, 29517, 29521, 29533, 29535, 29563, 29577, 29589, 29595, 29599, 29611, 29613, 29623, 29625, 29653, 29659, 29661, 29665, 29677, 29689, 29697, 29709, 29715, 29721, 29751, 29757, 29779, 29781, 29787, 29791, 29805, 29815, 29829, 29845, 29847, 29851, 29865, 29877, 29893, 29905, 29913, 29925, 29949, 29959, 29971, 29973, 29989, 29995, 30013, 30021, 30061, 30067, 30073, 30075, 30087, 30103, 30115, 30121, 30159, 30163, 30181, 30207, 30225, 30229, 30231, 30241, 30243, 30253, 30261, 30265, 30273, 30289, 30291, 30303, 30313, 30327, 30337, 30367, 30369, 30373, 30387, 30397, 30409, 30411, 30429, 30439, 30465, 30471, 30475, 30477, 30495, 30499, 30505, 30523, 30529, 30537, 30541, 30543, 30547, 30559, 30565, 30567, 30589, 30601, 30643, 30651, 30681, 30687, 30727, 30747, 30753, 30765, 30775, 30777, 30789, 30793, 30807, 30817, 30837, 30849, 30861, 30871, 30873, 30877, 30885, 30901, 30915, 30919, 30943, 30945, 30949, 30969, 30997, 30999, 31003, 31021, 31029, 31033, 31039, 31051, 31069, 31071, 31081, 31093, 31095, 31107, 31135, 31137, 31143, 31147, 31189, 31191, 31207, 31221, 31231, 31237, 31239, 31249, 31251, 31255, 31261, 31263, 31293, 31303, 31311, 31315, 31335, 31341, 31363, 31381, 31383, 31387, 31389, 31395, 31405, 31411, 31425, 31429];\n\n let partition-numbers = [1, 2, 3, 5, 7, 11, 15, 22, 30, 42, 56, 77, 101, 135, 176, 231, 297, 385, 490, 627, 792, 1002, 1255, 1575, 1958, 2436, 3010, 3718, 4565, 5604, 6842, 8349, 10143, 12310, 14883, 17977, 21637, 26015, 31185, 37338, 44583, 53174, 63261, 75175, 89134, 105558, 124754, 147273, 173525, 204226, 239943, 281589, 329931, 386155, 451276, 526823, 614154, 715220, 831820, 966467, 1121505, 1300156, 1505499, 1741630, 2012558, 2323520, 2679689, 3087735, 3554345, 4087968, 4697205, 5392783, 6185689, 7089500, 8118264, 9289091, 10619863, 12132164, 13848650, 15796476, 18004327, 20506255, 23338469, 26543660, 30167357, 34262962, 38887673, 44108109, 49995925, 56634173, 64112359, 72533807, 82010177, 92669720, 104651419, 118114304, 133230930, 150198136, 169229875, 190569292, 214481126, 241265379, 271248950, 304801365, 342325709, 384276336, 431149389, 483502844, 541946240, 607163746, 679903203, 761002156, 851376628, 952050665, 1064144451, 1188908248, 1327710076, 1482074143, 1653668665, 1844349560, 2056148051, 2291320912, 2552338241, 2841940500, 3163127352, 3519222692, 3913864295, 4351078600, 4835271870, 5371315400, 5964539504, 6620830889, 7346629512, 8149040695, 9035836076, 10015581680, 11097645016, 12292341831, 13610949895, 15065878135, 16670689208, 18440293320, 20390982757, 22540654445, 24908858009, 27517052599, 30388671978, 33549419497, 37027355200, 40853235313, 45060624582, 49686288421, 54770336324, 60356673280, 66493182097, 73232243759, 80630964769, 88751778802, 97662728555, 107438159466, 118159068427, 129913904637, 142798995930, 156919475295, 172389800255, 189334822579, 207890420102, 228204732751, 250438925115, 274768617130, 301384802048, 330495499613, 362326859895, 397125074750, 435157697830, 476715857290, 522115831195, 571701605655, 625846753120, 684957390936, 749474411781, 819876908323, 896684817527, 980462880430, 1071823774337, 1171432692373, 1280011042268, 1398341745571, 1527273599625, 1667727404093, 1820701100652, 1987276856363, 2168627105469, 2366022741845, 2580840212973, 2814570987591, 3068829878530, 3345365983698, 3646072432125, 3972999029388, 4328363658647, 4714566886083, 5134205287973, 5590088317495, 6085253859260, 6622987708040, 7206841706490, 7840656226137, 8528581302375, 9275102575355, 10085065885767, 10963707205259, 11916681236278, 12950095925895, 14070545699287, 15285151248481, 16601598107914, 18028182516671, 19573856161145, 21248279009367, 23061871173849, 25025873760111, 27152408925615, 29454549941750, 31946390696157, 34643126322519, 37561133582570, 40718063627362, 44132934884255, 47826239745920, 51820051838712, 56138148670947, 60806135438329, 65851585970275, 71304185514919, 77195892663512, 83561103925871, 90436839668817, 97862933703585, 105882246722733, 114540884553038, 123888443077259, 133978259344888, 144867692496445, 156618412527946, 169296722391554, 182973889854026, 197726516681672, 213636919820625, 230793554364681, 249291451168559, 269232701252579, 290726957916112, 313891991306665, 338854264248680, 365749566870782, 394723676655357, 425933084409356, 459545750448675, 495741934760846, 534715062908609, 576672674947168, 621837416509615, 670448123060170, 722760953690372, 779050629562167, 839611730366814, 904760108316360, 974834369944625, 1050197489931117, 1131238503938606, 1218374349844333, 1312051800816215, 1412749565173450, 1520980492851175, 1637293969337171, 1762278433057269, 1896564103591584, 2040825852575075, 2195786311682516, 2362219145337711, 2540952590045698, 2732873183547535, 2938929793929555, 3160137867148997, 3397584011986773, 3652430836071053, 3925922161489422, 4219388528587095, 4534253126900886, 4872038056472084, 5234371069753672, 5622992691950605, 6039763882095515, 6486674127079088, 6965850144195831, 7479565078510584, 8030248384943040, 8620496275465025];\n\n {\n // =========================================================================\n // FINITE SEQUENCES — generate inline\n // =========================================================================\n\n fibonacci-take-while: (fn) -> do\n loop (result = [], a = 0, b = 1, i = 0) ->\n if fn(a, i) then recur(push(result, a), b, a + b, i + 1)\n else result end\n end,\n\n tribonacci-take-while: (fn) -> do\n loop (result = [], a = 0, b = 1, c = 1, i = 0) ->\n if fn(a, i) then recur(push(result, a), b, c, a + b + c, i + 1)\n else result end\n end,\n\n lucas-take-while: (fn) -> do\n loop (result = [], a = 2, b = 1, i = 0) ->\n if fn(a, i) then recur(push(result, a), b, a + b, i + 1)\n else result end\n end,\n\n pell-take-while: (fn) -> do\n loop (result = [], a = 1, b = 2, i = 0) ->\n if fn(a, i) then recur(push(result, a), b, 2 * b + a, i + 1)\n else result end\n end,\n\n padovan-take-while: (fn) -> do\n loop (result = [], a = 1, b = 1, c = 1, i = 0) ->\n if fn(a, i) then recur(push(result, a), b, c, a + b, i + 1)\n else result end\n end,\n\n factorial-take-while: (fn) -> do\n loop (result = [], fact = 1, i = 0) ->\n if fn(fact, i) then recur(push(result, fact), fact * (i + 1), i + 1)\n else result end\n end,\n\n\n\n // =========================================================================\n // PREDICATE SEQUENCES — use inline predicates\n // =========================================================================\n\n prime-take-while: (fn) -> do\n loop (result = [], n = 2) ->\n if is-prime(n) then\n if fn(n, count(result)) then recur(push(result, n), n + 1)\n else result end\n else recur(result, n + 1) end\n end,\n\n composite-take-while: (fn) -> do\n loop (result = [], n = 4) ->\n if is-composite(n) then\n if fn(n, count(result)) then recur(push(result, n), n + 1)\n else result end\n else recur(result, n + 1) end\n end,\n\n abundant-take-while: (fn) -> do\n loop (result = [], n = 12) ->\n if is-abundant(n) then\n if fn(n, count(result)) then recur(push(result, n), n + 1)\n else result end\n else recur(result, n + 1) end\n end,\n\n deficient-take-while: (fn) -> do\n loop (result = [], n = 1) ->\n if is-deficient(n) then\n if fn(n, count(result)) then recur(push(result, n), n + 1)\n else result end\n else recur(result, n + 1) end\n end,\n\n perfect-square-take-while: (fn) -> do\n loop (result = [], i = 1) -> do\n let val = i * i;\n if fn(val, i - 1) then recur(push(result, val), i + 1)\n else result end\n end\n end,\n\n perfect-cube-take-while: (fn) -> do\n loop (result = [], i = 1) -> do\n let val = i * i * i;\n if fn(val, i - 1) then recur(push(result, val), i + 1)\n else result end\n end\n end,\n\n happy-take-while: (fn) -> do\n loop (result = [], n = 1) ->\n if is-happy(n) then\n if fn(n, count(result)) then recur(push(result, n), n + 1)\n else result end\n else recur(result, n + 1) end\n end,\n\n // =========================================================================\n // PARAMETERIZED SEQUENCES\n // =========================================================================\n\n arithmetic-take-while: (start, step, fn) -> do\n loop (result = [], i = 0) -> do\n let val = start + i * step;\n if fn(val, i) then recur(push(result, val), i + 1)\n else result end\n end\n end,\n\n geometric-take-while: (start, ratio, fn) -> do\n loop (result = [], i = 0) -> do\n let val = start * (ratio ^ i);\n if fn(val, i) then recur(push(result, val), i + 1)\n else result end\n end\n end,\n\n polygonal-take-while: (sides, fn) -> do\n loop (result = [], n = 1) -> do\n let val = (sides - 2) * n * (n - 1) / 2 + n;\n if fn(val, n - 1) then recur(push(result, val), n + 1)\n else result end\n end\n end,\n\n look-and-say-take-while: (fn) -> do\n let next-term = (s) -> do\n loop (result = \"\", i = 0) ->\n if i >= count(s) then result\n else do\n let ch = nth(s, i);\n let cnt = loop (c = 1, j = i + 1) ->\n if j < count(s) && nth(s, j) == ch then recur(c + 1, j + 1)\n else c end;\n recur(++(result, str(cnt), ch), i + cnt)\n end\n end\n end;\n loop (result = [], term = \"1\", idx = 0) ->\n if fn(term, idx) then recur(push(result, term), next-term(term), idx + 1)\n else result end\n end,\n\n // =========================================================================\n // FINITE SEQUENCES — iterate precomputed arrays\n // =========================================================================\n\n bell-take-while: (fn) -> do\n loop (result = [], i = 0) ->\n if i >= count(bell-numbers) then result\n else if fn(nth(bell-numbers, i), i) then recur(push(result, nth(bell-numbers, i)), i + 1)\n else result end\n end\n end,\n\n catalan-take-while: (fn) -> do\n loop (result = [], i = 0) ->\n if i >= count(catalan-numbers) then result\n else if fn(nth(catalan-numbers, i), i) then recur(push(result, nth(catalan-numbers, i)), i + 1)\n else result end\n end\n end,\n\n mersenne-take-while: (fn) -> do\n loop (result = [], i = 0) ->\n if i >= count(mersenne-numbers) then result\n else if fn(nth(mersenne-numbers, i), i) then recur(push(result, nth(mersenne-numbers, i)), i + 1)\n else result end\n end\n end,\n\n partition-take-while: (fn) -> do\n loop (result = [], i = 0) ->\n if i >= count(partition-numbers) then result\n else if fn(nth(partition-numbers, i), i) then recur(push(result, nth(partition-numbers, i)), i + 1)\n else result end\n end\n end,\n\n perfect-take-while: (fn) -> do\n loop (result = [], i = 0) ->\n if i >= count(perfect-numbers) then result\n else if fn(nth(perfect-numbers, i), i) then recur(push(result, nth(perfect-numbers, i)), i + 1)\n else result end\n end\n end,\n\n sylvester-take-while: (fn) -> do\n loop (result = [], i = 0) ->\n if i >= count(sylvester-numbers) then result\n else if fn(nth(sylvester-numbers, i), i) then recur(push(result, nth(sylvester-numbers, i)), i + 1)\n else result end\n end\n end,\n\n // =========================================================================\n // DYNAMIC SEQUENCES — generate on-the-fly\n // =========================================================================\n\n bernoulli-take-while: (fn) -> do\n // b-arr accumulates all Bernoulli numbers computed so far; B(0)=1 is always included\n loop (b-arr = [1], n = 1) -> do\n let bn = if n > 1 && n % 2 == 1 then 0\n else do\n let s = loop (k = 0, acc = 0) ->\n if k >= n then acc\n else recur(k + 1, acc + binom(n + 1, k) * nth(b-arr, k)) end;\n (0 - s) / (n + 1)\n end end;\n if fn(bn, n) then recur(push(b-arr, bn), n + 1)\n else b-arr end\n end\n end,\n\n golomb-take-while: (fn) -> do\n // g-arr is 0-indexed: g-arr[i] = g(i+1). g(1)=1, g(n)=1+g(n-g(g(n-1)))\n if not(fn(1, 0)) then []\n else do\n loop (g-arr = [1], n = 2) -> do\n let gn1 = nth(g-arr, n - 2);\n let ggn1 = nth(g-arr, gn1 - 1);\n let gval = 1 + nth(g-arr, n - 1 - ggn1);\n if fn(gval, n - 1) then recur(push(g-arr, gval), n + 1)\n else g-arr end\n end\n end\n end\n end,\n\n lucky-take-while: (fn) -> do\n loop (result = [], i = 0) ->\n if i >= count(lucky-numbers) then result\n else if fn(nth(lucky-numbers, i), i) then recur(push(result, nth(lucky-numbers, i)), i + 1)\n else result end\n end\n end,\n\n perfect-power-take-while: (fn) -> do\n loop (result = [], n = 1) ->\n if is-perfect-power(n) then\n if fn(n, count(result)) then recur(push(result, n), n + 1)\n else result end\n else recur(result, n + 1) end\n end,\n\n recaman-take-while: (fn) -> do\n let in-arr = (arr, val) ->\n loop (i = 0) ->\n if i >= count(arr) then false\n else if nth(arr, i) == val then true\n else recur(i + 1) end\n end;\n if not(fn(0, 0)) then []\n else do\n loop (result = [0], n = 1) -> do\n let prev = nth(result, n - 1);\n let backward = prev - n;\n let nxt = if backward > 0 && not(in-arr(result, backward)) then backward\n else prev + n end;\n if fn(nxt, n) then recur(push(result, nxt), n + 1)\n else result end\n end\n end\n end\n end,\n\n thue-morse-take-while: (fn) -> do\n loop (result = [], i = 0) -> do\n let val = count-bits(i) % 2;\n if fn(val, i) then recur(push(result, val), i + 1)\n else result end\n end\n end\n }\nend\n";
|
|
16958
|
+
//#endregion
|
|
17206
16959
|
//#region src/builtin/modules/number-theory/binomialCefficient.ts
|
|
17207
16960
|
function binomialCoefficient(n, k) {
|
|
17208
16961
|
if (k === 0 || k === n) return 1;
|
|
@@ -17921,19 +17674,7 @@ const abundantSequence = {
|
|
|
17921
17674
|
}
|
|
17922
17675
|
return abundants;
|
|
17923
17676
|
},
|
|
17924
|
-
"abundant?": (n) => isAbundant(n)
|
|
17925
|
-
"abundant-take-while": (takeWhile) => {
|
|
17926
|
-
const abundants = [];
|
|
17927
|
-
function loop(i) {
|
|
17928
|
-
if (!isAbundant(i)) return loop(i + 1);
|
|
17929
|
-
return chain(takeWhile(i, abundants.length), (keep) => {
|
|
17930
|
-
if (!keep) return abundants;
|
|
17931
|
-
abundants.push(i);
|
|
17932
|
-
return loop(i + 1);
|
|
17933
|
-
});
|
|
17934
|
-
}
|
|
17935
|
-
return loop(2);
|
|
17936
|
-
}
|
|
17677
|
+
"abundant?": (n) => isAbundant(n)
|
|
17937
17678
|
};
|
|
17938
17679
|
//#endregion
|
|
17939
17680
|
//#region src/builtin/modules/number-theory/sequences/arithmetic.ts
|
|
@@ -17966,23 +17707,8 @@ const arithmeticNormalExpressions = {
|
|
|
17966
17707
|
arity: toFixedArity(3)
|
|
17967
17708
|
},
|
|
17968
17709
|
"arithmetic-take-while": {
|
|
17969
|
-
evaluate: (
|
|
17970
|
-
|
|
17971
|
-
assertNumber(step, sourceCodeInfo, { finite: true });
|
|
17972
|
-
assertFunctionLike(fn, sourceCodeInfo);
|
|
17973
|
-
const s = start;
|
|
17974
|
-
const d = step;
|
|
17975
|
-
const f = fn;
|
|
17976
|
-
const arithmetic = [];
|
|
17977
|
-
function loop(i) {
|
|
17978
|
-
const value = s + i * d;
|
|
17979
|
-
return chain(executeFunction(f, [value, i], contextStack, sourceCodeInfo), (keep) => {
|
|
17980
|
-
if (!keep) return arithmetic;
|
|
17981
|
-
arithmetic.push(value);
|
|
17982
|
-
return loop(i + 1);
|
|
17983
|
-
});
|
|
17984
|
-
}
|
|
17985
|
-
return loop(0);
|
|
17710
|
+
evaluate: () => {
|
|
17711
|
+
throw new Error("unreachable: overridden by dvalaImpl");
|
|
17986
17712
|
},
|
|
17987
17713
|
arity: toFixedArity(3)
|
|
17988
17714
|
},
|
|
@@ -18045,25 +17771,6 @@ function getBernoulliSeq(length) {
|
|
|
18045
17771
|
}
|
|
18046
17772
|
return bernoulli;
|
|
18047
17773
|
}
|
|
18048
|
-
/**
|
|
18049
|
-
* Generates Bernoulli numbers as long as the predicate function returns true
|
|
18050
|
-
* @param predicate - Function that takes a Bernoulli number and its index and returns true if generation should continue
|
|
18051
|
-
* @returns Array of Bernoulli numbers generated until predicate returns false
|
|
18052
|
-
*/
|
|
18053
|
-
function generateBernoulli(predicate) {
|
|
18054
|
-
const bernoulli = [1];
|
|
18055
|
-
function loop(n) {
|
|
18056
|
-
let sum = 0;
|
|
18057
|
-
for (let k = 0; k < n; k++) sum += binomialCoefficient(n + 1, k) * bernoulli[k];
|
|
18058
|
-
const newValue = n > 1 && n % 2 === 1 ? 0 : -sum / (n + 1);
|
|
18059
|
-
return chain(predicate(newValue, n), (keep) => {
|
|
18060
|
-
if (!keep) return bernoulli;
|
|
18061
|
-
bernoulli.push(newValue);
|
|
18062
|
-
return loop(n + 1);
|
|
18063
|
-
});
|
|
18064
|
-
}
|
|
18065
|
-
return loop(1);
|
|
18066
|
-
}
|
|
18067
17774
|
const bernoulliNormalExpressions = {
|
|
18068
17775
|
"bernoulli-seq": {
|
|
18069
17776
|
evaluate: ([length], sourceCodeInfo) => {
|
|
@@ -18086,10 +17793,8 @@ const bernoulliNormalExpressions = {
|
|
|
18086
17793
|
arity: toFixedArity(1)
|
|
18087
17794
|
},
|
|
18088
17795
|
"bernoulli-take-while": {
|
|
18089
|
-
evaluate: (
|
|
18090
|
-
|
|
18091
|
-
const f = fn;
|
|
18092
|
-
return generateBernoulli((value, index) => chain(executeFunction(f, [value, index], contextStack), (val) => !!val));
|
|
17796
|
+
evaluate: () => {
|
|
17797
|
+
throw new Error("unreachable: overridden by dvalaImpl");
|
|
18093
17798
|
},
|
|
18094
17799
|
arity: toFixedArity(1)
|
|
18095
17800
|
}
|
|
@@ -18141,7 +17846,8 @@ const collatzSequence = {
|
|
|
18141
17846
|
}
|
|
18142
17847
|
return collatz;
|
|
18143
17848
|
},
|
|
18144
|
-
"noNth": true
|
|
17849
|
+
"noNth": true,
|
|
17850
|
+
"noTakeWhile": true
|
|
18145
17851
|
};
|
|
18146
17852
|
//#endregion
|
|
18147
17853
|
//#region src/builtin/modules/number-theory/sequences/prime.ts
|
|
@@ -18162,19 +17868,7 @@ const primeSequence = {
|
|
|
18162
17868
|
}
|
|
18163
17869
|
return primes;
|
|
18164
17870
|
},
|
|
18165
|
-
"prime?": (n) => isPrime(n)
|
|
18166
|
-
"prime-take-while": (takeWhile) => {
|
|
18167
|
-
const primes = [];
|
|
18168
|
-
function loop(i) {
|
|
18169
|
-
if (!isPrime(i)) return loop(i + 1);
|
|
18170
|
-
return chain(takeWhile(i, primes.length), (keep) => {
|
|
18171
|
-
if (!keep) return primes;
|
|
18172
|
-
primes.push(i);
|
|
18173
|
-
return loop(i + 1);
|
|
18174
|
-
});
|
|
18175
|
-
}
|
|
18176
|
-
return loop(2);
|
|
18177
|
-
}
|
|
17871
|
+
"prime?": (n) => isPrime(n)
|
|
18178
17872
|
};
|
|
18179
17873
|
//#endregion
|
|
18180
17874
|
//#region src/builtin/modules/number-theory/sequences/composite.ts
|
|
@@ -18192,19 +17886,7 @@ const compositeSequence = {
|
|
|
18192
17886
|
}
|
|
18193
17887
|
return composites;
|
|
18194
17888
|
},
|
|
18195
|
-
"composite?": (n) => isComposite(n)
|
|
18196
|
-
"composite-take-while": (takeWhile) => {
|
|
18197
|
-
const composites = [];
|
|
18198
|
-
function loop(i) {
|
|
18199
|
-
if (!isComposite(i)) return loop(i + 1);
|
|
18200
|
-
return chain(takeWhile(i, composites.length), (keep) => {
|
|
18201
|
-
if (!keep) return composites;
|
|
18202
|
-
composites.push(i);
|
|
18203
|
-
return loop(i + 1);
|
|
18204
|
-
});
|
|
18205
|
-
}
|
|
18206
|
-
return loop(4);
|
|
18207
|
-
}
|
|
17889
|
+
"composite?": (n) => isComposite(n)
|
|
18208
17890
|
};
|
|
18209
17891
|
//#endregion
|
|
18210
17892
|
//#region src/builtin/modules/number-theory/sequences/deficient.ts
|
|
@@ -18221,19 +17903,7 @@ const deficientSequence = {
|
|
|
18221
17903
|
}
|
|
18222
17904
|
return deficients;
|
|
18223
17905
|
},
|
|
18224
|
-
"deficient?": (n) => isDeficient(n)
|
|
18225
|
-
"deficient-take-while": (takeWhile) => {
|
|
18226
|
-
const deficients = [];
|
|
18227
|
-
function loop(i) {
|
|
18228
|
-
if (!isDeficient(i)) return loop(i + 1);
|
|
18229
|
-
return chain(takeWhile(i, deficients.length), (keep) => {
|
|
18230
|
-
if (!keep) return deficients;
|
|
18231
|
-
deficients.push(i);
|
|
18232
|
-
return loop(i + 1);
|
|
18233
|
-
});
|
|
18234
|
-
}
|
|
18235
|
-
return loop(1);
|
|
18236
|
-
}
|
|
17906
|
+
"deficient?": (n) => isDeficient(n)
|
|
18237
17907
|
};
|
|
18238
17908
|
//#endregion
|
|
18239
17909
|
//#region src/builtin/modules/number-theory/sequences/fibonacci.ts
|
|
@@ -18360,23 +18030,8 @@ const geometricNormalExpressions = {
|
|
|
18360
18030
|
arity: toFixedArity(3)
|
|
18361
18031
|
},
|
|
18362
18032
|
"geometric-take-while": {
|
|
18363
|
-
evaluate: (
|
|
18364
|
-
|
|
18365
|
-
assertNumber(ratio, sourceCodeInfo, { finite: true });
|
|
18366
|
-
assertFunctionLike(fn, sourceCodeInfo);
|
|
18367
|
-
const s = start;
|
|
18368
|
-
const r = ratio;
|
|
18369
|
-
const f = fn;
|
|
18370
|
-
const geometric = [];
|
|
18371
|
-
function loop(i) {
|
|
18372
|
-
const value = s * r ** i;
|
|
18373
|
-
return chain(executeFunction(f, [value, i], contextStack, sourceCodeInfo), (keep) => {
|
|
18374
|
-
if (!keep) return geometric;
|
|
18375
|
-
geometric.push(value);
|
|
18376
|
-
return loop(i + 1);
|
|
18377
|
-
});
|
|
18378
|
-
}
|
|
18379
|
-
return loop(0);
|
|
18033
|
+
evaluate: () => {
|
|
18034
|
+
throw new Error("unreachable: overridden by dvalaImpl");
|
|
18380
18035
|
},
|
|
18381
18036
|
arity: toFixedArity(3)
|
|
18382
18037
|
},
|
|
@@ -18409,25 +18064,9 @@ function getGolombSeq(n) {
|
|
|
18409
18064
|
for (let i = 2; i <= n; i += 1) golomb.push(1 + golomb[i - golomb[golomb[i - 1]]]);
|
|
18410
18065
|
return golomb.slice(1);
|
|
18411
18066
|
}
|
|
18412
|
-
function generateGolombSeq(pred) {
|
|
18413
|
-
const golomb = [0, 1];
|
|
18414
|
-
return chain(pred(1, 0), (keepFirst) => {
|
|
18415
|
-
if (!keepFirst) return [];
|
|
18416
|
-
function loop(i) {
|
|
18417
|
-
const golombNumber = 1 + golomb[i - golomb[golomb[i - 1]]];
|
|
18418
|
-
return chain(pred(golombNumber, i - 1), (keep) => {
|
|
18419
|
-
if (!keep) return golomb.slice(1);
|
|
18420
|
-
golomb.push(golombNumber);
|
|
18421
|
-
return loop(i + 1);
|
|
18422
|
-
});
|
|
18423
|
-
}
|
|
18424
|
-
return loop(2);
|
|
18425
|
-
});
|
|
18426
|
-
}
|
|
18427
18067
|
const golombSequence = {
|
|
18428
18068
|
"golomb-seq": (length) => getGolombSeq(length),
|
|
18429
|
-
"golomb?": () => true
|
|
18430
|
-
"golomb-take-while": (takeWhile) => generateGolombSeq(takeWhile)
|
|
18069
|
+
"golomb?": () => true
|
|
18431
18070
|
};
|
|
18432
18071
|
//#endregion
|
|
18433
18072
|
//#region src/builtin/modules/number-theory/sequences/happy.ts
|
|
@@ -18463,19 +18102,7 @@ const happySequence = {
|
|
|
18463
18102
|
}
|
|
18464
18103
|
return happyNumbers;
|
|
18465
18104
|
},
|
|
18466
|
-
"happy?": (n) => isHappyNumber(n)
|
|
18467
|
-
"happy-take-while": (takeWhile) => {
|
|
18468
|
-
const happyNumbers = [];
|
|
18469
|
-
function loop(i) {
|
|
18470
|
-
if (!isHappyNumber(i)) return loop(i + 1);
|
|
18471
|
-
return chain(takeWhile(i, happyNumbers.length), (keep) => {
|
|
18472
|
-
if (!keep) return happyNumbers;
|
|
18473
|
-
happyNumbers.push(i);
|
|
18474
|
-
return loop(i + 1);
|
|
18475
|
-
});
|
|
18476
|
-
}
|
|
18477
|
-
return loop(1);
|
|
18478
|
-
}
|
|
18105
|
+
"happy?": (n) => isHappyNumber(n)
|
|
18479
18106
|
};
|
|
18480
18107
|
//#endregion
|
|
18481
18108
|
//#region src/builtin/modules/number-theory/sequences/juggler.ts
|
|
@@ -18489,7 +18116,8 @@ const jugglerSequence = {
|
|
|
18489
18116
|
}
|
|
18490
18117
|
return juggler;
|
|
18491
18118
|
},
|
|
18492
|
-
"noNth": true
|
|
18119
|
+
"noNth": true,
|
|
18120
|
+
"noTakeWhile": true
|
|
18493
18121
|
};
|
|
18494
18122
|
//#endregion
|
|
18495
18123
|
//#region src/builtin/modules/number-theory/sequences/lookAndSay.ts
|
|
@@ -18535,22 +18163,6 @@ const lookAndSaySequence = {
|
|
|
18535
18163
|
for (let i = 1; i < length; i += 1) lookAndSay[i] = lookAndSay[i - 1].replace(/(\d)\1*/g, (match) => `${match.length}${match[0]}`);
|
|
18536
18164
|
return lookAndSay;
|
|
18537
18165
|
},
|
|
18538
|
-
"look-and-say-take-while": (takeWhile) => {
|
|
18539
|
-
const lookAndSay = [];
|
|
18540
|
-
return chain(takeWhile("1", 0), (keepFirst) => {
|
|
18541
|
-
if (!keepFirst) return lookAndSay;
|
|
18542
|
-
lookAndSay.push("1");
|
|
18543
|
-
function loop(i) {
|
|
18544
|
-
const next = lookAndSay[i - 1].replace(/(\d)\1*/g, (match) => `${match.length}${match[0]}`);
|
|
18545
|
-
return chain(takeWhile(next, i), (keep) => {
|
|
18546
|
-
if (!keep) return lookAndSay;
|
|
18547
|
-
lookAndSay.push(next);
|
|
18548
|
-
return loop(i + 1);
|
|
18549
|
-
});
|
|
18550
|
-
}
|
|
18551
|
-
return loop(1);
|
|
18552
|
-
});
|
|
18553
|
-
},
|
|
18554
18166
|
"look-and-say?": (n) => isLookAndSay(n)
|
|
18555
18167
|
};
|
|
18556
18168
|
//#endregion
|
|
@@ -18635,6 +18247,16 @@ const lucasNumbers = [
|
|
|
18635
18247
|
7639424778862807
|
|
18636
18248
|
];
|
|
18637
18249
|
//#endregion
|
|
18250
|
+
//#region src/utils/maybePromise.ts
|
|
18251
|
+
/**
|
|
18252
|
+
* Chain a value that might be a Promise. If the value is sync, calls fn synchronously.
|
|
18253
|
+
* If it's a Promise, chains with .then().
|
|
18254
|
+
*/
|
|
18255
|
+
function chain(value, fn) {
|
|
18256
|
+
if (value instanceof Promise) return value.then(fn);
|
|
18257
|
+
return fn(value);
|
|
18258
|
+
}
|
|
18259
|
+
//#endregion
|
|
18638
18260
|
//#region src/builtin/modules/number-theory/sequences/lucky.ts
|
|
18639
18261
|
/**
|
|
18640
18262
|
* Generates lucky numbers while the predicate function returns true.
|
|
@@ -18711,8 +18333,7 @@ function getLuckyNumbers(count) {
|
|
|
18711
18333
|
}
|
|
18712
18334
|
const luckySequence = {
|
|
18713
18335
|
"lucky-seq": (length) => getLuckyNumbers(length),
|
|
18714
|
-
"lucky?": (n) => generateLuckyNumbers((l) => l <= n).includes(n)
|
|
18715
|
-
"lucky-take-while": (takeWhile) => generateLuckyNumbers(takeWhile)
|
|
18336
|
+
"lucky?": (n) => generateLuckyNumbers((l) => l <= n).includes(n)
|
|
18716
18337
|
};
|
|
18717
18338
|
//#endregion
|
|
18718
18339
|
//#region src/builtin/modules/number-theory/sequences/mersenne.ts
|
|
@@ -18815,37 +18436,7 @@ const padovanSequence = {
|
|
|
18815
18436
|
for (let i = 3; i < length; i += 1) padovan[i] = padovan[i - 2] + padovan[i - 3];
|
|
18816
18437
|
return padovan.slice(0, length);
|
|
18817
18438
|
},
|
|
18818
|
-
"padovan?": (n) => isPadovan(n)
|
|
18819
|
-
"padovan-take-while": (takeWhile) => {
|
|
18820
|
-
const padovan = [];
|
|
18821
|
-
return chain(takeWhile(1, 0), (keep0) => {
|
|
18822
|
-
if (!keep0) return padovan;
|
|
18823
|
-
padovan.push(1);
|
|
18824
|
-
return chain(takeWhile(1, 1), (keep1) => {
|
|
18825
|
-
if (!keep1) return padovan;
|
|
18826
|
-
padovan.push(1);
|
|
18827
|
-
return chain(takeWhile(1, 2), (keep2) => {
|
|
18828
|
-
if (!keep2) return padovan;
|
|
18829
|
-
padovan.push(1);
|
|
18830
|
-
let a = 1;
|
|
18831
|
-
let b = 1;
|
|
18832
|
-
let c = 1;
|
|
18833
|
-
function loop(i) {
|
|
18834
|
-
const temp = a + b;
|
|
18835
|
-
a = b;
|
|
18836
|
-
b = c;
|
|
18837
|
-
c = temp;
|
|
18838
|
-
return chain(takeWhile(c, i), (keep) => {
|
|
18839
|
-
if (!keep) return padovan;
|
|
18840
|
-
padovan.push(c);
|
|
18841
|
-
return loop(i + 1);
|
|
18842
|
-
});
|
|
18843
|
-
}
|
|
18844
|
-
return loop(4);
|
|
18845
|
-
});
|
|
18846
|
-
});
|
|
18847
|
-
});
|
|
18848
|
-
}
|
|
18439
|
+
"padovan?": (n) => isPadovan(n)
|
|
18849
18440
|
};
|
|
18850
18441
|
//#endregion
|
|
18851
18442
|
//#region src/builtin/modules/number-theory/sequences/pell.ts
|
|
@@ -18912,19 +18503,7 @@ const perfectCubeSequence = {
|
|
|
18912
18503
|
for (let i = 1; i <= length; i++) perfectcubes.push(i ** 3);
|
|
18913
18504
|
return perfectcubes;
|
|
18914
18505
|
},
|
|
18915
|
-
"perfect-cube?": (n) => n > 0 && Number.isInteger(Math.cbrt(n))
|
|
18916
|
-
"perfect-cube-take-while": (takeWhile) => {
|
|
18917
|
-
const perfectcubes = [];
|
|
18918
|
-
function loop(i) {
|
|
18919
|
-
const value = i ** 3;
|
|
18920
|
-
return chain(takeWhile(value, i), (keep) => {
|
|
18921
|
-
if (!keep) return perfectcubes;
|
|
18922
|
-
perfectcubes.push(value);
|
|
18923
|
-
return loop(i + 1);
|
|
18924
|
-
});
|
|
18925
|
-
}
|
|
18926
|
-
return loop(1);
|
|
18927
|
-
}
|
|
18506
|
+
"perfect-cube?": (n) => n > 0 && Number.isInteger(Math.cbrt(n))
|
|
18928
18507
|
};
|
|
18929
18508
|
//#endregion
|
|
18930
18509
|
//#region src/builtin/modules/number-theory/sequences/perfectPower.ts
|
|
@@ -18954,19 +18533,7 @@ const perfectPowerSequence = {
|
|
|
18954
18533
|
for (let i = 1; perfectPowers.length < length; i++) if (perfectPower(i)) perfectPowers.push(i);
|
|
18955
18534
|
return perfectPowers;
|
|
18956
18535
|
},
|
|
18957
|
-
"perfect-power?": (n) => perfectPower(n) !== null
|
|
18958
|
-
"perfect-power-take-while": (takeWhile) => {
|
|
18959
|
-
const perfectPowers = [];
|
|
18960
|
-
function loop(i) {
|
|
18961
|
-
if (!perfectPower(i)) return loop(i + 1);
|
|
18962
|
-
return chain(takeWhile(i, perfectPowers.length), (keep) => {
|
|
18963
|
-
if (!keep) return perfectPowers;
|
|
18964
|
-
perfectPowers.push(i);
|
|
18965
|
-
return loop(i + 1);
|
|
18966
|
-
});
|
|
18967
|
-
}
|
|
18968
|
-
return loop(1);
|
|
18969
|
-
}
|
|
18536
|
+
"perfect-power?": (n) => perfectPower(n) !== null
|
|
18970
18537
|
};
|
|
18971
18538
|
//#endregion
|
|
18972
18539
|
//#region src/builtin/modules/number-theory/sequences/perfectSquare.ts
|
|
@@ -18976,19 +18543,7 @@ const perfectSquareSequence = {
|
|
|
18976
18543
|
for (let i = 1; i <= length; i++) perfectSquares.push(i ** 2);
|
|
18977
18544
|
return perfectSquares;
|
|
18978
18545
|
},
|
|
18979
|
-
"perfect-square?": (n) => n > 0 && Number.isInteger(Math.sqrt(n))
|
|
18980
|
-
"perfect-square-take-while": (takeWhile) => {
|
|
18981
|
-
const perfectSquares = [];
|
|
18982
|
-
function loop(i) {
|
|
18983
|
-
const value = i ** 2;
|
|
18984
|
-
return chain(takeWhile(value, i), (keep) => {
|
|
18985
|
-
if (!keep) return perfectSquares;
|
|
18986
|
-
perfectSquares.push(value);
|
|
18987
|
-
return loop(i + 1);
|
|
18988
|
-
});
|
|
18989
|
-
}
|
|
18990
|
-
return loop(1);
|
|
18991
|
-
}
|
|
18546
|
+
"perfect-square?": (n) => n > 0 && Number.isInteger(Math.sqrt(n))
|
|
18992
18547
|
};
|
|
18993
18548
|
//#endregion
|
|
18994
18549
|
//#region src/builtin/modules/number-theory/sequences/poligonal.ts
|
|
@@ -19010,24 +18565,8 @@ const poligonalNormalExpressions = {
|
|
|
19010
18565
|
arity: toFixedArity(2)
|
|
19011
18566
|
},
|
|
19012
18567
|
"polygonal-take-while": {
|
|
19013
|
-
evaluate: (
|
|
19014
|
-
|
|
19015
|
-
integer: true,
|
|
19016
|
-
gte: 3
|
|
19017
|
-
});
|
|
19018
|
-
assertFunctionLike(fn, sourceCodeInfo);
|
|
19019
|
-
const s = sides;
|
|
19020
|
-
const f = fn;
|
|
19021
|
-
const polygonal = [];
|
|
19022
|
-
function loop(i) {
|
|
19023
|
-
const value = (i * i * (s - 2) - i * (s - 4)) / 2;
|
|
19024
|
-
return chain(executeFunction(f, [value, i], contextStack, sourceCodeInfo), (keep) => {
|
|
19025
|
-
if (!keep) return polygonal;
|
|
19026
|
-
polygonal.push(value);
|
|
19027
|
-
return loop(i + 1);
|
|
19028
|
-
});
|
|
19029
|
-
}
|
|
19030
|
-
return loop(1);
|
|
18568
|
+
evaluate: () => {
|
|
18569
|
+
throw new Error("unreachable: overridden by dvalaImpl");
|
|
19031
18570
|
},
|
|
19032
18571
|
arity: toFixedArity(2)
|
|
19033
18572
|
},
|
|
@@ -19088,25 +18627,6 @@ function generateRecamanSequence(n) {
|
|
|
19088
18627
|
}
|
|
19089
18628
|
const recamanSequence = {
|
|
19090
18629
|
"recaman-seq": (length) => generateRecamanSequence(length),
|
|
19091
|
-
"recaman-take-while": (takeWhile) => {
|
|
19092
|
-
const sequence = [];
|
|
19093
|
-
const seen = new Set([0]);
|
|
19094
|
-
return chain(takeWhile(0, 0), (keepFirst) => {
|
|
19095
|
-
if (!keepFirst) return sequence;
|
|
19096
|
-
sequence.push(0);
|
|
19097
|
-
function loop(i) {
|
|
19098
|
-
let next = sequence[i - 1] - i;
|
|
19099
|
-
if (next <= 0 || seen.has(next)) next = sequence[i - 1] + i;
|
|
19100
|
-
return chain(takeWhile(next, i), (keep) => {
|
|
19101
|
-
if (!keep) return sequence;
|
|
19102
|
-
sequence.push(next);
|
|
19103
|
-
seen.add(next);
|
|
19104
|
-
return loop(i + 1);
|
|
19105
|
-
});
|
|
19106
|
-
}
|
|
19107
|
-
return loop(1);
|
|
19108
|
-
});
|
|
19109
|
-
},
|
|
19110
18630
|
"recaman?": () => true
|
|
19111
18631
|
};
|
|
19112
18632
|
//#endregion
|
|
@@ -19127,18 +18647,6 @@ const thueMorseSequence = {
|
|
|
19127
18647
|
for (let i = 0; i < length; i += 1) thueMorse[i] = countSetBits(i) % 2;
|
|
19128
18648
|
return thueMorse;
|
|
19129
18649
|
},
|
|
19130
|
-
"thue-morse-take-while": (takeWhile) => {
|
|
19131
|
-
const thueMorse = [];
|
|
19132
|
-
function loop(i) {
|
|
19133
|
-
const value = countSetBits(i) % 2;
|
|
19134
|
-
return chain(takeWhile(value, i), (keep) => {
|
|
19135
|
-
if (!keep) return thueMorse;
|
|
19136
|
-
thueMorse.push(value);
|
|
19137
|
-
return loop(i + 1);
|
|
19138
|
-
});
|
|
19139
|
-
}
|
|
19140
|
-
return loop(0);
|
|
19141
|
-
},
|
|
19142
18650
|
"thue-morse?": (n) => n === 1 || n === 0
|
|
19143
18651
|
};
|
|
19144
18652
|
function countSetBits(num) {
|
|
@@ -19260,16 +18768,7 @@ function addNormalExpressions$1(normalExpressions) {
|
|
|
19260
18768
|
function getFiniteNumberSequence(name, sequence) {
|
|
19261
18769
|
return {
|
|
19262
18770
|
[`${name}-seq`]: createSeqNormalExpression((length) => sequence.slice(0, length), sequence.length),
|
|
19263
|
-
[`${name}-take-while`]: createTakeWhileNormalExpression(
|
|
19264
|
-
function loop(i) {
|
|
19265
|
-
if (i >= sequence.length) return sequence.slice(0, i);
|
|
19266
|
-
return chain(takeWhile(sequence[i], i), (keep) => {
|
|
19267
|
-
if (!keep) return sequence.slice(0, i);
|
|
19268
|
-
return loop(i + 1);
|
|
19269
|
-
});
|
|
19270
|
-
}
|
|
19271
|
-
return loop(0);
|
|
19272
|
-
}, sequence.length),
|
|
18771
|
+
[`${name}-take-while`]: createTakeWhileNormalExpression(sequence.length),
|
|
19273
18772
|
[`${name}-nth`]: createNthNormalExpression(() => sequence, sequence.length),
|
|
19274
18773
|
[`${name}?`]: createNumberPredNormalExpression((n) => sequence.includes(n))
|
|
19275
18774
|
};
|
|
@@ -19281,8 +18780,8 @@ function addSequence(sequence) {
|
|
|
19281
18780
|
if (key.endsWith("seq")) {
|
|
19282
18781
|
sequenceNormalExpressions[key] = createSeqNormalExpression(value, sequence.maxLength);
|
|
19283
18782
|
if (!sequence.noNth) sequenceNormalExpressions[key.replace(/seq$/, "nth")] = createNthNormalExpression(value, sequence.maxLength);
|
|
19284
|
-
|
|
19285
|
-
else if (key.endsWith("?")) if (sequence.string) sequenceNormalExpressions[key] = createStringPredNormalExpression(value);
|
|
18783
|
+
if (!sequence.noTakeWhile) sequenceNormalExpressions[key.replace(/seq$/, "take-while")] = createTakeWhileNormalExpression(sequence.maxLength);
|
|
18784
|
+
} else if (key.endsWith("?")) if (sequence.string) sequenceNormalExpressions[key] = createStringPredNormalExpression(value);
|
|
19286
18785
|
else sequenceNormalExpressions[key] = createNumberPredNormalExpression(value);
|
|
19287
18786
|
}
|
|
19288
18787
|
}
|
|
@@ -19305,18 +18804,10 @@ function createSeqNormalExpression(seqFunction, maxLength) {
|
|
|
19305
18804
|
arity: typeof maxLength === "number" ? { max: 1 } : toFixedArity(1)
|
|
19306
18805
|
};
|
|
19307
18806
|
}
|
|
19308
|
-
function createTakeWhileNormalExpression(
|
|
18807
|
+
function createTakeWhileNormalExpression(maxLength) {
|
|
19309
18808
|
return {
|
|
19310
|
-
evaluate: (
|
|
19311
|
-
|
|
19312
|
-
assertFunctionLike(fn, sourceCodeInfo);
|
|
19313
|
-
return chain(takeWhileFunction((value, index) => chain(executeFunction(fn, [value, index], contextStack), (val) => !!val), sourceCodeInfo), (resolved) => {
|
|
19314
|
-
if (typeof resolved[0] === "number") {
|
|
19315
|
-
/* v8 ignore next 3 */
|
|
19316
|
-
if (resolved.some((n) => n > Number.MAX_SAFE_INTEGER)) throw new DvalaError("Result exceeds maximum safe integer", sourceCodeInfo);
|
|
19317
|
-
}
|
|
19318
|
-
return resolved;
|
|
19319
|
-
});
|
|
18809
|
+
evaluate: () => {
|
|
18810
|
+
throw new Error("unreachable: overridden by dvalaImpl");
|
|
19320
18811
|
},
|
|
19321
18812
|
arity: typeof maxLength === "number" ? { max: 1 } : toFixedArity(1)
|
|
19322
18813
|
};
|
|
@@ -19732,7 +19223,7 @@ if (combinatoricalNormalExpression[key]) combinatoricalNormalExpression[key].doc
|
|
|
19732
19223
|
const numberTheoryModule = {
|
|
19733
19224
|
name: "number-theory",
|
|
19734
19225
|
functions: combinatoricalNormalExpression,
|
|
19735
|
-
source:
|
|
19226
|
+
source: number_theory_default,
|
|
19736
19227
|
docs: moduleDocs$1
|
|
19737
19228
|
};
|
|
19738
19229
|
//#endregion
|
|
@@ -24880,7 +24371,7 @@ function printlnHandler(args, k) {
|
|
|
24880
24371
|
k
|
|
24881
24372
|
};
|
|
24882
24373
|
}
|
|
24883
|
-
function generateUUID() {
|
|
24374
|
+
function generateUUID$1() {
|
|
24884
24375
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => {
|
|
24885
24376
|
const random = Math.random() * 16 | 0;
|
|
24886
24377
|
return (char === "x" ? random : random & 3 | 8).toString(16);
|
|
@@ -25056,7 +24547,7 @@ const standardEffects = {
|
|
|
25056
24547
|
handler: (_args, k) => {
|
|
25057
24548
|
return {
|
|
25058
24549
|
type: "Value",
|
|
25059
|
-
value: generateUUID(),
|
|
24550
|
+
value: generateUUID$1(),
|
|
25060
24551
|
k
|
|
25061
24552
|
};
|
|
25062
24553
|
},
|
|
@@ -26605,57 +26096,416 @@ function createContextStack(params = {}, modules, pure) {
|
|
|
26605
26096
|
return params.globalModuleScope ? contextStack : contextStack.create({});
|
|
26606
26097
|
}
|
|
26607
26098
|
//#endregion
|
|
26608
|
-
//#region src/
|
|
26609
|
-
|
|
26610
|
-
|
|
26611
|
-
|
|
26612
|
-
|
|
26613
|
-
|
|
26614
|
-
|
|
26615
|
-
|
|
26616
|
-
|
|
26617
|
-
|
|
26618
|
-
|
|
26619
|
-
|
|
26620
|
-
|
|
26621
|
-
|
|
26622
|
-
|
|
26623
|
-
|
|
26624
|
-
|
|
26625
|
-
|
|
26626
|
-
|
|
26627
|
-
|
|
26628
|
-
|
|
26629
|
-
|
|
26630
|
-
|
|
26631
|
-
|
|
26632
|
-
|
|
26633
|
-
|
|
26634
|
-
|
|
26635
|
-
|
|
26636
|
-
|
|
26637
|
-
|
|
26638
|
-
|
|
26639
|
-
|
|
26640
|
-
|
|
26641
|
-
|
|
26642
|
-
|
|
26643
|
-
|
|
26644
|
-
|
|
26645
|
-
|
|
26646
|
-
|
|
26099
|
+
//#region src/builtin/bindingSlot.ts
|
|
26100
|
+
/**
|
|
26101
|
+
* Validate that the root value matches the expected binding target structure.
|
|
26102
|
+
*
|
|
26103
|
+
* For array destructuring (`let [a, b] = value`), value must be an array.
|
|
26104
|
+
* For object destructuring (`let {a, b} = value`), value must be an object.
|
|
26105
|
+
* For symbol binding (`let x = value`), no validation needed.
|
|
26106
|
+
*/
|
|
26107
|
+
function validateBindingRootType(target, value, sourceCodeInfo) {
|
|
26108
|
+
switch (target[0]) {
|
|
26109
|
+
case bindingTargetTypes.array:
|
|
26110
|
+
assertArray(value, sourceCodeInfo);
|
|
26111
|
+
break;
|
|
26112
|
+
case bindingTargetTypes.object:
|
|
26113
|
+
assertUnknownRecord(value, sourceCodeInfo);
|
|
26114
|
+
break;
|
|
26115
|
+
}
|
|
26116
|
+
}
|
|
26117
|
+
/**
|
|
26118
|
+
* Flatten a binding pattern into a linear list of slots.
|
|
26119
|
+
*
|
|
26120
|
+
* Example: `{a = 1, b: {c = 2}}`
|
|
26121
|
+
* Produces: [
|
|
26122
|
+
* { name: 'a', path: [{type: 'key', key: 'a'}], defaultNode: <1> },
|
|
26123
|
+
* { name: 'c', path: [{type: 'key', key: 'b'}, {type: 'key', key: 'c'}], defaultNode: <2> }
|
|
26124
|
+
* ]
|
|
26125
|
+
*/
|
|
26126
|
+
function flattenBindingPattern(target) {
|
|
26127
|
+
const slots = [];
|
|
26128
|
+
flattenTarget(target, [], slots);
|
|
26129
|
+
return slots;
|
|
26130
|
+
}
|
|
26131
|
+
function flattenTarget(target, path, slots) {
|
|
26132
|
+
const sourceCodeInfo = target[2];
|
|
26133
|
+
switch (target[0]) {
|
|
26134
|
+
case bindingTargetTypes.symbol: {
|
|
26135
|
+
const symbolNode = target[1][0];
|
|
26136
|
+
const defaultNode = target[1][1];
|
|
26137
|
+
slots.push({
|
|
26138
|
+
name: symbolNode[1],
|
|
26139
|
+
path: [...path],
|
|
26140
|
+
defaultNode,
|
|
26141
|
+
sourceCodeInfo
|
|
26142
|
+
});
|
|
26143
|
+
break;
|
|
26647
26144
|
}
|
|
26648
|
-
case
|
|
26649
|
-
const
|
|
26650
|
-
const
|
|
26651
|
-
|
|
26652
|
-
|
|
26653
|
-
|
|
26654
|
-
|
|
26655
|
-
|
|
26145
|
+
case bindingTargetTypes.rest: {
|
|
26146
|
+
const name = target[1][0];
|
|
26147
|
+
const defaultNode = target[1][1];
|
|
26148
|
+
slots.push({
|
|
26149
|
+
name,
|
|
26150
|
+
path: [...path],
|
|
26151
|
+
defaultNode,
|
|
26152
|
+
isRest: true,
|
|
26153
|
+
sourceCodeInfo
|
|
26656
26154
|
});
|
|
26155
|
+
break;
|
|
26657
26156
|
}
|
|
26658
|
-
case
|
|
26157
|
+
case bindingTargetTypes.object: {
|
|
26158
|
+
const entries = target[1][0];
|
|
26159
|
+
const capturedKeys = /* @__PURE__ */ new Set();
|
|
26160
|
+
for (const [key, element] of Object.entries(entries)) {
|
|
26161
|
+
if (element[0] === bindingTargetTypes.rest) continue;
|
|
26162
|
+
capturedKeys.add(key);
|
|
26163
|
+
const newPath = [...path, {
|
|
26164
|
+
type: "key",
|
|
26165
|
+
key
|
|
26166
|
+
}];
|
|
26167
|
+
const hasDefault = element[1][1] !== void 0;
|
|
26168
|
+
const isCompound = element[0] === bindingTargetTypes.object || element[0] === bindingTargetTypes.array;
|
|
26169
|
+
if (hasDefault && isCompound) slots.push({
|
|
26170
|
+
name: `_intermediate_${slots.length}`,
|
|
26171
|
+
path: newPath,
|
|
26172
|
+
defaultNode: element[1][1],
|
|
26173
|
+
nestedTarget: element,
|
|
26174
|
+
sourceCodeInfo: element[2]
|
|
26175
|
+
});
|
|
26176
|
+
else flattenTarget(element, newPath, slots);
|
|
26177
|
+
}
|
|
26178
|
+
for (const [_key, element] of Object.entries(entries)) if (element[0] === bindingTargetTypes.rest) {
|
|
26179
|
+
const name = element[1][0];
|
|
26180
|
+
slots.push({
|
|
26181
|
+
name,
|
|
26182
|
+
path: [...path],
|
|
26183
|
+
isRest: true,
|
|
26184
|
+
restKeys: capturedKeys,
|
|
26185
|
+
sourceCodeInfo: element[2]
|
|
26186
|
+
});
|
|
26187
|
+
break;
|
|
26188
|
+
}
|
|
26189
|
+
break;
|
|
26190
|
+
}
|
|
26191
|
+
case bindingTargetTypes.array: {
|
|
26192
|
+
const elements = target[1][0];
|
|
26193
|
+
for (let i = 0; i < elements.length; i++) {
|
|
26194
|
+
const element = elements[i];
|
|
26195
|
+
if (element === null || element === void 0) continue;
|
|
26196
|
+
if (element[0] === bindingTargetTypes.rest) {
|
|
26197
|
+
const name = element[1][0];
|
|
26198
|
+
slots.push({
|
|
26199
|
+
name,
|
|
26200
|
+
path: [...path],
|
|
26201
|
+
isRest: true,
|
|
26202
|
+
restIndex: i,
|
|
26203
|
+
sourceCodeInfo: element[2]
|
|
26204
|
+
});
|
|
26205
|
+
break;
|
|
26206
|
+
}
|
|
26207
|
+
const newPath = [...path, {
|
|
26208
|
+
type: "index",
|
|
26209
|
+
index: i
|
|
26210
|
+
}];
|
|
26211
|
+
const hasDefault = element[1][1] !== void 0;
|
|
26212
|
+
const isCompound = element[0] === bindingTargetTypes.object || element[0] === bindingTargetTypes.array;
|
|
26213
|
+
if (hasDefault && isCompound) slots.push({
|
|
26214
|
+
name: `_intermediate_${slots.length}`,
|
|
26215
|
+
path: newPath,
|
|
26216
|
+
defaultNode: element[1][1],
|
|
26217
|
+
nestedTarget: element,
|
|
26218
|
+
sourceCodeInfo: element[2]
|
|
26219
|
+
});
|
|
26220
|
+
else flattenTarget(element, newPath, slots);
|
|
26221
|
+
}
|
|
26222
|
+
break;
|
|
26223
|
+
}
|
|
26224
|
+
case bindingTargetTypes.literal:
|
|
26225
|
+
case bindingTargetTypes.wildcard: break;
|
|
26226
|
+
}
|
|
26227
|
+
}
|
|
26228
|
+
/**
|
|
26229
|
+
* Extract a value from a nested structure by following a path.
|
|
26230
|
+
*
|
|
26231
|
+
* Returns undefined if the path cannot be followed (missing key/index).
|
|
26232
|
+
*/
|
|
26233
|
+
function extractValueByPath(rootValue, path, sourceCodeInfo) {
|
|
26234
|
+
let current = rootValue;
|
|
26235
|
+
for (const step of path) {
|
|
26236
|
+
if (current === null || current === void 0) return;
|
|
26237
|
+
if (step.type === "key") {
|
|
26238
|
+
assertUnknownRecord(current, sourceCodeInfo);
|
|
26239
|
+
current = current[step.key];
|
|
26240
|
+
} else {
|
|
26241
|
+
assertArray(current, sourceCodeInfo);
|
|
26242
|
+
current = current[step.index];
|
|
26243
|
+
}
|
|
26244
|
+
}
|
|
26245
|
+
return current;
|
|
26246
|
+
}
|
|
26247
|
+
/**
|
|
26248
|
+
* Extract rest values for an object rest binding.
|
|
26249
|
+
* Returns an object with all keys except those in restKeys.
|
|
26250
|
+
*/
|
|
26251
|
+
function extractObjectRest(value, restKeys, sourceCodeInfo) {
|
|
26252
|
+
assertUnknownRecord(value, sourceCodeInfo);
|
|
26253
|
+
const result = {};
|
|
26254
|
+
for (const [key, val] of Object.entries(value)) if (!restKeys.has(key)) result[key] = asAny(val);
|
|
26255
|
+
return result;
|
|
26256
|
+
}
|
|
26257
|
+
/**
|
|
26258
|
+
* Extract rest values for an array rest binding.
|
|
26259
|
+
* Returns elements from restIndex onwards.
|
|
26260
|
+
*/
|
|
26261
|
+
function extractArrayRest(value, restIndex, sourceCodeInfo) {
|
|
26262
|
+
assertArray(value, sourceCodeInfo);
|
|
26263
|
+
return value.slice(restIndex);
|
|
26264
|
+
}
|
|
26265
|
+
//#endregion
|
|
26266
|
+
//#region src/builtin/matchSlot.ts
|
|
26267
|
+
/**
|
|
26268
|
+
* Flatten a binding pattern into a linear list of match slots.
|
|
26269
|
+
* Returns slots in order they should be processed.
|
|
26270
|
+
*
|
|
26271
|
+
* Type checks come first (to fail fast on type mismatch).
|
|
26272
|
+
* Then binding/literal slots in depth-first order.
|
|
26273
|
+
*/
|
|
26274
|
+
function flattenMatchPattern(target) {
|
|
26275
|
+
const slots = [];
|
|
26276
|
+
flattenMatchTarget(target, [], slots);
|
|
26277
|
+
return slots;
|
|
26278
|
+
}
|
|
26279
|
+
function flattenMatchTarget(target, path, slots) {
|
|
26280
|
+
switch (target[0]) {
|
|
26281
|
+
case bindingTargetTypes.wildcard:
|
|
26282
|
+
slots.push({
|
|
26283
|
+
kind: "wildcard",
|
|
26284
|
+
path: [...path]
|
|
26285
|
+
});
|
|
26286
|
+
break;
|
|
26287
|
+
case bindingTargetTypes.literal: {
|
|
26288
|
+
const literalNode = target[1][0];
|
|
26289
|
+
slots.push({
|
|
26290
|
+
kind: "literal",
|
|
26291
|
+
path: [...path],
|
|
26292
|
+
literalNode,
|
|
26293
|
+
sourceCodeInfo: target[2]
|
|
26294
|
+
});
|
|
26295
|
+
break;
|
|
26296
|
+
}
|
|
26297
|
+
case bindingTargetTypes.symbol: {
|
|
26298
|
+
const name = target[1][0][1];
|
|
26299
|
+
const defaultNode = target[1][1];
|
|
26300
|
+
slots.push({
|
|
26301
|
+
kind: "bind",
|
|
26302
|
+
name,
|
|
26303
|
+
path: [...path],
|
|
26304
|
+
defaultNode,
|
|
26305
|
+
sourceCodeInfo: target[2]
|
|
26306
|
+
});
|
|
26307
|
+
break;
|
|
26308
|
+
}
|
|
26309
|
+
case bindingTargetTypes.rest: {
|
|
26310
|
+
const name = target[1][0];
|
|
26311
|
+
const defaultNode = target[1][1];
|
|
26312
|
+
slots.push({
|
|
26313
|
+
kind: "rest",
|
|
26314
|
+
name,
|
|
26315
|
+
path: [...path],
|
|
26316
|
+
defaultNode,
|
|
26317
|
+
sourceCodeInfo: target[2]
|
|
26318
|
+
});
|
|
26319
|
+
break;
|
|
26320
|
+
}
|
|
26321
|
+
case bindingTargetTypes.object: {
|
|
26322
|
+
if (path.length > 0) slots.push({
|
|
26323
|
+
kind: "typeCheck",
|
|
26324
|
+
path: [...path],
|
|
26325
|
+
requiredType: "object",
|
|
26326
|
+
sourceCodeInfo: target[2]
|
|
26327
|
+
});
|
|
26328
|
+
const entries = target[1][0];
|
|
26329
|
+
const capturedKeys = /* @__PURE__ */ new Set();
|
|
26330
|
+
let restElement;
|
|
26331
|
+
for (const [key, element] of Object.entries(entries)) {
|
|
26332
|
+
if (element[0] === bindingTargetTypes.rest) {
|
|
26333
|
+
restElement = element;
|
|
26334
|
+
continue;
|
|
26335
|
+
}
|
|
26336
|
+
capturedKeys.add(key);
|
|
26337
|
+
flattenMatchTarget(element, [...path, {
|
|
26338
|
+
type: "key",
|
|
26339
|
+
key
|
|
26340
|
+
}], slots);
|
|
26341
|
+
}
|
|
26342
|
+
if (restElement) slots.push({
|
|
26343
|
+
kind: "rest",
|
|
26344
|
+
name: restElement[1][0],
|
|
26345
|
+
path: [...path],
|
|
26346
|
+
restKeys: capturedKeys,
|
|
26347
|
+
sourceCodeInfo: restElement[2]
|
|
26348
|
+
});
|
|
26349
|
+
break;
|
|
26350
|
+
}
|
|
26351
|
+
case bindingTargetTypes.array: {
|
|
26352
|
+
if (path.length > 0) slots.push({
|
|
26353
|
+
kind: "typeCheck",
|
|
26354
|
+
path: [...path],
|
|
26355
|
+
requiredType: "array",
|
|
26356
|
+
sourceCodeInfo: target[2]
|
|
26357
|
+
});
|
|
26358
|
+
const elements = target[1][0];
|
|
26359
|
+
for (let i = 0; i < elements.length; i++) {
|
|
26360
|
+
const element = elements[i];
|
|
26361
|
+
if (element === null || element === void 0) continue;
|
|
26362
|
+
if (element[0] === bindingTargetTypes.rest) {
|
|
26363
|
+
slots.push({
|
|
26364
|
+
kind: "rest",
|
|
26365
|
+
name: element[1][0],
|
|
26366
|
+
path: [...path],
|
|
26367
|
+
restIndex: i,
|
|
26368
|
+
sourceCodeInfo: element[2]
|
|
26369
|
+
});
|
|
26370
|
+
break;
|
|
26371
|
+
}
|
|
26372
|
+
flattenMatchTarget(element, [...path, {
|
|
26373
|
+
type: "index",
|
|
26374
|
+
index: i
|
|
26375
|
+
}], slots);
|
|
26376
|
+
}
|
|
26377
|
+
break;
|
|
26378
|
+
}
|
|
26379
|
+
}
|
|
26380
|
+
}
|
|
26381
|
+
/**
|
|
26382
|
+
* Extract a value from a nested structure by following a path.
|
|
26383
|
+
* Returns undefined if path cannot be followed.
|
|
26384
|
+
*/
|
|
26385
|
+
function extractMatchValueByPath(rootValue, path) {
|
|
26386
|
+
let current = rootValue;
|
|
26387
|
+
for (const step of path) {
|
|
26388
|
+
if (current === null || current === void 0) return;
|
|
26389
|
+
if (step.type === "key") {
|
|
26390
|
+
if (!isUnknownRecord(current)) return void 0;
|
|
26391
|
+
current = current[step.key];
|
|
26392
|
+
} else {
|
|
26393
|
+
if (!Array.isArray(current)) return void 0;
|
|
26394
|
+
current = current[step.index];
|
|
26395
|
+
}
|
|
26396
|
+
}
|
|
26397
|
+
return current;
|
|
26398
|
+
}
|
|
26399
|
+
/**
|
|
26400
|
+
* Check if value matches required type at path.
|
|
26401
|
+
*/
|
|
26402
|
+
function checkTypeAtPath(rootValue, path, requiredType) {
|
|
26403
|
+
const value = path.length > 0 ? extractMatchValueByPath(rootValue, path) : rootValue;
|
|
26404
|
+
if (value === null || value === void 0) return false;
|
|
26405
|
+
if (requiredType === "object") return isUnknownRecord(value);
|
|
26406
|
+
else return Array.isArray(value);
|
|
26407
|
+
}
|
|
26408
|
+
/**
|
|
26409
|
+
* Extract rest values for object rest.
|
|
26410
|
+
*/
|
|
26411
|
+
function extractMatchObjectRest(value, path, restKeys) {
|
|
26412
|
+
const obj = path.length > 0 ? extractMatchValueByPath(value, path) : value;
|
|
26413
|
+
if (!isUnknownRecord(obj)) return {};
|
|
26414
|
+
const result = {};
|
|
26415
|
+
for (const [key, val] of Object.entries(obj)) if (!restKeys.has(key)) result[key] = asAny(val);
|
|
26416
|
+
return result;
|
|
26417
|
+
}
|
|
26418
|
+
/**
|
|
26419
|
+
* Extract rest values for array rest.
|
|
26420
|
+
*/
|
|
26421
|
+
function extractMatchArrayRest(value, path, restIndex) {
|
|
26422
|
+
const arr = path.length > 0 ? extractMatchValueByPath(value, path) : value;
|
|
26423
|
+
if (!Array.isArray(arr)) return [];
|
|
26424
|
+
return arr.slice(restIndex).map((v) => asAny(v));
|
|
26425
|
+
}
|
|
26426
|
+
/**
|
|
26427
|
+
* Check array length constraints at pattern root.
|
|
26428
|
+
* For patterns like [a, b, c] - exact match required.
|
|
26429
|
+
* For patterns like [a, b, ...rest] - minimum match required.
|
|
26430
|
+
*/
|
|
26431
|
+
function checkArrayLengthConstraint(target, value) {
|
|
26432
|
+
if (target[0] !== bindingTargetTypes.array) return true;
|
|
26433
|
+
if (!Array.isArray(value)) return false;
|
|
26434
|
+
const elements = target[1][0];
|
|
26435
|
+
let hasRest = false;
|
|
26436
|
+
let nonRestCount = 0;
|
|
26437
|
+
for (const element of elements) {
|
|
26438
|
+
if (element === null) {
|
|
26439
|
+
nonRestCount++;
|
|
26440
|
+
continue;
|
|
26441
|
+
}
|
|
26442
|
+
if (element[0] === bindingTargetTypes.rest) {
|
|
26443
|
+
hasRest = true;
|
|
26444
|
+
break;
|
|
26445
|
+
}
|
|
26446
|
+
nonRestCount++;
|
|
26447
|
+
}
|
|
26448
|
+
if (hasRest) return value.length >= nonRestCount;
|
|
26449
|
+
else return value.length === nonRestCount;
|
|
26450
|
+
}
|
|
26451
|
+
/**
|
|
26452
|
+
* Check object exists at pattern root.
|
|
26453
|
+
*/
|
|
26454
|
+
function checkObjectTypeConstraint(target, value) {
|
|
26455
|
+
if (target[0] !== bindingTargetTypes.object) return true;
|
|
26456
|
+
return isUnknownRecord(value);
|
|
26457
|
+
}
|
|
26458
|
+
//#endregion
|
|
26459
|
+
//#region src/getUndefinedSymbols/index.ts
|
|
26460
|
+
const getUndefinedSymbols$1 = (ast, contextStack, builtin) => {
|
|
26461
|
+
const nodes = Array.isArray(ast) ? ast : [[NodeTypes.SpecialExpression, [
|
|
26462
|
+
specialExpressionTypes.block,
|
|
26463
|
+
ast.body,
|
|
26464
|
+
void 0
|
|
26465
|
+
]]];
|
|
26466
|
+
const unresolvedSymbols = /* @__PURE__ */ new Set();
|
|
26467
|
+
for (const subNode of nodes) findUnresolvedSymbolsInNode(subNode, contextStack, builtin)?.forEach((symbol) => unresolvedSymbols.add(symbol));
|
|
26468
|
+
return unresolvedSymbols;
|
|
26469
|
+
};
|
|
26470
|
+
function findUnresolvedSymbolsInNode(node, contextStack, builtin) {
|
|
26471
|
+
const nodeType = node[0];
|
|
26472
|
+
switch (nodeType) {
|
|
26473
|
+
case NodeTypes.UserDefinedSymbol: {
|
|
26474
|
+
const symbolNode = node;
|
|
26475
|
+
if (contextStack.lookUp(symbolNode) === null) return new Set([symbolNode[1]]);
|
|
26476
|
+
return null;
|
|
26477
|
+
}
|
|
26478
|
+
case NodeTypes.NormalBuiltinSymbol:
|
|
26479
|
+
case NodeTypes.SpecialBuiltinSymbol:
|
|
26480
|
+
case NodeTypes.String:
|
|
26481
|
+
case NodeTypes.Number:
|
|
26482
|
+
case NodeTypes.ReservedSymbol:
|
|
26483
|
+
case NodeTypes.Binding: return null;
|
|
26484
|
+
case NodeTypes.NormalExpression: {
|
|
26485
|
+
const normalExpressionNode = node;
|
|
26486
|
+
const unresolvedSymbols = /* @__PURE__ */ new Set();
|
|
26487
|
+
if (isNormalExpressionNodeWithName(normalExpressionNode)) {
|
|
26488
|
+
const [, [symbolNode]] = normalExpressionNode;
|
|
26489
|
+
if (isUserDefinedSymbolNode(symbolNode)) {
|
|
26490
|
+
if (contextStack.lookUp(symbolNode) === null) unresolvedSymbols.add(symbolNode[1]);
|
|
26491
|
+
}
|
|
26492
|
+
} else {
|
|
26493
|
+
const [, [expressionNode]] = normalExpressionNode;
|
|
26494
|
+
findUnresolvedSymbolsInNode(expressionNode, contextStack, builtin)?.forEach((symbol) => unresolvedSymbols.add(symbol));
|
|
26495
|
+
}
|
|
26496
|
+
for (const subNode of normalExpressionNode[1][1]) findUnresolvedSymbolsInNode(subNode, contextStack, builtin)?.forEach((symbol) => unresolvedSymbols.add(symbol));
|
|
26497
|
+
return unresolvedSymbols;
|
|
26498
|
+
}
|
|
26499
|
+
case NodeTypes.SpecialExpression: {
|
|
26500
|
+
const specialExpressionNode = node;
|
|
26501
|
+
const specialExpressionType = specialExpressionNode[1][0];
|
|
26502
|
+
const castedGetUndefinedSymbols = builtin.specialExpressions[specialExpressionType].getUndefinedSymbols;
|
|
26503
|
+
return castedGetUndefinedSymbols(specialExpressionNode, contextStack, {
|
|
26504
|
+
getUndefinedSymbols: getUndefinedSymbols$1,
|
|
26505
|
+
builtin
|
|
26506
|
+
});
|
|
26507
|
+
}
|
|
26508
|
+
case NodeTypes.Spread: return findUnresolvedSymbolsInNode(node[1], contextStack, builtin);
|
|
26659
26509
|
default: throw new DvalaError(`Unhandled node type: ${nodeType}`, node[2]);
|
|
26660
26510
|
}
|
|
26661
26511
|
}
|
|
@@ -27793,7 +27643,7 @@ const SUSPENDED_MESSAGE = "Program suspended";
|
|
|
27793
27643
|
* Generate a UUID for identifying a run() or resume() call.
|
|
27794
27644
|
* Uses crypto.randomUUID() when available, falls back to a simple generator.
|
|
27795
27645
|
*/
|
|
27796
|
-
function
|
|
27646
|
+
function generateUUID() {
|
|
27797
27647
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
|
|
27798
27648
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
27799
27649
|
const r = Math.random() * 16 | 0;
|
|
@@ -27801,6 +27651,15 @@ function generateRunId() {
|
|
|
27801
27651
|
});
|
|
27802
27652
|
}
|
|
27803
27653
|
/**
|
|
27654
|
+
* Create a Snapshot with a freshly generated unique `id`.
|
|
27655
|
+
*/
|
|
27656
|
+
function createSnapshot(fields) {
|
|
27657
|
+
return {
|
|
27658
|
+
id: generateUUID(),
|
|
27659
|
+
...fields
|
|
27660
|
+
};
|
|
27661
|
+
}
|
|
27662
|
+
/**
|
|
27804
27663
|
* Test whether a handler pattern key matches a given effect name.
|
|
27805
27664
|
*
|
|
27806
27665
|
* Rules:
|
|
@@ -28258,6 +28117,28 @@ function serializeSuspensionBlob(k, snapshots, nextSnapshotIndex, meta) {
|
|
|
28258
28117
|
return base;
|
|
28259
28118
|
}
|
|
28260
28119
|
/**
|
|
28120
|
+
* Create a terminal snapshot for completed or errored program states.
|
|
28121
|
+
* The continuation is empty (cannot resume), but checkpoints are preserved
|
|
28122
|
+
* for time travel debugging.
|
|
28123
|
+
*/
|
|
28124
|
+
function serializeTerminalSnapshot(snapshots, nextSnapshotIndex) {
|
|
28125
|
+
const base = {
|
|
28126
|
+
version: SUSPENSION_VERSION,
|
|
28127
|
+
contextStacks: [],
|
|
28128
|
+
k: []
|
|
28129
|
+
};
|
|
28130
|
+
if (snapshots.length > 0) {
|
|
28131
|
+
base.snapshots = snapshots;
|
|
28132
|
+
const roots = [];
|
|
28133
|
+
for (const snapshot of snapshots) roots.push(snapshot);
|
|
28134
|
+
const { roots: dedupedRoots, pool } = dedupSubTrees(roots, DEFAULT_DEDUP_THRESHOLD);
|
|
28135
|
+
for (let i = 0; i < base.snapshots.length; i++) base.snapshots[i] = dedupedRoots[i];
|
|
28136
|
+
if (Object.keys(pool).length > 0) base.pool = pool;
|
|
28137
|
+
}
|
|
28138
|
+
base.nextSnapshotIndex = nextSnapshotIndex;
|
|
28139
|
+
return base;
|
|
28140
|
+
}
|
|
28141
|
+
/**
|
|
28261
28142
|
* Deserialize a plain object (as produced by `serializeToObject`) back into
|
|
28262
28143
|
* a continuation stack and metadata.
|
|
28263
28144
|
*
|
|
@@ -28324,7 +28205,7 @@ function deserializeFromObject(blobData, options) {
|
|
|
28324
28205
|
};
|
|
28325
28206
|
}
|
|
28326
28207
|
//#endregion
|
|
28327
|
-
//#region src/evaluator/trampoline.ts
|
|
28208
|
+
//#region src/evaluator/trampoline-evaluator.ts
|
|
28328
28209
|
/**
|
|
28329
28210
|
* Trampoline evaluator — explicit-stack evaluation engine.
|
|
28330
28211
|
*
|
|
@@ -28342,292 +28223,10 @@ function deserializeFromObject(blobData, options) {
|
|
|
28342
28223
|
* - `stepNode` is always synchronous and returns `Step`.
|
|
28343
28224
|
* - `applyFrame` may return `Step | Promise<Step>` when normal expressions
|
|
28344
28225
|
* or compound function types produce async results.
|
|
28345
|
-
* - Normal built-in expressions are called directly with pre-evaluated args
|
|
28346
|
-
*
|
|
28347
|
-
* higher-order callbacks — suspension through them is deferred).
|
|
28348
|
-
* - Binding utilities (`evaluateBindingNodeValues`, `tryMatch`) are called
|
|
28349
|
-
* with a recursive `evaluateNode` helper. This is acceptable for Phase 1.
|
|
28226
|
+
* - Normal built-in expressions are called directly with pre-evaluated args.
|
|
28227
|
+
* - All binding and pattern matching use frame-based slot processing.
|
|
28350
28228
|
* - All state lives in frames (no JS closures) — enabling serialization later.
|
|
28351
28229
|
*/
|
|
28352
|
-
function evaluateNodeRecursive(node, contextStack) {
|
|
28353
|
-
switch (node[0]) {
|
|
28354
|
-
case NodeTypes.Number: return node[1];
|
|
28355
|
-
case NodeTypes.String: return node[1];
|
|
28356
|
-
case NodeTypes.NormalBuiltinSymbol:
|
|
28357
|
-
case NodeTypes.SpecialBuiltinSymbol:
|
|
28358
|
-
case NodeTypes.UserDefinedSymbol: return contextStack.evaluateSymbol(node);
|
|
28359
|
-
case NodeTypes.ReservedSymbol: return evaluateReservedSymbol(node);
|
|
28360
|
-
case NodeTypes.NormalExpression: return chain(evaluateNormalExpressionRecursive(node, contextStack), (resolved) => {
|
|
28361
|
-
if (typeof resolved === "number" && Number.isNaN(resolved)) throw new DvalaError("Number is NaN", node[2]);
|
|
28362
|
-
return annotate(resolved);
|
|
28363
|
-
});
|
|
28364
|
-
case NodeTypes.SpecialExpression: {
|
|
28365
|
-
const initial = {
|
|
28366
|
-
type: "Eval",
|
|
28367
|
-
node,
|
|
28368
|
-
env: contextStack,
|
|
28369
|
-
k: []
|
|
28370
|
-
};
|
|
28371
|
-
try {
|
|
28372
|
-
return annotate(runSyncTrampoline(initial));
|
|
28373
|
-
} catch (error) {
|
|
28374
|
-
/* v8 ignore next 4 */
|
|
28375
|
-
if (error instanceof DvalaError && error.message.includes("Unexpected async operation")) return runAsyncTrampoline({
|
|
28376
|
-
type: "Eval",
|
|
28377
|
-
node,
|
|
28378
|
-
env: contextStack,
|
|
28379
|
-
k: []
|
|
28380
|
-
}).then((r) => annotate(r));
|
|
28381
|
-
throw error;
|
|
28382
|
-
}
|
|
28383
|
-
}
|
|
28384
|
-
default: throw new DvalaError(`${getNodeTypeName(node[0])}-node cannot be evaluated`, node[2]);
|
|
28385
|
-
}
|
|
28386
|
-
}
|
|
28387
|
-
function evaluateParamsRecursive(paramNodes, contextStack) {
|
|
28388
|
-
const params = [];
|
|
28389
|
-
const placeholders = [];
|
|
28390
|
-
return chain(forEachSequential(paramNodes, (paramNode, index) => {
|
|
28391
|
-
if (isSpreadNode(paramNode))
|
|
28392
|
-
/* v8 ignore start */
|
|
28393
|
-
return chain(evaluateNodeRecursive(paramNode[1], contextStack), (spreadValue) => {
|
|
28394
|
-
if (Array.isArray(spreadValue)) params.push(...spreadValue);
|
|
28395
|
-
else throw new DvalaError(`Spread operator requires an array, got ${valueToString(paramNode)}`, paramNode[2]);
|
|
28396
|
-
});
|
|
28397
|
-
else if (paramNode[0] === NodeTypes.ReservedSymbol && paramNode[1] === "_") placeholders.push(index);
|
|
28398
|
-
else return chain(evaluateNodeRecursive(paramNode, contextStack), (value) => {
|
|
28399
|
-
params.push(value);
|
|
28400
|
-
});
|
|
28401
|
-
}), () => ({
|
|
28402
|
-
params,
|
|
28403
|
-
placeholders
|
|
28404
|
-
}));
|
|
28405
|
-
}
|
|
28406
|
-
function evaluateNormalExpressionRecursive(node, contextStack) {
|
|
28407
|
-
const sourceCodeInfo = node[2];
|
|
28408
|
-
return chain(evaluateParamsRecursive(node[1][1], contextStack), ({ params, placeholders }) => {
|
|
28409
|
-
if (isNormalExpressionNodeWithName(node)) {
|
|
28410
|
-
const nameSymbol = node[1][0];
|
|
28411
|
-
if (placeholders.length > 0) return chain(evaluateNodeRecursive(nameSymbol, contextStack), (resolvedFn) => {
|
|
28412
|
-
return {
|
|
28413
|
-
[FUNCTION_SYMBOL]: true,
|
|
28414
|
-
function: asFunctionLike(resolvedFn, sourceCodeInfo),
|
|
28415
|
-
functionType: "Partial",
|
|
28416
|
-
params,
|
|
28417
|
-
placeholders,
|
|
28418
|
-
sourceCodeInfo,
|
|
28419
|
-
arity: toFixedArity(placeholders.length)
|
|
28420
|
-
};
|
|
28421
|
-
});
|
|
28422
|
-
if (isNormalBuiltinSymbolNode(nameSymbol)) {
|
|
28423
|
-
const type = nameSymbol[1];
|
|
28424
|
-
const normalExpression = builtin.allNormalExpressions[type];
|
|
28425
|
-
if (contextStack.pure && normalExpression.pure === false) throw new DvalaError(`Cannot call impure function '${normalExpression.name}' in pure mode`, node[2]);
|
|
28426
|
-
/* v8 ignore next 3 */
|
|
28427
|
-
if (normalExpression.dvalaImpl) return executeUserDefinedRecursive(normalExpression.dvalaImpl, params, contextStack, node[2]);
|
|
28428
|
-
return normalExpression.evaluate(params, node[2], contextStack, { executeFunction: executeFunctionRecursive });
|
|
28429
|
-
} else {
|
|
28430
|
-
const fn = contextStack.getValue(nameSymbol[1]);
|
|
28431
|
-
if (fn !== void 0) return executeFunctionRecursive(asFunctionLike(fn, sourceCodeInfo), params, contextStack, sourceCodeInfo);
|
|
28432
|
-
/* v8 ignore next 1 */
|
|
28433
|
-
throw new UndefinedSymbolError(nameSymbol[1], node[2]);
|
|
28434
|
-
}
|
|
28435
|
-
} else {
|
|
28436
|
-
const fnNode = node[1][0];
|
|
28437
|
-
/* v8 ignore start */
|
|
28438
|
-
return chain(evaluateNodeRecursive(fnNode, contextStack), (resolvedFn) => {
|
|
28439
|
-
const fn = asFunctionLike(resolvedFn, sourceCodeInfo);
|
|
28440
|
-
if (placeholders.length > 0) return {
|
|
28441
|
-
[FUNCTION_SYMBOL]: true,
|
|
28442
|
-
function: fn,
|
|
28443
|
-
functionType: "Partial",
|
|
28444
|
-
params,
|
|
28445
|
-
placeholders,
|
|
28446
|
-
sourceCodeInfo,
|
|
28447
|
-
arity: toFixedArity(placeholders.length)
|
|
28448
|
-
};
|
|
28449
|
-
return executeFunctionRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28450
|
-
});
|
|
28451
|
-
}
|
|
28452
|
-
});
|
|
28453
|
-
}
|
|
28454
|
-
function executeFunctionRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28455
|
-
if (isDvalaFunction(fn)) return executeDvalaFunctionRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28456
|
-
if (Array.isArray(fn)) return evaluateArrayAsFunction(fn, params, sourceCodeInfo);
|
|
28457
|
-
if (isObj(fn)) return evaluateObjectAsFunction(fn, params, sourceCodeInfo);
|
|
28458
|
-
if (typeof fn === "string") return evaluateStringAsFunction(fn, params, sourceCodeInfo);
|
|
28459
|
-
if (isNumber(fn)) return evaluateNumberAsFunction(fn, params, sourceCodeInfo);
|
|
28460
|
-
/* v8 ignore next 1 */
|
|
28461
|
-
throw new DvalaError("Unexpected function type", sourceCodeInfo);
|
|
28462
|
-
}
|
|
28463
|
-
/**
|
|
28464
|
-
* Execute a DvalaFunction recursively. This is the old-style executor
|
|
28465
|
-
* used as a fallback for normal expression callbacks.
|
|
28466
|
-
*/
|
|
28467
|
-
function executeDvalaFunctionRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28468
|
-
switch (fn.functionType) {
|
|
28469
|
-
case "UserDefined": return executeUserDefinedRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28470
|
-
case "Partial": return executePartialRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28471
|
-
case "Comp": return executeCompRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28472
|
-
case "Constantly": return fn.value;
|
|
28473
|
-
case "Juxt": return executeJuxtRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28474
|
-
case "Complement": return chain(executeFunctionRecursive(fn.function, params, contextStack, sourceCodeInfo), (result) => !result);
|
|
28475
|
-
case "EveryPred": return executeEveryPredRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28476
|
-
case "SomePred": return executeSomePredRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28477
|
-
case "Fnull": return executeFnullRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28478
|
-
case "EffectMatcher": return executeEffectMatcherRecursive(fn, params, sourceCodeInfo);
|
|
28479
|
-
case "Builtin": {
|
|
28480
|
-
const normalExpression = builtin.allNormalExpressions[fn.normalBuiltinSymbolType];
|
|
28481
|
-
if (normalExpression.dvalaImpl) return executeUserDefinedRecursive(normalExpression.dvalaImpl, params, contextStack, sourceCodeInfo);
|
|
28482
|
-
return executeBuiltinRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28483
|
-
}
|
|
28484
|
-
case "SpecialBuiltin": return executeSpecialBuiltinRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28485
|
-
case "Module": return executeModuleRecursive(fn, params, contextStack, sourceCodeInfo);
|
|
28486
|
-
}
|
|
28487
|
-
}
|
|
28488
|
-
function executeUserDefinedRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28489
|
-
function setupAndExecute(currentParams) {
|
|
28490
|
-
if (!arityAcceptsMin(fn.arity, currentParams.length)) throw new DvalaError(`Expected ${fn.arity} arguments, got ${currentParams.length}.`, sourceCodeInfo);
|
|
28491
|
-
const evaluatedFunction = fn.evaluatedfunction;
|
|
28492
|
-
const args = evaluatedFunction[0];
|
|
28493
|
-
const nbrOfNonRestArgs = args.filter((arg) => arg[0] !== bindingTargetTypes.rest).length;
|
|
28494
|
-
const newContextStack = contextStack.create(fn.evaluatedfunction[2]);
|
|
28495
|
-
const newContext = { self: { value: fn } };
|
|
28496
|
-
const rest = [];
|
|
28497
|
-
let paramSetup = void 0;
|
|
28498
|
-
for (let i = 0; i < currentParams.length; i += 1) if (i < nbrOfNonRestArgs) {
|
|
28499
|
-
const paramIndex = i;
|
|
28500
|
-
paramSetup = chain(paramSetup, () => {
|
|
28501
|
-
const param = toAny(currentParams[paramIndex]);
|
|
28502
|
-
return chain(evaluateBindingNodeValues(args[paramIndex], param, (node) => evaluateNodeRecursive(node, newContextStack.create(newContext))), (valueRecord) => {
|
|
28503
|
-
Object.entries(valueRecord).forEach(([key, value]) => {
|
|
28504
|
-
newContext[key] = { value };
|
|
28505
|
-
});
|
|
28506
|
-
});
|
|
28507
|
-
});
|
|
28508
|
-
} else rest.push(toAny(currentParams[i]));
|
|
28509
|
-
let defaultSetup = void 0;
|
|
28510
|
-
for (let i = currentParams.length; i < nbrOfNonRestArgs; i++) {
|
|
28511
|
-
const argIndex = i;
|
|
28512
|
-
defaultSetup = chain(defaultSetup, () => {
|
|
28513
|
-
const arg = args[argIndex];
|
|
28514
|
-
return chain(evaluateNodeRecursive(arg[1][1], contextStack.create(newContext)), (defaultValue) => {
|
|
28515
|
-
return chain(evaluateBindingNodeValues(arg, defaultValue, (node) => evaluateNodeRecursive(node, contextStack.create(newContext))), (valueRecord) => {
|
|
28516
|
-
Object.entries(valueRecord).forEach(([key, value]) => {
|
|
28517
|
-
newContext[key] = { value };
|
|
28518
|
-
});
|
|
28519
|
-
});
|
|
28520
|
-
});
|
|
28521
|
-
});
|
|
28522
|
-
}
|
|
28523
|
-
return chain(paramSetup, () => chain(defaultSetup, () => {
|
|
28524
|
-
const restArgument = args.find((arg) => arg[0] === bindingTargetTypes.rest);
|
|
28525
|
-
return chain(restArgument !== void 0 ? chain(evaluateBindingNodeValues(restArgument, rest, (node) => evaluateNodeRecursive(node, contextStack.create(newContext))), (valueRecord) => {
|
|
28526
|
-
Object.entries(valueRecord).forEach(([key, value]) => {
|
|
28527
|
-
newContext[key] = { value };
|
|
28528
|
-
});
|
|
28529
|
-
}) : void 0, () => {
|
|
28530
|
-
const newContextStack2 = newContextStack.create(newContext);
|
|
28531
|
-
const bodyResult = reduceSequential(evaluatedFunction[1], (_acc, node) => evaluateNodeRecursive(node, newContextStack2), null);
|
|
28532
|
-
/* v8 ignore start */
|
|
28533
|
-
if (bodyResult instanceof Promise) return bodyResult.catch((error) => {
|
|
28534
|
-
if (error instanceof RecurSignal) return setupAndExecute(error.params);
|
|
28535
|
-
throw error;
|
|
28536
|
-
});
|
|
28537
|
-
/* v8 ignore stop */
|
|
28538
|
-
return bodyResult;
|
|
28539
|
-
});
|
|
28540
|
-
}));
|
|
28541
|
-
}
|
|
28542
|
-
for (;;) try {
|
|
28543
|
-
return setupAndExecute(params);
|
|
28544
|
-
} catch (error) {
|
|
28545
|
-
if (error instanceof RecurSignal) {
|
|
28546
|
-
params = error.params;
|
|
28547
|
-
continue;
|
|
28548
|
-
}
|
|
28549
|
-
throw error;
|
|
28550
|
-
}
|
|
28551
|
-
}
|
|
28552
|
-
function executePartialRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28553
|
-
const actualParams = [...fn.params];
|
|
28554
|
-
/* v8 ignore next 3 */
|
|
28555
|
-
if (params.length !== fn.placeholders.length) throw new DvalaError(`(partial) expects ${fn.placeholders.length} arguments, got ${params.length}.`, sourceCodeInfo);
|
|
28556
|
-
const paramsCopy = [...params];
|
|
28557
|
-
for (const placeholderIndex of fn.placeholders) actualParams.splice(placeholderIndex, 0, paramsCopy.shift());
|
|
28558
|
-
return executeFunctionRecursive(fn.function, actualParams, contextStack, sourceCodeInfo);
|
|
28559
|
-
}
|
|
28560
|
-
function executeCompRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28561
|
-
const { params: f } = fn;
|
|
28562
|
-
if (f.length === 0) {
|
|
28563
|
-
if (params.length !== 1) throw new DvalaError(`(comp) expects one argument, got ${valueToString(params.length)}.`, sourceCodeInfo);
|
|
28564
|
-
return asAny(params[0], sourceCodeInfo);
|
|
28565
|
-
}
|
|
28566
|
-
let result = params;
|
|
28567
|
-
for (let i = f.length - 1; i >= 0; i--) {
|
|
28568
|
-
const fun = f[i];
|
|
28569
|
-
result = chain(result, (currentParams) => chain(executeFunctionRecursive(asFunctionLike(fun, sourceCodeInfo), currentParams, contextStack, sourceCodeInfo), (r) => [r]));
|
|
28570
|
-
}
|
|
28571
|
-
return chain(result, (finalArr) => asAny(finalArr[0], sourceCodeInfo));
|
|
28572
|
-
}
|
|
28573
|
-
function executeJuxtRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28574
|
-
return mapSequential(fn.params, (fun) => executeFunctionRecursive(asFunctionLike(fun, sourceCodeInfo), params, contextStack, sourceCodeInfo));
|
|
28575
|
-
}
|
|
28576
|
-
function executeEveryPredRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28577
|
-
const checks = [];
|
|
28578
|
-
for (const f of fn.params) for (const param of params) checks.push(() => executeFunctionRecursive(asFunctionLike(f, sourceCodeInfo), [param], contextStack, sourceCodeInfo));
|
|
28579
|
-
return reduceSequential(checks, (acc, check) => {
|
|
28580
|
-
if (!acc) return false;
|
|
28581
|
-
return chain(check(), (result) => !!result);
|
|
28582
|
-
}, true);
|
|
28583
|
-
}
|
|
28584
|
-
function executeSomePredRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28585
|
-
const checks = [];
|
|
28586
|
-
for (const f of fn.params) for (const param of params) checks.push(() => executeFunctionRecursive(asFunctionLike(f, sourceCodeInfo), [param], contextStack, sourceCodeInfo));
|
|
28587
|
-
return reduceSequential(checks, (acc, check) => {
|
|
28588
|
-
if (acc) return true;
|
|
28589
|
-
return chain(check(), (result) => !!result);
|
|
28590
|
-
}, false);
|
|
28591
|
-
}
|
|
28592
|
-
function executeFnullRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28593
|
-
const fnulledParams = params.map((param, index) => param === null ? toAny(fn.params[index]) : param);
|
|
28594
|
-
return executeFunctionRecursive(asFunctionLike(fn.function, sourceCodeInfo), fnulledParams, contextStack, sourceCodeInfo);
|
|
28595
|
-
}
|
|
28596
|
-
function executeEffectMatcherRecursive(fn, params, sourceCodeInfo) {
|
|
28597
|
-
assertNumberOfParams({
|
|
28598
|
-
min: 1,
|
|
28599
|
-
max: 1
|
|
28600
|
-
}, params.length, fn.sourceCodeInfo ?? sourceCodeInfo);
|
|
28601
|
-
const effectRef = params[0];
|
|
28602
|
-
assertEffect(effectRef, sourceCodeInfo);
|
|
28603
|
-
const effectName = effectRef.name;
|
|
28604
|
-
if (fn.matchType === "string") return effectNameMatchesPattern(effectName, fn.pattern);
|
|
28605
|
-
return new RegExp(fn.pattern, fn.flags).test(effectName);
|
|
28606
|
-
}
|
|
28607
|
-
function executeBuiltinRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28608
|
-
const normalExpression = asNonUndefined(builtin.allNormalExpressions[fn.normalBuiltinSymbolType], sourceCodeInfo);
|
|
28609
|
-
/* v8 ignore next 6 */
|
|
28610
|
-
if (contextStack.pure && normalExpression.pure === false) throw new DvalaError(`Cannot call impure function '${fn.name}' in pure mode`, sourceCodeInfo);
|
|
28611
|
-
if (normalExpression.dvalaImpl) return executeUserDefinedRecursive(normalExpression.dvalaImpl, params, contextStack, sourceCodeInfo);
|
|
28612
|
-
return normalExpression.evaluate(params, sourceCodeInfo, contextStack, { executeFunction: executeFunctionRecursive });
|
|
28613
|
-
}
|
|
28614
|
-
/* v8 ignore start */
|
|
28615
|
-
function executeSpecialBuiltinRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28616
|
-
const specialExpression = asNonUndefined(builtin.specialExpressions[fn.specialBuiltinSymbolType], sourceCodeInfo);
|
|
28617
|
-
if (specialExpression.evaluateAsNormalExpression) return specialExpression.evaluateAsNormalExpression(params, sourceCodeInfo, contextStack, { executeFunction: executeFunctionRecursive });
|
|
28618
|
-
throw new DvalaError(`Special builtin function ${fn.specialBuiltinSymbolType} is not supported as normal expression.`, sourceCodeInfo);
|
|
28619
|
-
}
|
|
28620
|
-
function executeModuleRecursive(fn, params, contextStack, sourceCodeInfo) {
|
|
28621
|
-
const dvalaModule = contextStack.getModule(fn.moduleName);
|
|
28622
|
-
if (!dvalaModule) throw new DvalaError(`Module '${fn.moduleName}' not found.`, sourceCodeInfo);
|
|
28623
|
-
const expression = dvalaModule.functions[fn.functionName];
|
|
28624
|
-
if (!expression) throw new DvalaError(`Function '${fn.functionName}' not found in module '${fn.moduleName}'.`, sourceCodeInfo);
|
|
28625
|
-
if (contextStack.pure && expression.pure === false) throw new DvalaError(`Cannot call impure function '${fn.functionName}' in pure mode`, sourceCodeInfo);
|
|
28626
|
-
assertNumberOfParams(expression.arity, params.length, sourceCodeInfo);
|
|
28627
|
-
if (expression.dvalaImpl) return executeUserDefinedRecursive(expression.dvalaImpl, params, contextStack, sourceCodeInfo);
|
|
28628
|
-
return expression.evaluate(params, sourceCodeInfo, contextStack, { executeFunction: executeFunctionRecursive });
|
|
28629
|
-
}
|
|
28630
|
-
/* v8 ignore stop */
|
|
28631
28230
|
function evaluateObjectAsFunction(fn, params, sourceCodeInfo) {
|
|
28632
28231
|
if (params.length !== 1) throw new DvalaError("Object as function requires one string parameter.", sourceCodeInfo);
|
|
28633
28232
|
const key = params[0];
|
|
@@ -28675,7 +28274,7 @@ function evaluateFunction(fn, contextStack) {
|
|
|
28675
28274
|
});
|
|
28676
28275
|
return ctx;
|
|
28677
28276
|
}, {});
|
|
28678
|
-
getUndefinedSymbols$1(fn[1], contextStack.new(context), builtin
|
|
28277
|
+
getUndefinedSymbols$1(fn[1], contextStack.new(context), builtin).forEach((name) => {
|
|
28679
28278
|
const value = contextStack.getValue(name);
|
|
28680
28279
|
if (isAny(value)) functionContext[name] = { value };
|
|
28681
28280
|
});
|
|
@@ -28948,26 +28547,34 @@ function stepSpecialExpression(node, env, k) {
|
|
|
28948
28547
|
const nodes = node[1][1];
|
|
28949
28548
|
const withHandlerNodes = node[1][2];
|
|
28950
28549
|
const newEnv = env.create({});
|
|
28951
|
-
|
|
28952
|
-
|
|
28953
|
-
|
|
28954
|
-
|
|
28955
|
-
|
|
28956
|
-
|
|
28957
|
-
|
|
28958
|
-
|
|
28959
|
-
|
|
28960
|
-
|
|
28550
|
+
if (withHandlerNodes && withHandlerNodes.length > 0) {
|
|
28551
|
+
const effectRefFrame = {
|
|
28552
|
+
type: "EffectRef",
|
|
28553
|
+
handlerNodes: withHandlerNodes,
|
|
28554
|
+
evaluatedHandlers: [],
|
|
28555
|
+
index: 0,
|
|
28556
|
+
bodyNodes: nodes,
|
|
28557
|
+
bodyEnv: newEnv,
|
|
28558
|
+
env,
|
|
28559
|
+
sourceCodeInfo
|
|
28560
|
+
};
|
|
28561
|
+
return {
|
|
28562
|
+
type: "Eval",
|
|
28563
|
+
node: withHandlerNodes[0][0],
|
|
28564
|
+
env,
|
|
28565
|
+
k: [effectRefFrame, ...k]
|
|
28566
|
+
};
|
|
28567
|
+
}
|
|
28961
28568
|
if (nodes.length === 0) return {
|
|
28962
28569
|
type: "Value",
|
|
28963
28570
|
value: null,
|
|
28964
|
-
k
|
|
28571
|
+
k
|
|
28965
28572
|
};
|
|
28966
28573
|
if (nodes.length === 1) return {
|
|
28967
28574
|
type: "Eval",
|
|
28968
28575
|
node: nodes[0],
|
|
28969
28576
|
env: newEnv,
|
|
28970
|
-
k
|
|
28577
|
+
k
|
|
28971
28578
|
};
|
|
28972
28579
|
const frame = {
|
|
28973
28580
|
type: "Sequence",
|
|
@@ -28980,7 +28587,7 @@ function stepSpecialExpression(node, env, k) {
|
|
|
28980
28587
|
type: "Eval",
|
|
28981
28588
|
node: nodes[0],
|
|
28982
28589
|
env: newEnv,
|
|
28983
|
-
k: [frame, ...
|
|
28590
|
+
k: [frame, ...k]
|
|
28984
28591
|
};
|
|
28985
28592
|
}
|
|
28986
28593
|
case specialExpressionTypes.let: {
|
|
@@ -29335,7 +28942,7 @@ function dispatchCall(frame, k) {
|
|
|
29335
28942
|
if (env.pure && normalExpression.pure === false) throw new DvalaError(`Cannot call impure function '${normalExpression.name}' in pure mode`, sourceCodeInfo);
|
|
29336
28943
|
/* v8 ignore next 3 */
|
|
29337
28944
|
if (normalExpression.dvalaImpl) return setupUserDefinedCall(normalExpression.dvalaImpl, params, env, sourceCodeInfo, k);
|
|
29338
|
-
return wrapMaybePromiseAsStep(normalExpression.evaluate(params, sourceCodeInfo, env
|
|
28945
|
+
return wrapMaybePromiseAsStep(normalExpression.evaluate(params, sourceCodeInfo, env), k);
|
|
29339
28946
|
}
|
|
29340
28947
|
const fn = env.getValue(nameSymbol[1]);
|
|
29341
28948
|
if (fn !== void 0) return dispatchFunction(asFunctionLike(fn, sourceCodeInfo), params, placeholders, env, sourceCodeInfo, k);
|
|
@@ -29396,79 +29003,219 @@ function dispatchFunction(fn, params, placeholders, env, sourceCodeInfo, k) {
|
|
|
29396
29003
|
}
|
|
29397
29004
|
/**
|
|
29398
29005
|
* Dispatch a DvalaFunction. User-defined functions are set up with frames;
|
|
29399
|
-
* compound function types
|
|
29006
|
+
* some compound function types still use the recursive executor for iteration.
|
|
29400
29007
|
*/
|
|
29401
29008
|
function dispatchDvalaFunction(fn, params, env, sourceCodeInfo, k) {
|
|
29402
29009
|
switch (fn.functionType) {
|
|
29403
29010
|
case "UserDefined": return setupUserDefinedCall(fn, params, env, sourceCodeInfo, k);
|
|
29404
|
-
case "
|
|
29405
|
-
|
|
29406
|
-
|
|
29407
|
-
|
|
29408
|
-
|
|
29409
|
-
case "
|
|
29410
|
-
|
|
29411
|
-
|
|
29412
|
-
|
|
29413
|
-
|
|
29414
|
-
|
|
29415
|
-
|
|
29416
|
-
|
|
29417
|
-
|
|
29418
|
-
|
|
29419
|
-
|
|
29420
|
-
|
|
29011
|
+
case "Constantly": return {
|
|
29012
|
+
type: "Value",
|
|
29013
|
+
value: fn.value,
|
|
29014
|
+
k
|
|
29015
|
+
};
|
|
29016
|
+
case "EffectMatcher": {
|
|
29017
|
+
assertNumberOfParams({
|
|
29018
|
+
min: 1,
|
|
29019
|
+
max: 1
|
|
29020
|
+
}, params.length, fn.sourceCodeInfo ?? sourceCodeInfo);
|
|
29021
|
+
const effectRef = params[0];
|
|
29022
|
+
assertEffect(effectRef, sourceCodeInfo);
|
|
29023
|
+
const effectName = effectRef.name;
|
|
29024
|
+
if (fn.matchType === "string") return {
|
|
29025
|
+
type: "Value",
|
|
29026
|
+
value: effectNameMatchesPattern(effectName, fn.pattern),
|
|
29027
|
+
k
|
|
29028
|
+
};
|
|
29029
|
+
return {
|
|
29030
|
+
type: "Value",
|
|
29031
|
+
value: new RegExp(fn.pattern, fn.flags).test(effectName),
|
|
29032
|
+
k
|
|
29033
|
+
};
|
|
29421
29034
|
}
|
|
29422
|
-
case "
|
|
29035
|
+
case "Partial": {
|
|
29036
|
+
const actualParams = [...fn.params];
|
|
29037
|
+
if (params.length !== fn.placeholders.length) throw new DvalaError(`(partial) expects ${fn.placeholders.length} arguments, got ${params.length}.`, sourceCodeInfo);
|
|
29038
|
+
const paramsCopy = [...params];
|
|
29039
|
+
for (const placeholderIndex of fn.placeholders) actualParams.splice(placeholderIndex, 0, paramsCopy.shift());
|
|
29040
|
+
return dispatchFunction(fn.function, actualParams, [], env, sourceCodeInfo, k);
|
|
29041
|
+
}
|
|
29042
|
+
case "Fnull": {
|
|
29043
|
+
const fnulledParams = params.map((param, index) => param === null ? toAny(fn.params[index]) : param);
|
|
29044
|
+
return dispatchFunction(fn.function, fnulledParams, [], env, sourceCodeInfo, k);
|
|
29045
|
+
}
|
|
29046
|
+
case "Complement": {
|
|
29047
|
+
const frame = {
|
|
29048
|
+
type: "Complement",
|
|
29049
|
+
sourceCodeInfo
|
|
29050
|
+
};
|
|
29051
|
+
return dispatchFunction(fn.function, params, [], env, sourceCodeInfo, [frame, ...k]);
|
|
29052
|
+
}
|
|
29053
|
+
case "Comp": {
|
|
29054
|
+
const fns = fn.params;
|
|
29055
|
+
if (fns.length === 0) {
|
|
29056
|
+
if (params.length !== 1) throw new DvalaError(`(comp) expects one argument, got ${valueToString(params.length)}.`, sourceCodeInfo);
|
|
29057
|
+
return {
|
|
29058
|
+
type: "Value",
|
|
29059
|
+
value: asAny(params[0], sourceCodeInfo),
|
|
29060
|
+
k
|
|
29061
|
+
};
|
|
29062
|
+
}
|
|
29063
|
+
const startIndex = fns.length - 1;
|
|
29064
|
+
const frame = {
|
|
29065
|
+
type: "Comp",
|
|
29066
|
+
fns,
|
|
29067
|
+
index: startIndex - 1,
|
|
29068
|
+
env,
|
|
29069
|
+
sourceCodeInfo
|
|
29070
|
+
};
|
|
29071
|
+
return dispatchFunction(asFunctionLike(fns[startIndex], sourceCodeInfo), params, [], env, sourceCodeInfo, [frame, ...k]);
|
|
29072
|
+
}
|
|
29073
|
+
case "Juxt": {
|
|
29074
|
+
const fns = fn.params;
|
|
29075
|
+
if (fns.length === 0) return {
|
|
29076
|
+
type: "Value",
|
|
29077
|
+
value: [],
|
|
29078
|
+
k
|
|
29079
|
+
};
|
|
29080
|
+
const frame = {
|
|
29081
|
+
type: "Juxt",
|
|
29082
|
+
fns,
|
|
29083
|
+
params,
|
|
29084
|
+
index: 1,
|
|
29085
|
+
results: [],
|
|
29086
|
+
env,
|
|
29087
|
+
sourceCodeInfo
|
|
29088
|
+
};
|
|
29089
|
+
return dispatchFunction(asFunctionLike(fns[0], sourceCodeInfo), params, [], env, sourceCodeInfo, [frame, ...k]);
|
|
29090
|
+
}
|
|
29091
|
+
case "EveryPred": {
|
|
29092
|
+
const checks = [];
|
|
29093
|
+
for (const f of fn.params) for (const p of params) checks.push({
|
|
29094
|
+
fn: asFunctionLike(f, sourceCodeInfo),
|
|
29095
|
+
param: p
|
|
29096
|
+
});
|
|
29097
|
+
if (checks.length === 0) return {
|
|
29098
|
+
type: "Value",
|
|
29099
|
+
value: true,
|
|
29100
|
+
k
|
|
29101
|
+
};
|
|
29102
|
+
const frame = {
|
|
29103
|
+
type: "EveryPred",
|
|
29104
|
+
checks,
|
|
29105
|
+
index: 1,
|
|
29106
|
+
env,
|
|
29107
|
+
sourceCodeInfo
|
|
29108
|
+
};
|
|
29109
|
+
const firstCheck = checks[0];
|
|
29110
|
+
return dispatchFunction(firstCheck.fn, [firstCheck.param], [], env, sourceCodeInfo, [frame, ...k]);
|
|
29111
|
+
}
|
|
29112
|
+
case "SomePred": {
|
|
29113
|
+
const checks = [];
|
|
29114
|
+
for (const f of fn.params) for (const p of params) checks.push({
|
|
29115
|
+
fn: asFunctionLike(f, sourceCodeInfo),
|
|
29116
|
+
param: p
|
|
29117
|
+
});
|
|
29118
|
+
if (checks.length === 0) return {
|
|
29119
|
+
type: "Value",
|
|
29120
|
+
value: false,
|
|
29121
|
+
k
|
|
29122
|
+
};
|
|
29123
|
+
const frame = {
|
|
29124
|
+
type: "SomePred",
|
|
29125
|
+
checks,
|
|
29126
|
+
index: 1,
|
|
29127
|
+
env,
|
|
29128
|
+
sourceCodeInfo
|
|
29129
|
+
};
|
|
29130
|
+
const firstCheck = checks[0];
|
|
29131
|
+
return dispatchFunction(firstCheck.fn, [firstCheck.param], [], env, sourceCodeInfo, [frame, ...k]);
|
|
29132
|
+
}
|
|
29133
|
+
case "SpecialBuiltin": {
|
|
29134
|
+
const specialExpression = asNonUndefined(builtin.specialExpressions[fn.specialBuiltinSymbolType], sourceCodeInfo);
|
|
29135
|
+
if (specialExpression.evaluateAsNormalExpression) return wrapMaybePromiseAsStep(specialExpression.evaluateAsNormalExpression(params, sourceCodeInfo, env), k);
|
|
29136
|
+
throw new DvalaError(`Special builtin function ${fn.specialBuiltinSymbolType} is not supported as normal expression.`, sourceCodeInfo);
|
|
29137
|
+
}
|
|
29138
|
+
case "Module": {
|
|
29139
|
+
const dvalaModule = env.getModule(fn.moduleName);
|
|
29140
|
+
if (!dvalaModule) throw new DvalaError(`Module '${fn.moduleName}' not found.`, sourceCodeInfo);
|
|
29141
|
+
const expression = dvalaModule.functions[fn.functionName];
|
|
29142
|
+
if (!expression) throw new DvalaError(`Function '${fn.functionName}' not found in module '${fn.moduleName}'.`, sourceCodeInfo);
|
|
29143
|
+
if (env.pure && expression.pure === false) throw new DvalaError(`Cannot call impure function '${fn.functionName}' in pure mode`, sourceCodeInfo);
|
|
29144
|
+
assertNumberOfParams(expression.arity, params.length, sourceCodeInfo);
|
|
29145
|
+
if (expression.dvalaImpl) return setupUserDefinedCall(expression.dvalaImpl, params, env, sourceCodeInfo, k);
|
|
29146
|
+
return wrapMaybePromiseAsStep(expression.evaluate(params, sourceCodeInfo, env), k);
|
|
29147
|
+
}
|
|
29148
|
+
case "Builtin": {
|
|
29423
29149
|
const normalExpression = builtin.allNormalExpressions[fn.normalBuiltinSymbolType];
|
|
29150
|
+
if (env.pure && normalExpression.pure === false) throw new DvalaError(`Cannot call impure function '${normalExpression.name}' in pure mode`, sourceCodeInfo);
|
|
29424
29151
|
if (normalExpression.dvalaImpl) return setupUserDefinedCall(normalExpression.dvalaImpl, params, env, sourceCodeInfo, k);
|
|
29425
|
-
return wrapMaybePromiseAsStep(
|
|
29152
|
+
return wrapMaybePromiseAsStep(normalExpression.evaluate(params, sourceCodeInfo, env), k);
|
|
29426
29153
|
}
|
|
29427
29154
|
}
|
|
29428
29155
|
}
|
|
29429
29156
|
/**
|
|
29430
29157
|
* Set up a user-defined function call: bind params, push FnBodyFrame.
|
|
29431
29158
|
*
|
|
29432
|
-
*
|
|
29433
|
-
*
|
|
29434
|
-
* This will be converted to use frames in a later phase.
|
|
29159
|
+
* Uses frame-based binding slots for all argument binding, enabling
|
|
29160
|
+
* suspension/serialization at any point during destructuring.
|
|
29435
29161
|
*/
|
|
29436
29162
|
function setupUserDefinedCall(fn, params, env, sourceCodeInfo, k) {
|
|
29437
29163
|
if (!arityAcceptsMin(fn.arity, params.length)) throw new DvalaError(`Expected ${fn.arity} arguments, got ${params.length}.`, sourceCodeInfo);
|
|
29164
|
+
const nbrOfNonRestArgs = fn.evaluatedfunction[0].filter((arg) => arg[0] !== bindingTargetTypes.rest).length;
|
|
29165
|
+
return continueArgSlotBinding(fn, params, 0, nbrOfNonRestArgs, { self: { value: fn } }, env, sourceCodeInfo, k);
|
|
29166
|
+
}
|
|
29167
|
+
/**
|
|
29168
|
+
* Continue binding function arguments using slot-based binding.
|
|
29169
|
+
* Handles provided args, defaults, rest, then proceeds to body.
|
|
29170
|
+
*/
|
|
29171
|
+
function continueArgSlotBinding(fn, params, argIndex, nbrOfNonRestArgs, context, outerEnv, sourceCodeInfo, k) {
|
|
29438
29172
|
const evaluatedFunc = fn.evaluatedfunction;
|
|
29439
29173
|
const args = evaluatedFunc[0];
|
|
29440
|
-
const
|
|
29441
|
-
const
|
|
29442
|
-
|
|
29443
|
-
|
|
29444
|
-
|
|
29445
|
-
|
|
29446
|
-
|
|
29447
|
-
|
|
29448
|
-
|
|
29449
|
-
|
|
29450
|
-
|
|
29451
|
-
|
|
29452
|
-
|
|
29453
|
-
|
|
29454
|
-
|
|
29455
|
-
if (defaultValue instanceof Promise) return wrapMaybePromiseAsStep(executeUserDefinedRecursive(fn, params, env, sourceCodeInfo), k);
|
|
29456
|
-
const valueRecord = evaluateBindingNodeValues(arg, defaultValue, (n) => evaluateNodeRecursive(n, newContextStack.create(newContext)));
|
|
29457
|
-
if (valueRecord instanceof Promise) return wrapMaybePromiseAsStep(executeUserDefinedRecursive(fn, params, env, sourceCodeInfo), k);
|
|
29458
|
-
Object.entries(valueRecord).forEach(([key, value]) => {
|
|
29459
|
-
newContext[key] = { value };
|
|
29460
|
-
});
|
|
29174
|
+
const closureContext = evaluatedFunc[2];
|
|
29175
|
+
const bindingEnv = outerEnv.create(closureContext).create(context);
|
|
29176
|
+
if (argIndex < params.length && argIndex < nbrOfNonRestArgs) {
|
|
29177
|
+
const param = toAny(params[argIndex]);
|
|
29178
|
+
const argTarget = args[argIndex];
|
|
29179
|
+
return startBindingSlots(argTarget, param, bindingEnv, sourceCodeInfo, [{
|
|
29180
|
+
type: "FnArgSlotComplete",
|
|
29181
|
+
fn,
|
|
29182
|
+
params,
|
|
29183
|
+
argIndex,
|
|
29184
|
+
nbrOfNonRestArgs,
|
|
29185
|
+
context,
|
|
29186
|
+
outerEnv,
|
|
29187
|
+
sourceCodeInfo
|
|
29188
|
+
}, ...k]);
|
|
29461
29189
|
}
|
|
29190
|
+
if (argIndex < nbrOfNonRestArgs) return continueBindingArgs(fn, params, argIndex, nbrOfNonRestArgs, context, outerEnv, sourceCodeInfo, k);
|
|
29191
|
+
return handleRestArgAndBody(fn, params, nbrOfNonRestArgs, context, outerEnv, sourceCodeInfo, k);
|
|
29192
|
+
}
|
|
29193
|
+
/**
|
|
29194
|
+
* Handle rest argument binding and proceed to body evaluation.
|
|
29195
|
+
*/
|
|
29196
|
+
function handleRestArgAndBody(fn, params, nbrOfNonRestArgs, context, outerEnv, sourceCodeInfo, k) {
|
|
29197
|
+
const evaluatedFunc = fn.evaluatedfunction;
|
|
29198
|
+
const args = evaluatedFunc[0];
|
|
29199
|
+
const closureContext = evaluatedFunc[2];
|
|
29200
|
+
const bindingEnv = outerEnv.create(closureContext).create(context);
|
|
29201
|
+
const rest = params.slice(nbrOfNonRestArgs).map(toAny);
|
|
29462
29202
|
const restArgument = args.find((arg) => arg[0] === bindingTargetTypes.rest);
|
|
29463
|
-
if (restArgument) {
|
|
29464
|
-
|
|
29465
|
-
|
|
29466
|
-
|
|
29467
|
-
|
|
29468
|
-
|
|
29469
|
-
}
|
|
29470
|
-
|
|
29471
|
-
|
|
29203
|
+
if (restArgument) return startBindingSlots(restArgument, rest, bindingEnv, sourceCodeInfo, [{
|
|
29204
|
+
type: "FnRestArgComplete",
|
|
29205
|
+
fn,
|
|
29206
|
+
context,
|
|
29207
|
+
outerEnv,
|
|
29208
|
+
sourceCodeInfo
|
|
29209
|
+
}, ...k]);
|
|
29210
|
+
return proceedToFnBody(fn, context, outerEnv, sourceCodeInfo, k);
|
|
29211
|
+
}
|
|
29212
|
+
/**
|
|
29213
|
+
* Start evaluating function body.
|
|
29214
|
+
*/
|
|
29215
|
+
function proceedToFnBody(fn, context, outerEnv, sourceCodeInfo, k) {
|
|
29216
|
+
const closureContext = fn.evaluatedfunction[2];
|
|
29217
|
+
const bodyEnv = outerEnv.create(closureContext).create(context);
|
|
29218
|
+
const bodyNodes = fn.evaluatedfunction[1];
|
|
29472
29219
|
if (bodyNodes.length === 0) return {
|
|
29473
29220
|
type: "Value",
|
|
29474
29221
|
value: null,
|
|
@@ -29479,15 +29226,9 @@ function setupUserDefinedCall(fn, params, env, sourceCodeInfo, k) {
|
|
|
29479
29226
|
fn,
|
|
29480
29227
|
bodyIndex: 1,
|
|
29481
29228
|
env: bodyEnv,
|
|
29482
|
-
outerEnv
|
|
29229
|
+
outerEnv,
|
|
29483
29230
|
sourceCodeInfo
|
|
29484
29231
|
};
|
|
29485
|
-
if (bodyNodes.length === 1) return {
|
|
29486
|
-
type: "Eval",
|
|
29487
|
-
node: bodyNodes[0],
|
|
29488
|
-
env: bodyEnv,
|
|
29489
|
-
k: [fnBodyFrame, ...k]
|
|
29490
|
-
};
|
|
29491
29232
|
return {
|
|
29492
29233
|
type: "Eval",
|
|
29493
29234
|
node: bodyNodes[0],
|
|
@@ -29511,10 +29252,15 @@ function applyFrame(frame, value, k) {
|
|
|
29511
29252
|
case "ArrayBuild": return applyArrayBuild(frame, value, k);
|
|
29512
29253
|
case "ObjectBuild": return applyObjectBuild(frame, value, k);
|
|
29513
29254
|
case "LetBind": return applyLetBind(frame, value, k);
|
|
29255
|
+
case "LetBindComplete": return applyLetBindComplete(frame, value, k);
|
|
29514
29256
|
case "LoopBind": return applyLoopBind(frame, value, k);
|
|
29257
|
+
case "LoopBindComplete": return applyLoopBindComplete(frame, value, k);
|
|
29515
29258
|
case "LoopIterate": return applyLoopIterate(frame, value, k);
|
|
29516
29259
|
case "ForLoop": return applyForLoop(frame, value, k);
|
|
29260
|
+
case "ForElementBindComplete": return applyForElementBindComplete(frame, value, k);
|
|
29261
|
+
case "ForLetBind": return applyForLetBind(frame, value, k);
|
|
29517
29262
|
case "Recur": return applyRecur(frame, value, k);
|
|
29263
|
+
case "RecurLoopRebind": return applyRecurLoopRebind(frame, value, k);
|
|
29518
29264
|
case "PerformArgs": return applyPerformArgs(frame, value, k);
|
|
29519
29265
|
case "TryWith": return applyTryWith(value, k);
|
|
29520
29266
|
case "EffectResume": return applyEffectResume(frame, value, k);
|
|
@@ -29522,7 +29268,22 @@ function applyFrame(frame, value, k) {
|
|
|
29522
29268
|
case "EvalArgs": return applyEvalArgs(frame, value, k);
|
|
29523
29269
|
case "CallFn": return applyCallFn(frame, value, k);
|
|
29524
29270
|
case "FnBody": return applyFnBody(frame, value, k);
|
|
29525
|
-
case "
|
|
29271
|
+
case "FnArgBind": return applyFnArgBind(frame, value, k);
|
|
29272
|
+
case "FnArgSlotComplete": return applyFnArgSlotComplete(frame, value, k);
|
|
29273
|
+
case "FnRestArgComplete": return applyFnRestArgComplete(frame, value, k);
|
|
29274
|
+
case "BindingSlot": return applyBindingSlot(frame, value, k);
|
|
29275
|
+
case "MatchSlot": return applyMatchSlot(frame, value, k);
|
|
29276
|
+
case "EffectRef": return applyEffectRef(frame, value, k);
|
|
29277
|
+
case "HandlerInvoke": return applyHandlerInvoke(frame, value, k);
|
|
29278
|
+
case "Complement": return {
|
|
29279
|
+
type: "Value",
|
|
29280
|
+
value: !value,
|
|
29281
|
+
k
|
|
29282
|
+
};
|
|
29283
|
+
case "Comp": return applyComp(frame, value, k);
|
|
29284
|
+
case "Juxt": return applyJuxt(frame, value, k);
|
|
29285
|
+
case "EveryPred": return applyEveryPred(frame, value, k);
|
|
29286
|
+
case "SomePred": return applySomePred(frame, value, k);
|
|
29526
29287
|
case "NanCheck": return applyNanCheck(frame, value, k);
|
|
29527
29288
|
case "DebugStep": return applyDebugStep(frame, value, k);
|
|
29528
29289
|
case "ImportMerge": {
|
|
@@ -29658,44 +29419,17 @@ function applyMatch(frame, value, k) {
|
|
|
29658
29419
|
}
|
|
29659
29420
|
/**
|
|
29660
29421
|
* Process match cases starting from `frame.index`.
|
|
29661
|
-
* Uses
|
|
29422
|
+
* Uses frame-based slot processing for pattern matching.
|
|
29662
29423
|
*/
|
|
29663
29424
|
function processMatchCase(frame, k) {
|
|
29664
29425
|
const { matchValue, cases, index, env, sourceCodeInfo } = frame;
|
|
29665
|
-
|
|
29666
|
-
const [pattern, body, guard] = cases[i];
|
|
29667
|
-
const bindings = tryMatch(pattern, matchValue, (n) => evaluateNodeRecursive(n, env));
|
|
29668
|
-
if (bindings instanceof Promise) throw new DvalaError("Async pattern matching not supported in trampoline yet", sourceCodeInfo);
|
|
29669
|
-
if (bindings === null) continue;
|
|
29670
|
-
if (guard) {
|
|
29671
|
-
const context = {};
|
|
29672
|
-
for (const [name, val] of Object.entries(bindings)) context[name] = { value: val };
|
|
29673
|
-
return {
|
|
29674
|
-
type: "Eval",
|
|
29675
|
-
node: guard,
|
|
29676
|
-
env: env.create(context),
|
|
29677
|
-
k: [{
|
|
29678
|
-
...frame,
|
|
29679
|
-
phase: "guard",
|
|
29680
|
-
index: i,
|
|
29681
|
-
bindings
|
|
29682
|
-
}, ...k]
|
|
29683
|
-
};
|
|
29684
|
-
}
|
|
29685
|
-
const context = {};
|
|
29686
|
-
for (const [name, val] of Object.entries(bindings)) context[name] = { value: val };
|
|
29687
|
-
return {
|
|
29688
|
-
type: "Eval",
|
|
29689
|
-
node: body,
|
|
29690
|
-
env: env.create(context),
|
|
29691
|
-
k
|
|
29692
|
-
};
|
|
29693
|
-
}
|
|
29694
|
-
return {
|
|
29426
|
+
if (index >= cases.length) return {
|
|
29695
29427
|
type: "Value",
|
|
29696
29428
|
value: null,
|
|
29697
29429
|
k
|
|
29698
29430
|
};
|
|
29431
|
+
const [pattern] = cases[index];
|
|
29432
|
+
return startMatchSlots(pattern, matchValue, frame, env, sourceCodeInfo, k);
|
|
29699
29433
|
}
|
|
29700
29434
|
function applyAnd(frame, value, k) {
|
|
29701
29435
|
if (!value) return {
|
|
@@ -29892,50 +29626,74 @@ function applyObjectBuild(frame, value, k) {
|
|
|
29892
29626
|
}
|
|
29893
29627
|
function applyLetBind(frame, value, k) {
|
|
29894
29628
|
const { target, env, sourceCodeInfo } = frame;
|
|
29895
|
-
return
|
|
29896
|
-
|
|
29897
|
-
|
|
29898
|
-
|
|
29899
|
-
|
|
29900
|
-
|
|
29901
|
-
|
|
29902
|
-
|
|
29629
|
+
return startBindingSlots(target, value, env, sourceCodeInfo, [{
|
|
29630
|
+
type: "LetBindComplete",
|
|
29631
|
+
originalValue: value,
|
|
29632
|
+
env,
|
|
29633
|
+
sourceCodeInfo
|
|
29634
|
+
}, ...k]);
|
|
29635
|
+
}
|
|
29636
|
+
function applyLetBindComplete(frame, record, k) {
|
|
29637
|
+
const { originalValue, env, sourceCodeInfo } = frame;
|
|
29638
|
+
env.addValues(record, sourceCodeInfo);
|
|
29639
|
+
return {
|
|
29640
|
+
type: "Value",
|
|
29641
|
+
value: originalValue,
|
|
29642
|
+
k
|
|
29643
|
+
};
|
|
29903
29644
|
}
|
|
29904
29645
|
function applyLoopBind(frame, value, k) {
|
|
29905
29646
|
const { bindingNodes, index, context, body, env, sourceCodeInfo } = frame;
|
|
29906
29647
|
const target = bindingNodes[index][1][0];
|
|
29907
|
-
|
|
29908
|
-
|
|
29909
|
-
|
|
29910
|
-
|
|
29911
|
-
|
|
29912
|
-
|
|
29913
|
-
|
|
29914
|
-
|
|
29915
|
-
|
|
29916
|
-
|
|
29917
|
-
|
|
29918
|
-
|
|
29919
|
-
|
|
29920
|
-
|
|
29921
|
-
|
|
29922
|
-
|
|
29923
|
-
|
|
29924
|
-
|
|
29925
|
-
|
|
29926
|
-
};
|
|
29927
|
-
}
|
|
29928
|
-
const newFrame = {
|
|
29929
|
-
...frame,
|
|
29930
|
-
index: nextIndex
|
|
29931
|
-
};
|
|
29648
|
+
const completeFrame = {
|
|
29649
|
+
type: "LoopBindComplete",
|
|
29650
|
+
bindingNodes,
|
|
29651
|
+
index,
|
|
29652
|
+
context,
|
|
29653
|
+
body,
|
|
29654
|
+
env,
|
|
29655
|
+
sourceCodeInfo
|
|
29656
|
+
};
|
|
29657
|
+
return startBindingSlots(target, value, env.create(context), sourceCodeInfo, [completeFrame, ...k]);
|
|
29658
|
+
}
|
|
29659
|
+
function applyLoopBindComplete(frame, record, k) {
|
|
29660
|
+
const { bindingNodes, index, context, body, env, sourceCodeInfo } = frame;
|
|
29661
|
+
Object.entries(record).forEach(([name, val]) => {
|
|
29662
|
+
context[name] = { value: val };
|
|
29663
|
+
});
|
|
29664
|
+
const nextIndex = index + 1;
|
|
29665
|
+
if (nextIndex >= bindingNodes.length) {
|
|
29666
|
+
const loopEnv = env.create(context);
|
|
29932
29667
|
return {
|
|
29933
29668
|
type: "Eval",
|
|
29934
|
-
node:
|
|
29935
|
-
env:
|
|
29936
|
-
k: [
|
|
29669
|
+
node: body,
|
|
29670
|
+
env: loopEnv,
|
|
29671
|
+
k: [{
|
|
29672
|
+
type: "LoopIterate",
|
|
29673
|
+
bindingNodes,
|
|
29674
|
+
bindingContext: context,
|
|
29675
|
+
body,
|
|
29676
|
+
env: loopEnv,
|
|
29677
|
+
sourceCodeInfo
|
|
29678
|
+
}, ...k]
|
|
29937
29679
|
};
|
|
29938
|
-
}
|
|
29680
|
+
}
|
|
29681
|
+
const newFrame = {
|
|
29682
|
+
type: "LoopBind",
|
|
29683
|
+
phase: "value",
|
|
29684
|
+
bindingNodes,
|
|
29685
|
+
index: nextIndex,
|
|
29686
|
+
context,
|
|
29687
|
+
body,
|
|
29688
|
+
env,
|
|
29689
|
+
sourceCodeInfo
|
|
29690
|
+
};
|
|
29691
|
+
return {
|
|
29692
|
+
type: "Eval",
|
|
29693
|
+
node: bindingNodes[nextIndex][1][1],
|
|
29694
|
+
env: env.create(context),
|
|
29695
|
+
k: [newFrame, ...k]
|
|
29696
|
+
};
|
|
29939
29697
|
}
|
|
29940
29698
|
function applyLoopIterate(_frame, value, k) {
|
|
29941
29699
|
return {
|
|
@@ -29945,7 +29703,7 @@ function applyLoopIterate(_frame, value, k) {
|
|
|
29945
29703
|
};
|
|
29946
29704
|
}
|
|
29947
29705
|
function applyForLoop(frame, value, k) {
|
|
29948
|
-
const { returnResult, bindingNodes, result, env, sourceCodeInfo
|
|
29706
|
+
const { returnResult, bindingNodes, result, env, sourceCodeInfo } = frame;
|
|
29949
29707
|
const { asColl, isSeq } = getCollectionUtils();
|
|
29950
29708
|
switch (frame.phase) {
|
|
29951
29709
|
case "evalCollection": {
|
|
@@ -29957,21 +29715,19 @@ function applyForLoop(frame, value, k) {
|
|
|
29957
29715
|
collection: seq,
|
|
29958
29716
|
index: 0
|
|
29959
29717
|
};
|
|
29960
|
-
const
|
|
29961
|
-
const targetNode = binding[0][1][0];
|
|
29718
|
+
const targetNode = bindingNodes[frame.bindingLevel][0][1][0];
|
|
29962
29719
|
const element = seq[0];
|
|
29963
|
-
return
|
|
29964
|
-
|
|
29965
|
-
|
|
29966
|
-
|
|
29967
|
-
|
|
29968
|
-
|
|
29969
|
-
|
|
29970
|
-
|
|
29720
|
+
return startBindingSlots(targetNode, asAny(element, sourceCodeInfo), env, sourceCodeInfo, [{
|
|
29721
|
+
type: "ForElementBindComplete",
|
|
29722
|
+
forFrame: {
|
|
29723
|
+
...frame,
|
|
29724
|
+
levelStates
|
|
29725
|
+
},
|
|
29726
|
+
levelStates,
|
|
29727
|
+
env,
|
|
29728
|
+
sourceCodeInfo
|
|
29729
|
+
}, ...k]);
|
|
29971
29730
|
}
|
|
29972
|
-
case "evalLet":
|
|
29973
|
-
/* v8 ignore next 1 */
|
|
29974
|
-
throw new DvalaError("ForLoop evalLet should not reach applyFrame", sourceCodeInfo);
|
|
29975
29731
|
case "evalWhen": {
|
|
29976
29732
|
if (!value) return advanceForElement(frame, k);
|
|
29977
29733
|
const whileNode = bindingNodes[frame.bindingLevel][3];
|
|
@@ -30002,14 +29758,7 @@ function applyForLoop(frame, value, k) {
|
|
|
30002
29758
|
case "evalBody":
|
|
30003
29759
|
if (returnResult) result.push(value);
|
|
30004
29760
|
return advanceForElement(frame, k);
|
|
30005
|
-
case "evalElement": throw new DvalaError(`Unexpected ForLoop phase: ${frame.phase}`, sourceCodeInfo);
|
|
30006
29761
|
}
|
|
30007
|
-
/* v8 ignore next 1 */
|
|
30008
|
-
return {
|
|
30009
|
-
type: "Value",
|
|
30010
|
-
value: null,
|
|
30011
|
-
k
|
|
30012
|
-
};
|
|
30013
29762
|
}
|
|
30014
29763
|
/** Handle for-loop abort: no more elements at the outermost level. */
|
|
30015
29764
|
function handleForAbort(frame, k) {
|
|
@@ -30021,7 +29770,7 @@ function handleForAbort(frame, k) {
|
|
|
30021
29770
|
}
|
|
30022
29771
|
/** Advance to the next element at the current binding level. */
|
|
30023
29772
|
function advanceForElement(frame, k) {
|
|
30024
|
-
const { bindingNodes, env, sourceCodeInfo
|
|
29773
|
+
const { bindingNodes, env, sourceCodeInfo } = frame;
|
|
30025
29774
|
const levelStates = [...frame.levelStates];
|
|
30026
29775
|
const currentLevel = frame.bindingLevel;
|
|
30027
29776
|
const currentState = levelStates[currentLevel];
|
|
@@ -30037,47 +29786,71 @@ function advanceForElement(frame, k) {
|
|
|
30037
29786
|
...currentState,
|
|
30038
29787
|
index: nextElementIndex
|
|
30039
29788
|
};
|
|
30040
|
-
const
|
|
30041
|
-
const targetNode = binding[0][1][0];
|
|
29789
|
+
const targetNode = bindingNodes[currentLevel][0][1][0];
|
|
30042
29790
|
const element = currentState.collection[nextElementIndex];
|
|
30043
|
-
return
|
|
30044
|
-
|
|
30045
|
-
|
|
30046
|
-
});
|
|
30047
|
-
const letBindings = binding[1];
|
|
30048
|
-
if (letBindings.length > 0) return processForLetBindings({
|
|
29791
|
+
return startBindingSlots(targetNode, asAny(element, sourceCodeInfo), env, sourceCodeInfo, [{
|
|
29792
|
+
type: "ForElementBindComplete",
|
|
29793
|
+
forFrame: {
|
|
30049
29794
|
...frame,
|
|
30050
29795
|
levelStates,
|
|
30051
29796
|
bindingLevel: currentLevel
|
|
30052
|
-
},
|
|
30053
|
-
|
|
30054
|
-
|
|
30055
|
-
|
|
30056
|
-
|
|
30057
|
-
|
|
29797
|
+
},
|
|
29798
|
+
levelStates,
|
|
29799
|
+
env,
|
|
29800
|
+
sourceCodeInfo
|
|
29801
|
+
}, ...k]);
|
|
29802
|
+
}
|
|
29803
|
+
/** Handle completion of for-loop element binding. */
|
|
29804
|
+
function applyForElementBindComplete(frame, record, k) {
|
|
29805
|
+
const { forFrame, levelStates, env, sourceCodeInfo } = frame;
|
|
29806
|
+
Object.entries(record).forEach(([name, val]) => {
|
|
29807
|
+
forFrame.context[name] = { value: val };
|
|
30058
29808
|
});
|
|
29809
|
+
const letBindings = forFrame.bindingNodes[forFrame.bindingLevel][1];
|
|
29810
|
+
if (letBindings.length > 0) return startForLetBindings(forFrame, levelStates, letBindings, 0, env, sourceCodeInfo, k);
|
|
29811
|
+
return processForGuards(forFrame, levelStates, k);
|
|
30059
29812
|
}
|
|
30060
|
-
/**
|
|
30061
|
-
function
|
|
30062
|
-
|
|
30063
|
-
|
|
30064
|
-
|
|
30065
|
-
|
|
30066
|
-
|
|
30067
|
-
|
|
30068
|
-
|
|
30069
|
-
|
|
30070
|
-
|
|
30071
|
-
|
|
30072
|
-
|
|
30073
|
-
|
|
30074
|
-
|
|
30075
|
-
}
|
|
29813
|
+
/** Start processing let-bindings at the current for-loop level. */
|
|
29814
|
+
function startForLetBindings(forFrame, levelStates, letBindings, letIndex, env, sourceCodeInfo, k) {
|
|
29815
|
+
return {
|
|
29816
|
+
type: "Eval",
|
|
29817
|
+
node: letBindings[letIndex][1][1],
|
|
29818
|
+
env,
|
|
29819
|
+
k: [{
|
|
29820
|
+
type: "ForLetBind",
|
|
29821
|
+
phase: "evalValue",
|
|
29822
|
+
forFrame,
|
|
29823
|
+
levelStates,
|
|
29824
|
+
letBindings,
|
|
29825
|
+
letIndex,
|
|
29826
|
+
env,
|
|
29827
|
+
sourceCodeInfo
|
|
29828
|
+
}, ...k]
|
|
29829
|
+
};
|
|
29830
|
+
}
|
|
29831
|
+
/** Handle continuation after evaluating a for-loop let-binding value or destructuring. */
|
|
29832
|
+
function applyForLetBind(frame, value, k) {
|
|
29833
|
+
const { phase, forFrame, levelStates, letBindings, letIndex, env, sourceCodeInfo } = frame;
|
|
29834
|
+
if (phase === "evalValue") {
|
|
29835
|
+
const target = letBindings[letIndex][1][0];
|
|
29836
|
+
return startBindingSlots(target, value, env, sourceCodeInfo, [{
|
|
29837
|
+
type: "ForLetBind",
|
|
29838
|
+
phase: "destructure",
|
|
29839
|
+
forFrame,
|
|
29840
|
+
levelStates,
|
|
29841
|
+
letBindings,
|
|
29842
|
+
letIndex,
|
|
29843
|
+
currentValue: value,
|
|
29844
|
+
env,
|
|
29845
|
+
sourceCodeInfo
|
|
29846
|
+
}, ...k]);
|
|
30076
29847
|
}
|
|
30077
|
-
|
|
30078
|
-
|
|
30079
|
-
|
|
30080
|
-
|
|
29848
|
+
Object.entries(value).forEach(([name, val]) => {
|
|
29849
|
+
forFrame.context[name] = { value: val };
|
|
29850
|
+
});
|
|
29851
|
+
const nextIndex = letIndex + 1;
|
|
29852
|
+
if (nextIndex >= letBindings.length) return processForGuards(forFrame, levelStates, k);
|
|
29853
|
+
return startForLetBindings(forFrame, levelStates, letBindings, nextIndex, env, sourceCodeInfo, k);
|
|
30081
29854
|
}
|
|
30082
29855
|
/** Process when/while guards at the current level. */
|
|
30083
29856
|
function processForGuards(frame, levelStates, k) {
|
|
@@ -30182,8 +29955,7 @@ function applyRecur(frame, value, k) {
|
|
|
30182
29955
|
/**
|
|
30183
29956
|
* Handle recur by searching the continuation stack for the nearest
|
|
30184
29957
|
* LoopIterateFrame or FnBodyFrame, rebinding parameters, and restarting.
|
|
30185
|
-
*
|
|
30186
|
-
* evaluator with proper continuation-based control flow.
|
|
29958
|
+
* Uses frame-based slot binding for proper suspension support.
|
|
30187
29959
|
*/
|
|
30188
29960
|
function handleRecur(params, k, sourceCodeInfo) {
|
|
30189
29961
|
for (let i = 0; i < k.length; i++) {
|
|
@@ -30192,30 +29964,7 @@ function handleRecur(params, k, sourceCodeInfo) {
|
|
|
30192
29964
|
const { bindingNodes, bindingContext, body, env } = frame;
|
|
30193
29965
|
const remainingK = k.slice(i + 1);
|
|
30194
29966
|
if (params.length !== bindingNodes.length) throw new DvalaError(`recur expected ${bindingNodes.length} parameters, got ${params.length}`, sourceCodeInfo);
|
|
30195
|
-
return
|
|
30196
|
-
const target = bindingNode[1][0];
|
|
30197
|
-
return chain(evaluateBindingNodeValues(target, toAny(params[j]), (n) => evaluateNodeRecursive(n, env)), (valueRecord) => {
|
|
30198
|
-
Object.entries(valueRecord).forEach(([name, val]) => {
|
|
30199
|
-
bindingContext[name] = { value: val };
|
|
30200
|
-
});
|
|
30201
|
-
});
|
|
30202
|
-
}), () => {
|
|
30203
|
-
const innermostContext = env.getContextsRaw()[0];
|
|
30204
|
-
if (innermostContext !== bindingContext) for (const [name, entry] of Object.entries(bindingContext)) innermostContext[name] = entry;
|
|
30205
|
-
return {
|
|
30206
|
-
type: "Eval",
|
|
30207
|
-
node: body,
|
|
30208
|
-
env,
|
|
30209
|
-
k: [{
|
|
30210
|
-
type: "LoopIterate",
|
|
30211
|
-
bindingNodes,
|
|
30212
|
-
bindingContext,
|
|
30213
|
-
body,
|
|
30214
|
-
env,
|
|
30215
|
-
sourceCodeInfo: frame.sourceCodeInfo
|
|
30216
|
-
}, ...remainingK]
|
|
30217
|
-
};
|
|
30218
|
-
});
|
|
29967
|
+
return startRecurLoopRebind(bindingNodes, 0, params, bindingContext, body, env, remainingK, sourceCodeInfo);
|
|
30219
29968
|
}
|
|
30220
29969
|
if (frame.type === "FnBody") {
|
|
30221
29970
|
const { fn, outerEnv } = frame;
|
|
@@ -30225,6 +29974,51 @@ function handleRecur(params, k, sourceCodeInfo) {
|
|
|
30225
29974
|
}
|
|
30226
29975
|
throw new DvalaError("recur called outside of loop or function body", sourceCodeInfo);
|
|
30227
29976
|
}
|
|
29977
|
+
/**
|
|
29978
|
+
* Start rebinding loop variables during recur using slot-based binding.
|
|
29979
|
+
*/
|
|
29980
|
+
function startRecurLoopRebind(bindingNodes, bindingIndex, params, bindingContext, body, env, remainingK, sourceCodeInfo) {
|
|
29981
|
+
if (bindingIndex >= bindingNodes.length) {
|
|
29982
|
+
const innermostContext = env.getContextsRaw()[0];
|
|
29983
|
+
if (innermostContext !== bindingContext) for (const [name, entry] of Object.entries(bindingContext)) innermostContext[name] = entry;
|
|
29984
|
+
return {
|
|
29985
|
+
type: "Eval",
|
|
29986
|
+
node: body,
|
|
29987
|
+
env,
|
|
29988
|
+
k: [{
|
|
29989
|
+
type: "LoopIterate",
|
|
29990
|
+
bindingNodes,
|
|
29991
|
+
bindingContext,
|
|
29992
|
+
body,
|
|
29993
|
+
env,
|
|
29994
|
+
sourceCodeInfo
|
|
29995
|
+
}, ...remainingK]
|
|
29996
|
+
};
|
|
29997
|
+
}
|
|
29998
|
+
const target = bindingNodes[bindingIndex][1][0];
|
|
29999
|
+
return startBindingSlots(target, toAny(params[bindingIndex]), env, sourceCodeInfo, [{
|
|
30000
|
+
type: "RecurLoopRebind",
|
|
30001
|
+
bindingNodes,
|
|
30002
|
+
bindingIndex,
|
|
30003
|
+
params,
|
|
30004
|
+
bindingContext,
|
|
30005
|
+
body,
|
|
30006
|
+
env,
|
|
30007
|
+
remainingK,
|
|
30008
|
+
sourceCodeInfo
|
|
30009
|
+
}, ...remainingK]);
|
|
30010
|
+
}
|
|
30011
|
+
/**
|
|
30012
|
+
* Handle completion of one loop binding during recur rebinding.
|
|
30013
|
+
*/
|
|
30014
|
+
function applyRecurLoopRebind(frame, value, _k) {
|
|
30015
|
+
const { bindingNodes, bindingIndex, params, bindingContext, body, env, remainingK, sourceCodeInfo } = frame;
|
|
30016
|
+
const record = value;
|
|
30017
|
+
Object.entries(record).forEach(([name, val]) => {
|
|
30018
|
+
bindingContext[name] = { value: val };
|
|
30019
|
+
});
|
|
30020
|
+
return startRecurLoopRebind(bindingNodes, bindingIndex + 1, params, bindingContext, body, env, remainingK, sourceCodeInfo);
|
|
30021
|
+
}
|
|
30228
30022
|
function applyTryWith(_value, k) {
|
|
30229
30023
|
return {
|
|
30230
30024
|
type: "Value",
|
|
@@ -30262,6 +30056,7 @@ function applyPerformArgs(frame, value, k) {
|
|
|
30262
30056
|
if (index >= argNodes.length) {
|
|
30263
30057
|
const effectRef = params[0];
|
|
30264
30058
|
assertEffect(effectRef, frame.sourceCodeInfo);
|
|
30059
|
+
if (env.pure) throw new DvalaError(`Cannot perform effect '${effectRef.name}' in pure mode`, frame.sourceCodeInfo);
|
|
30265
30060
|
return {
|
|
30266
30061
|
type: "Perform",
|
|
30267
30062
|
effect: effectRef,
|
|
@@ -30312,9 +30107,9 @@ function applyPerformArgs(frame, value, k) {
|
|
|
30312
30107
|
function handlerMatchesEffect(handler, effect, env, sourceCodeInfo) {
|
|
30313
30108
|
if (isEffect(handler.effectRef)) return handler.effectRef.name === effect.name;
|
|
30314
30109
|
if (isDvalaFunction(handler.effectRef)) {
|
|
30315
|
-
const
|
|
30316
|
-
if (
|
|
30317
|
-
return !!
|
|
30110
|
+
const step = dispatchFunction(handler.effectRef, [effect], [], env, sourceCodeInfo, []);
|
|
30111
|
+
if (step instanceof Promise) throw new DvalaError("Effect handler predicates must be synchronous", sourceCodeInfo);
|
|
30112
|
+
return !!runSyncTrampoline(step);
|
|
30318
30113
|
}
|
|
30319
30114
|
return false;
|
|
30320
30115
|
}
|
|
@@ -30325,12 +30120,23 @@ function handlerMatchesEffect(handler, effect, env, sourceCodeInfo) {
|
|
|
30325
30120
|
function invokeMatchedHandler(handler, frame, args, k, frameIndex, sourceCodeInfo) {
|
|
30326
30121
|
const resumeK = k;
|
|
30327
30122
|
const outerK = k.slice(frameIndex + 1);
|
|
30328
|
-
const
|
|
30329
|
-
type: "
|
|
30330
|
-
|
|
30123
|
+
const handlerInvokeFrame = {
|
|
30124
|
+
type: "HandlerInvoke",
|
|
30125
|
+
args,
|
|
30126
|
+
handlerK: [{
|
|
30127
|
+
type: "EffectResume",
|
|
30128
|
+
resumeK,
|
|
30129
|
+
sourceCodeInfo
|
|
30130
|
+
}, ...outerK],
|
|
30131
|
+
handlerEnv: frame.env,
|
|
30331
30132
|
sourceCodeInfo
|
|
30332
|
-
}
|
|
30333
|
-
return
|
|
30133
|
+
};
|
|
30134
|
+
return {
|
|
30135
|
+
type: "Eval",
|
|
30136
|
+
node: handler.handlerNode,
|
|
30137
|
+
env: frame.env,
|
|
30138
|
+
k: [handlerInvokeFrame, ...outerK]
|
|
30139
|
+
};
|
|
30334
30140
|
}
|
|
30335
30141
|
function dispatchPerform(effect, args, k, sourceCodeInfo, handlers, signal, snapshotState) {
|
|
30336
30142
|
const standardDef = getStandardEffectDefinition(effect.name);
|
|
@@ -30338,14 +30144,14 @@ function dispatchPerform(effect, args, k, sourceCodeInfo, handlers, signal, snap
|
|
|
30338
30144
|
if (effect.name === "dvala.checkpoint" && snapshotState) {
|
|
30339
30145
|
const message = args[0];
|
|
30340
30146
|
const meta = args[1];
|
|
30341
|
-
const snapshot = {
|
|
30147
|
+
const snapshot = createSnapshot({
|
|
30342
30148
|
continuation: serializeToObject(k),
|
|
30343
30149
|
timestamp: Date.now(),
|
|
30344
30150
|
index: snapshotState.nextSnapshotIndex++,
|
|
30345
|
-
|
|
30151
|
+
executionId: snapshotState.executionId,
|
|
30346
30152
|
message,
|
|
30347
30153
|
...meta !== void 0 ? { meta } : {}
|
|
30348
|
-
};
|
|
30154
|
+
});
|
|
30349
30155
|
snapshotState.snapshots.push(snapshot);
|
|
30350
30156
|
if (snapshotState.maxSnapshots !== void 0 && snapshotState.snapshots.length > snapshotState.maxSnapshots) snapshotState.snapshots.shift();
|
|
30351
30157
|
}
|
|
@@ -30495,14 +30301,14 @@ function dispatchHostHandler(effectName, matchingHandlers, args, k, signal, sour
|
|
|
30495
30301
|
},
|
|
30496
30302
|
checkpoint: (message, meta) => {
|
|
30497
30303
|
if (!snapshotState) throw new DvalaError("checkpoint is not available outside effect-enabled execution", sourceCodeInfo);
|
|
30498
|
-
const snapshot = {
|
|
30304
|
+
const snapshot = createSnapshot({
|
|
30499
30305
|
continuation: serializeToObject(k),
|
|
30500
30306
|
timestamp: Date.now(),
|
|
30501
30307
|
index: snapshotState.nextSnapshotIndex++,
|
|
30502
|
-
|
|
30308
|
+
executionId: snapshotState.executionId,
|
|
30503
30309
|
message,
|
|
30504
30310
|
...meta !== void 0 ? { meta } : {}
|
|
30505
|
-
};
|
|
30311
|
+
});
|
|
30506
30312
|
snapshotState.snapshots.push(snapshot);
|
|
30507
30313
|
if (snapshotState.maxSnapshots !== void 0 && snapshotState.snapshots.length > snapshotState.maxSnapshots) snapshotState.snapshots.shift();
|
|
30508
30314
|
return snapshot;
|
|
@@ -30510,7 +30316,7 @@ function dispatchHostHandler(effectName, matchingHandlers, args, k, signal, sour
|
|
|
30510
30316
|
resumeFrom: (snapshot, value) => {
|
|
30511
30317
|
if (settled) throw new DvalaError("Effect handler called resumeFrom() after already calling another operation", sourceCodeInfo);
|
|
30512
30318
|
if (!snapshotState) throw new DvalaError("resumeFrom is not available outside effect-enabled execution", sourceCodeInfo);
|
|
30513
|
-
const found = snapshotState.snapshots.find((s) => s.index === snapshot.index && s.
|
|
30319
|
+
const found = snapshotState.snapshots.find((s) => s.index === snapshot.index && s.executionId === snapshot.executionId);
|
|
30514
30320
|
if (!found) throw new DvalaError(`Invalid snapshot: no snapshot with index ${snapshot.index} found in current run`, sourceCodeInfo);
|
|
30515
30321
|
settled = true;
|
|
30516
30322
|
outcome = {
|
|
@@ -30818,16 +30624,492 @@ function applyFnBody(frame, value, k) {
|
|
|
30818
30624
|
k: [newFrame, ...k]
|
|
30819
30625
|
};
|
|
30820
30626
|
}
|
|
30821
|
-
|
|
30822
|
-
|
|
30823
|
-
|
|
30824
|
-
|
|
30825
|
-
|
|
30627
|
+
/**
|
|
30628
|
+
* Handle function argument binding after a default value is evaluated.
|
|
30629
|
+
* Binds the value to the current argument using slots, then continues with remaining args.
|
|
30630
|
+
*/
|
|
30631
|
+
function applyFnArgBind(frame, value, k) {
|
|
30632
|
+
const { fn, params, argIndex, context, outerEnv, sourceCodeInfo } = frame;
|
|
30633
|
+
const evaluatedFunc = fn.evaluatedfunction;
|
|
30634
|
+
const args = evaluatedFunc[0];
|
|
30635
|
+
const nbrOfNonRestArgs = args.filter((arg) => arg[0] !== bindingTargetTypes.rest).length;
|
|
30636
|
+
const arg = args[argIndex];
|
|
30637
|
+
const closureContext = evaluatedFunc[2];
|
|
30638
|
+
return startBindingSlots(arg, value, outerEnv.create(closureContext).create(context), sourceCodeInfo, [{
|
|
30639
|
+
type: "FnArgSlotComplete",
|
|
30640
|
+
fn,
|
|
30641
|
+
params,
|
|
30642
|
+
argIndex,
|
|
30643
|
+
nbrOfNonRestArgs,
|
|
30644
|
+
context,
|
|
30645
|
+
outerEnv,
|
|
30646
|
+
sourceCodeInfo
|
|
30647
|
+
}, ...k]);
|
|
30648
|
+
}
|
|
30649
|
+
/**
|
|
30650
|
+
* Handle completion of slot-based binding for a function argument.
|
|
30651
|
+
* Merges the binding record into context and continues with next arg.
|
|
30652
|
+
*/
|
|
30653
|
+
function applyFnArgSlotComplete(frame, value, k) {
|
|
30654
|
+
const { fn, params, argIndex, nbrOfNonRestArgs, context, outerEnv, sourceCodeInfo } = frame;
|
|
30655
|
+
const record = value;
|
|
30656
|
+
Object.entries(record).forEach(([key, val]) => {
|
|
30657
|
+
context[key] = { value: val };
|
|
30658
|
+
});
|
|
30659
|
+
return continueArgSlotBinding(fn, params, argIndex + 1, nbrOfNonRestArgs, context, outerEnv, sourceCodeInfo, k);
|
|
30660
|
+
}
|
|
30661
|
+
/**
|
|
30662
|
+
* Handle completion of rest argument slot-based binding.
|
|
30663
|
+
* Merges bindings into context and proceeds to body evaluation.
|
|
30664
|
+
*/
|
|
30665
|
+
function applyFnRestArgComplete(frame, value, k) {
|
|
30666
|
+
const { fn, context, outerEnv, sourceCodeInfo } = frame;
|
|
30667
|
+
const record = value;
|
|
30668
|
+
Object.entries(record).forEach(([key, val]) => {
|
|
30669
|
+
context[key] = { value: val };
|
|
30670
|
+
});
|
|
30671
|
+
return proceedToFnBody(fn, context, outerEnv, sourceCodeInfo, k);
|
|
30672
|
+
}
|
|
30673
|
+
/**
|
|
30674
|
+
* Continue binding function arguments starting from argIndex.
|
|
30675
|
+
* Handles only the default evaluation phase - rest handling moved to handleRestArgAndBody.
|
|
30676
|
+
*/
|
|
30677
|
+
function continueBindingArgs(fn, params, argIndex, nbrOfNonRestArgs, context, outerEnv, sourceCodeInfo, k) {
|
|
30678
|
+
const evaluatedFunc = fn.evaluatedfunction;
|
|
30679
|
+
const args = evaluatedFunc[0];
|
|
30680
|
+
const closureContext = evaluatedFunc[2];
|
|
30681
|
+
const bindingEnv = outerEnv.create(closureContext).create(context);
|
|
30682
|
+
for (let i = argIndex; i < nbrOfNonRestArgs; i++) {
|
|
30683
|
+
const defaultNode = args[i][1][1];
|
|
30684
|
+
if (!defaultNode) throw new DvalaError(`Missing required argument ${i}`, sourceCodeInfo);
|
|
30685
|
+
return {
|
|
30686
|
+
type: "Eval",
|
|
30687
|
+
node: defaultNode,
|
|
30688
|
+
env: bindingEnv,
|
|
30689
|
+
k: [{
|
|
30690
|
+
type: "FnArgBind",
|
|
30691
|
+
phase: "default",
|
|
30692
|
+
fn,
|
|
30693
|
+
params,
|
|
30694
|
+
argIndex: i,
|
|
30695
|
+
context,
|
|
30696
|
+
outerEnv,
|
|
30697
|
+
sourceCodeInfo
|
|
30698
|
+
}, ...k]
|
|
30699
|
+
};
|
|
30700
|
+
}
|
|
30701
|
+
return handleRestArgAndBody(fn, params, nbrOfNonRestArgs, context, outerEnv, sourceCodeInfo, k);
|
|
30702
|
+
}
|
|
30703
|
+
/**
|
|
30704
|
+
* Start processing a binding pattern using linearized slots.
|
|
30705
|
+
* This is the entry point for frame-based destructuring.
|
|
30706
|
+
* @internal Exported for testing/incremental migration
|
|
30707
|
+
*/
|
|
30708
|
+
function startBindingSlots(target, rootValue, env, sourceCodeInfo, k) {
|
|
30709
|
+
validateBindingRootType(target, rootValue, sourceCodeInfo);
|
|
30710
|
+
return continueBindingSlots([{
|
|
30711
|
+
slots: flattenBindingPattern(target),
|
|
30712
|
+
index: 0,
|
|
30713
|
+
rootValue
|
|
30714
|
+
}], {}, env, sourceCodeInfo, k);
|
|
30715
|
+
}
|
|
30716
|
+
/**
|
|
30717
|
+
* Continue processing binding slots using the context stack.
|
|
30718
|
+
* Handles extracting values, evaluating defaults, and nested binding targets.
|
|
30719
|
+
*/
|
|
30720
|
+
function continueBindingSlots(contexts, record, env, sourceCodeInfo, k) {
|
|
30721
|
+
while (contexts.length > 0) {
|
|
30722
|
+
const ctx = contexts[contexts.length - 1];
|
|
30723
|
+
if (ctx.index >= ctx.slots.length) {
|
|
30724
|
+
contexts.pop();
|
|
30725
|
+
continue;
|
|
30726
|
+
}
|
|
30727
|
+
const slot = ctx.slots[ctx.index];
|
|
30728
|
+
if (slot.isRest) {
|
|
30729
|
+
if (slot.restKeys !== void 0) {
|
|
30730
|
+
const parentValue = slot.path.length > 0 ? extractValueByPath(ctx.rootValue, slot.path, sourceCodeInfo) ?? null : ctx.rootValue;
|
|
30731
|
+
record[slot.name] = extractObjectRest(parentValue, slot.restKeys, sourceCodeInfo);
|
|
30732
|
+
} else if (slot.restIndex !== void 0) {
|
|
30733
|
+
const parentValue = slot.path.length > 0 ? extractValueByPath(ctx.rootValue, slot.path, sourceCodeInfo) ?? null : ctx.rootValue;
|
|
30734
|
+
record[slot.name] = extractArrayRest(parentValue, slot.restIndex, sourceCodeInfo);
|
|
30735
|
+
} else {
|
|
30736
|
+
const value = slot.path.length > 0 ? extractValueByPath(ctx.rootValue, slot.path, sourceCodeInfo) ?? null : ctx.rootValue;
|
|
30737
|
+
record[slot.name] = value;
|
|
30738
|
+
}
|
|
30739
|
+
ctx.index++;
|
|
30740
|
+
continue;
|
|
30741
|
+
}
|
|
30742
|
+
const value = extractValueByPath(ctx.rootValue, slot.path, sourceCodeInfo);
|
|
30743
|
+
if (value === void 0 && slot.defaultNode) {
|
|
30744
|
+
const frame = {
|
|
30745
|
+
type: "BindingSlot",
|
|
30746
|
+
contexts: contexts.map((c) => ({ ...c })),
|
|
30747
|
+
record,
|
|
30748
|
+
env,
|
|
30749
|
+
sourceCodeInfo
|
|
30750
|
+
};
|
|
30751
|
+
return {
|
|
30752
|
+
type: "Eval",
|
|
30753
|
+
node: slot.defaultNode,
|
|
30754
|
+
env,
|
|
30755
|
+
k: [frame, ...k]
|
|
30756
|
+
};
|
|
30757
|
+
}
|
|
30758
|
+
const resolvedValue = value ?? null;
|
|
30759
|
+
if (slot.nestedTarget) {
|
|
30760
|
+
const nestedSlots = flattenBindingPatternWithoutDefault(slot.nestedTarget);
|
|
30761
|
+
validateBindingRootType(slot.nestedTarget, resolvedValue, slot.sourceCodeInfo);
|
|
30762
|
+
contexts.push({
|
|
30763
|
+
slots: nestedSlots,
|
|
30764
|
+
index: 0,
|
|
30765
|
+
rootValue: resolvedValue
|
|
30766
|
+
});
|
|
30767
|
+
ctx.index++;
|
|
30768
|
+
continue;
|
|
30769
|
+
}
|
|
30770
|
+
record[slot.name] = resolvedValue;
|
|
30771
|
+
ctx.index++;
|
|
30772
|
+
}
|
|
30826
30773
|
return {
|
|
30827
30774
|
type: "Value",
|
|
30828
|
-
value,
|
|
30775
|
+
value: record,
|
|
30776
|
+
k
|
|
30777
|
+
};
|
|
30778
|
+
}
|
|
30779
|
+
/**
|
|
30780
|
+
* Flatten a binding pattern without using its top-level default.
|
|
30781
|
+
* Used when we've already resolved the default and need to process the nested structure.
|
|
30782
|
+
*/
|
|
30783
|
+
function flattenBindingPatternWithoutDefault(target) {
|
|
30784
|
+
return flattenBindingPattern([
|
|
30785
|
+
target[0],
|
|
30786
|
+
[target[1][0], void 0],
|
|
30787
|
+
target[2]
|
|
30788
|
+
]);
|
|
30789
|
+
}
|
|
30790
|
+
/**
|
|
30791
|
+
* Handle continuation after evaluating a binding slot's default value.
|
|
30792
|
+
*/
|
|
30793
|
+
function applyBindingSlot(frame, value, k) {
|
|
30794
|
+
const { contexts, record, env, sourceCodeInfo } = frame;
|
|
30795
|
+
const ctx = contexts[contexts.length - 1];
|
|
30796
|
+
const slot = ctx.slots[ctx.index];
|
|
30797
|
+
const resolvedValue = value ?? null;
|
|
30798
|
+
if (slot.nestedTarget) {
|
|
30799
|
+
const nestedSlots = flattenBindingPatternWithoutDefault(slot.nestedTarget);
|
|
30800
|
+
validateBindingRootType(slot.nestedTarget, resolvedValue, slot.sourceCodeInfo);
|
|
30801
|
+
contexts.push({
|
|
30802
|
+
slots: nestedSlots,
|
|
30803
|
+
index: 0,
|
|
30804
|
+
rootValue: resolvedValue
|
|
30805
|
+
});
|
|
30806
|
+
ctx.index++;
|
|
30807
|
+
} else {
|
|
30808
|
+
record[slot.name] = resolvedValue;
|
|
30809
|
+
ctx.index++;
|
|
30810
|
+
}
|
|
30811
|
+
return continueBindingSlots(contexts, record, env, sourceCodeInfo, k);
|
|
30812
|
+
}
|
|
30813
|
+
/**
|
|
30814
|
+
* Start pattern matching with slot-based processing.
|
|
30815
|
+
* Returns Step to continue matching, or moves to next case on failure.
|
|
30816
|
+
*/
|
|
30817
|
+
function startMatchSlots(pattern, matchValue, matchFrame, env, sourceCodeInfo, k) {
|
|
30818
|
+
if (!checkObjectTypeConstraint(pattern, matchValue)) return tryNextMatchCase(matchFrame, k);
|
|
30819
|
+
if (!checkArrayLengthConstraint(pattern, matchValue)) return tryNextMatchCase(matchFrame, k);
|
|
30820
|
+
const slots = flattenMatchPattern(pattern);
|
|
30821
|
+
if (slots.length === 0) return matchSucceeded({}, matchFrame, k);
|
|
30822
|
+
return continueMatchSlots([{
|
|
30823
|
+
slots,
|
|
30824
|
+
index: 0,
|
|
30825
|
+
rootValue: matchValue
|
|
30826
|
+
}], {}, matchFrame, env, sourceCodeInfo, k);
|
|
30827
|
+
}
|
|
30828
|
+
/**
|
|
30829
|
+
* Continue processing match slots.
|
|
30830
|
+
* Returns Step for next action (eval, success, or try next case).
|
|
30831
|
+
*/
|
|
30832
|
+
function continueMatchSlots(contexts, record, matchFrame, env, sourceCodeInfo, k) {
|
|
30833
|
+
while (contexts.length > 0) {
|
|
30834
|
+
const ctx = contexts[contexts.length - 1];
|
|
30835
|
+
if (ctx.index >= ctx.slots.length) {
|
|
30836
|
+
contexts.pop();
|
|
30837
|
+
continue;
|
|
30838
|
+
}
|
|
30839
|
+
const slot = ctx.slots[ctx.index];
|
|
30840
|
+
switch (slot.kind) {
|
|
30841
|
+
case "wildcard":
|
|
30842
|
+
ctx.index++;
|
|
30843
|
+
continue;
|
|
30844
|
+
case "typeCheck":
|
|
30845
|
+
if (!slot.requiredType || !checkTypeAtPath(ctx.rootValue, slot.path, slot.requiredType)) return tryNextMatchCase(matchFrame, k);
|
|
30846
|
+
ctx.index++;
|
|
30847
|
+
continue;
|
|
30848
|
+
case "literal": {
|
|
30849
|
+
const frame = {
|
|
30850
|
+
type: "MatchSlot",
|
|
30851
|
+
contexts: contexts.map((c) => ({ ...c })),
|
|
30852
|
+
record: { ...record },
|
|
30853
|
+
matchFrame,
|
|
30854
|
+
phase: "literal",
|
|
30855
|
+
currentSlot: slot,
|
|
30856
|
+
env,
|
|
30857
|
+
sourceCodeInfo
|
|
30858
|
+
};
|
|
30859
|
+
return {
|
|
30860
|
+
type: "Eval",
|
|
30861
|
+
node: slot.literalNode,
|
|
30862
|
+
env,
|
|
30863
|
+
k: [frame, ...k]
|
|
30864
|
+
};
|
|
30865
|
+
}
|
|
30866
|
+
case "rest":
|
|
30867
|
+
if (slot.restKeys !== void 0) record[slot.name] = extractMatchObjectRest(ctx.rootValue, slot.path, slot.restKeys);
|
|
30868
|
+
else if (slot.restIndex !== void 0) record[slot.name] = extractMatchArrayRest(ctx.rootValue, slot.path, slot.restIndex);
|
|
30869
|
+
else {
|
|
30870
|
+
const value = slot.path.length > 0 ? extractMatchValueByPath(ctx.rootValue, slot.path) ?? null : ctx.rootValue;
|
|
30871
|
+
record[slot.name] = value;
|
|
30872
|
+
}
|
|
30873
|
+
ctx.index++;
|
|
30874
|
+
continue;
|
|
30875
|
+
case "bind": {
|
|
30876
|
+
const value = extractMatchValueByPath(ctx.rootValue, slot.path);
|
|
30877
|
+
if (value === void 0 || value === null) {
|
|
30878
|
+
if (slot.defaultNode) {
|
|
30879
|
+
const frame = {
|
|
30880
|
+
type: "MatchSlot",
|
|
30881
|
+
contexts: contexts.map((c) => ({ ...c })),
|
|
30882
|
+
record: { ...record },
|
|
30883
|
+
matchFrame,
|
|
30884
|
+
phase: "default",
|
|
30885
|
+
currentSlot: slot,
|
|
30886
|
+
env,
|
|
30887
|
+
sourceCodeInfo
|
|
30888
|
+
};
|
|
30889
|
+
return {
|
|
30890
|
+
type: "Eval",
|
|
30891
|
+
node: slot.defaultNode,
|
|
30892
|
+
env,
|
|
30893
|
+
k: [frame, ...k]
|
|
30894
|
+
};
|
|
30895
|
+
}
|
|
30896
|
+
record[slot.name] = value ?? null;
|
|
30897
|
+
} else record[slot.name] = value;
|
|
30898
|
+
ctx.index++;
|
|
30899
|
+
continue;
|
|
30900
|
+
}
|
|
30901
|
+
}
|
|
30902
|
+
}
|
|
30903
|
+
return matchSucceeded(record, matchFrame, k);
|
|
30904
|
+
}
|
|
30905
|
+
/**
|
|
30906
|
+
* Handle continuation after evaluating a match slot value.
|
|
30907
|
+
*/
|
|
30908
|
+
function applyMatchSlot(frame, value, k) {
|
|
30909
|
+
const { contexts, record, matchFrame, phase, currentSlot, env, sourceCodeInfo } = frame;
|
|
30910
|
+
const ctx = contexts[contexts.length - 1];
|
|
30911
|
+
if (phase === "literal") {
|
|
30912
|
+
if (!deepEqual$1(extractMatchValueByPath(ctx.rootValue, currentSlot.path), value)) return tryNextMatchCase(matchFrame, k);
|
|
30913
|
+
ctx.index++;
|
|
30914
|
+
} else {
|
|
30915
|
+
record[currentSlot.name] = value ?? null;
|
|
30916
|
+
ctx.index++;
|
|
30917
|
+
}
|
|
30918
|
+
return continueMatchSlots(contexts, record, matchFrame, env, sourceCodeInfo, k);
|
|
30919
|
+
}
|
|
30920
|
+
/**
|
|
30921
|
+
* Pattern matching succeeded — proceed to guard or body.
|
|
30922
|
+
*/
|
|
30923
|
+
function matchSucceeded(bindings, matchFrame, k) {
|
|
30924
|
+
const { cases, index, env } = matchFrame;
|
|
30925
|
+
const [, body, guard] = cases[index];
|
|
30926
|
+
const context = {};
|
|
30927
|
+
for (const [name, val] of Object.entries(bindings)) context[name] = { value: val };
|
|
30928
|
+
if (guard) return {
|
|
30929
|
+
type: "Eval",
|
|
30930
|
+
node: guard,
|
|
30931
|
+
env: env.create(context),
|
|
30932
|
+
k: [{
|
|
30933
|
+
...matchFrame,
|
|
30934
|
+
phase: "guard",
|
|
30935
|
+
bindings
|
|
30936
|
+
}, ...k]
|
|
30937
|
+
};
|
|
30938
|
+
return {
|
|
30939
|
+
type: "Eval",
|
|
30940
|
+
node: body,
|
|
30941
|
+
env: env.create(context),
|
|
30942
|
+
k
|
|
30943
|
+
};
|
|
30944
|
+
}
|
|
30945
|
+
/**
|
|
30946
|
+
* Current pattern didn't match — try next case.
|
|
30947
|
+
*/
|
|
30948
|
+
function tryNextMatchCase(matchFrame, k) {
|
|
30949
|
+
return processMatchCase({
|
|
30950
|
+
...matchFrame,
|
|
30951
|
+
index: matchFrame.index + 1
|
|
30952
|
+
}, k);
|
|
30953
|
+
}
|
|
30954
|
+
/**
|
|
30955
|
+
* Handles continuation after evaluating an effect reference expression.
|
|
30956
|
+
* Stores the evaluated ref, then either evaluates the next ref or starts the body.
|
|
30957
|
+
*/
|
|
30958
|
+
function applyEffectRef(frame, value, k) {
|
|
30959
|
+
const { handlerNodes, evaluatedHandlers, index, bodyNodes, bodyEnv, env, sourceCodeInfo } = frame;
|
|
30960
|
+
const currentHandler = handlerNodes[index];
|
|
30961
|
+
evaluatedHandlers.push({
|
|
30962
|
+
effectRef: value,
|
|
30963
|
+
handlerNode: currentHandler[1]
|
|
30964
|
+
});
|
|
30965
|
+
const nextIndex = index + 1;
|
|
30966
|
+
if (nextIndex < handlerNodes.length) {
|
|
30967
|
+
const nextFrame = {
|
|
30968
|
+
type: "EffectRef",
|
|
30969
|
+
handlerNodes,
|
|
30970
|
+
evaluatedHandlers,
|
|
30971
|
+
index: nextIndex,
|
|
30972
|
+
bodyNodes,
|
|
30973
|
+
bodyEnv,
|
|
30974
|
+
env,
|
|
30975
|
+
sourceCodeInfo
|
|
30976
|
+
};
|
|
30977
|
+
return {
|
|
30978
|
+
type: "Eval",
|
|
30979
|
+
node: handlerNodes[nextIndex][0],
|
|
30980
|
+
env,
|
|
30981
|
+
k: [nextFrame, ...k]
|
|
30982
|
+
};
|
|
30983
|
+
}
|
|
30984
|
+
const bodyK = [{
|
|
30985
|
+
type: "TryWith",
|
|
30986
|
+
handlers: evaluatedHandlers,
|
|
30987
|
+
env,
|
|
30988
|
+
sourceCodeInfo
|
|
30989
|
+
}, ...k];
|
|
30990
|
+
if (bodyNodes.length === 0) return {
|
|
30991
|
+
type: "Value",
|
|
30992
|
+
value: null,
|
|
30993
|
+
k: bodyK
|
|
30994
|
+
};
|
|
30995
|
+
if (bodyNodes.length === 1) return {
|
|
30996
|
+
type: "Eval",
|
|
30997
|
+
node: bodyNodes[0],
|
|
30998
|
+
env: bodyEnv,
|
|
30999
|
+
k: bodyK
|
|
31000
|
+
};
|
|
31001
|
+
const sequenceFrame = {
|
|
31002
|
+
type: "Sequence",
|
|
31003
|
+
nodes: bodyNodes,
|
|
31004
|
+
index: 1,
|
|
31005
|
+
env: bodyEnv,
|
|
31006
|
+
sourceCodeInfo
|
|
31007
|
+
};
|
|
31008
|
+
return {
|
|
31009
|
+
type: "Eval",
|
|
31010
|
+
node: bodyNodes[0],
|
|
31011
|
+
env: bodyEnv,
|
|
31012
|
+
k: [sequenceFrame, ...bodyK]
|
|
31013
|
+
};
|
|
31014
|
+
}
|
|
31015
|
+
/**
|
|
31016
|
+
* Handler expression has been evaluated — dispatch the handler function.
|
|
31017
|
+
*/
|
|
31018
|
+
function applyHandlerInvoke(frame, value, _k) {
|
|
31019
|
+
return dispatchFunction(asFunctionLike(value, frame.sourceCodeInfo), [frame.args], [], frame.handlerEnv, frame.sourceCodeInfo, frame.handlerK);
|
|
31020
|
+
}
|
|
31021
|
+
/**
|
|
31022
|
+
* Comp iteration — chain to the next function in the composition.
|
|
31023
|
+
* Result from previous function is wrapped in array and passed to next.
|
|
31024
|
+
*/
|
|
31025
|
+
function applyComp(frame, value, k) {
|
|
31026
|
+
const { fns, index, env, sourceCodeInfo } = frame;
|
|
31027
|
+
const nextParams = [value];
|
|
31028
|
+
if (index < 0) return {
|
|
31029
|
+
type: "Value",
|
|
31030
|
+
value: asAny(value, sourceCodeInfo),
|
|
31031
|
+
k
|
|
31032
|
+
};
|
|
31033
|
+
const nextFrame = {
|
|
31034
|
+
type: "Comp",
|
|
31035
|
+
fns,
|
|
31036
|
+
index: index - 1,
|
|
31037
|
+
env,
|
|
31038
|
+
sourceCodeInfo
|
|
31039
|
+
};
|
|
31040
|
+
return dispatchFunction(asFunctionLike(fns[index], sourceCodeInfo), nextParams, [], env, sourceCodeInfo, [nextFrame, ...k]);
|
|
31041
|
+
}
|
|
31042
|
+
/**
|
|
31043
|
+
* Juxt iteration — collect result and call next function.
|
|
31044
|
+
*/
|
|
31045
|
+
function applyJuxt(frame, value, k) {
|
|
31046
|
+
const { fns, params, index, results, env, sourceCodeInfo } = frame;
|
|
31047
|
+
const newResults = [...results, value];
|
|
31048
|
+
if (index >= fns.length) return {
|
|
31049
|
+
type: "Value",
|
|
31050
|
+
value: newResults,
|
|
31051
|
+
k
|
|
31052
|
+
};
|
|
31053
|
+
const nextFrame = {
|
|
31054
|
+
type: "Juxt",
|
|
31055
|
+
fns,
|
|
31056
|
+
params,
|
|
31057
|
+
index: index + 1,
|
|
31058
|
+
results: newResults,
|
|
31059
|
+
env,
|
|
31060
|
+
sourceCodeInfo
|
|
31061
|
+
};
|
|
31062
|
+
return dispatchFunction(asFunctionLike(fns[index], sourceCodeInfo), params, [], env, sourceCodeInfo, [nextFrame, ...k]);
|
|
31063
|
+
}
|
|
31064
|
+
/**
|
|
31065
|
+
* EveryPred iteration — short-circuit on falsy, continue on truthy.
|
|
31066
|
+
*/
|
|
31067
|
+
function applyEveryPred(frame, value, k) {
|
|
31068
|
+
const { checks, index, env, sourceCodeInfo } = frame;
|
|
31069
|
+
if (!value) return {
|
|
31070
|
+
type: "Value",
|
|
31071
|
+
value: false,
|
|
31072
|
+
k
|
|
31073
|
+
};
|
|
31074
|
+
if (index >= checks.length) return {
|
|
31075
|
+
type: "Value",
|
|
31076
|
+
value: true,
|
|
30829
31077
|
k
|
|
30830
31078
|
};
|
|
31079
|
+
const nextFrame = {
|
|
31080
|
+
type: "EveryPred",
|
|
31081
|
+
checks,
|
|
31082
|
+
index: index + 1,
|
|
31083
|
+
env,
|
|
31084
|
+
sourceCodeInfo
|
|
31085
|
+
};
|
|
31086
|
+
const check = checks[index];
|
|
31087
|
+
return dispatchFunction(check.fn, [check.param], [], env, sourceCodeInfo, [nextFrame, ...k]);
|
|
31088
|
+
}
|
|
31089
|
+
/**
|
|
31090
|
+
* SomePred iteration — short-circuit on truthy, continue on falsy.
|
|
31091
|
+
*/
|
|
31092
|
+
function applySomePred(frame, value, k) {
|
|
31093
|
+
const { checks, index, env, sourceCodeInfo } = frame;
|
|
31094
|
+
if (value) return {
|
|
31095
|
+
type: "Value",
|
|
31096
|
+
value: true,
|
|
31097
|
+
k
|
|
31098
|
+
};
|
|
31099
|
+
if (index >= checks.length) return {
|
|
31100
|
+
type: "Value",
|
|
31101
|
+
value: false,
|
|
31102
|
+
k
|
|
31103
|
+
};
|
|
31104
|
+
const nextFrame = {
|
|
31105
|
+
type: "SomePred",
|
|
31106
|
+
checks,
|
|
31107
|
+
index: index + 1,
|
|
31108
|
+
env,
|
|
31109
|
+
sourceCodeInfo
|
|
31110
|
+
};
|
|
31111
|
+
const check = checks[index];
|
|
31112
|
+
return dispatchFunction(check.fn, [check.param], [], env, sourceCodeInfo, [nextFrame, ...k]);
|
|
30831
31113
|
}
|
|
30832
31114
|
function applyNanCheck(frame, value, k) {
|
|
30833
31115
|
if (typeof value === "number" && Number.isNaN(value)) throw new DvalaError("Number is NaN", frame.sourceCodeInfo);
|
|
@@ -30996,7 +31278,7 @@ function tick(step, handlers, signal, snapshotState) {
|
|
|
30996
31278
|
function runSyncTrampoline(initial, effectHandlers) {
|
|
30997
31279
|
let step = initial;
|
|
30998
31280
|
for (;;) {
|
|
30999
|
-
if (step instanceof Promise) throw new DvalaError("Unexpected async operation in synchronous context.
|
|
31281
|
+
if (step instanceof Promise) throw new DvalaError("Unexpected async operation in synchronous context.", void 0);
|
|
31000
31282
|
if (step.type === "Value" && step.k.length === 0) return step.value;
|
|
31001
31283
|
step = tick(step, effectHandlers);
|
|
31002
31284
|
}
|
|
@@ -31056,30 +31338,6 @@ function evaluate(ast, contextStack) {
|
|
|
31056
31338
|
}
|
|
31057
31339
|
}
|
|
31058
31340
|
/**
|
|
31059
|
-
* Evaluate a single AST node using the trampoline.
|
|
31060
|
-
* Used as the `evaluateNode` callback passed to `getUndefinedSymbols`
|
|
31061
|
-
* and other utilities.
|
|
31062
|
-
*/
|
|
31063
|
-
function evaluateNode(node, contextStack) {
|
|
31064
|
-
const initial = {
|
|
31065
|
-
type: "Eval",
|
|
31066
|
-
node,
|
|
31067
|
-
env: contextStack,
|
|
31068
|
-
k: []
|
|
31069
|
-
};
|
|
31070
|
-
try {
|
|
31071
|
-
return runSyncTrampoline(initial);
|
|
31072
|
-
} catch (error) {
|
|
31073
|
-
if (error instanceof DvalaError && error.message.includes("Unexpected async operation")) return runAsyncTrampoline({
|
|
31074
|
-
type: "Eval",
|
|
31075
|
-
node,
|
|
31076
|
-
env: contextStack,
|
|
31077
|
-
k: []
|
|
31078
|
-
});
|
|
31079
|
-
throw error;
|
|
31080
|
-
}
|
|
31081
|
-
}
|
|
31082
|
-
/**
|
|
31083
31341
|
* Evaluate an AST with full effect handler support.
|
|
31084
31342
|
*
|
|
31085
31343
|
* Uses the async trampoline loop, passing `handlers` and `signal` to `tick`
|
|
@@ -31130,18 +31388,42 @@ async function runEffectLoop(initial, handlers, signal, initialSnapshotState, ma
|
|
|
31130
31388
|
const snapshotState = {
|
|
31131
31389
|
snapshots: initialSnapshotState ? initialSnapshotState.snapshots : [],
|
|
31132
31390
|
nextSnapshotIndex: initialSnapshotState ? initialSnapshotState.nextSnapshotIndex : 0,
|
|
31133
|
-
|
|
31391
|
+
executionId: generateUUID(),
|
|
31134
31392
|
...maxSnapshots !== void 0 ? { maxSnapshots } : {},
|
|
31135
31393
|
...autoCheckpoint ? { autoCheckpoint } : {}
|
|
31136
31394
|
};
|
|
31137
31395
|
let step = initial;
|
|
31396
|
+
function createTerminalSnapshot(options) {
|
|
31397
|
+
if (!snapshotState.autoCheckpoint) return;
|
|
31398
|
+
const continuation = serializeTerminalSnapshot(snapshotState.snapshots, snapshotState.nextSnapshotIndex);
|
|
31399
|
+
const meta = {};
|
|
31400
|
+
if (options?.error) meta.error = options.error.toJSON();
|
|
31401
|
+
if (options?.result !== void 0) meta.result = options.result;
|
|
31402
|
+
const message = options?.error ? "Run failed with error" : "Run completed successfully";
|
|
31403
|
+
return createSnapshot({
|
|
31404
|
+
continuation,
|
|
31405
|
+
timestamp: Date.now(),
|
|
31406
|
+
index: snapshotState.nextSnapshotIndex,
|
|
31407
|
+
executionId: snapshotState.executionId,
|
|
31408
|
+
message,
|
|
31409
|
+
terminal: true,
|
|
31410
|
+
...Object.keys(meta).length > 0 ? { meta } : {}
|
|
31411
|
+
});
|
|
31412
|
+
}
|
|
31138
31413
|
for (;;) try {
|
|
31139
31414
|
for (;;) {
|
|
31140
31415
|
if (step instanceof Promise) step = await step;
|
|
31141
|
-
if (step.type === "Value" && step.k.length === 0)
|
|
31142
|
-
|
|
31143
|
-
|
|
31144
|
-
|
|
31416
|
+
if (step.type === "Value" && step.k.length === 0) {
|
|
31417
|
+
const snapshot = createTerminalSnapshot({ result: step.value });
|
|
31418
|
+
return snapshot ? {
|
|
31419
|
+
type: "completed",
|
|
31420
|
+
value: step.value,
|
|
31421
|
+
snapshot
|
|
31422
|
+
} : {
|
|
31423
|
+
type: "completed",
|
|
31424
|
+
value: step.value
|
|
31425
|
+
};
|
|
31426
|
+
}
|
|
31145
31427
|
if (debugMode && step.type === "Eval" && step.node[2]) {
|
|
31146
31428
|
const nodeType = step.node[0];
|
|
31147
31429
|
if (nodeType === NodeTypes.NormalExpression || nodeType === NodeTypes.SpecialExpression) {
|
|
@@ -31173,24 +31455,37 @@ async function runEffectLoop(initial, handlers, signal, initialSnapshotState, ma
|
|
|
31173
31455
|
}
|
|
31174
31456
|
if (isSuspensionSignal(error)) return {
|
|
31175
31457
|
type: "suspended",
|
|
31176
|
-
snapshot: {
|
|
31458
|
+
snapshot: createSnapshot({
|
|
31177
31459
|
continuation: serializeSuspensionBlob(error.k, error.snapshots, error.nextSnapshotIndex, error.meta),
|
|
31178
31460
|
timestamp: Date.now(),
|
|
31179
31461
|
index: snapshotState.nextSnapshotIndex++,
|
|
31180
|
-
|
|
31462
|
+
executionId: snapshotState.executionId,
|
|
31181
31463
|
message: SUSPENDED_MESSAGE,
|
|
31182
31464
|
meta: error.meta,
|
|
31183
31465
|
effectName: error.effectName,
|
|
31184
31466
|
effectArgs: error.effectArgs
|
|
31185
|
-
}
|
|
31467
|
+
})
|
|
31186
31468
|
};
|
|
31187
|
-
if (error instanceof DvalaError)
|
|
31469
|
+
if (error instanceof DvalaError) {
|
|
31470
|
+
const snapshot = createTerminalSnapshot({ error });
|
|
31471
|
+
return snapshot ? {
|
|
31472
|
+
type: "error",
|
|
31473
|
+
error,
|
|
31474
|
+
snapshot
|
|
31475
|
+
} : {
|
|
31476
|
+
type: "error",
|
|
31477
|
+
error
|
|
31478
|
+
};
|
|
31479
|
+
}
|
|
31480
|
+
const snapshot = createTerminalSnapshot();
|
|
31481
|
+
const dvalaError = new DvalaError(`${error}`, void 0);
|
|
31482
|
+
return snapshot ? {
|
|
31188
31483
|
type: "error",
|
|
31189
|
-
error
|
|
31190
|
-
|
|
31191
|
-
|
|
31484
|
+
error: dvalaError,
|
|
31485
|
+
snapshot
|
|
31486
|
+
} : {
|
|
31192
31487
|
type: "error",
|
|
31193
|
-
error:
|
|
31488
|
+
error: dvalaError
|
|
31194
31489
|
};
|
|
31195
31490
|
}
|
|
31196
31491
|
}
|
|
@@ -31298,7 +31593,7 @@ function getUndefinedSymbols(source, options) {
|
|
|
31298
31593
|
return getUndefinedSymbols$1({
|
|
31299
31594
|
body: parse(minifyTokenStream(tokenize(source, false, void 0), { removeWhiteSpace: true })),
|
|
31300
31595
|
hasDebugData: false
|
|
31301
|
-
}, contextStack, builtin
|
|
31596
|
+
}, contextStack, builtin);
|
|
31302
31597
|
}
|
|
31303
31598
|
//#endregion
|
|
31304
31599
|
//#region src/createDvala.ts
|
|
@@ -31331,6 +31626,7 @@ function createDvala(options) {
|
|
|
31331
31626
|
const modules = options?.modules ? new Map(options.modules.map((m) => [m.name, m])) : void 0;
|
|
31332
31627
|
const factoryBindings = options?.bindings;
|
|
31333
31628
|
const factoryEffectHandlers = options?.effectHandlers;
|
|
31629
|
+
const factoryDisableTimeTravel = options?.disableAutoCheckpoint ?? false;
|
|
31334
31630
|
const debug = options?.debug ?? false;
|
|
31335
31631
|
const cache = options?.cache ? new Cache(options.cache) : null;
|
|
31336
31632
|
function buildAst(source, filePath) {
|
|
@@ -31406,10 +31702,12 @@ function createDvala(options) {
|
|
|
31406
31702
|
}
|
|
31407
31703
|
contextStack.pure = savedPure;
|
|
31408
31704
|
}
|
|
31409
|
-
const
|
|
31705
|
+
const ast = buildAst(isDvalaBundle(source) ? source.program : source);
|
|
31706
|
+
const disableAutoCheckpoint = runOptions?.disableAutoCheckpoint ?? factoryDisableTimeTravel;
|
|
31707
|
+
const result = await evaluateWithEffects(ast, contextStack, effectHandlers, runOptions?.maxSnapshots, {
|
|
31410
31708
|
values: bindings,
|
|
31411
31709
|
modules
|
|
31412
|
-
},
|
|
31710
|
+
}, !disableAutoCheckpoint);
|
|
31413
31711
|
if (result.type === "completed") return {
|
|
31414
31712
|
...result,
|
|
31415
31713
|
definedBindings: contextStack.getModuleScopeBindings()
|