// *** partial implementation, will be fixed in proj2 **** // NewObj --- // Id cid; public IrExp visit(AstNewObj n) { // A NewObj node should be translated into a CALL to "malloc" with a single argument representing the size // of the object, followed by a sequence of statements for initializing the object’s class variables. // A special note: the initialization expressions saved in the the symbol table entry for this purpose are // AST expressions, and need to be translated into IR expressions. Furthermore, this translation should be // conducted in the proper scope environment — the IrgenVisitor variable currClass needs to point to the // object’s class. IrStmtList stmts = new IrStmtList(); // Calculate the size of the object ClassRec classRec = symTable.GetClass(n.cid); // <get the object's ClassRec from symbol table>; int numVars = GetNumObjVars(classRec); // Construct malloc call node IrExp size = new IrBinop(IrBinop.OP.MUL, new IrConst(numVars > 0 ? numVars : 1), cWordSize); IrCall call = new IrCall(new IrName("malloc"), new IrExpList(size)); IrTemp tmp = new IrTemp(); // This TEMP will contain the location of the object variables stmts.add(new IrMove(tmp, call)); // Move the results of the malloc call into the temp GetInitStmts(classRec, stmts, tmp); // Recursively get object's variable initialization statements return new IrEseq(stmts, tmp); // Construct resulting statement }
private int GetInitStmts(ClassRec c, IrStmtList stmts, IrTemp tmp) { ClassRec saveCurrClass; VarRec v; int varCnt = 0; // Get init STMTs from inherited class if (null != c.Parent()) { varCnt = GetInitStmts(c.Parent(), stmts, tmp); } // Add init STMTs from this class for (int i = 0; i < c.VarCnt(); i++) { v = c.GetClassVarAt(i); if (null == v.Init()) { stmts.add(ObjVarInitStmt(tmp, varCnt + i, v.Idx - 1, cZero)); } else { saveCurrClass = currClass; currClass = c; IrExp e = v.Init().accept(this); currClass = saveCurrClass; stmts.add(ObjVarInitStmt(tmp, varCnt + i, v.Idx - 1, e)); } } return varCnt + c.VarCnt(); }
// Relop --- // int op; // Exp e1, e2; public IrExp visit(AstRelop n) { IrExp l = n.e1.accept(this); IrExp r = n.e2.accept(this); IrStmtList sl = new IrStmtList(); IrTemp tmp = new IrTemp(); IrName done = new IrName(); sl.add(new IrMove(tmp, cOne)); sl.add(new IrCJump(n.op, l, r, done)); sl.add(new IrMove(tmp, cZero)); sl.add(new IrLabel(done)); return new IrEseq(sl, tmp); }
// NewArray --- // int size; public IrExp visit(AstNewArray n) { IrExp size = new IrConst(n.size); IrStmtList sl = new IrStmtList(); IrName top = new IrName(); IrTemp array = new IrTemp(); IrTemp cnt = new IrTemp(); IrExp bound = new IrBinop(IrBinop.OP.MUL, new IrConst(n.size + 1), cWordSize); sl.add(new IrMove(array, new IrCall(new IrName("malloc"), new IrExpList(bound)))); sl.add(new IrMove(new IrMem(array), size)); sl.add(new IrMove(cnt, new IrBinop(IrBinop.OP.ADD, array, new IrBinop(IrBinop.OP.MUL, size, cWordSize)))); sl.add(new IrLabel(top)); sl.add(new IrMove(new IrMem(cnt), cZero)); sl.add(new IrMove(cnt, new IrBinop(IrBinop.OP.SUB, cnt, cWordSize))); sl.add(new IrCJump(IrCJump.OP.GT, cnt, array, top)); return new IrEseq(sl, array); }
private int getLValue(IrTemp t) { int addr = t.Num; return addr; }
public int visit(IrTemp t) { return temps[t.Num]; }
/* throws ParseException */ public static IrExp EXP() { IrToken t; int n; String str; IrStmt s; IrExp e, e2; IrExpList el = new IrExpList(); jj_consume_token(RegExpId.kw32); switch ((jj_ntk == RegExpId.UNDEFINED) ? jj_ntk_fn() : jj_ntk) { case RegExpId.kwESEQ: jj_consume_token(RegExpId.kwESEQ); s = STMT(); e = EXP(); e = new IrEseq(s,e); break; case RegExpId.kwMEM: jj_consume_token(RegExpId.kwMEM); e = EXP(); e = new IrMem(e); break; case RegExpId.kwBINOP: jj_consume_token(RegExpId.kwBINOP); IrBinop.OP op = binopCode(); e = EXP(); e2 = EXP(); e = new IrBinop(op,e,e2); break; case RegExpId.kwCALL: jj_consume_token(RegExpId.kwCALL); e = EXP(); jj_consume_token(RegExpId.kw32); // label_4: while (true) { switch ((jj_ntk == RegExpId.UNDEFINED) ? jj_ntk_fn() : jj_ntk) { case RegExpId.kw32: break; default: jj_la1[7] = jj_gen; goto label_4a; // break label_4; } e2 = EXP(); el.add(e2); } label_4a: jj_consume_token(RegExpId.kw35); e = new IrCall((IrName)e,el); break; case RegExpId.kwTEMP: jj_consume_token(RegExpId.kwTEMP); n = INT(); e = new IrTemp(n); break; case RegExpId.kwNAME: jj_consume_token(RegExpId.kwNAME); t = jj_consume_token(RegExpId.ID); e = new IrName(t.image); break; case RegExpId.kwFIELD: jj_consume_token(RegExpId.kwFIELD); e = EXP(); n = INT(); e = new IrField(e,n); break; case RegExpId.kwPARAM: jj_consume_token(RegExpId.kwPARAM); n = INT(); e = new IrParam(n); break; case RegExpId.kwVAR: jj_consume_token(RegExpId.kwVAR); n = INT(); e = new IrVar(n); break; case RegExpId.kwCONST: jj_consume_token(RegExpId.kwCONST); n = INT(); e = new IrConst(n); break; case RegExpId.kwSTRING: jj_consume_token(RegExpId.kwSTRING); str = STR(); e = new IrString(str); break; default: jj_la1[8] = jj_gen; jj_consume_token(RegExpId.UNDEFINED); throw new IrParseException(); } jj_consume_token(RegExpId.kw35); {if (true) return e;} throw new Error("Missing return statement in function"); }
public IrExp visit(IrTemp t) { return t; }
public IrExp visit(IrCall t) { IrExp args = t.args.accept(this); IrStmt s = getStmt(args); if (t.func.id != "malloc") { IrTemp tmp = new IrTemp(); IrStmt s1 = new IrMove(tmp, new IrCall(t.func, (IrExpList)getExp(args))); return new IrEseq(mergeStmts(s, s1), tmp); } else if (s != null) { return new IrEseq(s, new IrCall(t.func, (IrExpList)getExp(args))); } else { return t; } }