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. ASTFunDecl.java */ 19*0c56280aSSorin Basca /* JJT: 0.3pre1 */ 20*0c56280aSSorin Basca 21*0c56280aSSorin Basca package Mini; 22*0c56280aSSorin Basca import java.io.PrintWriter; 23*0c56280aSSorin Basca import java.util.Iterator; 24*0c56280aSSorin Basca 25*0c56280aSSorin Basca import org.apache.bcel.generic.ALOAD; 26*0c56280aSSorin Basca import org.apache.bcel.generic.ASTORE; 27*0c56280aSSorin Basca import org.apache.bcel.generic.ArrayType; 28*0c56280aSSorin Basca import org.apache.bcel.generic.BranchHandle; 29*0c56280aSSorin Basca import org.apache.bcel.generic.BranchInstruction; 30*0c56280aSSorin Basca import org.apache.bcel.generic.ClassGen; 31*0c56280aSSorin Basca import org.apache.bcel.generic.ConstantPoolGen; 32*0c56280aSSorin Basca import org.apache.bcel.generic.GETSTATIC; 33*0c56280aSSorin Basca import org.apache.bcel.generic.GOTO; 34*0c56280aSSorin Basca import org.apache.bcel.generic.INVOKEVIRTUAL; 35*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionConstants; 36*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionHandle; 37*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionList; 38*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionTargeter; 39*0c56280aSSorin Basca import org.apache.bcel.generic.LocalVariableGen; 40*0c56280aSSorin Basca import org.apache.bcel.generic.MethodGen; 41*0c56280aSSorin Basca import org.apache.bcel.generic.ObjectType; 42*0c56280aSSorin Basca import org.apache.bcel.generic.TargetLostException; 43*0c56280aSSorin Basca import org.apache.bcel.generic.Type; 44*0c56280aSSorin Basca import org.apache.bcel.util.InstructionFinder; 45*0c56280aSSorin Basca 46*0c56280aSSorin Basca /** 47*0c56280aSSorin Basca * 48*0c56280aSSorin Basca * @version $Id$ 49*0c56280aSSorin Basca */ 50*0c56280aSSorin Basca public class ASTFunDecl extends SimpleNode 51*0c56280aSSorin Basca implements MiniParserTreeConstants, org.apache.bcel.Constants { 52*0c56280aSSorin Basca private ASTIdent name; 53*0c56280aSSorin Basca private ASTIdent[] argv; 54*0c56280aSSorin Basca private ASTExpr body; 55*0c56280aSSorin Basca private int type = T_UNKNOWN; 56*0c56280aSSorin Basca private int line, column; 57*0c56280aSSorin Basca private boolean is_simple; // true, if simple expression like `12 + f(a)' 58*0c56280aSSorin Basca private boolean is_recursive; // Not used yet, TODO 59*0c56280aSSorin Basca // private int max_depth; // max. expression tree depth 60*0c56280aSSorin Basca private Environment env; 61*0c56280aSSorin Basca 62*0c56280aSSorin Basca // Generated methods ASTFunDecl(int id)63*0c56280aSSorin Basca ASTFunDecl(int id) { 64*0c56280aSSorin Basca super(id); 65*0c56280aSSorin Basca } 66*0c56280aSSorin Basca ASTFunDecl(MiniParser p, int id)67*0c56280aSSorin Basca ASTFunDecl(MiniParser p, int id) { 68*0c56280aSSorin Basca super(p, id); 69*0c56280aSSorin Basca } 70*0c56280aSSorin Basca jjtCreate(MiniParser p, int id)71*0c56280aSSorin Basca public static Node jjtCreate(MiniParser p, int id) { 72*0c56280aSSorin Basca return new ASTFunDecl(p, id); 73*0c56280aSSorin Basca } 74*0c56280aSSorin Basca ASTFunDecl(ASTIdent name, ASTIdent[] argv, ASTExpr body, int type)75*0c56280aSSorin Basca ASTFunDecl(ASTIdent name, ASTIdent[] argv, ASTExpr body, int type) { 76*0c56280aSSorin Basca this(JJTFUNDECL); 77*0c56280aSSorin Basca 78*0c56280aSSorin Basca this.name = name; 79*0c56280aSSorin Basca this.argv = argv; 80*0c56280aSSorin Basca this.body = body; 81*0c56280aSSorin Basca this.type = type; 82*0c56280aSSorin Basca } 83*0c56280aSSorin Basca 84*0c56280aSSorin Basca /** 85*0c56280aSSorin Basca * Overrides SimpleNode.closeNode() 86*0c56280aSSorin Basca * Cast children to appropiate type. 87*0c56280aSSorin Basca */ 88*0c56280aSSorin Basca @Override closeNode()89*0c56280aSSorin Basca public void closeNode() { 90*0c56280aSSorin Basca name = (ASTIdent)children[0]; 91*0c56280aSSorin Basca body = (ASTExpr)children[children.length - 1]; 92*0c56280aSSorin Basca 93*0c56280aSSorin Basca argv = new ASTIdent[children.length - 2]; // May be 0-size array 94*0c56280aSSorin Basca for(int i = 1; i < children.length - 1; i++) { 95*0c56280aSSorin Basca argv[i - 1] = (ASTIdent)children[i]; 96*0c56280aSSorin Basca } 97*0c56280aSSorin Basca 98*0c56280aSSorin Basca children=null; // Throw away old reference 99*0c56280aSSorin Basca } 100*0c56280aSSorin Basca 101*0c56280aSSorin Basca /** 102*0c56280aSSorin Basca * First pass of parse tree. 103*0c56280aSSorin Basca */ traverse(Environment env)104*0c56280aSSorin Basca public ASTFunDecl traverse(Environment env) { 105*0c56280aSSorin Basca this.env = env; 106*0c56280aSSorin Basca 107*0c56280aSSorin Basca // Put arguments into hash table aka environment 108*0c56280aSSorin Basca for(int i=0; i < argv.length; i++) { 109*0c56280aSSorin Basca EnvEntry entry = env.get(argv[i].getName()); 110*0c56280aSSorin Basca 111*0c56280aSSorin Basca if(entry != null) { 112*0c56280aSSorin Basca MiniC.addError(argv[i].getLine(), argv[i].getColumn(), 113*0c56280aSSorin Basca "Redeclaration of " + entry + "."); 114*0c56280aSSorin Basca } else { 115*0c56280aSSorin Basca env.put(new Variable(argv[i])); 116*0c56280aSSorin Basca } 117*0c56280aSSorin Basca } 118*0c56280aSSorin Basca 119*0c56280aSSorin Basca /* Update entry of this function, i.e. set argument references. 120*0c56280aSSorin Basca * The entry is already in there by garantuee, but may be of wrong type, 121*0c56280aSSorin Basca * i.e. the user defined a function `TRUE', e.g. and `TRUE' is of type `Variable'. 122*0c56280aSSorin Basca */ 123*0c56280aSSorin Basca try { 124*0c56280aSSorin Basca Function fun = (Function)env.get(name.getName()); 125*0c56280aSSorin Basca fun.setArgs(argv); 126*0c56280aSSorin Basca } catch(ClassCastException e) {} // Who cares? 127*0c56280aSSorin Basca 128*0c56280aSSorin Basca body = body.traverse(env); // Traverse expression body 129*0c56280aSSorin Basca 130*0c56280aSSorin Basca return this; 131*0c56280aSSorin Basca } 132*0c56280aSSorin Basca 133*0c56280aSSorin Basca /** Second pass 134*0c56280aSSorin Basca * @return type of expression 135*0c56280aSSorin Basca */ eval(int pass)136*0c56280aSSorin Basca public int eval(int pass) { 137*0c56280aSSorin Basca int expected = name.getType(); // Maybe other function has already called us 138*0c56280aSSorin Basca type = body.eval(expected); // And updated the env 139*0c56280aSSorin Basca 140*0c56280aSSorin Basca if((expected != T_UNKNOWN) && (type != expected)) { 141*0c56280aSSorin Basca MiniC.addError(line, column, 142*0c56280aSSorin Basca "Function f ist not of type " + TYPE_NAMES[expected] + 143*0c56280aSSorin Basca " as previously assumed, but " + TYPE_NAMES[type]); 144*0c56280aSSorin Basca } 145*0c56280aSSorin Basca 146*0c56280aSSorin Basca name.setType(type); 147*0c56280aSSorin Basca 148*0c56280aSSorin Basca is_simple = body.isSimple(); 149*0c56280aSSorin Basca 150*0c56280aSSorin Basca if(pass == 2 && type == T_UNKNOWN) { 151*0c56280aSSorin Basca is_recursive = true; 152*0c56280aSSorin Basca } 153*0c56280aSSorin Basca 154*0c56280aSSorin Basca return type; 155*0c56280aSSorin Basca } 156*0c56280aSSorin Basca 157*0c56280aSSorin Basca /** 158*0c56280aSSorin Basca * Fourth pass, produce Java code. 159*0c56280aSSorin Basca */ code(PrintWriter out)160*0c56280aSSorin Basca public void code(PrintWriter out) { 161*0c56280aSSorin Basca String expr; 162*0c56280aSSorin Basca boolean main=false, ignore=false; 163*0c56280aSSorin Basca 164*0c56280aSSorin Basca String fname = name.getName(); 165*0c56280aSSorin Basca 166*0c56280aSSorin Basca if(fname.equals("main")) { 167*0c56280aSSorin Basca out.println(" public static void main(String[] _argv) {"); 168*0c56280aSSorin Basca main = true; 169*0c56280aSSorin Basca } 170*0c56280aSSorin Basca else if(fname.equals("READ") || fname.equals("WRITE")) { // Do nothing 171*0c56280aSSorin Basca ignore = true; 172*0c56280aSSorin Basca } 173*0c56280aSSorin Basca else { 174*0c56280aSSorin Basca out.print(" public static final " + "int" + // type_names[type] + 175*0c56280aSSorin Basca " " + fname + "("); 176*0c56280aSSorin Basca 177*0c56280aSSorin Basca for(int i = 0; i < argv.length; i++) { 178*0c56280aSSorin Basca out.print("int " + argv[i].getName()); 179*0c56280aSSorin Basca 180*0c56280aSSorin Basca if(i < argv.length - 1) { 181*0c56280aSSorin Basca out.print(", "); 182*0c56280aSSorin Basca } 183*0c56280aSSorin Basca } 184*0c56280aSSorin Basca 185*0c56280aSSorin Basca out.println(")\n throws IOException\n {"); 186*0c56280aSSorin Basca } 187*0c56280aSSorin Basca 188*0c56280aSSorin Basca if(!ignore) { 189*0c56280aSSorin Basca StringBuffer buf = new StringBuffer(); 190*0c56280aSSorin Basca 191*0c56280aSSorin Basca body.code(buf); 192*0c56280aSSorin Basca out.println(getVarDecls()); 193*0c56280aSSorin Basca 194*0c56280aSSorin Basca expr = buf.toString(); 195*0c56280aSSorin Basca 196*0c56280aSSorin Basca if(main) { 197*0c56280aSSorin Basca out.println(" try {"); 198*0c56280aSSorin Basca } 199*0c56280aSSorin Basca 200*0c56280aSSorin Basca out.println(expr); 201*0c56280aSSorin Basca 202*0c56280aSSorin Basca if(main) { 203*0c56280aSSorin Basca out.println(" } catch(Exception e) { System.err.println(e); }\n }\n"); 204*0c56280aSSorin Basca } else { 205*0c56280aSSorin Basca out.println("\n return " + pop() + ";\n }\n"); 206*0c56280aSSorin Basca } 207*0c56280aSSorin Basca } 208*0c56280aSSorin Basca 209*0c56280aSSorin Basca reset(); 210*0c56280aSSorin Basca } 211*0c56280aSSorin Basca 212*0c56280aSSorin Basca /** 213*0c56280aSSorin Basca * Fifth pass, produce Java byte code. 214*0c56280aSSorin Basca */ byte_code(ClassGen class_gen, ConstantPoolGen cp)215*0c56280aSSorin Basca public void byte_code(ClassGen class_gen, ConstantPoolGen cp) { 216*0c56280aSSorin Basca MethodGen method=null; 217*0c56280aSSorin Basca boolean main=false, ignore=false; 218*0c56280aSSorin Basca String class_name = class_gen.getClassName(); 219*0c56280aSSorin Basca String fname = name.getName(); 220*0c56280aSSorin Basca InstructionList il = new InstructionList(); 221*0c56280aSSorin Basca 222*0c56280aSSorin Basca Type[] args = { new ArrayType(Type.STRING, 1) }; // default for `main' 223*0c56280aSSorin Basca String[] arg_names = { "$argv" }; 224*0c56280aSSorin Basca 225*0c56280aSSorin Basca if(fname.equals("main")) { 226*0c56280aSSorin Basca method = new MethodGen(ACC_STATIC | ACC_PUBLIC, 227*0c56280aSSorin Basca Type.VOID, args, arg_names, 228*0c56280aSSorin Basca "main", class_name, il, cp); 229*0c56280aSSorin Basca 230*0c56280aSSorin Basca main = true; 231*0c56280aSSorin Basca } else if(fname.equals("READ") || fname.equals("WRITE")) { // Do nothing 232*0c56280aSSorin Basca ignore = true; 233*0c56280aSSorin Basca } else { 234*0c56280aSSorin Basca int size = argv.length; 235*0c56280aSSorin Basca 236*0c56280aSSorin Basca arg_names = new String[size]; 237*0c56280aSSorin Basca args = new Type[size]; 238*0c56280aSSorin Basca 239*0c56280aSSorin Basca for(int i = 0; i < size; i++) { 240*0c56280aSSorin Basca args[i] = Type.INT; 241*0c56280aSSorin Basca arg_names[i] = argv[i].getName(); 242*0c56280aSSorin Basca } 243*0c56280aSSorin Basca 244*0c56280aSSorin Basca method = new MethodGen(ACC_STATIC | ACC_PRIVATE | ACC_FINAL, 245*0c56280aSSorin Basca Type.INT, args, arg_names, 246*0c56280aSSorin Basca fname, class_name, il, cp); 247*0c56280aSSorin Basca 248*0c56280aSSorin Basca LocalVariableGen[] lv = method.getLocalVariables(); 249*0c56280aSSorin Basca for(int i = 0; i < size; i++) { 250*0c56280aSSorin Basca Variable entry = (Variable)env.get(arg_names[i]); 251*0c56280aSSorin Basca entry.setLocalVariable(lv[i]); 252*0c56280aSSorin Basca } 253*0c56280aSSorin Basca 254*0c56280aSSorin Basca method.addException("java.io.IOException"); 255*0c56280aSSorin Basca } 256*0c56280aSSorin Basca 257*0c56280aSSorin Basca if(!ignore) { 258*0c56280aSSorin Basca body.byte_code(il, method, cp); 259*0c56280aSSorin Basca 260*0c56280aSSorin Basca if(main) { 261*0c56280aSSorin Basca ObjectType e_type = new ObjectType("java.lang.Exception"); 262*0c56280aSSorin Basca InstructionHandle start = il.getStart(), end, handler, end_handler; 263*0c56280aSSorin Basca LocalVariableGen exc = method.addLocalVariable("$e", 264*0c56280aSSorin Basca e_type, 265*0c56280aSSorin Basca null, null); 266*0c56280aSSorin Basca int slot = exc.getIndex(); 267*0c56280aSSorin Basca 268*0c56280aSSorin Basca il.append(InstructionConstants.POP); pop(); // Remove last element on stack 269*0c56280aSSorin Basca end = il.append(InstructionConstants.RETURN); // Use instruction constants, if possible 270*0c56280aSSorin Basca 271*0c56280aSSorin Basca // catch 272*0c56280aSSorin Basca handler = il.append(new ASTORE(slot)); // save exception object 273*0c56280aSSorin Basca il.append(new GETSTATIC(cp.addFieldref("java.lang.System", "err", 274*0c56280aSSorin Basca "Ljava/io/PrintStream;"))); 275*0c56280aSSorin Basca il.append(new ALOAD(slot)); push(2); 276*0c56280aSSorin Basca il.append(new INVOKEVIRTUAL(cp.addMethodref("java.io.PrintStream", 277*0c56280aSSorin Basca "println", 278*0c56280aSSorin Basca "(Ljava/lang/Object;)V"))); 279*0c56280aSSorin Basca pop(2); 280*0c56280aSSorin Basca end_handler = il.append(InstructionConstants.RETURN); 281*0c56280aSSorin Basca method.addExceptionHandler(start, end, handler, e_type); 282*0c56280aSSorin Basca exc.setStart(handler); exc.setEnd(end_handler); 283*0c56280aSSorin Basca } else { 284*0c56280aSSorin Basca il.append(InstructionConstants.IRETURN); // Reuse object to save memory 285*0c56280aSSorin Basca } 286*0c56280aSSorin Basca 287*0c56280aSSorin Basca method.removeNOPs(); // First optimization pass, provided by MethodGen 288*0c56280aSSorin Basca optimizeIFs(il); // Second optimization pass, application-specific 289*0c56280aSSorin Basca method.setMaxStack(max_size); 290*0c56280aSSorin Basca class_gen.addMethod(method.getMethod()); 291*0c56280aSSorin Basca } 292*0c56280aSSorin Basca 293*0c56280aSSorin Basca il.dispose(); // Dispose instruction handles for better memory utilization 294*0c56280aSSorin Basca 295*0c56280aSSorin Basca reset(); 296*0c56280aSSorin Basca } 297*0c56280aSSorin Basca 298*0c56280aSSorin Basca private static final InstructionFinder.CodeConstraint my_constraint = 299*0c56280aSSorin Basca new InstructionFinder.CodeConstraint() { 300*0c56280aSSorin Basca public boolean checkCode(InstructionHandle[] match) { 301*0c56280aSSorin Basca BranchInstruction if_icmp = (BranchInstruction)match[0].getInstruction(); 302*0c56280aSSorin Basca GOTO goto_ = (GOTO)match[2].getInstruction(); 303*0c56280aSSorin Basca return (if_icmp.getTarget() == match[3]) && (goto_.getTarget() == match[4]); 304*0c56280aSSorin Basca } 305*0c56280aSSorin Basca }; 306*0c56280aSSorin Basca 307*0c56280aSSorin Basca /** 308*0c56280aSSorin Basca * Replaces instruction sequences (typically generated by ASTIfExpr) of the form 309*0c56280aSSorin Basca * 310*0c56280aSSorin Basca * IF_ICMP__, ICONST_1, GOTO, ICONST_0, IFEQ, Instruction 311*0c56280aSSorin Basca * 312*0c56280aSSorin Basca * where the IF_ICMP__ branches to the ICONST_0 (else part) and the GOTO branches 313*0c56280aSSorin Basca * to the IFEQ with the simpler expression 314*0c56280aSSorin Basca * 315*0c56280aSSorin Basca * IF_ICMP__, Instruction 316*0c56280aSSorin Basca * 317*0c56280aSSorin Basca * where the IF_ICMP__ now branches to the target of the previous IFEQ instruction. 318*0c56280aSSorin Basca */ optimizeIFs(InstructionList il)319*0c56280aSSorin Basca private static void optimizeIFs(InstructionList il) { 320*0c56280aSSorin Basca InstructionFinder f = new InstructionFinder(il); 321*0c56280aSSorin Basca String pat = "IF_ICMP ICONST_1 GOTO ICONST_0 IFEQ Instruction"; 322*0c56280aSSorin Basca 323*0c56280aSSorin Basca for(Iterator<InstructionHandle[]> it = f.search(pat, my_constraint); it.hasNext();) { 324*0c56280aSSorin Basca InstructionHandle[] match = it.next(); 325*0c56280aSSorin Basca // Everything ok, update code 326*0c56280aSSorin Basca BranchInstruction ifeq = (BranchInstruction)(match[4].getInstruction()); 327*0c56280aSSorin Basca BranchHandle if_icmp = (BranchHandle)match[0]; 328*0c56280aSSorin Basca 329*0c56280aSSorin Basca if_icmp.setTarget(ifeq.getTarget()); 330*0c56280aSSorin Basca 331*0c56280aSSorin Basca try { 332*0c56280aSSorin Basca il.delete(match[1], match[4]); 333*0c56280aSSorin Basca } catch(TargetLostException e) { 334*0c56280aSSorin Basca InstructionHandle[] targets = e.getTargets(); 335*0c56280aSSorin Basca 336*0c56280aSSorin Basca System.err.println(targets[0]); 337*0c56280aSSorin Basca 338*0c56280aSSorin Basca for(int i=0; i < targets.length; i++) { 339*0c56280aSSorin Basca InstructionTargeter[] targeters = targets[i].getTargeters(); 340*0c56280aSSorin Basca 341*0c56280aSSorin Basca for(int j=0; j < targeters.length; j++) { 342*0c56280aSSorin Basca if((targets[i] != match[4]) || (targeters[j] != match[2])) { 343*0c56280aSSorin Basca System.err.println("Ooops: " + e); 344*0c56280aSSorin Basca } 345*0c56280aSSorin Basca } 346*0c56280aSSorin Basca } 347*0c56280aSSorin Basca } 348*0c56280aSSorin Basca } 349*0c56280aSSorin Basca } 350*0c56280aSSorin Basca 351*0c56280aSSorin Basca /** 352*0c56280aSSorin Basca * Overrides SimpleNode.toString() 353*0c56280aSSorin Basca */ 354*0c56280aSSorin Basca @Override toString()355*0c56280aSSorin Basca public String toString() { 356*0c56280aSSorin Basca StringBuffer buf = new StringBuffer(); 357*0c56280aSSorin Basca buf.append(jjtNodeName[id] + " " + name + "("); 358*0c56280aSSorin Basca 359*0c56280aSSorin Basca for(int i = 0; i < argv.length; i++) { 360*0c56280aSSorin Basca buf.append(argv[i].getName()); 361*0c56280aSSorin Basca if(i < argv.length - 1) { 362*0c56280aSSorin Basca buf.append(", "); 363*0c56280aSSorin Basca } 364*0c56280aSSorin Basca } 365*0c56280aSSorin Basca 366*0c56280aSSorin Basca buf.append(")"); 367*0c56280aSSorin Basca return buf.toString(); 368*0c56280aSSorin Basca } 369*0c56280aSSorin Basca isrecursive()370*0c56280aSSorin Basca public boolean isrecursive() { return is_recursive; } isSimple()371*0c56280aSSorin Basca public boolean isSimple() { return is_simple; } getName()372*0c56280aSSorin Basca public ASTIdent getName() { return name; } getNoArgs()373*0c56280aSSorin Basca public int getNoArgs() { return argv.length; } getArgs()374*0c56280aSSorin Basca public ASTIdent[] getArgs() { return argv; } getType()375*0c56280aSSorin Basca public int getType() { return type; } setType(int type)376*0c56280aSSorin Basca public void setType(int type) { this.type = type; } setLine(int line)377*0c56280aSSorin Basca public void setLine(int line) { this.line = line; } getLine()378*0c56280aSSorin Basca public int getLine() { return line; } setColumn(int column)379*0c56280aSSorin Basca public void setColumn(int column) { this.column = column; } getColumn()380*0c56280aSSorin Basca public int getColumn() { return column; } setPosition(int line, int column)381*0c56280aSSorin Basca public void setPosition(int line, int column) { 382*0c56280aSSorin Basca this.line = line; 383*0c56280aSSorin Basca this.column = column; 384*0c56280aSSorin Basca } 385*0c56280aSSorin Basca 386*0c56280aSSorin Basca /** 387*0c56280aSSorin Basca * Overrides SimpleNode.dump() 388*0c56280aSSorin Basca */ 389*0c56280aSSorin Basca @Override dump(String prefix)390*0c56280aSSorin Basca public void dump(String prefix) { 391*0c56280aSSorin Basca System.out.println(toString(prefix)); 392*0c56280aSSorin Basca 393*0c56280aSSorin Basca for(int i = 0; i < argv.length; i++) { 394*0c56280aSSorin Basca argv[i].dump(prefix + " "); 395*0c56280aSSorin Basca } 396*0c56280aSSorin Basca 397*0c56280aSSorin Basca body.dump(prefix + " "); 398*0c56280aSSorin Basca } 399*0c56280aSSorin Basca 400*0c56280aSSorin Basca /* Used to simpulate stack with local vars and compute maximum stack size. 401*0c56280aSSorin Basca */ 402*0c56280aSSorin Basca static int size, max_size; 403*0c56280aSSorin Basca reset()404*0c56280aSSorin Basca static void reset() { size = max_size = 0; } 405*0c56280aSSorin Basca getVarDecls()406*0c56280aSSorin Basca private static String getVarDecls() { 407*0c56280aSSorin Basca StringBuffer buf = new StringBuffer(" int "); 408*0c56280aSSorin Basca 409*0c56280aSSorin Basca for(int i=0; i < max_size; i++) { 410*0c56280aSSorin Basca buf.append("_s" + i); 411*0c56280aSSorin Basca 412*0c56280aSSorin Basca if(i < max_size - 1) { 413*0c56280aSSorin Basca buf.append(", "); 414*0c56280aSSorin Basca } 415*0c56280aSSorin Basca } 416*0c56280aSSorin Basca 417*0c56280aSSorin Basca buf.append(";\n"); 418*0c56280aSSorin Basca return buf.toString(); 419*0c56280aSSorin Basca } 420*0c56280aSSorin Basca 421*0c56280aSSorin Basca /** Used by byte_code() 422*0c56280aSSorin Basca */ pop(int s)423*0c56280aSSorin Basca static void pop(int s) { size -= s; } push(int s)424*0c56280aSSorin Basca static void push(int s) { 425*0c56280aSSorin Basca size += s; 426*0c56280aSSorin Basca 427*0c56280aSSorin Basca if(size > max_size) { 428*0c56280aSSorin Basca max_size = size; 429*0c56280aSSorin Basca } 430*0c56280aSSorin Basca } push()431*0c56280aSSorin Basca static void push() { push(1); } 432*0c56280aSSorin Basca 433*0c56280aSSorin Basca /** Used byte code() 434*0c56280aSSorin Basca */ push(StringBuffer buf, String str)435*0c56280aSSorin Basca static void push(StringBuffer buf, String str) { 436*0c56280aSSorin Basca buf.append(" _s" + size + " = " + str + ";\n"); 437*0c56280aSSorin Basca push(1); 438*0c56280aSSorin Basca } 439*0c56280aSSorin Basca pop()440*0c56280aSSorin Basca static String pop() { 441*0c56280aSSorin Basca return "_s" + (--size); 442*0c56280aSSorin Basca } 443*0c56280aSSorin Basca } 444