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;
+}