1   // Copyright 2013 Bill Campbell, Swami Iyer and Bahar Akbal-Delibas
2   
3   package jminusminus;
4   
5   import static jminusminus.CLConstants.*;
6   
7   /**
8    * The AST node for a while-statement.
9    */
10  
11  class JWhileStatement extends JStatement {
12  
13      /** Test expression. */
14      private JExpression condition;
15  
16      /** The body. */
17      private JStatement body;
18  
19      /**
20       * Construct an AST node for a while-statement given its line number, the
21       * test expression, and the body.
22       * 
23       * @param line
24       *            line in which the while-statement occurs in the source file.
25       * @param condition
26       *            test expression.
27       * @param body
28       *            the body.
29       */
30  
31      public JWhileStatement(int line, JExpression condition, JStatement body) {
32          super(line);
33          this.condition = condition;
34          this.body = body;
35      }
36  
37      /**
38       * Analysis involves analyzing the test, checking its type and analyzing the
39       * body statement.
40       * 
41       * @param context
42       *            context in which names are resolved.
43       * @return the analyzed (and possibly rewritten) AST subtree.
44       */
45  
46      public JWhileStatement analyze(Context context) {
47          condition = condition.analyze(context);
48          condition.type().mustMatchExpected(line(), Type.BOOLEAN);
49          body = (JStatement) body.analyze(context);
50          return this;
51      }
52  
53      /**
54       * Generate code for the while loop.
55       * 
56       * @param output
57       *            the code emitter (basically an abstraction for producing the
58       *            .class file).
59       */
60  
61      public void codegen(CLEmitter output) {
62          // Need two labels
63          String test = output.createLabel();
64          String out = output.createLabel();
65  
66          // Branch out of the loop on the test condition
67          // being false
68          output.addLabel(test);
69          condition.codegen(output, out, false);
70  
71          // Codegen body
72          body.codegen(output);
73  
74          // Unconditional jump back up to test
75          output.addBranchInstruction(GOTO, test);
76  
77          // The label below and outside the loop
78          output.addLabel(out);
79      }
80  
81      /**
82       * @inheritDoc
83       */
84  
85      public void writeToStdOut(PrettyPrinter p) {
86          p.printf("<JWhileStatement line=\"%d\">\n", line());
87          p.indentRight();
88          p.printf("<TestExpression>\n");
89          p.indentRight();
90          condition.writeToStdOut(p);
91          p.indentLeft();
92          p.printf("</TestExpression>\n");
93          p.printf("<Body>\n");
94          p.indentRight();
95          body.writeToStdOut(p);
96          p.indentLeft();
97          p.printf("</Body>\n");
98          p.indentLeft();
99          p.printf("</JWhileStatement>\n");
100     }
101 
102 }
103