visitForLoopStmt method
Implementation
@override
Object? visitForLoopStmt(ForLoopStmt forLoopStmt) {
final prevScope = scope;
pushScope();
try {
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);
throw '$lineInfo For-loop control did not evaluate to a variable!';
}
}
evalNum(LuaObject? n, String label) {
if (n == null) {
return 1;
} else if (n.valueAs<num>() != null) {
return n.valueAs<num>();
}
// n is not num
throw '$lineInfo For-loop $label did not evaluate to a number!';
}
final String controlId;
num ncontrol;
(controlId, ncontrol) = evalVar(control);
final num end = evalNum(forLoopStmt.endExpr.accept(this)?.unpack(), 'end')!;
final num step = evalNum(forLoopStmt.stepExpr.accept(this)?.unpack(), 'step')!;
while (ncontrol <= end) {
defLocal(LuaObject.variable(controlId, ncontrol));
for (int i = 0; i < forLoopStmt.body.length; i++) {
final stmt = forLoopStmt.body[i];
try {
stmt.accept(this);
} on LuaBreakStmtException {
break;
} on LuaReturnValueException {
rethrow;
} catch (e) {
addError(e.toString());
}
}
ncontrol += step;
}
} catch (e) {
rethrow;
} finally {
restoreScope(prevScope);
}
return null;
}