| /* Generated By:JJTree: Do not edit this line. ASTIfExpr.java */ |
| /* JJT: 0.3pre1 */ |
| |
| package Mini; |
| import org.apache.bcel.classfile.*; |
| import org.apache.bcel.generic.*; |
| |
| /** |
| * |
| * @version $Id$ |
| * @author <A HREF="http://www.berlin.de/~markus.dahm/">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[] |
| */ |
| public void closeNode() { |
| if_expr = (ASTExpr)children[0]; |
| then_expr = (ASTExpr)children[1]; |
| |
| if(children.length == 3) // has else branch |
| 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() |
| */ |
| 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 |
| */ |
| 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. |
| */ |
| 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. |
| */ |
| 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 |
| } |
| |
| 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 + " "); |
| } |
| } |