xref: /aosp_15_r20/external/apache-commons-bcel/src/examples/Mini/ASTFunDecl.java (revision 0c56280ab0842982c46a149f7b9eaa497e31e292)
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