// *** partial implementation, will be fixed in proj2 **** // Call --- // Exp obj; // Id cid, mid; // ExpList args; public IrExp visit(AstCall 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 IrCall(new IrName(label), el); }
public AstType visit(AstCall n) { return null; }
/* throws ParseException */ /* final */ public static AstExp astExp() { AstType t; AstToken n; AstRelop.OP relop; AstBinop.OP binop; AstUnop.OP unop; AstExp e, e1, e2; AstExpList el; jj_consume_token(AstRegExpId.kw56); switch ((jj_ntk == AstRegExpId.UNDEFINED)?jj_ntk_fn():jj_ntk) { case AstRegExpId.kwArrayElm: jj_consume_token(AstRegExpId.kwArrayElm); e1 = astExp(); e2 = astExp(); e = new AstArrayElm(e1,e2); break; case AstRegExpId.kwArrayLen: jj_consume_token(AstRegExpId.kwArrayLen); e1 = astExp(); e = new AstArrayLen(e1); break; case AstRegExpId.kwBinop: jj_consume_token(AstRegExpId.kwBinop); binop = binOp(); e1 = astExp(); e2 = astExp(); e = new AstBinop(binop,e1,e2); break; case AstRegExpId.kwBoolVal: jj_consume_token(AstRegExpId.kwBoolVal); switch ((jj_ntk == AstRegExpId.UNDEFINED)?jj_ntk_fn():jj_ntk) { case AstRegExpId.kwTrue: jj_consume_token(AstRegExpId.kwTrue); e = new AstBoolVal(true); break; case AstRegExpId.kwFalse: jj_consume_token(AstRegExpId.kwFalse); e = new AstBoolVal(false); break; default: jj_la1[12] = jj_gen; jj_consume_token(AstRegExpId.UNDEFINED); throw new AstParseException(); } break; case AstRegExpId.kwCall: jj_consume_token(AstRegExpId.kwCall); e1 = astExp(); e2 = astExp(); el = astExpList(); e = new AstCall(e1,(AstId)e2,el); break; case AstRegExpId.kwId: jj_consume_token(AstRegExpId.kwId); n = jj_consume_token(AstRegExpId.ID); e = new AstId(n.image); break; case AstRegExpId.kwIntVal: jj_consume_token(AstRegExpId.kwIntVal); n = jj_consume_token(AstRegExpId.INTVAL); e = new AstIntVal(int.Parse(n.image)); break; case AstRegExpId.kwField: jj_consume_token(AstRegExpId.kwField); e1 = astExp(); e2 = astExp(); e = new AstField(e1,(AstId)e2); break; case AstRegExpId.kwNewArray: jj_consume_token(AstRegExpId.kwNewArray); t = astType(); n = jj_consume_token(AstRegExpId.INTVAL); e = new AstNewArray((AstType)t, int.Parse(n.image)); break; case AstRegExpId.kwNewObj: jj_consume_token(AstRegExpId.kwNewObj); e1 = astExp(); el = astExpList(); e = new AstNewObj((AstId)e1,el); break; case AstRegExpId.kwRelop: jj_consume_token(AstRegExpId.kwRelop); relop = relOp(); e1 = astExp(); e2 = astExp(); e = new AstRelop(relop, e1, e2); break; case AstRegExpId.kwStrVal: jj_consume_token(AstRegExpId.kwStrVal); n = jj_consume_token(AstRegExpId.STRVAL); String s = n.image; e = new AstStrVal(s.Substring(1, s.Length-2)); break; case AstRegExpId.kwThis: jj_consume_token(AstRegExpId.kwThis); e = new AstThis(); break; case AstRegExpId.kwUnop: jj_consume_token(AstRegExpId.kwUnop); unop = unOp(); e1 = astExp(); e = new AstUnop(unop,e1); break; case AstRegExpId.kwNullExp: jj_consume_token(AstRegExpId.kwNullExp); e = null; break; default: jj_la1[13] = jj_gen; jj_consume_token(AstRegExpId.UNDEFINED); throw new AstParseException(); } jj_consume_token(AstRegExpId.kw57); {if (true) return e;} throw new Error("Missing return statement in function"); }
/* throws Exception */ // Call --- // Exp obj; // Id mid; // ExpList args; public AstType visit(AstCall n) { AstType t = n.obj.accept(this); if (null == (t as AstObjType)) throw new TypeException("Object in Call 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); } return m.RType(); }