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