Mercurial > projects > ddmd
annotate dmd/BreakStatement.d @ 192:eb38fdcb3e62 default tip
updated to compile with dmd2.062
author | korDen |
---|---|
date | Sat, 02 Mar 2013 01:25:52 -0800 |
parents | b0d41ff5e0df |
children |
rev | line source |
---|---|
0 | 1 module dmd.BreakStatement; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Statement; |
5 import dmd.Loc; | |
6 import dmd.Identifier; | |
7 import dmd.Scope; | |
8 import dmd.Expression; | |
9 import dmd.InterState; | |
10 import dmd.OutBuffer; | |
11 import dmd.HdrGenState; | |
12 import dmd.IRState; | |
13 import dmd.BE; | |
14 import dmd.FuncDeclaration; | |
15 import dmd.LabelStatement; | |
16 import dmd.ReturnStatement; | |
17 import dmd.IntegerExp; | |
18 | |
19 import dmd.backend.Util; | |
20 import dmd.backend.block; | |
21 import dmd.backend.Blockx; | |
22 import dmd.backend.BC; | |
23 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
24 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
|
25 |
0 | 26 class BreakStatement : Statement |
27 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
28 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
|
29 |
0 | 30 Identifier ident; |
31 | |
32 this(Loc loc, Identifier ident) | |
33 { | |
178 | 34 register(); |
35 | |
0 | 36 super(loc); |
37 this.ident = ident; | |
38 } | |
39 | |
72 | 40 override Statement syntaxCopy() |
0 | 41 { |
53 | 42 BreakStatement s = new BreakStatement(loc, ident); |
43 return s; | |
0 | 44 } |
45 | |
72 | 46 override Statement semantic(Scope sc) |
0 | 47 { |
48 //printf("BreakStatement::semantic()\n"); | |
49 // If: | |
50 // break Identifier; | |
51 if (ident) | |
52 { | |
53 Scope scx; | |
54 FuncDeclaration thisfunc = sc.func; | |
55 | |
56 for (scx = sc; scx; scx = scx.enclosing) | |
57 { | |
58 LabelStatement ls; | |
59 | |
60 if (scx.func != thisfunc) // if in enclosing function | |
61 { | |
62 if (sc.fes) // if this is the body of a foreach | |
63 { | |
64 /* Post this statement to the fes, and replace | |
65 * it with a return value that caller will put into | |
66 * a switch. Caller will figure out where the break | |
67 * label actually is. | |
68 * Case numbers start with 2, not 0, as 0 is continue | |
69 * and 1 is break. | |
70 */ | |
71 Statement s; | |
72 sc.fes.cases.push(cast(void*)this); | |
73 s = new ReturnStatement(Loc(0), new IntegerExp(sc.fes.cases.dim + 1)); | |
74 return s; | |
75 } | |
76 break; // can't break to it | |
77 } | |
78 | |
79 ls = scx.slabel; | |
80 if (ls && ls.ident == ident) | |
81 { | |
82 Statement s = ls.statement; | |
83 | |
84 if (!s.hasBreak()) | |
85 error("label '%s' has no break", ident.toChars()); | |
86 if (ls.tf != sc.tf) | |
87 error("cannot break out of finally block"); | |
88 return this; | |
89 } | |
90 } | |
91 error("enclosing label '%s' for break not found", ident.toChars()); | |
92 } | |
93 else if (!sc.sbreak) | |
94 { | |
95 if (sc.fes) | |
96 { | |
97 Statement s; | |
98 | |
99 // Replace break; with return 1; | |
100 s = new ReturnStatement(Loc(0), new IntegerExp(1)); | |
101 return s; | |
102 } | |
103 error("break is not inside a loop or switch"); | |
104 } | |
105 return this; | |
106 } | |
107 | |
72 | 108 override Expression interpret(InterState istate) |
0 | 109 { |
110 assert(false); | |
111 } | |
112 | |
72 | 113 override BE blockExit() |
0 | 114 { |
115 //printf("BreakStatement::blockExit(%p) = x%x\n", this, ident ? BEgoto : BEbreak); | |
116 return ident ? BE.BEgoto : BE.BEbreak; | |
117 } | |
118 | |
72 | 119 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 120 { |
174 | 121 buf.writestring("break"); |
122 if (ident) | |
123 { | |
124 buf.writebyte(' '); | |
125 buf.writestring(ident.toChars()); | |
126 } | |
127 buf.writebyte(';'); | |
128 buf.writenl(); | |
0 | 129 } |
130 | |
72 | 131 override void toIR(IRState* irs) |
0 | 132 { |
133 block* bbreak; | |
134 block* b; | |
135 Blockx* blx = irs.blx; | |
136 | |
137 bbreak = irs.getBreakBlock(ident); | |
138 assert(bbreak); | |
139 b = blx.curblock; | |
140 incUsage(irs, loc); | |
141 | |
142 // Adjust exception handler scope index if in different try blocks | |
143 if (b.Btry != bbreak.Btry) | |
144 { | |
145 //setScopeIndex(blx, b, bbreak.Btry ? bbreak.Btry.Bscope_index : -1); | |
146 } | |
147 | |
148 /* Nothing more than a 'goto' to the current break destination | |
149 */ | |
150 list_append(&b.Bsucc, bbreak); | |
151 block_next(blx, BCgoto, null); | |
152 } | |
72 | 153 } |