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