comparison dmd/interpret.c @ 159:5acec6b2eef8 trunk

[svn r175] merged dmd 1.029
author ChristianK
date Thu, 01 May 2008 15:15:28 +0200
parents 5825d48b27d1
children aaade6ded589
comparison
equal deleted inserted replaced
158:287540c5f05e 159:5acec6b2eef8
1 1
2 // Compiler implementation of the D programming language 2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2007 by Digital Mars 3 // Copyright (c) 1999-2008 by Digital Mars
4 // All Rights Reserved 4 // All Rights Reserved
5 // written by Walter Bright 5 // written by Walter Bright
6 // http://www.digitalmars.com 6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License 7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 // in artistic.txt, or the GNU General Public License in gnu.txt.
107 107
108 InterState istatex; 108 InterState istatex;
109 istatex.caller = istate; 109 istatex.caller = istate;
110 istatex.fd = this; 110 istatex.fd = this;
111 111
112 Expressions vsave; 112 Expressions vsave; // place to save previous parameter values
113 size_t dim = 0; 113 size_t dim = 0;
114 if (arguments) 114 if (arguments)
115 { 115 {
116 dim = arguments->dim; 116 dim = arguments->dim;
117 assert(!dim || parameters->dim == dim); 117 assert(!dim || parameters->dim == dim);
118 vsave.setDim(dim); 118 vsave.setDim(dim);
119 119
120 /* Evaluate all the arguments to the function,
121 * store the results in eargs[]
122 */
123 Expressions eargs;
124 eargs.setDim(dim);
125
120 for (size_t i = 0; i < dim; i++) 126 for (size_t i = 0; i < dim; i++)
121 { Expression *earg = (Expression *)arguments->data[i]; 127 { Expression *earg = (Expression *)arguments->data[i];
122 Argument *arg = Argument::getNth(tf->parameters, i); 128 Argument *arg = Argument::getNth(tf->parameters, i);
123 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 129
124 vsave.data[i] = v->value;
125 #if LOG
126 printf("arg[%d] = %s\n", i, earg->toChars());
127 #endif
128 if (arg->storageClass & (STCout | STCref)) 130 if (arg->storageClass & (STCout | STCref))
129 { 131 {
130 /* Bind out or ref parameter to the corresponding
131 * variable v2
132 */
133 if (!istate || earg->op != TOKvar)
134 return NULL; // can't bind to non-interpreted vars
135
136 VarDeclaration *v2;
137 while (1)
138 {
139 VarExp *ve = (VarExp *)earg;
140 v2 = ve->var->isVarDeclaration();
141 if (!v2)
142 return NULL;
143 if (!v2->value || v2->value->op != TOKvar)
144 break;
145 earg = v2->value;
146 }
147
148 v->value = new VarExp(earg->loc, v2);
149
150 /* Don't restore the value of v2 upon function return
151 */
152 assert(istate);
153 for (size_t i = 0; i < istate->vars.dim; i++)
154 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i];
155 if (v == v2)
156 { istate->vars.data[i] = NULL;
157 break;
158 }
159 }
160 } 132 }
161 else 133 else
162 { /* Value parameters 134 { /* Value parameters
163 */ 135 */
164 Type *ta = arg->type->toBasetype(); 136 Type *ta = arg->type->toBasetype();
170 earg = ((AddrExp *)earg)->e1; 142 earg = ((AddrExp *)earg)->e1;
171 } 143 }
172 earg = earg->interpret(istate ? istate : &istatex); 144 earg = earg->interpret(istate ? istate : &istatex);
173 if (earg == EXP_CANT_INTERPRET) 145 if (earg == EXP_CANT_INTERPRET)
174 return NULL; 146 return NULL;
147 }
148 eargs.data[i] = earg;
149 }
150
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))
160 {
161 /* Bind out or ref parameter to the corresponding
162 * variable v2
163 */
164 if (!istate || earg->op != TOKvar)
165 return NULL; // can't bind to non-interpreted vars
166
167 VarDeclaration *v2;
168 while (1)
169 {
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;
177 }
178
179 v->value = new VarExp(earg->loc, v2);
180
181 /* Don't restore the value of v2 upon function return
182 */
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;
189 }
190 }
191 }
192 else
193 { /* Value parameters
194 */
175 v->value = earg; 195 v->value = earg;
176 } 196 }
177 #if LOG 197 #if LOG
178 printf("interpreted arg[%d] = %s\n", i, earg->toChars()); 198 printf("interpreted arg[%d] = %s\n", i, earg->toChars());
179 #endif 199 #endif
582 return e; 602 return e;
583 } 603 }
584 604
585 while (1) 605 while (1)
586 { 606 {
607 if (!condition)
608 goto Lhead;
587 e = condition->interpret(istate); 609 e = condition->interpret(istate);
588 if (e == EXP_CANT_INTERPRET) 610 if (e == EXP_CANT_INTERPRET)
589 break; 611 break;
590 if (!e->isConst()) 612 if (!e->isConst())
591 { e = EXP_CANT_INTERPRET; 613 { e = EXP_CANT_INTERPRET;
592 break; 614 break;
593 } 615 }
594 if (e->isBool(TRUE)) 616 if (e->isBool(TRUE))
595 { e = body ? body->interpret(istate) : NULL; 617 {
618 Lhead:
619 e = body ? body->interpret(istate) : NULL;
596 if (e == EXP_CANT_INTERPRET) 620 if (e == EXP_CANT_INTERPRET)
597 break; 621 break;
598 if (e == EXP_BREAK_INTERPRET) 622 if (e == EXP_BREAK_INTERPRET)
599 { e = NULL; 623 { e = NULL;
600 break; 624 break;
601 } 625 }
602 if (e && e != EXP_CONTINUE_INTERPRET) 626 if (e && e != EXP_CONTINUE_INTERPRET)
603 break; 627 break;
604 Lcontinue: 628 Lcontinue:
605 e = increment->interpret(istate); 629 if (increment)
606 if (e == EXP_CANT_INTERPRET) 630 {
607 break; 631 e = increment->interpret(istate);
632 if (e == EXP_CANT_INTERPRET)
633 break;
634 }
608 } 635 }
609 else if (e->isBool(FALSE)) 636 else if (e->isBool(FALSE))
610 { e = NULL; 637 { e = NULL;
611 break; 638 break;
612 } 639 }