changeset 68:381975d76baf new_gen

A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
author Anders Johnsen <skabet@gmail.com>
date Thu, 01 May 2008 19:25:49 +0200
parents 3fdf20b08a81
children 688b516408cd
files ast/Exp.d dang/compiler.d gen/CodeGen.d lexer/Keyword.d lexer/Token.d parser/Action.d parser/Parser.d sema/AstAction.d sema/DType.d sema/Declarations.d sema/Visitor.d tests/code/basic_types_2.d tools/AstPrinter.d
diffstat 13 files changed, 186 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/ast/Exp.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/ast/Exp.d	Thu May 01 19:25:49 2008 +0200
@@ -21,6 +21,7 @@
     Identifier,
     AssignExp,
     CallExp,
+    CastExp,
 }
 
 class Exp
@@ -144,6 +145,8 @@
         Mul, Div, Mod,
     }
 
+    char[][] getOp = ["=","==","!=","<","<=",">",">=","+","-","*","/","%"];
+
     this(Operator op, Exp left, Exp right)
     {
         super(ExpType.Binary);
@@ -157,6 +160,17 @@
         if (myType)
             return myType;
 
+        if (op == Operator.Eq || 
+            op == Operator.Ne ||
+            op == Operator.Lt ||
+            op == Operator.Le ||
+            op == Operator.Gt ||
+            op == Operator.Ge)
+        {
+            myType = DType.Bool;
+            return myType;
+        }
+
         DType l = left.type;
         DType r = right.type;
         if (l is r)
@@ -167,6 +181,7 @@
             myType = l;
         else
             return null;
+        return myType;
     }
 
     char[] resultType()
@@ -225,6 +240,8 @@
 
     override DType type() { return DType.Int; }
 
+    
+
     Token token;
     char[] name;
 }
@@ -254,6 +271,8 @@
             myType = t;
         // no error reporting here
         else assert(0, "Referencing non-existant member");
+
+        return myType;
     }
 
     Identifier child;
@@ -283,6 +302,31 @@
     IntegerLit pos;
 }
 
+class CastExp : Exp
+{
+    this(Identifier castType, Exp exp)
+    {
+        super(ExpType.CastExp);
+        this.castType = castType;
+        this.exp = exp;
+    }
+
+    override DType type()
+    {
+        return env.findType(this.castType);
+    }
+
+    Exp simplify()
+    {
+        castType.simplify;
+        exp.simplify;
+        return this;
+    }
+
+    Identifier castType;
+    Exp exp;
+}
+
 class Identifier : Exp
 {
     this(Token t)
--- a/dang/compiler.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/dang/compiler.d	Thu May 01 19:25:49 2008 +0200
@@ -19,6 +19,7 @@
 import sema.Visitor,
        sema.AstAction,
        sema.SymbolTableBuilder,
+       sema.ImplicitCast,
        sema.Declarations;
 
 import dang.OptParse;
@@ -170,6 +171,7 @@
 
         (new SymbolTableBuilder).visit(decls);
         (new Declarations).visit(decls);
+        (new ImplicitCast).visit(decls);
 
         foreach(decl ; decls)
             decl.simplify();
--- a/gen/CodeGen.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/gen/CodeGen.d	Thu May 01 19:25:49 2008 +0200
@@ -77,6 +77,45 @@
         auto temp = FunctionType.Get(Type.Void, [BytePtr, BytePtr, Type.Int32, Type.Int32]);
         llvm_memcpy = m.addFunction(temp, "llvm.memcpy.i32");
 
+        auto registerFunc =
+            (FuncDecl fd)
+            {
+                Type[] param_types;
+                foreach (i, p; fd.funcArgs)
+                {
+                    DType t = p.env.find(p.identifier).type;
+                    if(auto st = cast(DStruct)t)
+                    {
+                        Type pointer = PointerType.Get(llvm(st));
+                        param_types ~= pointer;
+                    }
+                    else
+                        param_types ~= llvm(t);
+                }
+                auto ret_t = fd.env.find(fd.identifier).type;
+                if(auto st = cast(DStruct)ret_t)
+                    ret_t = DType.Void;
+                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.identifier.get);
+
+                foreach (i, p; fd.funcArgs)
+                {
+                    if(i == 0 && fd.sret)
+                        llfunc.addParamAttr(0, ParamAttr.StructRet);
+
+                    DType t = p.env.find(p.identifier).type;
+                    if(auto st = cast(DStruct)t)
+                    {
+                        if(i == 0 && fd.sret)
+                            continue;
+                        llfunc.addParamAttr(i,ParamAttr.ByVal);
+                    }
+                }
+            };
+        auto visitor = new VisitFuncDecls(registerFunc);
+        visitor.visit(decls);
         // Before beginning we move all top level var-decls to the start
         // and then we generate the var-decls first
         // partition is NOT required to be stable, but that should not create
@@ -217,7 +256,7 @@
                 auto left = genExpression(binaryExp.left);
                 auto right = genExpression(binaryExp.right);
 
-                sextSmallerToLarger(left, right);
+//                sextSmallerToLarger(left, right);
 
                 OpBuilder op = opToLLVM[binaryExp.op];
 
@@ -248,6 +287,29 @@
                 if(callExp.sret)
                     return b.buildCall(m.getNamedFunction(func_sym.id.get), args, "");
                 return b.buildCall(m.getNamedFunction(func_sym.id.get), args, ".call");
+            case ExpType.CastExp:
+                auto castExp = cast(CastExp)exp;
+                auto value = genExpression(castExp.exp);
+
+                if(!castExp.type.hasImplicitConversionTo(castExp.type))
+                    assert(0, "Invalid cast");
+
+                Stdout(castExp.type.byteSize).newline;
+                Stdout(castExp.type.name).newline;
+                Stdout(castExp.exp.type.byteSize).newline;
+                Stdout(castExp.exp.type.name).newline;
+
+                Stdout(value).newline;
+
+                Value v;
+                if(castExp.exp.type.byteSize <= castExp.type.byteSize)
+                    v = b.buildZExt(value, llvm(castExp.type), "cast");
+                else
+                    v = b.buildTrunc(value, llvm(castExp.type), "cast");
+
+                Stdout(v).newline;
+                return v;
+
             case ExpType.Identifier:
                 auto identifier = cast(Identifier)exp;
                 auto sym = exp.env.find(identifier);
@@ -473,6 +535,9 @@
         Value t = getPointer(target);
         Value v = genExpression(exp);
 
+        Stdout(v).newline;
+        Stdout(t).newline;
+
         auto a = cast(PointerType)t.type;
 
         assert(a, "Assing to type have to be of type PointerType");
@@ -546,8 +611,14 @@
         else if (auto s = t.asStruct)
         {
             SmallArray!(Type, 8) members;
+            DType[] array;
+            array.length = s.members.length;
+
             foreach(m; s.members)
-                members ~= llvm(m.type);
+                array[m.index] = m.type;
+
+            foreach(m; array)
+                members ~= llvm(m);
 
             Type res = StructType.Get(members.unsafe());
             type_map[t] = res;
@@ -570,7 +641,7 @@
 
             Type res = FunctionType.Get(ret_t, params.unsafe());
             type_map[t] = res;
-            auto llfunc = m.addFunction(res, f.name);
+/*            auto llfunc = m.addFunction(res, f.name);
             
             foreach (i, param; f.params)
                 if (param.isStruct)
@@ -581,7 +652,7 @@
                 llfunc.removeParamAttr(0, ParamAttr.ByVal);
                 llfunc.addParamAttr(0, ParamAttr.StructRet);
             }
-
+*/
             return res;
         }
         assert(0, "Only integers, structs and functions are supported");
--- a/lexer/Keyword.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/lexer/Keyword.d	Thu May 01 19:25:49 2008 +0200
@@ -39,6 +39,7 @@
         "switch"    : Tok.Switch,
         "case"      : Tok.Case,
         "default"   : Tok.Default,
-        "return"    : Tok.Return
+        "return"    : Tok.Return,
+        "cast"      : Tok.Cast
     ];
 }
--- a/lexer/Token.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/lexer/Token.d	Thu May 01 19:25:49 2008 +0200
@@ -137,7 +137,7 @@
     If, Else,
     While,
     Switch, Case, Default,
-    Return,
+    Return, Cast,
 
 }
 
@@ -187,6 +187,7 @@
         Tok.Return:"Return",
         Tok.Struct:"Struct",
         Tok.Colon:"Colon",
-        Tok.Seperator:"Seperator"
+        Tok.Seperator:"Seperator",
+        Tok.Cast:"Cast"
     ];
 }
--- a/parser/Action.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/parser/Action.d	Thu May 01 19:25:49 2008 +0200
@@ -242,6 +242,14 @@
     {
         return null;
     }
+
+    /**
+      Cast expression.
+     */
+    ExprT actOnCastExpr(Id type, ExprT exp)
+    {
+        return null;
+    }
 }
 
 /**
--- a/parser/Parser.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/parser/Parser.d	Thu May 01 19:25:49 2008 +0200
@@ -373,6 +373,8 @@
                     return iden;
             }
         }
+        else if (next.type == Tok.Cast)
+            return parseCast();
         else if (next.type == Tok.Integer)
             return action.actOnNumericConstant(next);
 
@@ -380,6 +382,18 @@
         assert(0, "Should not happen");
     }
 
+    Exp parseCast()
+    {
+        require(Tok.OpenParentheses);
+        auto next = lexer.next;
+        if(!next.isBasicType && !next.isIdentifier)
+            throw error(__LINE__, "Expected cast type, not "~next.get).tok(next);
+        
+        require(Tok.CloseParentheses);
+        auto exp = P();
+        return action.actOnCastExpr(Id(next), exp);
+    }
+
     struct UnOp
     {
         Tok tokenType;
--- a/sema/AstAction.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/sema/AstAction.d	Thu May 01 19:25:49 2008 +0200
@@ -138,4 +138,9 @@
         Exp[] arguments = cast(Exp[])args.dup;
         return new CallExp(f, arguments);
     }
+
+    override ExprT actOnCastExpr(Id id, ExprT exp)
+    {
+        return new CastExp(new Identifier(id.tok), cast(Exp)exp );
+    }
 }
--- a/sema/DType.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/sema/DType.d	Thu May 01 19:25:49 2008 +0200
@@ -120,7 +120,8 @@
     override bool hasImplicitConversionTo(DType that)
     {
         if (auto o = cast(DInteger)that)
-            return this.bits >= o.bits;
+            return true;
+//            return this.bits >= o.bits;
         return false;
     }
 
--- a/sema/Declarations.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/sema/Declarations.d	Thu May 01 19:25:49 2008 +0200
@@ -37,6 +37,7 @@
         if (d.init)
             visitExp(d.init);
     }
+
     override void visitFuncDecl(FuncDecl f)
     {
         visitExp(f.identifier);
@@ -45,6 +46,11 @@
             visitStmt(stmt);
     }
 
+    override void visitCastExp(CastExp exp)
+    {
+        visitExp(exp.exp);
+    }
+
     override void visitMemberReference(MemberReference m)
     {
         switch(m.target.expType)
--- a/sema/Visitor.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/sema/Visitor.d	Thu May 01 19:25:49 2008 +0200
@@ -74,6 +74,8 @@
                 return visitAssignExp(cast(AssignExp)exp);
             case ExpType.CallExp:
                 return visitCallExp(cast(CallExp)exp);
+            case ExpType.CastExp:
+                return visitCastExp(cast(CastExp)exp);
             case ExpType.Identifier:
                 return visitIdentifier(cast(Identifier)exp);
             case ExpType.MemberReference:
@@ -236,6 +238,16 @@
             return ExpT.init;
     }
 
+    ExpT visitCastExp(CastExp exp)
+    {
+        visitExp(exp.castType);
+        visitExp(exp.exp);
+        static if (is(ExpT == void))
+            return;
+        else
+            return ExpT.init;
+    }
+
     ExpT visitNegateExp(NegateExp exp)
     {
         visitExp(exp.exp);
--- a/tests/code/basic_types_2.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/tests/code/basic_types_2.d	Thu May 01 19:25:49 2008 +0200
@@ -12,6 +12,8 @@
 
     c = stoi(a);
     c = stoi(b);
+
+    return 3;
 }
 
 long itol(int x) { return x; }
--- a/tools/AstPrinter.d	Tue Apr 29 20:15:22 2008 +0200
+++ b/tools/AstPrinter.d	Thu May 01 19:25:49 2008 +0200
@@ -104,9 +104,11 @@
         {
             case ExpType.Binary:
                 auto binaryExp = cast(BinaryExp)exp;
+                print("(");
                 printExp(binaryExp.left);
-                print([binaryExp.op] ~ " ");
+                print(" " ~ binaryExp.getOp[binaryExp.op] ~ " ");
                 printExp(binaryExp.right);
+                print(")");
                 break;
             case ExpType.IntegerLit:
                 auto integetLit = cast(IntegerLit)exp;
@@ -146,6 +148,14 @@
                 }
                 print(")");
                 break;
+            case ExpType.CastExp:
+                auto castExp = cast(CastExp)exp;
+                print("cast");
+                print("(");
+                printExp(castExp.castType);
+                print(")");
+                printExp(castExp.exp);
+                break;
         }
         
     }