Mercurial > projects > ldc
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 } |