Mercurial > projects > ddmd
annotate dmd/AddAssignExp.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
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; | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
10 import dmd.Parameter; |
12
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; | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
24 import dmd.ArrayLengthExp; |
0 | 25 |
26 import dmd.backend.OPER; | |
27 import dmd.backend.elem; | |
28 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
29 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
30 |
0 | 31 class AddAssignExp : BinExp |
32 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
33 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
34 |
0 | 35 this(Loc loc, Expression e1, Expression e2) |
36 { | |
178 | 37 register(); |
0 | 38 super(loc, TOK.TOKaddass, AddAssignExp.sizeof, e1, e2); |
39 } | |
40 | |
72 | 41 override Expression semantic(Scope sc) |
0 | 42 { |
43 Expression e; | |
44 | |
45 if (type) | |
46 return this; | |
47 | |
48 BinExp.semantic(sc); | |
49 e2 = resolveProperties(sc, e2); | |
50 | |
51 e = op_overload(sc); | |
52 if (e) | |
53 return e; | |
54 | |
55 Type tb1 = e1.type.toBasetype(); | |
56 Type tb2 = e2.type.toBasetype(); | |
57 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
58 if (e1.op == TOKarraylength) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
59 { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
60 e = ArrayLengthExp.rewriteOpAssign(this); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
61 e = e.semantic(sc); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
62 return e; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
63 } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
64 |
0 | 65 if (e1.op == TOK.TOKslice) |
66 { | |
67 typeCombine(sc); | |
68 type = e1.type; | |
69 return arrayOp(sc); | |
70 } | |
71 else | |
72 { | |
73 e1 = e1.modifiableLvalue(sc, e1); | |
74 } | |
75 | |
76 if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray) && tb1.nextOf().equals(tb2.nextOf())) | |
77 { | |
78 type = e1.type; | |
79 typeCombine(sc); | |
80 e = this; | |
81 } | |
82 else | |
83 { | |
84 e1.checkScalar(); | |
85 e1.checkNoBool(); | |
86 if (tb1.ty == TY.Tpointer && tb2.isintegral()) | |
87 e = scaleFactor(sc); | |
88 else if (tb1.ty == TY.Tbit || tb1.ty == TY.Tbool) | |
89 { | |
90 static if (false) { | |
91 // Need to rethink this | |
92 if (e1.op != TOK.TOKvar) | |
93 { | |
94 // Rewrite e1+=e2 to (v=&e1),*v=*v+e2 | |
95 VarDeclaration v; | |
96 Expression ea; | |
97 Expression ex; | |
98 | |
99 Identifier id = Lexer.uniqueId("__name"); | |
100 | |
101 v = new VarDeclaration(loc, tb1.pointerTo(), id, null); | |
102 v.semantic(sc); | |
103 if (!sc.insert(v)) | |
104 assert(0); | |
105 | |
106 v.parent = sc.func; | |
107 | |
108 ea = new AddrExp(loc, e1); | |
109 ea = new AssignExp(loc, new VarExp(loc, v), ea); | |
110 | |
111 ex = new VarExp(loc, v); | |
112 ex = new PtrExp(loc, ex); | |
113 e = new AddExp(loc, ex, e2); | |
114 e = new CastExp(loc, e, e1.type); | |
115 e = new AssignExp(loc, ex.syntaxCopy(), e); | |
116 | |
117 e = new CommaExp(loc, ea, e); | |
118 } | |
119 else | |
120 { | |
121 // Rewrite e1+=e2 to e1=e1+e2 | |
122 // BUG: doesn't account for side effects in e1 | |
123 // BUG: other assignment operators for bits aren't handled at all | |
124 e = new AddExp(loc, e1, e2); | |
125 e = new CastExp(loc, e, e1.type); | |
126 e = new AssignExp(loc, e1.syntaxCopy(), e); | |
127 } | |
128 } else { | |
129 // Rewrite e1+=e2 to e1=e1+e2 | |
130 // BUG: doesn't account for side effects in e1 | |
131 // BUG: other assignment operators for bits aren't handled at all | |
132 e = new AddExp(loc, e1, e2); | |
133 e = new CastExp(loc, e, e1.type); | |
134 e = new AssignExp(loc, e1.syntaxCopy(), e); | |
135 } | |
136 e = e.semantic(sc); | |
137 } | |
138 else | |
139 { | |
140 type = e1.type; | |
141 typeCombine(sc); | |
142 e1.checkArithmetic(); | |
143 e2.checkArithmetic(); | |
73 | 144 checkComplexAddAssign(); |
0 | 145 |
146 if (type.isreal() || type.isimaginary()) | |
147 { | |
148 assert(global.errors || e2.type.isfloating()); | |
149 e2 = e2.castTo(sc, e1.type); | |
150 } | |
151 e = this; | |
152 } | |
153 } | |
154 return e; | |
155 } | |
156 | |
72 | 157 override Expression interpret(InterState istate) |
0 | 158 { |
117 | 159 return interpretAssignCommon(istate, &Add); |
0 | 160 } |
161 | |
72 | 162 override void buildArrayIdent(OutBuffer buf, Expressions arguments) |
0 | 163 { |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
164 AssignExp_buildArrayIdent(buf, arguments, "Add"); |
0 | 165 } |
166 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
167 override Expression buildArrayLoop(Parameters fparams) |
0 | 168 { |
123 | 169 return AssignExp_buildArrayLoop!(typeof(this))(fparams); |
0 | 170 } |
171 | |
72 | 172 override Identifier opId() /* For operator overloading */ |
0 | 173 { |
174 return Id.addass; | |
175 } | |
176 | |
72 | 177 override elem* toElem(IRState* irs) |
0 | 178 { |
179 //printf("AddAssignExp::toElem() %s\n", toChars()); | |
180 elem *e; | |
181 Type tb1 = e1.type.toBasetype(); | |
182 Type tb2 = e2.type.toBasetype(); | |
183 | |
184 if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray)) | |
185 { | |
186 error("Array operations not implemented"); | |
187 } | |
188 else | |
189 e = toElemBin(irs, OPER.OPaddass); | |
190 | |
191 return e; | |
192 } | |
72 | 193 } |