// *** partial implementation, will be fixed in proj2 **** // CallStmt --- // Exp obj; // Id mid; // ExpList args; public IrStmt visit(AstCallStmt n) { string label; // An Important Detail: The TypeVisitor program has its own copy of // currClass and currMethod. These two variables need to be set to the // current environment before typechecking can work. Do the following: tv.setClass(currClass); tv.setMethod(currMethod); // 1. Perform typechecking on the obj component of the Call/CallStmt // node, which should return an ObjType representing the obj's class. AstObjType t = (AstObjType)n.obj.accept(tv); // 2. Look up the MethodRec with the class info. ClassRec classRec = symTable.GetClass(t.cid); MethodRec methodRec = symTable.GetMethod(classRec, n.mid); IrExp accessLink = n.obj.accept(this); IrExpList el = new IrExpList(accessLink); el.addAll(n.args.accept(this)); if (maxArgCnt <= n.args.Count()) maxArgCnt = n.args.Count() + 1; if (methodRec.Id().s.CompareTo("main") == 0) label = "main"; else label = symTable.UniqueMethodName(classRec, methodRec.Id()); return new IrCallst(new IrName(label), el); //return new CALLST(new NAME(n.mid.s), el); }
public void visit(AstCallStmt n) { }
/* throws ParseException */ /* final */ public static AstStmt astStmt() { AstExp e1, e2; AstStmt s, s1, s2; AstExpList el; AstStmtList sl; jj_consume_token(AstRegExpId.kw56); switch ((jj_ntk == AstRegExpId.UNDEFINED)?jj_ntk_fn():jj_ntk) { case AstRegExpId.kwBlock: jj_consume_token(AstRegExpId.kwBlock); sl = astStmtList(); s = new AstBlock(sl); break; case AstRegExpId.kwAssign: jj_consume_token(AstRegExpId.kwAssign); e1 = astExp(); e2 = astExp(); s = new AstAssign(e1,e2); break; case AstRegExpId.kwCallStmt: jj_consume_token(AstRegExpId.kwCallStmt); e1 = astExp(); e2 = astExp(); el = astExpList(); s = new AstCallStmt(e1,(AstId)e2,el); break; case AstRegExpId.kwIf: jj_consume_token(AstRegExpId.kwIf); e1 = astExp(); s1 = astStmt(); s2 = astStmt(); s = new AstIf(e1,s1,s2); break; case AstRegExpId.kwWhile: jj_consume_token(AstRegExpId.kwWhile); e1 = astExp(); s1 = astStmt(); s = new AstWhile(e1,s1); break; case AstRegExpId.kwPrint: jj_consume_token(AstRegExpId.kwPrint); e1 = astExp(); s = new AstPrint(e1); break; case AstRegExpId.kwReturn: jj_consume_token(AstRegExpId.kwReturn); e1 = astExp(); s = new AstReturn(e1); break; case AstRegExpId.kwNullStmt: jj_consume_token(AstRegExpId.kwNullStmt); s = null; break; default: jj_la1[8] = jj_gen; jj_consume_token(AstRegExpId.UNDEFINED); throw new AstParseException(); } jj_consume_token(AstRegExpId.kw57); {if (true) return s;} throw new Error("Missing return statement in function"); }
/* throws Exception */ // CallStmt --- // Exp obj; // Id mid; // ExpList args; public void visit(AstCallStmt n) { AstType t = n.obj.accept(this); if ((null == (t as AstObjType))) throw new TypeException("Object in CallStmt is not ObjType: " + t); ClassRec c = symTable.GetClass(((AstObjType) t).cid); MethodRec m = symTable.GetMethod(c, n.mid); int paramCnt = m.ParamCnt(); int argCnt = (n.args == null) ? 0 : n.args.Count(); if (paramCnt != argCnt) { throw new TypeException("Formals' and actuals' counts don't match: " + paramCnt + " vs. " + argCnt); } for (int i=0; i<paramCnt; i++) { AstType t1 = m.GetParamAt(i).Type(); AstType t2 = n.args[i].accept(this); if (!compatible(t1,t2)) throw new TypeException("Formal's and actual's types not compatible: " + t1 + " vs. " + t2); } }