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 }