2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars
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.
17 #include "statement.h"
18 #include "expression.h"
21 #include "staticassert.h"
24 #include "declaration.h"
25 #include "aggregate.h"
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
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.
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
)
60 printf("\n********\nFuncDeclaration::interpret(istate = %p) %s\n", istate
, toChars());
61 printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret
, semanticRun
);
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)
75 if (needThis() || isNested() || !fbody
)
80 //printf("test2 %d, %p\n", semanticRun, scope);
81 if (semanticRun
== 0 && scope
)
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*/)
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
)
109 istatex
.caller
= istate
;
112 Expressions vsave
; // place to save previous parameter values
116 dim
= arguments
->dim
;
117 assert(!dim
|| parameters
->dim
== dim
);
120 /* Evaluate all the arguments to the function,
121 * store the results in eargs[]
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
))
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
)
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
;
157 printf("arg[%d] = %s\n", i
, earg
->toChars());
159 if (arg
->storageClass
& (STCout
| STCref
))
161 /* Bind out or ref parameter to the corresponding
164 if (!istate
|| earg
->op
!= TOKvar
)
165 return NULL
; // can't bind to non-interpreted vars
170 VarExp
*ve
= (VarExp
*)earg
;
171 v2
= ve
->var
->isVarDeclaration();
174 if (!v2
->value
|| v2
->value
->op
!= TOKvar
)
179 v
->value
= new VarExp(earg
->loc
, v2
);
181 /* Don't restore the value of v2 upon function return
184 for (size_t i
= 0; i
< istate
->vars
.dim
; i
++)
185 { VarDeclaration
*v
= (VarDeclaration
*)istate
->vars
.data
[i
];
187 { istate
->vars
.data
[i
] = NULL
;
193 { /* Value parameters
198 printf("interpreted arg[%d] = %s\n", i
, earg
->toChars());
203 /* Save the values of the local variables used
205 Expressions valueSaves
;
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
];
214 //printf("\tsaving [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : "");
215 valueSaves
.data
[i
] = v
->value
;
221 Expression
*e
= NULL
;
225 e
= fbody
->interpret(&istatex
);
226 if (e
== EXP_CANT_INTERPRET
)
229 printf("function body failed to interpret\n");
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
;
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
];
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
];
265 { v
->value
= (Expression
*)valueSaves
.data
[i
];
266 //printf("\trestoring [%d] %s = %s\n", i, v->toChars(), v->value ? v->value->toChars() : "");
274 /******************************** Statement ***************************/
278 { if (istate->start != this) \
280 istate->start = NULL; \
283 /***********************************
284 * Interpret the statement.
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
)
294 printf("Statement::interpret()\n");
297 return EXP_CANT_INTERPRET
;
300 Expression
*ExpStatement::interpret(InterState
*istate
)
303 printf("ExpStatement::interpret(%s)\n", exp
? exp
->toChars() : "");
308 Expression
*e
= exp
->interpret(istate
);
309 if (e
== EXP_CANT_INTERPRET
)
311 //printf("-ExpStatement::interpret(): %p\n", e);
312 return EXP_CANT_INTERPRET
;
318 Expression
*CompoundStatement::interpret(InterState
*istate
)
319 { Expression
*e
= NULL
;
322 printf("CompoundStatement::interpret()\n");
324 if (istate
->start
== this)
325 istate
->start
= NULL
;
328 for (size_t i
= 0; i
< statements
->dim
; i
++)
329 { Statement
*s
= (Statement
*)statements
->data
[i
];
333 e
= s
->interpret(istate
);
340 printf("-CompoundStatement::interpret() %p\n", e
);
345 Expression
*UnrolledLoopStatement::interpret(InterState
*istate
)
346 { Expression
*e
= NULL
;
349 printf("UnrolledLoopStatement::interpret()\n");
351 if (istate
->start
== this)
352 istate
->start
= NULL
;
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
)
361 if (e
== EXP_CONTINUE_INTERPRET
)
365 if (e
== EXP_BREAK_INTERPRET
)
376 Expression
*IfStatement::interpret(InterState
*istate
)
379 printf("IfStatement::interpret(%s)\n", condition
->toChars());
382 if (istate
->start
== this)
383 istate
->start
= NULL
;
386 Expression
*e
= NULL
;
388 e
= ifbody
->interpret(istate
);
389 if (istate
->start
&& elsebody
)
390 e
= elsebody
->interpret(istate
);
394 Expression
*e
= condition
->interpret(istate
);
396 //if (e == EXP_CANT_INTERPRET) printf("cannot interpret\n");
397 if (e
!= EXP_CANT_INTERPRET
)
400 e
= ifbody
? ifbody
->interpret(istate
) : NULL
;
401 else if (e
->isBool(FALSE
))
402 e
= elsebody
? elsebody
->interpret(istate
) : NULL
;
405 e
= EXP_CANT_INTERPRET
;
411 Expression
*ScopeStatement::interpret(InterState
*istate
)
414 printf("ScopeStatement::interpret()\n");
416 if (istate
->start
== this)
417 istate
->start
= NULL
;
418 return statement
? statement
->interpret(istate
) : NULL
;
421 Expression
*ReturnStatement::interpret(InterState
*istate
)
424 printf("ReturnStatement::interpret(%s)\n", exp
? exp
->toChars() : "");
428 return EXP_VOID_INTERPRET
;
430 Expression
*e
= exp
->interpret(istate
);
431 printf("e = %p\n", e
);
434 return exp
->interpret(istate
);
438 Expression
*BreakStatement::interpret(InterState
*istate
)
441 printf("BreakStatement::interpret()\n");
445 return EXP_CANT_INTERPRET
;
447 return EXP_BREAK_INTERPRET
;
450 Expression
*ContinueStatement::interpret(InterState
*istate
)
453 printf("ContinueStatement::interpret()\n");
457 return EXP_CANT_INTERPRET
;
459 return EXP_CONTINUE_INTERPRET
;
462 Expression
*WhileStatement::interpret(InterState
*istate
)
465 printf("WhileStatement::interpret()\n");
467 if (istate
->start
== this)
468 istate
->start
= NULL
;
473 e
= body
? body
->interpret(istate
) : NULL
;
476 if (e
== EXP_CANT_INTERPRET
)
478 if (e
== EXP_BREAK_INTERPRET
)
480 if (e
!= EXP_CONTINUE_INTERPRET
)
486 e
= condition
->interpret(istate
);
487 if (e
== EXP_CANT_INTERPRET
)
490 { e
= EXP_CANT_INTERPRET
;
494 { e
= body
? body
->interpret(istate
) : NULL
;
495 if (e
== EXP_CANT_INTERPRET
)
497 if (e
== EXP_CONTINUE_INTERPRET
)
499 if (e
== EXP_BREAK_INTERPRET
)
506 else if (e
->isBool(FALSE
))
516 Expression
*DoStatement::interpret(InterState
*istate
)
519 printf("DoStatement::interpret()\n");
521 if (istate
->start
== this)
522 istate
->start
= NULL
;
527 e
= body
? body
->interpret(istate
) : NULL
;
530 if (e
== EXP_CANT_INTERPRET
)
532 if (e
== EXP_BREAK_INTERPRET
)
534 if (e
== EXP_CONTINUE_INTERPRET
)
542 e
= body
? body
->interpret(istate
) : NULL
;
543 if (e
== EXP_CANT_INTERPRET
)
545 if (e
== EXP_BREAK_INTERPRET
)
549 if (e
&& e
!= EXP_CONTINUE_INTERPRET
)
553 e
= condition
->interpret(istate
);
554 if (e
== EXP_CANT_INTERPRET
)
557 { e
= EXP_CANT_INTERPRET
;
563 else if (e
->isBool(FALSE
))
573 Expression
*ForStatement::interpret(InterState
*istate
)
576 printf("ForStatement::interpret()\n");
578 if (istate
->start
== this)
579 istate
->start
= NULL
;
584 e
= init
->interpret(istate
);
585 if (e
== EXP_CANT_INTERPRET
)
592 e
= body
? body
->interpret(istate
) : NULL
;
595 if (e
== EXP_CANT_INTERPRET
)
597 if (e
== EXP_BREAK_INTERPRET
)
599 if (e
== EXP_CONTINUE_INTERPRET
)
609 e
= condition
->interpret(istate
);
610 if (e
== EXP_CANT_INTERPRET
)
613 { e
= EXP_CANT_INTERPRET
;
619 e
= body
? body
->interpret(istate
) : NULL
;
620 if (e
== EXP_CANT_INTERPRET
)
622 if (e
== EXP_BREAK_INTERPRET
)
626 if (e
&& e
!= EXP_CONTINUE_INTERPRET
)
631 e
= increment
->interpret(istate
);
632 if (e
== EXP_CANT_INTERPRET
)
636 else if (e
->isBool(FALSE
))
646 Expression
*ForeachStatement::interpret(InterState
*istate
)
649 printf("ForeachStatement::interpret()\n");
651 if (istate
->start
== this)
652 istate
->start
= NULL
;
656 Expression
*e
= NULL
;
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();
676 if (op
== TOKforeach
)
678 for (index
= 0; index
< d
; index
++)
680 Expression
*ekey
= new IntegerExp(loc
, index
, Type::tsize_t
);
683 e
= Index(value
->type
, eaggr
, ekey
);
684 if (e
== EXP_CANT_INTERPRET
)
688 e
= body
? body
->interpret(istate
) : NULL
;
689 if (e
== EXP_CANT_INTERPRET
)
691 if (e
== EXP_BREAK_INTERPRET
)
695 if (e
== EXP_CONTINUE_INTERPRET
)
701 else // TOKforeach_reverse
703 for (index
= d
; index
-- != 0;)
705 Expression
*ekey
= new IntegerExp(loc
, index
, Type::tsize_t
);
708 e
= Index(value
->type
, eaggr
, ekey
);
709 if (e
== EXP_CANT_INTERPRET
)
713 e
= body
? body
->interpret(istate
) : NULL
;
714 if (e
== EXP_CANT_INTERPRET
)
716 if (e
== EXP_BREAK_INTERPRET
)
720 if (e
== EXP_CONTINUE_INTERPRET
)
726 value
->value
= valuesave
;
728 key
->value
= keysave
;
733 Expression
*ForeachRangeStatement::interpret(InterState
*istate
)
736 printf("ForeachRangeStatement::interpret()\n");
738 if (istate
->start
== this)
739 istate
->start
= 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
)
760 e
= Cmp(TOKlt
, key
->value
->type
, key
->value
, upr
);
761 if (e
== EXP_CANT_INTERPRET
)
763 if (e
->isBool(TRUE
) == FALSE
)
768 e
= body
? body
->interpret(istate
) : NULL
;
769 if (e
== EXP_CANT_INTERPRET
)
771 if (e
== EXP_BREAK_INTERPRET
)
775 e
= Add(key
->value
->type
, key
->value
, new IntegerExp(loc
, 1, key
->value
->type
));
776 if (e
== EXP_CANT_INTERPRET
)
781 else // TOKforeach_reverse
787 e
= Cmp(TOKgt
, key
->value
->type
, key
->value
, lwr
);
788 if (e
== EXP_CANT_INTERPRET
)
790 if (e
->isBool(TRUE
) == FALSE
)
795 e
= Min(key
->value
->type
, key
->value
, new IntegerExp(loc
, 1, key
->value
->type
));
796 if (e
== EXP_CANT_INTERPRET
)
800 e
= body
? body
->interpret(istate
) : NULL
;
801 if (e
== EXP_CANT_INTERPRET
)
803 if (e
== EXP_BREAK_INTERPRET
)
809 key
->value
= keysave
;
814 Expression
*SwitchStatement::interpret(InterState
*istate
)
817 printf("SwitchStatement::interpret()\n");
819 if (istate
->start
== this)
820 istate
->start
= NULL
;
821 Expression
*e
= NULL
;
825 e
= body
? body
->interpret(istate
) : NULL
;
828 if (e
== EXP_CANT_INTERPRET
)
830 if (e
== EXP_BREAK_INTERPRET
)
836 Expression
*econdition
= condition
->interpret(istate
);
837 if (econdition
== EXP_CANT_INTERPRET
)
838 return EXP_CANT_INTERPRET
;
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
;
857 error("no default or case for %s in switch statement", econdition
->toChars());
863 e
= body
? body
->interpret(istate
) : NULL
;
864 assert(!istate
->start
);
865 if (e
== EXP_BREAK_INTERPRET
)
870 Expression
*CaseStatement::interpret(InterState
*istate
)
873 printf("CaseStatement::interpret(%s) this = %p\n", exp
->toChars(), this);
875 if (istate
->start
== this)
876 istate
->start
= NULL
;
878 return statement
->interpret(istate
);
883 Expression
*DefaultStatement::interpret(InterState
*istate
)
886 printf("DefaultStatement::interpret()\n");
888 if (istate
->start
== this)
889 istate
->start
= NULL
;
891 return statement
->interpret(istate
);
896 Expression
*GotoStatement::interpret(InterState
*istate
)
899 printf("GotoStatement::interpret()\n");
902 assert(label
&& label
->statement
);
903 istate
->gotoTarget
= label
->statement
;
904 return EXP_GOTO_INTERPRET
;
907 Expression
*GotoCaseStatement::interpret(InterState
*istate
)
910 printf("GotoCaseStatement::interpret()\n");
914 istate
->gotoTarget
= cs
;
915 return EXP_GOTO_INTERPRET
;
918 Expression
*GotoDefaultStatement::interpret(InterState
*istate
)
921 printf("GotoDefaultStatement::interpret()\n");
924 assert(sw
&& sw
->sdefault
);
925 istate
->gotoTarget
= sw
->sdefault
;
926 return EXP_GOTO_INTERPRET
;
929 Expression
*LabelStatement::interpret(InterState
*istate
)
932 printf("LabelStatement::interpret()\n");
934 if (istate
->start
== this)
935 istate
->start
= NULL
;
936 return statement
? statement
->interpret(istate
) : NULL
;
939 /******************************** Expression ***************************/
941 Expression
*Expression::interpret(InterState
*istate
)
944 printf("Expression::interpret() %s\n", toChars());
945 printf("type = %s\n", type
->toChars());
948 return EXP_CANT_INTERPRET
;
951 Expression
*NullExp::interpret(InterState
*istate
)
956 Expression
*IntegerExp::interpret(InterState
*istate
)
959 printf("IntegerExp::interpret() %s\n", toChars());
964 Expression
*RealExp::interpret(InterState
*istate
)
967 printf("RealExp::interpret() %s\n", toChars());
972 Expression
*ComplexExp::interpret(InterState
*istate
)
977 Expression
*StringExp::interpret(InterState
*istate
)
980 printf("StringExp::interpret() %s\n", toChars());
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();
993 if ((v
->isConst() || v
->isInvariant()) && v
->init
&& !v
->value
)
995 if (v
->isConst() && v
->init
)
997 { e
= v
->init
->toExpression();
1004 error(loc
, "variable %s is used before initialization", v
->toChars());
1005 else if (e
!= EXP_CANT_INTERPRET
)
1006 e
= e
->interpret(istate
);
1009 e
= EXP_CANT_INTERPRET
;
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
);
1022 Expression
*VarExp::interpret(InterState
*istate
)
1025 printf("VarExp::interpret() %s\n", toChars());
1027 return getVarExp(loc
, istate
, var
);
1030 Expression
*DeclarationExp::interpret(InterState
*istate
)
1033 printf("DeclarationExp::interpret() %s\n", toChars());
1036 VarDeclaration
*v
= declaration
->isVarDeclaration();
1039 Dsymbol
*s
= v
->toAlias();
1040 if (s
== v
&& !v
->isStatic() && v
->init
)
1042 ExpInitializer
*ie
= v
->init
->isExpInitializer();
1044 e
= ie
->exp
->interpret(istate
);
1045 else if (v
->init
->isVoidInitializer())
1049 else if (s
== v
&& (v
->isConst() || v
->isInvariant()) && v
->init
)
1051 else if (s
== v
&& v
->isConst() && v
->init
)
1053 { e
= v
->init
->toExpression();
1055 e
= EXP_CANT_INTERPRET
;
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
;
1067 { // Others should not contain executable code, so are trivial to evaluate
1071 printf("-DeclarationExp::interpret(): %p\n", e
);
1076 Expression
*TupleExp::interpret(InterState
*istate
)
1079 printf("TupleExp::interpret() %s\n", toChars());
1081 Expressions
*expsx
= NULL
;
1083 for (size_t i
= 0; i
< exps
->dim
; i
++)
1084 { Expression
*e
= (Expression
*)exps
->data
[i
];
1087 ex
= e
->interpret(istate
);
1088 if (ex
== EXP_CANT_INTERPRET
)
1093 /* If any changes, do Copy On Write
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
;
1109 { TupleExp
*te
= new TupleExp(loc
, expsx
);
1110 expandTuples(te
->exps
);
1111 te
->type
= new TypeTuple(te
->exps
);
1117 Expression
*ArrayLiteralExp::interpret(InterState
*istate
)
1118 { Expressions
*expsx
= NULL
;
1121 printf("ArrayLiteralExp::interpret() %s\n", toChars());
1125 for (size_t i
= 0; i
< elements
->dim
; i
++)
1126 { Expression
*e
= (Expression
*)elements
->data
[i
];
1129 ex
= e
->interpret(istate
);
1130 if (ex
== EXP_CANT_INTERPRET
)
1132 return EXP_CANT_INTERPRET
;
1135 /* If any changes, do Copy On Write
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
)
1156 return EXP_CANT_INTERPRET
;
1158 ArrayLiteralExp
*ae
= new ArrayLiteralExp(loc
, expsx
);
1165 Expression
*AssocArrayLiteralExp::interpret(InterState
*istate
)
1166 { Expressions
*keysx
= keys
;
1167 Expressions
*valuesx
= values
;
1170 printf("AssocArrayLiteralExp::interpret() %s\n", toChars());
1172 for (size_t i
= 0; i
< keys
->dim
; i
++)
1173 { Expression
*ekey
= (Expression
*)keys
->data
[i
];
1174 Expression
*evalue
= (Expression
*)values
->data
[i
];
1177 ex
= ekey
->interpret(istate
);
1178 if (ex
== EXP_CANT_INTERPRET
)
1181 /* If any changes, do Copy On Write
1186 keysx
= (Expressions
*)keys
->copy();
1187 keysx
->data
[i
] = (void *)ex
;
1190 ex
= evalue
->interpret(istate
);
1191 if (ex
== EXP_CANT_INTERPRET
)
1194 /* If any changes, do Copy On Write
1198 if (valuesx
== values
)
1199 valuesx
= (Expressions
*)values
->copy();
1200 valuesx
->data
[i
] = (void *)ex
;
1204 expandTuples(keysx
);
1205 if (valuesx
!= values
)
1206 expandTuples(valuesx
);
1207 if (keysx
->dim
!= valuesx
->dim
)
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
)
1220 if (ex
->isBool(TRUE
)) // if a match
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
1235 if (keysx
!= keys
|| valuesx
!= values
)
1237 AssocArrayLiteralExp
*ae
;
1238 ae
= new AssocArrayLiteralExp(loc
, keysx
, valuesx
);
1247 if (valuesx
!= values
)
1249 return EXP_CANT_INTERPRET
;
1252 Expression
*StructLiteralExp::interpret(InterState
*istate
)
1253 { Expressions
*expsx
= NULL
;
1256 printf("StructLiteralExp::interpret() %s\n", toChars());
1258 /* We don't know how to deal with overlapping fields
1261 return EXP_CANT_INTERPRET
;
1265 for (size_t i
= 0; i
< elements
->dim
; i
++)
1266 { Expression
*e
= (Expression
*)elements
->data
[i
];
1270 Expression
*ex
= e
->interpret(istate
);
1271 if (ex
== EXP_CANT_INTERPRET
)
1273 return EXP_CANT_INTERPRET
;
1276 /* If any changes, do Copy On Write
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
)
1297 return EXP_CANT_INTERPRET
;
1299 StructLiteralExp
*se
= new StructLiteralExp(loc
, sd
, expsx
);
1306 Expression
*UnaExp::interpretCommon(InterState
*istate
, Expression
*(*fp
)(Type
*, Expression
*))
1311 printf("UnaExp::interpretCommon() %s\n", toChars());
1313 e1
= this->e1
->interpret(istate
);
1314 if (e1
== EXP_CANT_INTERPRET
)
1316 if (e1
->isConst() != 1)
1319 e
= (*fp
)(type
, e1
);
1323 return EXP_CANT_INTERPRET
;
1326 #define UNA_INTERPRET(op) \
1327 Expression *op##Exp::interpret(InterState *istate) \
1329 return interpretCommon(istate, &op); \
1338 typedef Expression
*(*fp_t
)(Type
*, Expression
*, Expression
*);
1340 Expression
*BinExp::interpretCommon(InterState
*istate
, fp_t fp
)
1346 printf("BinExp::interpretCommon() %s\n", toChars());
1348 e1
= this->e1
->interpret(istate
);
1349 if (e1
== EXP_CANT_INTERPRET
)
1351 if (e1
->isConst() != 1)
1354 e2
= this->e2
->interpret(istate
);
1355 if (e2
== EXP_CANT_INTERPRET
)
1357 if (e2
->isConst() != 1)
1360 e
= (*fp
)(type
, e1
, e2
);
1364 return EXP_CANT_INTERPRET
;
1367 #define BIN_INTERPRET(op) \
1368 Expression *op##Exp::interpret(InterState *istate) \
1370 return interpretCommon(istate, &op); \
1386 typedef Expression
*(*fp2_t
)(enum TOK
, Type
*, Expression
*, Expression
*);
1388 Expression
*BinExp::interpretCommon2(InterState
*istate
, fp2_t fp
)
1394 printf("BinExp::interpretCommon2() %s\n", toChars());
1396 e1
= this->e1
->interpret(istate
);
1397 if (e1
== EXP_CANT_INTERPRET
)
1399 if (e1
->isConst() != 1 &&
1400 e1
->op
!= TOKnull
&&
1401 e1
->op
!= TOKstring
&&
1402 e1
->op
!= TOKarrayliteral
&&
1403 e1
->op
!= TOKstructliteral
)
1406 e2
= this->e2
->interpret(istate
);
1407 if (e2
== EXP_CANT_INTERPRET
)
1409 if (e2
->isConst() != 1 &&
1410 e2
->op
!= TOKnull
&&
1411 e2
->op
!= TOKstring
&&
1412 e2
->op
!= TOKarrayliteral
&&
1413 e2
->op
!= TOKstructliteral
)
1416 e
= (*fp
)(op
, type
, e1
, e2
);
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
)
1433 Expression
*BinExp::interpretAssignCommon(InterState
*istate
, fp_t fp
, int post
)
1436 printf("BinExp::interpretAssignCommon() %s\n", toChars());
1438 Expression
*e
= EXP_CANT_INTERPRET
;
1439 Expression
*e1
= this->e1
;
1443 if (e1
->op
== TOKcast
)
1444 { CastExp
*ce
= (CastExp
*)e1
;
1448 if (e1
== EXP_CANT_INTERPRET
)
1450 Expression
*e2
= this->e2
->interpret(istate
);
1451 if (e2
== EXP_CANT_INTERPRET
)
1454 /* Assignment to variable of the form:
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()
1476 v
= ve2
->var
->isVarDeclaration();
1480 Expression
*ev
= v
->value
;
1482 { error("variable %s is used before initialization", v
->toChars());
1486 e2
= (*fp
)(v
->type
, ev
, e2
);
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());
1507 if (v
== (VarDeclaration
*)istate
->vars
.data
[i
])
1512 e
= Cast(type
, type
, post
? ev
: e2
);
1516 /* Assignment to struct member of the form:
1519 else if (e1
->op
== TOKstar
&& ((PtrExp
*)e1
)->e1
->op
== TOKsymoff
)
1520 { SymOffExp
*soe
= (SymOffExp
*)((PtrExp
*)e1
)->e1
;
1521 VarDeclaration
*v
= soe
->var
->isVarDeclaration();
1524 return EXP_CANT_INTERPRET
;
1525 if (fp
&& !v
->value
)
1526 { error("variable %s is used before initialization", v
->toChars());
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
);
1540 return EXP_CANT_INTERPRET
;
1541 Expression
*ev
= se
->getField(type
, soe
->offset
);
1543 e2
= (*fp
)(type
, ev
, e2
);
1545 e2
= Cast(type
, type
, e2
);
1546 if (e2
== EXP_CANT_INTERPRET
)
1549 if (!v
->isParameter())
1551 for (size_t i
= 0; 1; i
++)
1553 if (i
== istate
->vars
.dim
)
1554 { istate
->vars
.push(v
);
1557 if (v
== (VarDeclaration
*)istate
->vars
.data
[i
])
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
++)
1569 expsx
->data
[j
] = (void *)e2
;
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:
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
;
1591 { error("variable %s is used before initialization", v
->toChars());
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
);
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
;
1629 return EXP_CANT_INTERPRET
;
1631 Expression
*index
= ie
->e2
->interpret(istate
);
1632 if (index
== EXP_CANT_INTERPRET
)
1633 return EXP_CANT_INTERPRET
;
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
;
1643 e2
= (*fp
)(type
, ev
, e2
);
1645 e2
= Cast(type
, type
, e2
);
1646 if (e2
== EXP_CANT_INTERPRET
)
1649 if (!v
->isParameter())
1651 for (size_t i
= 0; 1; i
++)
1653 if (i
== istate
->vars
.dim
)
1654 { istate
->vars
.push(v
);
1657 if (v
== (VarDeclaration
*)istate
->vars
.data
[i
])
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
++)
1672 expsx
->data
[j
] = (void *)e2
;
1674 expsx
->data
[j
] = ae
->elements
->data
[j
];
1676 v
->value
= new ArrayLiteralExp(ae
->loc
, expsx
);
1677 v
->value
->type
= ae
->type
;
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
);
1687 for (size_t j
= valuesx
->dim
; 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
;
1698 valuesx
->data
[j
] = aae
->values
->data
[j
];
1701 { // Append index/e2 to keysx[]/valuesx[]
1703 keysx
= (Expressions
*)keysx
->copy();
1706 v
->value
= new AssocArrayLiteralExp(aae
->loc
, keysx
, valuesx
);
1707 v
->value
->type
= aae
->type
;
1711 /* Create new string literal reflecting updated elem
1713 int elemi
= index
->toInteger();
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();
1720 case 1: s
[elemi
] = value
; break;
1721 case 2: ((unsigned short *)s
)[elemi
] = value
; break;
1722 case 4: ((unsigned *)s
)[elemi
] = value
; 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
;
1736 e
= Cast(type
, type
, post
? ev
: e2
);
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
)
1774 printf("PostExp::interpret() %s\n", toChars());
1777 if (op
== TOKplusplus
)
1778 e
= interpretAssignCommon(istate
, &Add
, 1);
1780 e
= interpretAssignCommon(istate
, &Min
, 1);
1782 if (e
== EXP_CANT_INTERPRET
)
1783 printf("PostExp::interpret() CANT\n");
1788 Expression
*AndAndExp::interpret(InterState
*istate
)
1791 printf("AndAndExp::interpret() %s\n", toChars());
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
);
1808 e
= EXP_CANT_INTERPRET
;
1812 e
= EXP_CANT_INTERPRET
;
1817 Expression
*OrOrExp::interpret(InterState
*istate
)
1820 printf("OrOrExp::interpret() %s\n", toChars());
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
);
1837 e
= EXP_CANT_INTERPRET
;
1841 e
= EXP_CANT_INTERPRET
;
1847 Expression
*CallExp::interpret(InterState
*istate
)
1848 { Expression
*e
= EXP_CANT_INTERPRET
;
1851 printf("CallExp::interpret() %s\n", toChars());
1853 if (e1
->op
== TOKvar
)
1855 FuncDeclaration
*fd
= ((VarExp
*)e1
)->var
->isFuncDeclaration();
1859 enum BUILTIN b
= fd
->isBuiltin();
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
)
1869 args
.data
[i
] = (void *)earg
;
1871 e
= eval_builtin(b
, &args
);
1873 e
= EXP_CANT_INTERPRET
;
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
);
1889 Expression
*eresult
= fd
->interpret(istate
, arguments
);
1892 else if (fd
->type
->toBasetype()->nextOf()->ty
== Tvoid
&& !global
.errors
)
1893 e
= EXP_VOID_INTERPRET
;
1895 error("cannot evaluate %s at compile time", toChars());
1902 Expression
*CommaExp::interpret(InterState
*istate
)
1905 printf("CommaExp::interpret() %s\n", toChars());
1907 Expression
*e
= e1
->interpret(istate
);
1908 if (e
!= EXP_CANT_INTERPRET
)
1909 e
= e2
->interpret(istate
);
1913 Expression
*CondExp::interpret(InterState
*istate
)
1916 printf("CondExp::interpret() %s\n", toChars());
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
);
1926 e
= EXP_CANT_INTERPRET
;
1931 Expression
*ArrayLengthExp::interpret(InterState
*istate
)
1936 printf("ArrayLengthExp::interpret() %s\n", toChars());
1938 e1
= this->e1
->interpret(istate
);
1939 if (e1
== EXP_CANT_INTERPRET
)
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
);
1954 return EXP_CANT_INTERPRET
;
1957 Expression
*IndexExp::interpret(InterState
*istate
)
1963 printf("IndexExp::interpret() %s\n", toChars());
1965 e1
= this->e1
->interpret(istate
);
1966 if (e1
== EXP_CANT_INTERPRET
)
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
)
1977 lengthVar
->value
= e
;
1980 e2
= this->e2
->interpret(istate
);
1981 if (e2
== EXP_CANT_INTERPRET
)
1983 return Index(type
, e1
, e2
);
1986 return EXP_CANT_INTERPRET
;
1990 Expression
*SliceExp::interpret(InterState
*istate
)
1997 printf("SliceExp::interpret() %s\n", toChars());
1999 e1
= this->e1
->interpret(istate
);
2000 if (e1
== EXP_CANT_INTERPRET
)
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
)
2014 lengthVar
->value
= e
;
2016 /* Evaluate lower and upper bounds of slice
2018 lwr
= this->lwr
->interpret(istate
);
2019 if (lwr
== EXP_CANT_INTERPRET
)
2021 upr
= this->upr
->interpret(istate
);
2022 if (upr
== EXP_CANT_INTERPRET
)
2025 return Slice(type
, e1
, lwr
, upr
);
2028 return EXP_CANT_INTERPRET
;
2032 Expression
*CatExp::interpret(InterState
*istate
)
2038 printf("CatExp::interpret() %s\n", toChars());
2040 e1
= this->e1
->interpret(istate
);
2041 if (e1
== EXP_CANT_INTERPRET
)
2045 e2
= this->e2
->interpret(istate
);
2046 if (e2
== EXP_CANT_INTERPRET
)
2048 return Cat(type
, e1
, e2
);
2052 printf("CatExp::interpret() %s CANT\n", toChars());
2054 return EXP_CANT_INTERPRET
;
2058 Expression
*CastExp::interpret(InterState
*istate
)
2063 printf("CastExp::interpret() %s\n", toChars());
2065 e1
= this->e1
->interpret(istate
);
2066 if (e1
== EXP_CANT_INTERPRET
)
2068 return Cast(type
, to
, e1
);
2072 printf("CastExp::interpret() %s CANT\n", toChars());
2074 return EXP_CANT_INTERPRET
;
2078 Expression
*AssertExp::interpret(InterState
*istate
)
2083 printf("AssertExp::interpret() %s\n", toChars());
2085 e1
= this->e1
->interpret(istate
);
2086 if (e1
== EXP_CANT_INTERPRET
)
2088 if (e1
->isBool(TRUE
))
2091 else if (e1
->isBool(FALSE
))
2095 e
= msg
->interpret(istate
);
2096 if (e
== EXP_CANT_INTERPRET
)
2098 error("%s", e
->toChars());
2101 error("%s failed", toChars());
2109 return EXP_CANT_INTERPRET
;
2112 Expression
*PtrExp::interpret(InterState
*istate
)
2113 { Expression
*e
= EXP_CANT_INTERPRET
;
2116 printf("PtrExp::interpret() %s\n", toChars());
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
);
2133 e
= EXP_CANT_INTERPRET
;
2140 else if (e1
->op
== TOKsymoff
)
2141 { SymOffExp
*soe
= (SymOffExp
*)e1
;
2142 VarDeclaration
*v
= soe
->var
->isVarDeclaration();
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
);
2149 e
= EXP_CANT_INTERPRET
;
2154 if (e
== EXP_CANT_INTERPRET
)
2155 printf("PtrExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars());
2160 /******************************* Special Functions ***************************/
2162 Expression
*interpret_aaLen(InterState
*istate
, Expressions
*arguments
)
2164 if (!arguments
|| arguments
->dim
!= 1)
2166 Expression
*earg
= (Expression
*)arguments
->data
[0];
2167 earg
= earg
->interpret(istate
);
2168 if (earg
== EXP_CANT_INTERPRET
)
2170 if (earg
->op
!= TOKassocarrayliteral
)
2172 AssocArrayLiteralExp
*aae
= (AssocArrayLiteralExp
*)earg
;
2173 Expression
*e
= new IntegerExp(aae
->loc
, aae
->keys
->dim
, Type::tsize_t
);
2177 Expression
*interpret_aaKeys(InterState
*istate
, Expressions
*arguments
)
2179 //printf("interpret_aaKeys()\n");
2180 if (!arguments
|| arguments
->dim
!= 2)
2182 Expression
*earg
= (Expression
*)arguments
->data
[0];
2183 earg
= earg
->interpret(istate
);
2184 if (earg
== EXP_CANT_INTERPRET
)
2186 if (earg
->op
!= TOKassocarrayliteral
)
2188 AssocArrayLiteralExp
*aae
= (AssocArrayLiteralExp
*)earg
;
2189 Expression
*e
= new ArrayLiteralExp(aae
->loc
, aae
->keys
);
2193 Expression
*interpret_aaValues(InterState
*istate
, Expressions
*arguments
)
2195 //printf("interpret_aaValues()\n");
2196 if (!arguments
|| arguments
->dim
!= 3)
2198 Expression
*earg
= (Expression
*)arguments
->data
[0];
2199 earg
= earg
->interpret(istate
);
2200 if (earg
== EXP_CANT_INTERPRET
)
2202 if (earg
->op
!= TOKassocarrayliteral
)
2204 AssocArrayLiteralExp
*aae
= (AssocArrayLiteralExp
*)earg
;
2205 Expression
*e
= new ArrayLiteralExp(aae
->loc
, aae
->values
);
2206 //printf("result is %s\n", e->toChars());