1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  */
18 /* Generated By:JJTree: Do not edit this line. ASTIfExpr.java */
19 /* JJT: 0.3pre1 */
20 
21 package Mini;
22 import org.apache.bcel.generic.BranchHandle;
23 import org.apache.bcel.generic.ConstantPoolGen;
24 import org.apache.bcel.generic.GOTO;
25 import org.apache.bcel.generic.IFEQ;
26 import org.apache.bcel.generic.InstructionConstants;
27 import org.apache.bcel.generic.InstructionList;
28 import org.apache.bcel.generic.MethodGen;
29 
30 /**
31  *
32  */
33 public class ASTIfExpr extends ASTExpr implements org.apache.bcel.Constants {
34   private ASTExpr if_expr, then_expr, else_expr;
35 
36   // Generated methods
ASTIfExpr(final int id)37   ASTIfExpr(final int id) {
38     super(id);
39   }
40 
ASTIfExpr(final MiniParser p, final int id)41   ASTIfExpr(final MiniParser p, final int id) {
42     super(p, id);
43   }
44 
jjtCreate(final MiniParser p, final int id)45   public static Node jjtCreate(final MiniParser p, final int id) {
46     return new ASTIfExpr(p, id);
47   }
48 
49   /**
50    * Overrides ASTExpr.closeNode()
51    * Cast children nodes Node[] to appropiate type ASTExpr[]
52    */
53   @Override
closeNode()54   public void closeNode() {
55     if_expr = (ASTExpr)children[0];
56     then_expr = (ASTExpr)children[1];
57 
58     if(children.length == 3) {
59         else_expr = (ASTExpr)children[2];
60     } else {
61         MiniC.addError(if_expr.getLine(), if_expr.getColumn(),
62                      "IF expression has no ELSE branch");
63     }
64 
65     children=null; // Throw away
66   }
67 
68   /**
69    * Overrides ASTExpr.traverse()
70    */
71   @Override
traverse(final Environment env)72   public ASTExpr traverse(final Environment env) {
73     this.env = env;
74 
75     if_expr   = if_expr.traverse(env);
76     then_expr = then_expr.traverse(env);
77 
78     if(else_expr != null) {
79         else_expr = else_expr.traverse(env);
80     }
81 
82     return this;
83   }
84 
85   /**
86    * Second pass
87    * Overrides AstExpr.eval()
88    * @return type of expression
89    * @param expected type
90    */
91   @Override
eval(final int expected)92   public int eval(final int expected) {
93     int then_type, else_type, if_type;
94 
95     if((if_type=if_expr.eval(T_BOOLEAN)) != T_BOOLEAN) {
96         MiniC.addError(if_expr.getLine(), if_expr.getColumn(),
97                      "IF expression is not of type boolean, but " +
98                      TYPE_NAMES[if_type] + ".");
99     }
100 
101     then_type=then_expr.eval(expected);
102 
103     if((expected != T_UNKNOWN) && (then_type != expected)) {
104         MiniC.addError(then_expr.getLine(), then_expr.getColumn(),
105                      "THEN expression is not of expected type " +
106                      TYPE_NAMES[expected] + " but " + TYPE_NAMES[then_type] + ".");
107     }
108 
109     if(else_expr != null) {
110       else_type = else_expr.eval(expected);
111 
112       if((expected != T_UNKNOWN) && (else_type != expected)) {
113         MiniC.addError(else_expr.getLine(), else_expr.getColumn(),
114                        "ELSE expression is not of expected type " +
115                        TYPE_NAMES[expected] + " but " + TYPE_NAMES[else_type] + ".");
116     } else if(then_type == T_UNKNOWN) {
117         then_type = else_type;
118         then_expr.setType(else_type);
119       }
120     }
121     else {
122       else_type = then_type;
123       else_expr = then_expr;
124     }
125 
126     if(then_type != else_type) {
127         MiniC.addError(line, column,
128                      "Type mismatch in THEN-ELSE: " +
129                      TYPE_NAMES[then_type] + " vs. " + TYPE_NAMES[else_type] + ".");
130     }
131 
132     type = then_type;
133 
134     is_simple = if_expr.isSimple() && then_expr.isSimple() && else_expr.isSimple();
135 
136     return type;
137   }
138 
139   /**
140    * Fourth pass, produce Java code.
141    */
142   @Override
code(final StringBuffer buf)143   public void code(final StringBuffer buf) {
144     if_expr.code(buf);
145 
146     buf.append("    if(" + ASTFunDecl.pop() + " == 1) {\n");
147     final int size = ASTFunDecl.size;
148     then_expr.code(buf);
149     ASTFunDecl.size = size; // reset stack
150     buf.append("    } else {\n");
151     else_expr.code(buf);
152     buf.append("    }\n");
153   }
154 
155   /**
156    * Fifth pass, produce Java byte code.
157    */
158   @Override
byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp)159   public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
160     if_expr.byte_code(il, method, cp);
161 
162     final InstructionList then_code = new InstructionList();
163     final InstructionList else_code = new InstructionList();
164 
165     then_expr.byte_code(then_code, method, cp);
166     else_expr.byte_code(else_code, method, cp);
167 
168     BranchHandle i, g;
169 
170     i = il.append(new IFEQ(null)); // If POP() == FALSE(i.e. 0) then branch to ELSE
171     ASTFunDecl.pop();
172     il.append(then_code);
173     g = il.append(new GOTO(null));
174     i.setTarget(il.append(else_code));
175     g.setTarget(il.append(InstructionConstants.NOP)); // May be optimized away later
176   }
177 
178   @Override
dump(final String prefix)179   public void dump(final String prefix) {
180     System.out.println(toString(prefix));
181 
182     if_expr.dump(prefix + " ");
183     then_expr.dump(prefix + " ");
184     if(else_expr != null) {
185         else_expr.dump(prefix + " ");
186     }
187   }
188 }
189