changeset 49:c7cde6af0095 new_gen

Seperated the AST from LLVM * Changed SmallArray sligthly * Added a NullAction that doesn't do anything
author Anders Halager <halager@gmail.com>
date Sat, 26 Apr 2008 13:15:37 +0200
parents b6c1dc30ca4b
children e24515bcd4ef
files basic/SmallArray.d gen/LLVMGen.d parser/Action.d sema/DType.d
diffstat 4 files changed, 84 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/basic/SmallArray.d	Thu Apr 24 19:42:53 2008 +0200
+++ b/basic/SmallArray.d	Sat Apr 26 13:15:37 2008 +0200
@@ -31,7 +31,7 @@
 
     T[] opSlice()
     {
-        return ptr[0 .. len].dup;
+        return ptr[0 .. len];
     }
     alias opSlice unsafe;
 
@@ -39,7 +39,7 @@
     {
         if (len <= size)
             return static_array[0 .. len].dup;
-        return array[0 .. len].dup;
+        return array[0 .. len];
     }
 
     T[] opSliceAssign(T val, size_t low, size_t high)
@@ -68,21 +68,21 @@
     void opCatAssign(T val)
     {
         if (len < size)
-        {
-            ptr = static_array.ptr;
             static_array[len] = val;
-        }
         else if (len == size)
         {
             T[] tmp = static_array[].dup;
             array = tmp;
             array ~= val;
-            ptr = array.ptr;
         }
         else
             array ~= val;
 
         ++len;
+        if (len <= size)
+            ptr = static_array.ptr;
+        else
+            ptr = array.ptr;
     }
 
     size_t length() { return len; }
--- a/gen/LLVMGen.d	Thu Apr 24 19:42:53 2008 +0200
+++ b/gen/LLVMGen.d	Sat Apr 26 13:15:37 2008 +0200
@@ -47,6 +47,8 @@
             op.Ge       : mixin(genBuildCmp("SGE"))
         ];
         table = new SimpleSymbolTable();
+
+        createBasicTypes();
     }
 
     ~this()
@@ -74,13 +76,13 @@
                     DType t = p.env.find(p.identifier).type;
                     if(cast(DStruct)t)
                     {
-                        Type pointer = PointerType.Get(t.llvm());
+                        Type pointer = PointerType.Get(llvm(t));
                         param_types ~= pointer;
                     }
                     else
-                        param_types ~= t.llvm();
+                        param_types ~= llvm(t);
                 }
-                auto ret_t = fd.env.find(fd.identifier).type.llvm();
+                auto ret_t = llvm(fd.env.find(fd.identifier).type);
                 auto func_t = FunctionType.Get(ret_t, param_types);
                 auto llfunc = m.addFunction(func_t, fd.identifier.get);
             };
@@ -150,7 +152,7 @@
             case DeclType.VarDecl:
                 auto varDecl = cast(VarDecl)decl;
                 auto sym = varDecl.env.find(varDecl.identifier);
-                Type t = sym.type.llvm();
+                Type t = llvm(sym.type);
                 GlobalVariable g = m.addGlobal(t, sym.id.get);
                 g.initializer = ConstantInt.GetS(t, 0);
                 table[varDecl.identifier.get] = g;
@@ -162,7 +164,7 @@
                 foreach(varDecl ; structDecl.vars)
                 {
                     auto sym = varDecl.env.find(varDecl.identifier);
-                    Type t = sym.type.llvm();
+                    Type t = llvm(sym.type);
                     types ~= t;
                 }
 
@@ -185,7 +187,7 @@
                 auto varDecl = cast(VarDecl)decl;
                 auto name = varDecl.identifier.get;
                 auto sym = varDecl.env.find(varDecl.identifier);
-                auto AI = b.buildAlloca(sym.type.llvm(), name);
+                auto AI = b.buildAlloca(llvm(sym.type), name);
                 table[name] = AI;
                 if (varDecl.init)
                     buildAssign(varDecl.identifier, varDecl.init);
@@ -293,7 +295,7 @@
             case StmtType.Return:
                 auto ret = cast(ReturnStmt)stmt;
                 auto sym = stmt.env.parentFunction();
-                Type t = sym.type.llvm();
+                Type t = llvm(sym.type);
                 if (ret.exp is null)
                     if (t is Type.Void)
                     {
@@ -539,6 +541,51 @@
         return new Error(msg);
     }
 
+    /**
+      Get the LLVM Type corresponding to a DType.
+
+      Currently using the built-in associative array - not sure if it works
+      well when the hashes are so uniform.
+
+      Other possibilities would be to find a hash-function that works on
+      something as small as 4 bytes or to create a sparse array perhaps.
+     */
+    Type llvm(DType t)
+    {
+        if (auto llvm_t = t in type_map)
+            return *llvm_t;
+        return llvmCreateNew(t);
+    }
+
+    // Create an LLVM type and insert it into the type map, and return the
+    // result
+    Type llvmCreateNew(DType t)
+    {
+        if (auto i = cast(DInteger)t)
+        {
+            Type res = IntegerType.Get(i.byteSize() * 8);
+            type_map[t] = res;
+            return res;
+        }
+        assert(0, "Only integers are supported");
+    }
+
+    // Might as well insert all the basic types from the start
+    void createBasicTypes()
+    {
+        type_map[DType.Void] = Type.Void;
+
+        type_map[DType.Bool]   = Type.Int1;
+        type_map[DType.Byte]   = Type.Int8;
+        type_map[DType.UByte]  = Type.Int8;
+        type_map[DType.Short]  = Type.Int16;
+        type_map[DType.UShort] = Type.Int16;
+        type_map[DType.Int]    = Type.Int32;
+        type_map[DType.UInt]   = Type.Int32;
+        type_map[DType.Long]   = Type.Int64;
+        type_map[DType.ULong]  = Type.Int64;
+    }
+
 private:
 
     // llvm stuff
@@ -546,6 +593,7 @@
     Builder b;
     Function llvm_memcpy;
     Type BytePtr;
+    Type[DType] type_map;
 
     FuncDecl[char[]] functions;
 
--- a/parser/Action.d	Thu Apr 24 19:42:53 2008 +0200
+++ b/parser/Action.d	Sat Apr 26 13:15:37 2008 +0200
@@ -244,6 +244,13 @@
 }
 
 /**
+  Doesn't do anything at all - can be used for benchmarking the parser.
+ */
+class NullAction : Action
+{
+}
+
+/**
   This class implements the default actions for Dang, by building up an AST
   with the data needed in a compiler.
  */
@@ -277,9 +284,8 @@
     // -- Statements --
     override StmtT actOnCompoundStmt(ref Token l, ref Token r, StmtT[] stmts)
     {
-        StmtT[] array = stmts.dup;
-        Stmt[] statements = cast(Stmt[])array;
-        return new CompoundStatement(statements);
+        Stmt[] statements = cast(Stmt[])stmts;
+        return new CompoundStatement(statements.dup);
     }
 
     override StmtT actOnExprStmt(ExprT exp)
--- a/sema/DType.d	Thu Apr 24 19:42:53 2008 +0200
+++ b/sema/DType.d	Sat Apr 26 13:15:37 2008 +0200
@@ -1,9 +1,5 @@
 module sema.DType;
 
-import tango.text.Util : jhash;
-
-import LLVM = llvm.llvm;
-
 import lexer.Token,
        ast.Exp;
 
@@ -14,22 +10,19 @@
     private char[] id;
     private Location loc;
     public DType actual;
-    private LLVM.Type llvmType;
 
     this(Identifier id, DType actual = null)
     {
         Token temp = id.token;
         this.id = temp.get;
         this.loc = temp.location;
-        if (actual !is null)
-            this.actual = this;
+        this.actual = actual is null? this : actual;
     }
 
     this(char[] id, DType actual = null)
     {
         this.id = id;
-        if (actual !is null)
-            this.actual = this;
+        this.actual = actual is null? this : actual;
     }
 
     int opEquals(Object o)
@@ -46,6 +39,13 @@
         return 0;
     }
 
+    /**
+      Hashing is done by casting the reference to a void* and taking that
+      value, but this gives a bad distribution of hash-values.
+
+      Multiple DType's allocated close to each other will only have a
+      difference in the lower bits of their hashes.
+     */
     hash_t toHash()
     {
         return cast(hash_t)(cast(void*)this);
@@ -53,7 +53,6 @@
 
     char[] name() { return id; }
     Location getLoc() { return loc; }
-    LLVM.Type llvm() { return llvmType; }
     int byteSize() { return 0; }
 
     static DInteger
@@ -66,7 +65,6 @@
     static this()
     {
         Void   = new DType("void");
-        Void.llvmType = LLVM.Type.Void;
 
         Bool   = new DInteger("bool",    1, false);
         Byte   = new DInteger("byte",    8, false);
@@ -80,6 +78,9 @@
     }
 }
 
+/**
+  Class to represent the built-in integer types, from byte to long.
+ */
 class DInteger : DType
 {
     this(char[] name, int bits, bool unsigned)
@@ -87,7 +88,6 @@
         super(name, null);
         this.bits = bits;
         this.unsigned = unsigned;
-        llvmType = LLVM.IntegerType.Get(bits);
     }
 
     override int byteSize() { return bits / 8; }
@@ -109,17 +109,10 @@
     {
         this.members = members;
 
-        LLVM.Type[] types;
-
         foreach (type; members)
-        {
-            types ~= type.llvm;
             bytes_total += type.byteSize();
-        }
+    }
 
-        this.llvmType = LLVM.StructType.Get(types);
-
-    }
     DType[char[]] members;
     private int bytes_total;
 }
@@ -130,6 +123,7 @@
     {
         super(id, actual);
     }
+
     DType[] params;
     DType return_type;
 }