blob: aa65ec1815e0a8e411a99c849add0704b6135fad [file] [log] [blame]
/*
* 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;
}
}