changeset 143:d76cc5cad4fc

Added partial support for switches. Added support for extern(C) in CodeGen.
author Anders Johnsen <skabet@gmail.com>
date Mon, 21 Jul 2008 01:05:20 +0200
parents 1e48315c36fc
children 6e6355fb5f0f
files ast/Stmt.d basic/Attribute.d gen/CodeGen.d parser/Action.d parser/Parser.d sema/AstAction.d sema/Visitor.d
diffstat 7 files changed, 128 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/ast/Stmt.d	Sun Jul 20 23:41:53 2008 +0200
+++ b/ast/Stmt.d	Mon Jul 21 01:05:20 2008 +0200
@@ -175,16 +175,17 @@
         cond = target;
     }
 
-    void addCase(IntegerLit[] values, Stmt[] stmts)
+    void addCase(Exp[] values, Stmt[] stmts)
     {
-        long[] new_values;
-        foreach (lit; values)
-            new_values ~= Integer.parse(lit.get);
-        cases ~= Case(values, stmts, new_values);
+//        long[] new_values;
+//        foreach (lit; values)
+//            new_values ~= Integer.parse(lit.get);
+//        cases ~= Case(values, stmts, new_values);
+        cases ~= Case(values, stmts);
 
         // Make sure there is no two cases with the same value
         // Does it belong here?
-        new_values = new_values.dup;
+/+        new_values = new_values.dup;
         Array.sort(new_values);
         long[] all_values = Array.unionOf(old_values, new_values);
         if (all_values.length != old_values.length + new_values.length)
@@ -211,6 +212,7 @@
             throw e;+/
         }
         old_values = all_values;
+        +/
     }
 
     void setDefault(Stmt[] stmts)
@@ -241,7 +243,7 @@
 
     struct Case
     {
-        IntegerLit[] values;
+        Exp[] values;
         Stmt[] stmts;
         long[] values_converted;
         bool followedByDefault = false;
--- a/basic/Attribute.d	Sun Jul 20 23:41:53 2008 +0200
+++ b/basic/Attribute.d	Mon Jul 21 01:05:20 2008 +0200
@@ -61,7 +61,37 @@
 
     void setExtern(Extern e)    
     { 
-        att &= ~e; 
+        att &= 0xFF7C0FFF;
+        att |= e; 
+    }
+
+    Extern getExtern()
+    {
+        Extern e = Extern.D;
+        switch(bsf(0xF0000000 | att >> 12))
+        {
+            case 0:
+                e = Extern.C;
+                break;
+            case 1:
+                e = Extern.CPlusPlus;
+                break;
+            case 2:
+                e = Extern.D;
+                break;
+            case 3:
+                e = Extern.Windows;
+                break;
+            case 4:
+                e = Extern.Pascal;
+                break;
+            case 5:
+                e = Extern.System;
+                break;
+            default:
+                break;
+        }
+        return e;
     }
 
     void setStatic()    { att &= ~Static; }
--- a/gen/CodeGen.d	Sun Jul 20 23:41:53 2008 +0200
+++ b/gen/CodeGen.d	Mon Jul 21 01:05:20 2008 +0200
@@ -12,6 +12,7 @@
        ast.Module : DModule = Module;
 
 import basic.SmallArray,
+       basic.Attribute,
        basic.LiteralParsing;
 
 import lexer.Token;
@@ -116,7 +117,7 @@
                 else if(auto f = cast(DFunction)ret_t)
                     ret_t = f.returnType;
                 auto func_t = FunctionType.Get(llvm(ret_t), param_types);
-                auto llfunc = m.addFunction(func_t, fd.sym.getMangledFQN());
+                auto llfunc = m.addFunction(func_t, symbolName(fd));
 
                 foreach (i, p; fd.funcArgs)
                 {
@@ -173,7 +174,7 @@
                     return;
 
                 llvm(funcDecl.type);
-                auto llfunc = m.getNamedFunction(funcDecl.sym.getMangledFQN());
+                auto llfunc = m.getNamedFunction(symbolName(funcDecl));
                 auto func_tp = cast(PointerType)llfunc.type;
                 auto func_t = cast(FunctionType)func_tp.elementType();
                 auto ret_t = func_t.returnType();
@@ -327,7 +328,7 @@
                 foreach (i, arg; callExp.args)
                     args[i] = genExpression(arg).value;
                 llvm(type);
-                auto f = m.getNamedFunction(sym.getMangledFQN());
+                auto f = m.getNamedFunction(symbolName(callExp.exp));
                 DFunction f_type = type.asFunction();
                 bool isVoid = f_type.returnType is DType.Void;
                 // BUG: doesn't do implicit type-conversion on args
@@ -537,8 +538,8 @@
                 auto sw = cast(SwitchStmt)stmt;
                 Value cond = genExpression(sw.cond).value;
 
-                auto func_name = stmt.env.parentFunction().identifier.get;
-                Function func = m.getNamedFunction(func_name);
+                auto fc = stmt.env.parentFunction();
+                Function func = m.getNamedFunction(symbolName(fc));
 
                 BasicBlock oldBB = b.getInsertBlock();
                 BasicBlock defBB;
@@ -747,7 +748,16 @@
     /// Get the mangled name of a function
     char[] symbolName(FuncDecl f)
     {
-        return f.sym.getMangledFQN();
+        if (f.att.getExtern == Extern.D)
+            return f.sym.getMangledFQN();
+        return f.sym.getName;
+    }
+
+    char[] symbolName(Exp f)
+    {
+        if (f.getSymbol.decl.att.getExtern == Extern.D)
+            return f.getSymbol.getMangledFQN();
+        return f.getSymbol.getName;
     }
 
     /**
--- a/parser/Action.d	Sun Jul 20 23:41:53 2008 +0200
+++ b/parser/Action.d	Mon Jul 21 01:05:20 2008 +0200
@@ -277,16 +277,16 @@
         return null;
     }
 
-    StmtT actOnStartOfSwitchStmt()
+    StmtT actOnStartOfSwitchStmt(ExprT exp)
     {
         return null;
     }
 
-    void actOnCaseStmt()
+    void actOnCaseStmt(StmtT stmt, ExprT[] exps, StmtT[] stmts)
     {
     }
 
-    void actOnDefaultStmt()
+    void actOnDefaultStmt(StmtT stmt, StmtT[] stmts)
     {
     }
 
--- a/parser/Parser.d	Sun Jul 20 23:41:53 2008 +0200
+++ b/parser/Parser.d	Mon Jul 21 01:05:20 2008 +0200
@@ -133,7 +133,6 @@
             t = lexer.peek;
         }
 
-
         if (t.isBasicType || t.isIdentifier)
         {
             Id type;
@@ -532,8 +531,57 @@
         }
         else if(t.isSwitch)
         {
-            messages.report(UnexpectedTok, lexer.peek.location).arg(lexer.next.getType);
-            return null;
+            lexer.next;
+            require(Tok.OpenParentheses);
+            auto target = parseExpression();
+            auto res = action.actOnStartOfSwitchStmt(target);
+            require(Tok.CloseParentheses);
+            require(Tok.OpenBrace);
+            while (true)
+            {
+                Stmt[] statements;
+                if (skip(Tok.Default))
+                {
+                    require(Tok.Colon);
+                    statements.length = 0;
+                    while (lexer.peek.type != Tok.Case
+                            && lexer.peek.type != Tok.Default
+                            && lexer.peek.type != Tok.CloseBrace)
+                        statements ~= parseStatement();
+                    action.actOnDefaultStmt(res, statements);
+                    continue;
+                }
+
+                Token _case = lexer.peek;
+                if (_case.type != Tok.Case)
+                    break;
+                lexer.next();
+
+                Exp[] literals;
+                do
+                {
+                    Exp e = parseExpression();
+//                    IntegerLit lit = cast(IntegerLit)e;
+//                    if (lit is null)
+//                        messages.report(CaseValueMustBeInt, lexer.peek.location).arg(lexer.next.getType);
+//                    else
+                    literals ~= e;
+                }
+                while (skip(Tok.Comma));
+                require(Tok.Colon);
+
+                while (lexer.peek.type != Tok.Case
+                        && lexer.peek.type != Tok.Default
+                        && lexer.peek.type != Tok.CloseBrace)
+                    statements ~= parseStatement();
+
+                action.actOnCaseStmt(res, literals, statements);
+
+                if (lexer.peek.type == Tok.CloseBrace)
+                    break;
+            }
+            require(Tok.CloseBrace);
+            return res;
         }
         else
         {
--- a/sema/AstAction.d	Sun Jul 20 23:41:53 2008 +0200
+++ b/sema/AstAction.d	Mon Jul 21 01:05:20 2008 +0200
@@ -173,6 +173,23 @@
         return new DeclStmt(d);
     }
 
+    override StmtT actOnStartOfSwitchStmt(ExprT exp)
+    {
+        return new SwitchStmt(cast(Exp)exp);
+    }
+
+    override void actOnCaseStmt(StmtT stmt, ExprT[] exps, StmtT[] stmts)
+    {
+        auto sw = cast(SwitchStmt)stmt;
+        sw.addCase(cast(Exp[])exps, cast(Stmt[])stmts);
+    }
+
+    override void actOnDefaultStmt(StmtT stmt, StmtT[] stmts)
+    {
+        auto sw = cast(SwitchStmt)stmt;
+        sw.setDefault(cast(Stmt[])stmts);
+    }
+
     // -- Expressions --
     override ExprT actOnNumericConstant(Token c)
     {
--- a/sema/Visitor.d	Sun Jul 20 23:41:53 2008 +0200
+++ b/sema/Visitor.d	Mon Jul 21 01:05:20 2008 +0200
@@ -229,7 +229,7 @@
         foreach (c; s.cases)
         {
             foreach(lit; c.values)
-                visitIntegerLit(lit);
+                visitExp(lit);
             foreach(stmt; c.stmts)
                 visitStmt(stmt);
         }