Mercurial > projects > dang
view 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 source
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; }