comparison dmd/interpret.c @ 1587:def7a1d494fd

Merge DMD 1.051
author Christian Kamm <kamm incasoftware de>
date Fri, 06 Nov 2009 23:58:01 +0100
parents 8026319762be
children 8aa756a00228
comparison
equal deleted inserted replaced
1586:7f728c52e63c 1587:def7a1d494fd
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 //TODO
200 #ifdef IN_DMD
201 if (((VarExp *)v2->value)->var->isSymbolDeclaration())
202 { // This can happen if v is a struct initialized to
203 // 0 using an __initZ SymbolDeclaration from
204 // TypeStruct::defaultInit()
205 break; // eg default-initialized variable
206 }
207 #endif
177 earg = v2->value; 208 earg = v2->value;
178 } 209 }
179 210
180 v->value = new VarExp(earg->loc, v2); 211 v->value = new VarExp(earg->loc, v2);
181 212
189 break; 220 break;
190 } 221 }
191 } 222 }
192 } 223 }
193 else 224 else
194 { /* Value parameters 225 { // Value parameters and non-trivial references
195 */
196 v->value = earg; 226 v->value = earg;
197 } 227 }
198 #if LOG 228 #if LOG
199 printf("interpreted arg[%d] = %s\n", i, earg->toChars()); 229 printf("interpreted arg[%d] = %s\n", i, earg->toChars());
200 #endif 230 #endif
231 }
232 }
233 // Don't restore the value of 'this' upon function return
234 if (needThis() && thisarg->op==TOKvar) {
235 VarDeclaration *thisvar = ((VarExp *)(thisarg))->var->isVarDeclaration();
236 for (size_t i = 0; i < istate->vars.dim; i++)
237 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
238 if (v == thisvar)
239 { istate->vars.data[i] = NULL;
240 break;
241 }
201 } 242 }
202 } 243 }
203 244
204 /* Save the values of the local variables used 245 /* Save the values of the local variables used
205 */ 246 */
206 Expressions valueSaves; 247 Expressions valueSaves;
207 if (istate) 248 if (istate && !isNested())
208 { 249 {
209 //printf("saving local variables...\n"); 250 //printf("saving local variables...\n");
210 valueSaves.setDim(istate->vars.dim); 251 valueSaves.setDim(istate->vars.dim);
211 for (size_t i = 0; i < istate->vars.dim; i++) 252 for (size_t i = 0; i < istate->vars.dim; i++)
212 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; 253 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
218 } 259 }
219 } 260 }
220 } 261 }
221 262
222 Expression *e = NULL; 263 Expression *e = NULL;
223
224 while (1) 264 while (1)
225 { 265 {
226 e = fbody->interpret(&istatex); 266 e = fbody->interpret(&istatex);
227 if (e == EXP_CANT_INTERPRET) 267 if (e == EXP_CANT_INTERPRET)
228 { 268 {
244 istatex.gotoTarget = NULL; 284 istatex.gotoTarget = NULL;
245 } 285 }
246 else 286 else
247 break; 287 break;
248 } 288 }
249
250 /* Restore the parameter values 289 /* Restore the parameter values
251 */ 290 */
252 for (size_t i = 0; i < dim; i++) 291 for (size_t i = 0; i < dim; i++)
253 { 292 {
254 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 293 VarDeclaration *v = (VarDeclaration *)parameters->data[i];
255 v->value = (Expression *)vsave.data[i]; 294 v->value = (Expression *)vsave.data[i];
256 } 295 }
257 296
258 if (istate) 297 if (istate && !isNested())
259 { 298 {
260 /* Restore the variable values 299 /* Restore the variable values
261 */ 300 */
262 //printf("restoring local variables...\n"); 301 //printf("restoring local variables...\n");
263 for (size_t i = 0; i < istate->vars.dim; i++) 302 for (size_t i = 0; i < istate->vars.dim; i++)
266 { v->value = (Expression *)valueSaves.data[i]; 305 { v->value = (Expression *)valueSaves.data[i];
267 //printf("\trestoring [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : ""); 306 //printf("\trestoring [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : "");
268 } 307 }
269 } 308 }
270 } 309 }
271
272 return e; 310 return e;
273 } 311 }
274 312
275 /******************************** Statement ***************************/ 313 /******************************** Statement ***************************/
276 314
476 return NULL; 514 return NULL;
477 if (e == EXP_CANT_INTERPRET) 515 if (e == EXP_CANT_INTERPRET)
478 return e; 516 return e;
479 if (e == EXP_BREAK_INTERPRET) 517 if (e == EXP_BREAK_INTERPRET)
480 return NULL; 518 return NULL;
481 if (e != EXP_CONTINUE_INTERPRET) 519 if (e && e != EXP_CONTINUE_INTERPRET)
482 return e; 520 return e;
483 } 521 }
484 522
485 while (1) 523 while (1)
486 { 524 {
756 { 794 {
757 key->value = elwr; 795 key->value = elwr;
758 796
759 while (1) 797 while (1)
760 { 798 {
761 e = Cmp(TOKlt, key->value->type, key->value, upr); 799 e = Cmp(TOKlt, key->value->type, key->value, eupr);
762 if (e == EXP_CANT_INTERPRET) 800 if (e == EXP_CANT_INTERPRET)
763 break; 801 break;
764 if (e->isBool(TRUE) == FALSE) 802 if (e->isBool(TRUE) == FALSE)
765 { e = NULL; 803 { e = NULL;
766 break; 804 break;
771 break; 809 break;
772 if (e == EXP_BREAK_INTERPRET) 810 if (e == EXP_BREAK_INTERPRET)
773 { e = NULL; 811 { e = NULL;
774 break; 812 break;
775 } 813 }
776 e = Add(key->value->type, key->value, new IntegerExp(loc, 1, key->value->type)); 814 if (e == NULL || e == EXP_CONTINUE_INTERPRET)
777 if (e == EXP_CANT_INTERPRET) 815 { e = Add(key->value->type, key->value, new IntegerExp(loc, 1, key->value->type));
778 break; 816 if (e == EXP_CANT_INTERPRET)
779 key->value = e; 817 break;
818 key->value = e;
819 }
820 else
821 break;
780 } 822 }
781 } 823 }
782 else // TOKforeach_reverse 824 else // TOKforeach_reverse
783 { 825 {
784 key->value = eupr; 826 key->value = eupr;
785 827
786 while (1) 828 do
787 { 829 {
788 e = Cmp(TOKgt, key->value->type, key->value, lwr); 830 e = Cmp(TOKgt, key->value->type, key->value, elwr);
789 if (e == EXP_CANT_INTERPRET) 831 if (e == EXP_CANT_INTERPRET)
790 break; 832 break;
791 if (e->isBool(TRUE) == FALSE) 833 if (e->isBool(TRUE) == FALSE)
792 { e = NULL; 834 { e = NULL;
793 break; 835 break;
803 break; 845 break;
804 if (e == EXP_BREAK_INTERPRET) 846 if (e == EXP_BREAK_INTERPRET)
805 { e = NULL; 847 { e = NULL;
806 break; 848 break;
807 } 849 }
808 } 850 } while (e == NULL || e == EXP_CONTINUE_INTERPRET);
809 } 851 }
810 key->value = keysave; 852 key->value = keysave;
811 return e; 853 return e;
812 } 854 }
813 #endif 855 #endif
944 #if LOG 986 #if LOG
945 printf("Expression::interpret() %s\n", toChars()); 987 printf("Expression::interpret() %s\n", toChars());
946 printf("type = %s\n", type->toChars()); 988 printf("type = %s\n", type->toChars());
947 dump(0); 989 dump(0);
948 #endif 990 #endif
991 error("Cannot interpret %s at compile time", toChars());
992 return EXP_CANT_INTERPRET;
993 }
994
995 Expression *ThisExp::interpret(InterState *istate)
996 {
997 if (istate->localThis)
998 return istate->localThis->interpret(istate);
949 return EXP_CANT_INTERPRET; 999 return EXP_CANT_INTERPRET;
950 } 1000 }
951 1001
952 Expression *NullExp::interpret(InterState *istate) 1002 Expression *NullExp::interpret(InterState *istate)
953 { 1003 {
989 VarDeclaration *v = d->isVarDeclaration(); 1039 VarDeclaration *v = d->isVarDeclaration();
990 StaticStructInitDeclaration *s = d->isStaticStructInitDeclaration(); 1040 StaticStructInitDeclaration *s = d->isStaticStructInitDeclaration();
991 if (v) 1041 if (v)
992 { 1042 {
993 #if DMDV2 1043 #if DMDV2
994 if ((v->isConst() || v->isInvariant()) && v->init && !v->value) 1044 if ((v->isConst() || v->isInvariant() || v->storage_class & STCmanifest) && v->init && !v->value)
995 #else 1045 #else
996 if (v->isConst() && v->init) 1046 if (v->isConst() && v->init)
997 #endif 1047 #endif
998 { e = v->init->toExpression(); 1048 { e = v->init->toExpression();
999 if (e && !e->type) 1049 if (e && !e->type)
1000 e->type = v->type; 1050 e->type = v->type;
1001 } 1051 }
1002 else 1052 else
1003 { e = v->value; 1053 { e = v->value;
1004 if (!e) 1054 if (v->isDataseg())
1055 { error(loc, "static variable %s cannot be read at compile time", v->toChars());
1056 e = EXP_CANT_INTERPRET;
1057 }
1058 else if (!e)
1005 error(loc, "variable %s is used before initialization", v->toChars()); 1059 error(loc, "variable %s is used before initialization", v->toChars());
1006 else if (e != EXP_CANT_INTERPRET) 1060 else if (e != EXP_CANT_INTERPRET)
1007 e = e->interpret(istate); 1061 e = e->interpret(istate);
1008 } 1062 }
1009 if (!e) 1063 if (!e)
1058 } 1112 }
1059 else if (declaration->isAttribDeclaration() || 1113 else if (declaration->isAttribDeclaration() ||
1060 declaration->isTemplateMixin() || 1114 declaration->isTemplateMixin() ||
1061 declaration->isTupleDeclaration()) 1115 declaration->isTupleDeclaration())
1062 { // These can be made to work, too lazy now 1116 { // These can be made to work, too lazy now
1117 error("Declaration %s is not yet implemented in CTFE", toChars());
1118
1063 e = EXP_CANT_INTERPRET; 1119 e = EXP_CANT_INTERPRET;
1064 } 1120 }
1065 else 1121 else
1066 { // Others should not contain executable code, so are trivial to evaluate 1122 { // Others should not contain executable code, so are trivial to evaluate
1067 e = NULL; 1123 e = NULL;
1068 } 1124 }
1069 #if LOG 1125 #if LOG
1070 printf("-DeclarationExp::interpret(): %p\n", e); 1126 printf("-DeclarationExp::interpret(%s): %p\n", toChars(), e);
1071 #endif 1127 #endif
1072 return e; 1128 return e;
1073 } 1129 }
1074 1130
1075 Expression *TupleExp::interpret(InterState *istate) 1131 Expression *TupleExp::interpret(InterState *istate)
1255 printf("StructLiteralExp::interpret() %s\n", toChars()); 1311 printf("StructLiteralExp::interpret() %s\n", toChars());
1256 #endif 1312 #endif
1257 /* We don't know how to deal with overlapping fields 1313 /* We don't know how to deal with overlapping fields
1258 */ 1314 */
1259 if (sd->hasUnions) 1315 if (sd->hasUnions)
1260 return EXP_CANT_INTERPRET; 1316 { error("Unions with overlapping fields are not yet supported in CTFE");
1317 return EXP_CANT_INTERPRET;
1318 }
1261 1319
1262 if (elements) 1320 if (elements)
1263 { 1321 {
1264 for (size_t i = 0; i < elements->dim; i++) 1322 for (size_t i = 0; i < elements->dim; i++)
1265 { Expression *e = (Expression *)elements->data[i]; 1323 { Expression *e = (Expression *)elements->data[i];
1427 1485
1428 BIN_INTERPRET2(Equal) 1486 BIN_INTERPRET2(Equal)
1429 BIN_INTERPRET2(Identity) 1487 BIN_INTERPRET2(Identity)
1430 BIN_INTERPRET2(Cmp) 1488 BIN_INTERPRET2(Cmp)
1431 1489
1490 /* Helper functions for BinExp::interpretAssignCommon
1491 */
1492
1493 /***************************************
1494 * Duplicate the elements array, then set field 'indexToChange' = newelem.
1495 */
1496 Expressions *changeOneElement(Expressions *oldelems, size_t indexToChange, void *newelem)
1497 {
1498 Expressions *expsx = new Expressions();
1499 expsx->setDim(oldelems->dim);
1500 for (size_t j = 0; j < expsx->dim; j++)
1501 {
1502 if (j == indexToChange)
1503 expsx->data[j] = newelem;
1504 else
1505 expsx->data[j] = oldelems->data[j];
1506 }
1507 return expsx;
1508 }
1509
1510 /***************************************
1511 * Returns oldelems[0..insertpoint] ~ newelems ~ oldelems[insertpoint..$]
1512 */
1513 Expressions *spliceElements(Expressions *oldelems,
1514 Expressions *newelems, size_t insertpoint)
1515 {
1516 Expressions *expsx = new Expressions();
1517 expsx->setDim(oldelems->dim);
1518 for (size_t j = 0; j < expsx->dim; j++)
1519 {
1520 if (j >= insertpoint && j < insertpoint + newelems->dim)
1521 expsx->data[j] = newelems->data[j - insertpoint];
1522 else
1523 expsx->data[j] = oldelems->data[j];
1524 }
1525 return expsx;
1526 }
1527
1528 /******************************
1529 * Create an array literal consisting of 'elem' duplicated 'dim' times.
1530 */
1531 ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Type *type,
1532 Expression *elem, size_t dim)
1533 {
1534 Expressions *elements = new Expressions();
1535 elements->setDim(dim);
1536 for (size_t i = 0; i < dim; i++)
1537 elements->data[i] = elem;
1538 ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements);
1539 ae->type = type;
1540 return ae;
1541 }
1542
1543
1544 /********************************
1545 * Necessary because defaultInit() for a struct is a VarExp, not a StructLiteralExp.
1546 */
1547 StructLiteralExp *createDefaultInitStructLiteral(Loc loc, StructDeclaration *sym)
1548 {
1549 Expressions *structelems = new Expressions();
1550 structelems->setDim(sym->fields.dim);
1551 for (size_t j = 0; j < structelems->dim; j++)
1552 {
1553 structelems->data[j] = ((VarDeclaration *)(sym->fields.data[j]))->type->defaultInit();
1554 }
1555 StructLiteralExp *structinit = new StructLiteralExp(loc, sym, structelems);
1556 // Why doesn't the StructLiteralExp constructor do this, when
1557 // sym->type != NULL ?
1558 structinit->type = sym->type;
1559 return structinit;
1560 }
1561
1562 /********************************
1563 * Add v to the istate list, unless it already exists there.
1564 */
1565 void addVarToInterstate(InterState *istate, VarDeclaration *v)
1566 {
1567 if (!v->isParameter())
1568 {
1569 for (size_t i = 0; 1; i++)
1570 {
1571 if (i == istate->vars.dim)
1572 { istate->vars.push(v);
1573 //printf("\tadding %s to istate\n", v->toChars());
1574 break;
1575 }
1576 if (v == (VarDeclaration *)istate->vars.data[i])
1577 break;
1578 }
1579 }
1580 }
1581
1432 Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post) 1582 Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
1433 { 1583 {
1434 #if LOG 1584 #if LOG
1435 printf("BinExp::interpretAssignCommon() %s\n", toChars()); 1585 printf("BinExp::interpretAssignCommon() %s\n", toChars());
1436 #endif 1586 #endif
1447 if (e1 == EXP_CANT_INTERPRET) 1597 if (e1 == EXP_CANT_INTERPRET)
1448 return e1; 1598 return e1;
1449 Expression *e2 = this->e2->interpret(istate); 1599 Expression *e2 = this->e2->interpret(istate);
1450 if (e2 == EXP_CANT_INTERPRET) 1600 if (e2 == EXP_CANT_INTERPRET)
1451 return e2; 1601 return e2;
1452 1602
1603 // Chase down rebinding of out and ref.
1604 if (e1->op == TOKvar)
1605 {
1606 VarExp *ve = (VarExp *)e1;
1607 VarDeclaration *v = ve->var->isVarDeclaration();
1608 if (v && v->value && v->value->op == TOKvar)
1609 {
1610 VarExp *ve2 = (VarExp *)v->value;
1611 //TODO
1612 #ifdef IN_DMD
1613 if (ve2->var->isSymbolDeclaration())
1614 { // This can happen if v is a struct initialized to
1615 // 0 using an __initZ SymbolDeclaration from
1616 // TypeStruct::defaultInit()
1617 }
1618 else
1619 #endif
1620 e1 = v->value;
1621 }
1622 else if (v && v->value && (v->value->op==TOKindex || v->value->op == TOKdotvar))
1623 {
1624 // It is no longer be a TOKvar, eg when a[4] is passed by ref.
1625 e1 = v->value;
1626 }
1627 }
1628
1629 // To reduce code complexity of handling dotvar expressions,
1630 // extract the aggregate now.
1631 Expression *aggregate;
1632 if (e1->op == TOKdotvar) {
1633 aggregate = ((DotVarExp *)e1)->e1;
1634 // Get rid of 'this'.
1635 if (aggregate->op == TOKthis && istate->localThis)
1636 aggregate = istate->localThis;
1637 }
1638
1453 /* Assignment to variable of the form: 1639 /* Assignment to variable of the form:
1454 * v = e2 1640 * v = e2
1455 */ 1641 */
1456 if (e1->op == TOKvar) 1642 if (e1->op == TOKvar)
1457 { 1643 {
1458 VarExp *ve = (VarExp *)e1; 1644 VarExp *ve = (VarExp *)e1;
1459 VarDeclaration *v = ve->var->isVarDeclaration(); 1645 VarDeclaration *v = ve->var->isVarDeclaration();
1646 assert(v);
1647 if (v && v->isDataseg())
1648 { // Can't modify global or static data
1649 error("%s cannot be modified at compile time", v->toChars());
1650 return EXP_CANT_INTERPRET;
1651 }
1460 if (v && !v->isDataseg()) 1652 if (v && !v->isDataseg())
1461 { 1653 {
1462 /* Chase down rebinding of out and ref
1463 */
1464 if (v->value && v->value->op == TOKvar)
1465 {
1466 VarExp *ve2 = (VarExp *)v->value;
1467 if (ve2->var->isStaticStructInitDeclaration())
1468 {
1469 /* This can happen if v is a struct initialized to
1470 * 0 using an StaticStructInitDeclaration from
1471 * TypeStruct::defaultInit()
1472 */
1473 }
1474 else
1475 v = ve2->var->isVarDeclaration();
1476 assert(v);
1477 }
1478
1479 Expression *ev = v->value; 1654 Expression *ev = v->value;
1480 if (fp && !ev) 1655 if (fp && !ev)
1481 { error("variable %s is used before initialization", v->toChars()); 1656 { error("variable %s is used before initialization", v->toChars());
1482 return e; 1657 return e;
1483 } 1658 }
1490 { 1665 {
1491 e2 = v->type->defaultInit(); 1666 e2 = v->type->defaultInit();
1492 } 1667 }
1493 e2 = Cast(v->type, v->type, e2); 1668 e2 = Cast(v->type, v->type, e2);
1494 } 1669 }
1495 if (e2 != EXP_CANT_INTERPRET) 1670 if (e2 == EXP_CANT_INTERPRET)
1496 { 1671 return e2;
1497 if (!v->isParameter()) 1672
1498 { 1673 addVarToInterstate(istate, v);
1499 for (size_t i = 0; 1; i++) 1674 v->value = e2;
1500 { 1675 e = Cast(type, type, post ? ev : e2);
1501 if (i == istate->vars.dim) 1676 }
1502 { istate->vars.push(v); 1677 }
1503 //printf("\tadding %s to istate\n", v->toChars()); 1678 else if (e1->op == TOKdotvar && aggregate->op == TOKdotvar)
1504 break; 1679 { // eg v.u.var = e2, v[3].u.var = e2, etc.
1505 } 1680 error("Nested struct assignment %s is not yet supported in CTFE", toChars());
1506 if (v == (VarDeclaration *)istate->vars.data[i])
1507 break;
1508 }
1509 }
1510 v->value = e2;
1511 e = Cast(type, type, post ? ev : e2);
1512 }
1513 }
1514 } 1681 }
1515 /* Assignment to struct member of the form: 1682 /* Assignment to struct member of the form:
1516 * v.var = e2 1683 * v.var = e2
1517 */ 1684 */
1518 else if (e1->op == TOKdotvar && ((DotVarExp *)e1)->e1->op == TOKvar) 1685 else if (e1->op == TOKdotvar && aggregate->op == TOKvar)
1519 { VarExp *ve = (VarExp *)((DotVarExp *)e1)->e1; 1686 { VarDeclaration *v = ((VarExp *)aggregate)->var->isVarDeclaration();
1520 VarDeclaration *v = ve->var->isVarDeclaration();
1521 1687
1522 if (v->isDataseg()) 1688 if (v->isDataseg())
1689 { // Can't modify global or static data
1690 error("%s cannot be modified at compile time", v->toChars());
1523 return EXP_CANT_INTERPRET; 1691 return EXP_CANT_INTERPRET;
1692 } else {
1693 // Chase down rebinding of out and ref
1694 if (v->value && v->value->op == TOKvar)
1695 {
1696 VarExp *ve2 = (VarExp *)v->value;
1697 //TODO
1698 #ifdef IN_DMD
1699 if (ve2->var->isSymbolDeclaration())
1700 { // This can happen if v is a struct initialized to
1701 // 0 using an __initZ SymbolDeclaration from
1702 // TypeStruct::defaultInit()
1703 }
1704 else
1705 #endif
1706 v = ve2->var->isVarDeclaration();
1707 assert(v);
1708 }
1709 }
1524 if (fp && !v->value) 1710 if (fp && !v->value)
1525 { error("variable %s is used before initialization", v->toChars()); 1711 { error("variable %s is used before initialization", v->toChars());
1526 return e; 1712 return e;
1527 } 1713 }
1528 if (v->value == NULL && v->init->isVoidInitializer()) 1714 if (v->value == NULL && v->init->isVoidInitializer())
1555 else 1741 else
1556 e2 = Cast(type, type, e2); 1742 e2 = Cast(type, type, e2);
1557 if (e2 == EXP_CANT_INTERPRET) 1743 if (e2 == EXP_CANT_INTERPRET)
1558 return e2; 1744 return e2;
1559 1745
1560 if (!v->isParameter()) 1746 addVarToInterstate(istate, v);
1561 {
1562 for (size_t i = 0; 1; i++)
1563 {
1564 if (i == istate->vars.dim)
1565 { istate->vars.push(v);
1566 break;
1567 }
1568 if (v == (VarDeclaration *)istate->vars.data[i])
1569 break;
1570 }
1571 }
1572 1747
1573 /* Create new struct literal reflecting updated fieldi 1748 /* Create new struct literal reflecting updated fieldi
1574 */ 1749 */
1575 Expressions *expsx = new Expressions(); 1750 Expressions *expsx = changeOneElement(se->elements, fieldi, e2);
1576 expsx->setDim(se->elements->dim);
1577 for (size_t j = 0; j < expsx->dim; j++)
1578 {
1579 if (j == fieldi)
1580 expsx->data[j] = (void *)e2;
1581 else
1582 expsx->data[j] = se->elements->data[j];
1583 }
1584 v->value = new StructLiteralExp(se->loc, se->sd, expsx); 1751 v->value = new StructLiteralExp(se->loc, se->sd, expsx);
1585 v->value->type = se->type; 1752 v->value->type = se->type;
1586 1753
1587 e = Cast(type, type, post ? ev : e2); 1754 e = Cast(type, type, post ? ev : e2);
1588 } 1755 }
1592 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff) 1759 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff)
1593 { SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1; 1760 { SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1;
1594 VarDeclaration *v = soe->var->isVarDeclaration(); 1761 VarDeclaration *v = soe->var->isVarDeclaration();
1595 1762
1596 if (v->isDataseg()) 1763 if (v->isDataseg())
1764 {
1765 error("%s cannot be modified at compile time", v->toChars());
1597 return EXP_CANT_INTERPRET; 1766 return EXP_CANT_INTERPRET;
1767 }
1598 if (fp && !v->value) 1768 if (fp && !v->value)
1599 { error("variable %s is used before initialization", v->toChars()); 1769 { error("variable %s is used before initialization", v->toChars());
1600 return e; 1770 return e;
1601 } 1771 }
1602 Expression *vie = v->value; 1772 Expression *vie = v->value;
1617 else 1787 else
1618 e2 = Cast(type, type, e2); 1788 e2 = Cast(type, type, e2);
1619 if (e2 == EXP_CANT_INTERPRET) 1789 if (e2 == EXP_CANT_INTERPRET)
1620 return e2; 1790 return e2;
1621 1791
1622 if (!v->isParameter()) 1792 addVarToInterstate(istate, v);
1623 {
1624 for (size_t i = 0; 1; i++)
1625 {
1626 if (i == istate->vars.dim)
1627 { istate->vars.push(v);
1628 break;
1629 }
1630 if (v == (VarDeclaration *)istate->vars.data[i])
1631 break;
1632 }
1633 }
1634 1793
1635 /* Create new struct literal reflecting updated fieldi 1794 /* Create new struct literal reflecting updated fieldi
1636 */ 1795 */
1637 Expressions *expsx = new Expressions(); 1796 Expressions *expsx = changeOneElement(se->elements, fieldi, e2);
1638 expsx->setDim(se->elements->dim);
1639 for (size_t j = 0; j < expsx->dim; j++)
1640 {
1641 if (j == fieldi)
1642 expsx->data[j] = (void *)e2;
1643 else
1644 expsx->data[j] = se->elements->data[j];
1645 }
1646 v->value = new StructLiteralExp(se->loc, se->sd, expsx); 1797 v->value = new StructLiteralExp(se->loc, se->sd, expsx);
1647 v->value->type = se->type; 1798 v->value->type = se->type;
1648 1799
1649 e = Cast(type, type, post ? ev : e2); 1800 e = Cast(type, type, post ? ev : e2);
1650 } 1801 }
1653 */ 1804 */
1654 else if (e1->op == TOKindex && ((IndexExp *)e1)->e1->op == TOKvar) 1805 else if (e1->op == TOKindex && ((IndexExp *)e1)->e1->op == TOKvar)
1655 { IndexExp *ie = (IndexExp *)e1; 1806 { IndexExp *ie = (IndexExp *)e1;
1656 VarExp *ve = (VarExp *)ie->e1; 1807 VarExp *ve = (VarExp *)ie->e1;
1657 VarDeclaration *v = ve->var->isVarDeclaration(); 1808 VarDeclaration *v = ve->var->isVarDeclaration();
1658
1659 if (!v || v->isDataseg()) 1809 if (!v || v->isDataseg())
1810 {
1811 error("%s cannot be modified at compile time", v ? v->toChars(): "void");
1660 return EXP_CANT_INTERPRET; 1812 return EXP_CANT_INTERPRET;
1813 }
1814 if (v->value && v->value->op == TOKvar)
1815 {
1816 VarExp *ve2 = (VarExp *)v->value;
1817 // TODO
1818 #ifdef IN_DMD
1819 if (ve2->var->isSymbolDeclaration())
1820 { // This can happen if v is a struct initialized to
1821 // 0 using an __initZ SymbolDeclaration from
1822 // TypeStruct::defaultInit()
1823 }
1824 else
1825 #endif
1826 v = ve2->var->isVarDeclaration();
1827 assert(v);
1828 }
1661 if (!v->value) 1829 if (!v->value)
1662 { 1830 {
1663 if (fp) 1831 if (fp)
1664 { error("variable %s is used before initialization", v->toChars()); 1832 { error("variable %s is used before initialization", v->toChars());
1665 return e; 1833 return e;
1673 * What we should do is fill the array literal with 1841 * What we should do is fill the array literal with
1674 * NULL data, so use-before-initialized can be detected. 1842 * NULL data, so use-before-initialized can be detected.
1675 * But we're too lazy at the moment to do it, as that 1843 * But we're too lazy at the moment to do it, as that
1676 * involves redoing Index() and whoever calls it. 1844 * involves redoing Index() and whoever calls it.
1677 */ 1845 */
1678 Expression *ev = v->type->defaultInit(); 1846
1679 size_t dim = ((TypeSArray *)t)->dim->toInteger(); 1847 size_t dim = ((TypeSArray *)t)->dim->toInteger();
1680 Expressions *elements = new Expressions(); 1848 v->value = createBlockDuplicatedArrayLiteral(v->type,
1681 elements->setDim(dim); 1849 v->type->defaultInit(), dim);
1682 for (size_t i = 0; i < dim; i++)
1683 elements->data[i] = (void *)ev;
1684 ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements);
1685 ae->type = v->type;
1686 v->value = ae;
1687 } 1850 }
1688 else 1851 else
1689 return EXP_CANT_INTERPRET; 1852 return EXP_CANT_INTERPRET;
1690 } 1853 }
1691 1854
1696 ae = (ArrayLiteralExp *)v->value; 1859 ae = (ArrayLiteralExp *)v->value;
1697 else if (v->value->op == TOKassocarrayliteral) 1860 else if (v->value->op == TOKassocarrayliteral)
1698 aae = (AssocArrayLiteralExp *)v->value; 1861 aae = (AssocArrayLiteralExp *)v->value;
1699 else if (v->value->op == TOKstring) 1862 else if (v->value->op == TOKstring)
1700 se = (StringExp *)v->value; 1863 se = (StringExp *)v->value;
1864 else if (v->value->op == TOKnull)
1865 {
1866 // This would be a runtime segfault
1867 error("Cannot index null array %s", v->toChars());
1868 return EXP_CANT_INTERPRET;
1869 }
1701 else 1870 else
1702 return EXP_CANT_INTERPRET; 1871 return EXP_CANT_INTERPRET;
1703 1872
1873 /* Set the $ variable
1874 */
1875 Expression *ee = ArrayLength(Type::tsize_t, v->value);
1876 if (ee != EXP_CANT_INTERPRET && ie->lengthVar)
1877 ie->lengthVar->value = ee;
1704 Expression *index = ie->e2->interpret(istate); 1878 Expression *index = ie->e2->interpret(istate);
1705 if (index == EXP_CANT_INTERPRET) 1879 if (index == EXP_CANT_INTERPRET)
1706 return EXP_CANT_INTERPRET; 1880 return EXP_CANT_INTERPRET;
1707 Expression *ev; 1881 Expression *ev;
1708 if (fp || ae || se) // not for aae, because key might not be there 1882 if (fp || ae || se) // not for aae, because key might not be there
1716 e2 = (*fp)(type, ev, e2); 1890 e2 = (*fp)(type, ev, e2);
1717 else 1891 else
1718 e2 = Cast(type, type, e2); 1892 e2 = Cast(type, type, e2);
1719 if (e2 == EXP_CANT_INTERPRET) 1893 if (e2 == EXP_CANT_INTERPRET)
1720 return e2; 1894 return e2;
1721 1895
1722 if (!v->isParameter()) 1896 addVarToInterstate(istate, v);
1723 {
1724 for (size_t i = 0; 1; i++)
1725 {
1726 if (i == istate->vars.dim)
1727 { istate->vars.push(v);
1728 break;
1729 }
1730 if (v == (VarDeclaration *)istate->vars.data[i])
1731 break;
1732 }
1733 }
1734
1735 if (ae) 1897 if (ae)
1736 { 1898 {
1737 /* Create new array literal reflecting updated elem 1899 /* Create new array literal reflecting updated elem
1738 */ 1900 */
1739 int elemi = index->toInteger(); 1901 int elemi = index->toInteger();
1740 Expressions *expsx = new Expressions(); 1902 Expressions *expsx = changeOneElement(ae->elements, elemi, e2);
1741 expsx->setDim(ae->elements->dim);
1742 for (size_t j = 0; j < expsx->dim; j++)
1743 {
1744 if (j == elemi)
1745 expsx->data[j] = (void *)e2;
1746 else
1747 expsx->data[j] = ae->elements->data[j];
1748 }
1749 v->value = new ArrayLiteralExp(ae->loc, expsx); 1903 v->value = new ArrayLiteralExp(ae->loc, expsx);
1750 v->value->type = ae->type; 1904 v->value->type = ae->type;
1751 } 1905 }
1752 else if (aae) 1906 else if (aae)
1753 { 1907 {
1806 else 1960 else
1807 assert(0); 1961 assert(0);
1808 1962
1809 e = Cast(type, type, post ? ev : e2); 1963 e = Cast(type, type, post ? ev : e2);
1810 } 1964 }
1965
1966 /* Assignment to struct element in array, of the form:
1967 * a[i].var = e2
1968 */
1969 else if (e1->op == TOKdotvar && aggregate->op == TOKindex &&
1970 ((IndexExp *)aggregate)->e1->op == TOKvar)
1971 {
1972 IndexExp * ie = (IndexExp *)aggregate;
1973 VarExp *ve = (VarExp *)(ie->e1);
1974 VarDeclaration *v = ve->var->isVarDeclaration();
1975 if (!v || v->isDataseg())
1976 {
1977 error("%s cannot be modified at compile time", v ? v->toChars(): "void");
1978 return EXP_CANT_INTERPRET;
1979 }
1980 Type *t = ve->type->toBasetype();
1981 ArrayLiteralExp *ae = (ArrayLiteralExp *)v->value;
1982 if (!ae)
1983 {
1984 // assignment to one element in an uninitialized (static) array.
1985 // This is quite difficult, because defaultInit() for a struct is a VarExp,
1986 // not a StructLiteralExp.
1987 Type *t = v->type->toBasetype();
1988 if (t->ty != Tsarray)
1989 {
1990 error("Cannot index an uninitialized variable");
1991 return EXP_CANT_INTERPRET;
1992 }
1993
1994 Type *telem = ((TypeSArray *)t)->nextOf()->toBasetype();
1995 if (telem->ty != Tstruct) { return EXP_CANT_INTERPRET; }
1996
1997 // Create a default struct literal...
1998 StructDeclaration *sym = ((TypeStruct *)telem)->sym;
1999 StructLiteralExp *structinit = createDefaultInitStructLiteral(v->loc, sym);
2000
2001 // ... and use to create a blank array literal
2002 size_t dim = ((TypeSArray *)t)->dim->toInteger();
2003 ae = createBlockDuplicatedArrayLiteral(v->type, structinit, dim);
2004 v->value = ae;
2005 }
2006 if ((Expression *)(ae->elements) == EXP_CANT_INTERPRET)
2007 {
2008 // Note that this would be a runtime segfault
2009 error("Cannot index null array %s", v->toChars());
2010 return EXP_CANT_INTERPRET;
2011 }
2012 // Set the $ variable
2013 Expression *ee = ArrayLength(Type::tsize_t, v->value);
2014 if (ee != EXP_CANT_INTERPRET && ie->lengthVar)
2015 ie->lengthVar->value = ee;
2016 // Determine the index, and check that it's OK.
2017 Expression *index = ie->e2->interpret(istate);
2018 if (index == EXP_CANT_INTERPRET)
2019 return EXP_CANT_INTERPRET;
2020
2021 int elemi = index->toInteger();
2022 if (elemi >= ae->elements->dim)
2023 {
2024 error("array index %d is out of bounds %s[0..%d]", elemi,
2025 v->toChars(), ae->elements->dim);
2026 return EXP_CANT_INTERPRET;
2027 }
2028 // Get old element
2029 Expression *vie = (Expression *)(ae->elements->data[elemi]);
2030 if (vie->op != TOKstructliteral)
2031 return EXP_CANT_INTERPRET;
2032
2033 // Work out which field needs to be changed
2034 StructLiteralExp *se = (StructLiteralExp *)vie;
2035 VarDeclaration *vf = ((DotVarExp *)e1)->var->isVarDeclaration();
2036 if (!vf)
2037 return EXP_CANT_INTERPRET;
2038
2039 int fieldi = se->getFieldIndex(type, vf->offset);
2040 if (fieldi == -1)
2041 return EXP_CANT_INTERPRET;
2042
2043 Expression *ev = se->getField(type, vf->offset);
2044 if (fp)
2045 e2 = (*fp)(type, ev, e2);
2046 else
2047 e2 = Cast(type, type, e2);
2048 if (e2 == EXP_CANT_INTERPRET)
2049 return e2;
2050
2051 // Create new struct literal reflecting updated field
2052 Expressions *expsx = changeOneElement(se->elements, fieldi, e2);
2053 Expression * newstruct = new StructLiteralExp(se->loc, se->sd, expsx);
2054
2055 // Create new array literal reflecting updated struct elem
2056 ae->elements = changeOneElement(ae->elements, elemi, newstruct);
2057 return ae;
2058 }
2059 /* Slice assignment, initialization of static arrays
2060 * a[] = e
2061 */
2062 else if (e1->op == TOKslice && ((SliceExp *)e1)->e1->op==TOKvar)
2063 {
2064 SliceExp * sexp = (SliceExp *)e1;
2065 VarExp *ve = (VarExp *)(sexp->e1);
2066 VarDeclaration *v = ve->var->isVarDeclaration();
2067 if (!v || v->isDataseg())
2068 {
2069 error("%s cannot be modified at compile time", v->toChars());
2070 return EXP_CANT_INTERPRET;
2071 }
2072 // Chase down rebinding of out and ref
2073 if (v->value && v->value->op == TOKvar)
2074 {
2075 VarExp *ve2 = (VarExp *)v->value;
2076 // TODO
2077 #ifdef IN_DMD
2078 if (ve2->var->isSymbolDeclaration())
2079 { // This can happen if v is a struct initialized to
2080 // 0 using an __initZ SymbolDeclaration from
2081 // TypeStruct::defaultInit()
2082 }
2083 else
2084 #endif
2085 v = ve2->var->isVarDeclaration();
2086 assert(v);
2087 }
2088 /* Set the $ variable
2089 */
2090 Expression *ee = v->value ? ArrayLength(Type::tsize_t, v->value)
2091 : EXP_CANT_INTERPRET;
2092 if (ee != EXP_CANT_INTERPRET && sexp->lengthVar)
2093 sexp->lengthVar->value = ee;
2094 Expression *upper = NULL;
2095 Expression *lower = NULL;
2096 if (sexp->upr)
2097 {
2098 upper = sexp->upr->interpret(istate);
2099 if (upper == EXP_CANT_INTERPRET)
2100 return EXP_CANT_INTERPRET;
2101 }
2102 if (sexp->lwr)
2103 {
2104 lower = sexp->lwr->interpret(istate);
2105 if (lower == EXP_CANT_INTERPRET)
2106 return EXP_CANT_INTERPRET;
2107 }
2108 Type *t = v->type->toBasetype();
2109 size_t dim;
2110 if (t->ty == Tsarray)
2111 dim = ((TypeSArray *)t)->dim->toInteger();
2112 else if (t->ty == Tarray)
2113 {
2114 if (!v->value || v->value->op == TOKnull)
2115 {
2116 error("cannot assign to null array %s", v->toChars());
2117 return EXP_CANT_INTERPRET;
2118 }
2119 if (v->value->op == TOKarrayliteral)
2120 dim = ((ArrayLiteralExp *)v->value)->elements->dim;
2121 else if (v->value->op ==TOKstring)
2122 {
2123 error("String slice assignment is not yet supported in CTFE");
2124 return EXP_CANT_INTERPRET;
2125 }
2126 }
2127 else
2128 {
2129 error("%s cannot be evaluated at compile time", toChars());
2130 return EXP_CANT_INTERPRET;
2131 }
2132 int upperbound = upper ? upper->toInteger() : dim;
2133 int lowerbound = lower ? lower->toInteger() : 0;
2134
2135 ArrayLiteralExp *existing;
2136 if (((int)lowerbound < 0) || (upperbound > dim))
2137 {
2138 error("Array bounds [0..%d] exceeded in slice [%d..%d]", dim, lowerbound, upperbound);
2139 return EXP_CANT_INTERPRET;
2140 }
2141 if (upperbound-lowerbound != dim)
2142 {
2143 // Only modifying part of the array. Must create a new array literal.
2144 // If the existing array is uninitialized (this can only happen
2145 // with static arrays), create it.
2146 if (v->value && v->value->op == TOKarrayliteral)
2147 existing = (ArrayLiteralExp *)v->value;
2148 else
2149 {
2150 // this can only happen with static arrays
2151 existing = createBlockDuplicatedArrayLiteral(v->type, v->type->defaultInit(), dim);
2152 }
2153 }
2154
2155 if (e2->op == TOKarrayliteral)
2156 {
2157 // Static array assignment from literal
2158 ArrayLiteralExp *ae = (ArrayLiteralExp *)e2;
2159 if (ae->elements->dim != (upperbound - lowerbound))
2160 {
2161 error("Array length mismatch assigning [0..%d] to [%d..%d]", ae->elements->dim, lowerbound, upperbound);
2162 return e;
2163 }
2164 if (upperbound - lowerbound == dim)
2165 v->value = ae;
2166 else
2167 {
2168 // value[] = value[0..lower] ~ ae ~ value[upper..$]
2169 existing->elements = spliceElements(existing->elements, ae->elements, lowerbound);
2170 v->value = existing;
2171 }
2172 return e2;
2173 }
2174 else if (t->nextOf()->ty == e2->type->ty)
2175 {
2176 // Static array block assignment
2177 if (upperbound-lowerbound ==dim)
2178 v->value = createBlockDuplicatedArrayLiteral(v->type, e2, dim);
2179 else
2180 {
2181 // value[] = value[0..lower] ~ ae ~ value[upper..$]
2182 existing->elements = spliceElements(existing->elements, createBlockDuplicatedArrayLiteral(v->type, e2, upperbound-lowerbound)->elements, lowerbound);
2183 v->value = existing;
2184 }
2185 return e2;
2186 }
2187 else if (e2->op == TOKstring)
2188 {
2189 StringExp *se = (StringExp *)e2;
2190 // This is problematic. char[8] should be storing
2191 // values as a string literal, not
2192 // as an array literal. Then, for static arrays, we
2193 // could do modifications
2194 // in-place, with a dramatic memory and speed improvement.
2195 error("String slice assignment is not yet supported in CTFE");
2196 return e2;
2197 }
2198 else
2199 {
2200 error("Slice operation %s cannot be evaluated at compile time", toChars());
2201 return e;
2202 }
2203 }
1811 else 2204 else
1812 { 2205 {
2206 error("%s cannot be evaluated at compile time", toChars());
1813 #ifdef DEBUG 2207 #ifdef DEBUG
1814 dump(0); 2208 dump(0);
1815 #endif 2209 #endif
1816 } 2210 }
1817 return e; 2211 return e;
1921 { Expression *e = EXP_CANT_INTERPRET; 2315 { Expression *e = EXP_CANT_INTERPRET;
1922 2316
1923 #if LOG 2317 #if LOG
1924 printf("CallExp::interpret() %s\n", toChars()); 2318 printf("CallExp::interpret() %s\n", toChars());
1925 #endif 2319 #endif
2320 if (e1->op == TOKdotvar)
2321 {
2322 Expression * pthis = ((DotVarExp*)e1)->e1;
2323 FuncDeclaration *fd = ((DotVarExp*)e1)->var->isFuncDeclaration();
2324 TypeFunction *tf = fd ? (TypeFunction *)(fd->type) : NULL;
2325 if (tf)
2326 { // Member function call
2327 if(pthis->op == TOKthis)
2328 pthis = istate->localThis;
2329 Expression *eresult = fd->interpret(istate, arguments, pthis);
2330 if (eresult)
2331 e = eresult;
2332 else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors)
2333 e = EXP_VOID_INTERPRET;
2334 else
2335 error("cannot evaluate %s at compile time", toChars());
2336 return e;
2337 }
2338 error("cannot evaluate %s at compile time", toChars());
2339 return EXP_CANT_INTERPRET;
2340 }
1926 if (e1->op == TOKvar) 2341 if (e1->op == TOKvar)
1927 { 2342 {
1928 FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration(); 2343 FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration();
1929 if (fd) 2344 if (fd)
1930 { 2345 {
2153 Expression *e1; 2568 Expression *e1;
2154 2569
2155 #if LOG 2570 #if LOG
2156 printf("AssertExp::interpret() %s\n", toChars()); 2571 printf("AssertExp::interpret() %s\n", toChars());
2157 #endif 2572 #endif
2573 if( this->e1->op == TOKaddress)
2574 { // Special case: deal with compiler-inserted assert(&this, "null this")
2575 AddrExp *ade = (AddrExp *)this->e1;
2576 if(ade->e1->op == TOKthis && istate->localThis)
2577 return istate->localThis->interpret(istate);
2578 }
2579 if (this->e1->op == TOKthis)
2580 {
2581 if(istate->localThis)
2582 return istate->localThis->interpret(istate);
2583 }
2158 e1 = this->e1->interpret(istate); 2584 e1 = this->e1->interpret(istate);
2159 if (e1 == EXP_CANT_INTERPRET) 2585 if (e1 == EXP_CANT_INTERPRET)
2160 goto Lcant; 2586 goto Lcant;
2161 if (e1->isBool(TRUE)) 2587 if (e1->isBool(TRUE))
2162 { 2588 {
2221 if (!e) 2647 if (!e)
2222 e = EXP_CANT_INTERPRET; 2648 e = EXP_CANT_INTERPRET;
2223 } 2649 }
2224 } 2650 }
2225 } 2651 }
2652 #if DMDV2
2653 #else // this is required for D1, where structs return *this instead of 'this'.
2654 else if (e1->op == TOKthis)
2655 {
2656 if(istate->localThis)
2657 return istate->localThis->interpret(istate);
2658 }
2659 #endif
2226 #if LOG 2660 #if LOG
2227 if (e == EXP_CANT_INTERPRET) 2661 if (e == EXP_CANT_INTERPRET)
2228 printf("PtrExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars()); 2662 printf("PtrExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars());
2229 #endif 2663 #endif
2230 return e; 2664 return e;
2247 { e = se->getField(type, v->offset); 2681 { e = se->getField(type, v->offset);
2248 if (!e) 2682 if (!e)
2249 e = EXP_CANT_INTERPRET; 2683 e = EXP_CANT_INTERPRET;
2250 return e; 2684 return e;
2251 } 2685 }
2252 } 2686 } else error("%s.%s is not yet implemented at compile time", ex->toChars(), var->toChars());
2253 } 2687 }
2254 2688
2255 #if LOG 2689 #if LOG
2256 if (e == EXP_CANT_INTERPRET) 2690 if (e == EXP_CANT_INTERPRET)
2257 printf("DotVarExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars()); 2691 printf("DotVarExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars());
2276 return e; 2710 return e;
2277 } 2711 }
2278 2712
2279 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments) 2713 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments)
2280 { 2714 {
2281 //printf("interpret_aaKeys()\n"); 2715 #if LOG
2716 printf("interpret_aaKeys()\n");
2717 #endif
2282 if (!arguments || arguments->dim != 2) 2718 if (!arguments || arguments->dim != 2)
2283 return NULL; 2719 return NULL;
2284 Expression *earg = (Expression *)arguments->data[0]; 2720 Expression *earg = (Expression *)arguments->data[0];
2285 earg = earg->interpret(istate); 2721 earg = earg->interpret(istate);
2286 if (earg == EXP_CANT_INTERPRET) 2722 if (earg == EXP_CANT_INTERPRET)
2287 return NULL; 2723 return NULL;
2288 if (earg->op != TOKassocarrayliteral) 2724 if (earg->op != TOKassocarrayliteral)
2289 return NULL; 2725 return NULL;
2290 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; 2726 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
2291 Expression *e = new ArrayLiteralExp(aae->loc, aae->keys); 2727 Expression *e = new ArrayLiteralExp(aae->loc, aae->keys);
2728 Type *elemType = ((TypeAArray *)aae->type)->index;
2729 e->type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments->dim : 0));
2292 return e; 2730 return e;
2293 } 2731 }
2294 2732
2295 Expression *interpret_aaValues(InterState *istate, Expressions *arguments) 2733 Expression *interpret_aaValues(InterState *istate, Expressions *arguments)
2296 { 2734 {
2303 return NULL; 2741 return NULL;
2304 if (earg->op != TOKassocarrayliteral) 2742 if (earg->op != TOKassocarrayliteral)
2305 return NULL; 2743 return NULL;
2306 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; 2744 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
2307 Expression *e = new ArrayLiteralExp(aae->loc, aae->values); 2745 Expression *e = new ArrayLiteralExp(aae->loc, aae->values);
2746 Type *elemType = ((TypeAArray *)aae->type)->next;
2747 e->type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments->dim : 0));
2308 //printf("result is %s\n", e->toChars()); 2748 //printf("result is %s\n", e->toChars());
2309 return e; 2749 return e;
2310 } 2750 }
2311 2751