1 module d.ast.statement;
2 
3 import d.ast.declaration;
4 import d.ast.expression;
5 
6 import d.common.node;
7 
8 import source.context;
9 
10 class Statement : Node {
11 	this(Location location) {
12 		super(location);
13 	}
14 
15 	string toString(const Context) const {
16 		assert(0, "toString not implement for " ~ typeid(this).toString());
17 	}
18 }
19 
20 final:
21 
22 /**
23  * Blocks
24  */
25 class BlockStatement : Statement {
26 	Statement[] statements;
27 
28 	this(Location location, Statement[] statements) {
29 		super(location);
30 
31 		this.statements = statements;
32 	}
33 }
34 
35 /**
36  * Expressions
37  */
38 class ExpressionStatement : Statement {
39 	AstExpression expression;
40 
41 	this(AstExpression expression) {
42 		super(expression.location);
43 
44 		this.expression = expression;
45 	}
46 }
47 
48 /**
49  * Declarations
50  */
51 class DeclarationStatement : Statement {
52 	Declaration declaration;
53 
54 	this(Declaration declaration) {
55 		super(declaration.location);
56 
57 		this.declaration = declaration;
58 	}
59 }
60 
61 /**
62  * indentifier * identifier kind of things
63  */
64 class IdentifierStarNameStatement : Statement {
65 	import source.name;
66 	Name name;
67 
68 	import d.ast.identifier;
69 	Identifier identifier;
70 	AstExpression value;
71 
72 	this(Location location, Identifier identifier, Name name,
73 	     AstExpression value) {
74 		super(location);
75 
76 		this.identifier = identifier;
77 		this.name = name;
78 		this.value = value;
79 	}
80 }
81 
82 /**
83  * if statements.
84  */
85 class IfStatement : Statement {
86 	AstExpression condition;
87 	Statement then;
88 
89 	// Nullable
90 	Statement elseStatement;
91 
92 	this(Location location, AstExpression condition, Statement then,
93 	     Statement elseStatement) {
94 		super(location);
95 
96 		this.condition = condition;
97 		this.then = then;
98 		this.elseStatement = elseStatement;
99 	}
100 }
101 
102 /**
103  * while statements
104  */
105 class WhileStatement : Statement {
106 	AstExpression condition;
107 	Statement statement;
108 
109 	this(Location location, AstExpression condition, Statement statement) {
110 		super(location);
111 
112 		this.condition = condition;
113 		this.statement = statement;
114 	}
115 }
116 
117 /**
118  * do .. while statements
119  */
120 class DoWhileStatement : Statement {
121 	AstExpression condition;
122 	Statement statement;
123 
124 	this(Location location, AstExpression condition, Statement statement) {
125 		super(location);
126 
127 		this.condition = condition;
128 		this.statement = statement;
129 	}
130 }
131 
132 /**
133  * for statements
134  */
135 class ForStatement : Statement {
136 	Statement initialize;
137 	AstExpression condition;
138 	AstExpression increment;
139 	Statement statement;
140 
141 	this(Location location, Statement initialize, AstExpression condition,
142 	     AstExpression increment, Statement statement) {
143 		super(location);
144 
145 		this.initialize = initialize;
146 		this.condition = condition;
147 		this.increment = increment;
148 		this.statement = statement;
149 	}
150 }
151 
152 /**
153  * foreach statements
154  */
155 class ForeachStatement : Statement {
156 	ParamDecl[] tupleElements;
157 	AstExpression iterated;
158 	Statement statement;
159 	bool reverse;
160 
161 	this(Location location, ParamDecl[] tupleElements, AstExpression iterated,
162 	     Statement statement, bool reverse) {
163 		super(location);
164 
165 		this.tupleElements = tupleElements;
166 		this.iterated = iterated;
167 		this.statement = statement;
168 		this.reverse = reverse;
169 	}
170 }
171 
172 /**
173  * foreach statements
174  */
175 class ForeachRangeStatement : Statement {
176 	ParamDecl[] tupleElements;
177 	AstExpression start;
178 	AstExpression stop;
179 	Statement statement;
180 	bool reverse;
181 
182 	this(Location location, ParamDecl[] tupleElements, AstExpression start,
183 	     AstExpression stop, Statement statement, bool reverse) {
184 		super(location);
185 
186 		this.tupleElements = tupleElements;
187 		this.start = start;
188 		this.stop = stop;
189 		this.statement = statement;
190 		this.reverse = reverse;
191 	}
192 }
193 
194 /**
195  * return statements
196  */
197 class ReturnStatement : Statement {
198 	AstExpression value;
199 
200 	this(Location location, AstExpression value) {
201 		super(location);
202 
203 		this.value = value;
204 	}
205 }
206 
207 /**
208  * switch statements
209  */
210 class SwitchStatement : Statement {
211 	AstExpression expression;
212 	Statement statement;
213 
214 	this(Location location, AstExpression expression, Statement statement) {
215 		super(location);
216 
217 		this.expression = expression;
218 		this.statement = statement;
219 	}
220 }
221 
222 /**
223  * case statements
224  */
225 class CaseStatement : Statement {
226 	AstExpression[] cases;
227 	Statement statement;
228 
229 	this(Location location, AstExpression[] cases, Statement statement) {
230 		super(location);
231 
232 		this.cases = cases;
233 		this.statement = statement;
234 	}
235 }
236 
237 /**
238  * break statements
239  */
240 class BreakStatement : Statement {
241 	this(Location location) {
242 		super(location);
243 	}
244 }
245 
246 /**
247  * continue statements
248  */
249 class ContinueStatement : Statement {
250 	this(Location location) {
251 		super(location);
252 	}
253 }
254 
255 /**
256  * goto statements
257  */
258 class GotoStatement : Statement {
259 	import source.name;
260 	Name label;
261 
262 	this(Location location, Name label) {
263 		super(location);
264 
265 		this.label = label;
266 	}
267 }
268 
269 /**
270  * Label: statement
271  */
272 class LabeledStatement : Statement {
273 	import source.name;
274 	Name label;
275 
276 	Statement statement;
277 
278 	this(Location location, Name label, Statement statement) {
279 		super(location);
280 
281 		this.label = label;
282 		this.statement = statement;
283 	}
284 }
285 
286 /**
287  * synchronized statements
288  */
289 class SynchronizedStatement : Statement {
290 	Statement statement;
291 
292 	this(Location location, Statement statement) {
293 		super(location);
294 
295 		this.statement = statement;
296 	}
297 }
298 
299 /**
300  * Scope statement
301  */
302 enum ScopeKind {
303 	Success,
304 	Exit,
305 	Failure,
306 }
307 
308 class ScopeStatement : Statement {
309 	import std.bitmanip;
310 	mixin(taggedClassRef!(
311 		// sdfmt off
312 		Statement, "statement",
313 		ScopeKind, "kind", 2,
314 		// sdfmt on
315 	));
316 
317 	this(Location location, ScopeKind kind, Statement statement) {
318 		super(location);
319 
320 		this.kind = kind;
321 		this.statement = statement;
322 	}
323 }
324 
325 /**
326  * assert
327  */
328 class AssertStatement : Statement {
329 	AstExpression condition;
330 	AstExpression message;
331 
332 	this(Location location, AstExpression condition, AstExpression message) {
333 		super(location);
334 
335 		this.condition = condition;
336 		this.message = message;
337 	}
338 
339 	override string toString(const Context c) const {
340 		auto cstr = condition.toString(c);
341 		auto mstr = message ? ", " ~ message.toString(c) : "";
342 
343 		return "assert(" ~ cstr ~ mstr ~ ")";
344 	}
345 }
346 
347 /**
348  * throw statements
349  */
350 class ThrowStatement : Statement {
351 	AstExpression value;
352 
353 	this(Location location, AstExpression value) {
354 		super(location);
355 
356 		this.value = value;
357 	}
358 }
359 
360 /**
361  * try statements
362  */
363 class TryStatement : Statement {
364 	Statement statement;
365 	CatchBlock[] catches;
366 
367 	// nullable
368 	Statement finallyBlock;
369 
370 	this(Location location, Statement statement, CatchBlock[] catches,
371 	     Statement finallyBlock) {
372 		super(location);
373 
374 		this.statement = statement;
375 		this.catches = catches;
376 		this.finallyBlock = finallyBlock;
377 	}
378 }
379 
380 struct CatchBlock {
381 	Location location;
382 
383 	import source.name;
384 	Name name;
385 
386 	import d.ast.identifier;
387 	Identifier type;
388 	Statement statement;
389 
390 	this(Location location, Identifier type, Name name, Statement statement) {
391 		this.location = location;
392 		this.name = name;
393 		this.type = type;
394 		this.statement = statement;
395 	}
396 }