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. ASTLetExpr.java */
     19 /* JJT: 0.3pre1 */
     20 
     21 package Mini;
     22 import org.apache.bcel.generic.BasicType;
     23 import org.apache.bcel.generic.ConstantPoolGen;
     24 import org.apache.bcel.generic.ISTORE;
     25 import org.apache.bcel.generic.InstructionHandle;
     26 import org.apache.bcel.generic.InstructionList;
     27 import org.apache.bcel.generic.LocalVariableGen;
     28 import org.apache.bcel.generic.MethodGen;
     29 import org.apache.bcel.generic.Type;
     30 
     31 /**
     32  *
     33  * @version $Id$
     34  */
     35 public class ASTLetExpr extends ASTExpr implements org.apache.bcel.Constants {
     36   private ASTIdent[]  idents;
     37   private ASTExpr[]   exprs;
     38   private ASTExpr     body;
     39 
     40   // Generated methods
     41   ASTLetExpr(int id) {
     42     super(id);
     43   }
     44 
     45   ASTLetExpr(MiniParser p, int id) {
     46     super(p, id);
     47   }
     48 
     49   public static Node jjtCreate(MiniParser p, int id) {
     50     return new ASTLetExpr(p, id);
     51   }
     52 
     53 
     54   /**
     55    * Overrides ASTExpr.closeNode()
     56    * Cast children nodes to appropiate types.
     57    */
     58   @Override
     59   public void closeNode() {
     60     int i, len_2 = children.length / 2; /* length must be a multiple of
     61                                          * two (ident = expr) + 1 (body expr) */
     62     idents = new ASTIdent[len_2];
     63     exprs  = new ASTExpr[len_2];
     64 
     65     // At least one assignment is enforced by the grammar
     66     for(i=0; i < len_2; i++) {
     67       idents[i] = (ASTIdent)children[i * 2];
     68       exprs[i]  = (ASTExpr)children[i * 2 + 1];
     69     }
     70 
     71     body = (ASTExpr)children[children.length - 1]; // Last expr is the body
     72     children=null; // Throw away old reference
     73   }
     74 
     75   /**
     76    * Overrides ASTExpr.traverse()
     77    */
     78   @Override
     79   public ASTExpr traverse(Environment env) {
     80     this.env = env;
     81 
     82     // Traverse RHS exprs first, so no references to LHS vars are allowed
     83     for(int i=0; i < exprs.length; i++) {
     84         exprs[i] = exprs[i].traverse((Environment)env.clone());
     85     }
     86 
     87     // Put argument names into hash table aka. environment
     88     for(int i=0; i < idents.length; i++) {
     89       ASTIdent id    = idents[i];
     90       String   name  = id.getName();
     91       EnvEntry entry = env.get(name);
     92 
     93       if(entry != null) {
     94         MiniC.addError(id.getLine(), id.getColumn(),
     95                        "Redeclaration of " + entry + ".");
     96     } else {
     97         env.put(new Variable(id));
     98     }
     99     }
    100 
    101     body = body.traverse(env);
    102 
    103     return this;
    104   }
    105 
    106   /**
    107    * Second pass
    108    * Overrides AstExpr.eval()
    109    * @return type of expression
    110    * @param expected type
    111    */
    112   @Override
    113   public int eval(int expected) {
    114     //is_simple = true;
    115 
    116     for(int i=0; i < idents.length; i++) {
    117       int t = exprs[i].eval(T_UNKNOWN);
    118 
    119       idents[i].setType(t);
    120       //      is_simple = is_simple && exprs[i].isSimple();
    121     }
    122 
    123     return type = body.eval(expected);
    124   }
    125 
    126   /**
    127    * Fifth pass, produce Java code.
    128    */
    129   @Override
    130   public void code(StringBuffer buf) {
    131     for(int i = 0; i < idents.length; i++) {
    132       String ident = idents[i].getName();
    133       int    t     = idents[i].getType(); // can only be int
    134 
    135       /* Idents have to be declared at start of function for later use.
    136        * Each name is unique, so there shouldn't be a problem in application.
    137        */
    138       exprs[i].code(buf);
    139 
    140       buf.append("    " + TYPE_NAMES[t] + " " + ident + " = " +
    141                  ASTFunDecl.pop() + ";\n");
    142     }
    143 
    144     body.code(buf);
    145   }
    146 
    147   /**
    148    * Fifth pass, produce Java byte code.
    149    */
    150   @Override
    151   public void byte_code(InstructionList il, MethodGen method, ConstantPoolGen cp) {
    152     int size = idents.length;
    153     LocalVariableGen[] l = new LocalVariableGen[size];
    154 
    155     for(int i=0; i < size; i++) {
    156       String           ident = idents[i].getName();
    157       Variable         entry = (Variable)env.get(ident);
    158       Type             t     = BasicType.getType((byte)idents[i].getType());
    159       LocalVariableGen lg    = method.addLocalVariable(ident, t, null, null);
    160       int              slot  = lg.getIndex();
    161 
    162       entry.setLocalVariable(lg);
    163       InstructionHandle start = il.getEnd();
    164       exprs[i].byte_code(il, method, cp);
    165       start = (start == null)? il.getStart() : start.getNext();
    166       lg.setStart(start);
    167       il.append(new ISTORE(slot));     ASTFunDecl.pop();
    168       l[i] = lg;
    169     }
    170 
    171     body.byte_code(il, method, cp);
    172     InstructionHandle end = il.getEnd();
    173     for(int i=0; i < size; i++) {
    174         l[i].setEnd(end);
    175     }
    176   }
    177 
    178   @Override
    179   public void dump(String prefix) {
    180     System.out.println(toString(prefix));
    181 
    182     for(int i=0; i < idents.length; i++) {
    183       idents[i].dump(prefix + " ");
    184       exprs[i].dump(prefix + " ");
    185     }
    186 
    187     body.dump(prefix + " ");
    188   }
    189 
    190 }
    191