• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * @version $Id$
33  */
34 public class ASTIfExpr extends ASTExpr implements org.apache.bcel.Constants {
35   private ASTExpr if_expr, then_expr, else_expr;
36 
37   // Generated methods
ASTIfExpr(int id)38   ASTIfExpr(int id) {
39     super(id);
40   }
41 
ASTIfExpr(MiniParser p, int id)42   ASTIfExpr(MiniParser p, int id) {
43     super(p, id);
44   }
45 
jjtCreate(MiniParser p, int id)46   public static Node jjtCreate(MiniParser p, int id) {
47     return new ASTIfExpr(p, id);
48   }
49 
50   /**
51    * Overrides ASTExpr.closeNode()
52    * Cast children nodes Node[] to appropiate type ASTExpr[]
53    */
54   @Override
closeNode()55   public void closeNode() {
56     if_expr = (ASTExpr)children[0];
57     then_expr = (ASTExpr)children[1];
58 
59     if(children.length == 3) {
60         else_expr = (ASTExpr)children[2];
61     } else {
62         MiniC.addError(if_expr.getLine(), if_expr.getColumn(),
63                      "IF expression has no ELSE branch");
64     }
65 
66     children=null; // Throw away
67   }
68 
69   /**
70    * Overrides ASTExpr.traverse()
71    */
72   @Override
traverse(Environment env)73   public ASTExpr traverse(Environment env) {
74     this.env = env;
75 
76     if_expr   = if_expr.traverse(env);
77     then_expr = then_expr.traverse(env);
78 
79     if(else_expr != null) {
80         else_expr = else_expr.traverse(env);
81     }
82 
83     return this;
84   }
85 
86   /**
87    * Second pass
88    * Overrides AstExpr.eval()
89    * @return type of expression
90    * @param expected type
91    */
92   @Override
eval(int expected)93   public int eval(int expected) {
94     int then_type, else_type, if_type;
95 
96     if((if_type=if_expr.eval(T_BOOLEAN)) != T_BOOLEAN) {
97         MiniC.addError(if_expr.getLine(), if_expr.getColumn(),
98                      "IF expression is not of type boolean, but " +
99                      TYPE_NAMES[if_type] + ".");
100     }
101 
102     then_type=then_expr.eval(expected);
103 
104     if((expected != T_UNKNOWN) && (then_type != expected)) {
105         MiniC.addError(then_expr.getLine(), then_expr.getColumn(),
106                      "THEN expression is not of expected type " +
107                      TYPE_NAMES[expected] + " but " + TYPE_NAMES[then_type] + ".");
108     }
109 
110     if(else_expr != null) {
111       else_type = else_expr.eval(expected);
112 
113       if((expected != T_UNKNOWN) && (else_type != expected)) {
114         MiniC.addError(else_expr.getLine(), else_expr.getColumn(),
115                        "ELSE expression is not of expected type " +
116                        TYPE_NAMES[expected] + " but " + TYPE_NAMES[else_type] + ".");
117     } else if(then_type == T_UNKNOWN) {
118         then_type = else_type;
119         then_expr.setType(else_type);
120       }
121     }
122     else {
123       else_type = then_type;
124       else_expr = then_expr;
125     }
126 
127     if(then_type != else_type) {
128         MiniC.addError(line, column,
129                      "Type mismatch in THEN-ELSE: " +
130                      TYPE_NAMES[then_type] + " vs. " + TYPE_NAMES[else_type] + ".");
131     }
132 
133     type = then_type;
134 
135     is_simple = if_expr.isSimple() && then_expr.isSimple() && else_expr.isSimple();
136 
137     return type;
138   }
139 
140   /**
141    * Fourth pass, produce Java code.
142    */
143   @Override
code(StringBuffer buf)144   public void code(StringBuffer buf) {
145     if_expr.code(buf);
146 
147     buf.append("    if(" + ASTFunDecl.pop() + " == 1) {\n");
148     int size = ASTFunDecl.size;
149     then_expr.code(buf);
150     ASTFunDecl.size = size; // reset stack
151     buf.append("    } else {\n");
152     else_expr.code(buf);
153     buf.append("    }\n");
154   }
155 
156   /**
157    * Fifth pass, produce Java byte code.
158    */
159   @Override
byte_code(InstructionList il, MethodGen method, ConstantPoolGen cp)160   public void byte_code(InstructionList il, MethodGen method, ConstantPoolGen cp) {
161     if_expr.byte_code(il, method, cp);
162 
163     InstructionList then_code = new InstructionList();
164     InstructionList else_code = new InstructionList();
165 
166     then_expr.byte_code(then_code, method, cp);
167     else_expr.byte_code(else_code, method, cp);
168 
169     BranchHandle i, g;
170 
171     i = il.append(new IFEQ(null)); // If POP() == FALSE(i.e. 0) then branch to ELSE
172     ASTFunDecl.pop();
173     il.append(then_code);
174     g = il.append(new GOTO(null));
175     i.setTarget(il.append(else_code));
176     g.setTarget(il.append(InstructionConstants.NOP)); // May be optimized away later
177   }
178 
179   @Override
dump(String prefix)180   public void dump(String prefix) {
181     System.out.println(toString(prefix));
182 
183     if_expr.dump(prefix + " ");
184     then_expr.dump(prefix + " ");
185     if(else_expr != null) {
186         else_expr.dump(prefix + " ");
187     }
188   }
189 }
190