changeset 58:fc62c5296a1c new_gen

Add types to our Exp
author Anders Halager <halager@gmail.com>
date Mon, 28 Apr 2008 21:51:39 +0200
parents 43bb0a36b869
children 1d6f4ad38a91
files ast/Exp.d gen/CodeGen.d sema/DType.d
diffstat 3 files changed, 81 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/ast/Exp.d	Mon Apr 28 21:47:01 2008 +0200
+++ b/ast/Exp.d	Mon Apr 28 21:51:39 2008 +0200
@@ -8,7 +8,8 @@
 
 import lexer.Token;
 
-import sema.SymbolTable;
+import sema.SymbolTable,
+       sema.DType;
 
 enum ExpType
 {
@@ -29,6 +30,8 @@
         this.expType = expType;
     }
 
+    DType type() { return null; }
+
     ExpType expType;
     Scope env;
     int stmtIndex;
@@ -48,6 +51,13 @@
         this.args = args;
     }
 
+    override DType type()
+    {
+        DFunction f = cast(DFunction)exp.type();
+        assert(f, "Can only call functions");
+        return f.return_type;
+    }
+
     Exp exp;
     Exp[] args;
     bool sret = false;
@@ -105,6 +115,8 @@
         return this;
     }
 
+    override DType type() { return identifier.type(); }
+
     Exp identifier;
     Exp exp;
 }
@@ -132,6 +144,23 @@
         this.right = right;
     }
 
+    override DType type()
+    {
+        if (myType)
+            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;
+    }
+
     char[] resultType()
     {
         if (op >= Operator.Eq && op <= Operator.Ge)
@@ -147,6 +176,7 @@
 
     Operator op;
     Exp left, right;
+    private DType myType;
 }
 
 class NegateExp : Exp
@@ -162,6 +192,8 @@
         return this;
     }
 
+    override DType type() { return exp.type(); }
+
     public Exp exp;
 }
 
@@ -177,6 +209,8 @@
         return this;
     }
 
+    override DType type() { return DType.Int; }
+
     Token token;
 }
 
@@ -195,8 +229,22 @@
         return this;
     }
 
+    override DType type()
+    {
+        if (myType)
+            return myType;
+
+        DStruct st = cast(DStruct)target.type;
+        assert(st, "Only structs have members");
+        if (auto t = st.typeOf(child.token.get))
+            myType = t;
+        // no error reporting here
+        else assert(0, "Referencing non-existant member");
+    }
+
     Identifier child;
     Exp target;
+    private DType myType;
 }
 
 class ArrayLookup : Exp
@@ -208,6 +256,8 @@
         this.pos = pos;
     }
 
+    override DType type() { return target.type(); }
+
     Exp simplify()
     {
         target = target.simplify;
@@ -228,6 +278,14 @@
         name = t.get;
     }
 
+    override DType type()
+    {
+        if (myType)
+            return myType;
+        myType = env.find(this).type;
+        return myType;
+    }
+
     this(char[] name)
     {
         super(ExpType.Identifier);
@@ -265,6 +323,6 @@
 
     Token token;
     char[] name;
+    private DType myType;
 }
 
-
--- a/gen/CodeGen.d	Mon Apr 28 21:47:01 2008 +0200
+++ b/gen/CodeGen.d	Mon Apr 28 21:51:39 2008 +0200
@@ -10,7 +10,8 @@
        ast.Stmt,
        ast.Exp;
 
-import misc.Error;
+import misc.Error,
+       basic.SmallArray;
 
 import lexer.Token;
 
@@ -588,13 +589,13 @@
             type_map[t] = res;
             return res;
         }
-        if (auto s = cast(DStruct)t)
+        else if (auto s = cast(DStruct)t)
         {
-            Type[] members;
+            SmallArray!(Type, 8) members;
             foreach(m; s.members)
                 members ~= llvm(m.type);
 
-            Type res = StructType.Get(members);
+            Type res = StructType.Get(members.unsafe());
             type_map[t] = res;
             return res;
         }
--- a/sema/DType.d	Mon Apr 28 21:47:01 2008 +0200
+++ b/sema/DType.d	Mon Apr 28 21:51:39 2008 +0200
@@ -55,6 +55,12 @@
     Location getLoc() { return loc; }
     int byteSize() { return 0; }
 
+    /**
+      Can this type legally be converted to that type with no casts?
+      True for short -> int etc.
+     */
+    bool hasImplicitConversionTo(DType that) { return false; }
+
     static DInteger
         Bool,
         Byte, UByte, Short, UShort,
@@ -92,6 +98,13 @@
 
     override int byteSize() { return bits / 8; }
 
+    override bool hasImplicitConversionTo(DType that)
+    {
+        if (auto o = cast(DInteger)that)
+            return this.bits >= o.bits;
+        return false;
+    }
+
     int bits;
     bool unsigned;
 }
@@ -123,7 +136,9 @@
 
     DType typeOf(char[] name)
     {
-        return members[name].type;
+        if (auto res = name in members)
+            return res.type;
+        return null;
     }
 
     DStructMember[char[]] members;