diff options
author | geno <gabriele.genovese2@studio.unibo.it> | 2024-07-11 14:30:11 +0200 |
---|---|---|
committer | geno <gabriele.genovese2@studio.unibo.it> | 2024-07-11 14:30:11 +0200 |
commit | 57599a42b863cc48050c137de2ec108aa1d59a44 (patch) | |
tree | 243ae356023fe1c2e749e171a865d1c20a261ab8 | |
parent | b50c7e99603e9f85d82d700d62c16c4fcef88715 (diff) |
feat: clear stack before halt
-rw-r--r-- | src/ast/nodes/AssignmentNode.java | 4 | ||||
-rw-r--r-- | src/ast/nodes/ExprNode.java | 252 | ||||
-rw-r--r-- | src/ast/nodes/RootNode.java | 7 | ||||
-rw-r--r-- | src/codegen/Label.java | 9 |
4 files changed, 143 insertions, 129 deletions
diff --git a/src/ast/nodes/AssignmentNode.java b/src/ast/nodes/AssignmentNode.java index 358d497..13e7a33 100644 --- a/src/ast/nodes/AssignmentNode.java +++ b/src/ast/nodes/AssignmentNode.java @@ -1,8 +1,8 @@ package ast.nodes; import ast.types.*; +import codegen.Label; import java.util.ArrayList; - import semanticanalysis.STentry; import semanticanalysis.SemanticError; import semanticanalysis.SymbolTable; @@ -42,6 +42,8 @@ public class AssignmentNode implements Node { STentry e = ST.lookup(leftAtom.getId()); if (ft != null) { ft.addLocalVar(); + } else { + Label.addGlobalVar(); } if (e == null) { diff --git a/src/ast/nodes/ExprNode.java b/src/ast/nodes/ExprNode.java index dec0b54..3d05eea 100644 --- a/src/ast/nodes/ExprNode.java +++ b/src/ast/nodes/ExprNode.java @@ -1,13 +1,12 @@ package ast.nodes; import ast.types.*; +import codegen.Label; import java.util.ArrayList; import java.util.Arrays; - import semanticanalysis.STentry; import semanticanalysis.SemanticError; import semanticanalysis.SymbolTable; -import codegen.Label; /** * Node for the `expr` statement of the grammar. @@ -133,21 +132,22 @@ public class ExprNode implements Node { // If the atom is a built-in function. return the trailer's content if (Arrays.asList(bif).contains(atom.getId())) { - return trailerS; + // remove "pushr A0\n" at the end of the trailer because it's useless + return trailerS.substring(0, trailerS.length() - 9); } // We're not considering nested functions, so despite of slide 62 // we do not have a forloop for nesting_level - // loopkup(..).nesting_level here. - return "pushr FP\n" + - "move SP FP\n" + - "addi FP 1\n" + - "move AL T1\n" + - "pushr T1\n" + - trailerS + - "move FP AL\n" + - "subi AL 1\n" + - "jsub " + funL + "\n"; + return "pushr FP\n" + + "move SP FP\n" + + "addi FP 1\n" + + "move AL T1\n" + + "pushr T1\n" + + trailerS + + "move FP AL\n" + + "subi AL 1\n" + + "jsub " + funL + "\n"; } // Check operation @@ -156,8 +156,8 @@ public class ExprNode implements Node { case "+": case "-": case "*": - // In real Python `/` is a float division but we'll consider the - // int division here below. + // In real Python `/` is a float division but we'll consider the + // int division here below. case "/": return intOpCodeGen(exprs.get(0), exprs.get(1), op); case "%": @@ -263,12 +263,12 @@ public class ExprNode implements Node { ops = "Error: cannot manage op " + op; } - return ls + - "pushr A0\n" + - rs + - "popr T1\n" + - ops + " T1 A0\n" + - "popr A0\n"; + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + ops + " T1 A0\n" + + "popr A0\n"; } private String modCodeGen(Node leftE, Node rightE) { @@ -280,38 +280,38 @@ public class ExprNode implements Node { // 7 / 2 = 3 // 3 * 2 = 6 // 7 - 6 = 1 <--- result - return ls + - "pushr A0\n" + - "pushr A0\n" + - rs + - "popr T1\n" + - // Divide the two numbers - "div T1 A0\n" + - "popr T1\n" + - // Multiply the division result for the number at the left - "mul T1 A0\n" + - "popr A0\n" + - // Get the previous number at the left from the stack - "popr T1\n" + - // Subtracting the two numbers we have the module value - "sub T1 A0\n" + - "popr A0\n"; + return ls + + "pushr A0\n" + + "pushr A0\n" + + rs + + "popr T1\n" + + // Divide the two numbers + "div T1 A0\n" + + "popr T1\n" + + // Multiply the division result for the number at the left + "mul T1 A0\n" + + "popr A0\n" + + // Get the previous number at the left from the stack + "popr T1\n" + + // Subtracting the two numbers we have the module value + "sub T1 A0\n" + + "popr A0\n"; } /** - * NOTE: for the boolean operation we assume that False = 0, True = 1 - * NOTE: we should optimize ignoring the the right value if the left value - * is false. + * NOTE: for the boolean operation we assume that False = 0, True = 1 NOTE: + * we should optimize ignoring the the right value if the left value is + * false. */ private String andCodeGen(Node leftE, Node rightE) { String endl = Label.newBasic("endAnd"); String ls = leftE.codeGeneration(); String rs = rightE.codeGeneration(); - return ls + - "storei T1 0\n" + - "beq A0 T1 " + endl + "\n" + - rs + - endl + ":\n"; + return ls + + "storei T1 0\n" + + "beq A0 T1 " + endl + "\n" + + rs + + endl + ":\n"; } /** @@ -322,11 +322,11 @@ public class ExprNode implements Node { String endl = Label.newBasic("endOr"); String ls = leftE.codeGeneration(); String rs = rightE.codeGeneration(); - return ls + - "storei T1 1\n" + - "beq A0 T1 " + endl + "\n" + - rs + - endl + ":\n"; + return ls + + "storei T1 1\n" + + "beq A0 T1 " + endl + "\n" + + rs + + endl + ":\n"; } private String notCodeGen(Node expr) { @@ -334,10 +334,10 @@ public class ExprNode implements Node { // We use the `sub` because: // not True = 1 - 1 = 0 = False // not False = 1 - 0 = 1 = True - return exprs + - "storei T1 1\n" + - "sub T1 A0\n" + - "popr A0\n"; + return exprs + + "storei T1 1\n" + + "sub T1 A0\n" + + "popr A0\n"; } private String eqCodeGen(Node leftE, Node rightE) { @@ -345,16 +345,16 @@ public class ExprNode implements Node { String endl = Label.newBasic("end"); String ls = leftE.codeGeneration(); String rs = rightE.codeGeneration(); - return ls + - "pushr A0\n" + - rs + - "popr T1\n" + - "beq T1 A0 " + truel + "\n" + - "storei A0 0\n" + - "b " + endl + "\n" + - truel + ":\n" + - "storei A0 1\n" + - endl + ":\n"; + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + "beq T1 A0 " + truel + "\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + truel + ":\n" + + "storei A0 1\n" + + endl + ":\n"; } private String neqCodeGen(Node leftE, Node rightE) { @@ -362,18 +362,18 @@ public class ExprNode implements Node { String endl = Label.newBasic("end"); String ls = leftE.codeGeneration(); String rs = rightE.codeGeneration(); - return ls + - "pushr A0\n" + - rs + - "popr T1\n" + - "beq T1 A0 " + truel + "\n" + - "storei A0 1\n" + - // storei A0 1 instead of storei A0 0 - "b " + endl + "\n" + - truel + ":\n" + - // storei A0 0 instead of storei A0 1 - "storei A0 0\n" + - endl + ":\n"; + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + "beq T1 A0 " + truel + "\n" + + "storei A0 1\n" + + // storei A0 1 instead of storei A0 0 + "b " + endl + "\n" + + truel + ":\n" + + // storei A0 0 instead of storei A0 1 + "storei A0 0\n" + + endl + ":\n"; } private String lsCodeGen(Node leftE, Node rightE) { @@ -382,21 +382,21 @@ public class ExprNode implements Node { String endl = Label.newBasic("end"); String ls = leftE.codeGeneration(); String rs = rightE.codeGeneration(); - return ls + - "pushr A0\n" + - rs + - "popr T1\n" + - "bleq T1 A0 " + truel + "\n" + - "storei A0 0\n" + - "b " + endl + "\n" + - truel + ":\n" + - "beq T1 A0 " + truel2 + "\n" + - "storei A0 1\n" + - "b " + endl + "\n" + - truel2 + ":\n" + - "storei A0 0\n" + - "b " + endl + "\n" + - endl + ":\n"; + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + "bleq T1 A0 " + truel + "\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + truel + ":\n" + + "beq T1 A0 " + truel2 + "\n" + + "storei A0 1\n" + + "b " + endl + "\n" + + truel2 + ":\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + endl + ":\n"; } private String leqCodeGen(Node leftE, Node rightE) { @@ -404,16 +404,16 @@ public class ExprNode implements Node { String endl = Label.newBasic("end"); String ls = leftE.codeGeneration(); String rs = rightE.codeGeneration(); - return ls + - "pushr A0\n" + - rs + - "popr T1\n" + - "bleq T1 A0 " + truel + "\n" + - "storei A0 0\n" + - "b " + endl + "\n" + - truel + ":\n" + - "storei A0 1\n" + - endl + ":\n"; + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + "bleq T1 A0 " + truel + "\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + truel + ":\n" + + "storei A0 1\n" + + endl + ":\n"; } private String gtCodeGen(Node leftE, Node rightE) { @@ -421,17 +421,17 @@ public class ExprNode implements Node { String endl = Label.newBasic("end"); String ls = leftE.codeGeneration(); String rs = rightE.codeGeneration(); - return ls + - "pushr A0\n" + - rs + - "popr T1\n" + - // Invert A0 and T1 (different than leq) - "bleq A0 T1 " + truel + "\n" + - "storei A0 0\n" + - "b " + endl + "\n" + - truel + ":\n" + - "storei A0 1\n" + - endl + ":\n"; + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + // Invert A0 and T1 (different than leq) + "bleq A0 T1 " + truel + "\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + truel + ":\n" + + "storei A0 1\n" + + endl + ":\n"; } private String gteCodeGen(Node leftE, Node rightE) { @@ -440,21 +440,21 @@ public class ExprNode implements Node { String endl = Label.newBasic("end"); String ls = leftE.codeGeneration(); String rs = rightE.codeGeneration(); - return ls + - "pushr A0\n" + - rs + - "popr T1\n" + - "bleq T1 A0 " + truel + "\n" + - "storei A0 1\n" + - "b " + endl + "\n" + - truel + ":\n" + - "beq T1 A0 " + truel2 + "\n" + - "storei A0 0\n" + - "b " + endl + "\n" + - truel2 + ":\n" + - "storei A0 1\n" + - "b " + endl + "\n" + - endl + ":\n"; + return ls + + "pushr A0\n" + + rs + + "popr T1\n" + + "bleq T1 A0 " + truel + "\n" + + "storei A0 1\n" + + "b " + endl + "\n" + + truel + ":\n" + + "beq T1 A0 " + truel2 + "\n" + + "storei A0 0\n" + + "b " + endl + "\n" + + truel2 + ":\n" + + "storei A0 1\n" + + "b " + endl + "\n" + + endl + ":\n"; } } diff --git a/src/ast/nodes/RootNode.java b/src/ast/nodes/RootNode.java index 9cad871..2c99164 100644 --- a/src/ast/nodes/RootNode.java +++ b/src/ast/nodes/RootNode.java @@ -2,7 +2,6 @@ package ast.nodes; import ast.types.*; import codegen.Label; - import java.util.ArrayList; import java.util.HashMap; import semanticanalysis.*; @@ -55,7 +54,11 @@ public class RootNode implements Node { str += child.codeGeneration(); } - return str + "halt\n" + Label.getFunDef(); + for (int i = 0; i < Label.getGlobalVarNum(); i++) { + str += "pop\n"; + } + + return str + "pop\npop\nhalt\n" + Label.getFunDef(); } @Override diff --git a/src/codegen/Label.java b/src/codegen/Label.java index 52977c7..f0a4c6e 100644 --- a/src/codegen/Label.java +++ b/src/codegen/Label.java @@ -4,6 +4,7 @@ public class Label { private static String funDef = ""; private static int labelCounter = 0; + private static int globalVarNum = 0; private static int functionLabelCounter = 0; public static void addFunDef(String s) { @@ -14,6 +15,14 @@ public class Label { return funDef; } + public static void addGlobalVar() { + globalVarNum++; + } + + public static int getGlobalVarNum() { + return globalVarNum; + } + /** * Create a new basic label. Use this method to define labels for if, while and * for statemests. |