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