visitIfStatement method
Visit a SIfStatement.
Implementation
@override
Object? visitIfStatement(SIfStatement node) {
// Evaluate the expression
final expressionValue = node.condition!.accept<Object?>(this);
// If the evaluation returns an AsyncSuspensionRequest, return it immediately
if (expressionValue is AsyncSuspensionRequest) {
Logger.debug(
"[SIfStatement] Expression suspended (AsyncSuspensionRequest). Propagating.",
);
return expressionValue;
}
// Check if this is an if-case statement (pattern matching)
final caseClause = node.caseClause;
if (caseClause != null) {
// This is an if-case statement: if (expr case Pattern when guard) { ... }
final cc = caseClause;
final gp = cc.guardedPattern;
final pattern = gp.pattern;
final guard = gp.whenClause?.expression;
// Create a temporary environment for pattern variable bindings
final caseEnvironment = Environment(enclosing: environment);
try {
// Attempt to match the pattern against the expression value
_matchAndBind(pattern, expressionValue, caseEnvironment);
Logger.debug(
"[SIfStatement] Pattern ${pattern.runtimeType} matched value ${expressionValue?.runtimeType}",
);
// Pattern matched, now check the guard (if it exists)
bool guardPassed = true;
if (guard != null) {
final previousVisitorEnv = environment;
try {
environment = caseEnvironment; // Evaluate guard in case scope
final guardResult = guard.accept<Object?>(this);
if (guardResult is! bool) {
throw RuntimeD4rtException(
"If-case 'when' clause must evaluate to a boolean.",
);
}
guardPassed = guardResult;
Logger.debug("[SIfStatement] Guard evaluated to: $guardPassed");
} finally {
environment = previousVisitorEnv;
}
}
// If pattern matched and guard passed, execute thenStatement
if (guardPassed) {
final previousVisitorEnv = environment;
try {
environment = caseEnvironment; // Execute body in case scope
node.thenStatement!.accept<Object?>(this);
} finally {
environment = previousVisitorEnv;
}
} else if (node.elseStatement != null) {
// Guard failed, execute elseStatement
node.elseStatement!.accept<Object?>(this);
}
} on PatternMatchD4rtException {
// Pattern didn't match, execute elseStatement if present
Logger.debug(
"[SIfStatement] Pattern ${pattern.runtimeType} did not match. Executing else if present.",
);
if (node.elseStatement != null) {
node.elseStatement!.accept<Object?>(this);
}
}
return null;
}
// Regular boolean condition if statement
bool conditionResult;
final bridgedInstance = toBridgedInstance(expressionValue);
if (expressionValue is bool) {
conditionResult = expressionValue;
} else if (bridgedInstance.$2 && bridgedInstance.$1?.nativeObject is bool) {
conditionResult = bridgedInstance.$1!.nativeObject as bool;
} else {
throw RuntimeD4rtException(
"The condition of an 'if' must be a boolean, but was ${expressionValue?.runtimeType}.",
);
}
if (conditionResult) {
node.thenStatement!.accept<Object?>(this);
} else if (node.elseStatement != null) {
node.elseStatement!.accept<Object?>(this);
}
return null; // The If instruction normally ends with null
}