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