private void ExecuteForStmt(Ast.ForStmt stmt, ScriptEnv env) { var firstNumber = EvaluateExpr <long>(stmt.FirstNumberExpr, env); var lastNumber = EvaluateExpr <long>(stmt.LastNumberExpr, env); long step = firstNumber <= lastNumber ? 1 : -1; if (stmt.StepExpr != null) { step = EvaluateExpr <long>(stmt.StepExpr, env); } if (step == 0) { throw new ScriptException("The STEP value in a FOR statement must not be zero."); } else if (step < 0 && firstNumber < lastNumber) { throw new ScriptException( "The STEP value in a FOR statement must be positive if \"first-number\" < \"last-number\"."); } else if (step > 0 && firstNumber > lastNumber) { throw new ScriptException( "The STEP value in a FOR statement must be negative if \"first-number\" > \"last-number\"."); } var upward = step > 0; long counter = firstNumber; while ((upward && counter <= lastNumber) || (!upward && counter >= lastNumber)) { env.Vars[stmt.VariableName] = counter; ExecuteBlock(stmt.Block, env); if (env.DidReturn || env.DidThrow) { return; } else if (env.DidBreak) { env.DidBreak = false; break; } else if (env.DidContinue) { env.DidContinue = false; } counter += step; } }
private Ast.Stmt ParseForStmt(TokenQueue q) { var stmt = new Ast.ForStmt { SourceToken = q.SourceToken }; q.Take("for"); stmt.VariableName = ParseVariableName(q); q.Take("="); stmt.FirstNumberExpr = ParseExpr(q); q.Take("to"); stmt.LastNumberExpr = ParseExpr(q); if (q.TakeMaybe("step")) { stmt.StepExpr = ParseExpr(q); } stmt.Block = ParseBlock(q); ConsumeSemicolon(q); return(stmt); }