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. ASTFunAppl.java */ 19*0c56280aSSorin Basca /* JJT: 0.3pre1 */ 20*0c56280aSSorin Basca 21*0c56280aSSorin Basca package Mini; 22*0c56280aSSorin Basca import org.apache.bcel.generic.ConstantPoolGen; 23*0c56280aSSorin Basca import org.apache.bcel.generic.INVOKESTATIC; 24*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionList; 25*0c56280aSSorin Basca import org.apache.bcel.generic.MethodGen; 26*0c56280aSSorin Basca import org.apache.bcel.generic.Type; 27*0c56280aSSorin Basca 28*0c56280aSSorin Basca /** 29*0c56280aSSorin Basca * 30*0c56280aSSorin Basca * @version $Id$ 31*0c56280aSSorin Basca */ 32*0c56280aSSorin Basca public class ASTFunAppl extends ASTExpr implements MiniParserTreeConstants, 33*0c56280aSSorin Basca org.apache.bcel.Constants { 34*0c56280aSSorin Basca private ASTIdent name; 35*0c56280aSSorin Basca private Function function; // Points to Function in environment 36*0c56280aSSorin Basca 37*0c56280aSSorin Basca // Generated methods ASTFunAppl(int id)38*0c56280aSSorin Basca ASTFunAppl(int id) { 39*0c56280aSSorin Basca super(id); 40*0c56280aSSorin Basca } 41*0c56280aSSorin Basca ASTFunAppl(MiniParser p, int id)42*0c56280aSSorin Basca ASTFunAppl(MiniParser p, int id) { 43*0c56280aSSorin Basca super(p, id); 44*0c56280aSSorin Basca } 45*0c56280aSSorin Basca jjtCreate(MiniParser p, int id)46*0c56280aSSorin Basca public static Node jjtCreate(MiniParser p, int id) { 47*0c56280aSSorin Basca return new ASTFunAppl(p, id); 48*0c56280aSSorin Basca } 49*0c56280aSSorin Basca ASTFunAppl(ASTIdent name, Function function, ASTExpr[] exprs)50*0c56280aSSorin Basca ASTFunAppl(ASTIdent name, Function function, ASTExpr[] exprs) { 51*0c56280aSSorin Basca this(JJTFUNAPPL); 52*0c56280aSSorin Basca 53*0c56280aSSorin Basca this.name = name; 54*0c56280aSSorin Basca this.function = function; 55*0c56280aSSorin Basca this.exprs = exprs; 56*0c56280aSSorin Basca } 57*0c56280aSSorin Basca 58*0c56280aSSorin Basca @Override toString()59*0c56280aSSorin Basca public String toString() { 60*0c56280aSSorin Basca return jjtNodeName[id] + " " + name.getName(); 61*0c56280aSSorin Basca } 62*0c56280aSSorin Basca 63*0c56280aSSorin Basca /** 64*0c56280aSSorin Basca * Overrides ASTExpr.closeNode() 65*0c56280aSSorin Basca */ 66*0c56280aSSorin Basca @Override closeNode()67*0c56280aSSorin Basca public void closeNode() { 68*0c56280aSSorin Basca name = (ASTIdent)children[0]; 69*0c56280aSSorin Basca 70*0c56280aSSorin Basca if(children.length > 1) { 71*0c56280aSSorin Basca exprs = new ASTExpr[children.length - 1]; 72*0c56280aSSorin Basca System.arraycopy(children, 1, exprs, 0, children.length - 1); 73*0c56280aSSorin Basca } 74*0c56280aSSorin Basca 75*0c56280aSSorin Basca children=null; // Throw away old reference 76*0c56280aSSorin Basca } 77*0c56280aSSorin Basca 78*0c56280aSSorin Basca /** 79*0c56280aSSorin Basca * Overrides ASTExpr.traverse() 80*0c56280aSSorin Basca */ 81*0c56280aSSorin Basca @Override traverse(Environment env)82*0c56280aSSorin Basca public ASTExpr traverse(Environment env) { 83*0c56280aSSorin Basca String fname = name.getName(); 84*0c56280aSSorin Basca EnvEntry entry = env.get(fname); 85*0c56280aSSorin Basca 86*0c56280aSSorin Basca this.env = env; 87*0c56280aSSorin Basca 88*0c56280aSSorin Basca if(entry == null) { 89*0c56280aSSorin Basca MiniC.addError(name.getLine(), name.getColumn(), 90*0c56280aSSorin Basca "Applying unknown function " + fname + "."); 91*0c56280aSSorin Basca } else { 92*0c56280aSSorin Basca if(!(entry instanceof Function)) { 93*0c56280aSSorin Basca MiniC.addError(name.getLine(), name.getColumn(), 94*0c56280aSSorin Basca "Applying non-function " + fname + "."); 95*0c56280aSSorin Basca } else { 96*0c56280aSSorin Basca int len = (exprs != null)? exprs.length : 0; 97*0c56280aSSorin Basca Function fun = (Function)entry; 98*0c56280aSSorin Basca 99*0c56280aSSorin Basca if(len != fun.getNoArgs()) { 100*0c56280aSSorin Basca MiniC.addError(name.getLine(), name.getColumn(), 101*0c56280aSSorin Basca "Function " + fname + " expects " + fun.getNoArgs() + 102*0c56280aSSorin Basca " arguments, you supplied " + len + "."); 103*0c56280aSSorin Basca } else { // Adjust references 104*0c56280aSSorin Basca function = fun; 105*0c56280aSSorin Basca name = fun.getName(); 106*0c56280aSSorin Basca } 107*0c56280aSSorin Basca } 108*0c56280aSSorin Basca } 109*0c56280aSSorin Basca 110*0c56280aSSorin Basca if(exprs != null) { 111*0c56280aSSorin Basca for(int i=0; i < exprs.length; i++) { 112*0c56280aSSorin Basca exprs[i] = exprs[i].traverse(env); 113*0c56280aSSorin Basca } 114*0c56280aSSorin Basca } 115*0c56280aSSorin Basca 116*0c56280aSSorin Basca return this; 117*0c56280aSSorin Basca } 118*0c56280aSSorin Basca 119*0c56280aSSorin Basca /** 120*0c56280aSSorin Basca * Second pass 121*0c56280aSSorin Basca * Overrides AstExpr.eval() 122*0c56280aSSorin Basca * @return type of expression 123*0c56280aSSorin Basca * @param expected type 124*0c56280aSSorin Basca */ 125*0c56280aSSorin Basca @Override eval(int expected)126*0c56280aSSorin Basca public int eval(int expected) { 127*0c56280aSSorin Basca String fname = name.getName(); 128*0c56280aSSorin Basca Function f = function; 129*0c56280aSSorin Basca ASTIdent fun = f.getName(); 130*0c56280aSSorin Basca ASTIdent[] args = f.getArgs(); 131*0c56280aSSorin Basca int t = fun.getType(); 132*0c56280aSSorin Basca 133*0c56280aSSorin Basca is_simple = true; // Only true if all arguments are simple expressions 134*0c56280aSSorin Basca 135*0c56280aSSorin Basca // Check arguments 136*0c56280aSSorin Basca if(exprs != null) { 137*0c56280aSSorin Basca for(int i=0; i < exprs.length; i++) { // length match checked in previous pass 138*0c56280aSSorin Basca int expect = args[i].getType(); // May be T_UNKNOWN 139*0c56280aSSorin Basca int t_e = exprs[i].eval(expect); // May be T_UNKNOWN 140*0c56280aSSorin Basca 141*0c56280aSSorin Basca if((expect != T_UNKNOWN) && (t_e != expect)) { 142*0c56280aSSorin Basca MiniC.addError(exprs[i].getLine(), exprs[i].getColumn(), 143*0c56280aSSorin Basca "Argument " + (i + 1) + " in application of " + fname + 144*0c56280aSSorin Basca " is not of type " + TYPE_NAMES[expect] + " but " + 145*0c56280aSSorin Basca TYPE_NAMES[t_e]); 146*0c56280aSSorin Basca } else { 147*0c56280aSSorin Basca args[i].setType(t_e); // Update, may be identical 148*0c56280aSSorin Basca } 149*0c56280aSSorin Basca 150*0c56280aSSorin Basca is_simple = is_simple && exprs[i].isSimple(); // Check condition 151*0c56280aSSorin Basca } 152*0c56280aSSorin Basca } 153*0c56280aSSorin Basca 154*0c56280aSSorin Basca if(t == T_UNKNOWN) { 155*0c56280aSSorin Basca fun.setType(t = expected); // May be still T_UNKNOWN 156*0c56280aSSorin Basca } 157*0c56280aSSorin Basca 158*0c56280aSSorin Basca return type = t; 159*0c56280aSSorin Basca } 160*0c56280aSSorin Basca 161*0c56280aSSorin Basca /** 162*0c56280aSSorin Basca * Fourth pass, produce Java code. 163*0c56280aSSorin Basca */ 164*0c56280aSSorin Basca @Override code(StringBuffer buf)165*0c56280aSSorin Basca public void code(StringBuffer buf) { 166*0c56280aSSorin Basca String fname = name.getName(); 167*0c56280aSSorin Basca // Function f = function; 168*0c56280aSSorin Basca // ASTIdent[] args = f.getArgs(); 169*0c56280aSSorin Basca 170*0c56280aSSorin Basca if(fname.equals("READ")) { 171*0c56280aSSorin Basca ASTFunDecl.push(buf, "_readInt()"); 172*0c56280aSSorin Basca } else if(fname.equals("WRITE")) { 173*0c56280aSSorin Basca exprs[0].code(buf); 174*0c56280aSSorin Basca ASTFunDecl.push(buf, "_writeInt(" + ASTFunDecl.pop() + ")"); 175*0c56280aSSorin Basca } 176*0c56280aSSorin Basca else { // Normal function 177*0c56280aSSorin Basca if(exprs != null) { // Output in reverse odrder 178*0c56280aSSorin Basca for(int i = exprs.length - 1; i >= 0; i--) { 179*0c56280aSSorin Basca exprs[i].code(buf); 180*0c56280aSSorin Basca } 181*0c56280aSSorin Basca } 182*0c56280aSSorin Basca 183*0c56280aSSorin Basca StringBuffer call = new StringBuffer(fname + "("); 184*0c56280aSSorin Basca // Function call 185*0c56280aSSorin Basca 186*0c56280aSSorin Basca if(exprs != null) { 187*0c56280aSSorin Basca for(int i=0; i < exprs.length; i++) { 188*0c56280aSSorin Basca call.append(ASTFunDecl.pop()); 189*0c56280aSSorin Basca if(i < exprs.length - 1) { 190*0c56280aSSorin Basca call.append(", "); 191*0c56280aSSorin Basca } 192*0c56280aSSorin Basca } 193*0c56280aSSorin Basca } 194*0c56280aSSorin Basca call.append(")"); 195*0c56280aSSorin Basca 196*0c56280aSSorin Basca ASTFunDecl.push(buf, call.toString()); 197*0c56280aSSorin Basca } 198*0c56280aSSorin Basca } 199*0c56280aSSorin Basca 200*0c56280aSSorin Basca /** 201*0c56280aSSorin Basca * Fifth pass, produce Java byte code. 202*0c56280aSSorin Basca */ 203*0c56280aSSorin Basca @Override byte_code(InstructionList il, MethodGen method, ConstantPoolGen cp)204*0c56280aSSorin Basca public void byte_code(InstructionList il, MethodGen method, ConstantPoolGen cp) { 205*0c56280aSSorin Basca String fname = name.getName(); 206*0c56280aSSorin Basca // Function f = function; 207*0c56280aSSorin Basca //ASTIdent fun = f.getName(); 208*0c56280aSSorin Basca // ASTIdent[] args = f.getArgs(); 209*0c56280aSSorin Basca String class_name = method.getClassName(); 210*0c56280aSSorin Basca 211*0c56280aSSorin Basca if(fname.equals("READ")) { 212*0c56280aSSorin Basca il.append(new INVOKESTATIC(cp.addMethodref(class_name, 213*0c56280aSSorin Basca "_readInt", 214*0c56280aSSorin Basca "()I"))); 215*0c56280aSSorin Basca } else if(fname.equals("WRITE")) { 216*0c56280aSSorin Basca exprs[0].byte_code(il, method, cp); 217*0c56280aSSorin Basca ASTFunDecl.pop(); 218*0c56280aSSorin Basca il.append(new INVOKESTATIC(cp.addMethodref(class_name, 219*0c56280aSSorin Basca "_writeInt", 220*0c56280aSSorin Basca "(I)I"))); 221*0c56280aSSorin Basca } 222*0c56280aSSorin Basca else { // Normal function 223*0c56280aSSorin Basca int size = exprs.length; 224*0c56280aSSorin Basca Type[] argv = null; 225*0c56280aSSorin Basca 226*0c56280aSSorin Basca if(exprs != null) { 227*0c56280aSSorin Basca argv = new Type[size]; 228*0c56280aSSorin Basca 229*0c56280aSSorin Basca for(int i=0; i < size; i++) { 230*0c56280aSSorin Basca argv[i] = Type.INT; 231*0c56280aSSorin Basca exprs[i].byte_code(il, method, cp); 232*0c56280aSSorin Basca } 233*0c56280aSSorin Basca 234*0c56280aSSorin Basca //ASTFunDecl.push(size); 235*0c56280aSSorin Basca } 236*0c56280aSSorin Basca 237*0c56280aSSorin Basca ASTFunDecl.pop(size); 238*0c56280aSSorin Basca 239*0c56280aSSorin Basca // Function call 240*0c56280aSSorin Basca il.append(new INVOKESTATIC(cp.addMethodref(class_name, 241*0c56280aSSorin Basca fname, 242*0c56280aSSorin Basca Type.getMethodSignature(Type.INT, 243*0c56280aSSorin Basca argv)))); 244*0c56280aSSorin Basca } 245*0c56280aSSorin Basca 246*0c56280aSSorin Basca ASTFunDecl.push(); 247*0c56280aSSorin Basca } 248*0c56280aSSorin Basca 249*0c56280aSSorin Basca // dump() inherited getName()250*0c56280aSSorin Basca public ASTIdent getName() { return name; } getFunction()251*0c56280aSSorin Basca public Function getFunction() { return function; } 252*0c56280aSSorin Basca } 253