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