/* * 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. ASTLetExpr.java */ /* JJT: 0.3pre1 */ package Mini; import org.apache.bcel.generic.BasicType; import org.apache.bcel.generic.ConstantPoolGen; import org.apache.bcel.generic.ISTORE; import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.LocalVariableGen; import org.apache.bcel.generic.MethodGen; import org.apache.bcel.generic.Type; /** * * @version $Id$ */ public class ASTLetExpr extends ASTExpr implements org.apache.bcel.Constants { private ASTIdent[] idents; private ASTExpr[] exprs; private ASTExpr body; // Generated methods ASTLetExpr(int id) { super(id); } ASTLetExpr(MiniParser p, int id) { super(p, id); } public static Node jjtCreate(MiniParser p, int id) { return new ASTLetExpr(p, id); } /** * Overrides ASTExpr.closeNode() * Cast children nodes to appropiate types. */ @Override public void closeNode() { int i, len_2 = children.length / 2; /* length must be a multiple of * two (ident = expr) + 1 (body expr) */ idents = new ASTIdent[len_2]; exprs = new ASTExpr[len_2]; // At least one assignment is enforced by the grammar for(i=0; i < len_2; i++) { idents[i] = (ASTIdent)children[i * 2]; exprs[i] = (ASTExpr)children[i * 2 + 1]; } body = (ASTExpr)children[children.length - 1]; // Last expr is the body children=null; // Throw away old reference } /** * Overrides ASTExpr.traverse() */ @Override public ASTExpr traverse(Environment env) { this.env = env; // Traverse RHS exprs first, so no references to LHS vars are allowed for(int i=0; i < exprs.length; i++) { exprs[i] = exprs[i].traverse((Environment)env.clone()); } // Put argument names into hash table aka. environment for(int i=0; i < idents.length; i++) { ASTIdent id = idents[i]; String name = id.getName(); EnvEntry entry = env.get(name); if(entry != null) { MiniC.addError(id.getLine(), id.getColumn(), "Redeclaration of " + entry + "."); } else { env.put(new Variable(id)); } } body = body.traverse(env); return this; } /** * Second pass * Overrides AstExpr.eval() * @return type of expression * @param expected type */ @Override public int eval(int expected) { //is_simple = true; for(int i=0; i < idents.length; i++) { int t = exprs[i].eval(T_UNKNOWN); idents[i].setType(t); // is_simple = is_simple && exprs[i].isSimple(); } return type = body.eval(expected); } /** * Fifth pass, produce Java code. */ @Override public void code(StringBuffer buf) { for(int i = 0; i < idents.length; i++) { String ident = idents[i].getName(); int t = idents[i].getType(); // can only be int /* Idents have to be declared at start of function for later use. * Each name is unique, so there shouldn't be a problem in application. */ exprs[i].code(buf); buf.append(" " + TYPE_NAMES[t] + " " + ident + " = " + ASTFunDecl.pop() + ";\n"); } body.code(buf); } /** * Fifth pass, produce Java byte code. */ @Override public void byte_code(InstructionList il, MethodGen method, ConstantPoolGen cp) { int size = idents.length; LocalVariableGen[] l = new LocalVariableGen[size]; for(int i=0; i < size; i++) { String ident = idents[i].getName(); Variable entry = (Variable)env.get(ident); Type t = BasicType.getType((byte)idents[i].getType()); LocalVariableGen lg = method.addLocalVariable(ident, t, null, null); int slot = lg.getIndex(); entry.setLocalVariable(lg); InstructionHandle start = il.getEnd(); exprs[i].byte_code(il, method, cp); start = (start == null)? il.getStart() : start.getNext(); lg.setStart(start); il.append(new ISTORE(slot)); ASTFunDecl.pop(); l[i] = lg; } body.byte_code(il, method, cp); InstructionHandle end = il.getEnd(); for(int i=0; i < size; i++) { l[i].setEnd(end); } } @Override public void dump(String prefix) { System.out.println(toString(prefix)); for(int i=0; i < idents.length; i++) { idents[i].dump(prefix + " "); exprs[i].dump(prefix + " "); } body.dump(prefix + " "); } }