@@ -221,6 +221,8 @@ class Evaluation {
221
221
* @param {Set<any> } values
222
222
*/
223
223
constructor ( scope , expression , values ) {
224
+ current_evaluations . set ( expression , this ) ;
225
+
224
226
this . values = values ;
225
227
226
228
switch ( expression . type ) {
@@ -543,6 +545,8 @@ class Evaluation {
543
545
if ( this . values . size > 1 || typeof this . value === 'symbol' ) {
544
546
this . is_known = false ;
545
547
}
548
+
549
+ current_evaluations . delete ( expression ) ;
546
550
}
547
551
}
548
552
@@ -734,10 +738,20 @@ export class Scope {
734
738
* @param {Set<any> } [values]
735
739
*/
736
740
evaluate ( expression , values = new Set ( ) ) {
741
+ const current = current_evaluations . get ( expression ) ;
742
+ if ( current ) return current ;
743
+
737
744
return new Evaluation ( this , expression , values ) ;
738
745
}
739
746
}
740
747
748
+ /**
749
+ * Track which expressions are currently being evaluated — this allows
750
+ * us to prevent cyclical evaluations without passing the map around
751
+ * @type {Map<Expression | FunctionDeclaration, Evaluation> }
752
+ */
753
+ const current_evaluations = new Map ( ) ;
754
+
741
755
/** @type {Record<BinaryOperator, (left: any, right: any) => any> } */
742
756
const binary = {
743
757
'!=' : ( left , right ) => left != right ,
0 commit comments