changeset 155:2149f4a7b48d

Codegen for statements
author Anders Halager <halager@gmail.com>
date Mon, 21 Jul 2008 22:12:33 +0200
parents 0ea5d2f3e96b
children bb01c1dc452a
files gen/CodeGen.d
diffstat 1 files changed, 50 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- 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.