| /* |
| * 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. ASTLetExpr.java */ |
| /* JJT: 0.3pre1 */ |
| |
| package Mini; |
| |
| import org.apache.bcel.Const; |
| 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; |
| |
| /** |
| */ |
| public class ASTLetExpr extends ASTExpr { |
| public static Node jjtCreate(final MiniParser p, final int id) { |
| return new ASTLetExpr(p, id); |
| } |
| |
| private ASTIdent[] idents; |
| private ASTExpr[] exprs; |
| |
| private ASTExpr body; |
| |
| // Generated methods |
| ASTLetExpr(final int id) { |
| super(id); |
| } |
| |
| ASTLetExpr(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) { |
| final int size = idents.length; |
| final LocalVariableGen[] l = new LocalVariableGen[size]; |
| |
| for (int i = 0; i < size; i++) { |
| final String ident = idents[i].getName(); |
| final Variable entry = (Variable) env.get(ident); |
| final Type t = BasicType.getType((byte) idents[i].getType()); |
| final LocalVariableGen lg = method.addLocalVariable(ident, t, null, null); |
| final 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); |
| final InstructionHandle end = il.getEnd(); |
| for (int i = 0; i < size; i++) { |
| l[i].setEnd(end); |
| } |
| } |
| |
| /** |
| * Overrides ASTExpr.closeNode() Cast children nodes to appropriate types. |
| */ |
| @Override |
| public void closeNode() { |
| int i; /* |
| * length must be a multiple of two (ident = expr) + 1 (body expr) |
| */ |
| final int len_2 = children.length / 2; |
| 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 |
| } |
| |
| /** |
| * Fifth pass, produce Java code. |
| */ |
| @Override |
| public void code(final StringBuffer buf) { |
| for (int i = 0; i < idents.length; i++) { |
| final String ident = idents[i].getName(); |
| final 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(" " + Const.getTypeName(t) + " " + ident + " = " + ASTFunDecl.pop() + ";\n"); |
| } |
| |
| body.code(buf); |
| } |
| |
| @Override |
| public void dump(final 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 + " "); |
| } |
| |
| /** |
| * Second pass Overrides AstExpr.eval(). |
| * |
| * @return type of expression. |
| * @param expected type. |
| */ |
| @Override |
| public int eval(final int expected) { |
| // is_simple = true; |
| |
| for (int i = 0; i < idents.length; i++) { |
| final int t = exprs[i].eval(Const.T_UNKNOWN); |
| |
| idents[i].setType(t); |
| // is_simple = is_simple && exprs[i].isSimple(); |
| } |
| |
| return type = body.eval(expected); |
| } |
| |
| /** |
| * Overrides ASTExpr.traverse(). |
| */ |
| @Override |
| public ASTExpr traverse(final 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 (final ASTIdent id : idents) { |
| final String name = id.getName(); |
| final 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; |
| } |
| |
| } |