comparison dmd2/interpret.c @ 758:f04dde6e882c

Added initial D2 support, D2 frontend and changes to codegen to make things compile.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 11 Nov 2008 01:38:48 +0100
parents
children 75c53f8f67a4
comparison
equal deleted inserted replaced
757:2c730d530c98 758:f04dde6e882c
1
2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars
4 // All Rights Reserved
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <assert.h>
14
15 #include "mem.h"
16
17 #include "statement.h"
18 #include "expression.h"
19 #include "cond.h"
20 #include "init.h"
21 #include "staticassert.h"
22 #include "mtype.h"
23 #include "scope.h"
24 #include "declaration.h"
25 #include "aggregate.h"
26 #include "id.h"
27
28 #define LOG 0
29
30 struct InterState
31 {
32 InterState *caller; // calling function's InterState
33 FuncDeclaration *fd; // function being interpreted
34 Dsymbols vars; // variables used in this function
35 Statement *start; // if !=NULL, start execution at this statement
36 Statement *gotoTarget; // target of EXP_GOTO_INTERPRET result
37
38 InterState();
39 };
40
41 InterState::InterState()
42 {
43 memset(this, 0, sizeof(InterState));
44 }
45
46 Expression *interpret_aaLen(InterState *istate, Expressions *arguments);
47 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments);
48 Expression *interpret_aaValues(InterState *istate, Expressions *arguments);
49
50 /*************************************
51 * Attempt to interpret a function given the arguments.
52 * Input:
53 * istate state for calling function (NULL if none)
54 * Return result expression if successful, NULL if not.
55 */
56
57 Expression *FuncDeclaration::interpret(InterState *istate, Expressions *arguments)
58 {
59 #if LOG
60 printf("\n********\nFuncDeclaration::interpret(istate = %p) %s\n", istate, toChars());
61 printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret, semanticRun);
62 #endif
63 if (global.errors)
64 return NULL;
65 if (ident == Id::aaLen)
66 return interpret_aaLen(istate, arguments);
67 else if (ident == Id::aaKeys)
68 return interpret_aaKeys(istate, arguments);
69 else if (ident == Id::aaValues)
70 return interpret_aaValues(istate, arguments);
71
72 if (cantInterpret || semanticRun == 1)
73 return NULL;
74
75 if (needThis() || isNested() || !fbody)
76 { cantInterpret = 1;
77 return NULL;
78 }
79
80 if (semanticRun == 0 && scope)
81 {
82 semantic3(scope);
83 if (global.errors) // if errors compiling this function
84 return NULL;
85 }
86 if (semanticRun < 2)
87 return NULL;
88
89 Type *tb = type->toBasetype();
90 assert(tb->ty == Tfunction);
91 TypeFunction *tf = (TypeFunction *)tb;
92 Type *tret = tf->next->toBasetype();
93 if (tf->varargs /*|| tret->ty == Tvoid*/)
94 { cantInterpret = 1;
95 return NULL;
96 }
97
98 if (tf->parameters)
99 { size_t dim = Argument::dim(tf->parameters);
100 for (size_t i = 0; i < dim; i++)
101 { Argument *arg = Argument::getNth(tf->parameters, i);
102 if (arg->storageClass & STClazy)
103 { cantInterpret = 1;
104 return NULL;
105 }
106 }
107 }
108
109 InterState istatex;
110 istatex.caller = istate;
111 istatex.fd = this;
112
113 Expressions vsave; // place to save previous parameter values
114 size_t dim = 0;
115 if (arguments)
116 {
117 dim = arguments->dim;
118 assert(!dim || parameters->dim == dim);
119 vsave.setDim(dim);
120
121 /* Evaluate all the arguments to the function,
122 * store the results in eargs[]
123 */
124 Expressions eargs;
125 eargs.setDim(dim);
126
127 for (size_t i = 0; i < dim; i++)
128 { Expression *earg = (Expression *)arguments->data[i];
129 Argument *arg = Argument::getNth(tf->parameters, i);
130
131 if (arg->storageClass & (STCout | STCref))
132 {
133 }
134 else
135 { /* Value parameters
136 */
137 Type *ta = arg->type->toBasetype();
138 if (ta->ty == Tsarray && earg->op == TOKaddress)
139 {
140 /* Static arrays are passed by a simple pointer.
141 * Skip past this to get at the actual arg.
142 */
143 earg = ((AddrExp *)earg)->e1;
144 }
145 earg = earg->interpret(istate ? istate : &istatex);
146 if (earg == EXP_CANT_INTERPRET)
147 return NULL;
148 }
149 eargs.data[i] = earg;
150 }
151
152 for (size_t i = 0; i < dim; i++)
153 { Expression *earg = (Expression *)eargs.data[i];
154 Argument *arg = Argument::getNth(tf->parameters, i);
155 VarDeclaration *v = (VarDeclaration *)parameters->data[i];
156 vsave.data[i] = v->value;
157 #if LOG
158 printf("arg[%d] = %s\n", i, earg->toChars());
159 #endif
160 if (arg->storageClass & (STCout | STCref))
161 {
162 /* Bind out or ref parameter to the corresponding
163 * variable v2
164 */
165 if (!istate || earg->op != TOKvar)
166 return NULL; // can't bind to non-interpreted vars
167
168 VarDeclaration *v2;
169 while (1)
170 {
171 VarExp *ve = (VarExp *)earg;
172 v2 = ve->var->isVarDeclaration();
173 if (!v2)
174 return NULL;
175 if (!v2->value || v2->value->op != TOKvar)
176 break;
177 earg = v2->value;
178 }
179
180 v->value = new VarExp(earg->loc, v2);
181
182 /* Don't restore the value of v2 upon function return
183 */
184 assert(istate);
185 for (size_t i = 0; i < istate->vars.dim; i++)
186 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
187 if (v == v2)
188 { istate->vars.data[i] = NULL;
189 break;
190 }
191 }
192 }
193 else
194 { /* Value parameters
195 */
196 v->value = earg;
197 }
198 #if LOG
199 printf("interpreted arg[%d] = %s\n", i, earg->toChars());
200 #endif
201 }
202 }
203
204 /* Save the values of the local variables used
205 */
206 Expressions valueSaves;
207 if (istate)
208 {
209 //printf("saving local variables...\n");
210 valueSaves.setDim(istate->vars.dim);
211 for (size_t i = 0; i < istate->vars.dim; i++)
212 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
213 if (v)
214 {
215 //printf("\tsaving [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : "");
216 valueSaves.data[i] = v->value;
217 v->value = NULL;
218 }
219 }
220 }
221
222 Expression *e = NULL;
223
224 while (1)
225 {
226 e = fbody->interpret(&istatex);
227 if (e == EXP_CANT_INTERPRET)
228 {
229 #if LOG
230 printf("function body failed to interpret\n");
231 #endif
232 e = NULL;
233 }
234
235 /* This is how we deal with a recursive statement AST
236 * that has arbitrary goto statements in it.
237 * Bubble up a 'result' which is the target of the goto
238 * statement, then go recursively down the AST looking
239 * for that statement, then execute starting there.
240 */
241 if (e == EXP_GOTO_INTERPRET)
242 {
243 istatex.start = istatex.gotoTarget; // set starting statement
244 istatex.gotoTarget = NULL;
245 }
246 else
247 break;
248 }
249
250 /* Restore the parameter values
251 */
252 for (size_t i = 0; i < dim; i++)
253 {
254 VarDeclaration *v = (VarDeclaration *)parameters->data[i];
255 v->value = (Expression *)vsave.data[i];
256 }
257
258 if (istate)
259 {
260 /* Restore the variable values
261 */
262 //printf("restoring local variables...\n");
263 for (size_t i = 0; i < istate->vars.dim; i++)
264 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
265 if (v)
266 { v->value = (Expression *)valueSaves.data[i];
267 //printf("\trestoring [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : "");
268 }
269 }
270 }
271
272 return e;
273 }
274
275 /******************************** Statement ***************************/
276
277 #define START() \
278 if (istate->start) \
279 { if (istate->start != this) \
280 return NULL; \
281 istate->start = NULL; \
282 }
283
284 /***********************************
285 * Interpret the statement.
286 * Returns:
287 * NULL continue to next statement
288 * EXP_CANT_INTERPRET cannot interpret statement at compile time
289 * !NULL expression from return statement
290 */
291
292 Expression *Statement::interpret(InterState *istate)
293 {
294 #if LOG
295 printf("Statement::interpret()\n");
296 #endif
297 START()
298 return EXP_CANT_INTERPRET;
299 }
300
301 Expression *ExpStatement::interpret(InterState *istate)
302 {
303 #if LOG
304 printf("ExpStatement::interpret(%s)\n", exp ? exp->toChars() : "");
305 #endif
306 START()
307 if (exp)
308 {
309 Expression *e = exp->interpret(istate);
310 if (e == EXP_CANT_INTERPRET)
311 {
312 //printf("-ExpStatement::interpret(): %p\n", e);
313 return EXP_CANT_INTERPRET;
314 }
315 }
316 return NULL;
317 }
318
319 Expression *CompoundStatement::interpret(InterState *istate)
320 { Expression *e = NULL;
321
322 #if LOG
323 printf("CompoundStatement::interpret()\n");
324 #endif
325 if (istate->start == this)
326 istate->start = NULL;
327 if (statements)
328 {
329 for (size_t i = 0; i < statements->dim; i++)
330 { Statement *s = (Statement *)statements->data[i];
331
332 if (s)
333 {
334 e = s->interpret(istate);
335 if (e)
336 break;
337 }
338 }
339 }
340 #if LOG
341 printf("-CompoundStatement::interpret() %p\n", e);
342 #endif
343 return e;
344 }
345
346 Expression *UnrolledLoopStatement::interpret(InterState *istate)
347 { Expression *e = NULL;
348
349 #if LOG
350 printf("UnrolledLoopStatement::interpret()\n");
351 #endif
352 if (istate->start == this)
353 istate->start = NULL;
354 if (statements)
355 {
356 for (size_t i = 0; i < statements->dim; i++)
357 { Statement *s = (Statement *)statements->data[i];
358
359 e = s->interpret(istate);
360 if (e == EXP_CANT_INTERPRET)
361 break;
362 if (e == EXP_CONTINUE_INTERPRET)
363 { e = NULL;
364 continue;
365 }
366 if (e == EXP_BREAK_INTERPRET)
367 { e = NULL;
368 break;
369 }
370 if (e)
371 break;
372 }
373 }
374 return e;
375 }
376
377 Expression *IfStatement::interpret(InterState *istate)
378 {
379 #if LOG
380 printf("IfStatement::interpret(%s)\n", condition->toChars());
381 #endif
382
383 if (istate->start == this)
384 istate->start = NULL;
385 if (istate->start)
386 {
387 Expression *e = NULL;
388 if (ifbody)
389 e = ifbody->interpret(istate);
390 if (istate->start && elsebody)
391 e = elsebody->interpret(istate);
392 return e;
393 }
394
395 Expression *e = condition->interpret(istate);
396 assert(e);
397 //if (e == EXP_CANT_INTERPRET) printf("cannot interpret\n");
398 if (e != EXP_CANT_INTERPRET)
399 {
400 if (e->isBool(TRUE))
401 e = ifbody ? ifbody->interpret(istate) : NULL;
402 else if (e->isBool(FALSE))
403 e = elsebody ? elsebody->interpret(istate) : NULL;
404 else
405 {
406 e = EXP_CANT_INTERPRET;
407 }
408 }
409 return e;
410 }
411
412 Expression *ScopeStatement::interpret(InterState *istate)
413 {
414 #if LOG
415 printf("ScopeStatement::interpret()\n");
416 #endif
417 if (istate->start == this)
418 istate->start = NULL;
419 return statement ? statement->interpret(istate) : NULL;
420 }
421
422 Expression *ReturnStatement::interpret(InterState *istate)
423 {
424 #if LOG
425 printf("ReturnStatement::interpret(%s)\n", exp ? exp->toChars() : "");
426 #endif
427 START()
428 if (!exp)
429 return EXP_VOID_INTERPRET;
430 #if LOG
431 Expression *e = exp->interpret(istate);
432 printf("e = %p\n", e);
433 return e;
434 #else
435 return exp->interpret(istate);
436 #endif
437 }
438
439 Expression *BreakStatement::interpret(InterState *istate)
440 {
441 #if LOG
442 printf("BreakStatement::interpret()\n");
443 #endif
444 START()
445 if (ident)
446 return EXP_CANT_INTERPRET;
447 else
448 return EXP_BREAK_INTERPRET;
449 }
450
451 Expression *ContinueStatement::interpret(InterState *istate)
452 {
453 #if LOG
454 printf("ContinueStatement::interpret()\n");
455 #endif
456 START()
457 if (ident)
458 return EXP_CANT_INTERPRET;
459 else
460 return EXP_CONTINUE_INTERPRET;
461 }
462
463 Expression *WhileStatement::interpret(InterState *istate)
464 {
465 #if LOG
466 printf("WhileStatement::interpret()\n");
467 #endif
468 if (istate->start == this)
469 istate->start = NULL;
470 Expression *e;
471
472 if (istate->start)
473 {
474 e = body ? body->interpret(istate) : NULL;
475 if (istate->start)
476 return NULL;
477 if (e == EXP_CANT_INTERPRET)
478 return e;
479 if (e == EXP_BREAK_INTERPRET)
480 return NULL;
481 if (e != EXP_CONTINUE_INTERPRET)
482 return e;
483 }
484
485 while (1)
486 {
487 e = condition->interpret(istate);
488 if (e == EXP_CANT_INTERPRET)
489 break;
490 if (!e->isConst())
491 { e = EXP_CANT_INTERPRET;
492 break;
493 }
494 if (e->isBool(TRUE))
495 { e = body ? body->interpret(istate) : NULL;
496 if (e == EXP_CANT_INTERPRET)
497 break;
498 if (e == EXP_CONTINUE_INTERPRET)
499 continue;
500 if (e == EXP_BREAK_INTERPRET)
501 { e = NULL;
502 break;
503 }
504 if (e)
505 break;
506 }
507 else if (e->isBool(FALSE))
508 { e = NULL;
509 break;
510 }
511 else
512 assert(0);
513 }
514 return e;
515 }
516
517 Expression *DoStatement::interpret(InterState *istate)
518 {
519 #if LOG
520 printf("DoStatement::interpret()\n");
521 #endif
522 if (istate->start == this)
523 istate->start = NULL;
524 Expression *e;
525
526 if (istate->start)
527 {
528 e = body ? body->interpret(istate) : NULL;
529 if (istate->start)
530 return NULL;
531 if (e == EXP_CANT_INTERPRET)
532 return e;
533 if (e == EXP_BREAK_INTERPRET)
534 return NULL;
535 if (e == EXP_CONTINUE_INTERPRET)
536 goto Lcontinue;
537 if (e)
538 return e;
539 }
540
541 while (1)
542 {
543 e = body ? body->interpret(istate) : NULL;
544 if (e == EXP_CANT_INTERPRET)
545 break;
546 if (e == EXP_BREAK_INTERPRET)
547 { e = NULL;
548 break;
549 }
550 if (e && e != EXP_CONTINUE_INTERPRET)
551 break;
552
553 Lcontinue:
554 e = condition->interpret(istate);
555 if (e == EXP_CANT_INTERPRET)
556 break;
557 if (!e->isConst())
558 { e = EXP_CANT_INTERPRET;
559 break;
560 }
561 if (e->isBool(TRUE))
562 {
563 }
564 else if (e->isBool(FALSE))
565 { e = NULL;
566 break;
567 }
568 else
569 assert(0);
570 }
571 return e;
572 }
573
574 Expression *ForStatement::interpret(InterState *istate)
575 {
576 #if LOG
577 printf("ForStatement::interpret()\n");
578 #endif
579 if (istate->start == this)
580 istate->start = NULL;
581 Expression *e;
582
583 if (init)
584 {
585 e = init->interpret(istate);
586 if (e == EXP_CANT_INTERPRET)
587 return e;
588 assert(!e);
589 }
590
591 if (istate->start)
592 {
593 e = body ? body->interpret(istate) : NULL;
594 if (istate->start)
595 return NULL;
596 if (e == EXP_CANT_INTERPRET)
597 return e;
598 if (e == EXP_BREAK_INTERPRET)
599 return NULL;
600 if (e == EXP_CONTINUE_INTERPRET)
601 goto Lcontinue;
602 if (e)
603 return e;
604 }
605
606 while (1)
607 {
608 if (!condition)
609 goto Lhead;
610 e = condition->interpret(istate);
611 if (e == EXP_CANT_INTERPRET)
612 break;
613 if (!e->isConst())
614 { e = EXP_CANT_INTERPRET;
615 break;
616 }
617 if (e->isBool(TRUE))
618 {
619 Lhead:
620 e = body ? body->interpret(istate) : NULL;
621 if (e == EXP_CANT_INTERPRET)
622 break;
623 if (e == EXP_BREAK_INTERPRET)
624 { e = NULL;
625 break;
626 }
627 if (e && e != EXP_CONTINUE_INTERPRET)
628 break;
629 Lcontinue:
630 if (increment)
631 {
632 e = increment->interpret(istate);
633 if (e == EXP_CANT_INTERPRET)
634 break;
635 }
636 }
637 else if (e->isBool(FALSE))
638 { e = NULL;
639 break;
640 }
641 else
642 assert(0);
643 }
644 return e;
645 }
646
647 Expression *ForeachStatement::interpret(InterState *istate)
648 {
649 #if LOG
650 printf("ForeachStatement::interpret()\n");
651 #endif
652 if (istate->start == this)
653 istate->start = NULL;
654 if (istate->start)
655 return NULL;
656
657 Expression *e = NULL;
658 Expression *eaggr;
659
660 if (value->isOut() || value->isRef())
661 return EXP_CANT_INTERPRET;
662
663 eaggr = aggr->interpret(istate);
664 if (eaggr == EXP_CANT_INTERPRET)
665 return EXP_CANT_INTERPRET;
666
667 Expression *dim = ArrayLength(Type::tsize_t, eaggr);
668 if (dim == EXP_CANT_INTERPRET)
669 return EXP_CANT_INTERPRET;
670
671 Expression *keysave = key ? key->value : NULL;
672 Expression *valuesave = value->value;
673
674 uinteger_t d = dim->toUInteger();
675 uinteger_t index;
676
677 if (op == TOKforeach)
678 {
679 for (index = 0; index < d; index++)
680 {
681 Expression *ekey = new IntegerExp(loc, index, Type::tsize_t);
682 if (key)
683 key->value = ekey;
684 e = Index(value->type, eaggr, ekey);
685 if (e == EXP_CANT_INTERPRET)
686 break;
687 value->value = e;
688
689 e = body ? body->interpret(istate) : NULL;
690 if (e == EXP_CANT_INTERPRET)
691 break;
692 if (e == EXP_BREAK_INTERPRET)
693 { e = NULL;
694 break;
695 }
696 if (e == EXP_CONTINUE_INTERPRET)
697 e = NULL;
698 else if (e)
699 break;
700 }
701 }
702 else // TOKforeach_reverse
703 {
704 for (index = d; index-- != 0;)
705 {
706 Expression *ekey = new IntegerExp(loc, index, Type::tsize_t);
707 if (key)
708 key->value = ekey;
709 e = Index(value->type, eaggr, ekey);
710 if (e == EXP_CANT_INTERPRET)
711 break;
712 value->value = e;
713
714 e = body ? body->interpret(istate) : NULL;
715 if (e == EXP_CANT_INTERPRET)
716 break;
717 if (e == EXP_BREAK_INTERPRET)
718 { e = NULL;
719 break;
720 }
721 if (e == EXP_CONTINUE_INTERPRET)
722 e = NULL;
723 else if (e)
724 break;
725 }
726 }
727 value->value = valuesave;
728 if (key)
729 key->value = keysave;
730 return e;
731 }
732
733 #if DMDV2
734 Expression *ForeachRangeStatement::interpret(InterState *istate)
735 {
736 #if LOG
737 printf("ForeachRangeStatement::interpret()\n");
738 #endif
739 if (istate->start == this)
740 istate->start = NULL;
741 if (istate->start)
742 return NULL;
743
744 Expression *e = NULL;
745 Expression *elwr = lwr->interpret(istate);
746 if (elwr == EXP_CANT_INTERPRET)
747 return EXP_CANT_INTERPRET;
748
749 Expression *eupr = upr->interpret(istate);
750 if (eupr == EXP_CANT_INTERPRET)
751 return EXP_CANT_INTERPRET;
752
753 Expression *keysave = key->value;
754
755 if (op == TOKforeach)
756 {
757 key->value = elwr;
758
759 while (1)
760 {
761 e = Cmp(TOKlt, key->value->type, key->value, upr);
762 if (e == EXP_CANT_INTERPRET)
763 break;
764 if (e->isBool(TRUE) == FALSE)
765 { e = NULL;
766 break;
767 }
768
769 e = body ? body->interpret(istate) : NULL;
770 if (e == EXP_CANT_INTERPRET)
771 break;
772 if (e == EXP_BREAK_INTERPRET)
773 { e = NULL;
774 break;
775 }
776 e = Add(key->value->type, key->value, new IntegerExp(loc, 1, key->value->type));
777 if (e == EXP_CANT_INTERPRET)
778 break;
779 key->value = e;
780 }
781 }
782 else // TOKforeach_reverse
783 {
784 key->value = eupr;
785
786 while (1)
787 {
788 e = Cmp(TOKgt, key->value->type, key->value, lwr);
789 if (e == EXP_CANT_INTERPRET)
790 break;
791 if (e->isBool(TRUE) == FALSE)
792 { e = NULL;
793 break;
794 }
795
796 e = Min(key->value->type, key->value, new IntegerExp(loc, 1, key->value->type));
797 if (e == EXP_CANT_INTERPRET)
798 break;
799 key->value = e;
800
801 e = body ? body->interpret(istate) : NULL;
802 if (e == EXP_CANT_INTERPRET)
803 break;
804 if (e == EXP_BREAK_INTERPRET)
805 { e = NULL;
806 break;
807 }
808 }
809 }
810 key->value = keysave;
811 return e;
812 }
813 #endif
814
815 Expression *SwitchStatement::interpret(InterState *istate)
816 {
817 #if LOG
818 printf("SwitchStatement::interpret()\n");
819 #endif
820 if (istate->start == this)
821 istate->start = NULL;
822 Expression *e = NULL;
823
824 if (istate->start)
825 {
826 e = body ? body->interpret(istate) : NULL;
827 if (istate->start)
828 return NULL;
829 if (e == EXP_CANT_INTERPRET)
830 return e;
831 if (e == EXP_BREAK_INTERPRET)
832 return NULL;
833 return e;
834 }
835
836
837 Expression *econdition = condition->interpret(istate);
838 if (econdition == EXP_CANT_INTERPRET)
839 return EXP_CANT_INTERPRET;
840
841 Statement *s = NULL;
842 if (cases)
843 {
844 for (size_t i = 0; i < cases->dim; i++)
845 {
846 CaseStatement *cs = (CaseStatement *)cases->data[i];
847 e = Equal(TOKequal, Type::tint32, econdition, cs->exp);
848 if (e == EXP_CANT_INTERPRET)
849 return EXP_CANT_INTERPRET;
850 if (e->isBool(TRUE))
851 { s = cs;
852 break;
853 }
854 }
855 }
856 if (!s)
857 { if (hasNoDefault)
858 error("no default or case for %s in switch statement", econdition->toChars());
859 s = sdefault;
860 }
861
862 assert(s);
863 istate->start = s;
864 e = body ? body->interpret(istate) : NULL;
865 assert(!istate->start);
866 if (e == EXP_BREAK_INTERPRET)
867 return NULL;
868 return e;
869 }
870
871 Expression *CaseStatement::interpret(InterState *istate)
872 {
873 #if LOG
874 printf("CaseStatement::interpret(%s) this = %p\n", exp->toChars(), this);
875 #endif
876 if (istate->start == this)
877 istate->start = NULL;
878 if (statement)
879 return statement->interpret(istate);
880 else
881 return NULL;
882 }
883
884 Expression *DefaultStatement::interpret(InterState *istate)
885 {
886 #if LOG
887 printf("DefaultStatement::interpret()\n");
888 #endif
889 if (istate->start == this)
890 istate->start = NULL;
891 if (statement)
892 return statement->interpret(istate);
893 else
894 return NULL;
895 }
896
897 Expression *GotoStatement::interpret(InterState *istate)
898 {
899 #if LOG
900 printf("GotoStatement::interpret()\n");
901 #endif
902 START()
903 assert(label && label->statement);
904 istate->gotoTarget = label->statement;
905 return EXP_GOTO_INTERPRET;
906 }
907
908 Expression *GotoCaseStatement::interpret(InterState *istate)
909 {
910 #if LOG
911 printf("GotoCaseStatement::interpret()\n");
912 #endif
913 START()
914 assert(cs);
915 istate->gotoTarget = cs;
916 return EXP_GOTO_INTERPRET;
917 }
918
919 Expression *GotoDefaultStatement::interpret(InterState *istate)
920 {
921 #if LOG
922 printf("GotoDefaultStatement::interpret()\n");
923 #endif
924 START()
925 assert(sw && sw->sdefault);
926 istate->gotoTarget = sw->sdefault;
927 return EXP_GOTO_INTERPRET;
928 }
929
930 Expression *LabelStatement::interpret(InterState *istate)
931 {
932 #if LOG
933 printf("LabelStatement::interpret()\n");
934 #endif
935 if (istate->start == this)
936 istate->start = NULL;
937 return statement ? statement->interpret(istate) : NULL;
938 }
939
940 /******************************** Expression ***************************/
941
942 Expression *Expression::interpret(InterState *istate)
943 {
944 #if LOG
945 printf("Expression::interpret() %s\n", toChars());
946 printf("type = %s\n", type->toChars());
947 dump(0);
948 #endif
949 return EXP_CANT_INTERPRET;
950 }
951
952 Expression *NullExp::interpret(InterState *istate)
953 {
954 return this;
955 }
956
957 Expression *IntegerExp::interpret(InterState *istate)
958 {
959 #if LOG
960 printf("IntegerExp::interpret() %s\n", toChars());
961 #endif
962 return this;
963 }
964
965 Expression *RealExp::interpret(InterState *istate)
966 {
967 #if LOG
968 printf("RealExp::interpret() %s\n", toChars());
969 #endif
970 return this;
971 }
972
973 Expression *ComplexExp::interpret(InterState *istate)
974 {
975 return this;
976 }
977
978 Expression *StringExp::interpret(InterState *istate)
979 {
980 #if LOG
981 printf("StringExp::interpret() %s\n", toChars());
982 #endif
983 return this;
984 }
985
986 Expression *getVarExp(Loc loc, InterState *istate, Declaration *d)
987 {
988 Expression *e = EXP_CANT_INTERPRET;
989 VarDeclaration *v = d->isVarDeclaration();
990 SymbolDeclaration *s = d->isSymbolDeclaration();
991 if (v)
992 {
993 #if DMDV2
994 if ((v->isConst() || v->isInvariant()) && v->init && !v->value)
995 #else
996 if (v->isConst() && v->init)
997 #endif
998 { e = v->init->toExpression();
999 if (e && !e->type)
1000 e->type = v->type;
1001 }
1002 else
1003 { e = v->value;
1004 if (!e)
1005 error(loc, "variable %s is used before initialization", v->toChars());
1006 else if (e != EXP_CANT_INTERPRET)
1007 e = e->interpret(istate);
1008 }
1009 if (!e)
1010 e = EXP_CANT_INTERPRET;
1011 }
1012 else if (s)
1013 {
1014 if (s->dsym->toInitializer() == s->sym)
1015 { Expressions *exps = new Expressions();
1016 e = new StructLiteralExp(0, s->dsym, exps);
1017 e = e->semantic(NULL);
1018 }
1019 }
1020 return e;
1021 }
1022
1023 Expression *VarExp::interpret(InterState *istate)
1024 {
1025 #if LOG
1026 printf("VarExp::interpret() %s\n", toChars());
1027 #endif
1028 return getVarExp(loc, istate, var);
1029 }
1030
1031 Expression *DeclarationExp::interpret(InterState *istate)
1032 {
1033 #if LOG
1034 printf("DeclarationExp::interpret() %s\n", toChars());
1035 #endif
1036 Expression *e;
1037 VarDeclaration *v = declaration->isVarDeclaration();
1038 if (v)
1039 {
1040 Dsymbol *s = v->toAlias();
1041 if (s == v && !v->isStatic() && v->init)
1042 {
1043 ExpInitializer *ie = v->init->isExpInitializer();
1044 if (ie)
1045 e = ie->exp->interpret(istate);
1046 else if (v->init->isVoidInitializer())
1047 e = NULL;
1048 }
1049 #if DMDV2
1050 else if (s == v && (v->isConst() || v->isInvariant()) && v->init)
1051 #else
1052 else if (s == v && v->isConst() && v->init)
1053 #endif
1054 { e = v->init->toExpression();
1055 if (!e)
1056 e = EXP_CANT_INTERPRET;
1057 else if (!e->type)
1058 e->type = v->type;
1059 }
1060 }
1061 else if (declaration->isAttribDeclaration() ||
1062 declaration->isTemplateMixin() ||
1063 declaration->isTupleDeclaration())
1064 { // These can be made to work, too lazy now
1065 e = EXP_CANT_INTERPRET;
1066 }
1067 else
1068 { // Others should not contain executable code, so are trivial to evaluate
1069 e = NULL;
1070 }
1071 #if LOG
1072 printf("-DeclarationExp::interpret(): %p\n", e);
1073 #endif
1074 return e;
1075 }
1076
1077 Expression *TupleExp::interpret(InterState *istate)
1078 {
1079 #if LOG
1080 printf("TupleExp::interpret() %s\n", toChars());
1081 #endif
1082 Expressions *expsx = NULL;
1083
1084 for (size_t i = 0; i < exps->dim; i++)
1085 { Expression *e = (Expression *)exps->data[i];
1086 Expression *ex;
1087
1088 ex = e->interpret(istate);
1089 if (ex == EXP_CANT_INTERPRET)
1090 { delete expsx;
1091 return ex;
1092 }
1093
1094 /* If any changes, do Copy On Write
1095 */
1096 if (ex != e)
1097 {
1098 if (!expsx)
1099 { expsx = new Expressions();
1100 expsx->setDim(exps->dim);
1101 for (size_t j = 0; j < i; j++)
1102 {
1103 expsx->data[j] = exps->data[j];
1104 }
1105 }
1106 expsx->data[i] = (void *)ex;
1107 }
1108 }
1109 if (expsx)
1110 { TupleExp *te = new TupleExp(loc, expsx);
1111 expandTuples(te->exps);
1112 te->type = new TypeTuple(te->exps);
1113 return te;
1114 }
1115 return this;
1116 }
1117
1118 Expression *ArrayLiteralExp::interpret(InterState *istate)
1119 { Expressions *expsx = NULL;
1120
1121 #if LOG
1122 printf("ArrayLiteralExp::interpret() %s\n", toChars());
1123 #endif
1124 if (elements)
1125 {
1126 for (size_t i = 0; i < elements->dim; i++)
1127 { Expression *e = (Expression *)elements->data[i];
1128 Expression *ex;
1129
1130 ex = e->interpret(istate);
1131 if (ex == EXP_CANT_INTERPRET)
1132 { delete expsx;
1133 return EXP_CANT_INTERPRET;
1134 }
1135
1136 /* If any changes, do Copy On Write
1137 */
1138 if (ex != e)
1139 {
1140 if (!expsx)
1141 { expsx = new Expressions();
1142 expsx->setDim(elements->dim);
1143 for (size_t j = 0; j < elements->dim; j++)
1144 {
1145 expsx->data[j] = elements->data[j];
1146 }
1147 }
1148 expsx->data[i] = (void *)ex;
1149 }
1150 }
1151 }
1152 if (elements && expsx)
1153 {
1154 expandTuples(expsx);
1155 if (expsx->dim != elements->dim)
1156 { delete expsx;
1157 return EXP_CANT_INTERPRET;
1158 }
1159 ArrayLiteralExp *ae = new ArrayLiteralExp(loc, expsx);
1160 ae->type = type;
1161 return ae;
1162 }
1163 return this;
1164 }
1165
1166 Expression *AssocArrayLiteralExp::interpret(InterState *istate)
1167 { Expressions *keysx = keys;
1168 Expressions *valuesx = values;
1169
1170 #if LOG
1171 printf("AssocArrayLiteralExp::interpret() %s\n", toChars());
1172 #endif
1173 for (size_t i = 0; i < keys->dim; i++)
1174 { Expression *ekey = (Expression *)keys->data[i];
1175 Expression *evalue = (Expression *)values->data[i];
1176 Expression *ex;
1177
1178 ex = ekey->interpret(istate);
1179 if (ex == EXP_CANT_INTERPRET)
1180 goto Lerr;
1181
1182 /* If any changes, do Copy On Write
1183 */
1184 if (ex != ekey)
1185 {
1186 if (keysx == keys)
1187 keysx = (Expressions *)keys->copy();
1188 keysx->data[i] = (void *)ex;
1189 }
1190
1191 ex = evalue->interpret(istate);
1192 if (ex == EXP_CANT_INTERPRET)
1193 goto Lerr;
1194
1195 /* If any changes, do Copy On Write
1196 */
1197 if (ex != evalue)
1198 {
1199 if (valuesx == values)
1200 valuesx = (Expressions *)values->copy();
1201 valuesx->data[i] = (void *)ex;
1202 }
1203 }
1204 if (keysx != keys)
1205 expandTuples(keysx);
1206 if (valuesx != values)
1207 expandTuples(valuesx);
1208 if (keysx->dim != valuesx->dim)
1209 goto Lerr;
1210
1211 /* Remove duplicate keys
1212 */
1213 for (size_t i = 1; i < keysx->dim; i++)
1214 { Expression *ekey = (Expression *)keysx->data[i - 1];
1215
1216 for (size_t j = i; j < keysx->dim; j++)
1217 { Expression *ekey2 = (Expression *)keysx->data[j];
1218 Expression *ex = Equal(TOKequal, Type::tbool, ekey, ekey2);
1219 if (ex == EXP_CANT_INTERPRET)
1220 goto Lerr;
1221 if (ex->isBool(TRUE)) // if a match
1222 {
1223 // Remove ekey
1224 if (keysx == keys)
1225 keysx = (Expressions *)keys->copy();
1226 if (valuesx == values)
1227 valuesx = (Expressions *)values->copy();
1228 keysx->remove(i - 1);
1229 valuesx->remove(i - 1);
1230 i -= 1; // redo the i'th iteration
1231 break;
1232 }
1233 }
1234 }
1235
1236 if (keysx != keys || valuesx != values)
1237 {
1238 AssocArrayLiteralExp *ae;
1239 ae = new AssocArrayLiteralExp(loc, keysx, valuesx);
1240 ae->type = type;
1241 return ae;
1242 }
1243 return this;
1244
1245 Lerr:
1246 if (keysx != keys)
1247 delete keysx;
1248 if (valuesx != values)
1249 delete values;
1250 return EXP_CANT_INTERPRET;
1251 }
1252
1253 Expression *StructLiteralExp::interpret(InterState *istate)
1254 { Expressions *expsx = NULL;
1255
1256 #if LOG
1257 printf("StructLiteralExp::interpret() %s\n", toChars());
1258 #endif
1259 /* We don't know how to deal with overlapping fields
1260 */
1261 if (sd->hasUnions)
1262 return EXP_CANT_INTERPRET;
1263
1264 if (elements)
1265 {
1266 for (size_t i = 0; i < elements->dim; i++)
1267 { Expression *e = (Expression *)elements->data[i];
1268 if (!e)
1269 continue;
1270
1271 Expression *ex = e->interpret(istate);
1272 if (ex == EXP_CANT_INTERPRET)
1273 { delete expsx;
1274 return EXP_CANT_INTERPRET;
1275 }
1276
1277 /* If any changes, do Copy On Write
1278 */
1279 if (ex != e)
1280 {
1281 if (!expsx)
1282 { expsx = new Expressions();
1283 expsx->setDim(elements->dim);
1284 for (size_t j = 0; j < elements->dim; j++)
1285 {
1286 expsx->data[j] = elements->data[j];
1287 }
1288 }
1289 expsx->data[i] = (void *)ex;
1290 }
1291 }
1292 }
1293 if (elements && expsx)
1294 {
1295 expandTuples(expsx);
1296 if (expsx->dim != elements->dim)
1297 { delete expsx;
1298 return EXP_CANT_INTERPRET;
1299 }
1300 StructLiteralExp *se = new StructLiteralExp(loc, sd, expsx);
1301 se->type = type;
1302 return se;
1303 }
1304 return this;
1305 }
1306
1307 Expression *UnaExp::interpretCommon(InterState *istate, Expression *(*fp)(Type *, Expression *))
1308 { Expression *e;
1309 Expression *e1;
1310
1311 #if LOG
1312 printf("UnaExp::interpretCommon() %s\n", toChars());
1313 #endif
1314 e1 = this->e1->interpret(istate);
1315 if (e1 == EXP_CANT_INTERPRET)
1316 goto Lcant;
1317 if (e1->isConst() != 1)
1318 goto Lcant;
1319
1320 e = (*fp)(type, e1);
1321 return e;
1322
1323 Lcant:
1324 return EXP_CANT_INTERPRET;
1325 }
1326
1327 #define UNA_INTERPRET(op) \
1328 Expression *op##Exp::interpret(InterState *istate) \
1329 { \
1330 return interpretCommon(istate, &op); \
1331 }
1332
1333 UNA_INTERPRET(Neg)
1334 UNA_INTERPRET(Com)
1335 UNA_INTERPRET(Not)
1336 UNA_INTERPRET(Bool)
1337
1338
1339 typedef Expression *(*fp_t)(Type *, Expression *, Expression *);
1340
1341 Expression *BinExp::interpretCommon(InterState *istate, fp_t fp)
1342 { Expression *e;
1343 Expression *e1;
1344 Expression *e2;
1345
1346 #if LOG
1347 printf("BinExp::interpretCommon() %s\n", toChars());
1348 #endif
1349 e1 = this->e1->interpret(istate);
1350 if (e1 == EXP_CANT_INTERPRET)
1351 goto Lcant;
1352 if (e1->isConst() != 1)
1353 goto Lcant;
1354
1355 e2 = this->e2->interpret(istate);
1356 if (e2 == EXP_CANT_INTERPRET)
1357 goto Lcant;
1358 if (e2->isConst() != 1)
1359 goto Lcant;
1360
1361 e = (*fp)(type, e1, e2);
1362 return e;
1363
1364 Lcant:
1365 return EXP_CANT_INTERPRET;
1366 }
1367
1368 #define BIN_INTERPRET(op) \
1369 Expression *op##Exp::interpret(InterState *istate) \
1370 { \
1371 return interpretCommon(istate, &op); \
1372 }
1373
1374 BIN_INTERPRET(Add)
1375 BIN_INTERPRET(Min)
1376 BIN_INTERPRET(Mul)
1377 BIN_INTERPRET(Div)
1378 BIN_INTERPRET(Mod)
1379 BIN_INTERPRET(Shl)
1380 BIN_INTERPRET(Shr)
1381 BIN_INTERPRET(Ushr)
1382 BIN_INTERPRET(And)
1383 BIN_INTERPRET(Or)
1384 BIN_INTERPRET(Xor)
1385
1386
1387 typedef Expression *(*fp2_t)(enum TOK, Type *, Expression *, Expression *);
1388
1389 Expression *BinExp::interpretCommon2(InterState *istate, fp2_t fp)
1390 { Expression *e;
1391 Expression *e1;
1392 Expression *e2;
1393
1394 #if LOG
1395 printf("BinExp::interpretCommon2() %s\n", toChars());
1396 #endif
1397 e1 = this->e1->interpret(istate);
1398 if (e1 == EXP_CANT_INTERPRET)
1399 goto Lcant;
1400 if (e1->isConst() != 1 &&
1401 e1->op != TOKnull &&
1402 e1->op != TOKstring &&
1403 e1->op != TOKarrayliteral &&
1404 e1->op != TOKstructliteral)
1405 goto Lcant;
1406
1407 e2 = this->e2->interpret(istate);
1408 if (e2 == EXP_CANT_INTERPRET)
1409 goto Lcant;
1410 if (e2->isConst() != 1 &&
1411 e2->op != TOKnull &&
1412 e2->op != TOKstring &&
1413 e2->op != TOKarrayliteral &&
1414 e2->op != TOKstructliteral)
1415 goto Lcant;
1416
1417 e = (*fp)(op, type, e1, e2);
1418 return e;
1419
1420 Lcant:
1421 return EXP_CANT_INTERPRET;
1422 }
1423
1424 #define BIN_INTERPRET2(op) \
1425 Expression *op##Exp::interpret(InterState *istate) \
1426 { \
1427 return interpretCommon2(istate, &op); \
1428 }
1429
1430 BIN_INTERPRET2(Equal)
1431 BIN_INTERPRET2(Identity)
1432 BIN_INTERPRET2(Cmp)
1433
1434 Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
1435 {
1436 #if LOG
1437 printf("BinExp::interpretAssignCommon() %s\n", toChars());
1438 #endif
1439 Expression *e = EXP_CANT_INTERPRET;
1440 Expression *e1 = this->e1;
1441
1442 if (fp)
1443 {
1444 if (e1->op == TOKcast)
1445 { CastExp *ce = (CastExp *)e1;
1446 e1 = ce->e1;
1447 }
1448 }
1449 if (e1 == EXP_CANT_INTERPRET)
1450 return e1;
1451 Expression *e2 = this->e2->interpret(istate);
1452 if (e2 == EXP_CANT_INTERPRET)
1453 return e2;
1454
1455 /* Assignment to variable of the form:
1456 * v = e2
1457 */
1458 if (e1->op == TOKvar)
1459 {
1460 VarExp *ve = (VarExp *)e1;
1461 VarDeclaration *v = ve->var->isVarDeclaration();
1462 if (v && !v->isDataseg())
1463 {
1464 /* Chase down rebinding of out and ref
1465 */
1466 if (v->value && v->value->op == TOKvar)
1467 {
1468 VarExp *ve2 = (VarExp *)v->value;
1469 if (ve2->var->isSymbolDeclaration())
1470 {
1471 /* This can happen if v is a struct initialized to
1472 * 0 using an __initZ SymbolDeclaration from
1473 * TypeStruct::defaultInit()
1474 */
1475 }
1476 else
1477 v = ve2->var->isVarDeclaration();
1478 assert(v);
1479 }
1480
1481 Expression *ev = v->value;
1482 if (fp && !ev)
1483 { error("variable %s is used before initialization", v->toChars());
1484 return e;
1485 }
1486 if (fp)
1487 e2 = (*fp)(v->type, ev, e2);
1488 else
1489 { /* Look for special case of struct being initialized with 0.
1490 */
1491 if (v->type->toBasetype()->ty == Tstruct && e2->op == TOKint64)
1492 {
1493 e2 = v->type->defaultInit();
1494 }
1495 e2 = Cast(v->type, v->type, e2);
1496 }
1497 if (e2 != EXP_CANT_INTERPRET)
1498 {
1499 if (!v->isParameter())
1500 {
1501 for (size_t i = 0; 1; i++)
1502 {
1503 if (i == istate->vars.dim)
1504 { istate->vars.push(v);
1505 //printf("\tadding %s to istate\n", v->toChars());
1506 break;
1507 }
1508 if (v == (VarDeclaration *)istate->vars.data[i])
1509 break;
1510 }
1511 }
1512 v->value = e2;
1513 e = Cast(type, type, post ? ev : e2);
1514 }
1515 }
1516 }
1517 /* Assignment to struct member of the form:
1518 * *(symoffexp) = e2
1519 */
1520 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff)
1521 { SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1;
1522 VarDeclaration *v = soe->var->isVarDeclaration();
1523
1524 if (v->isDataseg())
1525 return EXP_CANT_INTERPRET;
1526 if (fp && !v->value)
1527 { error("variable %s is used before initialization", v->toChars());
1528 return e;
1529 }
1530 Expression *vie = v->value;
1531 if (vie->op == TOKvar)
1532 {
1533 Declaration *d = ((VarExp *)vie)->var;
1534 vie = getVarExp(e1->loc, istate, d);
1535 }
1536 if (vie->op != TOKstructliteral)
1537 return EXP_CANT_INTERPRET;
1538 StructLiteralExp *se = (StructLiteralExp *)vie;
1539 int fieldi = se->getFieldIndex(type, soe->offset);
1540 if (fieldi == -1)
1541 return EXP_CANT_INTERPRET;
1542 Expression *ev = se->getField(type, soe->offset);
1543 if (fp)
1544 e2 = (*fp)(type, ev, e2);
1545 else
1546 e2 = Cast(type, type, e2);
1547 if (e2 == EXP_CANT_INTERPRET)
1548 return e2;
1549
1550 if (!v->isParameter())
1551 {
1552 for (size_t i = 0; 1; i++)
1553 {
1554 if (i == istate->vars.dim)
1555 { istate->vars.push(v);
1556 break;
1557 }
1558 if (v == (VarDeclaration *)istate->vars.data[i])
1559 break;
1560 }
1561 }
1562
1563 /* Create new struct literal reflecting updated fieldi
1564 */
1565 Expressions *expsx = new Expressions();
1566 expsx->setDim(se->elements->dim);
1567 for (size_t j = 0; j < expsx->dim; j++)
1568 {
1569 if (j == fieldi)
1570 expsx->data[j] = (void *)e2;
1571 else
1572 expsx->data[j] = se->elements->data[j];
1573 }
1574 v->value = new StructLiteralExp(se->loc, se->sd, expsx);
1575 v->value->type = se->type;
1576
1577 e = Cast(type, type, post ? ev : e2);
1578 }
1579 /* Assignment to array element of the form:
1580 * a[i] = e2
1581 */
1582 else if (e1->op == TOKindex && ((IndexExp *)e1)->e1->op == TOKvar)
1583 { IndexExp *ie = (IndexExp *)e1;
1584 VarExp *ve = (VarExp *)ie->e1;
1585 VarDeclaration *v = ve->var->isVarDeclaration();
1586
1587 if (!v || v->isDataseg())
1588 return EXP_CANT_INTERPRET;
1589 if (!v->value)
1590 {
1591 if (fp)
1592 { error("variable %s is used before initialization", v->toChars());
1593 return e;
1594 }
1595
1596 Type *t = v->type->toBasetype();
1597 if (t->ty == Tsarray)
1598 {
1599 /* This array was void initialized. Create a
1600 * default initializer for it.
1601 * What we should do is fill the array literal with
1602 * NULL data, so use-before-initialized can be detected.
1603 * But we're too lazy at the moment to do it, as that
1604 * involves redoing Index() and whoever calls it.
1605 */
1606 Expression *ev = v->type->defaultInit();
1607 size_t dim = ((TypeSArray *)t)->dim->toInteger();
1608 Expressions *elements = new Expressions();
1609 elements->setDim(dim);
1610 for (size_t i = 0; i < dim; i++)
1611 elements->data[i] = (void *)ev;
1612 ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements);
1613 ae->type = v->type;
1614 v->value = ae;
1615 }
1616 else
1617 return EXP_CANT_INTERPRET;
1618 }
1619
1620 ArrayLiteralExp *ae = NULL;
1621 AssocArrayLiteralExp *aae = NULL;
1622 StringExp *se = NULL;
1623 if (v->value->op == TOKarrayliteral)
1624 ae = (ArrayLiteralExp *)v->value;
1625 else if (v->value->op == TOKassocarrayliteral)
1626 aae = (AssocArrayLiteralExp *)v->value;
1627 else if (v->value->op == TOKstring)
1628 se = (StringExp *)v->value;
1629 else
1630 return EXP_CANT_INTERPRET;
1631
1632 Expression *index = ie->e2->interpret(istate);
1633 if (index == EXP_CANT_INTERPRET)
1634 return EXP_CANT_INTERPRET;
1635 Expression *ev;
1636 if (fp || ae || se) // not for aae, because key might not be there
1637 {
1638 ev = Index(type, v->value, index);
1639 if (ev == EXP_CANT_INTERPRET)
1640 return EXP_CANT_INTERPRET;
1641 }
1642
1643 if (fp)
1644 e2 = (*fp)(type, ev, e2);
1645 else
1646 e2 = Cast(type, type, e2);
1647 if (e2 == EXP_CANT_INTERPRET)
1648 return e2;
1649
1650 if (!v->isParameter())
1651 {
1652 for (size_t i = 0; 1; i++)
1653 {
1654 if (i == istate->vars.dim)
1655 { istate->vars.push(v);
1656 break;
1657 }
1658 if (v == (VarDeclaration *)istate->vars.data[i])
1659 break;
1660 }
1661 }
1662
1663 if (ae)
1664 {
1665 /* Create new array literal reflecting updated elem
1666 */
1667 int elemi = index->toInteger();
1668 Expressions *expsx = new Expressions();
1669 expsx->setDim(ae->elements->dim);
1670 for (size_t j = 0; j < expsx->dim; j++)
1671 {
1672 if (j == elemi)
1673 expsx->data[j] = (void *)e2;
1674 else
1675 expsx->data[j] = ae->elements->data[j];
1676 }
1677 v->value = new ArrayLiteralExp(ae->loc, expsx);
1678 v->value->type = ae->type;
1679 }
1680 else if (aae)
1681 {
1682 /* Create new associative array literal reflecting updated key/value
1683 */
1684 Expressions *keysx = aae->keys;
1685 Expressions *valuesx = new Expressions();
1686 valuesx->setDim(aae->values->dim);
1687 int updated = 0;
1688 for (size_t j = valuesx->dim; j; )
1689 { j--;
1690 Expression *ekey = (Expression *)aae->keys->data[j];
1691 Expression *ex = Equal(TOKequal, Type::tbool, ekey, index);
1692 if (ex == EXP_CANT_INTERPRET)
1693 return EXP_CANT_INTERPRET;
1694 if (ex->isBool(TRUE))
1695 { valuesx->data[j] = (void *)e2;
1696 updated = 1;
1697 }
1698 else
1699 valuesx->data[j] = aae->values->data[j];
1700 }
1701 if (!updated)
1702 { // Append index/e2 to keysx[]/valuesx[]
1703 valuesx->push(e2);
1704 keysx = (Expressions *)keysx->copy();
1705 keysx->push(index);
1706 }
1707 v->value = new AssocArrayLiteralExp(aae->loc, keysx, valuesx);
1708 v->value->type = aae->type;
1709 }
1710 else if (se)
1711 {
1712 /* Create new string literal reflecting updated elem
1713 */
1714 int elemi = index->toInteger();
1715 unsigned char *s;
1716 s = (unsigned char *)mem.calloc(se->len + 1, se->sz);
1717 memcpy(s, se->string, se->len * se->sz);
1718 unsigned value = e2->toInteger();
1719 switch (se->sz)
1720 {
1721 case 1: s[elemi] = value; break;
1722 case 2: ((unsigned short *)s)[elemi] = value; break;
1723 case 4: ((unsigned *)s)[elemi] = value; break;
1724 default:
1725 assert(0);
1726 break;
1727 }
1728 StringExp *se2 = new StringExp(se->loc, s, se->len);
1729 se2->committed = se->committed;
1730 se2->postfix = se->postfix;
1731 se2->type = se->type;
1732 v->value = se2;
1733 }
1734 else
1735 assert(0);
1736
1737 e = Cast(type, type, post ? ev : e2);
1738 }
1739 else
1740 {
1741 #ifdef DEBUG
1742 dump(0);
1743 #endif
1744 }
1745 return e;
1746 }
1747
1748 Expression *AssignExp::interpret(InterState *istate)
1749 {
1750 return interpretAssignCommon(istate, NULL);
1751 }
1752
1753 #define BIN_ASSIGN_INTERPRET(op) \
1754 Expression *op##AssignExp::interpret(InterState *istate) \
1755 { \
1756 return interpretAssignCommon(istate, &op); \
1757 }
1758
1759 BIN_ASSIGN_INTERPRET(Add)
1760 BIN_ASSIGN_INTERPRET(Min)
1761 BIN_ASSIGN_INTERPRET(Cat)
1762 BIN_ASSIGN_INTERPRET(Mul)
1763 BIN_ASSIGN_INTERPRET(Div)
1764 BIN_ASSIGN_INTERPRET(Mod)
1765 BIN_ASSIGN_INTERPRET(Shl)
1766 BIN_ASSIGN_INTERPRET(Shr)
1767 BIN_ASSIGN_INTERPRET(Ushr)
1768 BIN_ASSIGN_INTERPRET(And)
1769 BIN_ASSIGN_INTERPRET(Or)
1770 BIN_ASSIGN_INTERPRET(Xor)
1771
1772 Expression *PostExp::interpret(InterState *istate)
1773 {
1774 #if LOG
1775 printf("PostExp::interpret() %s\n", toChars());
1776 #endif
1777 Expression *e;
1778 if (op == TOKplusplus)
1779 e = interpretAssignCommon(istate, &Add, 1);
1780 else
1781 e = interpretAssignCommon(istate, &Min, 1);
1782 #if LOG
1783 if (e == EXP_CANT_INTERPRET)
1784 printf("PostExp::interpret() CANT\n");
1785 #endif
1786 return e;
1787 }
1788
1789 Expression *AndAndExp::interpret(InterState *istate)
1790 {
1791 #if LOG
1792 printf("AndAndExp::interpret() %s\n", toChars());
1793 #endif
1794 Expression *e = e1->interpret(istate);
1795 if (e != EXP_CANT_INTERPRET)
1796 {
1797 if (e->isBool(FALSE))
1798 e = new IntegerExp(e1->loc, 0, type);
1799 else if (e->isBool(TRUE))
1800 {
1801 e = e2->interpret(istate);
1802 if (e != EXP_CANT_INTERPRET)
1803 {
1804 if (e->isBool(FALSE))
1805 e = new IntegerExp(e1->loc, 0, type);
1806 else if (e->isBool(TRUE))
1807 e = new IntegerExp(e1->loc, 1, type);
1808 else
1809 e = EXP_CANT_INTERPRET;
1810 }
1811 }
1812 else
1813 e = EXP_CANT_INTERPRET;
1814 }
1815 return e;
1816 }
1817
1818 Expression *OrOrExp::interpret(InterState *istate)
1819 {
1820 #if LOG
1821 printf("OrOrExp::interpret() %s\n", toChars());
1822 #endif
1823 Expression *e = e1->interpret(istate);
1824 if (e != EXP_CANT_INTERPRET)
1825 {
1826 if (e->isBool(TRUE))
1827 e = new IntegerExp(e1->loc, 1, type);
1828 else if (e->isBool(FALSE))
1829 {
1830 e = e2->interpret(istate);
1831 if (e != EXP_CANT_INTERPRET)
1832 {
1833 if (e->isBool(FALSE))
1834 e = new IntegerExp(e1->loc, 0, type);
1835 else if (e->isBool(TRUE))
1836 e = new IntegerExp(e1->loc, 1, type);
1837 else
1838 e = EXP_CANT_INTERPRET;
1839 }
1840 }
1841 else
1842 e = EXP_CANT_INTERPRET;
1843 }
1844 return e;
1845 }
1846
1847
1848 Expression *CallExp::interpret(InterState *istate)
1849 { Expression *e = EXP_CANT_INTERPRET;
1850
1851 #if LOG
1852 printf("CallExp::interpret() %s\n", toChars());
1853 #endif
1854 if (e1->op == TOKvar)
1855 {
1856 FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration();
1857 if (fd)
1858 {
1859 #if DMDV2
1860 enum BUILTIN b = fd->isBuiltin();
1861 if (b)
1862 { Expressions args;
1863 args.setDim(arguments->dim);
1864 for (size_t i = 0; i < args.dim; i++)
1865 {
1866 Expression *earg = (Expression *)arguments->data[i];
1867 earg = earg->interpret(istate);
1868 if (earg == EXP_CANT_INTERPRET)
1869 return earg;
1870 args.data[i] = (void *)earg;
1871 }
1872 e = eval_builtin(b, &args);
1873 if (!e)
1874 e = EXP_CANT_INTERPRET;
1875 }
1876 else
1877 #endif
1878 // Inline .dup
1879 if (fd->ident == Id::adDup && arguments && arguments->dim == 2)
1880 {
1881 e = (Expression *)arguments->data[1];
1882 e = e->interpret(istate);
1883 if (e != EXP_CANT_INTERPRET)
1884 {
1885 e = expType(type, e);
1886 }
1887 }
1888 else
1889 {
1890 Expression *eresult = fd->interpret(istate, arguments);
1891 if (eresult)
1892 e = eresult;
1893 else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors)
1894 e = EXP_VOID_INTERPRET;
1895 else
1896 error("cannot evaluate %s at compile time", toChars());
1897 }
1898 }
1899 }
1900 return e;
1901 }
1902
1903 Expression *CommaExp::interpret(InterState *istate)
1904 {
1905 #if LOG
1906 printf("CommaExp::interpret() %s\n", toChars());
1907 #endif
1908 Expression *e = e1->interpret(istate);
1909 if (e != EXP_CANT_INTERPRET)
1910 e = e2->interpret(istate);
1911 return e;
1912 }
1913
1914 Expression *CondExp::interpret(InterState *istate)
1915 {
1916 #if LOG
1917 printf("CondExp::interpret() %s\n", toChars());
1918 #endif
1919 Expression *e = econd->interpret(istate);
1920 if (e != EXP_CANT_INTERPRET)
1921 {
1922 if (e->isBool(TRUE))
1923 e = e1->interpret(istate);
1924 else if (e->isBool(FALSE))
1925 e = e2->interpret(istate);
1926 else
1927 e = EXP_CANT_INTERPRET;
1928 }
1929 return e;
1930 }
1931
1932 Expression *ArrayLengthExp::interpret(InterState *istate)
1933 { Expression *e;
1934 Expression *e1;
1935
1936 #if LOG
1937 printf("ArrayLengthExp::interpret() %s\n", toChars());
1938 #endif
1939 e1 = this->e1->interpret(istate);
1940 if (e1 == EXP_CANT_INTERPRET)
1941 goto Lcant;
1942 if (e1->op == TOKstring || e1->op == TOKarrayliteral || e1->op == TOKassocarrayliteral)
1943 {
1944 e = ArrayLength(type, e1);
1945 }
1946 else if (e1->op == TOKnull)
1947 {
1948 e = new IntegerExp(loc, 0, type);
1949 }
1950 else
1951 goto Lcant;
1952 return e;
1953
1954 Lcant:
1955 return EXP_CANT_INTERPRET;
1956 }
1957
1958 Expression *IndexExp::interpret(InterState *istate)
1959 { Expression *e;
1960 Expression *e1;
1961 Expression *e2;
1962
1963 #if LOG
1964 printf("IndexExp::interpret() %s\n", toChars());
1965 #endif
1966 e1 = this->e1->interpret(istate);
1967 if (e1 == EXP_CANT_INTERPRET)
1968 goto Lcant;
1969
1970 if (e1->op == TOKstring || e1->op == TOKarrayliteral)
1971 {
1972 /* Set the $ variable
1973 */
1974 e = ArrayLength(Type::tsize_t, e1);
1975 if (e == EXP_CANT_INTERPRET)
1976 goto Lcant;
1977 if (lengthVar)
1978 lengthVar->value = e;
1979 }
1980
1981 e2 = this->e2->interpret(istate);
1982 if (e2 == EXP_CANT_INTERPRET)
1983 goto Lcant;
1984 return Index(type, e1, e2);
1985
1986 Lcant:
1987 return EXP_CANT_INTERPRET;
1988 }
1989
1990
1991 Expression *SliceExp::interpret(InterState *istate)
1992 { Expression *e;
1993 Expression *e1;
1994 Expression *lwr;
1995 Expression *upr;
1996
1997 #if LOG
1998 printf("SliceExp::interpret() %s\n", toChars());
1999 #endif
2000 e1 = this->e1->interpret(istate);
2001 if (e1 == EXP_CANT_INTERPRET)
2002 goto Lcant;
2003 if (!this->lwr)
2004 {
2005 e = e1->castTo(NULL, type);
2006 return e->interpret(istate);
2007 }
2008
2009 /* Set the $ variable
2010 */
2011 e = ArrayLength(Type::tsize_t, e1);
2012 if (e == EXP_CANT_INTERPRET)
2013 goto Lcant;
2014 if (lengthVar)
2015 lengthVar->value = e;
2016
2017 /* Evaluate lower and upper bounds of slice
2018 */
2019 lwr = this->lwr->interpret(istate);
2020 if (lwr == EXP_CANT_INTERPRET)
2021 goto Lcant;
2022 upr = this->upr->interpret(istate);
2023 if (upr == EXP_CANT_INTERPRET)
2024 goto Lcant;
2025
2026 return Slice(type, e1, lwr, upr);
2027
2028 Lcant:
2029 return EXP_CANT_INTERPRET;
2030 }
2031
2032
2033 Expression *CatExp::interpret(InterState *istate)
2034 { Expression *e;
2035 Expression *e1;
2036 Expression *e2;
2037
2038 #if LOG
2039 printf("CatExp::interpret() %s\n", toChars());
2040 #endif
2041 e1 = this->e1->interpret(istate);
2042 if (e1 == EXP_CANT_INTERPRET)
2043 {
2044 goto Lcant;
2045 }
2046 e2 = this->e2->interpret(istate);
2047 if (e2 == EXP_CANT_INTERPRET)
2048 goto Lcant;
2049 return Cat(type, e1, e2);
2050
2051 Lcant:
2052 #if LOG
2053 printf("CatExp::interpret() %s CANT\n", toChars());
2054 #endif
2055 return EXP_CANT_INTERPRET;
2056 }
2057
2058
2059 Expression *CastExp::interpret(InterState *istate)
2060 { Expression *e;
2061 Expression *e1;
2062
2063 #if LOG
2064 printf("CastExp::interpret() %s\n", toChars());
2065 #endif
2066 e1 = this->e1->interpret(istate);
2067 if (e1 == EXP_CANT_INTERPRET)
2068 goto Lcant;
2069 return Cast(type, to, e1);
2070
2071 Lcant:
2072 #if LOG
2073 printf("CastExp::interpret() %s CANT\n", toChars());
2074 #endif
2075 return EXP_CANT_INTERPRET;
2076 }
2077
2078
2079 Expression *AssertExp::interpret(InterState *istate)
2080 { Expression *e;
2081 Expression *e1;
2082
2083 #if LOG
2084 printf("AssertExp::interpret() %s\n", toChars());
2085 #endif
2086 e1 = this->e1->interpret(istate);
2087 if (e1 == EXP_CANT_INTERPRET)
2088 goto Lcant;
2089 if (e1->isBool(TRUE))
2090 {
2091 }
2092 else if (e1->isBool(FALSE))
2093 {
2094 if (msg)
2095 {
2096 e = msg->interpret(istate);
2097 if (e == EXP_CANT_INTERPRET)
2098 goto Lcant;
2099 error("%s", e->toChars());
2100 }
2101 else
2102 error("%s failed", toChars());
2103 goto Lcant;
2104 }
2105 else
2106 goto Lcant;
2107 return e1;
2108
2109 Lcant:
2110 return EXP_CANT_INTERPRET;
2111 }
2112
2113 Expression *PtrExp::interpret(InterState *istate)
2114 { Expression *e = EXP_CANT_INTERPRET;
2115
2116 #if LOG
2117 printf("PtrExp::interpret() %s\n", toChars());
2118 #endif
2119
2120 // Constant fold *(&structliteral + offset)
2121 if (e1->op == TOKadd)
2122 { AddExp *ae = (AddExp *)e1;
2123 if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64)
2124 { AddrExp *ade = (AddrExp *)ae->e1;
2125 Expression *ex = ade->e1;
2126 ex = ex->interpret(istate);
2127 if (ex != EXP_CANT_INTERPRET)
2128 {
2129 if (ex->op == TOKstructliteral)
2130 { StructLiteralExp *se = (StructLiteralExp *)ex;
2131 unsigned offset = ae->e2->toInteger();
2132 e = se->getField(type, offset);
2133 if (!e)
2134 e = EXP_CANT_INTERPRET;
2135 return e;
2136 }
2137 }
2138 }
2139 e = Ptr(type, e1);
2140 }
2141 else if (e1->op == TOKsymoff)
2142 { SymOffExp *soe = (SymOffExp *)e1;
2143 VarDeclaration *v = soe->var->isVarDeclaration();
2144 if (v)
2145 { Expression *ev = getVarExp(loc, istate, v);
2146 if (ev != EXP_CANT_INTERPRET && ev->op == TOKstructliteral)
2147 { StructLiteralExp *se = (StructLiteralExp *)ev;
2148 e = se->getField(type, soe->offset);
2149 if (!e)
2150 e = EXP_CANT_INTERPRET;
2151 }
2152 }
2153 }
2154 #if LOG
2155 if (e == EXP_CANT_INTERPRET)
2156 printf("PtrExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars());
2157 #endif
2158 return e;
2159 }
2160
2161 Expression *DotVarExp::interpret(InterState *istate)
2162 { Expression *e = EXP_CANT_INTERPRET;
2163
2164 Expression *ex = e1->interpret(istate);
2165
2166 // Constant fold structliteral.member
2167 if (ex != EXP_CANT_INTERPRET && ex->op == TOKstructliteral)
2168 { StructLiteralExp *se = (StructLiteralExp *)ex;
2169
2170 VarDeclaration* v;
2171 if (v = var->isVarDeclaration())
2172 {
2173 e = se->getField(type, v->offset);
2174 if (!e)
2175 e = EXP_CANT_INTERPRET;
2176 }
2177 }
2178
2179 return e;
2180 }
2181
2182 /******************************* Special Functions ***************************/
2183
2184 Expression *interpret_aaLen(InterState *istate, Expressions *arguments)
2185 {
2186 if (!arguments || arguments->dim != 1)
2187 return NULL;
2188 Expression *earg = (Expression *)arguments->data[0];
2189 earg = earg->interpret(istate);
2190 if (earg == EXP_CANT_INTERPRET)
2191 return NULL;
2192 if (earg->op != TOKassocarrayliteral)
2193 return NULL;
2194 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
2195 Expression *e = new IntegerExp(aae->loc, aae->keys->dim, Type::tsize_t);
2196 return e;
2197 }
2198
2199 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments)
2200 {
2201 //printf("interpret_aaKeys()\n");
2202 if (!arguments || arguments->dim != 2)
2203 return NULL;
2204 Expression *earg = (Expression *)arguments->data[0];
2205 earg = earg->interpret(istate);
2206 if (earg == EXP_CANT_INTERPRET)
2207 return NULL;
2208 if (earg->op != TOKassocarrayliteral)
2209 return NULL;
2210 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
2211 Expression *e = new ArrayLiteralExp(aae->loc, aae->keys);
2212 return e;
2213 }
2214
2215 Expression *interpret_aaValues(InterState *istate, Expressions *arguments)
2216 {
2217 //printf("interpret_aaValues()\n");
2218 if (!arguments || arguments->dim != 3)
2219 return NULL;
2220 Expression *earg = (Expression *)arguments->data[0];
2221 earg = earg->interpret(istate);
2222 if (earg == EXP_CANT_INTERPRET)
2223 return NULL;
2224 if (earg->op != TOKassocarrayliteral)
2225 return NULL;
2226 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
2227 Expression *e = new ArrayLiteralExp(aae->loc, aae->values);
2228 //printf("result is %s\n", e->toChars());
2229 return e;
2230 }
2231