blob: 38cb951f4b44b8f423b86474d6d3c7e567ba7eb7 [file] [log] [blame]
/*
* 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
*
* https://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.Const;
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.InstructionConst;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
/**
*/
public class ASTIfExpr extends ASTExpr {
public static Node jjtCreate(final MiniParser p, final int id) {
return new ASTIfExpr(p, id);
}
private ASTExpr if_expr, then_expr, else_expr;
// Generated methods
ASTIfExpr(final int id) {
super(id);
}
ASTIfExpr(final MiniParser p, final int id) {
super(p, id);
}
/**
* Fifth pass, produce Java byte code.
*/
@Override
public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
if_expr.byte_code(il, method, cp);
final InstructionList then_code = new InstructionList();
final 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(for example 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(InstructionConst.NOP)); // May be optimized away later
}
/**
* Overrides ASTExpr.closeNode() Cast children nodes Node[] to appropriate 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
}
/**
* Fourth pass, produce Java code.
*/
@Override
public void code(final StringBuffer buf) {
if_expr.code(buf);
buf.append(" if(" + ASTFunDecl.pop() + " == 1) {\n");
final int size = ASTFunDecl.size;
then_expr.code(buf);
ASTFunDecl.size = size; // reset stack
buf.append(" } else {\n");
else_expr.code(buf);
buf.append(" }\n");
}
@Override
public void dump(final String prefix) {
System.out.println(toString(prefix));
if_expr.dump(prefix + " ");
then_expr.dump(prefix + " ");
if (else_expr != null) {
else_expr.dump(prefix + " ");
}
}
/**
* Second pass Overrides AstExpr.eval().
*
* @return type of expression.
* @param expected type.
*/
@Override
public int eval(final int expected) {
int thenType, elseType, ifType;
if ((ifType = if_expr.eval(Const.T_BOOLEAN)) != Const.T_BOOLEAN) {
MiniC.addError(if_expr.getLine(), if_expr.getColumn(), "IF expression is not of type boolean, but " + Const.getTypeName(ifType) + ".");
}
thenType = then_expr.eval(expected);
if (expected != Const.T_UNKNOWN && thenType != expected) {
MiniC.addError(then_expr.getLine(), then_expr.getColumn(),
"THEN expression is not of expected type " + Const.getTypeName(expected) + " but " + Const.getTypeName(thenType) + ".");
}
if (else_expr != null) {
elseType = else_expr.eval(expected);
if (expected != Const.T_UNKNOWN && elseType != expected) {
MiniC.addError(else_expr.getLine(), else_expr.getColumn(),
"ELSE expression is not of expected type " + Const.getTypeName(expected) + " but " + Const.getTypeName(elseType) + ".");
} else if (thenType == Const.T_UNKNOWN) {
thenType = elseType;
then_expr.setType(elseType);
}
} else {
elseType = thenType;
else_expr = then_expr;
}
if (thenType != elseType) {
MiniC.addError(line, column, "Type mismatch in THEN-ELSE: " + Const.getTypeName(thenType) + " vs. " + Const.getTypeName(elseType) + ".");
}
type = thenType;
is_simple = if_expr.isSimple() && then_expr.isSimple() && else_expr.isSimple();
return type;
}
/**
* Overrides ASTExpr.traverse()
*/
@Override
public ASTExpr traverse(final 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;
}
}