Mercurial > projects > ddmd
annotate dmd/AddAssignExp.d @ 117:fe941d774f4a
+ ctfe of assign operations
author | Trass3r |
---|---|
date | Thu, 02 Sep 2010 02:50:19 +0200 |
parents | e28b18c23469 |
children | 9e39c7de8438 |
rev | line source |
---|---|
0 | 1 module dmd.AddAssignExp; |
2 | |
114 | 3 import dmd.common; |
117 | 4 import dmd.expression.Add; |
0 | 5 import dmd.BinExp; |
6 import dmd.Loc; | |
7 import dmd.Expression; | |
8 import dmd.Scope; | |
9 import dmd.InterState; | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
10 import dmd.Argument; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
11 import dmd.STC; |
0 | 12 import dmd.OutBuffer; |
13 import dmd.ArrayTypes; | |
14 import dmd.Identifier; | |
15 import dmd.IRState; | |
16 import dmd.TOK; | |
17 import dmd.Type; | |
18 import dmd.TY; | |
19 import dmd.AddExp; | |
20 import dmd.CastExp; | |
21 import dmd.AssignExp; | |
22 import dmd.Global; | |
23 import dmd.Id; | |
24 | |
25 import dmd.backend.OPER; | |
26 import dmd.backend.elem; | |
27 | |
28 class AddAssignExp : BinExp | |
29 { | |
30 this(Loc loc, Expression e1, Expression e2) | |
31 { | |
32 super(loc, TOK.TOKaddass, AddAssignExp.sizeof, e1, e2); | |
33 } | |
34 | |
72 | 35 override Expression semantic(Scope sc) |
0 | 36 { |
37 Expression e; | |
38 | |
39 if (type) | |
40 return this; | |
41 | |
42 BinExp.semantic(sc); | |
43 e2 = resolveProperties(sc, e2); | |
44 | |
45 e = op_overload(sc); | |
46 if (e) | |
47 return e; | |
48 | |
49 Type tb1 = e1.type.toBasetype(); | |
50 Type tb2 = e2.type.toBasetype(); | |
51 | |
52 if (e1.op == TOK.TOKslice) | |
53 { | |
54 typeCombine(sc); | |
55 type = e1.type; | |
56 return arrayOp(sc); | |
57 } | |
58 else | |
59 { | |
60 e1 = e1.modifiableLvalue(sc, e1); | |
61 } | |
62 | |
63 if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray) && tb1.nextOf().equals(tb2.nextOf())) | |
64 { | |
65 type = e1.type; | |
66 typeCombine(sc); | |
67 e = this; | |
68 } | |
69 else | |
70 { | |
71 e1.checkScalar(); | |
72 e1.checkNoBool(); | |
73 if (tb1.ty == TY.Tpointer && tb2.isintegral()) | |
74 e = scaleFactor(sc); | |
75 else if (tb1.ty == TY.Tbit || tb1.ty == TY.Tbool) | |
76 { | |
77 static if (false) { | |
78 // Need to rethink this | |
79 if (e1.op != TOK.TOKvar) | |
80 { | |
81 // Rewrite e1+=e2 to (v=&e1),*v=*v+e2 | |
82 VarDeclaration v; | |
83 Expression ea; | |
84 Expression ex; | |
85 | |
86 Identifier id = Lexer.uniqueId("__name"); | |
87 | |
88 v = new VarDeclaration(loc, tb1.pointerTo(), id, null); | |
89 v.semantic(sc); | |
90 if (!sc.insert(v)) | |
91 assert(0); | |
92 | |
93 v.parent = sc.func; | |
94 | |
95 ea = new AddrExp(loc, e1); | |
96 ea = new AssignExp(loc, new VarExp(loc, v), ea); | |
97 | |
98 ex = new VarExp(loc, v); | |
99 ex = new PtrExp(loc, ex); | |
100 e = new AddExp(loc, ex, e2); | |
101 e = new CastExp(loc, e, e1.type); | |
102 e = new AssignExp(loc, ex.syntaxCopy(), e); | |
103 | |
104 e = new CommaExp(loc, ea, e); | |
105 } | |
106 else | |
107 { | |
108 // Rewrite e1+=e2 to e1=e1+e2 | |
109 // BUG: doesn't account for side effects in e1 | |
110 // BUG: other assignment operators for bits aren't handled at all | |
111 e = new AddExp(loc, e1, e2); | |
112 e = new CastExp(loc, e, e1.type); | |
113 e = new AssignExp(loc, e1.syntaxCopy(), e); | |
114 } | |
115 } else { | |
116 // Rewrite e1+=e2 to e1=e1+e2 | |
117 // BUG: doesn't account for side effects in e1 | |
118 // BUG: other assignment operators for bits aren't handled at all | |
119 e = new AddExp(loc, e1, e2); | |
120 e = new CastExp(loc, e, e1.type); | |
121 e = new AssignExp(loc, e1.syntaxCopy(), e); | |
122 } | |
123 e = e.semantic(sc); | |
124 } | |
125 else | |
126 { | |
127 type = e1.type; | |
128 typeCombine(sc); | |
129 e1.checkArithmetic(); | |
130 e2.checkArithmetic(); | |
73 | 131 checkComplexAddAssign(); |
0 | 132 |
133 if (type.isreal() || type.isimaginary()) | |
134 { | |
135 assert(global.errors || e2.type.isfloating()); | |
136 e2 = e2.castTo(sc, e1.type); | |
137 } | |
138 e = this; | |
139 } | |
140 } | |
141 return e; | |
142 } | |
143 | |
72 | 144 override Expression interpret(InterState istate) |
0 | 145 { |
117 | 146 return interpretAssignCommon(istate, &Add); |
0 | 147 } |
148 | |
72 | 149 override void buildArrayIdent(OutBuffer buf, Expressions arguments) |
0 | 150 { |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
151 AssignExp_buildArrayIdent(buf, arguments, "Add"); |
0 | 152 } |
153 | |
72 | 154 override Expression buildArrayLoop(Arguments fparams) |
0 | 155 { |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
156 /* Evaluate assign expressions right to left |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
157 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
158 Expression ex2 = e2.buildArrayLoop(fparams); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
159 Expression ex1 = e1.buildArrayLoop(fparams); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
160 Argument param = cast(Argument)fparams.data[0]; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
161 param.storageClass = STCundefined; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
162 Expression e = new AddAssignExp(Loc(0), ex1, ex2); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
163 return e; |
0 | 164 } |
165 | |
72 | 166 override Identifier opId() /* For operator overloading */ |
0 | 167 { |
168 return Id.addass; | |
169 } | |
170 | |
72 | 171 override elem* toElem(IRState* irs) |
0 | 172 { |
173 //printf("AddAssignExp::toElem() %s\n", toChars()); | |
174 elem *e; | |
175 Type tb1 = e1.type.toBasetype(); | |
176 Type tb2 = e2.type.toBasetype(); | |
177 | |
178 if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray)) | |
179 { | |
180 error("Array operations not implemented"); | |
181 } | |
182 else | |
183 e = toElemBin(irs, OPER.OPaddass); | |
184 | |
185 return e; | |
186 } | |
72 | 187 } |