handle cycles

pull/15792/head
Rich Harris 4 months ago
parent 29eec3fc33
commit ffc4769571

@ -221,6 +221,8 @@ class Evaluation {
* @param {Set<any>} values * @param {Set<any>} values
*/ */
constructor(scope, expression, values) { constructor(scope, expression, values) {
current_evaluations.set(expression, this);
this.values = values; this.values = values;
switch (expression.type) { switch (expression.type) {
@ -543,6 +545,8 @@ class Evaluation {
if (this.values.size > 1 || typeof this.value === 'symbol') { if (this.values.size > 1 || typeof this.value === 'symbol') {
this.is_known = false; this.is_known = false;
} }
current_evaluations.delete(expression);
} }
} }
@ -734,10 +738,20 @@ export class Scope {
* @param {Set<any>} [values] * @param {Set<any>} [values]
*/ */
evaluate(expression, values = new Set()) { evaluate(expression, values = new Set()) {
const current = current_evaluations.get(expression);
if (current) return current;
return new Evaluation(this, expression, values); return new Evaluation(this, expression, values);
} }
} }
/**
* Track which expressions are currently being evaluated this allows
* us to prevent cyclical evaluations without passing the map around
* @type {Map<Expression | FunctionDeclaration, Evaluation>}
*/
const current_evaluations = new Map();
/** @type {Record<BinaryOperator, (left: any, right: any) => any>} */ /** @type {Record<BinaryOperator, (left: any, right: any) => any>} */
const binary = { const binary = {
'!=': (left, right) => left != right, '!=': (left, right) => left != right,

Loading…
Cancel
Save