1
|
1
|
|
2 // Compiler implementation of the D programming language
|
|
3 // Copyright (c) 1999-2007 by Digital Mars
|
|
4 // All Rights Reserved
|
|
5 // written by Walter Bright
|
|
6 // http://www.digitalmars.com
|
|
7 // License for redistribution is by either the Artistic License
|
|
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
|
|
9 // See the included readme.txt for details.
|
|
10
|
|
11 #include <stdio.h>
|
|
12 #include <assert.h>
|
|
13
|
|
14 #include "mars.h"
|
|
15 #include "expression.h"
|
|
16 #include "statement.h"
|
|
17 #include "mtype.h"
|
|
18 #include "utf.h"
|
|
19 #include "declaration.h"
|
|
20 #include "aggregate.h"
|
|
21 #include "scope.h"
|
|
22
|
|
23 /********************************************
|
|
24 * Convert from expression to delegate that returns the expression,
|
|
25 * i.e. convert:
|
|
26 * expr
|
|
27 * to:
|
|
28 * t delegate() { return expr; }
|
|
29 */
|
|
30
|
|
31 Expression *Expression::toDelegate(Scope *sc, Type *t)
|
|
32 {
|
|
33 //printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), toChars());
|
|
34 TypeFunction *tf = new TypeFunction(NULL, t, 0, LINKd);
|
|
35 FuncLiteralDeclaration *fld =
|
|
36 new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
|
|
37 Expression *e;
|
|
38 #if 1
|
|
39 sc = sc->push();
|
|
40 sc->parent = fld; // set current function to be the delegate
|
|
41 e = this;
|
|
42 e->scanForNestedRef(sc);
|
|
43 sc = sc->pop();
|
|
44 #else
|
|
45 e = this->syntaxCopy();
|
|
46 #endif
|
|
47 Statement *s = new ReturnStatement(loc, e);
|
|
48 fld->fbody = s;
|
|
49 e = new FuncExp(loc, fld);
|
|
50 e = e->semantic(sc);
|
|
51 return e;
|
|
52 }
|
|
53
|
|
54 /******************************
|
|
55 * Perform scanForNestedRef() on an array of Expressions.
|
|
56 */
|
|
57
|
|
58 void arrayExpressionScanForNestedRef(Scope *sc, Expressions *a)
|
|
59 {
|
|
60 //printf("arrayExpressionScanForNestedRef(%p)\n", a);
|
|
61 if (a)
|
|
62 {
|
|
63 for (int i = 0; i < a->dim; i++)
|
|
64 { Expression *e = (Expression *)a->data[i];
|
|
65
|
|
66 if (e)
|
|
67 {
|
|
68 e->scanForNestedRef(sc);
|
|
69 }
|
|
70 }
|
|
71 }
|
|
72 }
|
|
73
|
|
74 void Expression::scanForNestedRef(Scope *sc)
|
|
75 {
|
|
76 //printf("Expression::scanForNestedRef(%s)\n", toChars());
|
|
77 }
|
|
78
|
|
79 void SymOffExp::scanForNestedRef(Scope *sc)
|
|
80 {
|
|
81 //printf("SymOffExp::scanForNestedRef(%s)\n", toChars());
|
|
82 VarDeclaration *v = var->isVarDeclaration();
|
|
83 if (v)
|
|
84 v->checkNestedReference(sc, 0);
|
|
85 }
|
|
86
|
|
87 void VarExp::scanForNestedRef(Scope *sc)
|
|
88 {
|
|
89 //printf("VarExp::scanForNestedRef(%s)\n", toChars());
|
|
90 VarDeclaration *v = var->isVarDeclaration();
|
|
91 if (v)
|
|
92 v->checkNestedReference(sc, 0);
|
|
93 }
|
|
94
|
|
95 void ThisExp::scanForNestedRef(Scope *sc)
|
|
96 {
|
|
97 assert(var);
|
|
98 var->isVarDeclaration()->checkNestedReference(sc, 0);
|
|
99 }
|
|
100
|
|
101 void SuperExp::scanForNestedRef(Scope *sc)
|
|
102 {
|
|
103 ThisExp::scanForNestedRef(sc);
|
|
104 }
|
|
105
|
|
106 void FuncExp::scanForNestedRef(Scope *sc)
|
|
107 {
|
|
108 //printf("FuncExp::scanForNestedRef(%s)\n", toChars());
|
|
109 //fd->parent = sc->parent;
|
|
110 }
|
|
111
|
|
112 void DeclarationExp::scanForNestedRef(Scope *sc)
|
|
113 {
|
|
114 //printf("DeclarationExp::scanForNestedRef() %s\n", toChars());
|
|
115 declaration->parent = sc->parent;
|
|
116 }
|
|
117
|
|
118 void NewExp::scanForNestedRef(Scope *sc)
|
|
119 {
|
|
120 //printf("NewExp::scanForNestedRef(Scope *sc): %s\n", toChars());
|
|
121
|
|
122 if (thisexp)
|
|
123 thisexp->scanForNestedRef(sc);
|
|
124 arrayExpressionScanForNestedRef(sc, newargs);
|
|
125 arrayExpressionScanForNestedRef(sc, arguments);
|
|
126 }
|
|
127
|
|
128 void UnaExp::scanForNestedRef(Scope *sc)
|
|
129 {
|
|
130 e1->scanForNestedRef(sc);
|
|
131 }
|
|
132
|
|
133 void BinExp::scanForNestedRef(Scope *sc)
|
|
134 {
|
|
135 e1->scanForNestedRef(sc);
|
|
136 e2->scanForNestedRef(sc);
|
|
137 }
|
|
138
|
|
139 void CallExp::scanForNestedRef(Scope *sc)
|
|
140 {
|
|
141 //printf("CallExp::scanForNestedRef(Scope *sc): %s\n", toChars());
|
|
142 e1->scanForNestedRef(sc);
|
|
143 arrayExpressionScanForNestedRef(sc, arguments);
|
|
144 }
|
|
145
|
|
146
|
|
147 void IndexExp::scanForNestedRef(Scope *sc)
|
|
148 {
|
|
149 e1->scanForNestedRef(sc);
|
|
150
|
|
151 if (lengthVar)
|
|
152 { //printf("lengthVar\n");
|
|
153 lengthVar->parent = sc->parent;
|
|
154 }
|
|
155 e2->scanForNestedRef(sc);
|
|
156 }
|
|
157
|
|
158
|
|
159 void SliceExp::scanForNestedRef(Scope *sc)
|
|
160 {
|
|
161 e1->scanForNestedRef(sc);
|
|
162
|
|
163 if (lengthVar)
|
|
164 { //printf("lengthVar\n");
|
|
165 lengthVar->parent = sc->parent;
|
|
166 }
|
|
167 if (lwr)
|
|
168 lwr->scanForNestedRef(sc);
|
|
169 if (upr)
|
|
170 upr->scanForNestedRef(sc);
|
|
171 }
|
|
172
|
|
173
|
|
174 void ArrayLiteralExp::scanForNestedRef(Scope *sc)
|
|
175 {
|
|
176 arrayExpressionScanForNestedRef(sc, elements);
|
|
177 }
|
|
178
|
|
179
|
|
180 void AssocArrayLiteralExp::scanForNestedRef(Scope *sc)
|
|
181 {
|
|
182 arrayExpressionScanForNestedRef(sc, keys);
|
|
183 arrayExpressionScanForNestedRef(sc, values);
|
|
184 }
|
|
185
|
|
186
|
|
187 void StructLiteralExp::scanForNestedRef(Scope *sc)
|
|
188 {
|
|
189 arrayExpressionScanForNestedRef(sc, elements);
|
|
190 }
|
|
191
|
|
192
|
|
193 void TupleExp::scanForNestedRef(Scope *sc)
|
|
194 {
|
|
195 arrayExpressionScanForNestedRef(sc, exps);
|
|
196 }
|
|
197
|
|
198
|
|
199 void ArrayExp::scanForNestedRef(Scope *sc)
|
|
200 {
|
|
201 e1->scanForNestedRef(sc);
|
|
202 arrayExpressionScanForNestedRef(sc, arguments);
|
|
203 }
|
|
204
|
|
205
|
|
206 void CondExp::scanForNestedRef(Scope *sc)
|
|
207 {
|
|
208 econd->scanForNestedRef(sc);
|
|
209 e1->scanForNestedRef(sc);
|
|
210 e2->scanForNestedRef(sc);
|
|
211 }
|
|
212
|
|
213
|
|
214
|