public override AstNode Visit(ForStatement node) { // Begin the node. builder.BeginNode(node); // Get the for elements. AstNode decl = node.GetDecls(); AstNode cond = node.GetCondition(); AstNode incr = node.GetIncr(); // Write the declaration. if(decl != null) decl.Accept(this); // Create the basics blocks. BasicBlock forStart = CreateBasicBlock(); BasicBlock forEnd = CreateBasicBlock(); BasicBlock forBreak = CreateBasicBlock(); BasicBlock forCond = forStart; // Set the blocks names. forStart.SetName("for_start"); forEnd.SetName("for_end"); forBreak.SetName("for_break"); // Store and update the break and continue points. BasicBlock oldBreak = currentBreak; BasicBlock oldContinue = currentContinue; currentBreak = forBreak; currentContinue = forEnd; // Write the condition. if(cond != null) { // Create the condition block. forCond = CreateBasicBlock(); forCond.SetName("for_cond"); // Jump into the condition. builder.CreateJmp(forCond); builder.SetBlock(forCond); // Write the condition. cond.Accept(this); // Cast the condition. IChelaType condType = cond.GetNodeType(); if(condType != ChelaType.GetBoolType()) Cast(node, cond.GetNodeValue(), condType, ChelaType.GetBoolType()); // Perform the conditional branch. builder.CreateBr(forStart, forBreak); } else { // Jump into the beginning of the loop. builder.CreateJmp(forStart); } // Write the loop content. builder.SetBlock(forStart); VisitList(node.GetChildren()); // Branch into the loop end. if(!builder.IsLastTerminator()) builder.CreateJmp(forEnd); // Write the for end. builder.SetBlock(forEnd); // Write the increment. if(incr != null) incr.Accept(this); // Branch into the condition. if(!builder.IsLastTerminator()) builder.CreateJmp(forCond); // Continue with the rest of the program. builder.SetBlock(forBreak); // Restore the break and continue point. currentBreak = oldBreak; currentContinue = oldContinue; return builder.EndNode(); }
public override AstNode Visit(ForStatement node) { // Create the for lexical scope. LexicalScope scope = CreateLexicalScope(node); node.SetScope(scope); // Enter into the for scope. PushScope(scope); // Get the for elements. AstNode decl = node.GetDecls(); AstNode cond = node.GetCondition(); AstNode incr = node.GetIncr(); // Visit his elements. if(decl != null) decl.Accept(this); // Check the condition. if(cond != null) { cond.Accept(this); // Check the condition type. IChelaType condType = cond.GetNodeType(); if(condType != ChelaType.GetBoolType() && Coerce(condType, ChelaType.GetBoolType()) != ChelaType.GetBoolType()) Error(node, "condition must be a boolean expression."); } // Visit the "increment". if(incr != null) incr.Accept(this); // Visit his children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); return node; }