import { Value } from '../value.mts'; import { Evaluate, type ValueEvaluator } from '../evaluator.mts'; import { Q, X } from '../completion.mts'; import type { ParseNode } from '../parser/ParseNode.mts'; import { ToBoolean, GetValue } from '#self'; /** https://tc39.es/ecma262/#sec-conditional-operator-runtime-semantics-evaluation */ // ConditionalExpression : // ShortCircuitExpression `?` AssignmentExpression `:` AssignmentExpression export function* Evaluate_ConditionalExpression({ ShortCircuitExpression, AssignmentExpression_a, AssignmentExpression_b, }: ParseNode.ConditionalExpression): ValueEvaluator { // 1. Let lref be the result of evaluating ShortCircuitExpression. const lref = Q(yield* Evaluate(ShortCircuitExpression)); // 2. Let lval be ! ToBoolean(? GetValue(lref)). const lval = X(ToBoolean(Q(yield* GetValue(lref)))); // 3. If lval is true, then if (lval === Value.true) { // a. Let trueRef be the result of evaluating the first AssignmentExpression. const trueRef = Q(yield* Evaluate(AssignmentExpression_a)); // b. Return ? GetValue(trueRef). return Q(yield* GetValue(trueRef)); } else { // 4. Else, // a. Let falseRef be the result of evaluating the second AssignmentExpression. const falseRef = Q(yield* Evaluate(AssignmentExpression_b)); // b. Return ? GetValue(falseRef). return Q(yield* GetValue(falseRef)); } }