# HG changeset patch # User Anders Halager # Date 1209208537 -7200 # Node ID c7cde6af00955d8c105618701eddfca6182e3dce # Parent b6c1dc30ca4bedbcd458366cc3b9b1726597e95f Seperated the AST from LLVM * Changed SmallArray sligthly * Added a NullAction that doesn't do anything diff -r b6c1dc30ca4b -r c7cde6af0095 basic/SmallArray.d --- 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; } diff -r b6c1dc30ca4b -r c7cde6af0095 gen/LLVMGen.d --- 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; diff -r b6c1dc30ca4b -r c7cde6af0095 parser/Action.d --- 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) diff -r b6c1dc30ca4b -r c7cde6af0095 sema/DType.d --- 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; }