changeset 195:4e1a7265d620

Made a BuildTypes pass, to give all exp's a type.
author Anders Johnsen <skabet@gmail.com>
date Tue, 29 Jul 2008 15:50:24 +0200
parents 08f68d684047
children bb06ffcfb170
files ast/Exp.d dang/compiler.d gen/CodeGen.d sema/BuildTypes.d sema/CheckTypes.d tests/parser/alias_1.d tools/AstPrinter.d
diffstat 7 files changed, 265 insertions(+), 201 deletions(-) [+]
line wrap: on
line diff
--- a/ast/Exp.d	Tue Jul 29 13:54:44 2008 +0200
+++ b/ast/Exp.d	Tue Jul 29 15:50:24 2008 +0200
@@ -66,7 +66,7 @@
     Symbol getSymbol() { return null; }
 
     /// Get the type of the expression
-    abstract DType type();
+    DType type;
 
     /// Indicates which type the expression is - to avoid a lot of casts
     ExpType expType;
@@ -74,8 +74,6 @@
     /// The environment of the expression
     Scope env;
 
-    Symbol symbol;
-
     int stmtIndex;
 
     /**
@@ -104,13 +102,6 @@
         this.args = args;
     }
 
-    override DType type()
-    {
-        DFunction f = exp.type.asCallable();
-        assert(f !is null, "Can only call functions");
-        return f.returnType;
-    }
-
     DType callerType()
     {
         DFunction f = new DFunction(new Identifier("function"));
@@ -165,8 +156,6 @@
         return identifier.sourceRange + exp.sourceRange;
     }
 
-    override DType type() { return identifier.type(); }
-
     Exp identifier;
     Exp exp;
 }
@@ -213,35 +202,6 @@
         this.right = right;
     }
 
-    override DType type()
-    {
-        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)
-            myType = l;
-        else if (l.hasImplicitConversionTo(r))
-            myType = r;
-        else if (r.hasImplicitConversionTo(l))
-            myType = l;
-        else
-            return null;
-        return myType;
-    }
-
     override SLoc startLoc() { return left.startLoc(); }
 
     override SourceRange sourceRange()
@@ -265,7 +225,6 @@
 
     Operator op;
     Exp left, right;
-    private DType myType;
 }
 
 class NegateExp : Exp
@@ -282,8 +241,6 @@
         return this;
     }
 
-    override DType type() { return exp.type(); }
-
     override SourceRange sourceRange()
     {
         return SourceRange(loc) + exp.sourceRange;
@@ -306,19 +263,11 @@
         return this;
     }
 
-    override DType type() 
-    {
-        if (_type)
-            return _type;
-        return exp.type().asPointer().pointerOf; 
-    }
-
     override SourceRange sourceRange()
     {
         return SourceRange(loc) + exp.sourceRange;
     }
 
-    DType _type;
     public Exp exp;
 }
 
@@ -336,11 +285,6 @@
         return this;
     }
 
-    override DType type() 
-    {
-        return exp.type().getPointerTo; 
-    }
-
     override SourceRange sourceRange()
     {
         return SourceRange(loc) + exp.sourceRange;
@@ -368,23 +312,6 @@
         return this;
     }
 
-    override DType type() 
-    { 
-        switch(number.type)
-        {
-            case NumberType.Int:
-                return DType.Int;
-            case NumberType.Long:
-                return DType.Long;
-            case NumberType.ULong:
-                return DType.ULong;
-            case NumberType.Double:
-                return DType.Double;
-            case NumberType.Real:
-                return DType.Real;
-        }
-    }
-
     override SourceRange sourceRange()
     {
         return range;
@@ -429,32 +356,6 @@
         return this;
     }
 
-    override DType type()
-    {
-        if (myType)
-            return myType;
-
-        if ( target.type.isStruct )
-        {
-            Symbol st = target.getSymbol;
-            if (auto t = st.findMembers(child.name))
-                myType = t[0].type;
-//            else assert(0, "Referencing non-existant member");
-        }
-        else if ( target.type.isClass )
-        {
-            Symbol cl = target.getSymbol;
-            if (auto t = cl.findMembers(child.name))
-                myType = t[0].type;
-//            else assert(0, "Referencing non-existant member");
-        }
-        else
-            assert(0, "Only structs and classes have members");
-        // no error reporting here
-
-        return myType;
-    }
-
     override SLoc startLoc() { return target.startLoc(); }
 
     override SourceRange sourceRange()
@@ -464,7 +365,6 @@
 
     Identifier child;
     Exp target;
-    private DType myType;
 }
 
 class IndexExp : Exp
@@ -478,16 +378,6 @@
         this.right_bracket = right_bracket;
     }
 
-    override DType type()
-    {
-        DType type = target.type();
-        if (type.isStaticArray())
-            return type.asStaticArray().arrayOf;
-        else if (type.isPointer())
-            return type.asPointer().pointerOf;
-        else assert(0, "Can only index pointers and arrays");
-    }
-
     override SourceRange sourceRange()
     {
         return target.sourceRange + SourceRange(right_bracket);
@@ -514,11 +404,6 @@
         this.exp = exp;
     }
 
-    override DType type()
-    {
-        return env.findType(this.castType.get);
-    }
-
     override CastExp simplify()
     {
         castType = castType.simplify();
@@ -543,19 +428,6 @@
         this.str = str;
     }
 
-    override DType type() 
-    {
-        switch (data.type)
-        {
-            case StringType.Char:
-                return DType.Char.getAsStaticArray(data.data.length); 
-            case StringType.WChar:
-                return DType.WChar.getAsStaticArray(data.data.length/2); 
-            case StringType.DChar:
-                return DType.DChar.getAsStaticArray(data.data.length/4); 
-        }
-    }
-
     char[] str;
     String data;
 }
@@ -570,11 +442,6 @@
         this.c_args = c_args;
     }
 
-    override DType type() 
-    { 
-        return env.findType(this.newType.get); 
-    }
-
     Exp[] a_args, c_args;
     Identifier newType;
     Symbol callSym;
@@ -586,11 +453,6 @@
     {
         super(ExpType.NullExp, loc);
     }
-
-    override DType type() 
-    { 
-        return new DPointer(DType.Int); 
-    }
 }
 
 class Identifier : Exp
@@ -618,24 +480,14 @@
 
     override Symbol getSymbol()
     {
+        if (!env)
+            return null;
         if (auto decl = env.find(this.get))
             if(decl.length)
                 return decl[$-1].sym;
         return null;
     }
 
-    override DType type()
-    {
-        if (myType !is null)
-            return myType;
-        else if (auto sym = getSymbol)
-            myType = sym.type;
-        else
-            myType = DType.Int;
-
-        return myType;
-    }
-
     this(char[] name)
     {
         super(ExpType.Identifier, SLoc.Invalid);
@@ -671,18 +523,12 @@
         return this;
     }
 
-    void setType(DType myType)
-    {
-        this.myType = myType;
-    }
-
     override SourceRange sourceRange()
     {
         return SourceRange(loc, loc + name.length);
     }
 
     char[] name;
-    private DType myType;
 }
 
 class IdentifierTypeExp : Identifier
@@ -708,11 +554,6 @@
         this.name = pointerOf.name;
     }
 
-    override DType type()
-    {
-        return pointerOf.type.getPointerTo();
-    }
-
     Identifier pointerOf;
 }
 
@@ -726,15 +567,8 @@
         this.name = arrayOf.name;
     }
 
-    override DType type()
-    {
-        return arrayOf.type.getAsStaticArray(size);
-    }
-
     Identifier arrayOf;
     int size;
-
-    private DType myType;
 }
 
 class ArrayTypeExp : IdentifierTypeExp
@@ -746,14 +580,7 @@
         this.name = arrayOf.name;
     }
 
-    override DType type()
-    {
-        return arrayOf.type.getAsArray();
-    }
-
     Identifier arrayOf;
-
-    private DType myType;
 }
 
 class FunctionTypeExp : IdentifierTypeExp
@@ -765,22 +592,8 @@
         this.decls = decls;
     }
 
-    override DType type()
-    {
-        if (myType)
-            return myType;
-        auto t  = new DFunction(returnType);
-        t.returnType = returnType.type;
-        foreach (decl ; decls)
-            t.params ~= decl.identifier.type;
-
-        myType = t.getPointerTo;
-        return myType;
-    }
-
     VarDecl[] decls;
     IdentifierTypeExp returnType;
-    private DType myType;
 }
 
 class ArrayLiteralExp : Exp
@@ -793,11 +606,6 @@
         this.end = end;
     }
 
-    override DType type()
-    {
-        return exps[0].type.getAsStaticArray(exps.length);
-    }
-
     Exp[] exps;
     SLoc begin, end;
 }
--- a/dang/compiler.d	Tue Jul 29 13:54:44 2008 +0200
+++ b/dang/compiler.d	Tue Jul 29 15:50:24 2008 +0200
@@ -27,6 +27,7 @@
        sema.AstAction,
        sema.BuildScopes,
        sema.BuildSymbols,
+       sema.BuildTypes,
        sema.CheckScopes,
        sema.CheckTypes,
        sema.LiteralInterpreter,
@@ -320,6 +321,9 @@
     StopWatch watch2;
     watch.start;
     watch2.start;
+
+    (new BuildTypes(messages)).visit(modules);
+
     (new CheckScopes(messages)).visit(modules);
     messages.checkErrors;
     auto scope_check = watch2.stop;
--- a/gen/CodeGen.d	Tue Jul 29 13:54:44 2008 +0200
+++ b/gen/CodeGen.d	Tue Jul 29 15:50:24 2008 +0200
@@ -344,14 +344,14 @@
                 auto AE = cast(AssignExp)exp;
                 LValue dst = genLValue(AE.identifier);
                 RValue src = genExpression(AE.exp);
-                storeThroughLValue(dst, src, AE.exp.type());
+                storeThroughLValue(dst, src, AE.exp.type);
                 return src;
             case ExpType.Index:
                 auto indexExp = cast(IndexExp)exp;
                 return loadLValue(genLValue(exp));
             case ExpType.NewExp:
                 auto newExp = cast(NewExp)exp;
-                DClass type = newExp.newType.type().asClass();
+                DClass type = newExp.newType.type.asClass();
                 auto llvm_type = cast(PointerType)llvm(type);
                 auto pointer = b.buildMalloc(llvm_type.elementType(), "new");
                 scope args = new Value[newExp.c_args.length];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sema/BuildTypes.d	Tue Jul 29 15:50:24 2008 +0200
@@ -0,0 +1,221 @@
+module sema.BuildTypes;
+
+import basic.LiteralParsing,
+       basic.Message;
+
+import sema.Visitor,
+       sema.Symbol,
+       sema.DType;
+
+import tango.io.Stdout;
+
+
+class BuildTypes : Visitor!(void)
+{
+    this(MessageHandler messages)
+    {
+        this.messages = messages;
+    }
+
+    override void visitCallExp(CallExp exp)
+    {
+        super.visitCallExp(exp);
+        DFunction f = exp.exp.type.asCallable();
+        assert(f !is null, "Can only call functions");
+        exp.type = f.returnType;
+    }
+
+    override void visitAssignExp(AssignExp exp)
+    {
+        super.visitAssignExp(exp);
+        exp.type = exp.identifier.type;
+    }
+
+    override void visitBinaryExp(BinaryExp exp)
+    {
+        super.visitBinaryExp(exp);
+        if (exp.op == BinaryExp.Operator.Eq || 
+            exp.op == BinaryExp.Operator.Ne ||
+            exp.op == BinaryExp.Operator.Lt ||
+            exp.op == BinaryExp.Operator.Le ||
+            exp.op == BinaryExp.Operator.Gt ||
+            exp.op == BinaryExp.Operator.Ge)
+        {
+            exp.type = DType.Bool;
+            return;
+        }
+
+        DType l = exp.left.type;
+        DType r = exp.right.type;
+        if (l.isSame(r))
+            exp.type = l;
+        else if (l.hasImplicitConversionTo(r))
+            exp.type = r;
+        else if (r.hasImplicitConversionTo(l))
+            exp.type = l;
+        else
+            exp.type = DType.Int; //FIXME: Throw error here.
+    }
+
+    override void visitNegateExp(NegateExp exp) 
+    { 
+        super.visitNegateExp(exp);
+        exp.type = exp.exp.type; 
+    }
+
+    override void visitDerefExp(DerefExp exp)
+    {
+        super.visitDerefExp(exp);
+        exp.type = exp.exp.type.asPointer().pointerOf; 
+    }
+
+    override void visitAddressOfExp(AddressOfExp exp)
+    {
+        super.visitAddressOfExp(exp);
+        exp.type = exp.exp.type.getPointerTo; 
+    }
+
+    override void visitIntegerLit(IntegerLit exp)
+    {
+        super.visitIntegerLit(exp);
+        switch(exp.number.type)
+        {
+            case NumberType.Int:
+                exp.type = DType.Int;
+                break;
+            case NumberType.Long:
+                exp.type = DType.Long;
+                break;
+            case NumberType.ULong:
+                exp.type = DType.ULong;
+                break;
+            case NumberType.Double:
+                exp.type = DType.Double;
+                break;
+            case NumberType.Real:
+                exp.type = DType.Real;
+                break;
+        }
+    }
+
+    override void visitMemberReference(MemberReference exp)
+    {
+        super.visitMemberReference(exp);
+        if ( exp.target.type.isStruct )
+        {
+            Symbol st = exp.target.getSymbol;
+            if (auto t = st.findMembers(exp.child.name))
+                exp.type = t[0].type;
+//            else assert(0, "Referencing non-existant member");
+        }
+        else if ( exp.target.type.isClass )
+        {
+            Symbol cl = exp.target.getSymbol;
+            if (auto t = cl.findMembers(exp.child.name))
+                exp.type = t[0].type;
+//            else assert(0, "Referencing non-existant member");
+        }
+        else
+            assert(0, "Only structs and classes have members");
+        // no error reporting here
+    }
+
+    override void visitIndexExp(IndexExp exp)
+    {
+        super.visitIndexExp(exp);
+        DType type = exp.target.type;
+        if (type.isStaticArray())
+            exp.type = type.asStaticArray().arrayOf;
+        else if (type.isPointer())
+            exp.type = type.asPointer().pointerOf;
+        else assert(0, "Can only index pointers and arrays");
+    }
+
+    override void visitCastExp(CastExp exp)
+    {
+        super.visitCastExp(exp);
+        exp.type = exp.env.findType(exp.castType.get);
+    }
+
+    override void visitStringExp(StringExp exp)
+    {
+        super.visitStringExp(exp);
+        switch (exp.data.type)
+        {
+            case StringType.Char:
+                exp.type = DType.Char.getAsStaticArray(exp.data.data.length); 
+                break;
+            case StringType.WChar:
+                exp.type = DType.WChar.getAsStaticArray(exp.data.data.length/2); 
+                break;
+            case StringType.DChar:
+                exp.type = DType.DChar.getAsStaticArray(exp.data.data.length/4); 
+                break;
+        }
+    }
+
+    override void visitNewExp(NewExp exp)
+    {
+        super.visitNewExp(exp);
+        exp.type = exp.env.findType(exp.newType.get); 
+    }
+
+    override void visitNullExp(NullExp exp)
+    {
+        super.visitNullExp(exp);
+        exp.type = new DPointer(DType.Int);
+    }
+
+    override void visitIdentifier(Identifier exp)
+    {
+        super.visitIdentifier(exp);
+        if (auto sym = exp.getSymbol)
+            exp.type = sym.type;
+        else
+            exp.type = DType.Int;
+    }
+
+/*    override void visitIdentifierTypeExp(IdentifierTypeExp exp)
+    {
+        if (auto sym = exp.getSymbol)
+            exp.type = sym.type;
+        else
+            exp.type = DType.Int;
+    }*/
+
+    override void visitPointerTypeExp(PointerTypeExp exp)
+    {
+        super.visitPointerTypeExp(exp);
+        exp.type = exp.pointerOf.type.getPointerTo();
+    }
+
+    override void visitStaticArrayTypeExp(StaticArrayTypeExp exp)
+    {
+        super.visitStaticArrayTypeExp(exp);
+        exp.type = exp.arrayOf.type.getAsStaticArray(exp.size);
+    }
+
+/*    override void visitArrayTypeExp(ArrayTypeExp exp)
+    {
+        exp.type = arrayOf.type.getAsArray();
+    }*/
+
+    override void visitFunctionTypeExp(FunctionTypeExp exp)
+    {
+        super.visitFunctionTypeExp(exp);
+        auto t  = new DFunction(exp.returnType);
+        t.returnType = exp.returnType.type;
+        foreach (decl ; exp.decls)
+            t.params ~= decl.varType.type;
+
+        exp.type = t.getPointerTo;
+    }
+
+    override void visitArrayLiteralExp(ArrayLiteralExp exp)
+    {
+        super.visitArrayLiteralExp(exp);
+        exp.type = exp.exps[0].type.getAsStaticArray(exp.exps.length);
+    }
+
+    MessageHandler messages;
+}
--- a/sema/CheckTypes.d	Tue Jul 29 13:54:44 2008 +0200
+++ b/sema/CheckTypes.d	Tue Jul 29 15:50:24 2008 +0200
@@ -21,7 +21,7 @@
     {
         super.visitBinaryExp(exp);
 
-        if(!(exp.left.type is exp.right.type))
+        if(!exp.left.type.isSame(exp.right.type))
         {
             if (!exp.right.type.hasImplicitConversionTo(exp.left.type) &&
                 !exp.left.type.hasImplicitConversionTo(exp.right.type))
@@ -59,7 +59,7 @@
                             SLoc.Invalid,
                             new Identifier(exp.left.type.name),
                             exp.right);
-                    else if(exp.left.type.byteSize > exp.right.type.byteSize)
+                    else if(exp.left.type.byteSize < exp.right.type.byteSize)
                         castExp = new CastExp(
                             SLoc.Invalid,
                             new Identifier(exp.right.type.name),
@@ -75,9 +75,15 @@
                 {
                     castExp.env = exp.env;
                     if(castExp.exp == exp.right)
+                    {
+                        exp.type = castExp.type = exp.left.type;
                         exp.right = castExp;
+                    }
                     else
+                    {
+                        exp.type = castExp.type = exp.right.type;
                         exp.left = castExp;
+                    }
 
                 }
             }
@@ -98,7 +104,7 @@
                     [exp.loc])
                 .arg(exp.exp.type.toString);
 
-            exp._type = DType.Int;
+            exp.type = DType.Int;
         }
     }
 
@@ -177,6 +183,7 @@
                             new Identifier(argType.name),
                             arg);
                     castExp.env = iden.env;
+                    castExp.type = argType;
                     newArgs ~= castExp;
                 }
                 else
@@ -245,6 +252,7 @@
                             new Identifier(argType.name),
                             arg);
                     castExp.env = iden.env;
+                    castExp.type = argType;
                     newArgs ~= castExp;
                 }
                 else
@@ -272,6 +280,7 @@
                             new Identifier(argType.name),
                             arg);
                     castExp.env = exp.exp.env;
+                    castExp.type = argType;
                     newArgs ~= castExp;
                 }
                 else
@@ -316,6 +325,7 @@
                             new Identifier(argType.name),
                             arg);
                     castExp.env = exp.newType.env;
+                    castExp.type = argType;
                     newArgs ~= castExp;
                 }
                 else
@@ -357,6 +367,7 @@
                     new Identifier(identifierType.name),
                     exp.exp);
             castExp.env = exp.exp.env;
+            exp.type = castExp.type = identifierType;
             exp.exp = castExp;
         }
 
@@ -388,6 +399,7 @@
                         new Identifier(returnType.name),
                         stmt.exp);
                 castExp.env = stmt.exp.env;
+                castExp.type = returnType;
                 stmt.exp = castExp;
             }
         }
@@ -413,6 +425,7 @@
                         new Identifier(varType.name),
                         decl.init);
                 castExp.env = decl.init.env;
+                castExp.type = varType;
                 decl.init = castExp;
             }
         }
--- a/tests/parser/alias_1.d	Tue Jul 29 13:54:44 2008 +0200
+++ b/tests/parser/alias_1.d	Tue Jul 29 15:50:24 2008 +0200
@@ -5,7 +5,7 @@
 }
 
 alias foo bar;
-alias int** i;
+alias int* i;
 alias int A;
 alias int B;
 
--- a/tools/AstPrinter.d	Tue Jul 29 13:54:44 2008 +0200
+++ b/tools/AstPrinter.d	Tue Jul 29 15:50:24 2008 +0200
@@ -139,6 +139,24 @@
                 }
                 printEndLine(";");
                 break;
+            case StmtType.If:
+                auto i = cast(IfStmt)stmt;
+                printBeginLine("if");
+                print(" (");
+                printExp(i.cond);
+                printEndLine(" )");
+                printOpenBrace;
+                printStatement(i.then_body);
+                printCloseBrace;
+                if (i.else_body)
+                {
+                    printBeginLine("else");
+                    printEndLine();
+                    printOpenBrace;
+                    printStatement(i.else_body);
+                    printCloseBrace;
+                }
+                break;
             case StmtType.Decl:
                 auto declStmt = cast(DeclStmt)stmt;
                 printDecl(declStmt.decl, false);