xref: /aosp_15_r20/external/apache-commons-bcel/src/examples/Mini/ASTLetExpr.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. ASTLetExpr.java */
19*0c56280aSSorin Basca /* JJT: 0.3pre1 */
20*0c56280aSSorin Basca 
21*0c56280aSSorin Basca package Mini;
22*0c56280aSSorin Basca import org.apache.bcel.generic.BasicType;
23*0c56280aSSorin Basca import org.apache.bcel.generic.ConstantPoolGen;
24*0c56280aSSorin Basca import org.apache.bcel.generic.ISTORE;
25*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionHandle;
26*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionList;
27*0c56280aSSorin Basca import org.apache.bcel.generic.LocalVariableGen;
28*0c56280aSSorin Basca import org.apache.bcel.generic.MethodGen;
29*0c56280aSSorin Basca import org.apache.bcel.generic.Type;
30*0c56280aSSorin Basca 
31*0c56280aSSorin Basca /**
32*0c56280aSSorin Basca  *
33*0c56280aSSorin Basca  * @version $Id$
34*0c56280aSSorin Basca  */
35*0c56280aSSorin Basca public class ASTLetExpr extends ASTExpr implements org.apache.bcel.Constants {
36*0c56280aSSorin Basca   private ASTIdent[]  idents;
37*0c56280aSSorin Basca   private ASTExpr[]   exprs;
38*0c56280aSSorin Basca   private ASTExpr     body;
39*0c56280aSSorin Basca 
40*0c56280aSSorin Basca   // Generated methods
ASTLetExpr(int id)41*0c56280aSSorin Basca   ASTLetExpr(int id) {
42*0c56280aSSorin Basca     super(id);
43*0c56280aSSorin Basca   }
44*0c56280aSSorin Basca 
ASTLetExpr(MiniParser p, int id)45*0c56280aSSorin Basca   ASTLetExpr(MiniParser p, int id) {
46*0c56280aSSorin Basca     super(p, id);
47*0c56280aSSorin Basca   }
48*0c56280aSSorin Basca 
jjtCreate(MiniParser p, int id)49*0c56280aSSorin Basca   public static Node jjtCreate(MiniParser p, int id) {
50*0c56280aSSorin Basca     return new ASTLetExpr(p, id);
51*0c56280aSSorin Basca   }
52*0c56280aSSorin Basca 
53*0c56280aSSorin Basca 
54*0c56280aSSorin Basca   /**
55*0c56280aSSorin Basca    * Overrides ASTExpr.closeNode()
56*0c56280aSSorin Basca    * Cast children nodes to appropiate types.
57*0c56280aSSorin Basca    */
58*0c56280aSSorin Basca   @Override
closeNode()59*0c56280aSSorin Basca   public void closeNode() {
60*0c56280aSSorin Basca     int i, len_2 = children.length / 2; /* length must be a multiple of
61*0c56280aSSorin Basca                                          * two (ident = expr) + 1 (body expr) */
62*0c56280aSSorin Basca     idents = new ASTIdent[len_2];
63*0c56280aSSorin Basca     exprs  = new ASTExpr[len_2];
64*0c56280aSSorin Basca 
65*0c56280aSSorin Basca     // At least one assignment is enforced by the grammar
66*0c56280aSSorin Basca     for(i=0; i < len_2; i++) {
67*0c56280aSSorin Basca       idents[i] = (ASTIdent)children[i * 2];
68*0c56280aSSorin Basca       exprs[i]  = (ASTExpr)children[i * 2 + 1];
69*0c56280aSSorin Basca     }
70*0c56280aSSorin Basca 
71*0c56280aSSorin Basca     body = (ASTExpr)children[children.length - 1]; // Last expr is the body
72*0c56280aSSorin Basca     children=null; // Throw away old reference
73*0c56280aSSorin Basca   }
74*0c56280aSSorin Basca 
75*0c56280aSSorin Basca   /**
76*0c56280aSSorin Basca    * Overrides ASTExpr.traverse()
77*0c56280aSSorin Basca    */
78*0c56280aSSorin Basca   @Override
traverse(Environment env)79*0c56280aSSorin Basca   public ASTExpr traverse(Environment env) {
80*0c56280aSSorin Basca     this.env = env;
81*0c56280aSSorin Basca 
82*0c56280aSSorin Basca     // Traverse RHS exprs first, so no references to LHS vars are allowed
83*0c56280aSSorin Basca     for(int i=0; i < exprs.length; i++) {
84*0c56280aSSorin Basca         exprs[i] = exprs[i].traverse((Environment)env.clone());
85*0c56280aSSorin Basca     }
86*0c56280aSSorin Basca 
87*0c56280aSSorin Basca     // Put argument names into hash table aka. environment
88*0c56280aSSorin Basca     for(int i=0; i < idents.length; i++) {
89*0c56280aSSorin Basca       ASTIdent id    = idents[i];
90*0c56280aSSorin Basca       String   name  = id.getName();
91*0c56280aSSorin Basca       EnvEntry entry = env.get(name);
92*0c56280aSSorin Basca 
93*0c56280aSSorin Basca       if(entry != null) {
94*0c56280aSSorin Basca         MiniC.addError(id.getLine(), id.getColumn(),
95*0c56280aSSorin Basca                        "Redeclaration of " + entry + ".");
96*0c56280aSSorin Basca     } else {
97*0c56280aSSorin Basca         env.put(new Variable(id));
98*0c56280aSSorin Basca     }
99*0c56280aSSorin Basca     }
100*0c56280aSSorin Basca 
101*0c56280aSSorin Basca     body = body.traverse(env);
102*0c56280aSSorin Basca 
103*0c56280aSSorin Basca     return this;
104*0c56280aSSorin Basca   }
105*0c56280aSSorin Basca 
106*0c56280aSSorin Basca   /**
107*0c56280aSSorin Basca    * Second pass
108*0c56280aSSorin Basca    * Overrides AstExpr.eval()
109*0c56280aSSorin Basca    * @return type of expression
110*0c56280aSSorin Basca    * @param expected type
111*0c56280aSSorin Basca    */
112*0c56280aSSorin Basca   @Override
eval(int expected)113*0c56280aSSorin Basca   public int eval(int expected) {
114*0c56280aSSorin Basca     //is_simple = true;
115*0c56280aSSorin Basca 
116*0c56280aSSorin Basca     for(int i=0; i < idents.length; i++) {
117*0c56280aSSorin Basca       int t = exprs[i].eval(T_UNKNOWN);
118*0c56280aSSorin Basca 
119*0c56280aSSorin Basca       idents[i].setType(t);
120*0c56280aSSorin Basca       //      is_simple = is_simple && exprs[i].isSimple();
121*0c56280aSSorin Basca     }
122*0c56280aSSorin Basca 
123*0c56280aSSorin Basca     return type = body.eval(expected);
124*0c56280aSSorin Basca   }
125*0c56280aSSorin Basca 
126*0c56280aSSorin Basca   /**
127*0c56280aSSorin Basca    * Fifth pass, produce Java code.
128*0c56280aSSorin Basca    */
129*0c56280aSSorin Basca   @Override
code(StringBuffer buf)130*0c56280aSSorin Basca   public void code(StringBuffer buf) {
131*0c56280aSSorin Basca     for(int i = 0; i < idents.length; i++) {
132*0c56280aSSorin Basca       String ident = idents[i].getName();
133*0c56280aSSorin Basca       int    t     = idents[i].getType(); // can only be int
134*0c56280aSSorin Basca 
135*0c56280aSSorin Basca       /* Idents have to be declared at start of function for later use.
136*0c56280aSSorin Basca        * Each name is unique, so there shouldn't be a problem in application.
137*0c56280aSSorin Basca        */
138*0c56280aSSorin Basca       exprs[i].code(buf);
139*0c56280aSSorin Basca 
140*0c56280aSSorin Basca       buf.append("    " + TYPE_NAMES[t] + " " + ident + " = " +
141*0c56280aSSorin Basca                  ASTFunDecl.pop() + ";\n");
142*0c56280aSSorin Basca     }
143*0c56280aSSorin Basca 
144*0c56280aSSorin Basca     body.code(buf);
145*0c56280aSSorin Basca   }
146*0c56280aSSorin Basca 
147*0c56280aSSorin Basca   /**
148*0c56280aSSorin Basca    * Fifth pass, produce Java byte code.
149*0c56280aSSorin Basca    */
150*0c56280aSSorin Basca   @Override
byte_code(InstructionList il, MethodGen method, ConstantPoolGen cp)151*0c56280aSSorin Basca   public void byte_code(InstructionList il, MethodGen method, ConstantPoolGen cp) {
152*0c56280aSSorin Basca     int size = idents.length;
153*0c56280aSSorin Basca     LocalVariableGen[] l = new LocalVariableGen[size];
154*0c56280aSSorin Basca 
155*0c56280aSSorin Basca     for(int i=0; i < size; i++) {
156*0c56280aSSorin Basca       String           ident = idents[i].getName();
157*0c56280aSSorin Basca       Variable         entry = (Variable)env.get(ident);
158*0c56280aSSorin Basca       Type             t     = BasicType.getType((byte)idents[i].getType());
159*0c56280aSSorin Basca       LocalVariableGen lg    = method.addLocalVariable(ident, t, null, null);
160*0c56280aSSorin Basca       int              slot  = lg.getIndex();
161*0c56280aSSorin Basca 
162*0c56280aSSorin Basca       entry.setLocalVariable(lg);
163*0c56280aSSorin Basca       InstructionHandle start = il.getEnd();
164*0c56280aSSorin Basca       exprs[i].byte_code(il, method, cp);
165*0c56280aSSorin Basca       start = (start == null)? il.getStart() : start.getNext();
166*0c56280aSSorin Basca       lg.setStart(start);
167*0c56280aSSorin Basca       il.append(new ISTORE(slot));     ASTFunDecl.pop();
168*0c56280aSSorin Basca       l[i] = lg;
169*0c56280aSSorin Basca     }
170*0c56280aSSorin Basca 
171*0c56280aSSorin Basca     body.byte_code(il, method, cp);
172*0c56280aSSorin Basca     InstructionHandle end = il.getEnd();
173*0c56280aSSorin Basca     for(int i=0; i < size; i++) {
174*0c56280aSSorin Basca         l[i].setEnd(end);
175*0c56280aSSorin Basca     }
176*0c56280aSSorin Basca   }
177*0c56280aSSorin Basca 
178*0c56280aSSorin Basca   @Override
dump(String prefix)179*0c56280aSSorin Basca   public void dump(String prefix) {
180*0c56280aSSorin Basca     System.out.println(toString(prefix));
181*0c56280aSSorin Basca 
182*0c56280aSSorin Basca     for(int i=0; i < idents.length; i++) {
183*0c56280aSSorin Basca       idents[i].dump(prefix + " ");
184*0c56280aSSorin Basca       exprs[i].dump(prefix + " ");
185*0c56280aSSorin Basca     }
186*0c56280aSSorin Basca 
187*0c56280aSSorin Basca     body.dump(prefix + " ");
188*0c56280aSSorin Basca   }
189*0c56280aSSorin Basca 
190*0c56280aSSorin Basca }
191