private Stmt ForStatement() { Consume(TokenType.LEFT_PAREN, "Expect '(' after 'for'."); Stmt initializer; if (Match(TokenType.SEMICOLON)) { initializer = null; } else if (Match(TokenType.VAR)) { initializer = VarDeclaration(); } else { initializer = ExpressionStatement(); } Expr condition = null; if (!Check(TokenType.SEMICOLON)) { condition = Expression(); } Consume(TokenType.SEMICOLON, "Expect ';' after loop condition."); Expr increment = null; if (!Check(TokenType.RIGHT_PAREN)) { increment = Expression(); } Consume(TokenType.RIGHT_PAREN, "Expect ')' after for clauses."); // This is the for loop body provided by the user Stmt forLoopBody = Statement(); //////////////// The for loop is rewritten as a while loop. /////////// //Copy for loop body into a list of while loop statements List <Stmt> whileLoopStatements = new List <Stmt> { forLoopBody }; //If an increment was given, append it to the list of while loop statements if (increment != null) { whileLoopStatements.Add(new Stmt.Expression(increment)); } //Form the while loop, without the initializer //Condition is forced to "true" if the for loop had no condition expression Stmt whileLoop = new Stmt.While( condition ?? new Expr.Literal(true), new Stmt.Block(whileLoopStatements) ); //If no initializer given, just return the while loop. //Otherwise, insert the initializer just above the while loop return(initializer == null ? whileLoop : new Stmt.Block(new List <Stmt> { initializer, whileLoop, })); }
public MyVoid VisitWhileStmt(Stmt.While stmt) { resolve(stmt.condition); resolve(stmt.body); return(null); }