From 0fc854fdb0e738180aafca2281240632b70421b2 Mon Sep 17 00:00:00 2001 From: bill Date: Thu, 6 May 2021 08:53:56 +0800 Subject: [PATCH] Fixed all object/class/method/attr related errors --- src/main/java/chocopy/pa3/CodeGenImpl.java | 52 +++++++++++++++++----- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index c1f3651..5fb4cae 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -207,17 +207,21 @@ public class CodeGenImpl extends CodeGenBase private int sp_off; /** Variable to store maximum possible offset depending on stack size.*/ private int max_sp; - private final Register[] registerPool = {T2,T3, T4, T5, T6, A2, A3, A4, A5, A6}; - private final boolean[] registerAvilMap = {true, true, true, true, true, true, true, true, true, true}; + private boolean l_value = false; + private final Register[] registerPool = {T2,T3, T4, T5, T6, A2, A3, A4, A5, A6, A7}; + private final boolean[] registerAvilMap = {true, true, true, true, true, true, true, true, true, true, true}; private int getRegister(){ //return a handle of a vacant register - for(int i = 0; i < 10; ++i) + for(int i = 0; i < 11; ++i) if(registerAvilMap[i]) { registerAvilMap[i]=false; return i; } - for(int i = 0; i < 10; ++i) + for(int i = 0; i < 11; ++i) + { + System.out.println("Insufficient Registers!!!"); registerAvilMap[i] = true; //freeall; + } return 0; } private void freeRegister(int handle){ //handle used to free the register @@ -292,7 +296,7 @@ public class CodeGenImpl extends CodeGenBase incSp(1); backend.emitSW(A0, FP, -sp_off*wordSize, "Push argument 0 from last."); - backend.emitADDI(SP, FP, sp_off*wordSize, "Set SP to last argument."); + backend.emitADDI(SP, FP, -sp_off*wordSize, "Set SP to last argument."); backend.emitLW(A1, A0, getDispatchTableOffset(), "Load address of object's dispatch table"); backend.emitLW(A1, A1, getMethodOffset(cls, "__init__"), String.format("Load address of method: %s.__init__", cls.getClassName())); backend.emitJALR(A1, String.format("Invoke method: %s.__init", cls.getClassName())); @@ -343,13 +347,19 @@ public class CodeGenImpl extends CodeGenBase if (expr.getInferredType().equals(Type.INT_TYPE)) { if ((functionId.name.equals("print")) &&(formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.INT_TYPE))) { - backend.emitJAL(makeintLabel, "Box integer"); + if(!(args.size() == 1 && (args.get(0) instanceof CallExpr) && + (sym.get(((CallExpr) args.get(0)).function.name) instanceof ClassInfo))) + backend.emitJAL(makeintLabel, "Box integer"); + + } else { // FIXME: passed argument does not match formal parameter } } else if (expr.getInferredType().equals(Type.BOOL_TYPE)) { if ((functionId.name.equals("print"))&&(formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.BOOL_TYPE))) { - backend.emitJAL(makeboolLabel, "Box boolean"); + if(!(args.size() == 1 && (args.get(0) instanceof CallExpr) && + (sym.get(((CallExpr) args.get(0)).function.name) instanceof ClassInfo))) + backend.emitJAL(makeboolLabel, "Box boolean"); } else { // FIXME: passed argument does not match formal parameter @@ -551,14 +561,26 @@ public class CodeGenImpl extends CodeGenBase { backend.emitSW(reg, Register.FP, -sp_off*wordSize, "Store value to b stored"); incSp(1); + boolean old_lvalue = l_value; + l_value = true; Register ret = target.dispatch(this); + l_value = old_lvalue; sp_off--; - backend.emitLW(reg, Register.FP, -sp_off*wordSize, "Load value to b stored"); - backend.emitSW(reg, ret, 0, "Set list element"); + Register tmp = reg; + int tmpHandle = -1; + if(ret.equals(reg)) + { + tmpHandle = getRegister(); + tmp = registerPool[tmpHandle]; + } + backend.emitLW(tmp, Register.FP, -sp_off*wordSize, "Load value to b stored"); + backend.emitSW(tmp, ret, 0, "Set list element"); + if(tmpHandle >= 0) + freeRegister(tmpHandle); } } //} - return reg; + return null; } @Override @@ -1117,13 +1139,19 @@ public class CodeGenImpl extends CodeGenBase { ClassInfo objectClass = (ClassInfo) globalSymbols.get(node.object.getInferredType().className()); Label label = generateLocalLabel(); + boolean old_lvalue = l_value; + l_value = false; Register obj = node.object.dispatch(this); + l_value = old_lvalue; backend.emitBNEZ(obj, label, "Ensure not None"); backend.emitJ(errorNone, "Go to error handler"); backend.emitLocalLabel(label, "Not None"); - backend.emitLW(A0, obj, getAttrOffset(objectClass, node.member.name), - String.format("Get attribute: %s.%s", objectClass.getClassName(), node.member.name)); + if(l_value) + backend.emitADDI(A0, obj, getAttrOffset(objectClass, node.member.name), "get address of attr"); + else + backend.emitLW(A0, obj, getAttrOffset(objectClass, node.member.name), + String.format("Get value of attribute: %s.%s", objectClass.getClassName(), node.member.name)); return A0; } }