Mercurial > projects > ddmd
annotate dmd/WithStatement.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
rev | line source |
---|---|
0 | 1 module dmd.WithStatement; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Statement; |
5 import dmd.Expression; | |
6 import dmd.VarDeclaration; | |
7 import dmd.Loc; | |
8 import dmd.OutBuffer; | |
129 | 9 import dmd.ScopeDsymbol; |
10 import dmd.TypeExp; | |
11 import dmd.TOK; | |
12 import dmd.Initializer; | |
13 import dmd.ExpInitializer; | |
14 import dmd.Id; | |
15 import dmd.ScopeExp; | |
16 import dmd.WithScopeSymbol; | |
17 import dmd.TY; | |
18 import dmd.Type; | |
0 | 19 import dmd.HdrGenState; |
20 import dmd.InlineScanState; | |
21 import dmd.IRState; | |
22 import dmd.Scope; | |
23 import dmd.BE; | |
24 | |
129 | 25 import dmd.backend.Symbol; |
26 import dmd.backend.block; | |
27 import dmd.backend.Blockx; | |
28 import dmd.backend.elem; | |
29 import dmd.backend.Util; | |
30 import dmd.backend.OPER; | |
31 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
32 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
33 |
0 | 34 class WithStatement : Statement |
35 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
36 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
37 |
0 | 38 Expression exp; |
39 Statement body_; | |
40 VarDeclaration wthis; | |
41 | |
42 this(Loc loc, Expression exp, Statement body_) | |
43 { | |
178 | 44 register(); |
0 | 45 super(loc); |
49 | 46 this.exp = exp; |
47 this.body_ = body_; | |
48 wthis = null; | |
0 | 49 } |
50 | |
72 | 51 override Statement syntaxCopy() |
0 | 52 { |
129 | 53 WithStatement s = new WithStatement(loc, exp.syntaxCopy(), body_ ? body_.syntaxCopy() : null); |
54 return s; | |
0 | 55 } |
56 | |
72 | 57 override Statement semantic(Scope sc) |
0 | 58 { |
129 | 59 ScopeDsymbol sym; |
60 Initializer init; | |
61 | |
62 //printf("WithStatement.semantic()\n"); | |
63 exp = exp.semantic(sc); | |
64 exp = resolveProperties(sc, exp); | |
65 if (exp.op == TOKimport) | |
66 { | |
67 ScopeExp es = cast(ScopeExp)exp; | |
68 | |
69 sym = es.sds; | |
70 } | |
71 else if (exp.op == TOKtype) | |
72 { | |
73 TypeExp es = cast(TypeExp)exp; | |
74 | |
75 sym = es.type.toDsymbol(sc).isScopeDsymbol(); | |
76 if (!sym) | |
77 { | |
78 error("%s has no members", es.toChars()); | |
79 body_ = body_.semantic(sc); | |
80 return this; | |
81 } | |
82 } | |
83 else | |
84 { | |
85 Type t = exp.type; | |
86 | |
87 assert(t); | |
88 t = t.toBasetype(); | |
89 if (t.isClassHandle()) | |
90 { | |
91 init = new ExpInitializer(loc, exp); | |
92 wthis = new VarDeclaration(loc, exp.type, Id.withSym, init); | |
93 wthis.semantic(sc); | |
94 | |
95 sym = new WithScopeSymbol(this); | |
96 sym.parent = sc.scopesym; | |
97 } | |
98 else if (t.ty == Tstruct) | |
99 { | |
100 Expression e = exp.addressOf(sc); | |
101 init = new ExpInitializer(loc, e); | |
102 wthis = new VarDeclaration(loc, e.type, Id.withSym, init); | |
103 wthis.semantic(sc); | |
104 sym = new WithScopeSymbol(this); | |
105 sym.parent = sc.scopesym; | |
106 } | |
107 else | |
108 { | |
109 error("with expressions must be class objects, not '%s'", exp.type.toChars()); | |
110 return null; | |
111 } | |
112 } | |
113 sc = sc.push(sym); | |
114 | |
115 if (body_) | |
116 body_ = body_.semantic(sc); | |
117 | |
118 sc.pop(); | |
119 | |
120 return this; | |
0 | 121 } |
122 | |
72 | 123 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 124 { |
125 assert(false); | |
126 } | |
127 | |
72 | 128 override bool usesEH() |
0 | 129 { |
130 assert(false); | |
131 } | |
132 | |
72 | 133 override BE blockExit() |
0 | 134 { |
129 | 135 BE result = BEnone; |
136 if (exp.canThrow()) | |
137 result = BEthrow; | |
138 if (body_) | |
139 result |= body_.blockExit(); | |
140 else | |
141 result |= BEfallthru; | |
142 return result; | |
0 | 143 } |
144 | |
72 | 145 override Statement inlineScan(InlineScanState* iss) |
0 | 146 { |
147 assert(false); | |
148 } | |
149 | |
72 | 150 override void toIR(IRState* irs) |
0 | 151 { |
129 | 152 Symbol* sp; |
153 elem* e; | |
154 elem* ei; | |
155 ExpInitializer ie; | |
156 Blockx* blx = irs.blx; | |
157 | |
158 //printf("WithStatement.toIR()\n"); | |
159 if (exp.op == TOKimport || exp.op == TOKtype) | |
160 { | |
161 } | |
162 else | |
163 { | |
164 // Declare with handle | |
165 sp = wthis.toSymbol(); | |
166 symbol_add(sp); | |
167 | |
168 // Perform initialization of with handle | |
169 ie = wthis.init.isExpInitializer(); | |
170 assert(ie); | |
171 ei = ie.exp.toElem(irs); | |
172 e = el_var(sp); | |
173 e = el_bin(OPeq,e.Ety, e, ei); | |
174 elem_setLoc(e, loc); | |
175 incUsage(irs, loc); | |
176 block_appendexp(blx.curblock,e); | |
177 } | |
178 // Execute with block | |
179 if (body_) | |
180 body_.toIR(irs); | |
0 | 181 } |
72 | 182 } |