blob: 5af056eea7558b28927cc2177b913da6b9d876b0 [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
*
* 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$
*/
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 + " ");
}
}
}