From 4d97a84bce204f4f640145c0b0fa8cf5ccf397b0 Mon Sep 17 00:00:00 2001 From: Sanjar Ahmadov Date: Sun, 2 May 2021 09:39:20 -0400 Subject: [PATCH 01/37] cleanup --- src/main/java/chocopy/pa3/CodeGenImpl.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index a68cd68..a9e384f 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -363,6 +363,9 @@ public class CodeGenImpl extends CodeGenBase int slotNum = argNum + 1; // We have extra slot for static link Expr expr = args.get(i); expr.dispatch(this); + // FIXME: Box primitives here + + // All expressions should save their end result in A0 // So, once expr is evaluated add value inside A0 onto stack as an argument backend.emitSW(A0, SP, -wordSize*slotNum, "Push argument " + argNum + " from left"); @@ -689,13 +692,7 @@ public class CodeGenImpl extends CodeGenBase public Register analyze(IntegerLiteral node) { backend.emitLW(T6, FP, 0, "Inside IntegerLiteral: " + node.value); backend.emitLI(A0, node.value, "Load integer literal " + node.value); - backend.emitJAL(makeIntLabel, "Box integer"); -// System.out.println("+++ Inside IntegerLiteral"); -// backend.emitLA(A0, new Label("$int$prototype"), "Load prototype"); -// backend.emitJAL(new Label("ra, alloc"), ""); -// backend.emitLI(T0, node.value, "Load integer " + node.value); -// backend.emitSW(T0, A0, "@.__int__", null); - + backend.emitJAL(makeIntLabel, "Box integer"); return A0; } From bcf37be308e8ef0017515e7484877b8ed74d98fd Mon Sep 17 00:00:00 2001 From: Sanjar Ahmadov Date: Sun, 2 May 2021 09:40:03 -0400 Subject: [PATCH 02/37] added makeint --- src/main/asm/chocopy/common/makeint.s | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/asm/chocopy/common/makeint.s diff --git a/src/main/asm/chocopy/common/makeint.s b/src/main/asm/chocopy/common/makeint.s new file mode 100644 index 0000000..9fbf065 --- /dev/null +++ b/src/main/asm/chocopy/common/makeint.s @@ -0,0 +1,11 @@ +# Box integer + addi sp, sp, -8 + sw ra, 4(sp) + sw a0, 0(sp) + la a0, $int$prototype + jal ra, alloc + lw t0, 0(sp) + sw t0, @.__int__(a0) + lw ra, 4(sp) + addi sp, sp, 8 + jr ra \ No newline at end of file From c0e7c2a87832d6a2551319047ea1c135a096422a Mon Sep 17 00:00:00 2001 From: Sanjar Ahmadov Date: Sun, 2 May 2021 09:49:23 -0400 Subject: [PATCH 03/37] added test scripts --- build.sh | 3 +++ generate_assembly_r.sh | 12 ++++++++++++ generate_assembly_s.sh | 12 ++++++++++++ run_r.sh | 12 ++++++++++++ run_s.sh | 12 ++++++++++++ test_sample.sh | 5 +++++ 6 files changed, 56 insertions(+) create mode 100755 build.sh create mode 100755 generate_assembly_r.sh create mode 100755 generate_assembly_s.sh create mode 100755 run_r.sh create mode 100755 run_s.sh create mode 100755 test_sample.sh diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..f4e6621 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +mvn clean package -e diff --git a/generate_assembly_r.sh b/generate_assembly_r.sh new file mode 100755 index 0000000..fb40b97 --- /dev/null +++ b/generate_assembly_r.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +FILENAME=$1 + +if [ -z "$1" ] ; then + echo "FILENAME is missing" + exit 1 +fi + +echo "Generating assembly code for file ${FILENAME}" + +java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy --pass=rrr ${FILENAME} diff --git a/generate_assembly_s.sh b/generate_assembly_s.sh new file mode 100755 index 0000000..129dd7f --- /dev/null +++ b/generate_assembly_s.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +FILENAME=$1 + +if [ -z "$1" ] ; then + echo "FILENAME is missing" + exit 1 +fi + +echo "Generating assembly code for file ${FILENAME}" + +java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy --pass=rrs ${FILENAME} diff --git a/run_r.sh b/run_r.sh new file mode 100755 index 0000000..2ab3ab0 --- /dev/null +++ b/run_r.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +FILENAME=$1 + +if [ -z "$1" ] ; then + echo "FILENAME is missing" + exit 1 +fi + +echo "Running file ${FILENAME}" + +java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy --pass=rrr --run ${FILENAME} diff --git a/run_s.sh b/run_s.sh new file mode 100755 index 0000000..9d41415 --- /dev/null +++ b/run_s.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +FILENAME=$1 + +if [ -z "$1" ] ; then + echo "FILENAME is missing" + exit 1 +fi + +echo "Running file ${FILENAME}" + +java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy --pass=rrs --run ${FILENAME} diff --git a/test_sample.sh b/test_sample.sh new file mode 100755 index 0000000..eaaa8bf --- /dev/null +++ b/test_sample.sh @@ -0,0 +1,5 @@ +#!/bin/bash + + +echo "Running all test cases inside src/test/data/pa3/sample/ folder)" +java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy --pass=rrs --test --run --dir src/test/data/pa3/sample/ From 3c4eeb2fdc4fd2fe5c571aba2ed8226f4792deac Mon Sep 17 00:00:00 2001 From: Sanjar Ahmadov Date: Sun, 2 May 2021 10:24:15 -0400 Subject: [PATCH 04/37] Added .equiv directives. Need to fix runtime exceptions --- src/main/asm/chocopy/common/makeint.s | 16 +--------------- src/main/java/chocopy/pa3/CodeGenImpl.java | 8 ++++++-- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/main/asm/chocopy/common/makeint.s b/src/main/asm/chocopy/common/makeint.s index e98fbc6..9fbf065 100644 --- a/src/main/asm/chocopy/common/makeint.s +++ b/src/main/asm/chocopy/common/makeint.s @@ -1,4 +1,3 @@ -<<<<<<< HEAD # Box integer addi sp, sp, -8 sw ra, 4(sp) @@ -9,17 +8,4 @@ sw t0, @.__int__(a0) lw ra, 4(sp) addi sp, sp, 8 - jr ra -======= - - addi sp, sp, -8 - sw ra, 4(sp) - sw a0, 0(sp) - la a0, $int$prototype - jal ra, alloc - lw t0, 0(sp) - sw t0, @.__int__(a0) - lw ra, 4(sp) - addi sp, sp, 8 - jr ra ->>>>>>> origin/bill/merge-cond-cls + jr ra \ No newline at end of file diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 766860c..939b9f0 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -56,8 +56,12 @@ public class CodeGenImpl extends CodeGenBase /** A code generator emitting instructions to BACKEND. */ public CodeGenImpl(RiscVBackend backend) { + super(backend); - + backend.defineSym("listHeaderWords", "4"); + backend.defineSym("strHeaderWords", "4"); + backend.defineSym("bool.True", "const_1"); + backend.defineSym("bool.False", "const_0"); } @@ -76,6 +80,7 @@ public class CodeGenImpl extends CodeGenBase */ protected void emitTopLevel(List statements) { + StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(null); backend.emitADDI(SP, SP, -2 * backend.getWordSize(), "Saved FP and saved RA (unused at top level)."); backend.emitSW(ZERO, SP, 0, "Top saved FP is 0."); @@ -848,7 +853,6 @@ public class CodeGenImpl extends CodeGenBase * to out-of-bounds error and abort"); */ protected void emitCustomCode() { - emitStdFunc("concat"); emitStdFunc("conslist"); emitStdFunc("strcat"); From 026eb099b0f679a57b1aa2938c554d74e0a8a714 Mon Sep 17 00:00:00 2001 From: Sanjar Ahmadov Date: Sun, 2 May 2021 10:54:51 -0400 Subject: [PATCH 05/37] Add jump to label in return statement --- src/main/java/chocopy/pa3/CodeGenImpl.java | 27 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 939b9f0..d4b4cfa 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -236,7 +236,10 @@ public class CodeGenImpl extends CodeGenBase // *********** functions start *********** public Register analyze(CallExpr node) { + System.out.println("Inside CallExpr: " + node.function.name); backend.emitLW(T6, FP, 0, "Inside CallExpr: " + node.function.name); + + SymbolInfo Ty = globalSymbols.get(node.function.name); if(Ty instanceof ClassInfo){ //object create @@ -295,6 +298,7 @@ public class CodeGenImpl extends CodeGenBase } public Register analyze(MethodCallExpr node) { + System.out.println("Inside MethodCallExpr: " + node.method.member.name); backend.emitLW(T6, FP, 0, "Inside MethodCallExpr: " + node.method.member.name); Register obj = node.method.object.dispatch(this); int n_args = node.args.size(); @@ -327,6 +331,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(ReturnStmt stmt) { + System.out.println("Inside ReturnStmt: "); backend.emitLW(T6, FP, 0, "Inside ReturnStmt: "); Expr expr = stmt.value; if (expr == null) { @@ -336,7 +341,7 @@ public class CodeGenImpl extends CodeGenBase // All expressions should save their end result in A0 expr.dispatch(this); - + backend.emitJ(this.epilogue, "Jump to function epilogue"); return A0; } @@ -347,6 +352,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(NoneLiteral node) { + System.out.println("Inside NoneLiteral: "); backend.emitLW(T6, FP, 0, "Inside NoneLiteral: "); backend.emitMV(Register.A0, Register.ZERO, "Load none"); return Register.A0; @@ -355,6 +361,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(StringLiteral node) { + System.out.println("Inside StringLiteral: "); backend.emitLW(T6, FP, 0, "Inside StringLiteral: "); Label l = constants.getStrConstant(node.value); backend.emitLA(Register.A0, l, "Load string literal"); @@ -364,6 +371,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(BooleanLiteral node) { + System.out.println("Inside BooleanLiteral: "); backend.emitLW(T6, FP, 0, "Inside BooleanLiteral: "); if(node.value==true) backend.emitLI(Register.A0, 1, "Load boolean literal: true "); @@ -376,6 +384,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(AssignStmt node) { + System.out.println("Inside AssignStmt: "); backend.emitLW(T6, FP, 0, "Inside AssignStmt: "); Type t = node.value.getInferredType(); // if(t.isSpecialType() || t.isListType()) @@ -415,6 +424,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(ExprStmt node) { + System.out.println("Inside ExprStmt: "); backend.emitLW(T6, FP, 0, "Inside ExprStmt: "); node.expr.dispatch(this); return null; @@ -423,6 +433,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(IfExpr node) { + System.out.println("Inside IfExpr: "); node.condition.dispatch(this); Label ln = generateLocalLabel(); node.thenExpr.dispatch(this); @@ -436,6 +447,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(IfStmt node) { + System.out.println("Inside IfStmt: "); node.condition.dispatch(this); Label ln = generateLocalLabel(); for(Stmt s:node.thenBody) @@ -514,6 +526,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(BinaryExpr node) { + System.out.println("Inside BinaryExpr: "); String operator = node.operator; backend.emitLW(T6, FP, 0, "Inside BinaryExpr: "); @@ -724,15 +737,18 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(WhileStmt node) { + System.out.println("Inside WhileStmt: "); Label startLoop = generateLocalLabel(); backend.emitLocalLabel(startLoop, "Beginning of while loop"); node.condition.dispatch(this); Label endLoop = elseBlock; - for(Stmt stmt:node.body) + for(Stmt stmt:node.body) { + System.out.println("Inside WhileStmt: for loop " + stmt.toString()); stmt.dispatch(this); + } backend.emitJ(startLoop, "Jump to beginning of loop"); backend.emitLocalLabel(endLoop, "End of while loop"); - + System.out.println("Inside WhileStmt: Done with while"); return null; } @@ -765,9 +781,12 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(IntegerLiteral node) { + System.out.println("Inside IntegerLiteral: " + node.value); backend.emitLW(T6, FP, 0, "Inside IntegerLiteral: " + node.value); backend.emitLI(A0, node.value, "Load integer literal " + node.value); - //backend.emitJAL(makeintLabel, "Box integer"); + + // FIXME: Remove line below later once you are boxing it in function call + backend.emitJAL(makeintLabel, "Box integer"); return A0; } From 398563d8ba229fb4eaed23cd7033de2adc900adf Mon Sep 17 00:00:00 2001 From: Sanjar Ahmadov Date: Sun, 2 May 2021 12:46:35 -0400 Subject: [PATCH 06/37] fixed issue in boxing --- src/main/java/chocopy/pa3/CodeGenImpl.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 42cc067..eac3a3b 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -129,7 +129,7 @@ public class CodeGenImpl extends CodeGenBase StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(funcInfo); int emptySlotNum = 4; - // backend.emitLW(A0, SP, varSlotMap.get(varName)) to load the variable using its name + // example usage: backend.emitLW(A0, SP, varSlotMap.get(varName)) to load the variable using its name Map varSlotMap = stmtAnalyzer.varSlotMap; for (int i = 0; i < funcInfo.getParams().size(); i++) { @@ -214,6 +214,7 @@ public class CodeGenImpl extends CodeGenBase 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<>(); private final String size_label; @@ -304,13 +305,13 @@ public class CodeGenImpl extends CodeGenBase if (expr.getInferredType().equals(Type.INT_TYPE)) { if (formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.INT_TYPE)) { - backend.emitJ(makeintLabel, "Box integer"); + backend.emitJAL(makeintLabel, "Box integer"); } else { // FIXME: passed argument does not match formal parameter } } else if (expr.getInferredType().equals(Type.BOOL_TYPE)) { if (formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.BOOL_TYPE)) { - backend.emitJ(makeboolLabel, "Box boolean"); + backend.emitJAL(makeboolLabel, "Box boolean"); } else { // FIXME: passed argument does not match formal parameter } From a86d93fcac34548d26bb1215c9ec1df7ca1e2538 Mon Sep 17 00:00:00 2001 From: bill Date: Mon, 3 May 2021 15:22:05 +0800 Subject: [PATCH 07/37] Index Expr, register pool, changed incSp --- .vscode/launch.json | 4 +- src/main/java/chocopy/pa3/CodeGenImpl.java | 106 ++++++++++++++------- 2 files changed, 73 insertions(+), 37 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 53608f3..40395d9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,8 +12,8 @@ "request": "launch", "classPaths": ["chocopy-ref.jar:target/assignment.jar"], "mainClass": "chocopy.ChocoPy", - //"args": [ "--pass=rrs", "--test","--dir", "src/test/data/pa3/sample/list_set_element_oob_1.py"], - "args": [ "--pass=rrs", "--test","--dir", "test.py"], + "args": [ "--pass=rrs", "--test","--dir", "src/test/data/pa3/sample/stmt_return_early.py"], + //"args": [ "--pass=rrs", "--test","--dir", "test.py"], "sourcePaths": [] } ] diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 939b9f0..4cd9c6f 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -5,14 +5,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import chocopy.common.analysis.AbstractNodeAnalyzer; -import chocopy.common.analysis.SymbolTable; +import chocopy.common.analysis.*; import chocopy.common.astnodes.*; import chocopy.common.analysis.types.*; import chocopy.common.codegen.*; -import static chocopy.common.codegen.RiscVBackend.Register.*; import chocopy.common.codegen.RiscVBackend.Register; +import static chocopy.common.codegen.RiscVBackend.Register.*; /** @@ -207,7 +206,19 @@ 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 int getRegister(){ //return a handle of a vacant reg + for(int i = 0; i < 10; ++i) + if(registerAvilMap[i]) + return i; + for(int i = 0; i < 10; ++i) + registerAvilMap[i] = true; //freeall; + return 0; + } + private void freeRegister(int handle){ //handle used to free the reg + registerAvilMap[handle] = false; + } /** * An analyzer for the function described by FUNCINFO0, which is null for the * top level. @@ -226,7 +237,7 @@ public class CodeGenImpl extends CodeGenBase epilogue = generateLocalLabel(); } private void incSp(int i){ - sp_off+=i+1; + sp_off+=i; max_sp = max_sp >= sp_off?max_sp:sp_off; } @@ -257,7 +268,7 @@ public class CodeGenImpl extends CodeGenBase String.format("Load pointer to prototype of: %s", cls.getClassName())); backend.emitJAL(objectAllocLabel, "Allocate new object in A0"); backend.emitSW(A0, FP, -sp_off*wordSize, String.format("Push on stack slot %d", sp_off)); - incSp(0); + incSp(1); backend.emitSW(A0, FP, -sp_off*wordSize, "Push argument 0 from last."); backend.emitADDI(SP, FP, sp_off, "Set SP to last argument."); @@ -687,7 +698,7 @@ public class CodeGenImpl extends CodeGenBase backend.emitSEQZ(Register.T0, Register.A0, "Not operation on Register A0"); } else - return null; + System.err.println("return null!"); return Register.A0; } @@ -789,35 +800,60 @@ public class CodeGenImpl extends CodeGenBase } - @Override - public Register analyze(IndexExpr node) - { -// incSp(1); -// Register listObj = node.list.dispatch(this); -// backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off)); -// Register index = node.index.dispatch(this); -// Register vacantReg = (index != A0) ? A0 : A1; -// -// if (node.list.getInferredType().isListType()) { -// backend.emitLW(vacantReg, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off)); -// -// this.d(vacantReg); -// return this.a(vacantReg, index, A0, false); -// }else{ -// this.a(0, vacantReg); -// Register a = a(index); -// Label ch = generateLocalLabel(); -// backend.emitLW(a, vacantReg, getAttrOffset(strClass, "__len__"), "Load attribute: __len__"); -// backend.emitBLTU(index, a, ch, "Ensure 0 <= idx < len"); -// backend.emitJ(f, "Go to error handler"); -// backend.emitLocalLabel(ch, "Index within bounds"); -// this.c(index); -// Register a2 = this.a(false); -// this.a(1); -// return a2; -// } - return null; + @Override + public Register analyze(IndexExpr node) + { + incSp(1); + Register listObj = node.list.dispatch(this); + backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off)); + Register index = node.index.dispatch(this); + Register vacantReg = (index != A0) ? A0 : A1; + int tmpHandle = getRegister(); + Register temp= registerPool[tmpHandle]; + + 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"); + backend.emitJ(errorNone, "Go to error handler"); + backend.emitLocalLabel(bp, "Not None"); + final Label bt = generateLocalLabel(); + backend.emitLW(temp, listObj, getAttrOffset(listClass, "__len__"), "Load attribute: __len__"); + backend.emitBLTU(index, temp, bt, "Ensure 0 <= index < len"); + backend.emitJ(errorOob, "Go to error handler"); + backend.emitLocalLabel(bt, "Index within bounds"); + backend.emitADDI(index, index, 4, "Compute list element offset in words"); + backend.emitLI(temp, wordSize, "Word size in bytes"); + 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 { + 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__"); + backend.emitBLTU(index, temp, boundchk, "Ensure 0 <= idx < len"); + backend.emitJ(errorOob, "Go to error handler"); + backend.emitLocalLabel(boundchk, "Index within bounds"); + incSp(1); + backend.emitSW(index, RiscVBackend.Register.FP, -sp_off * wordSize, String.format("Push on stack slot %d",sp_off)); + + getAttrOffset(strClass, "__len__"); + backend.emitLW(T0, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off)); + --sp_off; + backend.emitSW(A1, FP, -sp_off*wordSize, String.format("Push Argument %d", sp_off)); + + backend.emitADDI(T0, T0, 4 * wordSize, "Convert index to offset to char in bytes"); + backend.emitLBU(T0, T0, 0, "Load character"); + backend.emitLA(vacantReg, strClass.getPrototypeLabel(), "Create Str for char"); + backend.emitJAL(objectAllocLabel, "Alloc char"); + backend.emitLI(T1, 1, "str size"); + backend.emitSW(T1, vacantReg, 3*wordSize, "len"); + backend.emitSW(T0, vacantReg, 4*wordSize, "ch"); } + freeRegister(tmpHandle); + -- sp_off; + return vacantReg; + } public Register analyze(MemberExpr node) { From 3b92cea6c299500796c62eaf8735ed8a0262b65c Mon Sep 17 00:00:00 2001 From: bill Date: Mon, 3 May 2021 17:35:33 +0800 Subject: [PATCH 08/37] update --- src/main/java/chocopy/pa3/CodeGenImpl.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 24914e2..16ca8df 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -724,7 +724,13 @@ public class CodeGenImpl extends CodeGenBase } else if(node.left.getInferredType().equals(Type.STR_TYPE) && node.right.getInferredType().equals(Type.STR_TYPE)) { - + incSp(2); + backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last."); + backend.emitSW(node.right.dispatch(this), FP, ( - sp_off) *wordSize, "Push argument 1 from last."); + backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument."); + backend.emitJAL(streqlLablel, "Invoke method:streql"); + sp_off -= 2; + backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp"); } else { @@ -755,7 +761,7 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(Identifier node) { - backend.emitLW(T6, FP, 0, "Inside Identifier: "); + backend.emitLW(T6, FP, 0, "Inside Identifier: "); if (sym.getParent() == null) { GlobalVarInfo gvi=(GlobalVarInfo) sym.get(node.name); @@ -768,7 +774,7 @@ public class CodeGenImpl extends CodeGenBase // int loc = offsetMap.get(svi); // backend.emitLW(Register.A0, Register.FP, -loc*4, "Load local variable: "+svi.getVarName()); } - return null; + return A0; } @Override From 2a8b66cb940bb0df92e8e29f6d6b76343a99a3bd Mon Sep 17 00:00:00 2001 From: bill Date: Mon, 3 May 2021 17:37:21 +0800 Subject: [PATCH 09/37] deleted: .vscode/launch.json --- .vscode/launch.json | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 40395d9..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - - - { - "type": "java", - "name": "Launch Current File", - "request": "launch", - "classPaths": ["chocopy-ref.jar:target/assignment.jar"], - "mainClass": "chocopy.ChocoPy", - "args": [ "--pass=rrs", "--test","--dir", "src/test/data/pa3/sample/stmt_return_early.py"], - //"args": [ "--pass=rrs", "--test","--dir", "test.py"], - "sourcePaths": [] - } - ] -} \ No newline at end of file From 38e988763890809bac8825cf910dff565c2a4c8e Mon Sep 17 00:00:00 2001 From: Apoorva Ranade Date: Mon, 3 May 2021 20:02:48 +0530 Subject: [PATCH 10/37] Used incSp --- src/main/java/chocopy/pa3/CodeGenImpl.java | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index e28e807..8405d03 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -536,11 +536,11 @@ public class CodeGenImpl extends CodeGenBase //Store address and length of lists on stack backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Store address of first list"); - sp_off++; + incSp(1); backend.emitSW(Register.T0, Register.FP, -sp_off*wordSize, "Store address of second list"); - sp_off++; + incSp(1); backend.emitSW(Register.T3, Register.FP, -sp_off*wordSize, "Store length of combined list"); - sp_off++; + incSp(1); //Allocate space on heap backend.emitLA(Register.A0, listClass.getPrototypeLabel(), "Load empty list"); @@ -581,7 +581,7 @@ public class CodeGenImpl extends CodeGenBase { node.right.dispatch(this); backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off); - sp_off++; + incSp(1); node.left.dispatch(this); sp_off--; backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off); @@ -656,7 +656,7 @@ public class CodeGenImpl extends CodeGenBase { node.right.dispatch(this); backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off); - sp_off++; + incSp(1); node.left.dispatch(this); sp_off--; backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off); @@ -667,7 +667,7 @@ public class CodeGenImpl extends CodeGenBase { node.right.dispatch(this); backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off); - sp_off++; + incSp(1); node.left.dispatch(this); sp_off--; backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off); @@ -679,7 +679,7 @@ public class CodeGenImpl extends CodeGenBase Label label = generateLocalLabel(); node.left.dispatch(this); backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off); - sp_off++; + incSp(1); backend.emitBEQZ(Register.A0, label, "If first operand is false, don't check second"); node.right.dispatch(this); sp_off--; @@ -692,7 +692,7 @@ public class CodeGenImpl extends CodeGenBase Label label = generateLocalLabel(); node.left.dispatch(this); backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off); - sp_off++; + incSp(1); backend.emitBNEZ(Register.A0, label, "If first operand is true, don't check second"); node.right.dispatch(this); sp_off--; @@ -714,7 +714,7 @@ public class CodeGenImpl extends CodeGenBase { node.right.dispatch(this); backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off); - sp_off++; + incSp(1); node.left.dispatch(this); sp_off--; backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off); @@ -783,7 +783,7 @@ public class CodeGenImpl extends CodeGenBase node.value.dispatch(this); backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Store variable "+node.var.identifier.name+" value in Stack"); offsetMap.put(svi, sp_off); - sp_off++; + incSp(1); return null; } From fbd740eb2564331c84e8adf9376ceaa96acc33b0 Mon Sep 17 00:00:00 2001 From: Apoorva Ranade Date: Mon, 3 May 2021 22:38:48 +0530 Subject: [PATCH 11/37] For loop --- src/main/java/chocopy/pa3/CodeGenImpl.java | 157 +++++++++++++++------ 1 file changed, 117 insertions(+), 40 deletions(-) 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__"); From 7a8e5b20825599dfa68568643c47673f4b05059d Mon Sep 17 00:00:00 2001 From: Apoorva Ranade Date: Mon, 3 May 2021 22:56:01 +0530 Subject: [PATCH 12/37] Clean up --- src/main/java/chocopy/pa3/CodeGenImpl.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 83d4b4e..68fce7a 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -631,12 +631,13 @@ public class CodeGenImpl extends CodeGenBase { backend.emitADDI(Register.A0,Register.A0, 1, "Increment by 1"); backend.emitSLT(Register.A0, Register.A0, Register.T0, comment); - } + } + /* Maybe NA else if(operator.equals("is")) { backend.emitXOR(Register.A0, Register.A0, Register.T0, comment); backend.emitSEQZ(Register.A0, Register.A0, "Result is True if XOR equals 0"); - } + }*/ else { backend.emitJAL(errorNI, "Operator not implemented for integer operands"); @@ -695,12 +696,13 @@ public class CodeGenImpl extends CodeGenBase backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off); backend.emitOR(Register.A0, Register.A0, Register.T0, "OR operation"); backend.emitLocalLabel(label, "Next step after OR"); - } + } + /*Maybe NA else if(operator.equals("is")) { backend.emitXOR(Register.A0, Register.A0, Register.T0, comment); backend.emitSEQZ(Register.A0, Register.A0, "Result is True if XOR equals 0"); - } + }*/ else { backend.emitJAL(errorNI, "Operator not implemented for boolean operands"); @@ -727,6 +729,7 @@ public class CodeGenImpl extends CodeGenBase sp_off -= 2; backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp"); } + // TODO: Implement "is" for objects else { backend.emitJAL(errorNI, "Operator not implemented"); From 10cbb67c097b07ae013f1797296005ba6a197913 Mon Sep 17 00:00:00 2001 From: Apoorva Ranade Date: Mon, 3 May 2021 23:22:51 +0530 Subject: [PATCH 13/37] Fixed Identifier Analyze --- src/main/java/chocopy/pa3/CodeGenImpl.java | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 68fce7a..13d3270 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -452,8 +452,7 @@ public class CodeGenImpl extends CodeGenBase { for(Expr target: node.targets) { - StackVarInfo svi = (StackVarInfo) sym.get(((Identifier)target).name); - backend.emitLW(reg, SP, varSlotMap.get(svi.getVarName()),"Load local variable: "+svi.getVarName()); + backend.emitLW(reg, SP, varSlotMap.get(((Identifier)target).name),"Load local variable: "+((Identifier)target).name); } } //} @@ -767,8 +766,7 @@ public class CodeGenImpl extends CodeGenBase } else { - VarInfo svi = (VarInfo) sym.get(node.name); - backend.emitLW(Register.A0, SP, varSlotMap.get(svi.getVarName()),"Load local variable: "+svi.getVarName()); + backend.emitLW(Register.A0, SP, varSlotMap.get(node.name),"Load local variable: "+node.name); } return Register.A0; } @@ -776,14 +774,6 @@ public class CodeGenImpl extends CodeGenBase @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);*/ return null; } From 874808ef981b0d6b4e83e09329c3354e628365b8 Mon Sep 17 00:00:00 2001 From: Apoorva Ranade Date: Mon, 3 May 2021 23:40:11 +0530 Subject: [PATCH 14/37] Added is operator --- src/main/java/chocopy/pa3/CodeGenImpl.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 13d3270..6d522cf 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -728,7 +728,17 @@ public class CodeGenImpl extends CodeGenBase sp_off -= 2; backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp"); } - // TODO: Implement "is" for objects + else if(operator.equals("is")) + { + node.right.dispatch(this); + backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off); + incSp(1); + node.left.dispatch(this); + sp_off--; + backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off); + backend.emitXOR(Register.A0, Register.A0, Register.T0, "Operator: is"); + backend.emitSEQZ(Register.A0, Register.A0, "Result is True if XOR equals 0"); + } else { backend.emitJAL(errorNI, "Operator not implemented"); From 1952bb2d38ca7e3441e3eef018a38818dc5f55bd Mon Sep 17 00:00:00 2001 From: Apoorva Ranade Date: Tue, 4 May 2021 13:19:40 +0530 Subject: [PATCH 15/37] Changed ListExpr Analyze and add operator for lists --- src/main/java/chocopy/pa3/CodeGenImpl.java | 80 ++++++++++++++-------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 6d522cf..7376ce0 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -32,12 +32,12 @@ public class CodeGenImpl extends CodeGenBase { /** Label for built-in routines. */ protected final Label makeintLabel = new Label("makeint"); - protected final Label strneqlLablel = new Label("strneql"); - protected final Label streqlLablel = new Label("streql"); + protected final Label strneqlLabel = new Label("strneql"); + protected final Label streqlLabel = new Label("streql"); protected final Label makeboolLabel = new Label("makebool"); - protected final Label strcatLablel = new Label("strcat"); - protected final Label concatLablel = new Label("concat"); - protected final Label conslistLablel = new Label("conslist"); + protected final Label strcatLabel = new Label("strcat"); + protected final Label concatLabel = new Label("concat"); + protected final Label conslistLabel = new Label("conslist"); @@ -709,24 +709,42 @@ public class CodeGenImpl extends CodeGenBase } else if(node.left.getInferredType().isListType() && node.right.getInferredType().isListType()) { - node.right.dispatch(this); - backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off); - incSp(1); - node.left.dispatch(this); - sp_off--; - backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off); if(operator.equals("+")) - addLists(); + { + node.left.dispatch(this); + backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push left operand on stack slot "+sp_off); + incSp(1); + node.right.dispatch(this); + backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push right operand on stack slot "+sp_off); + incSp(1); + backend.emitADDI(Register.SP,Register.FP,-sp_off*wordSize,"Set SP to last argument"); + backend.emitJAL(concatLabel, "Call concatenation routine"); + backend.emitADDI(Register.SP, Register.FP, "-"+size_label, "Set SP to stack frame"); + return Register.A0; + //addLists(); + } + else + backend.emitJAL(errorNI, "Operator not implemented for list operands"); + } else if(node.left.getInferredType().equals(Type.STR_TYPE) && node.right.getInferredType().equals(Type.STR_TYPE)) { + if(operator.equals("==")) + { incSp(2); backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last."); backend.emitSW(node.right.dispatch(this), FP, ( - sp_off) *wordSize, "Push argument 1 from last."); backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument."); - backend.emitJAL(streqlLablel, "Invoke method:streql"); + backend.emitJAL(streqlLabel, "Invoke method:streql"); sp_off -= 2; backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp"); + } + else if(operator.equals("+")) + { + + } + else + backend.emitJAL(errorNI, "Operator not implemented for String operands"); } else if(operator.equals("is")) { @@ -808,25 +826,33 @@ public class CodeGenImpl extends CodeGenBase @Override public Register analyze(ListExpr node) { int l = node.elements.size(); - backend.emitLI(Register.A1, l+1, "Load length of list+1 in words"); - backend.emitLA(Register.A0, listClass.getPrototypeLabel(), "Load empty list"); - backend.emitJAL(objectAllocResizeLabel, "Allocate list"); - backend.emitMV(Register.A1, Register.A0, "Store address of allocated space"); - backend.emitMV(Register.T0, Register.A1, "Make a copy of address of allocated space"); - - int i = l; - backend.emitLI(Register.A0,l,"Load length of list in words"); - backend.emitSW(Register.A0,Register.T0,0,"Store length of list: "+i); - backend.emitADDI(Register.T0,Register.T0,wordSize,"Increment address"); - + int i=l; for(Expr exp:node.elements) { Register r = exp.dispatch(this); - backend.emitSW(r,Register.T0,0,"Store element "+i+" from last."); - backend.emitADDI(Register.T0,Register.T0,wordSize,"Increment address"); + if (exp.getInferredType().equals(Type.INT_TYPE) && !node.elements.get(0).getInferredType().equals(Type.INT_TYPE)) + { + if(r!=Register.A0) + backend.emitMV(r, Register.A0, "Copy to Register A0"); + backend.emitJAL(makeintLabel, "Box integer"); + } + else if (exp.getInferredType().equals(Type.BOOL_TYPE) && !node.elements.get(0).getInferredType().equals(Type.BOOL_TYPE)) + { + if(r!=Register.A0) + backend.emitMV(r, Register.A0, "Copy to Register A0"); + backend.emitJAL(makeboolLabel, "Box boolean"); + } + backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push argument "+i+" from last"); + incSp(1); i--; } - backend.emitMV(Register.A0,Register.A1,"Load address of list"); + backend.emitLI(Register.A0, l, "Pass list length"); + backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push length of list"); + incSp(1); + backend.emitADDI(Register.SP, Register.FP, -(sp_off-1)*wordSize, "Set SP to last argument"); + backend.emitJAL(conslistLabel, "Move values to new list object"); + backend.emitADDI(Register.SP, Register.FP, "-"+size_label, "Set SP to stack frame"); + sp_off-=l; return Register.A0; } From 4fa4a92e1fdd987c68251baedf6add0e83afa8b9 Mon Sep 17 00:00:00 2001 From: Apoorva Ranade Date: Tue, 4 May 2021 15:34:38 +0530 Subject: [PATCH 16/37] Added operators on Strings --- src/main/java/chocopy/pa3/CodeGenImpl.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 7376ce0..5d21ca2 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -739,9 +739,25 @@ public class CodeGenImpl extends CodeGenBase sp_off -= 2; backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp"); } + if(operator.equals("!=")) + { + incSp(2); + backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last."); + backend.emitSW(node.right.dispatch(this), FP, ( - sp_off) *wordSize, "Push argument 1 from last."); + backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument."); + backend.emitJAL(strneqlLabel, "Invoke method:strneql"); + sp_off -= 2; + backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp"); + } else if(operator.equals("+")) { - + incSp(2); + backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last."); + backend.emitSW(node.right.dispatch(this), FP, ( - sp_off) *wordSize, "Push argument 1 from last."); + backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument."); + backend.emitJAL(concatLabel, "Invoke method:concat"); + sp_off -= 2; + backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp"); } else backend.emitJAL(errorNI, "Operator not implemented for String operands"); From 0b00c3fc1d1211232c8eba52f936fd5ef0fb4516 Mon Sep 17 00:00:00 2001 From: Apoorva Ranade Date: Tue, 4 May 2021 15:39:52 +0530 Subject: [PATCH 17/37] Minor correction --- src/main/java/chocopy/pa3/CodeGenImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 5d21ca2..b442f02 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -739,7 +739,7 @@ public class CodeGenImpl extends CodeGenBase sp_off -= 2; backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp"); } - if(operator.equals("!=")) + else if(operator.equals("!=")) { incSp(2); backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last."); @@ -755,7 +755,7 @@ public class CodeGenImpl extends CodeGenBase backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last."); backend.emitSW(node.right.dispatch(this), FP, ( - sp_off) *wordSize, "Push argument 1 from last."); backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument."); - backend.emitJAL(concatLabel, "Invoke method:concat"); + backend.emitJAL(strcatLabel, "Invoke method:strcat"); sp_off -= 2; backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp"); } From d7ae4fc9edecd2f23e90661c281c7f466a3583c8 Mon Sep 17 00:00:00 2001 From: bill Date: Tue, 4 May 2021 22:16:58 +0800 Subject: [PATCH 18/37] modified: src/main/java/chocopy/pa3/CodeGenImpl.java --- src/main/java/chocopy/pa3/CodeGenImpl.java | 191 +++++++++++++++------ 1 file changed, 137 insertions(+), 54 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 7376ce0..1cb954f 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Stack; import chocopy.common.analysis.*; import chocopy.common.astnodes.*; @@ -90,6 +91,8 @@ public class CodeGenImpl extends CodeGenBase { stmt.dispatch(stmtAnalyzer); } + stmtAnalyzer.emitSizeLabel(); + backend.emitLI(A0, EXIT_ECALL, "Code for ecall: exit"); backend.emitEcall(null); } @@ -155,10 +158,8 @@ public class CodeGenImpl extends CodeGenBase for (Stmt stmt : funcInfo.getStatements()) { stmt.dispatch(stmtAnalyzer); } + stmtAnalyzer.emitSizeLabel(); backend.emitJ(stmtAnalyzer.epilogue, "Jump to function epilogue"); - - - // --- Epilogue --- backend.emitLocalLabel(stmtAnalyzer.epilogue, "Epilogue"); backend.emitLW(RA, FP, -4, "Get return address"); @@ -206,7 +207,7 @@ public class CodeGenImpl extends CodeGenBase private final FuncInfo funcInfo; /** Label of code that exits from block. */ - protected Label elseBlock; + protected Stack