diff sema/TypeCheck.d @ 92:771ac63898e2 new_gen

A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
author Anders Johnsen <skabet@gmail.com>
date Mon, 05 May 2008 18:44:20 +0200
parents sema/ImplicitCast.d@eb5b2c719a39
children 189c049cbfcc
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sema/TypeCheck.d	Mon May 05 18:44:20 2008 +0200
@@ -0,0 +1,146 @@
+module sema.TypeCheck;
+
+import sema.Visitor,
+       sema.DType;
+
+import tango.io.Stdout;
+
+import misc.Error,
+       basic.SourceLocation;
+
+class TypeCheck : Visitor!(void)
+{
+    private Error error(uint line, char[] msg)
+    {
+        return new Error(msg);
+    }
+
+    override void visitBinaryExp(BinaryExp exp)
+    {
+        super.visitBinaryExp(exp);
+
+        if(exp.left.type.byteSize > exp.right.type.byteSize)
+        {
+            if(!exp.right.type.hasImplicitConversionTo(exp.left.type))
+                throw error(__LINE__, "Cannot make implicit cast");
+
+            auto castExp = new CastExp(
+                    SLoc.Invalid,
+                    new Identifier(exp.left.type.name),
+                    exp.right);
+            castExp.env = exp.env;
+            exp.right = castExp;
+        }
+
+        if(exp.left.type.byteSize < exp.right.type.byteSize)
+        {
+            if(!exp.left.type.hasImplicitConversionTo(exp.right.type))
+                throw error(__LINE__, "Cannot make implicit cast");
+
+            auto castExp = new CastExp(
+                    SLoc.Invalid,
+                    new Identifier(exp.right.type.name),
+                    exp.left);
+            castExp.env = exp.env;
+            exp.left = castExp;
+        }
+
+    }
+
+    override void visitCallExp(CallExp exp)
+    {
+        super.visitCallExp(exp);
+
+        Exp[] newArgs;
+
+        foreach(i, arg; exp.args)
+        {
+            auto argType = (cast(DFunction)exp.exp.type).params[i];
+            auto expType = arg.type;
+            if(argType.byteSize != expType.byteSize)
+            {
+                if(!expType.hasImplicitConversionTo(argType))
+                    throw error(__LINE__, "Cannot make implicit cast");
+
+                auto castExp = new CastExp(
+                        SLoc.Invalid,
+                        new Identifier(argType.name),
+                        arg);
+                castExp.env = exp.exp.env;
+                newArgs ~= castExp;
+            }
+            else
+                newArgs ~= arg;
+        }
+
+        exp.args = newArgs;
+    }
+
+    override void visitAssignExp(AssignExp exp)
+    {
+        super.visitAssignExp(exp);
+
+        auto identifierType = exp.identifier.type;
+        auto expType = exp.exp.type;
+
+        if(identifierType != expType)
+        {
+            if(!expType.hasImplicitConversionTo(identifierType))
+                throw error(__LINE__, "Cannot make implicit cast between");
+
+            auto castExp = new CastExp(
+                    SLoc.Invalid,
+                    new Identifier(expType.name),
+                    exp.exp);
+            castExp.env = exp.exp.env;
+            exp.exp = castExp;
+        }
+    }
+
+    override void visitReturnStmt(ReturnStmt stmt)
+    {
+        super.visitReturnStmt(stmt);
+
+        if(stmt.exp)
+        {
+            auto returnType = stmt.env.parentFunction.type.asFunction.returnType;
+            auto expType = stmt.exp.type;
+            if(returnType != expType)
+            {
+                if(!expType.hasImplicitConversionTo(returnType))
+                    throw error(__LINE__, "Cannot make implicit cast");
+
+                auto castExp = new CastExp(
+                        SLoc.Invalid,
+                        new Identifier(returnType.name),
+                        stmt.exp);
+                castExp.env = stmt.exp.env;
+                stmt.exp = castExp;
+            }
+        }
+    }
+
+    override void visitVarDecl(VarDecl decl)
+    {
+        super.visitVarDecl(decl);
+
+        if(decl.init)
+        {
+            auto varType = decl.type;
+            auto expType = decl.init.type;
+            if(varType.byteSize != expType.byteSize)
+            {
+                if(!expType.hasImplicitConversionTo(varType))
+                    throw error(__LINE__, "Cannot make implicit cast");
+
+                auto castExp = new CastExp(
+                        SLoc.Invalid,
+                        new Identifier(varType.name),
+                        decl.init);
+                castExp.env = decl.init.env;
+                decl.init = castExp;
+            }
+        }
+    }
+}
+