1   // Copyright 2013 Bill Campbell, Swami Iyer and Bahar Akbal-Delibas
2   
3   package jminusminus;
4   
5   import java.util.ArrayList;
6   
7   /**
8    * The AST node for a block, which delimits a nested level of scope.
9    */
10  
11  class JBlock extends JStatement {
12  
13      /** List of statements forming the block body. */
14      private ArrayList<JStatement> statements;
15  
16      /**
17       * The new context (built in analyze()) represented by this block.
18       */
19      private LocalContext context;
20  
21      /**
22       * Construct an AST node for a block given its line number, and the list of
23       * statements forming the block body.
24       * 
25       * @param line
26       *            line in which the block occurs in the source file.
27       * @param statements
28       *            list of statements forming the block body.
29       */
30  
31      public JBlock(int line, ArrayList<JStatement> statements) {
32          super(line);
33          this.statements = statements;
34      }
35  
36      /**
37       * Return the list of statements comprising the block.
38       * 
39       * @return list of statements.
40       */
41  
42      public ArrayList<JStatement> statements() {
43          return statements;
44      }
45  
46      /**
47       * Analyzing a block consists of creating a new nested context for that
48       * block and analyzing each of its statements within that context.
49       * 
50       * @param context
51       *            context in which names are resolved.
52       * @return the analyzed (and possibly rewritten) AST subtree.
53       */
54  
55      public JBlock analyze(Context context) {
56          // { ... } defines a new level of scope.
57          this.context = new LocalContext(context);
58  
59          for (int i = 0; i < statements.size(); i++) {
60              statements.set(i, (JStatement) statements.get(i).analyze(
61                      this.context));
62          }
63          return this;
64      }
65  
66      /**
67       * Generating code for a block consists of generating code for each of its
68       * statements.
69       * 
70       * @param output
71       *            the code emitter (basically an abstraction for producing the
72       *            .class file).
73       */
74  
75      public void codegen(CLEmitter output) {
76          for (JStatement statement : statements) {
77              statement.codegen(output);
78          }
79      }
80  
81      /**
82       * @inheritDoc
83       */
84  
85      public void writeToStdOut(PrettyPrinter p) {
86          p.printf("<JBlock line=\"%d\">\n", line());
87          if (context != null) {
88              p.indentRight();
89              context.writeToStdOut(p);
90              p.indentLeft();
91          }
92          for (JStatement statement : statements) {
93              p.indentRight();
94              statement.writeToStdOut(p);
95              p.indentLeft();
96          }
97          p.printf("</JBlock>\n");
98      }
99  
100 }
101