Mercurial > projects > ddmd
annotate dmd/LabelStatement.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.LabelStatement; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Statement; |
5 import dmd.Identifier; | |
6 import dmd.TryFinallyStatement; | |
7 import dmd.Scope; | |
8 import dmd.Loc; | |
9 import dmd.ExpStatement; | |
10 import dmd.ArrayTypes; | |
11 import dmd.Expression; | |
12 import dmd.InterState; | |
13 import dmd.InlineScanState; | |
14 import dmd.LabelDsymbol; | |
15 import dmd.FuncDeclaration; | |
16 import dmd.CSX; | |
17 import dmd.IRState; | |
18 import dmd.OutBuffer; | |
19 import dmd.HdrGenState; | |
20 import dmd.BE; | |
21 | |
22 import dmd.backend.block; | |
23 import dmd.backend.Blockx; | |
24 import dmd.backend.Util; | |
25 import dmd.backend.BC; | |
26 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
27 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
|
28 |
0 | 29 class LabelStatement : Statement |
30 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
31 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
|
32 |
0 | 33 Identifier ident; |
34 Statement statement; | |
35 TryFinallyStatement tf = null; | |
36 block* lblock = null; // back end | |
37 int isReturnLabel = 0; | |
38 | |
39 this(Loc loc, Identifier ident, Statement statement) | |
40 { | |
178 | 41 register(); |
0 | 42 super(loc); |
43 this.ident = ident; | |
44 this.statement = statement; | |
45 } | |
46 | |
72 | 47 override Statement syntaxCopy() |
0 | 48 { |
49 LabelStatement s = new LabelStatement(loc, ident, statement.syntaxCopy()); | |
50 return s; | |
51 } | |
52 | |
72 | 53 override Statement semantic(Scope sc) |
0 | 54 { |
55 LabelDsymbol ls; | |
56 FuncDeclaration fd = sc.parent.isFuncDeclaration(); | |
57 | |
58 //printf("LabelStatement.semantic()\n"); | |
59 ls = fd.searchLabel(ident); | |
60 if (ls.statement) | |
61 error("Label '%s' already defined", ls.toChars()); | |
62 else | |
63 ls.statement = this; | |
64 tf = sc.tf; | |
65 sc = sc.push(); | |
66 sc.scopesym = sc.enclosing.scopesym; | |
67 sc.callSuper |= CSXlabel; | |
68 sc.slabel = this; | |
69 if (statement) | |
70 statement = statement.semantic(sc); | |
71 sc.pop(); | |
72 return this; | |
73 } | |
74 | |
72 | 75 override Statements flatten(Scope sc) |
0 | 76 { |
77 Statements a = null; | |
78 | |
79 if (statement) | |
80 { | |
81 a = statement.flatten(sc); | |
82 if (a) | |
83 { | |
84 if (!a.dim) | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
85 a.push(new ExpStatement(loc, null)); |
0 | 86 |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
87 Statement s = a[0]; |
0 | 88 |
89 s = new LabelStatement(loc, ident, s); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
90 a[0] = s; |
0 | 91 } |
92 } | |
93 | |
94 return a; | |
95 } | |
96 | |
72 | 97 override bool usesEH() |
0 | 98 { |
99 return statement ? statement.usesEH() : false; | |
100 } | |
101 | |
72 | 102 override BE blockExit() |
0 | 103 { |
104 //printf("LabelStatement.blockExit(%p)\n", this); | |
105 return statement ? statement.blockExit() : BE.BEfallthru; | |
106 } | |
107 | |
72 | 108 override bool comeFrom() |
0 | 109 { |
110 //printf("LabelStatement.comeFrom()\n"); | |
111 return true; | |
112 } | |
113 | |
72 | 114 override Expression interpret(InterState istate) |
0 | 115 { |
116 assert(false); | |
117 } | |
118 | |
72 | 119 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 120 { |
121 buf.writestring(ident.toChars()); | |
122 buf.writebyte(':'); | |
123 buf.writenl(); | |
124 if (statement) | |
125 statement.toCBuffer(buf, hgs); | |
126 } | |
127 | |
72 | 128 override Statement inlineScan(InlineScanState* iss) |
0 | 129 { |
130 if (statement) | |
131 statement = statement.inlineScan(iss); | |
132 return this; | |
133 } | |
134 | |
72 | 135 override void toIR(IRState* irs) |
0 | 136 { |
137 //printf("LabelStatement.toIR() %p, statement = %p\n", this, statement); | |
138 Blockx* blx = irs.blx; | |
139 block* bc = blx.curblock; | |
140 IRState mystate = IRState(irs,this); | |
141 mystate.ident = ident; | |
142 | |
143 if (lblock) | |
144 { | |
145 // We had made a guess about which tryblock the label is in. | |
146 // Error if we guessed wrong. | |
147 // BUG: should fix this | |
148 if (lblock.Btry != blx.tryblock) | |
149 error("cannot goto forward into different try block level"); | |
150 } | |
151 else | |
152 lblock = block_calloc(blx); | |
153 | |
154 block_next(blx,BCgoto,lblock); | |
155 list_append(&bc.Bsucc,blx.curblock); | |
156 if (statement) | |
157 statement.toIR(&mystate); | |
158 } | |
72 | 159 } |