logo
class

compiler::NopStmt

sys::Obj
  compiler::Node
    compiler::Stmt
      compiler::NopStmt
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   19 Jul 06  Brian Frank  Creation
   7  //
   8  
   9  **
  10  ** Stmt
  11  **
  12  abstract class Stmt : Node
  13  {
  14  
  15  //////////////////////////////////////////////////////////////////////////
  16  // Construction
  17  //////////////////////////////////////////////////////////////////////////
  18  
  19    new make(Location location, StmtId id)
  20      : super(location)
  21    {
  22      this.id = id
  23    }
  24  
  25  //////////////////////////////////////////////////////////////////////////
  26  // Stmt
  27  //////////////////////////////////////////////////////////////////////////
  28  
  29    **
  30    ** Does this statement always cause us to exit the method (or does it
  31    ** cause us to loop forever without a break to the next statement)
  32    **
  33    abstract Bool isExit()
  34  
  35  //////////////////////////////////////////////////////////////////////////
  36  // Tree
  37  //////////////////////////////////////////////////////////////////////////
  38  
  39    Void walk(Visitor v, VisitDepth depth)
  40    {
  41      v.enterStmt(this)
  42      walkChildren(v, depth)
  43      v.visitStmt(this)
  44      v.exitStmt(this)
  45    }
  46  
  47    virtual Void walkChildren(Visitor v, VisitDepth depth)
  48    {
  49    }
  50  
  51    static Expr walkExpr(Visitor v, VisitDepth depth, Expr expr)
  52    {
  53      if (depth === VisitDepth.expr && expr != null)
  54        return expr.walk(v)
  55      else
  56        return expr
  57    }
  58  
  59  //////////////////////////////////////////////////////////////////////////
  60  // Fields
  61  //////////////////////////////////////////////////////////////////////////
  62  
  63    readonly StmtId id
  64  
  65  }
  66  
  67  **************************************************************************
  68  ** NopStmt
  69  **************************************************************************
  70  
  71  **
  72  ** NopStmt is no operation do nothing statement.
  73  **
  74  class NopStmt : Stmt
  75  {
  76    new make(Location location) : super(location, StmtId.nop) {}
  77  
  78    override Bool isExit() { return false }
  79  
  80    override Void print(AstWriter out)
  81    {
  82      out.w("nop").nl
  83    }
  84  }
  85  
  86  **************************************************************************
  87  ** ExprStmt
  88  **************************************************************************
  89  
  90  **
  91  ** ExprStmt is a statement with a stand along expression such
  92  ** as an assignment or method call.
  93  **
  94  class ExprStmt : Stmt
  95  {
  96    new make(Expr expr)
  97      : super(expr.location, StmtId.expr)
  98    {
  99      this.expr = expr
 100    }
 101  
 102    override Bool isExit() { return false }
 103  
 104    override Void walkChildren(Visitor v, VisitDepth depth)
 105    {
 106      expr = walkExpr(v, depth, expr)
 107    }
 108  
 109    override Void print(AstWriter out)
 110    {
 111      printOpt(out)
 112    }
 113  
 114    Void printOpt(AstWriter out, Bool nl := true)
 115    {
 116      expr.print(out)
 117      if (nl) out.nl
 118    }
 119  
 120    Expr expr
 121  }
 122  
 123  **************************************************************************
 124  ** LocalDefStmt
 125  **************************************************************************
 126  
 127  **
 128  ** LocalDefStmt models a local variable declaration and its
 129  ** optional initialization expression.
 130  **
 131  class LocalDefStmt : Stmt
 132  {
 133    new make(Location location)
 134      : super(location, StmtId.localDef)
 135    {
 136      isCatchVar = false
 137    }
 138  
 139    override Bool isExit() { return false }
 140  
 141    override Void walkChildren(Visitor v, VisitDepth depth)
 142    {
 143      init = walkExpr(v, depth, init)
 144    }
 145  
 146    new makeCatchVar(Catch c)
 147      : super.make(c.location, StmtId.localDef)
 148    {
 149      ctype = c.errType
 150      name  = c.errVariable
 151      isCatchVar = true
 152    }
 153  
 154    override Void print(AstWriter out) { printOpt(out) }
 155  
 156    Void printOpt(AstWriter out, Bool nl := true)
 157    {
 158      if (ctype != null) out.w("$ctype ")
 159      out.w(name)
 160      if (init != null) out.w(" init: $init")
 161      if (nl) out.nl
 162    }
 163  
 164    CType ctype       // type of the variable (or null if inferred)
 165    Str name          // variable name
 166    Expr init         // rhs of init; in ResolveExpr it becomes full assign expr
 167    Bool isCatchVar   // is this auto-generated var for "catch (Err x)"
 168    MethodVar var     // variable binding
 169  }
 170  
 171  **************************************************************************
 172  ** IfStmt
 173  **************************************************************************
 174  
 175  **
 176  ** IfStmt models an if or if/else statement.
 177  **
 178  class IfStmt : Stmt
 179  {
 180    new make(Location location) : super(location, StmtId.ifStmt) {}
 181  
 182    override Bool isExit()
 183    {
 184      if (falseBlock == null) return false
 185      return trueBlock.isExit && falseBlock.isExit
 186    }
 187  
 188    override Void walkChildren(Visitor v, VisitDepth depth)
 189    {
 190      condition = walkExpr(v, depth, condition)
 191      trueBlock.walk(v, depth)
 192      if (falseBlock != null) falseBlock.walk(v, depth)
 193    }
 194  
 195    override Void print(AstWriter out)
 196    {
 197      out.w("if ($condition)").nl
 198      trueBlock.print(out)
 199      if (falseBlock != null)
 200      {
 201        out.w("else").nl
 202        falseBlock.print(out)
 203      }
 204    }
 205  
 206    Expr condition      // test expression
 207    Block trueBlock     // block to execute if condition true
 208    Block falseBlock    // else clause or null
 209  }
 210  
 211  **************************************************************************
 212  ** ReturnStmt
 213  **************************************************************************
 214  
 215  **
 216  ** ReturnStmt returns from the method
 217  **
 218  class ReturnStmt : Stmt
 219  {
 220    new make(Location location, Expr expr := null)
 221      : super(location, StmtId.returnStmt)
 222    {
 223      this.expr = expr
 224    }
 225  
 226    override Bool isExit() { return true }
 227  
 228    override Void walkChildren(Visitor v, VisitDepth depth)
 229    {
 230      expr = walkExpr(v, depth, expr)
 231    }
 232  
 233    override Void print(AstWriter out)
 234    {
 235      out.w("return")
 236      if (expr != null) out.w(" $expr")
 237      out.nl
 238    }
 239  
 240  
 241    Expr expr           // expr to return of null if void return
 242    MethodVar leaveVar  // to stash result for leave from protected region
 243  }
 244  
 245  **************************************************************************
 246  ** ThrowStmt
 247  **************************************************************************
 248  
 249  **
 250  ** ThrowStmt throws an exception
 251  **
 252  class ThrowStmt : Stmt
 253  {
 254    new make(Location location) : super(location, StmtId.throwStmt) {}
 255  
 256    override Bool isExit() { return true }
 257  
 258    override Void walkChildren(Visitor v, VisitDepth depth)
 259    {
 260      exception = walkExpr(v, depth, exception)
 261    }
 262  
 263    override Void print(AstWriter out)
 264    {
 265      out.w("throw $exception").nl
 266    }
 267  
 268    Expr exception   // exception to throw
 269  }
 270  
 271  **************************************************************************
 272  ** ForStmt
 273  **************************************************************************
 274  
 275  **
 276  ** ForStmt models a for loop of the format:
 277  **   for (init; condition; update) block
 278  **
 279  class ForStmt : Stmt
 280  {
 281    new make(Location location) : super(location, StmtId.forStmt) {}
 282  
 283    override Bool isExit()
 284    {
 285      return false
 286    }
 287  
 288    override Void walkChildren(Visitor v, VisitDepth depth)
 289    {
 290      if (init != null) init.walk(v, depth)
 291      condition = walkExpr(v, depth, condition)
 292      update = walkExpr(v, depth, update)
 293      block.walk(v, depth)
 294    }
 295  
 296    override Void print(AstWriter out)
 297    {
 298      out.w("for (")
 299      if (init != null) init->printOpt(out, false)
 300      out.w("; ")
 301      if (condition != null) condition.print(out)
 302      out.w("; ")
 303      if (update != null) update.print(out)
 304      out.w(")").nl
 305      block.print(out)
 306    }
 307  
 308    Stmt init         // loop initialization
 309    Expr condition    // loop condition
 310    Expr update       // loop update
 311    Block block       // code to run inside loop
 312  }
 313  
 314  **************************************************************************
 315  ** WhileStmt
 316  **************************************************************************
 317  
 318  **
 319  ** WhileStmt models a while loop of the format:
 320  **   while (condition) block
 321  **
 322  class WhileStmt : Stmt
 323  {
 324    new make(Location location) : super(location, StmtId.whileStmt) {}
 325  
 326    override Bool isExit()
 327    {
 328      return false
 329    }
 330  
 331    override Void walkChildren(Visitor v, VisitDepth depth)
 332    {
 333      condition = walkExpr(v, depth, condition)
 334      block.walk(v, depth)
 335    }
 336  
 337    override Void print(AstWriter out)
 338    {
 339      out.w("while ($condition)").nl
 340      block.print(out)
 341    }
 342  
 343    Expr condition     // loop condition
 344    Block block        // code to run inside loop
 345  }
 346  
 347  **************************************************************************
 348  ** BreakStmt
 349  **************************************************************************
 350  
 351  **
 352  ** BreakStmt breaks out of a while/for loop.
 353  **
 354  class BreakStmt : Stmt
 355  {
 356    new make(Location location) : super(location, StmtId.breakStmt) {}
 357  
 358    override Bool isExit() { return false }
 359  
 360    override Void print(AstWriter out)
 361    {
 362      out.w("break").nl
 363    }
 364  
 365     Stmt loop   // loop to break out of
 366  }
 367  
 368  **************************************************************************
 369  ** ContinueStmt
 370  **************************************************************************
 371  
 372  **
 373  ** ContinueStmt continues a while/for loop.
 374  **
 375  class ContinueStmt : Stmt
 376  {
 377    new make(Location location) : super(location, StmtId.continueStmt) {}
 378  
 379    override Bool isExit() { return false }
 380  
 381    override Void print(AstWriter out)
 382    {
 383      out.w("continue").nl
 384    }
 385  
 386    Stmt loop   // loop to continue
 387  }
 388  
 389  **************************************************************************
 390  ** TryStmt
 391  **************************************************************************
 392  
 393  **
 394  ** TryStmt models a try/catch/finally block
 395  **
 396  class TryStmt : Stmt
 397  {
 398    new make(Location location)
 399      : super(location, StmtId.tryStmt)
 400    {
 401      catches = Catch[,]
 402    }
 403  
 404    override Bool isExit()
 405    {
 406      if (!block.isExit) return false
 407      return catches.all |Catch c->Bool| { return c.block.isExit }
 408    }
 409  
 410    override Void walkChildren(Visitor v, VisitDepth depth)
 411    {
 412      block.walk(v, depth)
 413      catches.each |Catch c| { c.block.walk(v, depth) }
 414      if (finallyBlock != null)
 415      {
 416        v.enterFinally(this)
 417        finallyBlock.walk(v, depth)
 418        v.exitFinally(this)
 419      }
 420    }
 421  
 422    override Void print(AstWriter out)
 423    {
 424      out.w("try").nl
 425      block.print(out)
 426      catches.each |Catch c| { c.print(out) }
 427      if (finallyBlock != null)
 428      {
 429        out.w("finally").nl
 430        finallyBlock.print(out)
 431      }
 432    }
 433  
 434    Expr exception      // expression which leaves exception on stack
 435    Block block         // body of try block
 436    Catch[] catches     // list of catch clauses
 437    Block finallyBlock  // body of finally block or null
 438  }
 439  
 440  **
 441  ** Catch models a single catch clause of a TryStmt
 442  **
 443  class Catch : Node
 444  {
 445    new make(Location location) : super(location) {}
 446  
 447    override Void print(AstWriter out)
 448    {
 449      out.w("catch")
 450      if (errType != null) out.w("($errType $errVariable)")
 451      out.nl
 452      block.print(out)
 453    }
 454  
 455    TypeRef errType      // Err type to catch or null for catch-all
 456    Str errVariable      // name of err local variable
 457    Block block          // body of catch block
 458    Int start            // start offset generated in CodeAsm
 459    Int end              // end offset generated in CodeAsm
 460  }
 461  
 462  **************************************************************************
 463  ** SwitchStmt
 464  **************************************************************************
 465  
 466  **
 467  ** SwitchStmt models a switch and its case and default block
 468  **
 469  class SwitchStmt : Stmt
 470  {
 471    new make(Location location)
 472      : super(location, StmtId.switchStmt)
 473    {
 474      cases = Case[,]
 475    }
 476  
 477    override Bool isExit()
 478    {
 479      if (defaultBlock == null) return false
 480      if (!defaultBlock.isExit) return false
 481      return cases.all |Case c->Bool| { return c.block.isExit }
 482    }
 483  
 484    override Void walkChildren(Visitor v, VisitDepth depth)
 485    {
 486      condition = walkExpr(v, depth, condition)
 487      cases.each |Case c| { c.walk(v, depth) }
 488      if (defaultBlock != null) defaultBlock.walk(v, depth)
 489    }
 490  
 491    override Void print(AstWriter out)
 492    {
 493      out.w("switch ($condition)").nl
 494      out.w("{").nl
 495      out.indent
 496      cases.each |Case c| { c.print(out) }
 497      if (defaultBlock != null)
 498      {
 499        out.w("default:").nl
 500        out.indent
 501        defaultBlock.printOpt(out, false)
 502        out.unindent
 503      }
 504      out.unindent
 505      out.w("}").nl
 506    }
 507  
 508    Expr condition        // test expression
 509    Case[] cases          // list of case blocks
 510    Block defaultBlock    // default block (or null)
 511    Bool isTableswitch    // just for testing
 512  }
 513  
 514  **
 515  ** Case models a single case block of a SwitchStmt
 516  **
 517  class Case : Node
 518  {
 519    new make(Location location)
 520      : super(location)
 521    {
 522      cases = Expr[,]
 523    }
 524  
 525    Void walk(Visitor v, VisitDepth depth)
 526    {
 527      if (depth === VisitDepth.expr)
 528        cases = Expr.walkExprs(v, cases)
 529  
 530      block.walk(v, depth)
 531    }
 532  
 533    override Void print(AstWriter out)
 534    {
 535      cases.each |Expr c| { out.w("case $c:").nl }
 536      out.indent
 537      if (block != null) block.printOpt(out, false)
 538      out.unindent
 539    }
 540  
 541    Expr[] cases     // list of case target (literal expressions)
 542    Block block      // code to run for case
 543    Int startOffset  // start offset for CodeAsm
 544  }
 545  
 546  **************************************************************************
 547  ** StmtId
 548  **************************************************************************
 549  
 550  enum StmtId
 551  {
 552    nop,
 553    expr,
 554    localDef,
 555    ifStmt,
 556    returnStmt,
 557    throwStmt,
 558    forStmt,
 559    whileStmt,
 560    breakStmt,
 561    continueStmt,
 562    tryStmt,
 563    switchStmt
 564  }

More Info

Slots