# HG changeset patch # User Anders Halager # Date 1216671153 -7200 # Node ID 2149f4a7b48db9f7a4398bf172b7ce1bd0ff12f0 # Parent 0ea5d2f3e96b04dd6d5f8c445a59c1f7b8dd107a Codegen for statements diff -r 0ea5d2f3e96b -r 2149f4a7b48d gen/CodeGen.d --- a/gen/CodeGen.d Mon Jul 21 21:45:54 2008 +0200 +++ b/gen/CodeGen.d Mon Jul 21 22:12:33 2008 +0200 @@ -510,29 +510,19 @@ break; case StmtType.While: auto wStmt = cast(WhileStmt)stmt; - auto fd = stmt.env.parentFunction(); - Function func = m.getNamedFunction(symbolName(fd)); - - auto condBB = func.appendBasicBlock("cond"); - auto bodyBB = func.appendBasicBlock("body"); - auto doneBB = func.appendBasicBlock("done"); - - b.buildBr(condBB); - b.positionAtEnd(condBB); - Value cond = genExpression(wStmt.cond).value; - if (cond.type !is Type.Int1) - { - Value False = ConstantInt.GetS(cond.type, 0); - cond = b.buildICmp(IntPredicate.NE, cond, False, ".cond"); - } - b.buildCondBr(cond, bodyBB, doneBB); - - b.positionAtEnd(bodyBB); - genStmt(wStmt.whileBody); - if (b.getInsertBlock().terminated() is false) - b.buildBr(condBB); - - b.positionAtEnd(doneBB); + genLoop(stmt.env, wStmt.cond, false, wStmt.whileBody); + break; + /+ + case StmtType.DoWhile: + auto wStmt = cast(DoWhileStmt)stmt; + genLoop(stmt.env, wStmt.cond, true, wStmt.whileBody); + break; + +/ + case StmtType.For: + auto fStmt = cast(ForStmt)stmt; + genStmt(fStmt.init); + scope inc = new ExpStmt(fStmt.incre); + genLoop(stmt.env, fStmt.cond, false, fStmt.forBody, inc); break; case StmtType.Switch: auto sw = cast(SwitchStmt)stmt; @@ -587,6 +577,43 @@ } } + /** + Generate a loop. + + Loops while cond is true, executing all statements in stmts every time. + + If skipFirstCond is set, the condition is skipped the first time around, + like in a do-while loop. + **/ + void genLoop(Scope env, Exp cond, bool skipFirstCond, Stmt[] stmts...) + { + auto fd = env.parentFunction(); + Function func = m.getNamedFunction(symbolName(fd)); + + auto condBB = func.appendBasicBlock("cond"); + auto bodyBB = func.appendBasicBlock("body"); + auto doneBB = func.appendBasicBlock("done"); + + b.buildBr(skipFirstCond? bodyBB : condBB); + b.positionAtEnd(condBB); + + Value cond_v = genExpression(cond).value; + if (cond_v.type !is Type.Int1) + { + Value False = ConstantInt.GetS(cond_v.type, 0); + cond_v = b.buildICmp(IntPredicate.NE, cond_v, False, ".cond"); + } + b.buildCondBr(cond_v, bodyBB, doneBB); + + b.positionAtEnd(bodyBB); + foreach (stmt; stmts) + genStmt(stmt); + if (b.getInsertBlock().terminated() is false) + b.buildBr(condBB); + + b.positionAtEnd(doneBB); + } + /* Get the address of an expression - allowing us to modify something in memory or on the stack.