Mercurial > projects > ddmd
annotate dmd/CatAssignExp.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.CatAssignExp; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.BinExp; |
5 import dmd.Loc; | |
6 import dmd.Expression; | |
7 import dmd.Scope; | |
8 import dmd.InterState; | |
9 import dmd.SliceExp; | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
10 import dmd.ErrorExp; |
0 | 11 import dmd.Identifier; |
12 import dmd.IRState; | |
13 import dmd.TOK; | |
14 import dmd.TY; | |
15 import dmd.Id; | |
16 import dmd.Type; | |
17 import dmd.backend.elem; | |
18 import dmd.backend.RTLSYM; | |
19 import dmd.backend.Util; | |
20 import dmd.backend.OPER; | |
21 import dmd.backend.TYM; | |
22 import dmd.backend.mTY; | |
23 | |
117 | 24 import dmd.expression.Cat; |
0 | 25 import dmd.expression.Util; |
26 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
27 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
|
28 |
0 | 29 class CatAssignExp : BinExp |
30 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
31 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
|
32 |
0 | 33 this(Loc loc, Expression e1, Expression e2) |
34 { | |
178 | 35 register(); |
36 | |
0 | 37 super(loc, TOK.TOKcatass, CatAssignExp.sizeof, e1, e2); |
38 } | |
39 | |
72 | 40 override Expression semantic(Scope sc) |
0 | 41 { |
42 Expression e; | |
43 | |
44 BinExp.semantic(sc); | |
45 e2 = resolveProperties(sc, e2); | |
46 | |
47 e = op_overload(sc); | |
48 if (e) | |
49 return e; | |
50 | |
51 if (e1.op == TOKslice) | |
52 { | |
53 SliceExp se = cast(SliceExp)e1; | |
54 | |
55 if (se.e1.type.toBasetype().ty == Tsarray) | |
56 error("cannot append to static array %s", se.e1.type.toChars()); | |
57 } | |
58 | |
59 e1 = e1.modifiableLvalue(sc, e1); | |
60 | |
61 Type tb1 = e1.type.toBasetype(); | |
62 Type tb2 = e2.type.toBasetype(); | |
63 | |
64 e2.rvalue(); | |
65 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
66 Type tb1next = tb1.nextOf(); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
67 |
0 | 68 if ((tb1.ty == Tarray) && |
69 (tb2.ty == Tarray || tb2.ty == Tsarray) && | |
70 (e2.implicitConvTo(e1.type) || | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
71 //version(DMDV2) { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
72 tb2.nextOf().implicitConvTo(tb1next) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
73 //} |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
74 ) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
75 |
0 | 76 ) |
77 { // Append array | |
78 e2 = e2.castTo(sc, e1.type); | |
79 type = e1.type; | |
80 e = this; | |
81 } | |
82 else if ((tb1.ty == Tarray) && | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
83 e2.implicitConvTo(tb1next) |
0 | 84 ) |
85 { // Append element | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
86 e2 = e2.castTo(sc, tb1next); |
0 | 87 type = e1.type; |
88 e = this; | |
89 } | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
90 else if (tb1.ty == Tarray && |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
91 (tb1next.ty == Tchar || tb1next.ty == Twchar) && |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
92 e2.implicitConvTo(Type.tdchar) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
93 ) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
94 { // Append dchar to char[] or wchar[] |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
95 e2 = e2.castTo(sc, Type.tdchar); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
96 type = e1.type; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
97 e = this; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
98 |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
99 /* Do not allow appending wchar to char[] because if wchar happens |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
100 * to be a surrogate pair, nothing good can result. |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
101 */ |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
102 } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
103 else |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
104 { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
105 error("cannot append type %s to type %s", tb2.toChars(), tb1.toChars()); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
106 e = new ErrorExp(); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
107 } |
0 | 108 return e; |
109 } | |
110 | |
72 | 111 override Expression interpret(InterState istate) |
0 | 112 { |
117 | 113 return interpretAssignCommon(istate, &Cat); |
0 | 114 } |
115 | |
72 | 116 override Identifier opId() /* For operator overloading */ |
0 | 117 { |
118 return Id.catass; | |
119 } | |
120 | |
72 | 121 override elem* toElem(IRState* irs) |
0 | 122 { |
123 //printf("CatAssignExp.toElem('%s')\n", toChars()); | |
124 elem* e; | |
125 Type tb1 = e1.type.toBasetype(); | |
126 Type tb2 = e2.type.toBasetype(); | |
127 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
128 if (tb1.ty == Tarray && tb2.ty == Tdchar && |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
129 (tb1.nextOf().ty == Tchar || tb1.nextOf().ty == Twchar)) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
130 { // Append dchar to char[] or wchar[] |
0 | 131 |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
132 auto e1 = this.e1.toElem(irs); |
0 | 133 e1 = el_una(OPaddr, TYnptr, e1); |
134 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
135 auto e2 = this.e2.toElem(irs); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
136 |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
137 auto ep = el_params(e2, e1, null); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
138 int rtl = (tb1.nextOf().ty == Tchar) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
139 ? RTLSYM_ARRAYAPPENDCD |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
140 : RTLSYM_ARRAYAPPENDWD; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
141 e = el_bin(OPcall, TYdarray, el_var(rtlsym[rtl]), ep); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
142 el_setLoc(e,loc); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
143 } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
144 else if (tb1.ty == Tarray || tb2.ty == Tsarray) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
145 { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
146 auto e1 = this.e1.toElem(irs); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
147 e1 = el_una(OPaddr, TYnptr, e1); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
148 |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
149 auto e2 = this.e2.toElem(irs); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
150 |
108
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
72
diff
changeset
|
151 if (tybasic(e2.Ety) == TYstruct || tybasic(e2.Ety) == TYarray) |
0 | 152 { |
153 e2 = el_una(OPstrpar, TYstruct, e2); | |
154 e2.Enumbytes = e2.E1.Enumbytes; | |
155 assert(e2.Enumbytes); | |
156 } | |
157 | |
158 Type tb1n = tb1.nextOf().toBasetype(); | |
159 if ((tb2.ty == Tarray || tb2.ty == Tsarray) && | |
160 tb1n.equals(tb2.nextOf().toBasetype())) | |
161 { // Append array | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
162 auto ep = el_params(e2, e1, this.e1.type.getTypeInfo(null).toElem(irs), null); |
0 | 163 e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDT]), ep); |
164 } | |
165 else | |
166 { // Append element | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
117
diff
changeset
|
167 auto ep = el_params(e2, e1, this.e1.type.getTypeInfo(null).toElem(irs), null); |
0 | 168 e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDCT]), ep); |
169 } | |
170 el_setLoc(e,loc); | |
171 } | |
172 else | |
173 assert(0); | |
174 | |
175 return e; | |
176 } | |
72 | 177 } |