/*
 * 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;
    }
}
