Mercurial > projects > dang
view sema/DType.d @ 88:eb5b2c719a39 new_gen
Major change to locations, tokens and expressions.
A location (now SourceLocation or SLoc) is only 32 bit in size -
disadvantage is that it can't find its own text. You have to go through the
new SourceManager to do that.
This has caused changes to a lot of stuff and removal of DataSource and the
old Location
Additionally Exp has gotten some location stuff, so we can give proper
error messages. Not in Decl and Stmt yet, but thats coming too.
author | Anders Halager <halager@gmail.com> |
---|---|
date | Sun, 04 May 2008 18:13:46 +0200 |
parents | 9e90694f5da0 |
children | 438e6ed4cda1 |
line wrap: on
line source
module sema.DType; import lexer.Token, ast.Exp; import tango.io.Stdout; class DType { private char[] id; private SourceLocation loc; public DType actual; this(Identifier id, DType actual = null) { this.id = id.name; this.loc = id.startLoc(); this.actual = actual is null? this : actual; } this(char[] id, DType actual = null) { this.id = id; this.actual = actual is null? this : actual; } /// Is this type a DStruct bool isStruct() { return false; } /// Return a DStruct if this is one, otherwise return null DStruct asStruct() { return null; } /// Is this type a DArray bool isArray() { return false; } /// Return a DArray if this is one, otherwise return null DArray asArray() { return null; } /// Is this type a DPointer bool isPointer() { return false; } /// Return a DPointer if this is one, otherwise return null DPointer asPointer() { return null; } /// Is this type a DFunction bool isFunction() { return false; } /// Return a DFunction if this is one, otherwise return null DFunction asFunction() { return null; } /// Is this type a DInteger bool isInteger() { return false; } /// Return a DInteger if this is one, otherwise return null DInteger asInteger() { return null; } int opEquals(Object o) { if (auto t = cast(DType)o) return this.actual is t.actual; return 0; } int opCmp(Object o) { if (auto t = cast(DType)o) return cast(void*)this.actual - cast(void*)t.actual; 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); } char[] name() { return id; } SourceLocation 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; } /** Get a type representing a pointer to this type (from int to int*) */ DPointer getPointerTo() { if(myPointer !is null) return myPointer; myPointer = new DPointer(this); return myPointer; } private DPointer myPointer; /** Get a type representing a static array of this type with length 'size' */ DArray getAsArray(int size) { if(size in myArray) return myArray[size]; myArray[size] = new DArray(this, size); return myArray[size]; } private DArray[int] myArray; static DInteger Bool, Byte, UByte, Short, UShort, Int, UInt, Long, ULong; static DType Void; static this() { Void = new DType("void"); Bool = new DInteger("bool", 1, false); Byte = new DInteger("byte", 8, false); UByte = new DInteger("ubyte", 8, true); Short = new DInteger("short", 16, false); UShort = new DInteger("ushort", 16, true); Int = new DInteger("int", 32, false); UInt = new DInteger("uint", 32, true); Long = new DInteger("long", 64, false); ULong = new DInteger("ulong", 64, true); } } /** Class to represent the built-in integer types, from byte to long. */ class DInteger : DType { this(char[] name, int bits, bool unsigned) { super(name, null); this.bits = bits; this.unsigned = unsigned; } override int byteSize() { return bits / 8; } override bool hasImplicitConversionTo(DType that) { if (auto o = cast(DInteger)that) return true; // return this.bits >= o.bits; return false; } override bool isInteger() { return true; } override DInteger asInteger() { return this; } int bits; bool unsigned; } class DStruct : DType { this(Identifier id, DType actual = null) { super(id, actual); } int byteSize() { return bytes_total; } override bool isStruct() { return true; } override DStruct asStruct() { return this; } void addMember(DType type, char[] name) { auto s = DStructMember(type, members.length); members[name] = s; bytes_total += type.byteSize(); } int indexOf(char[] name) { if(name in members) return members[name].index; return -1; } DType typeOf(char[] name) { if (auto res = name in members) return res.type; return null; } DStructMember[char[]] members; private int bytes_total; struct DStructMember { DType type; int index; } } class DArray : DType { this(DType arrayOf, int size, DType actual = null) { super(id, actual); this.arrayOf = arrayOf; this.size = size; } override bool isArray() { return true; } override DArray asArray() { return this; } int byteSize() { return arrayOf.byteSize * size; } DType arrayOf; const int size; } class DPointer : DType { this(DType pointerOf, DType actual = null) { super(id, actual); this.pointerOf = pointerOf; } override bool isPointer() { return true; } override DPointer asPointer() { return this; } int byteSize() { return DType.Int.byteSize; } DType pointerOf; } class DFunction : DType { this(Identifier id, DType actual = null) { super(id, actual); } override bool isFunction() { return true; } override DFunction asFunction() { return this; } DType[] params; DType returnType; bool firstParamIsReturnValue = false; }