import { Evaluate } from '../evaluator.mts'; import { Completion, EnsureCompletion, NormalCompletion, Q, UpdateEmpty, } from '../completion.mts'; import { Value } from '../value.mts'; import type { ParseNode } from '../parser/ParseNode.mts'; import { GetValue, ToBoolean, } from '#self'; /** https://tc39.es/ecma262/#sec-if-statement-runtime-semantics-evaluation */ // IfStatement : // `if` `(` Expression `)` Statement `else` Statement // `if` `(` Expression `)` Statement export function* Evaluate_IfStatement({ Expression, Statement_a, Statement_b }: ParseNode.IfStatement) { // 1. Let exprRef be the result of evaluating Expression. const exprRef = Q(yield* Evaluate(Expression)); // 2. Let exprValue be ! ToBoolean(? GetValue(exprRef)). const exprValue = ToBoolean(Q(yield* GetValue(exprRef))); if (Statement_b) { let stmtCompletion; // 3. If exprValue is true, then if (exprValue === Value.true) { // a. Let stmtCompletion be the result of evaluating the first Statement. stmtCompletion = yield* Evaluate(Statement_a); } else { // 4. Else, // a. Let stmtCompletion be the result of evaluating the second Statement. stmtCompletion = yield* Evaluate(Statement_b); } // 5. Return Completion(UpdateEmpty(stmtCompletion, undefined)). return Completion(UpdateEmpty(EnsureCompletion(stmtCompletion), Value.undefined)); } else { // 3. If exprValue is false, then if (exprValue === Value.false) { // a. Return NormalCompletion(undefined). return NormalCompletion(Value.undefined); } else { // 4. Else, // a. Let stmtCompletion be the result of evaluating Statement. const stmtCompletion = yield* Evaluate(Statement_a); // b. Return Completion(UpdateEmpty(stmtCompletion, undefined)). return Completion(UpdateEmpty(EnsureCompletion(stmtCompletion), Value.undefined)); } } }