visitForLoopStmt method

  1. @override
Object? visitForLoopStmt(
  1. ForLoopStmt forLoopStmt
)
override

Implementation

@override
Object? visitForLoopStmt(ForLoopStmt forLoopStmt) {
  pushScope();
  Object? control = forLoopStmt.control.accept(this);

  evalVar(Object? v) {
    if (v is LuaObject && v.valueAsInt() is int) {
      final String id = v.id;
      return (id, v.valueAsInt()!);
    } else {
      final String lineInfo = this.lineInfo(forLoopStmt.token);
      popScope();
      throw '$lineInfo For-loop control did not evaluate to a variable!';
    }
  }

  evalNum(Object? n, String label) {
    if (n == null) {
      return 1;
    } else if (n is LuaObject && n.valueAsInt() is int) {
      return n.valueAsInt();
    } else if (n is num) {
      return n;
    }

    // n is not num
    popScope();
    throw '$lineInfo For-loop $label did not evaluate to an integer value!';
  }

  final String controlId;
  num ncontrol;
  (controlId, ncontrol) = evalVar(control);

  final num end = evalNum(forLoopStmt.endExpr.accept(this), 'end')!;
  final num step = evalNum(forLoopStmt.stepExpr.accept(this), 'step')!;
  final ctrl = defLocal(LuaObject.variable(controlId, ncontrol));

  while (ncontrol <= end) {
    for (Stmt stmt in forLoopStmt.body) {
      try {
        stmt.accept(this);
      } catch (e) {
        addError(e.toString());
      }
    }
    ncontrol += step;
    ctrl.value = ncontrol;
  }

  popScope();
  return null;
}