diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 8405d03..83d4b4e 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -1,5 +1,6 @@ package chocopy.pa3; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -146,7 +147,6 @@ public class CodeGenImpl extends CodeGenBase varSlotMap.put(var.getVarName(), requiredStackSpace-emptySlotNum*wordSize); emptySlotNum++; } - // --- Function Body --- // statements load all the variables that caller put on stack // statements use fp to load the variables @@ -208,9 +208,6 @@ public class CodeGenImpl extends CodeGenBase /** Label of code that exits from block. */ protected Label elseBlock; - /** Variable to keep track of offsets of stored variables */ - private Map offsetMap = new HashMap<>(); - /** Variable to keep track of slots of stored variables on stack */ // example usage: backend.emitLW(A0, SP, varSlotMap.get(varName)) to load the variable using its name private Map varSlotMap = new HashMap<>(); @@ -223,7 +220,7 @@ public class CodeGenImpl extends CodeGenBase 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 int getRegister(){ //return a handle of a vacant reg + private int getRegister(){ //return a handle of a vacant register for(int i = 0; i < 10; ++i) if(registerAvilMap[i]) return i; @@ -231,9 +228,10 @@ public class CodeGenImpl extends CodeGenBase registerAvilMap[i] = true; //freeall; return 0; } - private void freeRegister(int handle){ //handle used to free the reg + private void freeRegister(int handle){ //handle used to free the register registerAvilMap[handle] = false; } + /** * An analyzer for the function described by FUNCINFO0, which is null for the * top level. @@ -428,9 +426,9 @@ public class CodeGenImpl extends CodeGenBase { System.out.println("Inside AssignStmt: "); backend.emitLW(T6, FP, 0, "Inside AssignStmt: "); - Type t = node.value.getInferredType(); + //Type t = node.value.getInferredType(); // if(t.isSpecialType() || t.isListType()) - { + //{ Register reg = node.value.dispatch(this); if (reg == null) reg = A0; @@ -455,19 +453,18 @@ public class CodeGenImpl extends CodeGenBase for(Expr target: node.targets) { StackVarInfo svi = (StackVarInfo) sym.get(((Identifier)target).name); - int loc = offsetMap.get(svi); - backend.emitSW(reg, Register.FP, -loc*4, "Load local variable: "+svi.getVarName()); + backend.emitLW(reg, SP, varSlotMap.get(svi.getVarName()),"Load local variable: "+svi.getVarName()); } } - } - return Register.A0; + //} + return reg; } @Override public Register analyze(ExprStmt node) { System.out.println("Inside ExprStmt: "); - backend.emitLW(T6, FP, 0, "Inside ExprStmt: "); + backend.emitLW(T6, FP, 0, "Inside ExprStmt: "); node.expr.dispatch(this); return null; } @@ -479,7 +476,7 @@ public class CodeGenImpl extends CodeGenBase System.out.println("Inside IfExpr: "); Register result = node.condition.dispatch(this); Label ln = generateLocalLabel(); - backend.emitBEQZ(result, ln,"Jump to beginning of loop"); + backend.emitBEQZ(result, ln,"Jump to end of loop"); node.thenExpr.dispatch(this); backend.emitJ(ln, "Jump to end of if expression"); backend.emitLocalLabel(elseBlock, "Else part of if expression"); @@ -491,12 +488,11 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(IfStmt node) { - System.out.println("Inside IfStmt: "); Register result = node.condition.dispatch(this); Label ln = generateLocalLabel(); - backend.emitBEQZ(result, ln,"Jump to beginning of loop"); + backend.emitBEQZ(result, ln,"Jump to end of loop"); for(Stmt s:node.thenBody) s.dispatch(this); backend.emitJ(ln, "Jump to end of if statement"); @@ -573,7 +569,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(BinaryExpr node) { - System.out.println("Inside BinaryExpr: "); + System.out.println("Inside BinaryExpr: "); String operator = node.operator; backend.emitLW(T6, FP, 0, "Inside BinaryExpr: "); @@ -753,7 +749,7 @@ public class CodeGenImpl extends CodeGenBase backend.emitSEQZ(Register.T0, Register.A0, "Not operation on Register A0"); } else - System.err.println("return null!"); + backend.emitJAL(errorNI, "Operator not implemented"); return Register.A0; } @@ -768,22 +764,23 @@ public class CodeGenImpl extends CodeGenBase } else { -// FIXME: This breaks, so had to comment it -// VarInfo svi = (VarInfo) sym.get(node.name); -// int loc = offsetMap.get(svi); -// backend.emitLW(Register.A0, Register.FP, -loc*4, "Load local variable: "+svi.getVarName()); + VarInfo svi = (VarInfo) sym.get(node.name); + backend.emitLW(Register.A0, SP, varSlotMap.get(svi.getVarName()),"Load local variable: "+svi.getVarName()); } - return A0; + return Register.A0; } @Override public Register analyze(VarDef node) { + /* StackVarInfo svi = (StackVarInfo) sym.get(node.var.identifier.name); node.value.dispatch(this); backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Store variable "+node.var.identifier.name+" value in Stack"); + varSlotMap.put(node.var.identifier.name, requiredStackSpace-emptySlotNum*wordSize); + offsetMap.put(svi, sp_off); - incSp(1); + incSp(1);*/ return null; } @@ -842,22 +839,99 @@ public class CodeGenImpl extends CodeGenBase } - @Override - public Register analyze(ForStmt node) { - //System.out.println(node); - /* - node. - Label startLoop = generateLocalLabel(); - backend.emitLocalLabel(startLoop, "Beginning of while loop"); - node.condition.dispatch(this); - Label endLoop = elseBlock; - for(Stmt stmt:node.body) - stmt.dispatch(this); - backend.emitJ(startLoop, "Jump to beginning of loop"); - backend.emitLocalLabel(endLoop, "End of while loop");*/ + @Override + public Register analyze(ForStmt node) + { + int r; + List regs= new ArrayList(); + if (node.iterable.getInferredType().isListType()) + { + Label startLoop = generateLocalLabel(); + Label endLoop = generateLocalLabel(); + r=getRegister(); + regs.add(r); + Register iden = registerPool[r]; + node.iterable.dispatch(this); + r=getRegister(); + regs.add(r); + Register l = registerPool[r]; + r=getRegister(); + regs.add(r); + Register ln = registerPool[r]; + backend.emitMV(l,Register.A0,"Location of list"); + r=getRegister(); + regs.add(r); + Register iter = registerPool[r]; + backend.emitMV(iter, Register.ZERO, "Initialize index variable"); + backend.emitLocalLabel(startLoop, "Start for loop"); + backend.emitLW(ln, l, getAttrOffset(listClass, "__len__"), "Get attribute __len__"); + backend.emitBGE(iter, ln, endLoop, "Jump to end loop if counter exceeds length"); + backend.emitADDI(iden, iter, 4, "Compute list element offset in words"); + backend.emitLI(ln, wordSize, "Word size in bytes"); + backend.emitMUL(iden, iden, ln, "Compute list element offset in bytes"); + backend.emitADD(iden, l, iden, "Pointer to list element"); + backend.emitLW(iden, iden, 0, "Set list element"); + if(sym.getParent() == null) + { + GlobalVarInfo gvi=(GlobalVarInfo) sym.get(node.identifier.name); + backend.emitSW(iden, gvi.getLabel(), Register.T0, "Assign global: "+node.identifier.name+"(using tmp register)"); + } + else + backend.emitSW(iden, SP, varSlotMap.get(node.identifier.name),"Store local variable: "+node.identifier.name); + for(Stmt stmt:node.body) + stmt.dispatch(this); + backend.emitADDI(iter, iter, 1, "Increment counter"); + backend.emitJ(startLoop, "Jump to beginning of loop"); + backend.emitLocalLabel(endLoop, "End of for loop"); + } + else if (node.iterable.getInferredType().equals(Type.STR_TYPE)) + { + Label startLoop = generateLocalLabel(); + Label endLoop = generateLocalLabel(); + r=getRegister(); + regs.add(r); + Register iden = registerPool[r]; + node.iterable.dispatch(this); + r=getRegister(); + regs.add(r); + Register l = registerPool[r]; + r=getRegister(); + regs.add(r); + Register ln = registerPool[r]; + backend.emitMV(l,Register.A0,"Location of String"); + r=getRegister(); + regs.add(r); + Register iter = registerPool[r]; + backend.emitMV(iter, Register.ZERO, "Initialize index variable"); + backend.emitLocalLabel(startLoop, "Start for loop"); + backend.emitLW(ln, l, getAttrOffset(strClass, "__len__"), "Get attribute __len__"); + backend.emitBGE(iter, ln, endLoop, "Jump to end loop if counter exceeds length"); + + backend.emitADDI(iden, iter, 4 * wordSize, "Convert index to offset to char in bytes"); + backend.emitLBU(iden, iden, 0, "Load character"); + + if(sym.getParent() == null) + { + GlobalVarInfo gvi=(GlobalVarInfo) sym.get(node.identifier.name); + backend.emitSW(iden, gvi.getLabel(), Register.T0, "Assign global: "+node.identifier.name+"(using tmp register)"); + } + else + backend.emitSW(iden, SP, varSlotMap.get(node.identifier.name),"Store local variable: "+node.identifier.name); + for(Stmt stmt:node.body) + stmt.dispatch(this); + backend.emitADDI(iter, iter, 1, "Increment counter"); + backend.emitJ(startLoop, "Jump to beginning of loop"); + backend.emitLocalLabel(endLoop, "End of for loop"); + } + else + { + System.out.println("Iterable not a list or a string"); + } + for(int n:regs) + freeRegister(n); return null; - } + } @Override public Register analyze(IndexExpr node) @@ -870,7 +944,8 @@ public class CodeGenImpl extends CodeGenBase int tmpHandle = getRegister(); Register temp= registerPool[tmpHandle]; - if (node.list.getInferredType().isListType()) { + if (node.list.getInferredType().isListType()) + { backend.emitLW(vacantReg, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off)); final Label bp = generateLocalLabel(); backend.emitBNEZ(listObj, bp, "Ensure not None"); @@ -886,7 +961,9 @@ public class CodeGenImpl extends CodeGenBase backend.emitMUL(index, index, temp, "Compute list element offset in bytes"); backend.emitADD(index, listObj, index, "Pointer to list element"); backend.emitLW(vacantReg, index, 0, "Set list element"); - } else { + } + else + { backend.emitLW(vacantReg, FP, - sp_off * wordSize, String.format("Peek stack slot %d", sp_off- 1)); Label boundchk = generateLocalLabel(); backend.emitLW(temp, vacantReg, getAttrOffset(strClass, "__len__"), "Load attribute: __len__");