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