comparison dmd/Cast.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children cab4c37afb89
comparison
equal deleted inserted replaced
-1:000000000000 0:10317f0c89a5
1 module dmd.Cast;
2
3 import dmd.Expression;
4 import dmd.Type;
5 import dmd.Loc;
6 import dmd.MATCH;
7 import dmd.IntegerExp;
8 import dmd.RealExp;
9 import dmd.ComplexExp;
10 import dmd.StructDeclaration;
11 import dmd.ArrayTypes;
12 import dmd.Dsymbol;
13 import dmd.VarDeclaration;
14 import dmd.StructLiteralExp;
15 import dmd.Util;
16 import dmd.TY;
17 import dmd.TOK;
18 import dmd.GlobalExpressions;
19
20 import dmd.Complex;
21
22 Expression expType(Type type, Expression e)
23 {
24 if (type !is e.type)
25 {
26 e = e.copy();
27 e.type = type;
28 }
29 return e;
30 }
31
32 /* Also returns EXP_CANT_INTERPRET if cannot be computed.
33 * to: type to cast to
34 * type: type to paint the result
35 */
36
37 Expression Cast(Type type, Type to, Expression e1)
38 {
39 Expression e = EXP_CANT_INTERPRET;
40 Loc loc = e1.loc;
41
42 //printf("Cast(type = %s, to = %s, e1 = %s)\n", type.toChars(), to.toChars(), e1.toChars());
43 //printf("\te1.type = %s\n", e1.type.toChars());
44 if (e1.type.equals(type) && type.equals(to))
45 return e1;
46 if (e1.type.implicitConvTo(to) >= MATCH.MATCHconst || to.implicitConvTo(e1.type) >= MATCH.MATCHconst)
47 return expType(to, e1);
48
49 Type tb = to.toBasetype();
50 Type typeb = type.toBasetype();
51
52 /* Allow casting from one string type to another
53 */
54 if (e1.op == TOK.TOKstring)
55 {
56 if (tb.ty == TY.Tarray && typeb.ty == TY.Tarray &&
57 tb.nextOf().size() == typeb.nextOf().size())
58 {
59 return expType(to, e1);
60 }
61 }
62
63 if (e1.isConst() != 1)
64 return EXP_CANT_INTERPRET;
65
66 if (tb.ty == TY.Tbool)
67 e = new IntegerExp(loc, e1.toInteger() != 0, type);
68 else if (type.isintegral())
69 {
70 if (e1.type.isfloating())
71 {
72 long result;
73 real r = e1.toReal();
74
75 switch (typeb.ty)
76 {
77 case TY.Tint8: result = cast(byte)r; break;
78 case TY.Tchar:
79 case TY.Tuns8: result = cast(ubyte)r; break;
80 case TY.Tint16: result = cast(short)r; break;
81 case TY.Twchar:
82 case TY.Tuns16: result = cast(ushort)r; break;
83 case TY.Tint32: result = cast(int)r; break;
84 case TY.Tdchar:
85 case TY.Tuns32: result = cast(uint)r; break;
86 case TY.Tint64: result = cast(long)r; break;
87 case TY.Tuns64: result = cast(ulong)r; break;
88 }
89
90 e = new IntegerExp(loc, result, type);
91 }
92 else if (type.isunsigned())
93 e = new IntegerExp(loc, e1.toUInteger(), type);
94 else
95 e = new IntegerExp(loc, e1.toInteger(), type);
96 }
97 else if (tb.isreal())
98 {
99 real value = e1.toReal();
100 e = new RealExp(loc, value, type);
101 }
102 else if (tb.isimaginary())
103 {
104 real value = e1.toImaginary();
105 e = new RealExp(loc, value, type);
106 }
107 else if (tb.iscomplex())
108 {
109 Complex!(real) value = e1.toComplex();
110 e = new ComplexExp(loc, value, type);
111 }
112 else if (tb.isscalar())
113 e = new IntegerExp(loc, e1.toInteger(), type);
114 else if (tb.ty == TY.Tvoid)
115 e = EXP_CANT_INTERPRET;
116 else if (tb.ty == TY.Tstruct && e1.op == TOK.TOKint64)
117 {
118 // Struct = 0;
119 StructDeclaration sd = tb.toDsymbol(null).isStructDeclaration();
120 assert(sd);
121 Expressions elements = new Expressions;
122 for (size_t i = 0; i < sd.fields.dim; i++)
123 { Dsymbol s = cast(Dsymbol)sd.fields.data[i];
124 VarDeclaration v = s.isVarDeclaration();
125 assert(v);
126
127 Expression exp = new IntegerExp(0);
128 exp = Cast(v.type, v.type, exp);
129 if (exp == EXP_CANT_INTERPRET)
130 return exp;
131 elements.push(cast(void*)exp);
132 }
133 e = new StructLiteralExp(loc, sd, elements);
134 e.type = type;
135 }
136 else
137 {
138 error(loc, "cannot cast %s to %s", e1.type.toChars(), type.toChars());
139 e = new IntegerExp(loc, 0, Type.tint32);
140 }
141 return e;
142 }