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