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