From f92308238b470f1e7eae27e788bf53c42fc59536 Mon Sep 17 00:00:00 2001 From: Apoorva Ranade Date: Wed, 28 Apr 2021 13:26:37 +0530 Subject: [PATCH] Variable declarations and assignment --- src/main/java/chocopy/pa3/CodeGenImpl.java | 172 ++++++++++++++------- 1 file changed, 112 insertions(+), 60 deletions(-) diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 5ff130c..bd0626c 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -7,7 +7,9 @@ import static chocopy.common.codegen.RiscVBackend.Register.RA; import static chocopy.common.codegen.RiscVBackend.Register.SP; import static chocopy.common.codegen.RiscVBackend.Register.ZERO; +import java.util.HashMap; import java.util.List; +import java.util.Map; import chocopy.common.analysis.AbstractNodeAnalyzer; import chocopy.common.analysis.SymbolTable; @@ -38,6 +40,7 @@ import chocopy.common.codegen.FuncInfo; import chocopy.common.codegen.GlobalVarInfo; import chocopy.common.codegen.Label; import chocopy.common.codegen.RiscVBackend; +import chocopy.common.codegen.StackVarInfo; import chocopy.common.codegen.RiscVBackend.Register; import chocopy.common.codegen.SymbolInfo; @@ -55,10 +58,12 @@ import chocopy.common.codegen.SymbolInfo; * it exposes for its sub-class (this one). Of particular importance is knowing * what all the SymbolInfo classes contain. */ -public class CodeGenImpl extends CodeGenBase { +public class CodeGenImpl extends CodeGenBase +{ /** A code generator emitting instructions to BACKEND. */ - public CodeGenImpl(RiscVBackend backend) { + public CodeGenImpl(RiscVBackend backend) + { super(backend); } @@ -82,14 +87,16 @@ public class CodeGenImpl extends CodeGenBase { * * @param statements top level statements */ - protected void emitTopLevel(List statements) { + 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."); backend.emitSW(ZERO, SP, 4, "Top saved RA is 0."); backend.emitADDI(FP, SP, 2 * backend.getWordSize(), "Set FP to previous SP."); - for (Stmt stmt : statements) { + for (Stmt stmt : statements) + { stmt.dispatch(stmtAnalyzer); } backend.emitLI(A0, EXIT_ECALL, "Code for ecall: exit"); @@ -105,11 +112,13 @@ public class CodeGenImpl extends CodeGenBase { * own. So if function `bar` is nested within function `foo`, you only emit * `foo`'s code for `foo` and only emit `bar`'s code for `bar`. */ - protected void emitUserDefinedFunction(FuncInfo funcInfo) { + protected void emitUserDefinedFunction(FuncInfo funcInfo) + { backend.emitGlobalLabel(funcInfo.getCodeLabel()); StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(funcInfo); - for (Stmt stmt : funcInfo.getStatements()) { + for (Stmt stmt : funcInfo.getStatements()) + { stmt.dispatch(stmtAnalyzer); } @@ -121,7 +130,8 @@ public class CodeGenImpl extends CodeGenBase { } /** An analyzer that encapsulates code generation for statements. */ - private class StmtAnalyzer extends AbstractNodeAnalyzer { + private class StmtAnalyzer extends AbstractNodeAnalyzer + { /* * The symbol table has all the info you need to determine what a given * identifier 'x' in the current scope is. You can use it as follows: SymbolInfo @@ -160,14 +170,16 @@ public class CodeGenImpl extends CodeGenBase { /** Label of code that exits from block. */ protected Label elseBlock; - // Variable to store offset from frame pointer to identify next - // empty space on stack frame to store variable + /** Variable to store offset from frame pointer to identify next + * empty space on stack frame to store variable*/ private int offset = 3; + private Map offsetMap = new HashMap<>(); /** * An analyzer for the function described by FUNCINFO0, which is null for the * top level. */ - StmtAnalyzer(FuncInfo funcInfo0) { + StmtAnalyzer(FuncInfo funcInfo0) + { funcInfo = funcInfo0; if (funcInfo == null) { sym = globalSymbols; @@ -179,7 +191,8 @@ public class CodeGenImpl extends CodeGenBase { // FIXME: Example of statement. @Override - public Void analyze(ReturnStmt stmt) { + public Void analyze(ReturnStmt stmt) + { // FIXME: Here, we emit an instruction that does nothing. Clearly, // this is wrong, and you'll have to fix it. // This is here just to demonstrate how to emit a @@ -189,21 +202,24 @@ public class CodeGenImpl extends CodeGenBase { } @Override - public Void analyze(NoneLiteral node) { + public Void analyze(NoneLiteral node) + { backend.emitMV(Register.A0, Register.ZERO, "Load none"); return null; } @Override - public Void analyze(StringLiteral node) { + public Void analyze(StringLiteral node) + { Label l = constants.getStrConstant(node.value); backend.emitLA(Register.A0, l, "Load string literal"); return null; } @Override - public Void analyze(IntegerLiteral node) { + public Void analyze(IntegerLiteral node) + { backend.emitLI(Register.A0, node.value, "Load integer literal "+node.value); return null; - } + } @Override public Void analyze(BooleanLiteral node) { @@ -216,38 +232,44 @@ public class CodeGenImpl extends CodeGenBase { @Override public Void analyze(AssignStmt node) { - if (sym.getParent() == null) + Type t = node.value.getInferredType(); + if(t.isSpecialType()) { - Type t = node.value.getInferredType(); - for(Expr target: node.targets) + node.value.dispatch(this); + if (sym.getParent() == null) { - if(t.isSpecialType()) + for(Expr target: node.targets) { GlobalVarInfo gvi=(GlobalVarInfo)sym.get(((Identifier)target).name); - node.value.dispatch(this); backend.emitSW(Register.A0, gvi.getLabel(), Register.T0, "Assign global: "+gvi.getVarName()+"(using tmp register)"); } } + else + { + for(Expr target: node.targets) + { + StackVarInfo svi = (StackVarInfo) sym.get(((Identifier)target).name); + int loc = offsetMap.get(svi); + backend.emitSW(Register.A0, Register.FP, loc*4, "Load local variable: "+svi.getVarName()); + } + } } else - {/* TODO: Assignments inside functions - for(Expr target: node.targets) - { - - backend.emitGlobalLabel("$"+target.kind); - backend.emitWordLiteral(node.value); - }*/ + {//TODO: Object Assignment + } return null; } - @Override - public Void analyze(ExprStmt node) { + @Override + public Void analyze(ExprStmt node) + { node.expr.dispatch(this); return null; - } - @Override - public Void analyze(IfExpr node) { + } + @Override + public Void analyze(IfExpr node) + { node.condition.dispatch(this); Label ln = generateLocalLabel(); node.thenExpr.dispatch(this); @@ -256,9 +278,10 @@ public class CodeGenImpl extends CodeGenBase { node.elseExpr.dispatch(this); backend.emitLocalLabel(ln, "End of if expression"); return null; - } - @Override - public Void analyze(IfStmt node) { + } + @Override + public Void analyze(IfStmt node) + { node.condition.dispatch(this); Label ln = generateLocalLabel(); for(Stmt s:node.thenBody) @@ -269,15 +292,17 @@ public class CodeGenImpl extends CodeGenBase { s.dispatch(this); backend.emitLocalLabel(ln, "End of if statement"); return null; - } - @Override - public Void analyze(BinaryExpr node) { + } + @Override + public Void analyze(BinaryExpr node) + { node.left.dispatch(this); backend.emitSW(Register.A0, Register.FP, offset*4, "Push on stack slot "+offset); offset++; node.right.dispatch(this); offset--; backend.emitLW(Register.T0, Register.FP, (offset)*4, "Pop stack slot "+offset); + // Arithmetic Operators if(node.operator.equals("+")) backend.emitADD(Register.A0, Register.A0, Register.T0, "Add operation"); else if(node.operator.equals("-")) @@ -287,7 +312,7 @@ public class CodeGenImpl extends CodeGenBase { else if(node.operator.equals("/")) backend.emitDIV(Register.A0, Register.A0, Register.T0, "Div operation"); else - { + { // Comparison operators elseBlock = generateLocalLabel(); String comment="Branch on not "+node.operator; if(node.operator.equals("==")) @@ -312,18 +337,57 @@ public class CodeGenImpl extends CodeGenBase { } } return null; - } + } + @Override + public Void analyze(UnaryExpr node) + { + node.operand.dispatch(this); + if(node.operator.equals("-")) + { + backend.emitLI(Register.T0, -1, "Set value of Registr T0 to -1"); + backend.emitMUL(Register.A0, Register.A0, Register.T0, "Multiply by -1"); + } + return null; + } + + @Override + public Void analyze(Identifier node) + { + if (sym.getParent() == null) + { + GlobalVarInfo gvi=(GlobalVarInfo) sym.get(node.name); + backend.emitLW(Register.A0, gvi.getLabel(), "Load global: "+gvi.getVarName()); + } + else + { + StackVarInfo svi = (StackVarInfo) sym.get(node.name); + int loc = offsetMap.get(svi); + backend.emitLW(Register.A0, Register.FP, loc*4, "Load local variable: "+svi.getVarName()); + } + return null; + } + @Override + public Void analyze(VarDef node) + { + StackVarInfo svi = (StackVarInfo) sym.get(node.var.identifier.name); + node.value.dispatch(this); + backend.emitSW(Register.A0, Register.FP, offset*4, "Store variable "+node.var.identifier.name+" value in Stack"); + offsetMap.put(svi, offset); + offset++; + return null; + } + @Override + public Void analyze(TypedVar node) + { + return null; + } @Override public Void analyze(ForStmt node) { // control flow return defaultAction(node); } - @Override - public Void analyze(Identifier node) { - // statement - return defaultAction(node); - } + @Override @@ -345,23 +409,11 @@ public class CodeGenImpl extends CodeGenBase { return defaultAction(node); } - @Override - public Void analyze(TypedVar node) { - // statement - return defaultAction(node); - } + - @Override - public Void analyze(UnaryExpr node) { - // statement - return defaultAction(node); - } + - @Override - public Void analyze(VarDef node) { - // statement - return defaultAction(node); - } + @Override public Void analyze(WhileStmt node) {