comparison dmd2/interpret.c @ 1577:e4f7b5d9c68a

DMD 2.032 Merge.
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 08 Sep 2009 10:07:56 +0100
parents 54b3c1394d62
children
comparison
equal deleted inserted replaced
1576:4551475bc6b6 1577:e4f7b5d9c68a
1 1
2 // Compiler implementation of the D programming language 2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars 3 // Copyright (c) 1999-2009 by Digital Mars
4 // All Rights Reserved 4 // All Rights Reserved
5 // written by Walter Bright 5 // written by Walter Bright
6 // http://www.digitalmars.com 6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License 7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 // in artistic.txt, or the GNU General Public License in gnu.txt.
32 InterState *caller; // calling function's InterState 32 InterState *caller; // calling function's InterState
33 FuncDeclaration *fd; // function being interpreted 33 FuncDeclaration *fd; // function being interpreted
34 Dsymbols vars; // variables used in this function 34 Dsymbols vars; // variables used in this function
35 Statement *start; // if !=NULL, start execution at this statement 35 Statement *start; // if !=NULL, start execution at this statement
36 Statement *gotoTarget; // target of EXP_GOTO_INTERPRET result 36 Statement *gotoTarget; // target of EXP_GOTO_INTERPRET result
37 Expression *localThis; // value of 'this', or NULL if none
37 38
38 InterState(); 39 InterState();
39 }; 40 };
40 41
41 InterState::InterState() 42 InterState::InterState()
48 Expression *interpret_aaValues(InterState *istate, Expressions *arguments); 49 Expression *interpret_aaValues(InterState *istate, Expressions *arguments);
49 50
50 /************************************* 51 /*************************************
51 * Attempt to interpret a function given the arguments. 52 * Attempt to interpret a function given the arguments.
52 * Input: 53 * Input:
53 * istate state for calling function (NULL if none) 54 * istate state for calling function (NULL if none)
55 * arguments function arguments
56 * thisarg 'this', if a needThis() function, NULL if not.
57 *
54 * Return result expression if successful, NULL if not. 58 * Return result expression if successful, NULL if not.
55 */ 59 */
56 60
57 Expression *FuncDeclaration::interpret(InterState *istate, Expressions *arguments) 61 Expression *FuncDeclaration::interpret(InterState *istate, Expressions *arguments, Expression *thisarg)
58 { 62 {
59 #if LOG 63 #if LOG
60 printf("\n********\nFuncDeclaration::interpret(istate = %p) %s\n", istate, toChars()); 64 printf("\n********\nFuncDeclaration::interpret(istate = %p) %s\n", istate, toChars());
61 printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret, semanticRun); 65 printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret, semanticRun);
62 #endif 66 #endif
70 return interpret_aaValues(istate, arguments); 74 return interpret_aaValues(istate, arguments);
71 75
72 if (cantInterpret || semanticRun == 3) 76 if (cantInterpret || semanticRun == 3)
73 return NULL; 77 return NULL;
74 78
75 if (needThis() || isNested() || !fbody) 79 if (!fbody)
76 { cantInterpret = 1; 80 { cantInterpret = 1;
77 return NULL; 81 return NULL;
78 } 82 }
79 83
80 if (semanticRun < 3 && scope) 84 if (semanticRun < 3 && scope)
88 92
89 Type *tb = type->toBasetype(); 93 Type *tb = type->toBasetype();
90 assert(tb->ty == Tfunction); 94 assert(tb->ty == Tfunction);
91 TypeFunction *tf = (TypeFunction *)tb; 95 TypeFunction *tf = (TypeFunction *)tb;
92 Type *tret = tf->next->toBasetype(); 96 Type *tret = tf->next->toBasetype();
93 if (tf->varargs /*|| tret->ty == Tvoid*/) 97 if (tf->varargs)
94 { cantInterpret = 1; 98 { cantInterpret = 1;
99 error("Variadic functions are not yet implemented in CTFE");
95 return NULL; 100 return NULL;
96 } 101 }
97 102
103 // Ensure there are no lazy parameters
98 if (tf->parameters) 104 if (tf->parameters)
99 { size_t dim = Argument::dim(tf->parameters); 105 { size_t dim = Argument::dim(tf->parameters);
100 for (size_t i = 0; i < dim; i++) 106 for (size_t i = 0; i < dim; i++)
101 { Argument *arg = Argument::getNth(tf->parameters, i); 107 { Argument *arg = Argument::getNth(tf->parameters, i);
102 if (arg->storageClass & STClazy) 108 if (arg->storageClass & STClazy)
107 } 113 }
108 114
109 InterState istatex; 115 InterState istatex;
110 istatex.caller = istate; 116 istatex.caller = istate;
111 istatex.fd = this; 117 istatex.fd = this;
118 istatex.localThis = thisarg;
112 119
113 Expressions vsave; // place to save previous parameter values 120 Expressions vsave; // place to save previous parameter values
114 size_t dim = 0; 121 size_t dim = 0;
122 if (needThis() && !thisarg)
123 { cantInterpret = 1;
124 // error, no this. Prevent segfault.
125 error("need 'this' to access member %s", toChars());
126 return NULL;
127 }
115 if (arguments) 128 if (arguments)
116 { 129 {
117 dim = arguments->dim; 130 dim = arguments->dim;
118 assert(!dim || parameters->dim == dim); 131 assert(!dim || (parameters && (parameters->dim == dim)));
119 vsave.setDim(dim); 132 vsave.setDim(dim);
120 133
121 /* Evaluate all the arguments to the function, 134 /* Evaluate all the arguments to the function,
122 * store the results in eargs[] 135 * store the results in eargs[]
123 */ 136 */
142 */ 155 */
143 earg = ((AddrExp *)earg)->e1; 156 earg = ((AddrExp *)earg)->e1;
144 } 157 }
145 earg = earg->interpret(istate ? istate : &istatex); 158 earg = earg->interpret(istate ? istate : &istatex);
146 if (earg == EXP_CANT_INTERPRET) 159 if (earg == EXP_CANT_INTERPRET)
160 { cantInterpret = 1;
147 return NULL; 161 return NULL;
162 }
148 } 163 }
149 eargs.data[i] = earg; 164 eargs.data[i] = earg;
150 } 165 }
151 166
152 for (size_t i = 0; i < dim; i++) 167 for (size_t i = 0; i < dim; i++)
155 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 170 VarDeclaration *v = (VarDeclaration *)parameters->data[i];
156 vsave.data[i] = v->value; 171 vsave.data[i] = v->value;
157 #if LOG 172 #if LOG
158 printf("arg[%d] = %s\n", i, earg->toChars()); 173 printf("arg[%d] = %s\n", i, earg->toChars());
159 #endif 174 #endif
160 if (arg->storageClass & (STCout | STCref)) 175 if (arg->storageClass & (STCout | STCref) && earg->op==TOKvar)
161 { 176 {
162 /* Bind out or ref parameter to the corresponding 177 /* Bind out or ref parameter to the corresponding
163 * variable v2 178 * variable v2
164 */ 179 */
165 if (!istate || earg->op != TOKvar) 180 if (!istate)
181 { cantInterpret = 1;
182 error("%s cannot be by passed by reference at compile time", earg->toChars());
166 return NULL; // can't bind to non-interpreted vars 183 return NULL; // can't bind to non-interpreted vars
167 184 }
185 // We need to chase down all of the the passed parameters until
186 // we find something that isn't a TOKvar, then create a variable
187 // containg that expression.
168 VarDeclaration *v2; 188 VarDeclaration *v2;
169 while (1) 189 while (1)
170 { 190 {
171 VarExp *ve = (VarExp *)earg; 191 VarExp *ve = (VarExp *)earg;
172 v2 = ve->var->isVarDeclaration(); 192 v2 = ve->var->isVarDeclaration();
173 if (!v2) 193 if (!v2)
194 { cantInterpret = 1;
174 return NULL; 195 return NULL;
196 }
175 if (!v2->value || v2->value->op != TOKvar) 197 if (!v2->value || v2->value->op != TOKvar)
176 break; 198 break;
199 if (((VarExp *)v2->value)->var->isStaticStructInitDeclaration())
200 { // This can happen if v is a struct initialized to
201 // 0 using an __initZ StaticStructInitDeclaration from
202 // TypeStruct::defaultInit()
203 break; // eg default-initialized variable
204 }
177 earg = v2->value; 205 earg = v2->value;
178 } 206 }
179 207
180 v->value = new VarExp(earg->loc, v2); 208 v->value = new VarExp(earg->loc, v2);
181 209
189 break; 217 break;
190 } 218 }
191 } 219 }
192 } 220 }
193 else 221 else
194 { /* Value parameters 222 { // Value parameters and non-trivial references
195 */
196 v->value = earg; 223 v->value = earg;
197 } 224 }
198 #if LOG 225 #if LOG
199 printf("interpreted arg[%d] = %s\n", i, earg->toChars()); 226 printf("interpreted arg[%d] = %s\n", i, earg->toChars());
200 #endif 227 #endif
228 }
229 }
230 // Don't restore the value of 'this' upon function return
231 if (needThis() && thisarg->op==TOKvar) {
232 VarDeclaration *thisvar = ((VarExp *)(thisarg))->var->isVarDeclaration();
233 for (size_t i = 0; i < istate->vars.dim; i++)
234 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
235 if (v == thisvar)
236 { istate->vars.data[i] = NULL;
237 break;
238 }
201 } 239 }
202 } 240 }
203 241
204 /* Save the values of the local variables used 242 /* Save the values of the local variables used
205 */ 243 */
206 Expressions valueSaves; 244 Expressions valueSaves;
207 if (istate) 245 if (istate && !isNested())
208 { 246 {
209 //printf("saving local variables...\n"); 247 //printf("saving local variables...\n");
210 valueSaves.setDim(istate->vars.dim); 248 valueSaves.setDim(istate->vars.dim);
211 for (size_t i = 0; i < istate->vars.dim; i++) 249 for (size_t i = 0; i < istate->vars.dim; i++)
212 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; 250 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
218 } 256 }
219 } 257 }
220 } 258 }
221 259
222 Expression *e = NULL; 260 Expression *e = NULL;
223
224 while (1) 261 while (1)
225 { 262 {
226 e = fbody->interpret(&istatex); 263 e = fbody->interpret(&istatex);
227 if (e == EXP_CANT_INTERPRET) 264 if (e == EXP_CANT_INTERPRET)
228 { 265 {
244 istatex.gotoTarget = NULL; 281 istatex.gotoTarget = NULL;
245 } 282 }
246 else 283 else
247 break; 284 break;
248 } 285 }
249
250 /* Restore the parameter values 286 /* Restore the parameter values
251 */ 287 */
252 for (size_t i = 0; i < dim; i++) 288 for (size_t i = 0; i < dim; i++)
253 { 289 {
254 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 290 VarDeclaration *v = (VarDeclaration *)parameters->data[i];
255 v->value = (Expression *)vsave.data[i]; 291 v->value = (Expression *)vsave.data[i];
256 } 292 }
257 293
258 if (istate) 294 if (istate && !isNested())
259 { 295 {
260 /* Restore the variable values 296 /* Restore the variable values
261 */ 297 */
262 //printf("restoring local variables...\n"); 298 //printf("restoring local variables...\n");
263 for (size_t i = 0; i < istate->vars.dim; i++) 299 for (size_t i = 0; i < istate->vars.dim; i++)
266 { v->value = (Expression *)valueSaves.data[i]; 302 { v->value = (Expression *)valueSaves.data[i];
267 //printf("\trestoring [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : ""); 303 //printf("\trestoring [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : "");
268 } 304 }
269 } 305 }
270 } 306 }
271
272 return e; 307 return e;
273 } 308 }
274 309
275 /******************************** Statement ***************************/ 310 /******************************** Statement ***************************/
276 311
476 return NULL; 511 return NULL;
477 if (e == EXP_CANT_INTERPRET) 512 if (e == EXP_CANT_INTERPRET)
478 return e; 513 return e;
479 if (e == EXP_BREAK_INTERPRET) 514 if (e == EXP_BREAK_INTERPRET)
480 return NULL; 515 return NULL;
481 if (e != EXP_CONTINUE_INTERPRET) 516 if (e && e != EXP_CONTINUE_INTERPRET)
482 return e; 517 return e;
483 } 518 }
484 519
485 while (1) 520 while (1)
486 { 521 {
756 { 791 {
757 key->value = elwr; 792 key->value = elwr;
758 793
759 while (1) 794 while (1)
760 { 795 {
761 e = Cmp(TOKlt, key->value->type, key->value, upr); 796 e = Cmp(TOKlt, key->value->type, key->value, eupr);
762 if (e == EXP_CANT_INTERPRET) 797 if (e == EXP_CANT_INTERPRET)
763 break; 798 break;
764 if (e->isBool(TRUE) == FALSE) 799 if (e->isBool(TRUE) == FALSE)
765 { e = NULL; 800 { e = NULL;
766 break; 801 break;
771 break; 806 break;
772 if (e == EXP_BREAK_INTERPRET) 807 if (e == EXP_BREAK_INTERPRET)
773 { e = NULL; 808 { e = NULL;
774 break; 809 break;
775 } 810 }
776 e = Add(key->value->type, key->value, new IntegerExp(loc, 1, key->value->type)); 811 if (e == NULL || e == EXP_CONTINUE_INTERPRET)
777 if (e == EXP_CANT_INTERPRET) 812 { e = Add(key->value->type, key->value, new IntegerExp(loc, 1, key->value->type));
778 break; 813 if (e == EXP_CANT_INTERPRET)
779 key->value = e; 814 break;
815 key->value = e;
816 }
817 else
818 break;
780 } 819 }
781 } 820 }
782 else // TOKforeach_reverse 821 else // TOKforeach_reverse
783 { 822 {
784 key->value = eupr; 823 key->value = eupr;
785 824
786 while (1) 825 do
787 { 826 {
788 e = Cmp(TOKgt, key->value->type, key->value, lwr); 827 e = Cmp(TOKgt, key->value->type, key->value, elwr);
789 if (e == EXP_CANT_INTERPRET) 828 if (e == EXP_CANT_INTERPRET)
790 break; 829 break;
791 if (e->isBool(TRUE) == FALSE) 830 if (e->isBool(TRUE) == FALSE)
792 { e = NULL; 831 { e = NULL;
793 break; 832 break;
803 break; 842 break;
804 if (e == EXP_BREAK_INTERPRET) 843 if (e == EXP_BREAK_INTERPRET)
805 { e = NULL; 844 { e = NULL;
806 break; 845 break;
807 } 846 }
808 } 847 } while (e == NULL || e == EXP_CONTINUE_INTERPRET);
809 } 848 }
810 key->value = keysave; 849 key->value = keysave;
811 return e; 850 return e;
812 } 851 }
813 #endif 852 #endif
944 #if LOG 983 #if LOG
945 printf("Expression::interpret() %s\n", toChars()); 984 printf("Expression::interpret() %s\n", toChars());
946 printf("type = %s\n", type->toChars()); 985 printf("type = %s\n", type->toChars());
947 dump(0); 986 dump(0);
948 #endif 987 #endif
988 error("Cannot interpret %s at compile time", toChars());
989 return EXP_CANT_INTERPRET;
990 }
991
992 Expression *ThisExp::interpret(InterState *istate)
993 {
994 if (istate->localThis)
995 return istate->localThis->interpret(istate);
949 return EXP_CANT_INTERPRET; 996 return EXP_CANT_INTERPRET;
950 } 997 }
951 998
952 Expression *NullExp::interpret(InterState *istate) 999 Expression *NullExp::interpret(InterState *istate)
953 { 1000 {
993 SymbolDeclaration *s = d->isSymbolDeclaration(); 1040 SymbolDeclaration *s = d->isSymbolDeclaration();
994 #endif 1041 #endif
995 if (v) 1042 if (v)
996 { 1043 {
997 #if DMDV2 1044 #if DMDV2
998 if ((v->isConst() || v->isInvariant()) && v->init && !v->value) 1045 if ((v->isConst() || v->isInvariant() || v->storage_class & STCmanifest) && v->init && !v->value)
999 #else 1046 #else
1000 if (v->isConst() && v->init) 1047 if (v->isConst() && v->init)
1001 #endif 1048 #endif
1002 { e = v->init->toExpression(); 1049 { e = v->init->toExpression();
1003 if (e && !e->type) 1050 if (e && !e->type)
1004 e->type = v->type; 1051 e->type = v->type;
1005 } 1052 }
1006 else 1053 else
1007 { e = v->value; 1054 { e = v->value;
1008 if (!e) 1055 if (v->isDataseg())
1056 { error(loc, "static variable %s cannot be read at compile time", v->toChars());
1057 e = EXP_CANT_INTERPRET;
1058 }
1059 else if (!e)
1009 error(loc, "variable %s is used before initialization", v->toChars()); 1060 error(loc, "variable %s is used before initialization", v->toChars());
1010 else if (e != EXP_CANT_INTERPRET) 1061 else if (e != EXP_CANT_INTERPRET)
1011 e = e->interpret(istate); 1062 e = e->interpret(istate);
1012 } 1063 }
1013 if (!e) 1064 if (!e)
1062 } 1113 }
1063 else if (declaration->isAttribDeclaration() || 1114 else if (declaration->isAttribDeclaration() ||
1064 declaration->isTemplateMixin() || 1115 declaration->isTemplateMixin() ||
1065 declaration->isTupleDeclaration()) 1116 declaration->isTupleDeclaration())
1066 { // These can be made to work, too lazy now 1117 { // These can be made to work, too lazy now
1118 error("Declaration %s is not yet implemented in CTFE", toChars());
1119
1067 e = EXP_CANT_INTERPRET; 1120 e = EXP_CANT_INTERPRET;
1068 } 1121 }
1069 else 1122 else
1070 { // Others should not contain executable code, so are trivial to evaluate 1123 { // Others should not contain executable code, so are trivial to evaluate
1071 e = NULL; 1124 e = NULL;
1072 } 1125 }
1073 #if LOG 1126 #if LOG
1074 printf("-DeclarationExp::interpret(): %p\n", e); 1127 printf("-DeclarationExp::interpret(%s): %p\n", toChars(), e);
1075 #endif 1128 #endif
1076 return e; 1129 return e;
1077 } 1130 }
1078 1131
1079 Expression *TupleExp::interpret(InterState *istate) 1132 Expression *TupleExp::interpret(InterState *istate)
1259 printf("StructLiteralExp::interpret() %s\n", toChars()); 1312 printf("StructLiteralExp::interpret() %s\n", toChars());
1260 #endif 1313 #endif
1261 /* We don't know how to deal with overlapping fields 1314 /* We don't know how to deal with overlapping fields
1262 */ 1315 */
1263 if (sd->hasUnions) 1316 if (sd->hasUnions)
1264 return EXP_CANT_INTERPRET; 1317 { error("Unions with overlapping fields are not yet supported in CTFE");
1318 return EXP_CANT_INTERPRET;
1319 }
1265 1320
1266 if (elements) 1321 if (elements)
1267 { 1322 {
1268 for (size_t i = 0; i < elements->dim; i++) 1323 for (size_t i = 0; i < elements->dim; i++)
1269 { Expression *e = (Expression *)elements->data[i]; 1324 { Expression *e = (Expression *)elements->data[i];
1431 1486
1432 BIN_INTERPRET2(Equal) 1487 BIN_INTERPRET2(Equal)
1433 BIN_INTERPRET2(Identity) 1488 BIN_INTERPRET2(Identity)
1434 BIN_INTERPRET2(Cmp) 1489 BIN_INTERPRET2(Cmp)
1435 1490
1491 /* Helper functions for BinExp::interpretAssignCommon
1492 */
1493
1494 /***************************************
1495 * Duplicate the elements array, then set field 'indexToChange' = newelem.
1496 */
1497 Expressions *changeOneElement(Expressions *oldelems, size_t indexToChange, void *newelem)
1498 {
1499 Expressions *expsx = new Expressions();
1500 expsx->setDim(oldelems->dim);
1501 for (size_t j = 0; j < expsx->dim; j++)
1502 {
1503 if (j == indexToChange)
1504 expsx->data[j] = newelem;
1505 else
1506 expsx->data[j] = oldelems->data[j];
1507 }
1508 return expsx;
1509 }
1510
1511 /***************************************
1512 * Returns oldelems[0..insertpoint] ~ newelems ~ oldelems[insertpoint..$]
1513 */
1514 Expressions *spliceElements(Expressions *oldelems,
1515 Expressions *newelems, size_t insertpoint)
1516 {
1517 Expressions *expsx = new Expressions();
1518 expsx->setDim(oldelems->dim);
1519 for (size_t j = 0; j < expsx->dim; j++)
1520 {
1521 if (j >= insertpoint && j < insertpoint + newelems->dim)
1522 expsx->data[j] = newelems->data[j - insertpoint];
1523 else
1524 expsx->data[j] = oldelems->data[j];
1525 }
1526 return expsx;
1527 }
1528
1529 /******************************
1530 * Create an array literal consisting of 'elem' duplicated 'dim' times.
1531 */
1532 ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Type *type,
1533 Expression *elem, size_t dim)
1534 {
1535 Expressions *elements = new Expressions();
1536 elements->setDim(dim);
1537 for (size_t i = 0; i < dim; i++)
1538 elements->data[i] = elem;
1539 ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements);
1540 ae->type = type;
1541 return ae;
1542 }
1543
1544
1545 /********************************
1546 * Necessary because defaultInit() for a struct is a VarExp, not a StructLiteralExp.
1547 */
1548 StructLiteralExp *createDefaultInitStructLiteral(Loc loc, StructDeclaration *sym)
1549 {
1550 Expressions *structelems = new Expressions();
1551 structelems->setDim(sym->fields.dim);
1552 for (size_t j = 0; j < structelems->dim; j++)
1553 {
1554 structelems->data[j] = ((VarDeclaration *)(sym->fields.data[j]))->type->defaultInit();
1555 }
1556 StructLiteralExp *structinit = new StructLiteralExp(loc, sym, structelems);
1557 // Why doesn't the StructLiteralExp constructor do this, when
1558 // sym->type != NULL ?
1559 structinit->type = sym->type;
1560 return structinit;
1561 }
1562
1563 /********************************
1564 * Add v to the istate list, unless it already exists there.
1565 */
1566 void addVarToInterstate(InterState *istate, VarDeclaration *v)
1567 {
1568 if (!v->isParameter())
1569 {
1570 for (size_t i = 0; 1; i++)
1571 {
1572 if (i == istate->vars.dim)
1573 { istate->vars.push(v);
1574 //printf("\tadding %s to istate\n", v->toChars());
1575 break;
1576 }
1577 if (v == (VarDeclaration *)istate->vars.data[i])
1578 break;
1579 }
1580 }
1581 }
1582
1436 Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post) 1583 Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
1437 { 1584 {
1438 #if LOG 1585 #if LOG
1439 printf("BinExp::interpretAssignCommon() %s\n", toChars()); 1586 printf("BinExp::interpretAssignCommon() %s\n", toChars());
1440 #endif 1587 #endif
1451 if (e1 == EXP_CANT_INTERPRET) 1598 if (e1 == EXP_CANT_INTERPRET)
1452 return e1; 1599 return e1;
1453 Expression *e2 = this->e2->interpret(istate); 1600 Expression *e2 = this->e2->interpret(istate);
1454 if (e2 == EXP_CANT_INTERPRET) 1601 if (e2 == EXP_CANT_INTERPRET)
1455 return e2; 1602 return e2;
1456 1603
1604 // Chase down rebinding of out and ref.
1605 if (e1->op == TOKvar)
1606 {
1607 VarExp *ve = (VarExp *)e1;
1608 VarDeclaration *v = ve->var->isVarDeclaration();
1609 if (v && v->value && v->value->op == TOKvar)
1610 {
1611 VarExp *ve2 = (VarExp *)v->value;
1612 if (ve2->var->isStaticStructInitDeclaration())
1613 { // This can happen if v is a struct initialized to
1614 // 0 using an __initZ StaticStructInitDeclaration from
1615 // TypeStruct::defaultInit()
1616 }
1617 else
1618 e1 = v->value;
1619 }
1620 else if (v && v->value && (v->value->op==TOKindex || v->value->op == TOKdotvar))
1621 {
1622 // It is no longer be a TOKvar, eg when a[4] is passed by ref.
1623 e1 = v->value;
1624 }
1625 }
1626
1627 // To reduce code complexity of handling dotvar expressions,
1628 // extract the aggregate now.
1629 Expression *aggregate;
1630 if (e1->op == TOKdotvar) {
1631 aggregate = ((DotVarExp *)e1)->e1;
1632 // Get rid of 'this'.
1633 if (aggregate->op == TOKthis && istate->localThis)
1634 aggregate = istate->localThis;
1635 }
1636
1457 /* Assignment to variable of the form: 1637 /* Assignment to variable of the form:
1458 * v = e2 1638 * v = e2
1459 */ 1639 */
1460 if (e1->op == TOKvar) 1640 if (e1->op == TOKvar)
1461 { 1641 {
1462 VarExp *ve = (VarExp *)e1; 1642 VarExp *ve = (VarExp *)e1;
1463 VarDeclaration *v = ve->var->isVarDeclaration(); 1643 VarDeclaration *v = ve->var->isVarDeclaration();
1644 assert(v);
1645 if (v && v->isDataseg())
1646 { // Can't modify global or static data
1647 error("%s cannot be modified at compile time", v->toChars());
1648 return EXP_CANT_INTERPRET;
1649 }
1464 if (v && !v->isDataseg()) 1650 if (v && !v->isDataseg())
1465 { 1651 {
1466 /* Chase down rebinding of out and ref
1467 */
1468 if (v->value && v->value->op == TOKvar)
1469 {
1470 VarExp *ve2 = (VarExp *)v->value;
1471 if (ve2->var->isStaticStructInitDeclaration())
1472 {
1473 /* This can happen if v is a struct initialized to
1474 * 0 using an StaticStructInitDeclaration from
1475 * TypeStruct::defaultInit()
1476 */
1477 }
1478 else
1479 v = ve2->var->isVarDeclaration();
1480 assert(v);
1481 }
1482
1483 Expression *ev = v->value; 1652 Expression *ev = v->value;
1484 if (fp && !ev) 1653 if (fp && !ev)
1485 { error("variable %s is used before initialization", v->toChars()); 1654 { error("variable %s is used before initialization", v->toChars());
1486 return e; 1655 return e;
1487 } 1656 }
1494 { 1663 {
1495 e2 = v->type->defaultInit(); 1664 e2 = v->type->defaultInit();
1496 } 1665 }
1497 e2 = Cast(v->type, v->type, e2); 1666 e2 = Cast(v->type, v->type, e2);
1498 } 1667 }
1499 if (e2 != EXP_CANT_INTERPRET) 1668 if (e2 == EXP_CANT_INTERPRET)
1500 { 1669 return e2;
1501 if (!v->isParameter()) 1670
1502 { 1671 addVarToInterstate(istate, v);
1503 for (size_t i = 0; 1; i++) 1672 v->value = e2;
1504 { 1673 e = Cast(type, type, post ? ev : e2);
1505 if (i == istate->vars.dim) 1674 }
1506 { istate->vars.push(v); 1675 }
1507 //printf("\tadding %s to istate\n", v->toChars()); 1676 else if (e1->op == TOKdotvar && aggregate->op == TOKdotvar)
1508 break; 1677 { // eg v.u.var = e2, v[3].u.var = e2, etc.
1509 } 1678 error("Nested struct assignment %s is not yet supported in CTFE", toChars());
1510 if (v == (VarDeclaration *)istate->vars.data[i])
1511 break;
1512 }
1513 }
1514 v->value = e2;
1515 e = Cast(type, type, post ? ev : e2);
1516 }
1517 }
1518 } 1679 }
1519 /* Assignment to struct member of the form: 1680 /* Assignment to struct member of the form:
1520 * v.var = e2 1681 * v.var = e2
1521 */ 1682 */
1522 else if (e1->op == TOKdotvar && ((DotVarExp *)e1)->e1->op == TOKvar) 1683 else if (e1->op == TOKdotvar && aggregate->op == TOKvar)
1523 { VarExp *ve = (VarExp *)((DotVarExp *)e1)->e1; 1684 { VarDeclaration *v = ((VarExp *)aggregate)->var->isVarDeclaration();
1524 VarDeclaration *v = ve->var->isVarDeclaration();
1525 1685
1526 if (v->isDataseg()) 1686 if (v->isDataseg())
1687 { // Can't modify global or static data
1688 error("%s cannot be modified at compile time", v->toChars());
1527 return EXP_CANT_INTERPRET; 1689 return EXP_CANT_INTERPRET;
1690 } else {
1691 // Chase down rebinding of out and ref
1692 if (v->value && v->value->op == TOKvar)
1693 {
1694 VarExp *ve2 = (VarExp *)v->value;
1695 if (ve2->var->isStaticStructInitDeclaration())
1696 { // This can happen if v is a struct initialized to
1697 // 0 using an __initZ StaticStructInitDeclaration from
1698 // TypeStruct::defaultInit()
1699 }
1700 else
1701 v = ve2->var->isVarDeclaration();
1702 assert(v);
1703 }
1704 }
1528 if (fp && !v->value) 1705 if (fp && !v->value)
1529 { error("variable %s is used before initialization", v->toChars()); 1706 { error("variable %s is used before initialization", v->toChars());
1530 return e; 1707 return e;
1531 } 1708 }
1532 if (v->value == NULL && v->init->isVoidInitializer()) 1709 if (v->value == NULL && v->init->isVoidInitializer())
1559 else 1736 else
1560 e2 = Cast(type, type, e2); 1737 e2 = Cast(type, type, e2);
1561 if (e2 == EXP_CANT_INTERPRET) 1738 if (e2 == EXP_CANT_INTERPRET)
1562 return e2; 1739 return e2;
1563 1740
1564 if (!v->isParameter()) 1741 addVarToInterstate(istate, v);
1565 {
1566 for (size_t i = 0; 1; i++)
1567 {
1568 if (i == istate->vars.dim)
1569 { istate->vars.push(v);
1570 break;
1571 }
1572 if (v == (VarDeclaration *)istate->vars.data[i])
1573 break;
1574 }
1575 }
1576 1742
1577 /* Create new struct literal reflecting updated fieldi 1743 /* Create new struct literal reflecting updated fieldi
1578 */ 1744 */
1579 Expressions *expsx = new Expressions(); 1745 Expressions *expsx = changeOneElement(se->elements, fieldi, e2);
1580 expsx->setDim(se->elements->dim);
1581 for (size_t j = 0; j < expsx->dim; j++)
1582 {
1583 if (j == fieldi)
1584 expsx->data[j] = (void *)e2;
1585 else
1586 expsx->data[j] = se->elements->data[j];
1587 }
1588 v->value = new StructLiteralExp(se->loc, se->sd, expsx); 1746 v->value = new StructLiteralExp(se->loc, se->sd, expsx);
1589 v->value->type = se->type; 1747 v->value->type = se->type;
1590 1748
1591 e = Cast(type, type, post ? ev : e2); 1749 e = Cast(type, type, post ? ev : e2);
1592 } 1750 }
1596 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff) 1754 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff)
1597 { SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1; 1755 { SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1;
1598 VarDeclaration *v = soe->var->isVarDeclaration(); 1756 VarDeclaration *v = soe->var->isVarDeclaration();
1599 1757
1600 if (v->isDataseg()) 1758 if (v->isDataseg())
1759 {
1760 error("%s cannot be modified at compile time", v->toChars());
1601 return EXP_CANT_INTERPRET; 1761 return EXP_CANT_INTERPRET;
1762 }
1602 if (fp && !v->value) 1763 if (fp && !v->value)
1603 { error("variable %s is used before initialization", v->toChars()); 1764 { error("variable %s is used before initialization", v->toChars());
1604 return e; 1765 return e;
1605 } 1766 }
1606 Expression *vie = v->value; 1767 Expression *vie = v->value;
1621 else 1782 else
1622 e2 = Cast(type, type, e2); 1783 e2 = Cast(type, type, e2);
1623 if (e2 == EXP_CANT_INTERPRET) 1784 if (e2 == EXP_CANT_INTERPRET)
1624 return e2; 1785 return e2;
1625 1786
1626 if (!v->isParameter()) 1787 addVarToInterstate(istate, v);
1627 {
1628 for (size_t i = 0; 1; i++)
1629 {
1630 if (i == istate->vars.dim)
1631 { istate->vars.push(v);
1632 break;
1633 }
1634 if (v == (VarDeclaration *)istate->vars.data[i])
1635 break;
1636 }
1637 }
1638 1788
1639 /* Create new struct literal reflecting updated fieldi 1789 /* Create new struct literal reflecting updated fieldi
1640 */ 1790 */
1641 Expressions *expsx = new Expressions(); 1791 Expressions *expsx = changeOneElement(se->elements, fieldi, e2);
1642 expsx->setDim(se->elements->dim);
1643 for (size_t j = 0; j < expsx->dim; j++)
1644 {
1645 if (j == fieldi)
1646 expsx->data[j] = (void *)e2;
1647 else
1648 expsx->data[j] = se->elements->data[j];
1649 }
1650 v->value = new StructLiteralExp(se->loc, se->sd, expsx); 1792 v->value = new StructLiteralExp(se->loc, se->sd, expsx);
1651 v->value->type = se->type; 1793 v->value->type = se->type;
1652 1794
1653 e = Cast(type, type, post ? ev : e2); 1795 e = Cast(type, type, post ? ev : e2);
1654 } 1796 }
1657 */ 1799 */
1658 else if (e1->op == TOKindex && ((IndexExp *)e1)->e1->op == TOKvar) 1800 else if (e1->op == TOKindex && ((IndexExp *)e1)->e1->op == TOKvar)
1659 { IndexExp *ie = (IndexExp *)e1; 1801 { IndexExp *ie = (IndexExp *)e1;
1660 VarExp *ve = (VarExp *)ie->e1; 1802 VarExp *ve = (VarExp *)ie->e1;
1661 VarDeclaration *v = ve->var->isVarDeclaration(); 1803 VarDeclaration *v = ve->var->isVarDeclaration();
1662
1663 if (!v || v->isDataseg()) 1804 if (!v || v->isDataseg())
1805 {
1806 error("%s cannot be modified at compile time", v ? v->toChars(): "void");
1664 return EXP_CANT_INTERPRET; 1807 return EXP_CANT_INTERPRET;
1808 }
1809 if (v->value && v->value->op == TOKvar)
1810 {
1811 VarExp *ve2 = (VarExp *)v->value;
1812 if (ve2->var->isStaticStructInitDeclaration())
1813 { // This can happen if v is a struct initialized to
1814 // 0 using an __initZ StaticStructInitDeclaration from
1815 // TypeStruct::defaultInit()
1816 }
1817 else
1818 v = ve2->var->isVarDeclaration();
1819 assert(v);
1820 }
1665 if (!v->value) 1821 if (!v->value)
1666 { 1822 {
1667 if (fp) 1823 if (fp)
1668 { error("variable %s is used before initialization", v->toChars()); 1824 { error("variable %s is used before initialization", v->toChars());
1669 return e; 1825 return e;
1677 * What we should do is fill the array literal with 1833 * What we should do is fill the array literal with
1678 * NULL data, so use-before-initialized can be detected. 1834 * NULL data, so use-before-initialized can be detected.
1679 * But we're too lazy at the moment to do it, as that 1835 * But we're too lazy at the moment to do it, as that
1680 * involves redoing Index() and whoever calls it. 1836 * involves redoing Index() and whoever calls it.
1681 */ 1837 */
1682 Expression *ev = v->type->defaultInit(); 1838
1683 size_t dim = ((TypeSArray *)t)->dim->toInteger(); 1839 size_t dim = ((TypeSArray *)t)->dim->toInteger();
1684 Expressions *elements = new Expressions(); 1840 v->value = createBlockDuplicatedArrayLiteral(v->type,
1685 elements->setDim(dim); 1841 v->type->defaultInit(), dim);
1686 for (size_t i = 0; i < dim; i++)
1687 elements->data[i] = (void *)ev;
1688 ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements);
1689 ae->type = v->type;
1690 v->value = ae;
1691 } 1842 }
1692 else 1843 else
1693 return EXP_CANT_INTERPRET; 1844 return EXP_CANT_INTERPRET;
1694 } 1845 }
1695 1846
1700 ae = (ArrayLiteralExp *)v->value; 1851 ae = (ArrayLiteralExp *)v->value;
1701 else if (v->value->op == TOKassocarrayliteral) 1852 else if (v->value->op == TOKassocarrayliteral)
1702 aae = (AssocArrayLiteralExp *)v->value; 1853 aae = (AssocArrayLiteralExp *)v->value;
1703 else if (v->value->op == TOKstring) 1854 else if (v->value->op == TOKstring)
1704 se = (StringExp *)v->value; 1855 se = (StringExp *)v->value;
1856 else if (v->value->op == TOKnull)
1857 {
1858 // This would be a runtime segfault
1859 error("Cannot index null array %s", v->toChars());
1860 return EXP_CANT_INTERPRET;
1861 }
1705 else 1862 else
1706 return EXP_CANT_INTERPRET; 1863 return EXP_CANT_INTERPRET;
1707 1864
1865 /* Set the $ variable
1866 */
1867 Expression *ee = ArrayLength(Type::tsize_t, v->value);
1868 if (ee != EXP_CANT_INTERPRET && ie->lengthVar)
1869 ie->lengthVar->value = ee;
1708 Expression *index = ie->e2->interpret(istate); 1870 Expression *index = ie->e2->interpret(istate);
1709 if (index == EXP_CANT_INTERPRET) 1871 if (index == EXP_CANT_INTERPRET)
1710 return EXP_CANT_INTERPRET; 1872 return EXP_CANT_INTERPRET;
1711 Expression *ev; 1873 Expression *ev;
1712 if (fp || ae || se) // not for aae, because key might not be there 1874 if (fp || ae || se) // not for aae, because key might not be there
1720 e2 = (*fp)(type, ev, e2); 1882 e2 = (*fp)(type, ev, e2);
1721 else 1883 else
1722 e2 = Cast(type, type, e2); 1884 e2 = Cast(type, type, e2);
1723 if (e2 == EXP_CANT_INTERPRET) 1885 if (e2 == EXP_CANT_INTERPRET)
1724 return e2; 1886 return e2;
1725 1887
1726 if (!v->isParameter()) 1888 addVarToInterstate(istate, v);
1727 {
1728 for (size_t i = 0; 1; i++)
1729 {
1730 if (i == istate->vars.dim)
1731 { istate->vars.push(v);
1732 break;
1733 }
1734 if (v == (VarDeclaration *)istate->vars.data[i])
1735 break;
1736 }
1737 }
1738
1739 if (ae) 1889 if (ae)
1740 { 1890 {
1741 /* Create new array literal reflecting updated elem 1891 /* Create new array literal reflecting updated elem
1742 */ 1892 */
1743 int elemi = index->toInteger(); 1893 int elemi = index->toInteger();
1744 Expressions *expsx = new Expressions(); 1894 Expressions *expsx = changeOneElement(ae->elements, elemi, e2);
1745 expsx->setDim(ae->elements->dim);
1746 for (size_t j = 0; j < expsx->dim; j++)
1747 {
1748 if (j == elemi)
1749 expsx->data[j] = (void *)e2;
1750 else
1751 expsx->data[j] = ae->elements->data[j];
1752 }
1753 v->value = new ArrayLiteralExp(ae->loc, expsx); 1895 v->value = new ArrayLiteralExp(ae->loc, expsx);
1754 v->value->type = ae->type; 1896 v->value->type = ae->type;
1755 } 1897 }
1756 else if (aae) 1898 else if (aae)
1757 { 1899 {
1810 else 1952 else
1811 assert(0); 1953 assert(0);
1812 1954
1813 e = Cast(type, type, post ? ev : e2); 1955 e = Cast(type, type, post ? ev : e2);
1814 } 1956 }
1957
1958 /* Assignment to struct element in array, of the form:
1959 * a[i].var = e2
1960 */
1961 else if (e1->op == TOKdotvar && aggregate->op == TOKindex &&
1962 ((IndexExp *)aggregate)->e1->op == TOKvar)
1963 {
1964 IndexExp * ie = (IndexExp *)aggregate;
1965 VarExp *ve = (VarExp *)(ie->e1);
1966 VarDeclaration *v = ve->var->isVarDeclaration();
1967 if (!v || v->isDataseg())
1968 {
1969 error("%s cannot be modified at compile time", v ? v->toChars(): "void");
1970 return EXP_CANT_INTERPRET;
1971 }
1972 Type *t = ve->type->toBasetype();
1973 ArrayLiteralExp *ae = (ArrayLiteralExp *)v->value;
1974 if (!ae)
1975 {
1976 // assignment to one element in an uninitialized (static) array.
1977 // This is quite difficult, because defaultInit() for a struct is a VarExp,
1978 // not a StructLiteralExp.
1979 Type *t = v->type->toBasetype();
1980 if (t->ty != Tsarray)
1981 {
1982 error("Cannot index an uninitialized variable");
1983 return EXP_CANT_INTERPRET;
1984 }
1985
1986 Type *telem = ((TypeSArray *)t)->nextOf()->toBasetype();
1987 if (telem->ty != Tstruct) { return EXP_CANT_INTERPRET; }
1988
1989 // Create a default struct literal...
1990 StructDeclaration *sym = ((TypeStruct *)telem)->sym;
1991 StructLiteralExp *structinit = createDefaultInitStructLiteral(v->loc, sym);
1992
1993 // ... and use to create a blank array literal
1994 size_t dim = ((TypeSArray *)t)->dim->toInteger();
1995 ae = createBlockDuplicatedArrayLiteral(v->type, structinit, dim);
1996 v->value = ae;
1997 }
1998 if ((Expression *)(ae->elements) == EXP_CANT_INTERPRET)
1999 {
2000 // Note that this would be a runtime segfault
2001 error("Cannot index null array %s", v->toChars());
2002 return EXP_CANT_INTERPRET;
2003 }
2004 // Set the $ variable
2005 Expression *ee = ArrayLength(Type::tsize_t, v->value);
2006 if (ee != EXP_CANT_INTERPRET && ie->lengthVar)
2007 ie->lengthVar->value = ee;
2008 // Determine the index, and check that it's OK.
2009 Expression *index = ie->e2->interpret(istate);
2010 if (index == EXP_CANT_INTERPRET)
2011 return EXP_CANT_INTERPRET;
2012
2013 int elemi = index->toInteger();
2014 if (elemi >= ae->elements->dim)
2015 {
2016 error("array index %d is out of bounds %s[0..%d]", elemi,
2017 v->toChars(), ae->elements->dim);
2018 return EXP_CANT_INTERPRET;
2019 }
2020 // Get old element
2021 Expression *vie = (Expression *)(ae->elements->data[elemi]);
2022 if (vie->op != TOKstructliteral)
2023 return EXP_CANT_INTERPRET;
2024
2025 // Work out which field needs to be changed
2026 StructLiteralExp *se = (StructLiteralExp *)vie;
2027 VarDeclaration *vf = ((DotVarExp *)e1)->var->isVarDeclaration();
2028 if (!vf)
2029 return EXP_CANT_INTERPRET;
2030
2031 int fieldi = se->getFieldIndex(type, vf->offset);
2032 if (fieldi == -1)
2033 return EXP_CANT_INTERPRET;
2034
2035 Expression *ev = se->getField(type, vf->offset);
2036 if (fp)
2037 e2 = (*fp)(type, ev, e2);
2038 else
2039 e2 = Cast(type, type, e2);
2040 if (e2 == EXP_CANT_INTERPRET)
2041 return e2;
2042
2043 // Create new struct literal reflecting updated field
2044 Expressions *expsx = changeOneElement(se->elements, fieldi, e2);
2045 Expression * newstruct = new StructLiteralExp(se->loc, se->sd, expsx);
2046
2047 // Create new array literal reflecting updated struct elem
2048 ae->elements = changeOneElement(ae->elements, elemi, newstruct);
2049 return ae;
2050 }
2051 /* Slice assignment, initialization of static arrays
2052 * a[] = e
2053 */
2054 else if (e1->op == TOKslice && ((SliceExp *)e1)->e1->op==TOKvar)
2055 {
2056 SliceExp * sexp = (SliceExp *)e1;
2057 VarExp *ve = (VarExp *)(sexp->e1);
2058 VarDeclaration *v = ve->var->isVarDeclaration();
2059 if (!v || v->isDataseg())
2060 {
2061 error("%s cannot be modified at compile time", v->toChars());
2062 return EXP_CANT_INTERPRET;
2063 }
2064 // Chase down rebinding of out and ref
2065 if (v->value && v->value->op == TOKvar)
2066 {
2067 VarExp *ve2 = (VarExp *)v->value;
2068 if (ve2->var->isStaticStructInitDeclaration())
2069 { // This can happen if v is a struct initialized to
2070 // 0 using an __initZ StaticStructInitDeclaration from
2071 // TypeStruct::defaultInit()
2072 }
2073 else
2074 v = ve2->var->isVarDeclaration();
2075 assert(v);
2076 }
2077 /* Set the $ variable
2078 */
2079 Expression *ee = v->value ? ArrayLength(Type::tsize_t, v->value)
2080 : EXP_CANT_INTERPRET;
2081 if (ee != EXP_CANT_INTERPRET && sexp->lengthVar)
2082 sexp->lengthVar->value = ee;
2083 Expression *upper = NULL;
2084 Expression *lower = NULL;
2085 if (sexp->upr)
2086 {
2087 upper = sexp->upr->interpret(istate);
2088 if (upper == EXP_CANT_INTERPRET)
2089 return EXP_CANT_INTERPRET;
2090 }
2091 if (sexp->lwr)
2092 {
2093 lower = sexp->lwr->interpret(istate);
2094 if (lower == EXP_CANT_INTERPRET)
2095 return EXP_CANT_INTERPRET;
2096 }
2097 Type *t = v->type->toBasetype();
2098 size_t dim;
2099 if (t->ty == Tsarray)
2100 dim = ((TypeSArray *)t)->dim->toInteger();
2101 else if (t->ty == Tarray)
2102 {
2103 if (!v->value || v->value->op == TOKnull)
2104 {
2105 error("cannot assign to null array %s", v->toChars());
2106 return EXP_CANT_INTERPRET;
2107 }
2108 if (v->value->op == TOKarrayliteral)
2109 dim = ((ArrayLiteralExp *)v->value)->elements->dim;
2110 else if (v->value->op ==TOKstring)
2111 {
2112 error("String slice assignment is not yet supported in CTFE");
2113 return EXP_CANT_INTERPRET;
2114 }
2115 }
2116 else
2117 {
2118 error("%s cannot be evaluated at compile time", toChars());
2119 return EXP_CANT_INTERPRET;
2120 }
2121 int upperbound = upper ? upper->toInteger() : dim;
2122 int lowerbound = lower ? lower->toInteger() : 0;
2123
2124 ArrayLiteralExp *existing;
2125 if (((int)lowerbound < 0) || (upperbound > dim))
2126 {
2127 error("Array bounds [0..%d] exceeded in slice [%d..%d]", dim, lowerbound, upperbound);
2128 return EXP_CANT_INTERPRET;
2129 }
2130 if (upperbound-lowerbound != dim)
2131 {
2132 // Only modifying part of the array. Must create a new array literal.
2133 // If the existing array is uninitialized (this can only happen
2134 // with static arrays), create it.
2135 if (v->value && v->value->op == TOKarrayliteral)
2136 existing = (ArrayLiteralExp *)v->value;
2137 else
2138 {
2139 // this can only happen with static arrays
2140 existing = createBlockDuplicatedArrayLiteral(v->type, v->type->defaultInit(), dim);
2141 }
2142 }
2143
2144 if (e2->op == TOKarrayliteral)
2145 {
2146 // Static array assignment from literal
2147 ArrayLiteralExp *ae = (ArrayLiteralExp *)e2;
2148 if (ae->elements->dim != (upperbound - lowerbound))
2149 {
2150 error("Array length mismatch assigning [0..%d] to [%d..%d]", ae->elements->dim, lowerbound, upperbound);
2151 return e;
2152 }
2153 if (upperbound - lowerbound == dim)
2154 v->value = ae;
2155 else
2156 {
2157 // value[] = value[0..lower] ~ ae ~ value[upper..$]
2158 existing->elements = spliceElements(existing->elements, ae->elements, lowerbound);
2159 v->value = existing;
2160 }
2161 return e2;
2162 }
2163 else if (t->nextOf()->ty == e2->type->ty)
2164 {
2165 // Static array block assignment
2166 if (upperbound-lowerbound ==dim)
2167 v->value = createBlockDuplicatedArrayLiteral(v->type, e2, dim);
2168 else
2169 {
2170 // value[] = value[0..lower] ~ ae ~ value[upper..$]
2171 existing->elements = spliceElements(existing->elements, createBlockDuplicatedArrayLiteral(v->type, e2, upperbound-lowerbound)->elements, lowerbound);
2172 v->value = existing;
2173 }
2174 return e2;
2175 }
2176 else if (e2->op == TOKstring)
2177 {
2178 StringExp *se = (StringExp *)e2;
2179 // This is problematic. char[8] should be storing
2180 // values as a string literal, not
2181 // as an array literal. Then, for static arrays, we
2182 // could do modifications
2183 // in-place, with a dramatic memory and speed improvement.
2184 error("String slice assignment is not yet supported in CTFE");
2185 return e2;
2186 }
2187 else
2188 {
2189 error("Slice operation %s cannot be evaluated at compile time", toChars());
2190 return e;
2191 }
2192 }
1815 else 2193 else
1816 { 2194 {
2195 error("%s cannot be evaluated at compile time", toChars());
1817 #ifdef DEBUG 2196 #ifdef DEBUG
1818 dump(0); 2197 dump(0);
1819 #endif 2198 #endif
1820 } 2199 }
1821 return e; 2200 return e;
1925 { Expression *e = EXP_CANT_INTERPRET; 2304 { Expression *e = EXP_CANT_INTERPRET;
1926 2305
1927 #if LOG 2306 #if LOG
1928 printf("CallExp::interpret() %s\n", toChars()); 2307 printf("CallExp::interpret() %s\n", toChars());
1929 #endif 2308 #endif
2309 if (e1->op == TOKdotvar)
2310 {
2311 Expression * pthis = ((DotVarExp*)e1)->e1;
2312 FuncDeclaration *fd = ((DotVarExp*)e1)->var->isFuncDeclaration();
2313 TypeFunction *tf = fd ? (TypeFunction *)(fd->type) : NULL;
2314 if (tf)
2315 { // Member function call
2316 if(pthis->op == TOKthis)
2317 pthis = istate->localThis;
2318 Expression *eresult = fd->interpret(istate, arguments, pthis);
2319 if (eresult)
2320 e = eresult;
2321 else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors)
2322 e = EXP_VOID_INTERPRET;
2323 else
2324 error("cannot evaluate %s at compile time", toChars());
2325 return e;
2326 }
2327 error("cannot evaluate %s at compile time", toChars());
2328 return EXP_CANT_INTERPRET;
2329 }
1930 if (e1->op == TOKvar) 2330 if (e1->op == TOKvar)
1931 { 2331 {
1932 FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration(); 2332 FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration();
1933 if (fd) 2333 if (fd)
1934 { 2334 {
2157 Expression *e1; 2557 Expression *e1;
2158 2558
2159 #if LOG 2559 #if LOG
2160 printf("AssertExp::interpret() %s\n", toChars()); 2560 printf("AssertExp::interpret() %s\n", toChars());
2161 #endif 2561 #endif
2562 if( this->e1->op == TOKaddress)
2563 { // Special case: deal with compiler-inserted assert(&this, "null this")
2564 AddrExp *ade = (AddrExp *)this->e1;
2565 if(ade->e1->op == TOKthis && istate->localThis)
2566 return istate->localThis->interpret(istate);
2567 }
2568 if (this->e1->op == TOKthis)
2569 {
2570 if(istate->localThis)
2571 return istate->localThis->interpret(istate);
2572 }
2162 e1 = this->e1->interpret(istate); 2573 e1 = this->e1->interpret(istate);
2163 if (e1 == EXP_CANT_INTERPRET) 2574 if (e1 == EXP_CANT_INTERPRET)
2164 goto Lcant; 2575 goto Lcant;
2165 if (e1->isBool(TRUE)) 2576 if (e1->isBool(TRUE))
2166 { 2577 {
2225 if (!e) 2636 if (!e)
2226 e = EXP_CANT_INTERPRET; 2637 e = EXP_CANT_INTERPRET;
2227 } 2638 }
2228 } 2639 }
2229 } 2640 }
2641 #if DMDV2
2642 #else // this is required for D1, where structs return *this instead of 'this'.
2643 else if (e1->op == TOKthis)
2644 {
2645 if(istate->localThis)
2646 return istate->localThis->interpret(istate);
2647 }
2648 #endif
2230 #if LOG 2649 #if LOG
2231 if (e == EXP_CANT_INTERPRET) 2650 if (e == EXP_CANT_INTERPRET)
2232 printf("PtrExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars()); 2651 printf("PtrExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars());
2233 #endif 2652 #endif
2234 return e; 2653 return e;
2251 { e = se->getField(type, v->offset); 2670 { e = se->getField(type, v->offset);
2252 if (!e) 2671 if (!e)
2253 e = EXP_CANT_INTERPRET; 2672 e = EXP_CANT_INTERPRET;
2254 return e; 2673 return e;
2255 } 2674 }
2256 } 2675 } else error("%s.%s is not yet implemented at compile time", ex->toChars(), var->toChars());
2257 } 2676 }
2258 2677
2259 #if LOG 2678 #if LOG
2260 if (e == EXP_CANT_INTERPRET) 2679 if (e == EXP_CANT_INTERPRET)
2261 printf("DotVarExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars()); 2680 printf("DotVarExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars());
2280 return e; 2699 return e;
2281 } 2700 }
2282 2701
2283 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments) 2702 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments)
2284 { 2703 {
2285 //printf("interpret_aaKeys()\n"); 2704 #if LOG
2705 printf("interpret_aaKeys()\n");
2706 #endif
2286 if (!arguments || arguments->dim != 2) 2707 if (!arguments || arguments->dim != 2)
2287 return NULL; 2708 return NULL;
2288 Expression *earg = (Expression *)arguments->data[0]; 2709 Expression *earg = (Expression *)arguments->data[0];
2289 earg = earg->interpret(istate); 2710 earg = earg->interpret(istate);
2290 if (earg == EXP_CANT_INTERPRET) 2711 if (earg == EXP_CANT_INTERPRET)