Mercurial > projects > ddmd
annotate dmd/interpret/Util.d @ 107:d8f19d85fadb
changes from interpret.c
author | Trass3r |
---|---|
date | Tue, 31 Aug 2010 18:18:31 +0200 |
parents | be2ab491772e |
children | e28b18c23469 |
rev | line source |
---|---|
63 | 1 module dmd.interpret.Util; |
2 | |
3 import dmd.StructDeclaration; | |
4 import dmd.Expression; | |
107 | 5 import dmd.FuncDeclaration; |
63 | 6 import dmd.InterState; |
7 import dmd.ArrayTypes; | |
8 import dmd.GlobalExpressions; | |
9 import dmd.TOK; | |
10 import dmd.AssocArrayLiteralExp; | |
11 import dmd.IntegerExp; | |
12 import dmd.Type; | |
13 import dmd.Declaration; | |
14 import dmd.Loc; | |
15 import dmd.ArrayLiteralExp; | |
16 import dmd.TypeAArray; | |
107 | 17 import dmd.TypeFunction; |
63 | 18 import dmd.TypeSArray; |
107 | 19 import dmd.TY; |
63 | 20 import dmd.STC; |
21 import dmd.SymbolDeclaration; | |
22 import dmd.StructLiteralExp; | |
23 import dmd.VarDeclaration; | |
24 import dmd.Util; | |
25 | |
107 | 26 version(DMDV1) |
27 { | |
63 | 28 Expression interpret_aaLen(InterState istate, Expressions arguments) |
29 { | |
107 | 30 if (!arguments || arguments.dim != 1) |
63 | 31 return null; |
107 | 32 auto earg = arguments[0]; |
33 earg = earg.interpret(istate); | |
34 if (earg is EXP_CANT_INTERPRET) | |
63 | 35 return null; |
107 | 36 if (earg.op != TOKassocarrayliteral) |
63 | 37 return null; |
107 | 38 auto aae = cast(AssocArrayLiteralExp)earg; |
39 auto e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t); | |
40 return e; | |
63 | 41 } |
42 | |
43 Expression interpret_aaKeys(InterState istate, Expressions arguments) | |
44 { | |
45 version (LOG) { | |
107 | 46 writef("interpret_aaKeys()\n"); |
63 | 47 } |
107 | 48 if (!arguments || arguments.dim != 2) |
63 | 49 return null; |
107 | 50 auto earg = arguments[0]; |
51 earg = earg.interpret(istate); | |
52 if (earg is EXP_CANT_INTERPRET) | |
63 | 53 return null; |
107 | 54 if (earg.op != TOKassocarrayliteral) |
63 | 55 return null; |
107 | 56 auto aae = cast(AssocArrayLiteralExp)earg; |
57 auto e = new ArrayLiteralExp(aae.loc, aae.keys); | |
58 Type elemType = (cast(TypeAArray)aae.type).index; | |
59 e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0)); | |
60 return e; | |
63 | 61 } |
62 | |
63 Expression interpret_aaValues(InterState istate, Expressions arguments) | |
64 { | |
107 | 65 //writef("interpret_aaValues()\n"); |
66 if (!arguments || arguments.dim != 3) | |
67 return null; | |
68 auto earg = arguments[0]; | |
69 earg = earg.interpret(istate); | |
70 if (earg is EXP_CANT_INTERPRET) | |
71 return null; | |
72 if (earg.op != TOKassocarrayliteral) | |
63 | 73 return null; |
107 | 74 auto aae = cast(AssocArrayLiteralExp)earg; |
75 auto e = new ArrayLiteralExp(aae.loc, aae.values); | |
76 Type elemType = (cast(TypeAArray)aae.type).next; | |
77 e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0)); | |
78 //writef("result is %s\n", e.toChars()); | |
79 return e; | |
80 } | |
81 } | |
82 else version(DMDV2) | |
83 { | |
84 Expression interpret_length(InterState istate, Expression earg) | |
85 { | |
86 // writef("interpret_length()\n"); | |
87 earg = earg.interpret(istate); | |
88 if (earg == EXP_CANT_INTERPRET) | |
89 return null; | |
90 if (earg.op != TOKassocarrayliteral) | |
63 | 91 return null; |
107 | 92 AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg; |
93 Expression e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t); | |
94 return e; | |
95 } | |
96 | |
97 Expression interpret_keys(InterState istate, Expression earg, FuncDeclaration fd) | |
98 { | |
99 version(LOG) | |
100 writef("interpret_keys()\n"); | |
101 | |
102 earg = earg.interpret(istate); | |
103 if (earg == EXP_CANT_INTERPRET) | |
104 return null; | |
105 if (earg.op != TOKassocarrayliteral) | |
106 return null; | |
107 AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg; | |
108 Expression e = new ArrayLiteralExp(aae.loc, aae.keys); | |
109 assert(fd.type.ty == Tfunction); | |
110 assert(fd.type.nextOf().ty == Tarray); | |
111 Type elemType = (cast(TypeFunction)fd.type).nextOf().nextOf(); | |
112 e.type = new TypeSArray(elemType, new IntegerExp(aae.keys.dim)); | |
113 return e; | |
114 } | |
115 Expression interpret_values(InterState istate, Expression earg, FuncDeclaration fd) | |
116 { | |
117 //writef("interpret_values()\n"); | |
118 earg = earg.interpret(istate); | |
119 if (earg == EXP_CANT_INTERPRET) | |
63 | 120 return null; |
107 | 121 if (earg.op != TOKassocarrayliteral) |
122 return null; | |
123 AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg; | |
124 Expression e = new ArrayLiteralExp(aae.loc, aae.values); | |
125 assert(fd.type.ty == Tfunction); | |
126 assert(fd.type.nextOf().ty == Tarray); | |
127 Type elemType = (cast(TypeFunction)fd.type).nextOf().nextOf(); | |
128 e.type = new TypeSArray(elemType, new IntegerExp(aae.values.dim)); | |
129 //writef("result is %s\n", e.toChars()); | |
130 return e; | |
131 } | |
63 | 132 } |
133 | |
134 Expression getVarExp(Loc loc, InterState istate, Declaration d) | |
135 { | |
107 | 136 Expression e = EXP_CANT_INTERPRET; |
137 VarDeclaration v = d.isVarDeclaration(); | |
138 SymbolDeclaration s = d.isSymbolDeclaration(); | |
139 if (v) | |
140 { | |
63 | 141 ///version (DMDV2) { |
142 if ((v.isConst() || v.isInvariant() || v.storage_class & STCmanifest) && v.init && !v.value) | |
143 ///} else { | |
144 /// if (v.isConst() && v.init) | |
145 ///} | |
146 { | |
147 e = v.init.toExpression(); | |
148 if (e && !e.type) | |
149 e.type = v.type; | |
150 } | |
151 else | |
152 { | |
153 e = v.value; | |
154 if (v.isDataseg()) | |
155 { | |
156 error(loc, "static variable %s cannot be read at compile time", v.toChars()); | |
157 e = EXP_CANT_INTERPRET; | |
158 } | |
159 else if (!e) | |
160 error(loc, "variable %s is used before initialization", v.toChars()); | |
161 else if (e !is EXP_CANT_INTERPRET) | |
162 e = e.interpret(istate); | |
163 } | |
164 if (!e) | |
165 e = EXP_CANT_INTERPRET; | |
107 | 166 } |
167 else if (s) | |
168 { | |
63 | 169 if (s.dsym.toInitializer() == s.sym) |
170 { | |
171 Expressions exps = new Expressions(); | |
172 e = new StructLiteralExp(Loc(0), s.dsym, exps); | |
173 e = e.semantic(null); | |
174 } | |
107 | 175 } |
176 return e; | |
63 | 177 } |
178 | |
179 /* Helper functions for BinExp.interpretAssignCommon | |
180 */ | |
181 | |
182 /*************************************** | |
183 * Duplicate the elements array, then set field 'indexToChange' = newelem. | |
184 */ | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
185 Expressions changeOneElement(Expressions oldelems, size_t indexToChange, Expression newelem) |
63 | 186 { |
107 | 187 auto expsx = new Expressions(); |
188 expsx.setDim(oldelems.dim); | |
189 for (size_t j = 0; j < expsx.dim; j++) | |
190 { | |
63 | 191 if (j == indexToChange) |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
192 expsx[j] = newelem; |
63 | 193 else |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
194 expsx[j] = oldelems[j]; |
107 | 195 } |
196 return expsx; | |
63 | 197 } |
198 | |
199 /*************************************** | |
200 * Returns oldelems[0..insertpoint] ~ newelems ~ oldelems[insertpoint..$] | |
201 */ | |
202 Expressions spliceElements(Expressions oldelems, Expressions newelems, size_t insertpoint) | |
203 { | |
107 | 204 auto expsx = new Expressions(); |
205 expsx.setDim(oldelems.dim); | |
206 for (size_t j = 0; j < expsx.dim; j++) | |
207 { | |
63 | 208 if (j >= insertpoint && j < insertpoint + newelems.dim) |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
209 expsx[j] = newelems[j - insertpoint]; |
63 | 210 else |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
211 expsx[j] = oldelems[j]; |
107 | 212 } |
213 return expsx; | |
63 | 214 } |
215 | |
216 /****************************** | |
217 * Create an array literal consisting of 'elem' duplicated 'dim' times. | |
218 */ | |
219 ArrayLiteralExp createBlockDuplicatedArrayLiteral(Type type, Expression elem, size_t dim) | |
220 { | |
107 | 221 auto elements = new Expressions(); |
222 elements.setDim(dim); | |
223 for (size_t i = 0; i < dim; i++) { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
224 elements[i] = elem; |
63 | 225 } |
226 | |
107 | 227 auto ae = new ArrayLiteralExp(Loc(0), elements); |
228 ae.type = type; | |
229 return ae; | |
63 | 230 } |
231 | |
232 | |
233 /******************************** | |
234 * Necessary because defaultInit() for a struct is a VarExp, not a StructLiteralExp. | |
235 */ | |
236 StructLiteralExp createDefaultInitStructLiteral(Loc loc, StructDeclaration sym) | |
237 { | |
107 | 238 Expressions structelems = new Expressions(); |
239 structelems.setDim(sym.fields.dim); | |
240 for (size_t j = 0; j < structelems.dim; j++) | |
241 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
242 structelems[j] = sym.fields[j].type.defaultInit(Loc(0)); |
107 | 243 } |
244 StructLiteralExp structinit = new StructLiteralExp(loc, sym, structelems); | |
245 // Why doesn't the StructLiteralExp constructor do this, when | |
246 // sym.type != null ? | |
247 structinit.type = sym.type; | |
248 return structinit; | |
63 | 249 } |
250 | |
251 /******************************** | |
252 * Add v to the istate list, unless it already exists there. | |
253 */ | |
254 void addVarToInterstate(InterState istate, VarDeclaration v) | |
255 { | |
107 | 256 if (!v.isParameter()) |
257 { | |
63 | 258 for (size_t i = 0; 1; i++) |
259 { | |
260 if (i == istate.vars.dim) | |
261 { | |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
63
diff
changeset
|
262 istate.vars.push(v); |
107 | 263 //writef("\tadding %s to istate\n", v.toChars()); |
63 | 264 break; |
265 } | |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
63
diff
changeset
|
266 if (v == cast(VarDeclaration)istate.vars[i]) |
63 | 267 break; |
268 } | |
107 | 269 } |
63 | 270 } |