Mercurial > projects > dang
diff sema/ImplicitCast.d @ 70:70a002b3fba4 new_gen
Added missing files and also cleaned up some Stdout debug-output.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Thu, 01 May 2008 19:30:51 +0200 |
parents | |
children | 682e20aa224f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sema/ImplicitCast.d Thu May 01 19:30:51 2008 +0200 @@ -0,0 +1,139 @@ +module sema.ImplicitCast; + +import sema.Visitor, + sema.DType; + +import tango.io.Stdout; + +import misc.Error; + +class ImplicitCast : 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( + 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( + 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( + 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.byteSize != expType.byteSize) + { + if(!expType.hasImplicitConversionTo(identifierType)) + throw error(__LINE__, "Cannot make implicit cast"); + + auto castExp = new CastExp( + 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 = (cast(DFunction)stmt.env.parentFunction.type).returnType; + auto expType = stmt.exp.type; + if(returnType.byteSize != expType.byteSize) + { + if(!expType.hasImplicitConversionTo(returnType)) + throw error(__LINE__, "Cannot make implicit cast"); + + auto castExp = new CastExp( + 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( + new Identifier(varType.name), + decl.init); + castExp.env = decl.init.env; + decl.init = castExp; + } + } + } +} +