Mercurial > projects > dang
diff sema/BuildTypes.d @ 195:4e1a7265d620
Made a BuildTypes pass, to give all exp's a type.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Tue, 29 Jul 2008 15:50:24 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sema/BuildTypes.d Tue Jul 29 15:50:24 2008 +0200 @@ -0,0 +1,221 @@ +module sema.BuildTypes; + +import basic.LiteralParsing, + basic.Message; + +import sema.Visitor, + sema.Symbol, + sema.DType; + +import tango.io.Stdout; + + +class BuildTypes : Visitor!(void) +{ + this(MessageHandler messages) + { + this.messages = messages; + } + + override void visitCallExp(CallExp exp) + { + super.visitCallExp(exp); + DFunction f = exp.exp.type.asCallable(); + assert(f !is null, "Can only call functions"); + exp.type = f.returnType; + } + + override void visitAssignExp(AssignExp exp) + { + super.visitAssignExp(exp); + exp.type = exp.identifier.type; + } + + override void visitBinaryExp(BinaryExp exp) + { + super.visitBinaryExp(exp); + if (exp.op == BinaryExp.Operator.Eq || + exp.op == BinaryExp.Operator.Ne || + exp.op == BinaryExp.Operator.Lt || + exp.op == BinaryExp.Operator.Le || + exp.op == BinaryExp.Operator.Gt || + exp.op == BinaryExp.Operator.Ge) + { + exp.type = DType.Bool; + return; + } + + DType l = exp.left.type; + DType r = exp.right.type; + if (l.isSame(r)) + exp.type = l; + else if (l.hasImplicitConversionTo(r)) + exp.type = r; + else if (r.hasImplicitConversionTo(l)) + exp.type = l; + else + exp.type = DType.Int; //FIXME: Throw error here. + } + + override void visitNegateExp(NegateExp exp) + { + super.visitNegateExp(exp); + exp.type = exp.exp.type; + } + + override void visitDerefExp(DerefExp exp) + { + super.visitDerefExp(exp); + exp.type = exp.exp.type.asPointer().pointerOf; + } + + override void visitAddressOfExp(AddressOfExp exp) + { + super.visitAddressOfExp(exp); + exp.type = exp.exp.type.getPointerTo; + } + + override void visitIntegerLit(IntegerLit exp) + { + super.visitIntegerLit(exp); + switch(exp.number.type) + { + case NumberType.Int: + exp.type = DType.Int; + break; + case NumberType.Long: + exp.type = DType.Long; + break; + case NumberType.ULong: + exp.type = DType.ULong; + break; + case NumberType.Double: + exp.type = DType.Double; + break; + case NumberType.Real: + exp.type = DType.Real; + break; + } + } + + override void visitMemberReference(MemberReference exp) + { + super.visitMemberReference(exp); + if ( exp.target.type.isStruct ) + { + Symbol st = exp.target.getSymbol; + if (auto t = st.findMembers(exp.child.name)) + exp.type = t[0].type; +// else assert(0, "Referencing non-existant member"); + } + else if ( exp.target.type.isClass ) + { + Symbol cl = exp.target.getSymbol; + if (auto t = cl.findMembers(exp.child.name)) + exp.type = t[0].type; +// else assert(0, "Referencing non-existant member"); + } + else + assert(0, "Only structs and classes have members"); + // no error reporting here + } + + override void visitIndexExp(IndexExp exp) + { + super.visitIndexExp(exp); + DType type = exp.target.type; + if (type.isStaticArray()) + exp.type = type.asStaticArray().arrayOf; + else if (type.isPointer()) + exp.type = type.asPointer().pointerOf; + else assert(0, "Can only index pointers and arrays"); + } + + override void visitCastExp(CastExp exp) + { + super.visitCastExp(exp); + exp.type = exp.env.findType(exp.castType.get); + } + + override void visitStringExp(StringExp exp) + { + super.visitStringExp(exp); + switch (exp.data.type) + { + case StringType.Char: + exp.type = DType.Char.getAsStaticArray(exp.data.data.length); + break; + case StringType.WChar: + exp.type = DType.WChar.getAsStaticArray(exp.data.data.length/2); + break; + case StringType.DChar: + exp.type = DType.DChar.getAsStaticArray(exp.data.data.length/4); + break; + } + } + + override void visitNewExp(NewExp exp) + { + super.visitNewExp(exp); + exp.type = exp.env.findType(exp.newType.get); + } + + override void visitNullExp(NullExp exp) + { + super.visitNullExp(exp); + exp.type = new DPointer(DType.Int); + } + + override void visitIdentifier(Identifier exp) + { + super.visitIdentifier(exp); + if (auto sym = exp.getSymbol) + exp.type = sym.type; + else + exp.type = DType.Int; + } + +/* override void visitIdentifierTypeExp(IdentifierTypeExp exp) + { + if (auto sym = exp.getSymbol) + exp.type = sym.type; + else + exp.type = DType.Int; + }*/ + + override void visitPointerTypeExp(PointerTypeExp exp) + { + super.visitPointerTypeExp(exp); + exp.type = exp.pointerOf.type.getPointerTo(); + } + + override void visitStaticArrayTypeExp(StaticArrayTypeExp exp) + { + super.visitStaticArrayTypeExp(exp); + exp.type = exp.arrayOf.type.getAsStaticArray(exp.size); + } + +/* override void visitArrayTypeExp(ArrayTypeExp exp) + { + exp.type = arrayOf.type.getAsArray(); + }*/ + + override void visitFunctionTypeExp(FunctionTypeExp exp) + { + super.visitFunctionTypeExp(exp); + auto t = new DFunction(exp.returnType); + t.returnType = exp.returnType.type; + foreach (decl ; exp.decls) + t.params ~= decl.varType.type; + + exp.type = t.getPointerTo; + } + + override void visitArrayLiteralExp(ArrayLiteralExp exp) + { + super.visitArrayLiteralExp(exp); + exp.type = exp.exps[0].type.getAsStaticArray(exp.exps.length); + } + + MessageHandler messages; +}