patchIfBlock method

void patchIfBlock(
  1. bool singleLineIf
)

Patches up all the branches for a single open if block. That includes the last "else" block, as well as one or more "end if" jumps.

Implementation

void patchIfBlock(bool singleLineIf) {
  ValNumber target = ValNumber(code.length.toDouble());

  int idx = backpatches.length - 1;
  while (idx >= 0) {
    BackPatch bp = backpatches[idx];
    if (bp.waitingFor == "if:MARK") {
      // There's the special marker that indicates the true start of this if block.
      backpatches.removeAt(idx);
      return;
    } else if (bp.waitingFor == "end if" || bp.waitingFor == "else") {
      code[bp.lineNum].rhsA = target;
      backpatches.removeAt(idx);
    } else if (backpatches[idx].waitingFor == "break") {
      // Not the expected keyword, but "break"; this is always OK.
    } else {
      // Not the expected patch, and not "break"; we have a mismatched block start/end.
      String msg;
      if (singleLineIf) {
        if (bp.waitingFor == "end for" || bp.waitingFor == "end while") {
          msg = "loop is invalid within single-line 'if'";
        } else {
          msg = "invalid control structure within single-line 'if'";
        }
      } else {
        msg = "'end if' without matching 'if'";
      }
      throw CompilerException(msg);
    }
    idx--;
  }
  // If we get here, we never found the expected if:MARK.  That's an error.
  throw CompilerException("'end if' without matching 'if'");
}