root/trunk/src/interpret.c

Revision 791, 97.5 kB (checked in by walter, 1 year ago)

bugzilla 5238 PATCH: fix return of uninitialised var in interpret.c

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2010 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <assert.h>
13
14 #include "rmem.h"
15
16 #include "statement.h"
17 #include "expression.h"
18 #include "cond.h"
19 #include "init.h"
20 #include "staticassert.h"
21 #include "mtype.h"
22 #include "scope.h"
23 #include "declaration.h"
24 #include "aggregate.h"
25 #include "id.h"
26
27 #define LOG     0
28
29 struct InterState
30 {
31     InterState *caller;         // calling function's InterState
32     FuncDeclaration *fd;        // function being interpreted
33     Dsymbols vars;              // variables used in this function
34     Statement *start;           // if !=NULL, start execution at this statement
35     Statement *gotoTarget;      // target of EXP_GOTO_INTERPRET result
36     Expression *localThis;      // value of 'this', or NULL if none
37     bool awaitingLvalueReturn;  // Support for ref return values:
38            // Any return to this function should return an lvalue.
39     InterState();
40 };
41
42 InterState::InterState()
43 {
44     memset(this, 0, sizeof(InterState));
45 }
46
47 Expression *interpret_aaLen(InterState *istate, Expressions *arguments);
48 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments);
49 Expression *interpret_aaValues(InterState *istate, Expressions *arguments);
50
51 Expression *interpret_length(InterState *istate, Expression *earg);
52 Expression *interpret_keys(InterState *istate, Expression *earg, FuncDeclaration *fd);
53 Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclaration *fd);
54
55 ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Type *type, Expression *elem, size_t dim);
56 Expression * resolveReferences(Expression *e, Expression *thisval, bool *isReference = NULL);
57 Expression *getVarExp(Loc loc, InterState *istate, Declaration *d);
58 VarDeclaration *findParentVar(Expression *e, Expression *thisval);
59
60 /*************************************
61  * Attempt to interpret a function given the arguments.
62  * Input:
63  *      istate     state for calling function (NULL if none)
64  *      arguments  function arguments
65  *      thisarg    'this', if a needThis() function, NULL if not.
66  *
67  * Return result expression if successful, NULL if not.
68  */
69
70 Expression *FuncDeclaration::interpret(InterState *istate, Expressions *arguments, Expression *thisarg)
71 {
72 #if LOG
73     printf("\n********\nFuncDeclaration::interpret(istate = %p) %s\n", istate, toChars());
74     printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret, semanticRun);
75 #endif
76     if (global.errors)
77         return NULL;
78 #if DMDV2
79     if (thisarg &&
80         (!arguments || arguments->dim == 0))
81     {
82         if (ident == Id::length)
83             return interpret_length(istate, thisarg);
84         else if (ident == Id::keys)
85             return interpret_keys(istate, thisarg, this);
86         else if (ident == Id::values)
87             return interpret_values(istate, thisarg, this);
88     }
89 #endif
90
91     if (cantInterpret || semanticRun == PASSsemantic3)
92         return NULL;
93
94     if (!fbody)
95     {   cantInterpret = 1;
96         error("cannot be interpreted at compile time,"
97             " because it has no available source code");
98         return NULL;
99     }
100
101     if (semanticRun < PASSsemantic3 && scope)
102     {
103         semantic3(scope);
104         if (global.errors)      // if errors compiling this function
105             return NULL;
106     }
107     if (semanticRun < PASSsemantic3done)
108         return NULL;
109
110     Type *tb = type->toBasetype();
111     assert(tb->ty == Tfunction);
112     TypeFunction *tf = (TypeFunction *)tb;
113     Type *tret = tf->next->toBasetype();
114     if (tf->varargs && arguments &&
115         ((parameters && arguments->dim != parameters->dim) || (!parameters && arguments->dim)))
116     {   cantInterpret = 1;
117         error("C-style variadic functions are not yet implemented in CTFE");
118         return NULL;
119     }
120
121     InterState istatex;
122     istatex.caller = istate;
123     istatex.fd = this;
124     istatex.localThis = thisarg;
125
126     Expressions vsave;          // place to save previous parameter values
127     size_t dim = 0;
128     if (needThis() && !thisarg)
129     {   cantInterpret = 1;
130         // error, no this. Prevent segfault.
131         error("need 'this' to access member %s", toChars());
132         return NULL;
133     }
134     if (thisarg && !istate)
135     {   // Check that 'this' aleady has a value
136         if (thisarg->interpret(istate) == EXP_CANT_INTERPRET)
137             return NULL;
138     }
139     if (arguments)
140     {
141         dim = arguments->dim;
142         assert(!dim || (parameters && (parameters->dim == dim)));
143         vsave.setDim(dim);
144
145         /* Evaluate all the arguments to the function,
146          * store the results in eargs[]
147          */
148         Expressions eargs;
149         eargs.setDim(dim);
150
151         for (size_t i = 0; i < dim; i++)
152         {   Expression *earg = (Expression *)arguments->data[i];
153             Parameter *arg = Parameter::getNth(tf->parameters, i);
154
155             if (arg->storageClass & (STCout | STCref))
156             {
157                 if (!istate)
158                 {
159                     earg->error("%s cannot be passed by reference at compile time", earg->toChars());
160                     return NULL;
161                 }
162             }
163             else if (arg->storageClass & STClazy)
164             {
165             }
166             else
167             {   /* Value parameters
168                  */
169                 Type *ta = arg->type->toBasetype();
170                 if (ta->ty == Tsarray && earg->op == TOKaddress)
171                 {
172                     /* Static arrays are passed by a simple pointer.
173                      * Skip past this to get at the actual arg.
174                      */
175                     earg = ((AddrExp *)earg)->e1;
176                 }
177                 earg = earg->interpret(istate); // ? istate : &istatex);
178                 if (earg == EXP_CANT_INTERPRET)
179                 {   cantInterpret = 1;
180                     return NULL;
181                 }
182             }
183             eargs.data[i] = earg;
184         }
185
186         for (size_t i = 0; i < dim; i++)
187         {   Expression *earg = (Expression *)eargs.data[i];
188             Parameter *arg = Parameter::getNth(tf->parameters, i);
189             VarDeclaration *v = (VarDeclaration *)parameters->data[i];
190             vsave.data[i] = v->value;
191 #if LOG
192             printf("arg[%d] = %s\n", i, earg->toChars());
193 #endif
194             if (arg->storageClass & (STCout | STCref) && earg->op==TOKvar)
195             {
196                 VarExp *ve = (VarExp *)earg;
197                 VarDeclaration *v2 = ve->var->isVarDeclaration();
198                 if (!v2)
199                 {   cantInterpret = 1;
200                         return NULL;
201                 }
202                 v->value = earg;
203                 /* Don't restore the value of v2 upon function return
204                  */
205                 assert(istate);
206                 for (size_t i = 0; i < istate->vars.dim; i++)
207                 {   VarDeclaration *vx = (VarDeclaration *)istate->vars.data[i];
208                     if (vx == v2)
209                     {   istate->vars.data[i] = NULL;
210                         break;
211                     }
212                 }
213             }
214             else
215             {   // Value parameters and non-trivial references
216                 v->value = earg;
217             }
218 #if LOG
219             printf("interpreted arg[%d] = %s\n", i, earg->toChars());
220 #endif
221         }
222     }
223     // Don't restore the value of 'this' upon function return
224     if (needThis() && istate)
225     {
226         VarDeclaration *thisvar = findParentVar(thisarg, istate->localThis);
227         if (!thisvar) // it's a reference. Find which variable it refers to.
228             thisvar = findParentVar(thisarg->interpret(istate), istate->localThis);
229         for (size_t i = 0; i < istate->vars.dim; i++)
230         {   VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
231             if (v == thisvar)
232             {   istate->vars.data[i] = NULL;
233                 break;
234             }
235         }
236     }
237
238     /* Save the values of the local variables used
239      */
240     Expressions valueSaves;
241     if (istate && !isNested())
242     {
243         //printf("saving local variables...\n");
244         valueSaves.setDim(istate->vars.dim);
245         for (size_t i = 0; i < istate->vars.dim; i++)
246         {   VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
247             if (v)
248             {
249                 //printf("\tsaving [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : "");
250                 valueSaves.data[i] = v->value;
251                 v->value = NULL;
252             }
253         }
254     }
255
256     Expression *e = NULL;
257     while (1)
258     {
259         e = fbody->interpret(&istatex);
260         if (e == EXP_CANT_INTERPRET)
261         {
262 #if LOG
263             printf("function body failed to interpret\n");
264 #endif
265             e = NULL;
266         }
267
268         /* This is how we deal with a recursive statement AST
269          * that has arbitrary goto statements in it.
270          * Bubble up a 'result' which is the target of the goto
271          * statement, then go recursively down the AST looking
272          * for that statement, then execute starting there.
273          */
274         if (e == EXP_GOTO_INTERPRET)
275         {
276             istatex.start = istatex.gotoTarget; // set starting statement
277             istatex.gotoTarget = NULL;
278         }
279         else
280             break;
281     }
282     /* Restore the parameter values
283      */
284     for (size_t i = 0; i < dim; i++)
285     {
286         VarDeclaration *v = (VarDeclaration *)parameters->data[i];
287         v->value = (Expression *)vsave.data[i];
288     }
289
290     if (istate && !isNested())
291     {
292         /* Restore the variable values
293          */
294         //printf("restoring local variables...\n");
295         for (size_t i = 0; i < istate->vars.dim; i++)
296         {   VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
297             if (v)
298             {   v->value = (Expression *)valueSaves.data[i];
299                 //printf("\trestoring [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : "");
300             }
301         }
302     }
303     return e;
304 }
305
306 /******************************** Statement ***************************/
307
308 #define START()                         \
309     if (istate->start)                  \
310     {   if (istate->start != this)      \
311             return NULL;                \
312         istate->start = NULL;           \
313     }
314
315 /***********************************
316  * Interpret the statement.
317  * Returns:
318  *      NULL    continue to next statement
319  *      EXP_CANT_INTERPRET      cannot interpret statement at compile time
320  *      !NULL   expression from return statement
321  */
322
323 Expression *Statement::interpret(InterState *istate)
324 {
325 #if LOG
326     printf("Statement::interpret()\n");
327 #endif
328     START()
329     error("Statement %s cannot be interpreted at compile time", this->toChars());
330     return EXP_CANT_INTERPRET;
331 }
332
333 Expression *ExpStatement::interpret(InterState *istate)
334 {
335 #if LOG
336     printf("ExpStatement::interpret(%s)\n", exp ? exp->toChars() : "");
337 #endif
338     START()
339     if (exp)
340     {
341         Expression *e = exp->interpret(istate);
342         if (e == EXP_CANT_INTERPRET)
343         {
344             //printf("-ExpStatement::interpret(): %p\n", e);
345             return EXP_CANT_INTERPRET;
346         }
347     }
348     return NULL;
349 }
350
351 Expression *CompoundStatement::interpret(InterState *istate)
352 {   Expression *e = NULL;
353
354 #if LOG
355     printf("CompoundStatement::interpret()\n");
356 #endif
357     if (istate->start == this)
358         istate->start = NULL;
359     if (statements)
360     {
361         for (size_t i = 0; i < statements->dim; i++)
362         {   Statement *s = (Statement *)statements->data[i];
363
364             if (s)
365             {
366                 e = s->interpret(istate);
367                 if (e)
368                     break;
369             }
370         }
371     }
372 #if LOG
373     printf("-CompoundStatement::interpret() %p\n", e);
374 #endif
375     return e;
376 }
377
378 Expression *UnrolledLoopStatement::interpret(InterState *istate)
379 {   Expression *e = NULL;
380
381 #if LOG
382     printf("UnrolledLoopStatement::interpret()\n");
383 #endif
384     if (istate->start == this)
385         istate->start = NULL;
386     if (statements)
387     {
388         for (size_t i = 0; i < statements->dim; i++)
389         {   Statement *s = (Statement *)statements->data[i];
390
391             e = s->interpret(istate);
392             if (e == EXP_CANT_INTERPRET)
393                 break;
394             if (e == EXP_CONTINUE_INTERPRET)
395             {   e = NULL;
396                 continue;
397             }
398             if (e == EXP_BREAK_INTERPRET)
399             {   e = NULL;
400                 break;
401             }
402             if (e)
403                 break;
404         }
405     }
406     return e;
407 }
408
409 Expression *IfStatement::interpret(InterState *istate)
410 {
411 #if LOG
412     printf("IfStatement::interpret(%s)\n", condition->toChars());
413 #endif
414
415     if (istate->start == this)
416         istate->start = NULL;
417     if (istate->start)
418     {
419         Expression *e = NULL;
420         if (ifbody)
421             e = ifbody->interpret(istate);
422         if (istate->start && elsebody)
423             e = elsebody->interpret(istate);
424         return e;
425     }
426
427     Expression *e = condition->interpret(istate);
428     assert(e);
429     //if (e == EXP_CANT_INTERPRET) printf("cannot interpret\n");
430     if (e != EXP_CANT_INTERPRET)
431     {
432         if (e->isBool(TRUE))
433             e = ifbody ? ifbody->interpret(istate) : NULL;
434         else if (e->isBool(FALSE))
435             e = elsebody ? elsebody->interpret(istate) : NULL;
436         else
437         {
438             e = EXP_CANT_INTERPRET;
439         }
440     }
441     return e;
442 }
443
444 Expression *ScopeStatement::interpret(InterState *istate)
445 {
446 #if LOG
447     printf("ScopeStatement::interpret()\n");
448 #endif
449     if (istate->start == this)
450         istate->start = NULL;
451     return statement ? statement->interpret(istate) : NULL;
452 }
453
454 // Helper for ReturnStatement::interpret() for returning references.
455 // Given an original expression, which is known to be a reference to a reference,
456 // turn it into a reference.
457 Expression * replaceReturnReference(Expression *original, InterState *istate)
458 {
459     Expression *e = original;
460     if (e->op == TOKcall)
461     {   // If it's a function call, interpret it now.
462         // It also needs to return an lvalue.
463         istate->awaitingLvalueReturn = true;
464         e  = e->interpret(istate);
465         if (e == EXP_CANT_INTERPRET)
466             return e;
467     }
468     // If it is a reference to a reference, convert it to a reference
469     if (e->op == TOKvar)
470     {
471         VarExp *ve = (VarExp *)e;
472         VarDeclaration *v = ve->var->isVarDeclaration();
473         assert (v && v->value);
474         return v->value;
475     }
476
477     if (e->op == TOKthis)
478     {
479         return istate->localThis;
480     }
481
482     Expression *r = e->copy();
483     e = r;
484     Expression *next;
485     for (;;)
486     {
487         if (e->op == TOKindex)
488             next = ((IndexExp*)e)->e1;
489         else if (e->op == TOKdotvar)
490             next = ((DotVarExp *)e)->e1;
491         else if (e->op == TOKdotti)
492             next = ((DotTemplateInstanceExp *)e)->e1;
493         else if (e->op == TOKslice)
494             next = ((SliceExp*)e)->e1;
495         else
496             return EXP_CANT_INTERPRET;
497
498         Expression *old = next;
499
500         if (next->op == TOKcall)
501         {
502             istate->awaitingLvalueReturn = true;
503             next = next->interpret(istate);
504             if (next == EXP_CANT_INTERPRET) return next;
505         }
506         if (next->op == TOKvar)
507         {
508             VarDeclaration * v = ((VarExp*)next)->var->isVarDeclaration();
509             if (v)
510                 next = v->value;
511         }
512         else if (next->op == TOKthis)
513             next = istate->localThis;
514
515         if (old == next)
516         {   // Haven't found the reference yet. Need to keep copying.
517             next = next->copy();
518             old = next;
519         }
520         if (e->op == TOKindex)
521             ((IndexExp*)e)->e1 = next;
522         else if (e->op == TOKdotvar)
523             ((DotVarExp *)e)->e1 = next;
524         else if (e->op == TOKdotti)
525             ((DotTemplateInstanceExp *)e)->e1 = next;
526         else if (e->op == TOKslice)
527             ((SliceExp*)e)->e1 = next;
528
529         if (old != next)
530             break;
531         e = next;
532     }
533
534      return r;
535 }
536
537 Expression *ReturnStatement::interpret(InterState *istate)
538 {
539 #if LOG
540     printf("ReturnStatement::interpret(%s)\n", exp ? exp->toChars() : "");
541 #endif
542     START()
543     if (!exp)
544         return EXP_VOID_INTERPRET;
545     assert(istate && istate->fd && istate->fd->type);
546 #if DMDV2
547     /* If the function returns a ref AND it's been called from an assignment,
548      * we need to return an lvalue. Otherwise, just do an (rvalue) interpret.
549      */
550     if (istate->fd->type && istate->fd->type->ty==Tfunction)
551     {
552         TypeFunction *tf = (TypeFunction *)istate->fd->type;
553         if (tf->isref && istate->caller && istate->caller->awaitingLvalueReturn)
554         {   // We need to return an lvalue. Can't do a normal interpret.
555             Expression *e = replaceReturnReference(exp, istate);
556             if (e == EXP_CANT_INTERPRET)
557                 error("ref return %s is not yet supported in CTFE", exp->toChars());
558             return e;
559         }
560         if (tf->next && (tf->next->ty == Tdelegate) && istate->fd->closureVars.dim > 0)
561         {
562             // To support this, we need to copy all the closure vars
563             // into the delegate literal.
564             error("closures are not yet supported in CTFE");
565             return EXP_CANT_INTERPRET;
566         }
567     }
568 #endif
569
570     Expression *e = exp->interpret(istate);
571     if (e == EXP_CANT_INTERPRET)
572         return e;
573     // Convert lvalues into rvalues (See Bugzilla 4825 for rationale)
574     if (e->op == TOKvar)
575         e = e->interpret(istate);
576     return e;
577 }
578
579 Expression *BreakStatement::interpret(InterState *istate)
580 {
581 #if LOG
582     printf("BreakStatement::interpret()\n");
583 #endif
584     START()
585     if (ident)
586         return EXP_CANT_INTERPRET;
587     else
588         return EXP_BREAK_INTERPRET;
589 }
590
591 Expression *ContinueStatement::interpret(InterState *istate)
592 {
593 #if LOG
594     printf("ContinueStatement::interpret()\n");
595 #endif
596     START()
597     if (ident)
598         return EXP_CANT_INTERPRET;
599     else
600         return EXP_CONTINUE_INTERPRET;
601 }
602
603 Expression *WhileStatement::interpret(InterState *istate)
604 {
605 #if LOG
606     printf("WhileStatement::interpret()\n");
607 #endif
608     assert(0);                  // rewritten to ForStatement
609     return NULL;
610 }
611
612 Expression *DoStatement::interpret(InterState *istate)
613 {
614 #if LOG
615     printf("DoStatement::interpret()\n");
616 #endif
617     if (istate->start == this)
618         istate->start = NULL;
619     Expression *e;
620
621     if (istate->start)
622     {
623         e = body ? body->interpret(istate) : NULL;
624         if (istate->start)
625             return NULL;
626         if (e == EXP_CANT_INTERPRET)
627             return e;
628         if (e == EXP_BREAK_INTERPRET)
629             return NULL;
630         if (e == EXP_CONTINUE_INTERPRET)
631             goto Lcontinue;
632         if (e)
633             return e;
634     }
635
636     while (1)
637     {
638         e = body ? body->interpret(istate) : NULL;
639         if (e == EXP_CANT_INTERPRET)
640             break;
641         if (e == EXP_BREAK_INTERPRET)
642         {   e = NULL;
643             break;
644         }
645         if (e && e != EXP_CONTINUE_INTERPRET)
646             break;
647
648     Lcontinue:
649         e = condition->interpret(istate);
650         if (e == EXP_CANT_INTERPRET)
651             break;
652         if (!e->isConst())
653         {   e = EXP_CANT_INTERPRET;
654             break;
655         }
656         if (e->isBool(TRUE))
657         {
658         }
659         else if (e->isBool(FALSE))
660         {   e = NULL;
661             break;
662         }
663         else
664             assert(0);
665     }
666     return e;
667 }
668
669 Expression *ForStatement::interpret(InterState *istate)
670 {
671 #if LOG
672     printf("ForStatement::interpret()\n");
673 #endif
674     if (istate->start == this)
675         istate->start = NULL;
676     Expression *e;
677
678     if (init)
679     {
680         e = init->interpret(istate);
681         if (e == EXP_CANT_INTERPRET)
682             return e;
683         assert(!e);
684     }
685
686     if (istate->start)
687     {
688         e = body ? body->interpret(istate) : NULL;
689         if (istate->start)
690             return NULL;
691         if (e == EXP_CANT_INTERPRET)
692             return e;
693         if (e == EXP_BREAK_INTERPRET)
694             return NULL;
695         if (e == EXP_CONTINUE_INTERPRET)
696             goto Lcontinue;
697         if (e)
698             return e;
699     }
700
701     while (1)
702     {
703         if (!condition)
704             goto Lhead;
705         e = condition->interpret(istate);
706         if (e == EXP_CANT_INTERPRET)
707             break;
708         if (!e->isConst())
709         {   e = EXP_CANT_INTERPRET;
710             break;
711         }
712         if (e->isBool(TRUE))
713         {
714         Lhead:
715             e = body ? body->interpret(istate) : NULL;
716             if (e == EXP_CANT_INTERPRET)
717                 break;
718             if (e == EXP_BREAK_INTERPRET)
719             {   e = NULL;
720                 break;
721             }
722             if (e && e != EXP_CONTINUE_INTERPRET)
723                 break;
724         Lcontinue:
725             if (increment)
726             {
727                 e = increment->interpret(istate);
728                 if (e == EXP_CANT_INTERPRET)
729                     break;
730             }
731         }
732         else if (e->isBool(FALSE))
733         {   e = NULL;
734             break;
735         }
736         else
737             assert(0);
738     }
739     return e;
740 }
741
742 Expression *ForeachStatement::interpret(InterState *istate)
743 {
744 #if 1
745     assert(0);                  // rewritten to ForStatement
746     return NULL;
747 #else
748 #if LOG
749     printf("ForeachStatement::interpret()\n");
750 #endif
751     if (istate->start == this)
752         istate->start = NULL;
753     if (istate->start)
754         return NULL;
755
756     Expression *e = NULL;
757     Expression *eaggr;
758
759     if (value->isOut() || value->isRef())
760         return EXP_CANT_INTERPRET;
761
762     eaggr = aggr->interpret(istate);
763     if (eaggr == EXP_CANT_INTERPRET)
764         return EXP_CANT_INTERPRET;
765
766     Expression *dim = ArrayLength(Type::tsize_t, eaggr);
767     if (dim == EXP_CANT_INTERPRET)
768         return EXP_CANT_INTERPRET;
769
770     Expression *keysave = key ? key->value : NULL;
771     Expression *valuesave = value->value;
772
773     uinteger_t d = dim->toUInteger();
774     uinteger_t index;
775
776     if (op == TOKforeach)
777     {
778         for (index = 0; index < d; index++)
779         {
780             Expression *ekey = new IntegerExp(loc, index, Type::tsize_t);
781             if (key)
782                 key->value = ekey;
783             e = Index(value->type, eaggr, ekey);
784             if (e == EXP_CANT_INTERPRET)
785                 break;
786             value->value = e;
787
788             e = body ? body->interpret(istate) : NULL;
789             if (e == EXP_CANT_INTERPRET)
790                 break;
791             if (e == EXP_BREAK_INTERPRET)
792             {   e = NULL;
793                 break;
794             }
795             if (e == EXP_CONTINUE_INTERPRET)
796                 e = NULL;
797             else if (e)
798                 break;
799         }
800     }
801     else // TOKforeach_reverse
802     {
803         for (index = d; index-- != 0;)
804         {
805             Expression *ekey = new IntegerExp(loc, index, Type::tsize_t);
806             if (key)
807                 key->value = ekey;
808             e = Index(value->type, eaggr, ekey);
809             if (e == EXP_CANT_INTERPRET)
810                 break;
811             value->value = e;
812
813             e = body ? body->interpret(istate) : NULL;
814             if (e == EXP_CANT_INTERPRET)
815                 break;
816             if (e == EXP_BREAK_INTERPRET)
817             {   e = NULL;
818                 break;
819             }
820             if (e == EXP_CONTINUE_INTERPRET)
821                 e = NULL;
822             else if (e)
823                 break;
824         }
825     }
826     value->value = valuesave;
827     if (key)
828         key->value = keysave;
829     return e;
830 #endif
831 }
832
833 #if DMDV2
834 Expression *ForeachRangeStatement::interpret(InterState *istate)
835 {
836 #if 1
837     assert(0);                  // rewritten to ForStatement
838     return NULL;
839 #else
840 #if LOG
841     printf("ForeachRangeStatement::interpret()\n");
842 #endif
843     if (istate->start == this)
844         istate->start = NULL;
845     if (istate->start)
846         return NULL;
847
848     Expression *e = NULL;
849     Expression *elwr = lwr->interpret(istate);
850     if (elwr == EXP_CANT_INTERPRET)
851         return EXP_CANT_INTERPRET;
852
853     Expression *eupr = upr->interpret(istate);
854     if (eupr == EXP_CANT_INTERPRET)
855         return EXP_CANT_INTERPRET;
856
857     Expression *keysave = key->value;
858
859     if (op == TOKforeach)
860     {
861         key->value = elwr;
862
863         while (1)
864         {
865             e = Cmp(TOKlt, key->value->type, key->value, eupr);
866             if (e == EXP_CANT_INTERPRET)
867                 break;
868             if (e->isBool(TRUE) == FALSE)
869             {   e = NULL;
870                 break;
871             }
872
873             e = body ? body->interpret(istate) : NULL;
874             if (e == EXP_CANT_INTERPRET)
875                 break;
876             if (e == EXP_BREAK_INTERPRET)
877             {   e = NULL;
878                 break;
879             }
880             if (e == NULL || e == EXP_CONTINUE_INTERPRET)
881             {   e = Add(key->value->type, key->value, new IntegerExp(loc, 1, key->value->type));
882                 if (e == EXP_CANT_INTERPRET)
883                     break;
884                 key->value = e;
885             }
886             else
887                 break;
888         }
889     }
890     else // TOKforeach_reverse
891     {
892         key->value = eupr;
893
894         do
895         {
896             e = Cmp(TOKgt, key->value->type, key->value, elwr);
897             if (e == EXP_CANT_INTERPRET)
898                 break;
899             if (e->isBool(TRUE) == FALSE)
900             {   e = NULL;
901                 break;
902             }
903
904             e = Min(key->value->type, key->value, new IntegerExp(loc, 1, key->value->type));
905             if (e == EXP_CANT_INTERPRET)
906                 break;
907             key->value = e;
908
909             e = body ? body->interpret(istate) : NULL;
910             if (e == EXP_CANT_INTERPRET)
911                 break;
912             if (e == EXP_BREAK_INTERPRET)
913             {   e = NULL;
914                 break;
915             }
916         } while (e == NULL || e == EXP_CONTINUE_INTERPRET);
917     }
918     key->value = keysave;
919     return e;
920 #endif
921 }
922 #endif
923
924 Expression *SwitchStatement::interpret(InterState *istate)
925 {
926 #if LOG
927     printf("SwitchStatement::interpret()\n");
928 #endif
929     if (istate->start == this)
930         istate->start = NULL;
931     Expression *e = NULL;
932
933     if (istate->start)
934     {
935         e = body ? body->interpret(istate) : NULL;
936         if (istate->start)
937             return NULL;
938         if (e == EXP_CANT_INTERPRET)
939             return e;
940         if (e == EXP_BREAK_INTERPRET)
941             return NULL;
942         return e;
943     }
944
945
946     Expression *econdition = condition->interpret(istate);
947     if (econdition == EXP_CANT_INTERPRET)
948         return EXP_CANT_INTERPRET;
949
950     Statement *s = NULL;
951     if (cases)
952     {
953         for (size_t i = 0; i < cases->dim; i++)
954         {
955             CaseStatement *cs = (CaseStatement *)cases->data[i];
956             e = Equal(TOKequal, Type::tint32, econdition, cs->exp);
957             if (e == EXP_CANT_INTERPRET)
958                 return EXP_CANT_INTERPRET;
959             if (e->isBool(TRUE))
960             {   s = cs;
961                 break;
962             }
963         }
964     }
965     if (!s)
966     {   if (hasNoDefault)
967             error("no default or case for %s in switch statement", econdition->toChars());
968         s = sdefault;
969     }
970
971     assert(s);
972     istate->start = s;
973     e = body ? body->interpret(istate) : NULL;
974     assert(!istate->start);
975     if (e == EXP_BREAK_INTERPRET)
976         return NULL;
977     return e;
978 }
979
980 Expression *CaseStatement::interpret(InterState *istate)
981 {
982 #if LOG
983     printf("CaseStatement::interpret(%s) this = %p\n", exp->toChars(), this);
984 #endif
985     if (istate->start == this)
986         istate->start = NULL;
987     if (statement)
988         return statement->interpret(istate);
989     else
990         return NULL;
991 }
992
993 Expression *DefaultStatement::interpret(InterState *istate)
994 {
995 #if LOG
996     printf("DefaultStatement::interpret()\n");
997 #endif
998     if (istate->start == this)
999         istate->start = NULL;
1000     if (statement)
1001         return statement->interpret(istate);
1002     else
1003         return NULL;
1004 }
1005
1006 Expression *GotoStatement::interpret(InterState *istate)
1007 {
1008 #if LOG
1009     printf("GotoStatement::interpret()\n");
1010 #endif
1011     START()
1012     assert(label && label->statement);
1013     istate->gotoTarget = label->statement;
1014     return EXP_GOTO_INTERPRET;
1015 }
1016
1017 Expression *GotoCaseStatement::interpret(InterState *istate)
1018 {
1019 #if LOG
1020     printf("GotoCaseStatement::interpret()\n");
1021 #endif
1022     START()
1023     assert(cs);
1024     istate->gotoTarget = cs;
1025     return EXP_GOTO_INTERPRET;
1026 }
1027
1028 Expression *GotoDefaultStatement::interpret(InterState *istate)
1029 {
1030 #if LOG
1031     printf("GotoDefaultStatement::interpret()\n");
1032 #endif
1033     START()
1034     assert(sw && sw->sdefault);
1035     istate->gotoTarget = sw->sdefault;
1036     return EXP_GOTO_INTERPRET;
1037 }
1038
1039 Expression *LabelStatement::interpret(InterState *istate)
1040 {
1041 #if LOG
1042     printf("LabelStatement::interpret()\n");
1043 #endif
1044     if (istate->start == this)
1045         istate->start = NULL;
1046     return statement ? statement->interpret(istate) : NULL;
1047 }
1048
1049
1050 Expression *TryCatchStatement::interpret(InterState *istate)
1051 {
1052 #if LOG
1053     printf("TryCatchStatement::interpret()\n");
1054 #endif
1055     START()
1056     error("try-catch statements are not yet supported in CTFE");
1057     return EXP_CANT_INTERPRET;
1058 }
1059
1060
1061 Expression *TryFinallyStatement::interpret(InterState *istate)
1062 {
1063 #if LOG
1064     printf("TryFinallyStatement::interpret()\n");
1065 #endif
1066     START()
1067     error("try-finally statements are not yet supported in CTFE");
1068     return EXP_CANT_INTERPRET;
1069 }
1070
1071 Expression *ThrowStatement::interpret(InterState *istate)
1072 {
1073 #if LOG
1074     printf("ThrowStatement::interpret()\n");
1075 #endif
1076     START()
1077     error("throw statements are not yet supported in CTFE");
1078     return EXP_CANT_INTERPRET;
1079 }
1080
1081 Expression *OnScopeStatement::interpret(InterState *istate)
1082 {
1083 #if LOG
1084     printf("OnScopeStatement::interpret()\n");
1085 #endif
1086     START()
1087     error("scope guard statements are not yet supported in CTFE");
1088     return EXP_CANT_INTERPRET;
1089 }
1090
1091 Expression *WithStatement::interpret(InterState *istate)
1092 {
1093 #if LOG
1094     printf("WithStatement::interpret()\n");
1095 #endif
1096     START()
1097     error("with statements are not yet supported in CTFE");
1098     return EXP_CANT_INTERPRET;
1099 }
1100
1101 Expression *AsmStatement::interpret(InterState *istate)
1102 {
1103 #if LOG
1104     printf("AsmStatement::interpret()\n");
1105 #endif
1106     START()
1107     error("asm statements cannot be interpreted at compile time");
1108     return EXP_CANT_INTERPRET;
1109 }
1110
1111 /******************************** Expression ***************************/
1112
1113 Expression *Expression::interpret(InterState *istate)
1114 {
1115 #if LOG
1116     printf("Expression::interpret() %s\n", toChars());
1117     printf("type = %s\n", type->toChars());
1118     dump(0);
1119 #endif
1120     error("Cannot interpret %s at compile time", toChars());
1121     return EXP_CANT_INTERPRET;
1122 }
1123
1124 Expression *ThisExp::interpret(InterState *istate)
1125 {
1126     if (istate && istate->localThis)
1127         return istate->localThis->interpret(istate);
1128     error("value of 'this' is not known at compile time");
1129     return EXP_CANT_INTERPRET;
1130 }
1131
1132 Expression *NullExp::interpret(InterState *istate)
1133 {
1134     return this;
1135 }
1136
1137 Expression *IntegerExp::interpret(InterState *istate)
1138 {
1139 #if LOG
1140     printf("IntegerExp::interpret() %s\n", toChars());
1141 #endif
1142     return this;
1143 }
1144
1145 Expression *RealExp::interpret(InterState *istate)
1146 {
1147 #if LOG
1148     printf("RealExp::interpret() %s\n", toChars());
1149 #endif
1150     return this;
1151 }
1152
1153 Expression *ComplexExp::interpret(InterState *istate)
1154 {
1155     return this;
1156 }
1157
1158 Expression *StringExp::interpret(InterState *istate)
1159 {
1160 #if LOG
1161     printf("StringExp::interpret() %s\n", toChars());
1162 #endif
1163     return this;
1164 }
1165
1166 Expression *FuncExp::interpret(InterState *istate)
1167 {
1168 #if LOG
1169     printf("FuncExp::interpret() %s\n", toChars());
1170 #endif
1171     return this;
1172 }
1173
1174 Expression *SymOffExp::interpret(InterState *istate)
1175 {
1176 #if LOG
1177     printf("SymOffExp::interpret() %s\n", toChars());
1178 #endif
1179     if (var->isFuncDeclaration() && offset == 0)
1180     {
1181         return this;
1182     }
1183     error("Cannot interpret %s at compile time", toChars());
1184     return EXP_CANT_INTERPRET;
1185 }
1186
1187 Expression *DelegateExp::interpret(InterState *istate)
1188 {
1189 #if LOG
1190     printf("DelegateExp::interpret() %s\n", toChars());
1191 #endif
1192     return this;
1193 }
1194
1195
1196 // -------------------------------------------------------------
1197 //         Remove out, ref, and this
1198 // -------------------------------------------------------------
1199 // The variable used in a dotvar, index, or slice expression,
1200 // after 'out', 'ref', and 'this' have been removed.
1201 // *isReference will be set to true if a reference was removed.
1202 Expression * resolveReferences(Expression *e, Expression *thisval, bool *isReference /*=NULL */)
1203 {
1204     if (isReference)
1205         *isReference = false;
1206     for(;;)
1207     {
1208         if (e->op == TOKthis)
1209         {
1210             assert(thisval);
1211             assert(e != thisval);
1212             e = thisval;
1213             continue;
1214         }
1215         if (e->op == TOKvar) {
1216             // Chase down rebinding of out and ref.
1217             VarExp *ve = (VarExp *)e;
1218             VarDeclaration *v = ve->var->isVarDeclaration();
1219             if (v && v->value && v->value->op == TOKvar) // it's probably a reference
1220             {
1221                 // Make sure it's a real reference.
1222                 // It's not a reference if v is a struct initialized to
1223                 // 0 using an __initZ SymbolDeclaration from
1224                 // TypeStruct::defaultInit()
1225                 VarExp *ve2 = (VarExp *)v->value;
1226                 if (!ve2->var->isSymbolDeclaration())
1227                 {
1228                     if (isReference)
1229                         *isReference = true;
1230                     e = v->value;
1231                     continue;
1232                 }
1233             }
1234             else if (v && v->value && (v->value->op==TOKindex || v->value->op == TOKdotvar
1235                   || v->value->op == TOKthis || v->value->op == TOKslice ))
1236             {
1237                 e = v->value;
1238                 continue;
1239             }
1240         }
1241         break;
1242     }
1243     return e;
1244 }
1245
1246 Expression *getVarExp(Loc loc, InterState *istate, Declaration *d)
1247 {
1248     Expression *e = EXP_CANT_INTERPRET;
1249     VarDeclaration *v = d->isVarDeclaration();
1250     SymbolDeclaration *s = d->isSymbolDeclaration();
1251     if (v)
1252     {
1253 #if DMDV2
1254         /* Magic variable __ctfe always returns true when interpreting
1255          */
1256         if (v->ident == Id::ctfe)
1257             return new IntegerExp(loc, 1, Type::tbool);
1258
1259         if ((v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) && v->init && !v->value)
1260 #else
1261         if (v->isConst() && v->init)
1262 #endif
1263         {   e = v->init->toExpression();
1264             if (e && !e->type)
1265                 e->type = v->type;
1266         }
1267         else if ((v->isCTFE() || (!v->isDataseg() && istate)) && !v->value)
1268         {
1269             if (v->init)
1270             {
1271                 if (v->init->isVoidInitializer())
1272                 {
1273                         error(loc, "variable %s is used before initialization", v->toChars());
1274                         return EXP_CANT_INTERPRET;
1275                 }
1276                 e = v->init->toExpression();
1277                 e = e->interpret(istate);
1278             }
1279             else
1280                 e = v->type->defaultInitLiteral(loc);
1281         }
1282         else if (!v->isDataseg() && !istate) {
1283             error(loc, "variable %s cannot be read at compile time", v->toChars());
1284             return EXP_CANT_INTERPRET;
1285         }
1286         else
1287         {   e = v->value;
1288              if (!v->isCTFE() && v->isDataseg())
1289             {   error(loc, "static variable %s cannot be read at compile time", v->toChars());
1290                 e = EXP_CANT_INTERPRET;
1291             }
1292             else if (!e)
1293                 error(loc, "variable %s is used before initialization", v->toChars());
1294             else if (e != EXP_CANT_INTERPRET)
1295                 e = e->interpret(istate);
1296         }
1297         if (!e)
1298             e = EXP_CANT_INTERPRET;
1299     }
1300     else if (s)
1301     {
1302         if (s->dsym->toInitializer() == s->sym)
1303         {   Expressions *exps = new Expressions();
1304             e = new StructLiteralExp(0, s->dsym, exps);
1305             e = e->semantic(NULL);
1306         }
1307     }
1308     return e;
1309 }
1310
1311 Expression *VarExp::interpret(InterState *istate)
1312 {
1313 #if LOG
1314     printf("VarExp::interpret() %s\n", toChars());
1315 #endif
1316     return getVarExp(loc, istate, var);
1317 }
1318
1319 Expression *DeclarationExp::interpret(InterState *istate)
1320 {
1321 #if LOG
1322     printf("DeclarationExp::interpret() %s\n", toChars());
1323 #endif
1324     Expression *e;
1325     VarDeclaration *v = declaration->isVarDeclaration();
1326     if (v)
1327     {
1328         Dsymbol *s = v->toAlias();
1329         if (s == v && !v->isStatic() && v->init)
1330         {
1331             ExpInitializer *ie = v->init->isExpInitializer();
1332             if (ie)
1333                 e = ie->exp->interpret(istate);
1334             else if (v->init->isVoidInitializer())
1335                 e = NULL;
1336             else
1337             {
1338                 error("Declaration %s is not yet implemented in CTFE", toChars());
1339                 e = EXP_CANT_INTERPRET;
1340             }
1341         }
1342 #if DMDV2
1343         else if (s == v && (v->isConst() || v->isImmutable()) && v->init)
1344 #else
1345         else if (s == v && v->isConst() && v->init)
1346 #endif
1347         {   e = v->init->toExpression();
1348             if (!e)
1349                 e = EXP_CANT_INTERPRET;
1350             else if (!e->type)
1351                 e->type = v->type;
1352         }
1353         else if (s->isTupleDeclaration() && !v->init)
1354             e = NULL;
1355         else
1356         {
1357             error("Declaration %s is not yet implemented in CTFE", toChars());
1358             e = EXP_CANT_INTERPRET;
1359         }
1360     }
1361     else if (declaration->isAttribDeclaration() ||
1362              declaration->isTemplateMixin() ||
1363              declaration->isTupleDeclaration())
1364     {   // These can be made to work, too lazy now
1365         error("Declaration %s is not yet implemented in CTFE", toChars());
1366         e = EXP_CANT_INTERPRET;
1367     }
1368     else
1369     {   // Others should not contain executable code, so are trivial to evaluate
1370         e = NULL;
1371     }
1372 #if LOG
1373     printf("-DeclarationExp::interpret(%s): %p\n", toChars(), e);
1374 #endif
1375     return e;
1376 }
1377
1378 Expression *TupleExp::interpret(InterState *istate)
1379 {
1380 #if LOG
1381     printf("TupleExp::interpret() %s\n", toChars());
1382 #endif
1383     Expressions *expsx = NULL;
1384
1385     for (size_t i = 0; i < exps->dim; i++)
1386     {   Expression *e = (Expression *)exps->data[i];
1387         Expression *ex;
1388
1389         ex = e->interpret(istate);
1390         if (ex == EXP_CANT_INTERPRET)
1391         {   delete expsx;
1392             return ex;
1393         }
1394
1395         /* If any changes, do Copy On Write
1396          */
1397         if (ex != e)
1398         {
1399             if (!expsx)
1400             {   expsx = new Expressions();
1401                 expsx->setDim(exps->dim);
1402                 for (size_t j = 0; j < i; j++)
1403                 {
1404                     expsx->data[j] = exps->data[j];
1405                 }
1406             }
1407             expsx->data[i] = (void *)ex;
1408         }
1409     }
1410     if (expsx)
1411     {   TupleExp *te = new TupleExp(loc, expsx);
1412         expandTuples(te->exps);
1413         te->type = new TypeTuple(te->exps);
1414         return te;
1415     }
1416     return this;
1417 }
1418
1419 Expression *ArrayLiteralExp::interpret(InterState *istate)
1420 {   Expressions *expsx = NULL;
1421
1422 #if LOG
1423     printf("ArrayLiteralExp::interpret() %s\n", toChars());
1424 #endif
1425     if (elements)
1426     {
1427         for (size_t i = 0; i < elements->dim; i++)
1428         {   Expression *e = (Expression *)elements->data[i];
1429             Expression *ex;
1430
1431             ex = e->interpret(istate);
1432             if (ex == EXP_CANT_INTERPRET)
1433                 goto Lerror;
1434
1435             /* If any changes, do Copy On Write
1436              */
1437             if (ex != e)
1438             {
1439                 if (!expsx)
1440                 {   expsx = new Expressions();
1441                     expsx->setDim(elements->dim);
1442                     for (size_t j = 0; j < elements->dim; j++)
1443                     {
1444                         expsx->data[j] = elements->data[j];
1445                     }
1446                 }
1447                 expsx->data[i] = (void *)ex;
1448             }
1449         }
1450     }
1451     if (elements && expsx)
1452     {
1453         expandTuples(expsx);
1454         if (expsx->dim != elements->dim)
1455             goto Lerror;
1456         ArrayLiteralExp *ae = new ArrayLiteralExp(loc, expsx);
1457         ae->type = type;
1458         return ae;
1459     }
1460     return this;
1461
1462 Lerror:
1463     if (expsx)
1464         delete expsx;
1465     error("cannot interpret array literal");
1466     return EXP_CANT_INTERPRET;
1467 }
1468
1469 Expression *AssocArrayLiteralExp::interpret(InterState *istate)
1470 {   Expressions *keysx = keys;
1471     Expressions *valuesx = values;
1472
1473 #if LOG
1474     printf("AssocArrayLiteralExp::interpret() %s\n", toChars());
1475 #endif
1476     for (size_t i = 0; i < keys->dim; i++)
1477     {   Expression *ekey = (Expression *)keys->data[i];
1478         Expression *evalue = (Expression *)values->data[i];
1479         Expression *ex;
1480
1481         ex = ekey->interpret(istate);
1482         if (ex == EXP_CANT_INTERPRET)
1483             goto Lerr;
1484
1485         /* If any changes, do Copy On Write
1486          */
1487         if (ex != ekey)
1488         {
1489             if (keysx == keys)
1490                 keysx = (Expressions *)keys->copy();
1491             keysx->data[i] = (void *)ex;
1492         }
1493
1494         ex = evalue->interpret(istate);
1495         if (ex == EXP_CANT_INTERPRET)
1496             goto Lerr;
1497
1498         /* If any changes, do Copy On Write
1499          */
1500         if (ex != evalue)
1501         {
1502             if (valuesx == values)
1503                 valuesx = (Expressions *)values->copy();
1504             valuesx->data[i] = (void *)ex;
1505         }
1506     }
1507     if (keysx != keys)
1508         expandTuples(keysx);
1509     if (valuesx != values)
1510         expandTuples(valuesx);
1511     if (keysx->dim != valuesx->dim)
1512         goto Lerr;
1513
1514     /* Remove duplicate keys
1515      */
1516     for (size_t i = 1; i < keysx->dim; i++)
1517     {   Expression *ekey = (Expression *)keysx->data[i - 1];
1518
1519         for (size_t j = i; j < keysx->dim; j++)
1520         {   Expression *ekey2 = (Expression *)keysx->data[j];
1521             Expression *ex = Equal(TOKequal, Type::tbool, ekey, ekey2);
1522             if (ex == EXP_CANT_INTERPRET)
1523                 goto Lerr;
1524             if (ex->isBool(TRUE))       // if a match
1525             {
1526                 // Remove ekey
1527                 if (keysx == keys)
1528                     keysx = (Expressions *)keys->copy();
1529                 if (valuesx == values)
1530                     valuesx = (Expressions *)values->copy();
1531                 keysx->remove(i - 1);
1532                 valuesx->remove(i - 1);
1533                 i -= 1;         // redo the i'th iteration
1534                 break;
1535             }
1536         }
1537     }
1538
1539     if (keysx != keys || valuesx != values)
1540     {
1541         AssocArrayLiteralExp *ae;
1542         ae = new AssocArrayLiteralExp(loc, keysx, valuesx);
1543         ae->type = type;
1544         return ae;
1545     }
1546     return this;
1547
1548 Lerr:
1549     if (keysx != keys)
1550         delete keysx;
1551     if (valuesx != values)
1552         delete values;
1553     return EXP_CANT_INTERPRET;
1554 }
1555
1556 Expression *StructLiteralExp::interpret(InterState *istate)
1557 {   Expressions *expsx = NULL;
1558
1559 #if LOG
1560     printf("StructLiteralExp::interpret() %s\n", toChars());
1561 #endif
1562     /* We don't know how to deal with overlapping fields
1563      */
1564     if (sd->hasUnions)
1565         {   error("Unions with overlapping fields are not yet supported in CTFE");
1566                 return EXP_CANT_INTERPRET;
1567     }
1568
1569     if (elements)
1570     {
1571         for (size_t i = 0; i < elements->dim; i++)
1572         {   Expression *e = (Expression *)elements->data[i];
1573             if (!e)
1574                 continue;
1575
1576             Expression *ex = e->interpret(istate);
1577             if (ex == EXP_CANT_INTERPRET)
1578             {   delete expsx;
1579                 return EXP_CANT_INTERPRET;
1580             }
1581
1582             /* If any changes, do Copy On Write
1583              */
1584             if (ex != e)
1585             {
1586                 if (!expsx)
1587                 {   expsx = new Expressions();
1588                     expsx->setDim(elements->dim);
1589                     for (size_t j = 0; j < elements->dim; j++)
1590                     {
1591                         expsx->data[j] = elements->data[j];
1592                     }
1593                 }
1594                 expsx->data[i] = (void *)ex;
1595             }
1596         }
1597     }
1598     if (elements && expsx)
1599     {
1600         expandTuples(expsx);
1601         if (expsx->dim != elements->dim)
1602         {   delete expsx;
1603             return EXP_CANT_INTERPRET;
1604         }
1605         StructLiteralExp *se = new StructLiteralExp(loc, sd, expsx);
1606         se->type = type;
1607         return se;
1608     }
1609     return this;
1610 }
1611
1612 Expression *NewExp::interpret(InterState *istate)
1613 {
1614 #if LOG
1615     printf("NewExp::interpret() %s\n", toChars());
1616 #endif
1617     if (newtype->ty == Tarray && arguments && arguments->dim == 1)
1618     {
1619         Expression *lenExpr = ((Expression *)(arguments->data[0]))->interpret(istate);
1620         if (lenExpr == EXP_CANT_INTERPRET)
1621             return EXP_CANT_INTERPRET;
1622         return createBlockDuplicatedArrayLiteral(newtype,
1623             ((TypeArray *)newtype)->next->defaultInitLiteral(),
1624             lenExpr->toInteger());
1625     }
1626     error("Cannot interpret %s at compile time", toChars());
1627     return EXP_CANT_INTERPRET;
1628 }
1629
1630 Expression *UnaExp::interpretCommon(InterState *istate, Expression *(*fp)(Type *, Expression *))
1631 {   Expression *e;
1632     Expression *e1;
1633
1634 #if LOG
1635     printf("UnaExp::interpretCommon() %s\n", toChars());
1636 #endif
1637     e1 = this->e1->interpret(istate);
1638     if (e1 == EXP_CANT_INTERPRET)
1639         goto Lcant;
1640     if (e1->isConst() != 1)
1641         goto Lcant;
1642
1643     e = (*fp)(type, e1);
1644     return e;
1645
1646 Lcant:
1647     return EXP_CANT_INTERPRET;
1648 }
1649
1650 #define UNA_INTERPRET(op) \
1651 Expression *op##Exp::interpret(InterState *istate)      \
1652 {                                                       \
1653     return interpretCommon(istate, &op);                \
1654 }
1655
1656 UNA_INTERPRET(Neg)
1657 UNA_INTERPRET(Com)
1658 UNA_INTERPRET(Not)
1659 UNA_INTERPRET(Bool)
1660
1661
1662 typedef Expression *(*fp_t)(Type *, Expression *, Expression *);
1663
1664 Expression *BinExp::interpretCommon(InterState *istate, fp_t fp)
1665 {   Expression *e;
1666     Expression *e1;
1667     Expression *e2;
1668
1669 #if LOG
1670     printf("BinExp::interpretCommon() %s\n", toChars());
1671 #endif
1672     e1 = this->e1->interpret(istate);
1673     if (e1 == EXP_CANT_INTERPRET)
1674         goto Lcant;
1675     if (e1->isConst() != 1)
1676         goto Lcant;
1677
1678     e2 = this->e2->interpret(istate);
1679     if (e2 == EXP_CANT_INTERPRET)
1680         goto Lcant;
1681     if (e2->isConst() != 1)
1682         goto Lcant;
1683
1684     e = (*fp)(type, e1, e2);
1685     return e;
1686
1687 Lcant:
1688     return EXP_CANT_INTERPRET;
1689 }
1690
1691 #define BIN_INTERPRET(op) \
1692 Expression *op##Exp::interpret(InterState *istate)      \
1693 {                                                       \
1694     return interpretCommon(istate, &op);                \
1695 }
1696
1697 BIN_INTERPRET(Add)
1698 BIN_INTERPRET(Min)
1699 BIN_INTERPRET(Mul)
1700 BIN_INTERPRET(Div)
1701 BIN_INTERPRET(Mod)
1702 BIN_INTERPRET(Shl)
1703 BIN_INTERPRET(Shr)
1704 BIN_INTERPRET(Ushr)
1705 BIN_INTERPRET(And)
1706 BIN_INTERPRET(Or)
1707 BIN_INTERPRET(Xor)
1708
1709
1710 typedef Expression *(*fp2_t)(enum TOK, Type *, Expression *, Expression *);
1711
1712 Expression *BinExp::interpretCommon2(InterState *istate, fp2_t fp)
1713 {   Expression *e;
1714     Expression *e1;
1715     Expression *e2;
1716
1717 #if LOG
1718     printf("BinExp::interpretCommon2() %s\n", toChars());
1719 #endif
1720     e1 = this->e1->interpret(istate);
1721     if (e1 == EXP_CANT_INTERPRET)
1722         goto Lcant;
1723     if (e1->isConst() != 1 &&
1724         e1->op != TOKnull &&
1725         e1->op != TOKstring &&
1726         e1->op != TOKarrayliteral &&
1727         e1->op != TOKstructliteral)
1728         goto Lcant;
1729
1730     e2 = this->e2->interpret(istate);
1731     if (e2 == EXP_CANT_INTERPRET)
1732         goto Lcant;
1733     if (e2->isConst() != 1 &&
1734         e2->op != TOKnull &&
1735         e2->op != TOKstring &&
1736         e2->op != TOKarrayliteral &&
1737         e2->op != TOKstructliteral)
1738         goto Lcant;
1739
1740     e = (*fp)(op, type, e1, e2);
1741     return e;
1742
1743 Lcant:
1744     return EXP_CANT_INTERPRET;
1745 }
1746
1747 #define BIN_INTERPRET2(op) \
1748 Expression *op##Exp::interpret(InterState *istate)      \
1749 {                                                       \
1750     return interpretCommon2(istate, &op);               \
1751 }
1752
1753 BIN_INTERPRET2(Equal)
1754 BIN_INTERPRET2(Identity)
1755 BIN_INTERPRET2(Cmp)
1756
1757 /* Helper functions for BinExp::interpretAssignCommon
1758  */
1759
1760 /***************************************
1761  * Duplicate the elements array, then set field 'indexToChange' = newelem.
1762  */
1763 Expressions *changeOneElement(Expressions *oldelems, size_t indexToChange, void *newelem)
1764 {
1765     Expressions *expsx = new Expressions();
1766     expsx->setDim(oldelems->dim);
1767     for (size_t j = 0; j < expsx->dim; j++)
1768     {
1769         if (j == indexToChange)
1770             expsx->data[j] = newelem;
1771         else
1772             expsx->data[j] = oldelems->data[j];
1773     }
1774     return expsx;
1775 }
1776
1777 /***************************************
1778  * Returns oldelems[0..insertpoint] ~ newelems ~ oldelems[insertpoint+newelems.length..$]
1779  */
1780 Expressions *spliceElements(Expressions *oldelems,
1781         Expressions *newelems, size_t insertpoint)
1782 {
1783     Expressions *expsx = new Expressions();
1784     expsx->setDim(oldelems->dim);
1785     for (size_t j = 0; j < expsx->dim; j++)
1786     {
1787         if (j >= insertpoint && j < insertpoint + newelems->dim)
1788             expsx->data[j] = newelems->data[j - insertpoint];
1789         else
1790             expsx->data[j] = oldelems->data[j];
1791     }
1792     return expsx;
1793 }
1794
1795 /***************************************
1796  * Returns oldstr[0..insertpoint] ~ newstr ~ oldstr[insertpoint+newlen..$]
1797  */
1798 StringExp *spliceStringExp(StringExp *oldstr, StringExp *newstr, size_t insertpoint)
1799 {
1800     assert(oldstr->sz==newstr->sz);
1801     unsigned char *s;
1802     size_t oldlen = oldstr->len;
1803     size_t newlen = newstr->len;
1804     size_t sz = oldstr->sz;
1805     s = (unsigned char *)mem.calloc(oldlen + 1, sz);
1806     memcpy(s, oldstr->string, oldlen * sz);
1807     memcpy(s + insertpoint * sz, newstr->string, newlen * sz);
1808     StringExp *se2 = new StringExp(oldstr->loc, s, oldlen);
1809     se2->committed = oldstr->committed;
1810     se2->postfix = oldstr->postfix;
1811     se2->type = oldstr->type;
1812     return se2;
1813 }
1814
1815 /******************************
1816  * Create an array literal consisting of 'elem' duplicated 'dim' times.
1817  */
1818 ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Type *type,
1819         Expression *elem, size_t dim)
1820 {
1821     Expressions *elements = new Expressions();
1822     elements->setDim(dim);
1823     for (size_t i = 0; i < dim; i++)
1824          elements->data[i] = elem;
1825     ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements);
1826     ae->type = type;
1827     return ae;
1828 }
1829
1830 /******************************
1831  * Create a string literal consisting of 'value' duplicated 'dim' times.
1832  */
1833 StringExp *createBlockDuplicatedStringLiteral(Type *type,
1834         unsigned value, size_t dim, int sz)
1835 {
1836     unsigned char *s;
1837     s = (unsigned char *)mem.calloc(dim + 1, sz);
1838     for (int elemi=0; elemi<dim; ++elemi)
1839     {
1840         switch (sz)
1841         {
1842             case 1:     s[elemi] = value; break;
1843             case 2:     ((unsigned short *)s)[elemi] = value; break;
1844             case 4:     ((unsigned *)s)[elemi] = value; break;
1845             default:    assert(0);
1846         }
1847     }
1848     StringExp *se = new StringExp(0, s, dim);
1849     se->type = type;
1850     return se;
1851 }
1852
1853 /********************************
1854  *  Add v to the istate list, unless it already exists there.
1855  */
1856 void addVarToInterstate(InterState *istate, VarDeclaration *v)
1857 {
1858     if (!v->isParameter())
1859     {
1860         for (size_t i = 0; 1; i++)
1861         {
1862             if (i == istate->vars.dim)
1863             {   istate->vars.push(v);
1864                 //printf("\tadding %s to istate\n", v->toChars());
1865                 break;
1866             }
1867             if (v == (VarDeclaration *)istate->vars.data[i])
1868                 break;
1869         }
1870     }
1871 }
1872
1873 // Create a new struct literal, which is the same as se except that se.field[offset] = elem
1874 Expression * modifyStructField(Type *type, StructLiteralExp *se, size_t offset, Expression *newval)
1875 {
1876     int fieldi = se->getFieldIndex(newval->type, offset);
1877     if (fieldi == -1)
1878         return EXP_CANT_INTERPRET;
1879     /* Create new struct literal reflecting updated fieldi
1880     */
1881     Expressions *expsx = changeOneElement(se->elements, fieldi, newval);
1882     Expression * ee = new StructLiteralExp(se->loc, se->sd, expsx);
1883     ee->type = se->type;
1884     return ee;
1885 }
1886
1887 /********************************
1888  * Given an array literal arr (either arrayliteral, stringliteral, or assocArrayLiteral),
1889  * set arr[index] = newval and return the new array.
1890  *
1891  */
1892 Expression * assignArrayElement(Loc loc, Expression *arr, Expression *index, Expression *newval)
1893 {
1894         ArrayLiteralExp *ae = NULL;
1895         AssocArrayLiteralExp *aae = NULL;
1896         StringExp *se = NULL;
1897         if (arr->op == TOKarrayliteral)
1898             ae = (ArrayLiteralExp *)arr;
1899         else if (arr->op == TOKassocarrayliteral)
1900             aae = (AssocArrayLiteralExp *)arr;
1901         else if (arr->op == TOKstring)
1902             se = (StringExp *)arr;
1903         else assert(0);
1904
1905         if (ae)
1906         {
1907             int elemi = index->toInteger();
1908             if (elemi >= ae->elements->dim)
1909             {
1910                 error(loc, "array index %d is out of bounds %s[0..%d]", elemi,
1911                     arr->toChars(), ae->elements->dim);
1912                 return EXP_CANT_INTERPRET;
1913             }
1914             // Create new array literal reflecting updated elem
1915             Expressions *expsx = changeOneElement(ae->elements, elemi, newval);
1916             Expression *ee = new ArrayLiteralExp(ae->loc, expsx);
1917             ee->type = ae->type;
1918             newval = ee;
1919         }
1920         else if (se)
1921         {
1922             /* Create new string literal reflecting updated elem
1923              */
1924             int elemi = index->toInteger();
1925             if (elemi >= se->len)
1926             {
1927                 error(loc, "array index %d is out of bounds %s[0..%d]", elemi,
1928                     arr->toChars(), se->len);
1929                 return EXP_CANT_INTERPRET;
1930             }
1931             unsigned char *s;
1932             s = (unsigned char *)mem.calloc(se->len + 1, se->sz);
1933             memcpy(s, se->string, se->len * se->sz);
1934             unsigned value = newval->toInteger();
1935             switch (se->sz)
1936             {
1937                 case 1: s[elemi] = value; break;
1938                 case 2: ((unsigned short *)s)[elemi] = value; break;
1939                 case 4: ((unsigned *)s)[elemi] = value; break;
1940                 default:
1941                     assert(0);
1942                     break;
1943             }
1944             StringExp *se2 = new StringExp(se->loc, s, se->len);
1945             se2->committed = se->committed;
1946             se2->postfix = se->postfix;
1947             se2->type = se->type;
1948             newval = se2;
1949         }
1950         else if (aae)
1951         {
1952             /* Create new associative array literal reflecting updated key/value
1953              */
1954             Expressions *keysx = aae->keys;
1955             Expressions *valuesx = new Expressions();
1956             valuesx->setDim(aae->values->dim);
1957             int updated = 0;
1958             for (size_t j = valuesx->dim; j; )
1959             {   j--;
1960                 Expression *ekey = (Expression *)aae->keys->data[j];
1961                 Expression *ex = Equal(TOKequal, Type::tbool, ekey, index);
1962                 if (ex == EXP_CANT_INTERPRET)
1963                     return EXP_CANT_INTERPRET;
1964                 if (ex->isBool(TRUE))
1965                 {   valuesx->data[j] = (void *)newval;
1966                     updated = 1;
1967                 }
1968                 else
1969                     valuesx->data[j] = aae->values->data[j];
1970             }
1971             if (!updated)
1972             {   // Append index/newval to keysx[]/valuesx[]
1973                 valuesx->push(newval);
1974                 keysx = (Expressions *)keysx->copy();
1975                 keysx->push(index);
1976             }
1977             Expression *aae2 = new AssocArrayLiteralExp(aae->loc, keysx, valuesx);
1978             aae2->type = aae->type;
1979             return aae2;
1980         }
1981         return newval;
1982 }
1983
1984 // Return true if e is derived from UnaryExp.
1985 // Consider moving this function into Expression.
1986 UnaExp *isUnaExp(Expression *e)
1987 {
1988    switch (e->op)
1989    {
1990         case TOKdotvar:
1991         case TOKindex:
1992         case TOKslice:
1993         case TOKcall:
1994         case TOKdot:
1995         case TOKdotti:
1996         case TOKdottype:
1997         case TOKcast:
1998             return (UnaExp *)e;
1999         default:
2000             break;
2001     }
2002         return NULL;
2003 }
2004
2005 // To resolve an assignment expression, we need to walk to the end of the
2006 // expression to find the ultimate variable which is modified. But, in building
2007 // up the expression, we need to walk the tree *backwards*. There isn't a
2008 // standard way to do this, but if we know we're at depth d, iterating from
2009 // the root up to depth d-1 will give us the parent node. Inefficient, but
2010 // depth is almost always < 3.
2011 struct ExpressionReverseIterator
2012 {
2013     Expression *totalExpr; // The root expression
2014     Expression *thisval;  // The value to be used for TOKthis
2015     int totalDepth;
2016
2017     ExpressionReverseIterator(Expression *root, Expression *thisexpr)
2018     {
2019        totalExpr = root;
2020        thisval = thisexpr;
2021        totalDepth = findExpressionDepth(totalExpr);
2022     }
2023
2024     int findExpressionDepth(Expression *e);
2025     Expression *getExpressionAtDepth(int depth);
2026 };
2027
2028 // Determines the depth in unary expressions.
2029 int ExpressionReverseIterator::findExpressionDepth(Expression *e)
2030 {
2031    int depth = 0;
2032    for (;;)
2033    {
2034         e = resolveReferences(e, thisval);
2035         if (e->op == TOKvar)
2036             return depth;
2037         if (e->op == TOKcall)
2038             return depth;
2039         ++depth;
2040         UnaExp *u = isUnaExp(e);
2041         if (u)
2042             e = u->e1;
2043         else
2044             return depth;
2045     }
2046 }
2047
2048 Expression *ExpressionReverseIterator::getExpressionAtDepth(int depth)
2049 {
2050    Expression *e = totalExpr;
2051    int d = 0;
2052    for (;;)
2053    {
2054         e = resolveReferences(e, thisval);
2055         if (d == depth) return e;
2056         ++d;
2057         assert(e->op != TOKvar);
2058         UnaExp *u = isUnaExp(e);
2059         if (u)
2060             e = u->e1;
2061         else
2062             return e;
2063     }
2064 }
2065
2066 // Returns the variable which is eventually modified, or NULL if an rvalue.
2067 // thisval is the current value of 'this'.
2068 VarDeclaration * findParentVar(Expression *e, Expression *thisval)
2069 {
2070     for (;;)
2071     {
2072         e = resolveReferences(e, thisval);
2073         if (e->op == TOKvar)
2074             break;
2075         if (e->op == TOKindex)
2076             e = ((IndexExp*)e)->e1;
2077         else if (e->op == TOKdotvar)
2078             e = ((DotVarExp *)e)->e1;
2079         else if (e->op == TOKdotti)
2080             e = ((DotTemplateInstanceExp *)e)->e1;
2081         else if (e->op == TOKslice)
2082             e = ((SliceExp*)e)->e1;
2083         else
2084             return NULL;
2085     }
2086     VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration();
2087     assert(v);
2088     return v;
2089 }
2090
2091 // Returns the value to be assigned to the last dotVar, given the existing value at this depth.
2092 Expression *assignDotVar(ExpressionReverseIterator rvs, int depth, Expression *existing, Expression *newval)
2093 {
2094     if (depth == 0)
2095         return newval;
2096     assert(existing && existing != EXP_CANT_INTERPRET);
2097     Expression *e = rvs.getExpressionAtDepth(depth - 1);
2098     if (e->op == TOKdotvar)
2099     {
2100         VarDeclaration *member = ((DotVarExp *)e)->var->isVarDeclaration();
2101         assert(member);
2102         assert(existing);
2103         assert(existing != EXP_CANT_INTERPRET);
2104         assert(existing->op == TOKstructliteral);
2105         if (existing->op != TOKstructliteral)
2106             return EXP_CANT_INTERPRET;
2107
2108         StructLiteralExp *se = (StructLiteralExp *)existing;
2109         int fieldi = se->getFieldIndex(member->type, member->offset);
2110         if (fieldi == -1)
2111             return EXP_CANT_INTERPRET;
2112         assert(fieldi>=0 && fieldi < se->elements->dim);
2113         Expression *ex =  (Expression *)(se->elements->data[fieldi]);
2114
2115         newval = assignDotVar(rvs, depth - 1, ex, newval);
2116         Expressions *expsx = changeOneElement(se->elements, fieldi, newval);
2117         Expression * ee = new StructLiteralExp(se->loc, se->sd, expsx);
2118         ee->type = se->type;
2119         return ee;
2120     }
2121     assert(0);
2122     return NULL;
2123 }
2124
2125
2126 Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
2127 {
2128 #if LOG
2129     printf("BinExp::interpretAssignCommon() %s\n", toChars());
2130 #endif
2131     Expression *e = EXP_CANT_INTERPRET;
2132     Expression *e1 = this->e1;
2133     if (!istate)
2134     {
2135         error("value of %s is not known at compile time", e1->toChars());
2136         return e;
2137     }
2138
2139     if (fp)
2140     {
2141         if (e1->op == TOKcast)
2142         {   CastExp *ce = (CastExp *)e1;
2143             e1 = ce->e1;
2144         }
2145     }
2146     if (e1 == EXP_CANT_INTERPRET)
2147         return e1;
2148
2149     assert(istate);
2150
2151     // ----------------------------------------------------
2152     //  Deal with read-modify-write assignments.
2153     //  Set 'newval' to the final assignment value
2154     //  Also determine the return value (except for slice
2155     //  assignments, which are more complicated)
2156     // ----------------------------------------------------
2157     Expression * newval = this->e2->interpret(istate);
2158     if (newval == EXP_CANT_INTERPRET)
2159         return newval;
2160
2161     if (fp || e1->op == TOKarraylength)
2162     {
2163         // If it isn't a simple assignment, we need the existing value
2164         Expression * oldval = e1->interpret(istate);
2165         if (oldval == EXP_CANT_INTERPRET)
2166             return EXP_CANT_INTERPRET;
2167         while (oldval->op == TOKvar)
2168         {
2169             oldval = resolveReferences(oldval, istate->localThis);
2170             oldval = oldval->interpret(istate);
2171             if (oldval == EXP_CANT_INTERPRET)
2172                 return oldval;
2173         }
2174
2175         if (fp)
2176         {
2177             newval = (*fp)(type, oldval, newval);
2178             if (newval == EXP_CANT_INTERPRET)
2179             {
2180                 error("Cannot interpret %s at compile time", toChars());
2181                 return EXP_CANT_INTERPRET;
2182             }
2183             // Determine the return value
2184             e = Cast(type, type, post ? oldval : newval);
2185             if (e == EXP_CANT_INTERPRET)
2186                 return e;
2187         }
2188         else
2189             e = newval;
2190
2191         if (e1->op == TOKarraylength)
2192         {
2193             size_t oldlen = oldval->toInteger();
2194             size_t newlen = newval->toInteger();
2195             if (oldlen == newlen) // no change required -- we're done!
2196                 return e;
2197             // Now change the assignment from arr.length = n into arr = newval
2198             e1 = ((ArrayLengthExp *)e1)->e1;
2199             if (oldlen != 0)
2200             {   // Get the old array literal.
2201                 oldval = e1->interpret(istate);
2202                 while (oldval->op == TOKvar)
2203                 {   oldval = resolveReferences(oldval, istate->localThis);
2204                     oldval = oldval->interpret(istate);
2205                 }
2206             }
2207             Type *t = e1->type->toBasetype();
2208             if (t->ty == Tarray)
2209             {
2210                 Type *elemType= NULL;
2211                 elemType = ((TypeArray *)t)->next;
2212                 assert(elemType);
2213                 Expression *defaultElem = elemType->defaultInitLiteral();
2214
2215                 Expressions *elements = new Expressions();
2216                 elements->setDim(newlen);
2217                 size_t copylen = oldlen < newlen ? oldlen : newlen;
2218                 ArrayLiteralExp *ae = (ArrayLiteralExp *)oldval;
2219                 for (size_t i = 0; i < copylen; i++)
2220                      elements->data[i] = ae->elements->data[i];
2221
2222                 for (size_t i = copylen; i < newlen; i++)
2223                     elements->data[i] = defaultElem;
2224                 ArrayLiteralExp *aae = new ArrayLiteralExp(0, elements);
2225                 aae->type = t;
2226                 newval = aae;
2227             }
2228             else
2229             {
2230                 error("%s is not yet supported at compile time", toChars());
2231                 return EXP_CANT_INTERPRET;
2232             }
2233
2234         }
2235     }
2236     else if (e1->op != TOKslice)
2237     {   /* Look for special case of struct being initialized with 0.
2238         */
2239         if (type->toBasetype()->ty == Tstruct && newval->op == TOKint64)
2240         {
2241             newval = type->defaultInitLiteral(loc);
2242         }
2243         newval = Cast(type, type, newval);
2244         e = newval;
2245     }
2246     if (newval == EXP_CANT_INTERPRET)
2247         return newval;
2248
2249     // -------------------------------------------------
2250     //         Make sure destination can be modified
2251     // -------------------------------------------------
2252     // Make sure we're not trying to modify a global or static variable
2253     // We do this by locating the ultimate parent variable which gets modified.
2254     VarDeclaration * ultimateVar = findParentVar(e1, istate->localThis);
2255     if (ultimateVar && ultimateVar->isDataseg() && !ultimateVar->isCTFE())
2256     {   // Can't modify global or static data
2257         error("%s cannot be modified at compile time", ultimateVar->toChars());
2258         return EXP_CANT_INTERPRET;
2259     }
2260
2261     // This happens inside compiler-generated foreach statements.
2262     if (op==TOKconstruct && this->e1->op==TOKvar
2263         && ((VarExp*)this->e1)->var->storage_class & STCref)
2264     {
2265         //error("assignment to ref variable %s is not yet supported in CTFE", this->toChars());
2266         VarDeclaration *v = ((VarExp *)e1)->var->isVarDeclaration();
2267         v->value = e2;
2268         return e2;
2269     }
2270     bool destinationIsReference = false;
2271     e1 = resolveReferences(e1, istate->localThis, &destinationIsReference);
2272
2273     // Unless we have a simple var assignment, we're
2274     // only modifying part of the variable. So we need to make sure
2275     // that the parent variable exists.
2276     if (e1->op != TOKvar && ultimateVar && !ultimateVar->value)
2277         ultimateVar->value = ultimateVar->type->defaultInitLiteral();
2278
2279     // ----------------------------------------
2280     //      Deal with dotvar expressions
2281     // ----------------------------------------
2282     // Because structs are not reference types, dotvar expressions can be
2283     // collapsed into a single assignment.
2284     bool startedWithCall = false;
2285     if (e1->op == TOKcall) startedWithCall = true;
2286     while (e1->op == TOKdotvar || e1->op == TOKcall)
2287     {
2288         ExpressionReverseIterator rvs(e1, istate->localThis);
2289         Expression *lastNonDotVar = e1;
2290         // Strip of all of the leading dotvars.
2291         if (e1->op == TOKdotvar)
2292         {
2293             int numDotVars = 0;
2294             while(lastNonDotVar->op == TOKdotvar)
2295             {
2296                 ++numDotVars;
2297                 if (lastNonDotVar->op == TOKdotvar)
2298                     lastNonDotVar = ((DotVarExp *)lastNonDotVar)->e1;
2299                 lastNonDotVar = resolveReferences(lastNonDotVar, istate->localThis);
2300                 assert(lastNonDotVar);
2301             }
2302             // We need the value of this first nonvar, since only part of it will be
2303             // modified.
2304             Expression * existing = lastNonDotVar->interpret(istate);
2305             if (existing == EXP_CANT_INTERPRET)
2306                 return existing;
2307             assert(newval !=EXP_CANT_INTERPRET);
2308             newval = assignDotVar(rvs, numDotVars, existing, newval);
2309             e1 = lastNonDotVar;
2310             if (e1->op == TOKvar)
2311             {
2312                 VarExp *ve = (VarExp *)e1;
2313                 VarDeclaration *v = ve->var->isVarDeclaration();
2314                 v->value = newval;
2315                 return e;
2316             }
2317             assert(newval !=EXP_CANT_INTERPRET);
2318
2319         } // end tokdotvar
2320         else
2321         {
2322             Expression * existing = lastNonDotVar->interpret(istate);
2323             if (existing == EXP_CANT_INTERPRET)
2324                 return existing;
2325             // It might be a reference. Turn it into an rvalue, by interpreting again.
2326             existing = existing->interpret(istate);
2327             if (existing == EXP_CANT_INTERPRET)
2328                 return existing;
2329             assert(newval !=EXP_CANT_INTERPRET);
2330             newval = assignDotVar(rvs, 0, existing, newval);
2331             assert(newval !=EXP_CANT_INTERPRET);
2332         }
2333         if (e1->op == TOKcall)
2334         {
2335                 istate->awaitingLvalueReturn = true;
2336                 e1 = e1->interpret(istate);
2337                 istate->awaitingLvalueReturn = false;
2338
2339                 if (e1==EXP_CANT_INTERPRET) return e1;
2340                 assert(newval);
2341                 assert(newval !=EXP_CANT_INTERPRET);
2342         }
2343     }
2344
2345     /* Assignment to variable of the form:
2346      *  v = newval
2347      */
2348     if (e1->op == TOKvar)
2349     {
2350         VarExp *ve = (VarExp *)e1;
2351         VarDeclaration *v = ve->var->isVarDeclaration();
2352         if (!destinationIsReference)
2353             addVarToInterstate(istate, v);
2354         v->value = newval;
2355     }
2356     else if (e1->op == TOKindex)
2357     {
2358         Expression *aggregate = resolveReferences(((IndexExp *)e1)->e1, istate->localThis);
2359         /* Assignment to array element of the form:
2360          *   aggregate[i] = newval
2361          */
2362         if (aggregate->op == TOKvar)
2363         {   IndexExp *ie = (IndexExp *)e1;
2364             VarExp *ve = (VarExp *)aggregate;
2365             VarDeclaration *v = ve->var->isVarDeclaration();
2366             if (v->value->op == TOKnull)
2367             {
2368                 if (v->type->ty == Taarray)
2369                 {   // Assign to empty associative array
2370                     Expressions *valuesx = new Expressions();
2371                     Expressions *keysx = new Expressions();
2372                     Expression *index = ie->e2->interpret(istate);
2373                     if (index == EXP_CANT_INTERPRET)
2374                         return EXP_CANT_INTERPRET;
2375                     valuesx->push(newval);
2376                     keysx->push(index);
2377                     Expression *aae2 = new AssocArrayLiteralExp(loc, keysx, valuesx);
2378                     aae2->type = v->type;
2379                     newval = aae2;
2380                     v->value = newval;
2381                     return e;
2382                 }
2383                 // This would be a runtime segfault
2384                 error("Cannot index null array %s", v->toChars());
2385                 return EXP_CANT_INTERPRET;
2386             }
2387             else if (v->value->op != TOKarrayliteral
2388                 && v->value->op != TOKassocarrayliteral
2389                 && v->value->op != TOKstring)
2390             {
2391                 error("CTFE internal compiler error");
2392                 return EXP_CANT_INTERPRET;
2393             }
2394             // Set the $ variable
2395             Expression *dollar = ArrayLength(Type::tsize_t, v->value);
2396             if (dollar != EXP_CANT_INTERPRET && ie->lengthVar)
2397                 ie->lengthVar->value = dollar;
2398             // Determine the index, and check that it's OK.
2399             Expression *index = ie->e2->interpret(istate);
2400             if (index == EXP_CANT_INTERPRET)
2401                 return EXP_CANT_INTERPRET;
2402             newval = assignArrayElement(loc, v->value, index, newval);
2403             if (newval == EXP_CANT_INTERPRET)
2404                 return EXP_CANT_INTERPRET;
2405             v->value = newval;
2406             return e;
2407         }
2408         else
2409             error("Index assignment %s is not yet supported in CTFE ", toChars());
2410
2411     }
2412     else if (e1->op == TOKslice)
2413     {
2414         Expression *aggregate = resolveReferences(((SliceExp *)e1)->e1, istate->localThis);
2415         // ------------------------------
2416         //   aggregate[] = newval
2417         //   aggregate[low..upp] = newval
2418         // ------------------------------
2419         /* Slice assignment, initialization of static arrays
2420         *   a[] = e
2421         */
2422         if (aggregate->op==TOKvar)
2423         {
2424             SliceExp * sexp = (SliceExp *)e1;
2425             VarExp *ve = (VarExp *)(aggregate);
2426             VarDeclaration *v = ve->var->isVarDeclaration();
2427             /* Set the $ variable
2428              */
2429             Expression *ee = v->value ? ArrayLength(Type::tsize_t, v->value)
2430                                   : EXP_CANT_INTERPRET;
2431             if (ee != EXP_CANT_INTERPRET && sexp->lengthVar)
2432                 sexp->lengthVar->value = ee;
2433             Expression *upper = NULL;
2434             Expression *lower = NULL;
2435             if (sexp->upr)
2436             {
2437                 upper = sexp->upr->interpret(istate);
2438                 if (upper == EXP_CANT_INTERPRET)
2439                     return EXP_CANT_INTERPRET;
2440             }
2441             if (sexp->lwr)
2442             {
2443                 lower = sexp->lwr->interpret(istate);
2444                 if (lower == EXP_CANT_INTERPRET)
2445                     return EXP_CANT_INTERPRET;
2446             }
2447             Type *t = v->type->toBasetype();
2448             size_t dim;
2449             if (t->ty == Tsarray)
2450                 dim = ((TypeSArray *)t)->dim->toInteger();
2451             else if (t->ty == Tarray)
2452             {
2453                 if (!v->value || v->value->op == TOKnull)
2454                 {
2455                     error("cannot assign to null array %s", v->toChars());
2456                     return EXP_CANT_INTERPRET;
2457                 }
2458                 if (v->value->op == TOKarrayliteral)
2459                     dim = ((ArrayLiteralExp *)v->value)->elements->dim;
2460                 else if (v->value->op ==TOKstring)
2461                     dim = ((StringExp *)v->value)->len;
2462             }
2463             else
2464             {
2465                 error("%s cannot be evaluated at compile time", toChars());
2466                 return EXP_CANT_INTERPRET;
2467             }
2468             int upperbound = upper ? upper->toInteger() : dim;
2469             int lowerbound = lower ? lower->toInteger() : 0;
2470
2471             if (((int)lowerbound < 0) || (upperbound > dim))
2472             {
2473                 error("Array bounds [0..%d] exceeded in slice [%d..%d]",
2474                     dim, lowerbound, upperbound);
2475                 return EXP_CANT_INTERPRET;
2476             }
2477             // Could either be slice assignment (v[] = e[]),
2478             // or block assignment (v[] = val).
2479             // For the former, we check that the lengths match.
2480             bool isSliceAssignment = (newval->op == TOKarrayliteral)
2481                 || (newval->op == TOKstring);
2482             size_t srclen = 0;
2483             if (newval->op == TOKarrayliteral)
2484                 srclen = ((ArrayLiteralExp *)newval)->elements->dim;
2485             else if (newval->op == TOKstring)
2486                 srclen = ((StringExp *)newval)->len;
2487             if (isSliceAssignment && srclen != (upperbound - lowerbound))
2488             {
2489                 error("Array length mismatch assigning [0..%d] to [%d..%d]", srclen, lowerbound, upperbound);
2490                 return e;
2491             }
2492         if (newval->op == TOKarrayliteral)
2493         {
2494             // Static array assignment from literal
2495             if (upperbound - lowerbound != dim)
2496             {
2497                 ArrayLiteralExp *ae = (ArrayLiteralExp *)newval;
2498                 ArrayLiteralExp *existing = (ArrayLiteralExp *)v->value;
2499                 // value[] = value[0..lower] ~ ae ~ value[upper..$]
2500                 existing->elements = spliceElements(existing->elements, ae->elements, lowerbound);
2501                 newval = existing;
2502             }
2503             v->value = newval;
2504             return newval;
2505         }
2506         else if (newval->op == TOKstring)
2507         {
2508             StringExp *se = (StringExp *)newval;
2509             if (upperbound-lowerbound == dim)
2510                 v->value = newval;
2511             else
2512             {
2513                 if (!v->value)
2514                     v->value = createBlockDuplicatedStringLiteral(se->type,
2515                         se->type->defaultInit()->toInteger(), dim, se->sz);
2516                 if (v->value->op==TOKstring)
2517                     v->value = spliceStringExp((StringExp *)v->value, se, lowerbound);
2518                 else
2519                     error("String slice assignment is not yet supported in CTFE");
2520             }
2521             return newval;
2522         }
2523         else if (t->nextOf()->ty == newval->type->ty)
2524         {
2525             // Static array block assignment
2526             e = createBlockDuplicatedArrayLiteral(v->type, newval, upperbound-lowerbound);
2527
2528             if (upperbound - lowerbound == dim)
2529                 newval = e;
2530             else
2531             {
2532                 ArrayLiteralExp * newarrayval;
2533                 // Only modifying part of the array. Must create a new array literal.
2534                 // If the existing array is uninitialized (this can only happen
2535                 // with static arrays), create it.
2536                 if (v->value && v->value->op == TOKarrayliteral)
2537                     newarrayval = (ArrayLiteralExp *)v->value;
2538                 else // this can only happen with static arrays
2539                     newarrayval = createBlockDuplicatedArrayLiteral(v->type, v->type->defaultInit(), dim);
2540                 // value[] = value[0..lower] ~ e ~ value[upper..$]
2541                 newarrayval->elements = spliceElements(newarrayval->elements,
2542                         ((ArrayLiteralExp *)e)->elements, lowerbound);
2543                 newval = newarrayval;
2544                 }
2545                 v->value = newval;
2546                 return e;
2547             }
2548             else
2549             {
2550                 error("Slice operation %s cannot be evaluated at compile time", toChars());
2551                 return e;
2552             }
2553         }
2554         else
2555             error("Slice operation %s cannot be evaluated at compile time", toChars());
2556     }
2557     else if (e1->op == TOKstar)
2558     {
2559         /* Assignment to struct member of the form:
2560          *   *(symoffexp) = newval
2561          */
2562         if (((PtrExp *)e1)->e1->op == TOKsymoff)
2563         {   SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1;
2564             VarDeclaration *v = soe->var->isVarDeclaration();
2565             if (v->isDataseg() && !v->isCTFE())
2566             {
2567                 error("%s cannot be modified at compile time", v->toChars());
2568                 return EXP_CANT_INTERPRET;
2569             }
2570             if (fp && !v->value)
2571             {   error("variable %s is used before initialization", v->toChars());
2572                 return e;
2573             }
2574             Expression *vie = v->value;
2575             if (vie->op == TOKvar)
2576             {
2577                 Declaration *d = ((VarExp *)vie)->var;
2578                 vie = getVarExp(e1->loc, istate, d);
2579             }
2580             if (vie->op != TOKstructliteral)
2581                 return EXP_CANT_INTERPRET;
2582
2583             StructLiteralExp *se = (StructLiteralExp *)vie;
2584
2585             newval = modifyStructField(type, se, soe->offset, newval);
2586
2587             addVarToInterstate(istate, v);
2588             v->value = newval;
2589         }
2590     }
2591     else
2592     {
2593         error("%s cannot be evaluated at compile time", toChars());
2594 #ifdef DEBUG
2595         dump(0);
2596 #endif
2597     }
2598     return e;
2599 }
2600
2601 Expression *AssignExp::interpret(InterState *istate)
2602 {
2603     return interpretAssignCommon(istate, NULL);
2604 }
2605
2606 #define BIN_ASSIGN_INTERPRET(op) \
2607 Expression *op##AssignExp::interpret(InterState *istate)        \
2608 {                                                               \
2609     return interpretAssignCommon(istate, &op);                  \
2610 }
2611
2612 BIN_ASSIGN_INTERPRET(Add)
2613 BIN_ASSIGN_INTERPRET(Min)
2614 BIN_ASSIGN_INTERPRET(Cat)
2615 BIN_ASSIGN_INTERPRET(Mul)
2616 BIN_ASSIGN_INTERPRET(Div)
2617 BIN_ASSIGN_INTERPRET(Mod)
2618 BIN_ASSIGN_INTERPRET(Shl)
2619 BIN_ASSIGN_INTERPRET(Shr)
2620 BIN_ASSIGN_INTERPRET(Ushr)
2621 BIN_ASSIGN_INTERPRET(And)
2622 BIN_ASSIGN_INTERPRET(Or)
2623 BIN_ASSIGN_INTERPRET(Xor)
2624
2625 Expression *PostExp::interpret(InterState *istate)
2626 {
2627 #if LOG
2628     printf("PostExp::interpret() %s\n", toChars());
2629 #endif
2630     Expression *e;
2631     if (op == TOKplusplus)
2632         e = interpretAssignCommon(istate, &Add, 1);
2633     else
2634         e = interpretAssignCommon(istate, &Min, 1);
2635 #if LOG
2636     if (e == EXP_CANT_INTERPRET)
2637         printf("PostExp::interpret() CANT\n");
2638 #endif
2639     return e;
2640 }
2641
2642 Expression *AndAndExp::interpret(InterState *istate)
2643 {
2644 #if LOG
2645     printf("AndAndExp::interpret() %s\n", toChars());
2646 #endif
2647     Expression *e = e1->interpret(istate);
2648     if (e != EXP_CANT_INTERPRET)
2649     {
2650         if (e->isBool(FALSE))
2651             e = new IntegerExp(e1->loc, 0, type);
2652         else if (e->isBool(TRUE))
2653         {
2654             e = e2->interpret(istate);
2655             if (e != EXP_CANT_INTERPRET)
2656             {
2657                 if (e->isBool(FALSE))
2658                     e = new IntegerExp(e1->loc, 0, type);
2659                 else if (e->isBool(TRUE))
2660                     e = new IntegerExp(e1->loc, 1, type);
2661                 else
2662                     e = EXP_CANT_INTERPRET;
2663             }
2664         }
2665         else
2666             e = EXP_CANT_INTERPRET;
2667     }
2668     return e;
2669 }
2670
2671 Expression *OrOrExp::interpret(InterState *istate)
2672 {
2673 #if LOG
2674     printf("OrOrExp::interpret() %s\n", toChars());
2675 #endif
2676     Expression *e = e1->interpret(istate);
2677     if (e != EXP_CANT_INTERPRET)
2678     {
2679         if (e->isBool(TRUE))
2680             e = new IntegerExp(e1->loc, 1, type);
2681         else if (e->isBool(FALSE))
2682         {
2683             e = e2->interpret(istate);
2684             if (e != EXP_CANT_INTERPRET)
2685             {
2686                 if (e->isBool(FALSE))
2687                     e = new IntegerExp(e1->loc, 0, type);
2688                 else if (e->isBool(TRUE))
2689                     e = new IntegerExp(e1->loc, 1, type);
2690                 else
2691                     e = EXP_CANT_INTERPRET;
2692             }
2693         }
2694         else
2695             e = EXP_CANT_INTERPRET;
2696     }
2697     return e;
2698 }
2699
2700
2701 Expression *CallExp::interpret(InterState *istate)
2702 {   Expression *e = EXP_CANT_INTERPRET;
2703
2704 #if LOG
2705     printf("CallExp::interpret() %s\n", toChars());
2706 #endif
2707
2708     Expression * pthis = NULL;
2709     FuncDeclaration *fd = NULL;
2710     Expression *ecall = e1;
2711     if (ecall->op == TOKcall)
2712     {
2713         ecall = e1->interpret(istate);
2714         if (ecall == EXP_CANT_INTERPRET)
2715             return ecall;
2716     }
2717     if (ecall->op == TOKstar)
2718     {   // Calling a function pointer
2719         Expression * pe = ((PtrExp*)ecall)->e1;
2720         if (pe->op == TOKvar) {
2721             VarDeclaration *vd = ((VarExp *)((PtrExp*)ecall)->e1)->var->isVarDeclaration();
2722             if (vd && vd->value && vd->value->op == TOKsymoff)
2723                 fd = ((SymOffExp *)vd->value)->var->isFuncDeclaration();
2724             else
2725             {
2726                 ecall = getVarExp(loc, istate, vd);
2727                 if (ecall == EXP_CANT_INTERPRET)
2728                     return ecall;
2729
2730                 if (ecall->op == TOKsymoff)
2731                     fd = ((SymOffExp *)ecall)->var->isFuncDeclaration();
2732             }
2733         }
2734         else
2735             ecall = ((PtrExp*)ecall)->e1->interpret(istate);
2736
2737     }
2738     if (ecall == EXP_CANT_INTERPRET)
2739         return ecall;
2740
2741     if (ecall->op == TOKindex)
2742     {   ecall = e1->interpret(istate);
2743         if (ecall == EXP_CANT_INTERPRET)
2744             return ecall;
2745     }
2746
2747     if (ecall->op == TOKdotvar && !((DotVarExp*)ecall)->var->isFuncDeclaration())
2748     {   ecall = e1->interpret(istate);
2749         if (ecall == EXP_CANT_INTERPRET)
2750             return ecall;
2751     }
2752
2753     if (ecall->op == TOKdotvar)
2754     {   // Calling a member function
2755         pthis = ((DotVarExp*)e1)->e1;
2756         fd = ((DotVarExp*)e1)->var->isFuncDeclaration();
2757     }
2758     else if (ecall->op == TOKvar)
2759     {
2760         VarDeclaration *vd = ((VarExp *)ecall)->var->isVarDeclaration();
2761         if (vd && vd->value)
2762             ecall = vd->value;
2763         else // Calling a function
2764             fd = ((VarExp *)e1)->var->isFuncDeclaration();
2765     }
2766     if (ecall->op == TOKdelegate)
2767     {   // Calling a delegate
2768         fd = ((DelegateExp *)ecall)->func;
2769         pthis = ((DelegateExp *)ecall)->e1;
2770     }
2771     else if (ecall->op == TOKfunction)
2772     {   // Calling a delegate literal
2773         fd = ((FuncExp*)ecall)->fd;
2774     }
2775     else if (ecall->op == TOKstar && ((PtrExp*)ecall)->e1->op==TOKfunction)
2776     {   // Calling a function literal
2777         fd = ((FuncExp*)((PtrExp*)ecall)->e1)->fd;
2778     }
2779
2780     TypeFunction *tf = fd ? (TypeFunction *)(fd->type) : NULL;
2781     if (!tf)
2782     {   // DAC: I'm not sure if this ever happens
2783         //printf("ecall=%s %d %d\n", ecall->toChars(), ecall->op, TOKcall);
2784         error("cannot evaluate %s at compile time", toChars());
2785         return EXP_CANT_INTERPRET;
2786     }
2787     if (pthis && fd)
2788     {   // Member function call
2789         if (pthis->op == TOKthis)
2790             pthis = istate ? istate->localThis : NULL;
2791         else if (pthis->op == TOKcomma)
2792             pthis = pthis->interpret(istate);
2793         if (!fd->fbody)
2794         {
2795             error("%s cannot be interpreted at compile time,"
2796                 " because it has no available source code", fd->toChars());
2797             return EXP_CANT_INTERPRET;
2798         }
2799         Expression *eresult = fd->interpret(istate, arguments, pthis);
2800         if (eresult)
2801             e = eresult;
2802         else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors)
2803             e = EXP_VOID_INTERPRET;
2804         else
2805             error("cannot evaluate %s at compile time", toChars());
2806         return e;
2807     }
2808     else if (fd)
2809     {    // function call
2810 #if DMDV2
2811         enum BUILTIN b = fd->isBuiltin();
2812         if (b)
2813         {   Expressions args;
2814             args.setDim(arguments->dim);
2815             for (size_t i = 0; i < args.dim; i++)
2816             {
2817                 Expression *earg = (Expression *)arguments->data[i];
2818                 earg = earg->interpret(istate);
2819                 if (earg == EXP_CANT_INTERPRET)
2820                     return earg;
2821                 args.data[i] = (void *)earg;
2822             }
2823             e = eval_builtin(b, &args);
2824             if (!e)
2825                 e = EXP_CANT_INTERPRET;
2826         }
2827         else
2828 #endif
2829
2830 #if DMDV1
2831         if (fd->ident == Id::aaLen)
2832             return interpret_aaLen(istate, arguments);
2833         else if (fd->ident == Id::aaKeys)
2834             return interpret_aaKeys(istate, arguments);
2835         else if (fd->ident == Id::aaValues)
2836             return interpret_aaValues(istate, arguments);
2837 #endif
2838
2839         // Inline .dup
2840         if (fd->ident == Id::adDup && arguments && arguments->dim == 2)
2841         {
2842             e = (Expression *)arguments->data[1];
2843             e = e->interpret(istate);
2844             if (e != EXP_CANT_INTERPRET)
2845             {
2846                 e = expType(type, e);
2847             }
2848         }
2849         else
2850         {
2851             if (!fd->fbody)
2852             {
2853                 error("%s cannot be interpreted at compile time,"
2854                     " because it has no available source code", fd->toChars());
2855                 return EXP_CANT_INTERPRET;
2856             }
2857             Expression *eresult = fd->interpret(istate, arguments);
2858             if (eresult)
2859                 e = eresult;
2860             else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors)
2861                 e = EXP_VOID_INTERPRET;
2862             else
2863                 error("cannot evaluate %s at compile time", toChars());
2864         }
2865     }
2866     else
2867     {
2868         error("cannot evaluate %s at compile time", toChars());
2869         return EXP_CANT_INTERPRET;
2870     }
2871     return e;
2872 }
2873
2874 Expression *CommaExp::interpret(InterState *istate)
2875 {
2876 #if LOG
2877     printf("CommaExp::interpret() %s\n", toChars());
2878 #endif
2879
2880     CommaExp * firstComma = this;
2881     while (firstComma->e1->op == TOKcomma)
2882         firstComma = (CommaExp *)firstComma->e1;
2883
2884     // If it creates a variable, and there's no context for
2885     // the variable to be created in, we need to create one now.
2886     InterState istateComma;
2887     if (!istate &&  firstComma->e1->op == TOKdeclaration)
2888         istate = &istateComma;
2889
2890     // If the comma returns a temporary variable, it needs to be an lvalue
2891     // (this is particularly important for struct constructors)
2892     if (e1->op == TOKdeclaration && e2->op == TOKvar
2893        && ((DeclarationExp *)e1)->declaration == ((VarExp*)e2)->var)
2894     {
2895         VarExp* ve = (VarExp *)e2;
2896         VarDeclaration *v = ve->var->isVarDeclaration();
2897         if (!v->init && !v->value)
2898             v->value = v->type->defaultInitLiteral();
2899         if (!v->value)
2900             v->value = v->init->toExpression();
2901         // Bug 4027. Copy constructors are a weird case where the
2902         // initializer is a void function (the variable is modified
2903         // through a reference parameter instead).
2904         Expression *newval = v->value->interpret(istate);
2905         if (newval != EXP_VOID_INTERPRET)
2906             v->value = newval;
2907         return e2;
2908     }
2909     Expression *e = e1->interpret(istate);
2910     if (e != EXP_CANT_INTERPRET)
2911         e = e2->interpret(istate);
2912     return e;
2913 }
2914
2915 Expression *CondExp::interpret(InterState *istate)
2916 {
2917 #if LOG
2918     printf("CondExp::interpret() %s\n", toChars());
2919 #endif
2920     Expression *e = econd->interpret(istate);
2921     if (e != EXP_CANT_INTERPRET)
2922     {
2923         if (e->isBool(TRUE))
2924             e = e1->interpret(istate);
2925         else if (e->isBool(FALSE))
2926             e = e2->interpret(istate);
2927         else
2928             e = EXP_CANT_INTERPRET;
2929     }
2930     return e;
2931 }
2932
2933 Expression *ArrayLengthExp::interpret(InterState *istate)
2934 {   Expression *e;
2935     Expression *e1;
2936
2937 #if LOG
2938     printf("ArrayLengthExp::interpret() %s\n", toChars());
2939 #endif
2940     e1 = this->e1->interpret(istate);
2941     if (e1 == EXP_CANT_INTERPRET)
2942         goto Lcant;
2943     if (e1->op == TOKstring || e1->op == TOKarrayliteral || e1->op == TOKassocarrayliteral)
2944     {
2945         e = ArrayLength(type, e1);
2946     }
2947     else if (e1->op == TOKnull)
2948     {
2949         e = new IntegerExp(loc, 0, type);
2950     }
2951     else
2952         goto Lcant;
2953     return e;
2954
2955 Lcant:
2956     return EXP_CANT_INTERPRET;
2957 }
2958
2959 Expression *IndexExp::interpret(InterState *istate)
2960 {   Expression *e;
2961     Expression *e1;
2962     Expression *e2;
2963
2964 #if LOG
2965     printf("IndexExp::interpret() %s\n", toChars());
2966 #endif
2967     e1 = this->e1->interpret(istate);
2968     if (e1 == EXP_CANT_INTERPRET)
2969         goto Lcant;
2970
2971     if (e1->op == TOKstring || e1->op == TOKarrayliteral)
2972     {
2973         /* Set the $ variable
2974          */
2975         e = ArrayLength(Type::tsize_t, e1);
2976         if (e == EXP_CANT_INTERPRET)
2977             goto Lcant;
2978         if (lengthVar)
2979             lengthVar->value = e;
2980     }
2981
2982     e2 = this->e2->interpret(istate);
2983     if (e2 == EXP_CANT_INTERPRET)
2984         goto Lcant;
2985     e = Index(type, e1, e2);
2986     if (e == EXP_CANT_INTERPRET)
2987         error("%s cannot be interpreted at compile time", toChars());
2988     return e;
2989
2990 Lcant:
2991     return EXP_CANT_INTERPRET;
2992 }
2993
2994
2995 Expression *SliceExp::interpret(InterState *istate)
2996 {   Expression *e;
2997     Expression *e1;
2998     Expression *lwr;
2999     Expression *upr;
3000
3001 #if LOG
3002     printf("SliceExp::interpret() %s\n", toChars());
3003 #endif
3004     e1 = this->e1->interpret(istate);
3005     if (e1 == EXP_CANT_INTERPRET)
3006         goto Lcant;
3007     if (!this->lwr)
3008     {
3009         e = e1->castTo(NULL, type);
3010         return e->interpret(istate);
3011     }
3012
3013     /* Set the $ variable
3014      */
3015     e = ArrayLength(Type::tsize_t, e1);
3016     if (e == EXP_CANT_INTERPRET)
3017         goto Lcant;
3018     if (lengthVar)
3019         lengthVar->value = e;
3020
3021     /* Evaluate lower and upper bounds of slice
3022      */
3023     lwr = this->lwr->interpret(istate);
3024     if (lwr == EXP_CANT_INTERPRET)
3025         goto Lcant;
3026     upr = this->upr->interpret(istate);
3027     if (upr == EXP_CANT_INTERPRET)
3028         goto Lcant;
3029
3030     e = Slice(type, e1, lwr, upr);
3031     if (e == EXP_CANT_INTERPRET)
3032         error("%s cannot be interpreted at compile time", toChars());
3033     return e;
3034
3035 Lcant:
3036     return EXP_CANT_INTERPRET;
3037 }
3038
3039
3040 Expression *CatExp::interpret(InterState *istate)
3041 {   Expression *e;
3042     Expression *e1;
3043     Expression *e2;
3044
3045 #if LOG
3046     printf("CatExp::interpret() %s\n", toChars());
3047 #endif
3048     e1 = this->e1->interpret(istate);
3049     if (e1 == EXP_CANT_INTERPRET)
3050     {
3051         goto Lcant;
3052     }
3053     e2 = this->e2->interpret(istate);
3054     if (e2 == EXP_CANT_INTERPRET)
3055         goto Lcant;
3056     e = Cat(type, e1, e2);
3057     if (e == EXP_CANT_INTERPRET)
3058         error("%s cannot be interpreted at compile time", toChars());
3059     return e;
3060
3061 Lcant:
3062 #if LOG
3063     printf("CatExp::interpret() %s CANT\n", toChars());
3064 #endif
3065     return EXP_CANT_INTERPRET;
3066 }
3067
3068
3069 Expression *CastExp::interpret(InterState *istate)
3070 {   Expression *e;
3071     Expression *e1;
3072
3073 #if LOG
3074     printf("CastExp::interpret() %s\n", toChars());
3075 #endif
3076     e1 = this->e1->interpret(istate);
3077     if (e1 == EXP_CANT_INTERPRET)
3078         goto Lcant;
3079     e = Cast(type, to, e1);
3080     if (e == EXP_CANT_INTERPRET)
3081         error("%s cannot be interpreted at compile time", toChars());
3082     return e;
3083
3084 Lcant:
3085 #if LOG
3086     printf("CastExp::interpret() %s CANT\n", toChars());
3087 #endif
3088     return EXP_CANT_INTERPRET;
3089 }
3090
3091
3092 Expression *AssertExp::interpret(InterState *istate)
3093 {   Expression *e;
3094     Expression *e1;
3095
3096 #if LOG
3097     printf("AssertExp::interpret() %s\n", toChars());
3098 #endif
3099     if( this->e1->op == TOKaddress)
3100     {   // Special case: deal with compiler-inserted assert(&this, "null this")
3101         AddrExp *ade = (AddrExp *)this->e1;
3102         if (ade->e1->op == TOKthis && istate->localThis)
3103             if (ade->e1->op == TOKdotvar
3104                 && ((DotVarExp *)(istate->localThis))->e1->op == TOKthis)
3105                 return getVarExp(loc, istate, ((DotVarExp*)(istate->localThis))->var);
3106             else
3107                 return istate->localThis->interpret(istate);
3108     }
3109     if (this->e1->op == TOKthis)
3110     {
3111         if (istate->localThis)
3112             return istate->localThis->interpret(istate);
3113     }
3114     e1 = this->e1->interpret(istate);
3115     if (e1 == EXP_CANT_INTERPRET)
3116         goto Lcant;
3117     if (e1->isBool(TRUE))
3118     {
3119     }
3120     else if (e1->isBool(FALSE))
3121     {
3122         if (msg)
3123         {
3124             e = msg->interpret(istate);
3125             if (e == EXP_CANT_INTERPRET)
3126                 goto Lcant;
3127             error("%s", e->toChars());
3128         }
3129         else
3130             error("%s failed", toChars());
3131         goto Lcant;
3132     }
3133     else
3134         goto Lcant;
3135     return e1;
3136
3137 Lcant:
3138     return EXP_CANT_INTERPRET;
3139 }
3140
3141 Expression *PtrExp::interpret(InterState *istate)
3142 {   Expression *e = EXP_CANT_INTERPRET;
3143
3144 #if LOG
3145     printf("PtrExp::interpret() %s\n", toChars());
3146 #endif
3147
3148     // Constant fold *(&structliteral + offset)
3149     if (e1->op == TOKadd)
3150     {   AddExp *ae = (AddExp *)e1;
3151         if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64)
3152         {   AddrExp *ade = (AddrExp *)ae->e1;
3153             Expression *ex = ade->e1;
3154             ex = ex->interpret(istate);
3155             if (ex != EXP_CANT_INTERPRET)
3156             {
3157                 if (ex->op == TOKstructliteral)
3158                 {   StructLiteralExp *se = (StructLiteralExp *)ex;
3159                     unsigned offset = ae->e2->toInteger();
3160                     e = se->getField(type, offset);
3161                     if (!e)
3162                         e = EXP_CANT_INTERPRET;
3163                     return e;
3164                 }
3165             }
3166         }
3167         e = Ptr(type, e1);
3168     }
3169     else if (e1->op == TOKsymoff)
3170     {   SymOffExp *soe = (SymOffExp *)e1;
3171         VarDeclaration *v = soe->var->isVarDeclaration();
3172         if (v)
3173         {   Expression *ev = getVarExp(loc, istate, v);
3174             if (ev != EXP_CANT_INTERPRET && ev->op == TOKstructliteral)
3175             {   StructLiteralExp *se = (StructLiteralExp *)ev;
3176                 e = se->getField(type, soe->offset);
3177                 if (!e)
3178                     e = EXP_CANT_INTERPRET;
3179             }
3180         }
3181     }
3182 #if DMDV2
3183 #else // this is required for D1, where structs return *this instead of 'this'.
3184     else if (e1->op == TOKthis)
3185     {
3186         if(istate->localThis)
3187             return istate->localThis->interpret(istate);
3188     }
3189 #endif
3190     else
3191         error("Cannot interpret %s at compile time", toChars());
3192
3193 #if LOG
3194     if (e == EXP_CANT_INTERPRET)
3195         printf("PtrExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars());
3196 #endif
3197     return e;
3198 }
3199
3200 Expression *DotVarExp::interpret(InterState *istate)
3201 {   Expression *e = EXP_CANT_INTERPRET;
3202
3203 #if LOG
3204     printf("DotVarExp::interpret() %s\n", toChars());
3205 #endif
3206
3207     Expression *ex = e1->interpret(istate);
3208     if (ex != EXP_CANT_INTERPRET)
3209     {
3210         if (ex->op == TOKstructliteral)
3211         {   StructLiteralExp *se = (StructLiteralExp *)ex;
3212             VarDeclaration *v = var->isVarDeclaration();
3213             if (v)
3214             {   e = se->getField(type, v->offset);
3215                 if (!e)
3216                 {
3217                     error("couldn't find field %s in %s", v->toChars(), type->toChars());
3218                     e = EXP_CANT_INTERPRET;
3219                 }
3220                 return e;
3221             }
3222         }
3223         else
3224             error("%s.%s is not yet implemented at compile time", e1->toChars(), var->toChars());
3225     }
3226
3227 #if LOG
3228     if (e == EXP_CANT_INTERPRET)
3229         printf("DotVarExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars());
3230 #endif
3231     return e;
3232 }
3233
3234 /******************************* Special Functions ***************************/
3235
3236 #if DMDV1
3237
3238 Expression *interpret_aaLen(InterState *istate, Expressions *arguments)
3239 {
3240     if (!arguments || arguments->dim != 1)
3241         return NULL;
3242     Expression *earg = (Expression *)arguments->data[0];
3243     earg = earg->interpret(istate);
3244     if (earg == EXP_CANT_INTERPRET)
3245         return NULL;
3246     if (earg->op != TOKassocarrayliteral)
3247         return NULL;
3248     AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
3249     Expression *e = new IntegerExp(aae->loc, aae->keys->dim, Type::tsize_t);
3250     return e;
3251 }
3252
3253 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments)
3254 {
3255 #if LOG
3256     printf("interpret_aaKeys()\n");
3257 #endif
3258     if (!arguments || arguments->dim != 2)
3259         return NULL;
3260     Expression *earg = (Expression *)arguments->data[0];
3261     earg = earg->interpret(istate);
3262     if (earg == EXP_CANT_INTERPRET)
3263         return NULL;
3264     if (earg->op != TOKassocarrayliteral)
3265         return NULL;
3266     AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
3267     Expression *e = new ArrayLiteralExp(aae->loc, aae->keys);
3268     Type *elemType = ((TypeAArray *)aae->type)->index;
3269     e->type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments->dim : 0));
3270     return e;
3271 }
3272
3273 Expression *interpret_aaValues(InterState *istate, Expressions *arguments)
3274 {
3275     //printf("interpret_aaValues()\n");
3276     if (!arguments || arguments->dim != 3)
3277         return NULL;
3278     Expression *earg = (Expression *)arguments->data[0];
3279     earg = earg->interpret(istate);
3280     if (earg == EXP_CANT_INTERPRET)
3281         return NULL;
3282     if (earg->op != TOKassocarrayliteral)
3283         return NULL;
3284     AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
3285     Expression *e = new ArrayLiteralExp(aae->loc, aae->values);
3286     Type *elemType = ((TypeAArray *)aae->type)->next;
3287     e->type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments->dim : 0));
3288     //printf("result is %s\n", e->toChars());
3289     return e;
3290 }
3291
3292 #endif
3293
3294 #if DMDV2
3295
3296 Expression *interpret_length(InterState *istate, Expression *earg)
3297 {
3298     //printf("interpret_length()\n");
3299     earg = earg->interpret(istate);
3300     if (earg == EXP_CANT_INTERPRET)
3301         return NULL;
3302     if (earg->op != TOKassocarrayliteral)
3303         return NULL;
3304     AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
3305     Expression *e = new IntegerExp(aae->loc, aae->keys->dim, Type::tsize_t);
3306     return e;
3307 }
3308
3309 Expression *interpret_keys(InterState *istate, Expression *earg, FuncDeclaration *fd)
3310 {
3311 #if LOG
3312     printf("interpret_keys()\n");
3313 #endif
3314     earg = earg->interpret(istate);
3315     if (earg == EXP_CANT_INTERPRET)
3316         return NULL;
3317     if (earg->op != TOKassocarrayliteral)
3318         return NULL;
3319     AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
3320     Expression *e = new ArrayLiteralExp(aae->loc, aae->keys);
3321     assert(fd->type->ty == Tfunction);
3322     assert(fd->type->nextOf()->ty == Tarray);
3323     Type *elemType = ((TypeFunction *)fd->type)->nextOf()->nextOf();
3324     e->type = new TypeSArray(elemType, new IntegerExp(aae->keys->dim));
3325     return e;
3326 }
3327
3328 Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclaration *fd)
3329 {
3330     //printf("interpret_values()\n");
3331     earg = earg->interpret(istate);
3332     if (earg == EXP_CANT_INTERPRET)
3333         return NULL;
3334     if (earg->op != TOKassocarrayliteral)
3335         return NULL;
3336     AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
3337     Expression *e = new ArrayLiteralExp(aae->loc, aae->values);
3338     assert(fd->type->ty == Tfunction);
3339     assert(fd->type->nextOf()->ty == Tarray);
3340     Type *elemType = ((TypeFunction *)fd->type)->nextOf()->nextOf();
3341     e->type = new TypeSArray(elemType, new IntegerExp(aae->values->dim));
3342     //printf("result is %s\n", e->toChars());
3343     return e;
3344 }
3345
3346 #endif
Note: See TracBrowser for help on using the browser.