# HG changeset patch # User Anders Halager # Date 1209412299 -7200 # Node ID fc62c5296a1cc6419a6cc81443f5070c2a8434cb # Parent 43bb0a36b869f944ccaa519f808d71ad9949203b Add types to our Exp diff -r 43bb0a36b869 -r fc62c5296a1c ast/Exp.d --- 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; } - diff -r 43bb0a36b869 -r fc62c5296a1c gen/CodeGen.d --- 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; } diff -r 43bb0a36b869 -r fc62c5296a1c sema/DType.d --- 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;