visitDoStatement method

  1. @override
Object? visitDoStatement(
  1. SDoStatement node
)
override

Visit a SDoStatement.

Implementation

@override
Object? visitDoStatement(SDoStatement node) {
  do {
    try {
      // Execute the body first
      node.body!.accept<Object?>(this);
    } on BreakException catch (e) {
      Logger.debug(
        "[DoWhile] Caught BreakException (label: ${e.label}) with current labels: $_currentStatementLabels",
      );
      if (e.label == null || _currentStatementLabels.contains(e.label)) {
        Logger.debug("[DoWhile] Breaking loop.");
        break; // Exit the do-while loop
      } else {
        Logger.debug("[DoWhile] Rethrowing outer break...");
        rethrow;
      }
    } on ContinueException catch (e) {
      Logger.debug(
        "[DoWhile] Caught ContinueException (label: ${e.label}) with current labels: $_currentStatementLabels",
      );
      if (e.label == null || _currentStatementLabels.contains(e.label)) {
        Logger.debug("[DoWhile] Continuing loop condition check.");
        // For do-while, continue still needs to check the condition
        // So we fall through to the condition check below
      } else {
        Logger.debug("[DoWhile] Rethrowing outer continue...");
        rethrow;
      }
    }

    // Then evaluate the condition
    // Handle condition being BridgedInstance<bool>
    final conditionValue = node.condition!.accept<Object?>(this);
    Logger.debug("[DoWhile] Condition value: $conditionValue");
    bool conditionResult;
    final bridgedInstance = toBridgedInstance(conditionValue);
    Logger.debug("[DoWhile] Bridged instance: $bridgedInstance");
    if (conditionValue is bool) {
      conditionResult = conditionValue;
    } else if (bridgedInstance.$2 &&
        bridgedInstance.$1?.nativeObject is bool) {
      conditionResult = bridgedInstance.$1!.nativeObject as bool;
    } else {
      throw RuntimeD4rtException(
        "The condition of a 'do-while' loop must be a boolean, but was ${conditionValue?.runtimeType}.",
      );
    }

    if (!conditionResult) {
      break;
    }
  } while (true);

  return null;
}