/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* Generated By:JJTree: Do not edit this line. ASTIfExpr.java */ /* JJT: 0.3pre1 */ package Mini; import org.apache.bcel.generic.BranchHandle; import org.apache.bcel.generic.ConstantPoolGen; import org.apache.bcel.generic.GOTO; import org.apache.bcel.generic.IFEQ; import org.apache.bcel.generic.InstructionConstants; import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.MethodGen; /** * * @version $Id: ASTIfExpr.java 1152313 2011-07-29 17:31:23Z sebb $ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> */ public class ASTIfExpr extends ASTExpr implements org.apache.bcel.Constants { private ASTExpr if_expr, then_expr, else_expr; // Generated methods ASTIfExpr(int id) { super(id); } ASTIfExpr(MiniParser p, int id) { super(p, id); } public static Node jjtCreate(MiniParser p, int id) { return new ASTIfExpr(p, id); } /** * Overrides ASTExpr.closeNode() * Cast children nodes Node[] to appropiate type ASTExpr[] */ @Override public void closeNode() { if_expr = (ASTExpr)children[0]; then_expr = (ASTExpr)children[1]; if(children.length == 3) { else_expr = (ASTExpr)children[2]; } else { MiniC.addError(if_expr.getLine(), if_expr.getColumn(), "IF expression has no ELSE branch"); } children=null; // Throw away } /** * Overrides ASTExpr.traverse() */ @Override public ASTExpr traverse(Environment env) { this.env = env; if_expr = if_expr.traverse(env); then_expr = then_expr.traverse(env); if(else_expr != null) { else_expr = else_expr.traverse(env); } return this; } /** * Second pass * Overrides AstExpr.eval() * @return type of expression * @param expected type */ @Override public int eval(int expected) { int then_type, else_type, if_type; if((if_type=if_expr.eval(T_BOOLEAN)) != T_BOOLEAN) { MiniC.addError(if_expr.getLine(), if_expr.getColumn(), "IF expression is not of type boolean, but " + TYPE_NAMES[if_type] + "."); } then_type=then_expr.eval(expected); if((expected != T_UNKNOWN) && (then_type != expected)) { MiniC.addError(then_expr.getLine(), then_expr.getColumn(), "THEN expression is not of expected type " + TYPE_NAMES[expected] + " but " + TYPE_NAMES[then_type] + "."); } if(else_expr != null) { else_type = else_expr.eval(expected); if((expected != T_UNKNOWN) && (else_type != expected)) { MiniC.addError(else_expr.getLine(), else_expr.getColumn(), "ELSE expression is not of expected type " + TYPE_NAMES[expected] + " but " + TYPE_NAMES[else_type] + "."); } else if(then_type == T_UNKNOWN) { then_type = else_type; then_expr.setType(else_type); } } else { else_type = then_type; else_expr = then_expr; } if(then_type != else_type) { MiniC.addError(line, column, "Type mismatch in THEN-ELSE: " + TYPE_NAMES[then_type] + " vs. " + TYPE_NAMES[else_type] + "."); } type = then_type; is_simple = if_expr.isSimple() && then_expr.isSimple() && else_expr.isSimple(); return type; } /** * Fourth pass, produce Java code. */ @Override public void code(StringBuffer buf) { if_expr.code(buf); buf.append(" if(" + ASTFunDecl.pop() + " == 1) {\n"); int size = ASTFunDecl.size; then_expr.code(buf); ASTFunDecl.size = size; // reset stack buf.append(" } else {\n"); else_expr.code(buf); buf.append(" }\n"); } /** * Fifth pass, produce Java byte code. */ @Override public void byte_code(InstructionList il, MethodGen method, ConstantPoolGen cp) { if_expr.byte_code(il, method, cp); InstructionList then_code = new InstructionList(); InstructionList else_code = new InstructionList(); then_expr.byte_code(then_code, method, cp); else_expr.byte_code(else_code, method, cp); BranchHandle i, g; i = il.append(new IFEQ(null)); // If POP() == FALSE(i.e. 0) then branch to ELSE ASTFunDecl.pop(); il.append(then_code); g = il.append(new GOTO(null)); i.setTarget(il.append(else_code)); g.setTarget(il.append(InstructionConstants.NOP)); // May be optimized away later } @Override public void dump(String prefix) { System.out.println(toString(prefix)); if_expr.dump(prefix + " "); then_expr.dump(prefix + " "); if(else_expr != null) { else_expr.dump(prefix + " "); } } }