Mercurial > projects > ddmd
diff dmd/Cast.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | cab4c37afb89 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/Cast.d Sat Oct 24 08:42:06 2009 +0400 @@ -0,0 +1,142 @@ +module dmd.Cast; + +import dmd.Expression; +import dmd.Type; +import dmd.Loc; +import dmd.MATCH; +import dmd.IntegerExp; +import dmd.RealExp; +import dmd.ComplexExp; +import dmd.StructDeclaration; +import dmd.ArrayTypes; +import dmd.Dsymbol; +import dmd.VarDeclaration; +import dmd.StructLiteralExp; +import dmd.Util; +import dmd.TY; +import dmd.TOK; +import dmd.GlobalExpressions; + +import dmd.Complex; + +Expression expType(Type type, Expression e) +{ + if (type !is e.type) + { + e = e.copy(); + e.type = type; + } + return e; +} + +/* Also returns EXP_CANT_INTERPRET if cannot be computed. + * to: type to cast to + * type: type to paint the result + */ + +Expression Cast(Type type, Type to, Expression e1) +{ + Expression e = EXP_CANT_INTERPRET; + Loc loc = e1.loc; + + //printf("Cast(type = %s, to = %s, e1 = %s)\n", type.toChars(), to.toChars(), e1.toChars()); + //printf("\te1.type = %s\n", e1.type.toChars()); + if (e1.type.equals(type) && type.equals(to)) + return e1; + if (e1.type.implicitConvTo(to) >= MATCH.MATCHconst || to.implicitConvTo(e1.type) >= MATCH.MATCHconst) + return expType(to, e1); + + Type tb = to.toBasetype(); + Type typeb = type.toBasetype(); + + /* Allow casting from one string type to another + */ + if (e1.op == TOK.TOKstring) + { + if (tb.ty == TY.Tarray && typeb.ty == TY.Tarray && + tb.nextOf().size() == typeb.nextOf().size()) + { + return expType(to, e1); + } + } + + if (e1.isConst() != 1) + return EXP_CANT_INTERPRET; + + if (tb.ty == TY.Tbool) + e = new IntegerExp(loc, e1.toInteger() != 0, type); + else if (type.isintegral()) + { + if (e1.type.isfloating()) + { + long result; + real r = e1.toReal(); + + switch (typeb.ty) + { + case TY.Tint8: result = cast(byte)r; break; + case TY.Tchar: + case TY.Tuns8: result = cast(ubyte)r; break; + case TY.Tint16: result = cast(short)r; break; + case TY.Twchar: + case TY.Tuns16: result = cast(ushort)r; break; + case TY.Tint32: result = cast(int)r; break; + case TY.Tdchar: + case TY.Tuns32: result = cast(uint)r; break; + case TY.Tint64: result = cast(long)r; break; + case TY.Tuns64: result = cast(ulong)r; break; + } + + e = new IntegerExp(loc, result, type); + } + else if (type.isunsigned()) + e = new IntegerExp(loc, e1.toUInteger(), type); + else + e = new IntegerExp(loc, e1.toInteger(), type); + } + else if (tb.isreal()) + { + real value = e1.toReal(); + e = new RealExp(loc, value, type); + } + else if (tb.isimaginary()) + { + real value = e1.toImaginary(); + e = new RealExp(loc, value, type); + } + else if (tb.iscomplex()) + { + Complex!(real) value = e1.toComplex(); + e = new ComplexExp(loc, value, type); + } + else if (tb.isscalar()) + e = new IntegerExp(loc, e1.toInteger(), type); + else if (tb.ty == TY.Tvoid) + e = EXP_CANT_INTERPRET; + else if (tb.ty == TY.Tstruct && e1.op == TOK.TOKint64) + { + // Struct = 0; + StructDeclaration sd = tb.toDsymbol(null).isStructDeclaration(); + assert(sd); + Expressions elements = new Expressions; + for (size_t i = 0; i < sd.fields.dim; i++) + { Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + VarDeclaration v = s.isVarDeclaration(); + assert(v); + + Expression exp = new IntegerExp(0); + exp = Cast(v.type, v.type, exp); + if (exp == EXP_CANT_INTERPRET) + return exp; + elements.push(cast(void*)exp); + } + e = new StructLiteralExp(loc, sd, elements); + e.type = type; + } + else + { + error(loc, "cannot cast %s to %s", e1.type.toChars(), type.toChars()); + e = new IntegerExp(loc, 0, Type.tint32); + } + return e; +} \ No newline at end of file