changeset 45:9bc660cbdbec new_gen

If statements are back Also fixed a bug in the codegen preventing return in the else branch, now it is optional. Also found an issue with the way we are generating our llvm from ifs - it doesn't mean anything but the code looks ugly. if (cond_1) if (cond_2) statement; return 0; Becomes: br cond_1, then, merge then: br cond_2 then2, merge2 merge: ret 0 then2: statements merge2: br merge This is because we use appendBasicBlock on the function
author Anders Halager <halager@gmail.com>
date Wed, 23 Apr 2008 16:43:42 +0200
parents 495188f9078e
children 90fb4fdfefdd
files ast/Stmt.d gen/LLVMGen.d parser/Action.d parser/Parser.d sema/SymbolTableBuilder.d sema/Visitor.d
diffstat 6 files changed, 73 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/ast/Stmt.d	Wed Apr 23 00:57:45 2008 +0200
+++ b/ast/Stmt.d	Wed Apr 23 16:43:42 2008 +0200
@@ -77,7 +77,7 @@
 
 class IfStmt : Stmt
 {
-    this(Exp cond, Stmt[] then, Stmt[] el = null)
+    this(Exp cond, Stmt then, Stmt el = null)
     {
         super(StmtType.If);
         this.cond = cond;
@@ -86,8 +86,8 @@
     }
 
     Exp cond;
-    Stmt[] then_body;
-    Stmt[] else_body;
+    Stmt then_body;
+    Stmt else_body;
 }
 
 class WhileStmt : Stmt
--- a/gen/LLVMGen.d	Wed Apr 23 00:57:45 2008 +0200
+++ b/gen/LLVMGen.d	Wed Apr 23 16:43:42 2008 +0200
@@ -338,7 +338,7 @@
                 }
                 auto func_name = stmt.env.parentFunction().id.get;
                 Function func = m.getNamedFunction(func_name);
-                bool has_else = ifStmt.else_body.length > 0;
+                bool has_else = (ifStmt.else_body !is null);
 
                 auto thenBB = func.appendBasicBlock("then");
                 auto elseBB = has_else? func.appendBasicBlock("else") : null;
@@ -346,8 +346,7 @@
 
                 b.buildCondBr(cond, thenBB, has_else? elseBB : mergeBB);
                 b.positionAtEnd(thenBB);
-                foreach (s; ifStmt.then_body)
-                    genStmt(s);
+                genStmt(ifStmt.then_body);
                 if (b.getInsertBlock().terminated() is false)
                     b.buildBr(mergeBB);
                 thenBB = b.getInsertBlock();
@@ -355,9 +354,9 @@
                 if (has_else)
                 {
                     b.positionAtEnd(elseBB);
-                    foreach (s; ifStmt.else_body)
-                        genStmt(s);
-                    b.buildBr(mergeBB);
+                    genStmt(ifStmt.else_body);
+                    if (elseBB.terminated() is false)
+                        b.buildBr(mergeBB);
                     elseBB = b.getInsertBlock();
                 }
 
--- a/parser/Action.d	Wed Apr 23 00:57:45 2008 +0200
+++ b/parser/Action.d	Wed Apr 23 16:43:42 2008 +0200
@@ -130,6 +130,14 @@
         return null;
     }
 
+    /**
+     */
+    StmtT actOnIfStmt(ref Token ifTok, ExprT cond, StmtT thenBody,
+                      ref Token elseTok, StmtT elseBody)
+    {
+        return null;
+    }
+
     StmtT actOnStartOfSwitchStmt()
     {
         return null;
@@ -200,6 +208,7 @@
  */
 class AstAction : Action
 {
+    // -- Declarations --
     override DeclT actOnDeclarator(ref Id type, ref Id id, ExprT init)
     {
         Exp exp = cast(Exp)init;
@@ -224,11 +233,11 @@
         return fd;
     }
 
+    // -- Statements --
     override StmtT actOnCompoundStmt(ref Token l, ref Token r, StmtT[] stmts)
     {
         StmtT[] array = stmts.dup;
         Stmt[] statements = cast(Stmt[])array;
-        Stdout(statements).newline;
         return new CompoundStatement(cast(Stmt[])array);
     }
 
@@ -240,6 +249,16 @@
         return res;
     }
 
+    override StmtT actOnIfStmt(ref Token ifTok, ExprT cond, StmtT thenBody,
+                               ref Token elseTok, StmtT elseBody)
+    {
+        Exp c = cast(Exp)cond;
+        Stmt t = cast(Stmt)thenBody;
+        Stmt e = cast(Stmt)elseBody;
+        return new IfStmt(c, t, e);
+    }
+
+    // -- Expressions --
     override ExprT actOnNumericConstant(Token c)
     {
         return new IntegerLit(c);
--- a/parser/Parser.d	Wed Apr 23 00:57:45 2008 +0200
+++ b/parser/Parser.d	Wed Apr 23 16:43:42 2008 +0200
@@ -86,8 +86,32 @@
                 require(Tok.Seperator);
                 return action.actOnReturnStmt(ret, exp);
 
+            /*
+               if (cond)
+                single statement | compound statement
+               [else
+                single statement | compound statement]
+             */
             case Tok.If:
-                return null;
+                Token _if = lexer.next();
+
+                require(Tok.OpenParentheses);
+                Exp cond = parseExpression();
+                require(Tok.CloseParentheses);
+
+                Stmt thenB = parseSingleOrCompoundStatement();
+
+                // if there is no else part we use the if as token, to have
+                // something than can be passed along
+                Token _else = _if;
+                Stmt elseB;
+                if (lexer.peek.type == Tok.Else)
+                {
+                    _else = lexer.next;
+                    elseB = parseSingleOrCompoundStatement();
+                }
+
+                return action.actOnIfStmt(_if, cond, thenB, _else, elseB);
 
             case Tok.While:
                 return null;
@@ -142,6 +166,16 @@
     }
 
     /**
+      Parse either a block, or a single statement as allowed after if, while
+      and for.
+     */
+    Stmt parseSingleOrCompoundStatement()
+    {
+        if (lexer.peek.type == Tok.OpenBrace)
+            return parseCompoundStatement();
+        return parseStatement();
+    }
+    /**
       Parses a function-body or similar, expects { to be current token.
       
       Will consume both the starting { and ending }
--- a/sema/SymbolTableBuilder.d	Wed Apr 23 00:57:45 2008 +0200
+++ b/sema/SymbolTableBuilder.d	Wed Apr 23 16:43:42 2008 +0200
@@ -115,14 +115,15 @@
         s.env = current();
         visitExp(s.cond);
         auto sc = push();
-        foreach (stmt; s.then_body)
-            visitStmt(stmt);
+        visitStmt(s.then_body);
         pop(sc);
 
-        sc = push();
-        foreach (stmt; s.else_body)
-            visitStmt(stmt);
-        pop(sc);
+        if (s.else_body !is null)
+        {
+            sc = push();
+            visitStmt(s.else_body);
+            pop(sc);
+        }
     }
 
     override void visitWhileStmt(WhileStmt s)
--- a/sema/Visitor.d	Wed Apr 23 00:57:45 2008 +0200
+++ b/sema/Visitor.d	Wed Apr 23 16:43:42 2008 +0200
@@ -158,10 +158,9 @@
     StmtT visitIfStmt(IfStmt s)
     {
         visitExp(s.cond);
-        foreach (stmt; s.then_body)
-            visitStmt(stmt);
-        foreach (stmt; s.else_body)
-            visitStmt(stmt);
+        visitStmt(s.then_body);
+        if (s.else_body !is null)
+            visitStmt(s.else_body);
         static if (is(StmtT == void))
             return;
         else