Document search flags
[delight/core.git] / dmd2 / interpret.c
blob89effd401f5c8099a7cf26068df1ab9216dfca42
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.
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <assert.h>
15 #include "mem.h"
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"
28 #define LOG 0
30 struct InterState
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
38 InterState();
41 InterState::InterState()
43 memset(this, 0, sizeof(InterState));
46 Expression *interpret_aaLen(InterState *istate, Expressions *arguments);
47 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments);
48 Expression *interpret_aaValues(InterState *istate, Expressions *arguments);
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.
57 Expression *FuncDeclaration::interpret(InterState *istate, Expressions *arguments)
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);
72 if (cantInterpret || semanticRun == 1)
73 return NULL;
75 if (needThis() || isNested() || !fbody)
76 { cantInterpret = 1;
77 return NULL;
80 //printf("test2 %d, %p\n", semanticRun, scope);
81 if (semanticRun == 0 && scope)
83 semantic3(scope);
85 if (semanticRun < 2)
86 return NULL;
88 Type *tb = type->toBasetype();
89 assert(tb->ty == Tfunction);
90 TypeFunction *tf = (TypeFunction *)tb;
91 Type *tret = tf->next->toBasetype();
92 if (tf->varargs /*|| tret->ty == Tvoid*/)
93 { cantInterpret = 1;
94 return NULL;
97 if (tf->parameters)
98 { size_t dim = Argument::dim(tf->parameters);
99 for (size_t i = 0; i < dim; i++)
100 { Argument *arg = Argument::getNth(tf->parameters, i);
101 if (arg->storageClass & STClazy)
102 { cantInterpret = 1;
103 return NULL;
108 InterState istatex;
109 istatex.caller = istate;
110 istatex.fd = this;
112 Expressions vsave; // place to save previous parameter values
113 size_t dim = 0;
114 if (arguments)
116 dim = arguments->dim;
117 assert(!dim || parameters->dim == dim);
118 vsave.setDim(dim);
120 /* Evaluate all the arguments to the function,
121 * store the results in eargs[]
123 Expressions eargs;
124 eargs.setDim(dim);
126 for (size_t i = 0; i < dim; i++)
127 { Expression *earg = (Expression *)arguments->data[i];
128 Argument *arg = Argument::getNth(tf->parameters, i);
130 if (arg->storageClass & (STCout | STCref))
133 else
134 { /* Value parameters
136 Type *ta = arg->type->toBasetype();
137 if (ta->ty == Tsarray && earg->op == TOKaddress)
139 /* Static arrays are passed by a simple pointer.
140 * Skip past this to get at the actual arg.
142 earg = ((AddrExp *)earg)->e1;
144 earg = earg->interpret(istate ? istate : &istatex);
145 if (earg == EXP_CANT_INTERPRET)
146 return NULL;
148 eargs.data[i] = earg;
151 for (size_t i = 0; i < dim; i++)
152 { Expression *earg = (Expression *)eargs.data[i];
153 Argument *arg = Argument::getNth(tf->parameters, i);
154 VarDeclaration *v = (VarDeclaration *)parameters->data[i];
155 vsave.data[i] = v->value;
156 #if LOG
157 printf("arg[%d] = %s\n", i, earg->toChars());
158 #endif
159 if (arg->storageClass & (STCout | STCref))
161 /* Bind out or ref parameter to the corresponding
162 * variable v2
164 if (!istate || earg->op != TOKvar)
165 return NULL; // can't bind to non-interpreted vars
167 VarDeclaration *v2;
168 while (1)
170 VarExp *ve = (VarExp *)earg;
171 v2 = ve->var->isVarDeclaration();
172 if (!v2)
173 return NULL;
174 if (!v2->value || v2->value->op != TOKvar)
175 break;
176 earg = v2->value;
179 v->value = new VarExp(earg->loc, v2);
181 /* Don't restore the value of v2 upon function return
183 assert(istate);
184 for (size_t i = 0; i < istate->vars.dim; i++)
185 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
186 if (v == v2)
187 { istate->vars.data[i] = NULL;
188 break;
192 else
193 { /* Value parameters
195 v->value = earg;
197 #if LOG
198 printf("interpreted arg[%d] = %s\n", i, earg->toChars());
199 #endif
203 /* Save the values of the local variables used
205 Expressions valueSaves;
206 if (istate)
208 //printf("saving local variables...\n");
209 valueSaves.setDim(istate->vars.dim);
210 for (size_t i = 0; i < istate->vars.dim; i++)
211 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
212 if (v)
214 //printf("\tsaving [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : "");
215 valueSaves.data[i] = v->value;
216 v->value = NULL;
221 Expression *e = NULL;
223 while (1)
225 e = fbody->interpret(&istatex);
226 if (e == EXP_CANT_INTERPRET)
228 #if LOG
229 printf("function body failed to interpret\n");
230 #endif
231 e = NULL;
234 /* This is how we deal with a recursive statement AST
235 * that has arbitrary goto statements in it.
236 * Bubble up a 'result' which is the target of the goto
237 * statement, then go recursively down the AST looking
238 * for that statement, then execute starting there.
240 if (e == EXP_GOTO_INTERPRET)
242 istatex.start = istatex.gotoTarget; // set starting statement
243 istatex.gotoTarget = NULL;
245 else
246 break;
249 /* Restore the parameter values
251 for (size_t i = 0; i < dim; i++)
253 VarDeclaration *v = (VarDeclaration *)parameters->data[i];
254 v->value = (Expression *)vsave.data[i];
257 if (istate)
259 /* Restore the variable values
261 //printf("restoring local variables...\n");
262 for (size_t i = 0; i < istate->vars.dim; i++)
263 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
264 if (v)
265 { v->value = (Expression *)valueSaves.data[i];
266 //printf("\trestoring [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : "");
271 return e;
274 /******************************** Statement ***************************/
276 #define START() \
277 if (istate->start) \
278 { if (istate->start != this) \
279 return NULL; \
280 istate->start = NULL; \
283 /***********************************
284 * Interpret the statement.
285 * Returns:
286 * NULL continue to next statement
287 * EXP_CANT_INTERPRET cannot interpret statement at compile time
288 * !NULL expression from return statement
291 Expression *Statement::interpret(InterState *istate)
293 #if LOG
294 printf("Statement::interpret()\n");
295 #endif
296 START()
297 return EXP_CANT_INTERPRET;
300 Expression *ExpStatement::interpret(InterState *istate)
302 #if LOG
303 printf("ExpStatement::interpret(%s)\n", exp ? exp->toChars() : "");
304 #endif
305 START()
306 if (exp)
308 Expression *e = exp->interpret(istate);
309 if (e == EXP_CANT_INTERPRET)
311 //printf("-ExpStatement::interpret(): %p\n", e);
312 return EXP_CANT_INTERPRET;
315 return NULL;
318 Expression *CompoundStatement::interpret(InterState *istate)
319 { Expression *e = NULL;
321 #if LOG
322 printf("CompoundStatement::interpret()\n");
323 #endif
324 if (istate->start == this)
325 istate->start = NULL;
326 if (statements)
328 for (size_t i = 0; i < statements->dim; i++)
329 { Statement *s = (Statement *)statements->data[i];
331 if (s)
333 e = s->interpret(istate);
334 if (e)
335 break;
339 #if LOG
340 printf("-CompoundStatement::interpret() %p\n", e);
341 #endif
342 return e;
345 Expression *UnrolledLoopStatement::interpret(InterState *istate)
346 { Expression *e = NULL;
348 #if LOG
349 printf("UnrolledLoopStatement::interpret()\n");
350 #endif
351 if (istate->start == this)
352 istate->start = NULL;
353 if (statements)
355 for (size_t i = 0; i < statements->dim; i++)
356 { Statement *s = (Statement *)statements->data[i];
358 e = s->interpret(istate);
359 if (e == EXP_CANT_INTERPRET)
360 break;
361 if (e == EXP_CONTINUE_INTERPRET)
362 { e = NULL;
363 continue;
365 if (e == EXP_BREAK_INTERPRET)
366 { e = NULL;
367 break;
369 if (e)
370 break;
373 return e;
376 Expression *IfStatement::interpret(InterState *istate)
378 #if LOG
379 printf("IfStatement::interpret(%s)\n", condition->toChars());
380 #endif
382 if (istate->start == this)
383 istate->start = NULL;
384 if (istate->start)
386 Expression *e = NULL;
387 if (ifbody)
388 e = ifbody->interpret(istate);
389 if (istate->start && elsebody)
390 e = elsebody->interpret(istate);
391 return e;
394 Expression *e = condition->interpret(istate);
395 assert(e);
396 //if (e == EXP_CANT_INTERPRET) printf("cannot interpret\n");
397 if (e != EXP_CANT_INTERPRET)
399 if (e->isBool(TRUE))
400 e = ifbody ? ifbody->interpret(istate) : NULL;
401 else if (e->isBool(FALSE))
402 e = elsebody ? elsebody->interpret(istate) : NULL;
403 else
405 e = EXP_CANT_INTERPRET;
408 return e;
411 Expression *ScopeStatement::interpret(InterState *istate)
413 #if LOG
414 printf("ScopeStatement::interpret()\n");
415 #endif
416 if (istate->start == this)
417 istate->start = NULL;
418 return statement ? statement->interpret(istate) : NULL;
421 Expression *ReturnStatement::interpret(InterState *istate)
423 #if LOG
424 printf("ReturnStatement::interpret(%s)\n", exp ? exp->toChars() : "");
425 #endif
426 START()
427 if (!exp)
428 return EXP_VOID_INTERPRET;
429 #if LOG
430 Expression *e = exp->interpret(istate);
431 printf("e = %p\n", e);
432 return e;
433 #else
434 return exp->interpret(istate);
435 #endif
438 Expression *BreakStatement::interpret(InterState *istate)
440 #if LOG
441 printf("BreakStatement::interpret()\n");
442 #endif
443 START()
444 if (ident)
445 return EXP_CANT_INTERPRET;
446 else
447 return EXP_BREAK_INTERPRET;
450 Expression *ContinueStatement::interpret(InterState *istate)
452 #if LOG
453 printf("ContinueStatement::interpret()\n");
454 #endif
455 START()
456 if (ident)
457 return EXP_CANT_INTERPRET;
458 else
459 return EXP_CONTINUE_INTERPRET;
462 Expression *WhileStatement::interpret(InterState *istate)
464 #if LOG
465 printf("WhileStatement::interpret()\n");
466 #endif
467 if (istate->start == this)
468 istate->start = NULL;
469 Expression *e;
471 if (istate->start)
473 e = body ? body->interpret(istate) : NULL;
474 if (istate->start)
475 return NULL;
476 if (e == EXP_CANT_INTERPRET)
477 return e;
478 if (e == EXP_BREAK_INTERPRET)
479 return NULL;
480 if (e != EXP_CONTINUE_INTERPRET)
481 return e;
484 while (1)
486 e = condition->interpret(istate);
487 if (e == EXP_CANT_INTERPRET)
488 break;
489 if (!e->isConst())
490 { e = EXP_CANT_INTERPRET;
491 break;
493 if (e->isBool(TRUE))
494 { e = body ? body->interpret(istate) : NULL;
495 if (e == EXP_CANT_INTERPRET)
496 break;
497 if (e == EXP_CONTINUE_INTERPRET)
498 continue;
499 if (e == EXP_BREAK_INTERPRET)
500 { e = NULL;
501 break;
503 if (e)
504 break;
506 else if (e->isBool(FALSE))
507 { e = NULL;
508 break;
510 else
511 assert(0);
513 return e;
516 Expression *DoStatement::interpret(InterState *istate)
518 #if LOG
519 printf("DoStatement::interpret()\n");
520 #endif
521 if (istate->start == this)
522 istate->start = NULL;
523 Expression *e;
525 if (istate->start)
527 e = body ? body->interpret(istate) : NULL;
528 if (istate->start)
529 return NULL;
530 if (e == EXP_CANT_INTERPRET)
531 return e;
532 if (e == EXP_BREAK_INTERPRET)
533 return NULL;
534 if (e == EXP_CONTINUE_INTERPRET)
535 goto Lcontinue;
536 if (e)
537 return e;
540 while (1)
542 e = body ? body->interpret(istate) : NULL;
543 if (e == EXP_CANT_INTERPRET)
544 break;
545 if (e == EXP_BREAK_INTERPRET)
546 { e = NULL;
547 break;
549 if (e && e != EXP_CONTINUE_INTERPRET)
550 break;
552 Lcontinue:
553 e = condition->interpret(istate);
554 if (e == EXP_CANT_INTERPRET)
555 break;
556 if (!e->isConst())
557 { e = EXP_CANT_INTERPRET;
558 break;
560 if (e->isBool(TRUE))
563 else if (e->isBool(FALSE))
564 { e = NULL;
565 break;
567 else
568 assert(0);
570 return e;
573 Expression *ForStatement::interpret(InterState *istate)
575 #if LOG
576 printf("ForStatement::interpret()\n");
577 #endif
578 if (istate->start == this)
579 istate->start = NULL;
580 Expression *e;
582 if (init)
584 e = init->interpret(istate);
585 if (e == EXP_CANT_INTERPRET)
586 return e;
587 assert(!e);
590 if (istate->start)
592 e = body ? body->interpret(istate) : NULL;
593 if (istate->start)
594 return NULL;
595 if (e == EXP_CANT_INTERPRET)
596 return e;
597 if (e == EXP_BREAK_INTERPRET)
598 return NULL;
599 if (e == EXP_CONTINUE_INTERPRET)
600 goto Lcontinue;
601 if (e)
602 return e;
605 while (1)
607 if (!condition)
608 goto Lhead;
609 e = condition->interpret(istate);
610 if (e == EXP_CANT_INTERPRET)
611 break;
612 if (!e->isConst())
613 { e = EXP_CANT_INTERPRET;
614 break;
616 if (e->isBool(TRUE))
618 Lhead:
619 e = body ? body->interpret(istate) : NULL;
620 if (e == EXP_CANT_INTERPRET)
621 break;
622 if (e == EXP_BREAK_INTERPRET)
623 { e = NULL;
624 break;
626 if (e && e != EXP_CONTINUE_INTERPRET)
627 break;
628 Lcontinue:
629 if (increment)
631 e = increment->interpret(istate);
632 if (e == EXP_CANT_INTERPRET)
633 break;
636 else if (e->isBool(FALSE))
637 { e = NULL;
638 break;
640 else
641 assert(0);
643 return e;
646 Expression *ForeachStatement::interpret(InterState *istate)
648 #if LOG
649 printf("ForeachStatement::interpret()\n");
650 #endif
651 if (istate->start == this)
652 istate->start = NULL;
653 if (istate->start)
654 return NULL;
656 Expression *e = NULL;
657 Expression *eaggr;
659 if (value->isOut() || value->isRef())
660 return EXP_CANT_INTERPRET;
662 eaggr = aggr->interpret(istate);
663 if (eaggr == EXP_CANT_INTERPRET)
664 return EXP_CANT_INTERPRET;
666 Expression *dim = ArrayLength(Type::tsize_t, eaggr);
667 if (dim == EXP_CANT_INTERPRET)
668 return EXP_CANT_INTERPRET;
670 Expression *keysave = key ? key->value : NULL;
671 Expression *valuesave = value->value;
673 uinteger_t d = dim->toUInteger();
674 uinteger_t index;
676 if (op == TOKforeach)
678 for (index = 0; index < d; index++)
680 Expression *ekey = new IntegerExp(loc, index, Type::tsize_t);
681 if (key)
682 key->value = ekey;
683 e = Index(value->type, eaggr, ekey);
684 if (e == EXP_CANT_INTERPRET)
685 break;
686 value->value = e;
688 e = body ? body->interpret(istate) : NULL;
689 if (e == EXP_CANT_INTERPRET)
690 break;
691 if (e == EXP_BREAK_INTERPRET)
692 { e = NULL;
693 break;
695 if (e == EXP_CONTINUE_INTERPRET)
696 e = NULL;
697 else if (e)
698 break;
701 else // TOKforeach_reverse
703 for (index = d; index-- != 0;)
705 Expression *ekey = new IntegerExp(loc, index, Type::tsize_t);
706 if (key)
707 key->value = ekey;
708 e = Index(value->type, eaggr, ekey);
709 if (e == EXP_CANT_INTERPRET)
710 break;
711 value->value = e;
713 e = body ? body->interpret(istate) : NULL;
714 if (e == EXP_CANT_INTERPRET)
715 break;
716 if (e == EXP_BREAK_INTERPRET)
717 { e = NULL;
718 break;
720 if (e == EXP_CONTINUE_INTERPRET)
721 e = NULL;
722 else if (e)
723 break;
726 value->value = valuesave;
727 if (key)
728 key->value = keysave;
729 return e;
732 #if V2
733 Expression *ForeachRangeStatement::interpret(InterState *istate)
735 #if LOG
736 printf("ForeachRangeStatement::interpret()\n");
737 #endif
738 if (istate->start == this)
739 istate->start = NULL;
740 if (istate->start)
741 return NULL;
743 Expression *e = NULL;
744 Expression *elwr = lwr->interpret(istate);
745 if (elwr == EXP_CANT_INTERPRET)
746 return EXP_CANT_INTERPRET;
748 Expression *eupr = upr->interpret(istate);
749 if (eupr == EXP_CANT_INTERPRET)
750 return EXP_CANT_INTERPRET;
752 Expression *keysave = key->value;
754 if (op == TOKforeach)
756 key->value = elwr;
758 while (1)
760 e = Cmp(TOKlt, key->value->type, key->value, upr);
761 if (e == EXP_CANT_INTERPRET)
762 break;
763 if (e->isBool(TRUE) == FALSE)
764 { e = NULL;
765 break;
768 e = body ? body->interpret(istate) : NULL;
769 if (e == EXP_CANT_INTERPRET)
770 break;
771 if (e == EXP_BREAK_INTERPRET)
772 { e = NULL;
773 break;
775 e = Add(key->value->type, key->value, new IntegerExp(loc, 1, key->value->type));
776 if (e == EXP_CANT_INTERPRET)
777 break;
778 key->value = e;
781 else // TOKforeach_reverse
783 key->value = eupr;
785 while (1)
787 e = Cmp(TOKgt, key->value->type, key->value, lwr);
788 if (e == EXP_CANT_INTERPRET)
789 break;
790 if (e->isBool(TRUE) == FALSE)
791 { e = NULL;
792 break;
795 e = Min(key->value->type, key->value, new IntegerExp(loc, 1, key->value->type));
796 if (e == EXP_CANT_INTERPRET)
797 break;
798 key->value = e;
800 e = body ? body->interpret(istate) : NULL;
801 if (e == EXP_CANT_INTERPRET)
802 break;
803 if (e == EXP_BREAK_INTERPRET)
804 { e = NULL;
805 break;
809 key->value = keysave;
810 return e;
812 #endif
814 Expression *SwitchStatement::interpret(InterState *istate)
816 #if LOG
817 printf("SwitchStatement::interpret()\n");
818 #endif
819 if (istate->start == this)
820 istate->start = NULL;
821 Expression *e = NULL;
823 if (istate->start)
825 e = body ? body->interpret(istate) : NULL;
826 if (istate->start)
827 return NULL;
828 if (e == EXP_CANT_INTERPRET)
829 return e;
830 if (e == EXP_BREAK_INTERPRET)
831 return NULL;
832 return e;
836 Expression *econdition = condition->interpret(istate);
837 if (econdition == EXP_CANT_INTERPRET)
838 return EXP_CANT_INTERPRET;
840 Statement *s = NULL;
841 if (cases)
843 for (size_t i = 0; i < cases->dim; i++)
845 CaseStatement *cs = (CaseStatement *)cases->data[i];
846 e = Equal(TOKequal, Type::tint32, econdition, cs->exp);
847 if (e == EXP_CANT_INTERPRET)
848 return EXP_CANT_INTERPRET;
849 if (e->isBool(TRUE))
850 { s = cs;
851 break;
855 if (!s)
856 { if (hasNoDefault)
857 error("no default or case for %s in switch statement", econdition->toChars());
858 s = sdefault;
861 assert(s);
862 istate->start = s;
863 e = body ? body->interpret(istate) : NULL;
864 assert(!istate->start);
865 if (e == EXP_BREAK_INTERPRET)
866 return NULL;
867 return e;
870 Expression *CaseStatement::interpret(InterState *istate)
872 #if LOG
873 printf("CaseStatement::interpret(%s) this = %p\n", exp->toChars(), this);
874 #endif
875 if (istate->start == this)
876 istate->start = NULL;
877 if (statement)
878 return statement->interpret(istate);
879 else
880 return NULL;
883 Expression *DefaultStatement::interpret(InterState *istate)
885 #if LOG
886 printf("DefaultStatement::interpret()\n");
887 #endif
888 if (istate->start == this)
889 istate->start = NULL;
890 if (statement)
891 return statement->interpret(istate);
892 else
893 return NULL;
896 Expression *GotoStatement::interpret(InterState *istate)
898 #if LOG
899 printf("GotoStatement::interpret()\n");
900 #endif
901 START()
902 assert(label && label->statement);
903 istate->gotoTarget = label->statement;
904 return EXP_GOTO_INTERPRET;
907 Expression *GotoCaseStatement::interpret(InterState *istate)
909 #if LOG
910 printf("GotoCaseStatement::interpret()\n");
911 #endif
912 START()
913 assert(cs);
914 istate->gotoTarget = cs;
915 return EXP_GOTO_INTERPRET;
918 Expression *GotoDefaultStatement::interpret(InterState *istate)
920 #if LOG
921 printf("GotoDefaultStatement::interpret()\n");
922 #endif
923 START()
924 assert(sw && sw->sdefault);
925 istate->gotoTarget = sw->sdefault;
926 return EXP_GOTO_INTERPRET;
929 Expression *LabelStatement::interpret(InterState *istate)
931 #if LOG
932 printf("LabelStatement::interpret()\n");
933 #endif
934 if (istate->start == this)
935 istate->start = NULL;
936 return statement ? statement->interpret(istate) : NULL;
939 /******************************** Expression ***************************/
941 Expression *Expression::interpret(InterState *istate)
943 #if LOG
944 printf("Expression::interpret() %s\n", toChars());
945 printf("type = %s\n", type->toChars());
946 dump(0);
947 #endif
948 return EXP_CANT_INTERPRET;
951 Expression *NullExp::interpret(InterState *istate)
953 return this;
956 Expression *IntegerExp::interpret(InterState *istate)
958 #if LOG
959 printf("IntegerExp::interpret() %s\n", toChars());
960 #endif
961 return this;
964 Expression *RealExp::interpret(InterState *istate)
966 #if LOG
967 printf("RealExp::interpret() %s\n", toChars());
968 #endif
969 return this;
972 Expression *ComplexExp::interpret(InterState *istate)
974 return this;
977 Expression *StringExp::interpret(InterState *istate)
979 #if LOG
980 printf("StringExp::interpret() %s\n", toChars());
981 #endif
982 return this;
985 Expression *getVarExp(Loc loc, InterState *istate, Declaration *d)
987 Expression *e = EXP_CANT_INTERPRET;
988 VarDeclaration *v = d->isVarDeclaration();
989 SymbolDeclaration *s = d->isSymbolDeclaration();
990 if (v)
992 #if V2
993 if ((v->isConst() || v->isInvariant()) && v->init && !v->value)
994 #else
995 if (v->isConst() && v->init)
996 #endif
997 { e = v->init->toExpression();
998 if (e && !e->type)
999 e->type = v->type;
1001 else
1002 { e = v->value;
1003 if (!e)
1004 error(loc, "variable %s is used before initialization", v->toChars());
1005 else if (e != EXP_CANT_INTERPRET)
1006 e = e->interpret(istate);
1008 if (!e)
1009 e = EXP_CANT_INTERPRET;
1011 else if (s)
1013 if (s->dsym->toInitializer() == s->sym)
1014 { Expressions *exps = new Expressions();
1015 e = new StructLiteralExp(0, s->dsym, exps);
1016 e = e->semantic(NULL);
1019 return e;
1022 Expression *VarExp::interpret(InterState *istate)
1024 #if LOG
1025 printf("VarExp::interpret() %s\n", toChars());
1026 #endif
1027 return getVarExp(loc, istate, var);
1030 Expression *DeclarationExp::interpret(InterState *istate)
1032 #if LOG
1033 printf("DeclarationExp::interpret() %s\n", toChars());
1034 #endif
1035 Expression *e;
1036 VarDeclaration *v = declaration->isVarDeclaration();
1037 if (v)
1039 Dsymbol *s = v->toAlias();
1040 if (s == v && !v->isStatic() && v->init)
1042 ExpInitializer *ie = v->init->isExpInitializer();
1043 if (ie)
1044 e = ie->exp->interpret(istate);
1045 else if (v->init->isVoidInitializer())
1046 e = NULL;
1048 #if V2
1049 else if (s == v && (v->isConst() || v->isInvariant()) && v->init)
1050 #else
1051 else if (s == v && v->isConst() && v->init)
1052 #endif
1053 { e = v->init->toExpression();
1054 if (!e)
1055 e = EXP_CANT_INTERPRET;
1056 else if (!e->type)
1057 e->type = v->type;
1060 else if (declaration->isAttribDeclaration() ||
1061 declaration->isTemplateMixin() ||
1062 declaration->isTupleDeclaration())
1063 { // These can be made to work, too lazy now
1064 e = EXP_CANT_INTERPRET;
1066 else
1067 { // Others should not contain executable code, so are trivial to evaluate
1068 e = NULL;
1070 #if LOG
1071 printf("-DeclarationExp::interpret(): %p\n", e);
1072 #endif
1073 return e;
1076 Expression *TupleExp::interpret(InterState *istate)
1078 #if LOG
1079 printf("TupleExp::interpret() %s\n", toChars());
1080 #endif
1081 Expressions *expsx = NULL;
1083 for (size_t i = 0; i < exps->dim; i++)
1084 { Expression *e = (Expression *)exps->data[i];
1085 Expression *ex;
1087 ex = e->interpret(istate);
1088 if (ex == EXP_CANT_INTERPRET)
1089 { delete expsx;
1090 return ex;
1093 /* If any changes, do Copy On Write
1095 if (ex != e)
1097 if (!expsx)
1098 { expsx = new Expressions();
1099 expsx->setDim(exps->dim);
1100 for (size_t j = 0; j < i; j++)
1102 expsx->data[j] = exps->data[j];
1105 expsx->data[i] = (void *)ex;
1108 if (expsx)
1109 { TupleExp *te = new TupleExp(loc, expsx);
1110 expandTuples(te->exps);
1111 te->type = new TypeTuple(te->exps);
1112 return te;
1114 return this;
1117 Expression *ArrayLiteralExp::interpret(InterState *istate)
1118 { Expressions *expsx = NULL;
1120 #if LOG
1121 printf("ArrayLiteralExp::interpret() %s\n", toChars());
1122 #endif
1123 if (elements)
1125 for (size_t i = 0; i < elements->dim; i++)
1126 { Expression *e = (Expression *)elements->data[i];
1127 Expression *ex;
1129 ex = e->interpret(istate);
1130 if (ex == EXP_CANT_INTERPRET)
1131 { delete expsx;
1132 return EXP_CANT_INTERPRET;
1135 /* If any changes, do Copy On Write
1137 if (ex != e)
1139 if (!expsx)
1140 { expsx = new Expressions();
1141 expsx->setDim(elements->dim);
1142 for (size_t j = 0; j < elements->dim; j++)
1144 expsx->data[j] = elements->data[j];
1147 expsx->data[i] = (void *)ex;
1151 if (elements && expsx)
1153 expandTuples(expsx);
1154 if (expsx->dim != elements->dim)
1155 { delete expsx;
1156 return EXP_CANT_INTERPRET;
1158 ArrayLiteralExp *ae = new ArrayLiteralExp(loc, expsx);
1159 ae->type = type;
1160 return ae;
1162 return this;
1165 Expression *AssocArrayLiteralExp::interpret(InterState *istate)
1166 { Expressions *keysx = keys;
1167 Expressions *valuesx = values;
1169 #if LOG
1170 printf("AssocArrayLiteralExp::interpret() %s\n", toChars());
1171 #endif
1172 for (size_t i = 0; i < keys->dim; i++)
1173 { Expression *ekey = (Expression *)keys->data[i];
1174 Expression *evalue = (Expression *)values->data[i];
1175 Expression *ex;
1177 ex = ekey->interpret(istate);
1178 if (ex == EXP_CANT_INTERPRET)
1179 goto Lerr;
1181 /* If any changes, do Copy On Write
1183 if (ex != ekey)
1185 if (keysx == keys)
1186 keysx = (Expressions *)keys->copy();
1187 keysx->data[i] = (void *)ex;
1190 ex = evalue->interpret(istate);
1191 if (ex == EXP_CANT_INTERPRET)
1192 goto Lerr;
1194 /* If any changes, do Copy On Write
1196 if (ex != evalue)
1198 if (valuesx == values)
1199 valuesx = (Expressions *)values->copy();
1200 valuesx->data[i] = (void *)ex;
1203 if (keysx != keys)
1204 expandTuples(keysx);
1205 if (valuesx != values)
1206 expandTuples(valuesx);
1207 if (keysx->dim != valuesx->dim)
1208 goto Lerr;
1210 /* Remove duplicate keys
1212 for (size_t i = 1; i < keysx->dim; i++)
1213 { Expression *ekey = (Expression *)keysx->data[i - 1];
1215 for (size_t j = i; j < keysx->dim; j++)
1216 { Expression *ekey2 = (Expression *)keysx->data[j];
1217 Expression *ex = Equal(TOKequal, Type::tbool, ekey, ekey2);
1218 if (ex == EXP_CANT_INTERPRET)
1219 goto Lerr;
1220 if (ex->isBool(TRUE)) // if a match
1222 // Remove ekey
1223 if (keysx == keys)
1224 keysx = (Expressions *)keys->copy();
1225 if (valuesx == values)
1226 valuesx = (Expressions *)values->copy();
1227 keysx->remove(i - 1);
1228 valuesx->remove(i - 1);
1229 i -= 1; // redo the i'th iteration
1230 break;
1235 if (keysx != keys || valuesx != values)
1237 AssocArrayLiteralExp *ae;
1238 ae = new AssocArrayLiteralExp(loc, keysx, valuesx);
1239 ae->type = type;
1240 return ae;
1242 return this;
1244 Lerr:
1245 if (keysx != keys)
1246 delete keysx;
1247 if (valuesx != values)
1248 delete values;
1249 return EXP_CANT_INTERPRET;
1252 Expression *StructLiteralExp::interpret(InterState *istate)
1253 { Expressions *expsx = NULL;
1255 #if LOG
1256 printf("StructLiteralExp::interpret() %s\n", toChars());
1257 #endif
1258 /* We don't know how to deal with overlapping fields
1260 if (sd->hasUnions)
1261 return EXP_CANT_INTERPRET;
1263 if (elements)
1265 for (size_t i = 0; i < elements->dim; i++)
1266 { Expression *e = (Expression *)elements->data[i];
1267 if (!e)
1268 continue;
1270 Expression *ex = e->interpret(istate);
1271 if (ex == EXP_CANT_INTERPRET)
1272 { delete expsx;
1273 return EXP_CANT_INTERPRET;
1276 /* If any changes, do Copy On Write
1278 if (ex != e)
1280 if (!expsx)
1281 { expsx = new Expressions();
1282 expsx->setDim(elements->dim);
1283 for (size_t j = 0; j < elements->dim; j++)
1285 expsx->data[j] = elements->data[j];
1288 expsx->data[i] = (void *)ex;
1292 if (elements && expsx)
1294 expandTuples(expsx);
1295 if (expsx->dim != elements->dim)
1296 { delete expsx;
1297 return EXP_CANT_INTERPRET;
1299 StructLiteralExp *se = new StructLiteralExp(loc, sd, expsx);
1300 se->type = type;
1301 return se;
1303 return this;
1306 Expression *UnaExp::interpretCommon(InterState *istate, Expression *(*fp)(Type *, Expression *))
1307 { Expression *e;
1308 Expression *e1;
1310 #if LOG
1311 printf("UnaExp::interpretCommon() %s\n", toChars());
1312 #endif
1313 e1 = this->e1->interpret(istate);
1314 if (e1 == EXP_CANT_INTERPRET)
1315 goto Lcant;
1316 if (e1->isConst() != 1)
1317 goto Lcant;
1319 e = (*fp)(type, e1);
1320 return e;
1322 Lcant:
1323 return EXP_CANT_INTERPRET;
1326 #define UNA_INTERPRET(op) \
1327 Expression *op##Exp::interpret(InterState *istate) \
1329 return interpretCommon(istate, &op); \
1332 UNA_INTERPRET(Neg)
1333 UNA_INTERPRET(Com)
1334 UNA_INTERPRET(Not)
1335 UNA_INTERPRET(Bool)
1338 typedef Expression *(*fp_t)(Type *, Expression *, Expression *);
1340 Expression *BinExp::interpretCommon(InterState *istate, fp_t fp)
1341 { Expression *e;
1342 Expression *e1;
1343 Expression *e2;
1345 #if LOG
1346 printf("BinExp::interpretCommon() %s\n", toChars());
1347 #endif
1348 e1 = this->e1->interpret(istate);
1349 if (e1 == EXP_CANT_INTERPRET)
1350 goto Lcant;
1351 if (e1->isConst() != 1)
1352 goto Lcant;
1354 e2 = this->e2->interpret(istate);
1355 if (e2 == EXP_CANT_INTERPRET)
1356 goto Lcant;
1357 if (e2->isConst() != 1)
1358 goto Lcant;
1360 e = (*fp)(type, e1, e2);
1361 return e;
1363 Lcant:
1364 return EXP_CANT_INTERPRET;
1367 #define BIN_INTERPRET(op) \
1368 Expression *op##Exp::interpret(InterState *istate) \
1370 return interpretCommon(istate, &op); \
1373 BIN_INTERPRET(Add)
1374 BIN_INTERPRET(Min)
1375 BIN_INTERPRET(Mul)
1376 BIN_INTERPRET(Div)
1377 BIN_INTERPRET(Mod)
1378 BIN_INTERPRET(Shl)
1379 BIN_INTERPRET(Shr)
1380 BIN_INTERPRET(Ushr)
1381 BIN_INTERPRET(And)
1382 BIN_INTERPRET(Or)
1383 BIN_INTERPRET(Xor)
1386 typedef Expression *(*fp2_t)(enum TOK, Type *, Expression *, Expression *);
1388 Expression *BinExp::interpretCommon2(InterState *istate, fp2_t fp)
1389 { Expression *e;
1390 Expression *e1;
1391 Expression *e2;
1393 #if LOG
1394 printf("BinExp::interpretCommon2() %s\n", toChars());
1395 #endif
1396 e1 = this->e1->interpret(istate);
1397 if (e1 == EXP_CANT_INTERPRET)
1398 goto Lcant;
1399 if (e1->isConst() != 1 &&
1400 e1->op != TOKnull &&
1401 e1->op != TOKstring &&
1402 e1->op != TOKarrayliteral &&
1403 e1->op != TOKstructliteral)
1404 goto Lcant;
1406 e2 = this->e2->interpret(istate);
1407 if (e2 == EXP_CANT_INTERPRET)
1408 goto Lcant;
1409 if (e2->isConst() != 1 &&
1410 e2->op != TOKnull &&
1411 e2->op != TOKstring &&
1412 e2->op != TOKarrayliteral &&
1413 e2->op != TOKstructliteral)
1414 goto Lcant;
1416 e = (*fp)(op, type, e1, e2);
1417 return e;
1419 Lcant:
1420 return EXP_CANT_INTERPRET;
1423 #define BIN_INTERPRET2(op) \
1424 Expression *op##Exp::interpret(InterState *istate) \
1426 return interpretCommon2(istate, &op); \
1429 BIN_INTERPRET2(Equal)
1430 BIN_INTERPRET2(Identity)
1431 BIN_INTERPRET2(Cmp)
1433 Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
1435 #if LOG
1436 printf("BinExp::interpretAssignCommon() %s\n", toChars());
1437 #endif
1438 Expression *e = EXP_CANT_INTERPRET;
1439 Expression *e1 = this->e1;
1441 if (fp)
1443 if (e1->op == TOKcast)
1444 { CastExp *ce = (CastExp *)e1;
1445 e1 = ce->e1;
1448 if (e1 == EXP_CANT_INTERPRET)
1449 return e1;
1450 Expression *e2 = this->e2->interpret(istate);
1451 if (e2 == EXP_CANT_INTERPRET)
1452 return e2;
1454 /* Assignment to variable of the form:
1455 * v = e2
1457 if (e1->op == TOKvar)
1459 VarExp *ve = (VarExp *)e1;
1460 VarDeclaration *v = ve->var->isVarDeclaration();
1461 if (v && !v->isDataseg())
1463 /* Chase down rebinding of out and ref
1465 if (v->value && v->value->op == TOKvar)
1467 VarExp *ve2 = (VarExp *)v->value;
1468 if (ve2->var->isSymbolDeclaration())
1470 /* This can happen if v is a struct initialized to
1471 * 0 using an __initZ SymbolDeclaration from
1472 * TypeStruct::defaultInit()
1475 else
1476 v = ve2->var->isVarDeclaration();
1477 assert(v);
1480 Expression *ev = v->value;
1481 if (fp && !ev)
1482 { error("variable %s is used before initialization", v->toChars());
1483 return e;
1485 if (fp)
1486 e2 = (*fp)(v->type, ev, e2);
1487 else
1488 { /* Look for special case of struct being initialized with 0.
1490 if (v->type->toBasetype()->ty == Tstruct && e2->op == TOKint64)
1492 e2 = v->type->defaultInit();
1494 e2 = Cast(v->type, v->type, e2);
1496 if (e2 != EXP_CANT_INTERPRET)
1498 if (!v->isParameter())
1500 for (size_t i = 0; 1; i++)
1502 if (i == istate->vars.dim)
1503 { istate->vars.push(v);
1504 //printf("\tadding %s to istate\n", v->toChars());
1505 break;
1507 if (v == (VarDeclaration *)istate->vars.data[i])
1508 break;
1511 v->value = e2;
1512 e = Cast(type, type, post ? ev : e2);
1516 /* Assignment to struct member of the form:
1517 * *(symoffexp) = e2
1519 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff)
1520 { SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1;
1521 VarDeclaration *v = soe->var->isVarDeclaration();
1523 if (v->isDataseg())
1524 return EXP_CANT_INTERPRET;
1525 if (fp && !v->value)
1526 { error("variable %s is used before initialization", v->toChars());
1527 return e;
1529 Expression *vie = v->value;
1530 if (vie->op == TOKvar)
1532 Declaration *d = ((VarExp *)vie)->var;
1533 vie = getVarExp(e1->loc, istate, d);
1535 if (vie->op != TOKstructliteral)
1536 return EXP_CANT_INTERPRET;
1537 StructLiteralExp *se = (StructLiteralExp *)vie;
1538 int fieldi = se->getFieldIndex(type, soe->offset);
1539 if (fieldi == -1)
1540 return EXP_CANT_INTERPRET;
1541 Expression *ev = se->getField(type, soe->offset);
1542 if (fp)
1543 e2 = (*fp)(type, ev, e2);
1544 else
1545 e2 = Cast(type, type, e2);
1546 if (e2 == EXP_CANT_INTERPRET)
1547 return e2;
1549 if (!v->isParameter())
1551 for (size_t i = 0; 1; i++)
1553 if (i == istate->vars.dim)
1554 { istate->vars.push(v);
1555 break;
1557 if (v == (VarDeclaration *)istate->vars.data[i])
1558 break;
1562 /* Create new struct literal reflecting updated fieldi
1564 Expressions *expsx = new Expressions();
1565 expsx->setDim(se->elements->dim);
1566 for (size_t j = 0; j < expsx->dim; j++)
1568 if (j == fieldi)
1569 expsx->data[j] = (void *)e2;
1570 else
1571 expsx->data[j] = se->elements->data[j];
1573 v->value = new StructLiteralExp(se->loc, se->sd, expsx);
1574 v->value->type = se->type;
1576 e = Cast(type, type, post ? ev : e2);
1578 /* Assignment to array element of the form:
1579 * a[i] = e2
1581 else if (e1->op == TOKindex && ((IndexExp *)e1)->e1->op == TOKvar)
1582 { IndexExp *ie = (IndexExp *)e1;
1583 VarExp *ve = (VarExp *)ie->e1;
1584 VarDeclaration *v = ve->var->isVarDeclaration();
1586 if (!v || v->isDataseg())
1587 return EXP_CANT_INTERPRET;
1588 if (!v->value)
1590 if (fp)
1591 { error("variable %s is used before initialization", v->toChars());
1592 return e;
1595 Type *t = v->type->toBasetype();
1596 if (t->ty == Tsarray)
1598 /* This array was void initialized. Create a
1599 * default initializer for it.
1600 * What we should do is fill the array literal with
1601 * NULL data, so use-before-initialized can be detected.
1602 * But we're too lazy at the moment to do it, as that
1603 * involves redoing Index() and whoever calls it.
1605 Expression *ev = v->type->defaultInit();
1606 size_t dim = ((TypeSArray *)t)->dim->toInteger();
1607 Expressions *elements = new Expressions();
1608 elements->setDim(dim);
1609 for (size_t i = 0; i < dim; i++)
1610 elements->data[i] = (void *)ev;
1611 ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements);
1612 ae->type = v->type;
1613 v->value = ae;
1615 else
1616 return EXP_CANT_INTERPRET;
1619 ArrayLiteralExp *ae = NULL;
1620 AssocArrayLiteralExp *aae = NULL;
1621 StringExp *se = NULL;
1622 if (v->value->op == TOKarrayliteral)
1623 ae = (ArrayLiteralExp *)v->value;
1624 else if (v->value->op == TOKassocarrayliteral)
1625 aae = (AssocArrayLiteralExp *)v->value;
1626 else if (v->value->op == TOKstring)
1627 se = (StringExp *)v->value;
1628 else
1629 return EXP_CANT_INTERPRET;
1631 Expression *index = ie->e2->interpret(istate);
1632 if (index == EXP_CANT_INTERPRET)
1633 return EXP_CANT_INTERPRET;
1634 Expression *ev;
1635 if (fp || ae || se) // not for aae, because key might not be there
1637 ev = Index(type, v->value, index);
1638 if (ev == EXP_CANT_INTERPRET)
1639 return EXP_CANT_INTERPRET;
1642 if (fp)
1643 e2 = (*fp)(type, ev, e2);
1644 else
1645 e2 = Cast(type, type, e2);
1646 if (e2 == EXP_CANT_INTERPRET)
1647 return e2;
1649 if (!v->isParameter())
1651 for (size_t i = 0; 1; i++)
1653 if (i == istate->vars.dim)
1654 { istate->vars.push(v);
1655 break;
1657 if (v == (VarDeclaration *)istate->vars.data[i])
1658 break;
1662 if (ae)
1664 /* Create new array literal reflecting updated elem
1666 int elemi = index->toInteger();
1667 Expressions *expsx = new Expressions();
1668 expsx->setDim(ae->elements->dim);
1669 for (size_t j = 0; j < expsx->dim; j++)
1671 if (j == elemi)
1672 expsx->data[j] = (void *)e2;
1673 else
1674 expsx->data[j] = ae->elements->data[j];
1676 v->value = new ArrayLiteralExp(ae->loc, expsx);
1677 v->value->type = ae->type;
1679 else if (aae)
1681 /* Create new associative array literal reflecting updated key/value
1683 Expressions *keysx = aae->keys;
1684 Expressions *valuesx = new Expressions();
1685 valuesx->setDim(aae->values->dim);
1686 int updated = 0;
1687 for (size_t j = valuesx->dim; j; )
1688 { j--;
1689 Expression *ekey = (Expression *)aae->keys->data[j];
1690 Expression *ex = Equal(TOKequal, Type::tbool, ekey, index);
1691 if (ex == EXP_CANT_INTERPRET)
1692 return EXP_CANT_INTERPRET;
1693 if (ex->isBool(TRUE))
1694 { valuesx->data[j] = (void *)e2;
1695 updated = 1;
1697 else
1698 valuesx->data[j] = aae->values->data[j];
1700 if (!updated)
1701 { // Append index/e2 to keysx[]/valuesx[]
1702 valuesx->push(e2);
1703 keysx = (Expressions *)keysx->copy();
1704 keysx->push(index);
1706 v->value = new AssocArrayLiteralExp(aae->loc, keysx, valuesx);
1707 v->value->type = aae->type;
1709 else if (se)
1711 /* Create new string literal reflecting updated elem
1713 int elemi = index->toInteger();
1714 unsigned char *s;
1715 s = (unsigned char *)mem.calloc(se->len + 1, se->sz);
1716 memcpy(s, se->string, se->len * se->sz);
1717 unsigned value = e2->toInteger();
1718 switch (se->sz)
1720 case 1: s[elemi] = value; break;
1721 case 2: ((unsigned short *)s)[elemi] = value; break;
1722 case 4: ((unsigned *)s)[elemi] = value; break;
1723 default:
1724 assert(0);
1725 break;
1727 StringExp *se2 = new StringExp(se->loc, s, se->len);
1728 se2->committed = se->committed;
1729 se2->postfix = se->postfix;
1730 se2->type = se->type;
1731 v->value = se2;
1733 else
1734 assert(0);
1736 e = Cast(type, type, post ? ev : e2);
1738 else
1740 #ifdef DEBUG
1741 dump(0);
1742 #endif
1744 return e;
1747 Expression *AssignExp::interpret(InterState *istate)
1749 return interpretAssignCommon(istate, NULL);
1752 #define BIN_ASSIGN_INTERPRET(op) \
1753 Expression *op##AssignExp::interpret(InterState *istate) \
1755 return interpretAssignCommon(istate, &op); \
1758 BIN_ASSIGN_INTERPRET(Add)
1759 BIN_ASSIGN_INTERPRET(Min)
1760 BIN_ASSIGN_INTERPRET(Cat)
1761 BIN_ASSIGN_INTERPRET(Mul)
1762 BIN_ASSIGN_INTERPRET(Div)
1763 BIN_ASSIGN_INTERPRET(Mod)
1764 BIN_ASSIGN_INTERPRET(Shl)
1765 BIN_ASSIGN_INTERPRET(Shr)
1766 BIN_ASSIGN_INTERPRET(Ushr)
1767 BIN_ASSIGN_INTERPRET(And)
1768 BIN_ASSIGN_INTERPRET(Or)
1769 BIN_ASSIGN_INTERPRET(Xor)
1771 Expression *PostExp::interpret(InterState *istate)
1773 #if LOG
1774 printf("PostExp::interpret() %s\n", toChars());
1775 #endif
1776 Expression *e;
1777 if (op == TOKplusplus)
1778 e = interpretAssignCommon(istate, &Add, 1);
1779 else
1780 e = interpretAssignCommon(istate, &Min, 1);
1781 #if LOG
1782 if (e == EXP_CANT_INTERPRET)
1783 printf("PostExp::interpret() CANT\n");
1784 #endif
1785 return e;
1788 Expression *AndAndExp::interpret(InterState *istate)
1790 #if LOG
1791 printf("AndAndExp::interpret() %s\n", toChars());
1792 #endif
1793 Expression *e = e1->interpret(istate);
1794 if (e != EXP_CANT_INTERPRET)
1796 if (e->isBool(FALSE))
1797 e = new IntegerExp(e1->loc, 0, type);
1798 else if (e->isBool(TRUE))
1800 e = e2->interpret(istate);
1801 if (e != EXP_CANT_INTERPRET)
1803 if (e->isBool(FALSE))
1804 e = new IntegerExp(e1->loc, 0, type);
1805 else if (e->isBool(TRUE))
1806 e = new IntegerExp(e1->loc, 1, type);
1807 else
1808 e = EXP_CANT_INTERPRET;
1811 else
1812 e = EXP_CANT_INTERPRET;
1814 return e;
1817 Expression *OrOrExp::interpret(InterState *istate)
1819 #if LOG
1820 printf("OrOrExp::interpret() %s\n", toChars());
1821 #endif
1822 Expression *e = e1->interpret(istate);
1823 if (e != EXP_CANT_INTERPRET)
1825 if (e->isBool(TRUE))
1826 e = new IntegerExp(e1->loc, 1, type);
1827 else if (e->isBool(FALSE))
1829 e = e2->interpret(istate);
1830 if (e != EXP_CANT_INTERPRET)
1832 if (e->isBool(FALSE))
1833 e = new IntegerExp(e1->loc, 0, type);
1834 else if (e->isBool(TRUE))
1835 e = new IntegerExp(e1->loc, 1, type);
1836 else
1837 e = EXP_CANT_INTERPRET;
1840 else
1841 e = EXP_CANT_INTERPRET;
1843 return e;
1847 Expression *CallExp::interpret(InterState *istate)
1848 { Expression *e = EXP_CANT_INTERPRET;
1850 #if LOG
1851 printf("CallExp::interpret() %s\n", toChars());
1852 #endif
1853 if (e1->op == TOKvar)
1855 FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration();
1856 if (fd)
1858 #if V2
1859 enum BUILTIN b = fd->isBuiltin();
1860 if (b)
1861 { Expressions args;
1862 args.setDim(arguments->dim);
1863 for (size_t i = 0; i < args.dim; i++)
1865 Expression *earg = (Expression *)arguments->data[i];
1866 earg = earg->interpret(istate);
1867 if (earg == EXP_CANT_INTERPRET)
1868 return earg;
1869 args.data[i] = (void *)earg;
1871 e = eval_builtin(b, &args);
1872 if (!e)
1873 e = EXP_CANT_INTERPRET;
1875 else
1876 #endif
1877 // Inline .dup
1878 if (fd->ident == Id::adDup && arguments && arguments->dim == 2)
1880 e = (Expression *)arguments->data[1];
1881 e = e->interpret(istate);
1882 if (e != EXP_CANT_INTERPRET)
1884 e = expType(type, e);
1887 else
1889 Expression *eresult = fd->interpret(istate, arguments);
1890 if (eresult)
1891 e = eresult;
1892 else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors)
1893 e = EXP_VOID_INTERPRET;
1894 else
1895 error("cannot evaluate %s at compile time", toChars());
1899 return e;
1902 Expression *CommaExp::interpret(InterState *istate)
1904 #if LOG
1905 printf("CommaExp::interpret() %s\n", toChars());
1906 #endif
1907 Expression *e = e1->interpret(istate);
1908 if (e != EXP_CANT_INTERPRET)
1909 e = e2->interpret(istate);
1910 return e;
1913 Expression *CondExp::interpret(InterState *istate)
1915 #if LOG
1916 printf("CondExp::interpret() %s\n", toChars());
1917 #endif
1918 Expression *e = econd->interpret(istate);
1919 if (e != EXP_CANT_INTERPRET)
1921 if (e->isBool(TRUE))
1922 e = e1->interpret(istate);
1923 else if (e->isBool(FALSE))
1924 e = e2->interpret(istate);
1925 else
1926 e = EXP_CANT_INTERPRET;
1928 return e;
1931 Expression *ArrayLengthExp::interpret(InterState *istate)
1932 { Expression *e;
1933 Expression *e1;
1935 #if LOG
1936 printf("ArrayLengthExp::interpret() %s\n", toChars());
1937 #endif
1938 e1 = this->e1->interpret(istate);
1939 if (e1 == EXP_CANT_INTERPRET)
1940 goto Lcant;
1941 if (e1->op == TOKstring || e1->op == TOKarrayliteral || e1->op == TOKassocarrayliteral)
1943 e = ArrayLength(type, e1);
1945 else if (e1->op == TOKnull)
1947 e = new IntegerExp(loc, 0, type);
1949 else
1950 goto Lcant;
1951 return e;
1953 Lcant:
1954 return EXP_CANT_INTERPRET;
1957 Expression *IndexExp::interpret(InterState *istate)
1958 { Expression *e;
1959 Expression *e1;
1960 Expression *e2;
1962 #if LOG
1963 printf("IndexExp::interpret() %s\n", toChars());
1964 #endif
1965 e1 = this->e1->interpret(istate);
1966 if (e1 == EXP_CANT_INTERPRET)
1967 goto Lcant;
1969 if (e1->op == TOKstring || e1->op == TOKarrayliteral)
1971 /* Set the $ variable
1973 e = ArrayLength(Type::tsize_t, e1);
1974 if (e == EXP_CANT_INTERPRET)
1975 goto Lcant;
1976 if (lengthVar)
1977 lengthVar->value = e;
1980 e2 = this->e2->interpret(istate);
1981 if (e2 == EXP_CANT_INTERPRET)
1982 goto Lcant;
1983 return Index(type, e1, e2);
1985 Lcant:
1986 return EXP_CANT_INTERPRET;
1990 Expression *SliceExp::interpret(InterState *istate)
1991 { Expression *e;
1992 Expression *e1;
1993 Expression *lwr;
1994 Expression *upr;
1996 #if LOG
1997 printf("SliceExp::interpret() %s\n", toChars());
1998 #endif
1999 e1 = this->e1->interpret(istate);
2000 if (e1 == EXP_CANT_INTERPRET)
2001 goto Lcant;
2002 if (!this->lwr)
2004 e = e1->castTo(NULL, type);
2005 return e->interpret(istate);
2008 /* Set the $ variable
2010 e = ArrayLength(Type::tsize_t, e1);
2011 if (e == EXP_CANT_INTERPRET)
2012 goto Lcant;
2013 if (lengthVar)
2014 lengthVar->value = e;
2016 /* Evaluate lower and upper bounds of slice
2018 lwr = this->lwr->interpret(istate);
2019 if (lwr == EXP_CANT_INTERPRET)
2020 goto Lcant;
2021 upr = this->upr->interpret(istate);
2022 if (upr == EXP_CANT_INTERPRET)
2023 goto Lcant;
2025 return Slice(type, e1, lwr, upr);
2027 Lcant:
2028 return EXP_CANT_INTERPRET;
2032 Expression *CatExp::interpret(InterState *istate)
2033 { Expression *e;
2034 Expression *e1;
2035 Expression *e2;
2037 #if LOG
2038 printf("CatExp::interpret() %s\n", toChars());
2039 #endif
2040 e1 = this->e1->interpret(istate);
2041 if (e1 == EXP_CANT_INTERPRET)
2043 goto Lcant;
2045 e2 = this->e2->interpret(istate);
2046 if (e2 == EXP_CANT_INTERPRET)
2047 goto Lcant;
2048 return Cat(type, e1, e2);
2050 Lcant:
2051 #if LOG
2052 printf("CatExp::interpret() %s CANT\n", toChars());
2053 #endif
2054 return EXP_CANT_INTERPRET;
2058 Expression *CastExp::interpret(InterState *istate)
2059 { Expression *e;
2060 Expression *e1;
2062 #if LOG
2063 printf("CastExp::interpret() %s\n", toChars());
2064 #endif
2065 e1 = this->e1->interpret(istate);
2066 if (e1 == EXP_CANT_INTERPRET)
2067 goto Lcant;
2068 return Cast(type, to, e1);
2070 Lcant:
2071 #if LOG
2072 printf("CastExp::interpret() %s CANT\n", toChars());
2073 #endif
2074 return EXP_CANT_INTERPRET;
2078 Expression *AssertExp::interpret(InterState *istate)
2079 { Expression *e;
2080 Expression *e1;
2082 #if LOG
2083 printf("AssertExp::interpret() %s\n", toChars());
2084 #endif
2085 e1 = this->e1->interpret(istate);
2086 if (e1 == EXP_CANT_INTERPRET)
2087 goto Lcant;
2088 if (e1->isBool(TRUE))
2091 else if (e1->isBool(FALSE))
2093 if (msg)
2095 e = msg->interpret(istate);
2096 if (e == EXP_CANT_INTERPRET)
2097 goto Lcant;
2098 error("%s", e->toChars());
2100 else
2101 error("%s failed", toChars());
2102 goto Lcant;
2104 else
2105 goto Lcant;
2106 return e1;
2108 Lcant:
2109 return EXP_CANT_INTERPRET;
2112 Expression *PtrExp::interpret(InterState *istate)
2113 { Expression *e = EXP_CANT_INTERPRET;
2115 #if LOG
2116 printf("PtrExp::interpret() %s\n", toChars());
2117 #endif
2119 // Constant fold *(&structliteral + offset)
2120 if (e1->op == TOKadd)
2121 { AddExp *ae = (AddExp *)e1;
2122 if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64)
2123 { AddrExp *ade = (AddrExp *)ae->e1;
2124 Expression *ex = ade->e1;
2125 ex = ex->interpret(istate);
2126 if (ex != EXP_CANT_INTERPRET)
2128 if (ex->op == TOKstructliteral)
2129 { StructLiteralExp *se = (StructLiteralExp *)ex;
2130 unsigned offset = ae->e2->toInteger();
2131 e = se->getField(type, offset);
2132 if (!e)
2133 e = EXP_CANT_INTERPRET;
2134 return e;
2138 e = Ptr(type, e1);
2140 else if (e1->op == TOKsymoff)
2141 { SymOffExp *soe = (SymOffExp *)e1;
2142 VarDeclaration *v = soe->var->isVarDeclaration();
2143 if (v)
2144 { Expression *ev = getVarExp(loc, istate, v);
2145 if (ev != EXP_CANT_INTERPRET && ev->op == TOKstructliteral)
2146 { StructLiteralExp *se = (StructLiteralExp *)ev;
2147 e = se->getField(type, soe->offset);
2148 if (!e)
2149 e = EXP_CANT_INTERPRET;
2153 #if LOG
2154 if (e == EXP_CANT_INTERPRET)
2155 printf("PtrExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars());
2156 #endif
2157 return e;
2160 /******************************* Special Functions ***************************/
2162 Expression *interpret_aaLen(InterState *istate, Expressions *arguments)
2164 if (!arguments || arguments->dim != 1)
2165 return NULL;
2166 Expression *earg = (Expression *)arguments->data[0];
2167 earg = earg->interpret(istate);
2168 if (earg == EXP_CANT_INTERPRET)
2169 return NULL;
2170 if (earg->op != TOKassocarrayliteral)
2171 return NULL;
2172 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
2173 Expression *e = new IntegerExp(aae->loc, aae->keys->dim, Type::tsize_t);
2174 return e;
2177 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments)
2179 //printf("interpret_aaKeys()\n");
2180 if (!arguments || arguments->dim != 2)
2181 return NULL;
2182 Expression *earg = (Expression *)arguments->data[0];
2183 earg = earg->interpret(istate);
2184 if (earg == EXP_CANT_INTERPRET)
2185 return NULL;
2186 if (earg->op != TOKassocarrayliteral)
2187 return NULL;
2188 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
2189 Expression *e = new ArrayLiteralExp(aae->loc, aae->keys);
2190 return e;
2193 Expression *interpret_aaValues(InterState *istate, Expressions *arguments)
2195 //printf("interpret_aaValues()\n");
2196 if (!arguments || arguments->dim != 3)
2197 return NULL;
2198 Expression *earg = (Expression *)arguments->data[0];
2199 earg = earg->interpret(istate);
2200 if (earg == EXP_CANT_INTERPRET)
2201 return NULL;
2202 if (earg->op != TOKassocarrayliteral)
2203 return NULL;
2204 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
2205 Expression *e = new ArrayLiteralExp(aae->loc, aae->values);
2206 //printf("result is %s\n", e->toChars());
2207 return e;