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