diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java
index 47a31c8..88dfde0 100644
--- a/src/main/java/chocopy/pa3/CodeGenImpl.java
+++ b/src/main/java/chocopy/pa3/CodeGenImpl.java
@@ -4,22 +4,38 @@ import chocopy.common.analysis.AbstractNodeAnalyzer;
import chocopy.common.analysis.SymbolTable;
import chocopy.common.astnodes.ReturnStmt;
import chocopy.common.astnodes.Stmt;
+import chocopy.common.astnodes.StringLiteral;
+import chocopy.common.astnodes.AssignStmt;
+import chocopy.common.astnodes.BinaryExpr;
+import chocopy.common.astnodes.BooleanLiteral;
+import chocopy.common.astnodes.Expr;
+import chocopy.common.astnodes.Identifier;
+import chocopy.common.astnodes.IntegerLiteral;
+import chocopy.common.astnodes.Literal;
import chocopy.common.codegen.*;
+import chocopy.common.codegen.Label;
+import chocopy.common.codegen.RiscVBackend.Register;
import java.util.List;
+
+import chocopy.common.analysis.types.Type;
+
import static chocopy.common.codegen.RiscVBackend.Register.*;
/**
* This is where the main implementation of PA3 will live.
*
- *
A large part of the functionality has already been implemented in the base class, CodeGenBase.
- * Make sure to read through that class, since you will want to use many of its fields and utility
- * methods in this class when emitting code.
+ *
+ * A large part of the functionality has already been implemented in the base
+ * class, CodeGenBase. Make sure to read through that class, since you will want
+ * to use many of its fields and utility methods in this class when emitting
+ * code.
*
- *
Also read the PDF spec for details on what the base class does and what APIs it exposes for
- * its sub-class (this one). Of particular importance is knowing what all the SymbolInfo classes
- * contain.
+ *
+ * Also read the PDF spec for details on what the base class does and what APIs
+ * it exposes for its sub-class (this one). Of particular importance is knowing
+ * what all the SymbolInfo classes contain.
*/
public class CodeGenImpl extends CodeGenBase {
@@ -38,17 +54,19 @@ public class CodeGenImpl extends CodeGenBase {
/**
* Emits the top level of the program.
*
- *
This method is invoked exactly once, and is surrounded by some boilerplate code that: (1)
- * initializes the heap before the top-level begins and (2) exits after the top-level ends.
+ *
+ * This method is invoked exactly once, and is surrounded by some boilerplate
+ * code that: (1) initializes the heap before the top-level begins and (2) exits
+ * after the top-level ends.
*
- *
You only need to generate code for statements.
+ *
+ * You only need to generate code for statements.
*
* @param statements top level 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.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.");
@@ -63,10 +81,11 @@ public class CodeGenImpl extends CodeGenBase {
/**
* Emits the code for a function described by FUNCINFO.
*
- * This method is invoked once per function and method definition. At the code generation
- * stage, nested functions are emitted as separate functions of their 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`.
+ *
+ * This method is invoked once per function and method definition. At the code
+ * generation stage, nested functions are emitted as separate functions of their
+ * 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) {
backend.emitGlobalLabel(funcInfo.getCodeLabel());
@@ -86,34 +105,30 @@ public class CodeGenImpl extends CodeGenBase {
/** An analyzer that encapsulates code generation for statements. */
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 x = sym.get("x");
+ * 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
+ * x = sym.get("x");
*
- * A SymbolInfo can be one the following:
- * - ClassInfo: a descriptor for classes
- * - FuncInfo: a descriptor for functions/methods
- * - AttrInfo: a descriptor for attributes
- * - GlobalVarInfo: a descriptor for global variables
- * - StackVarInfo: a descriptor for variables allocated on the stack,
- * such as locals and parameters
+ * A SymbolInfo can be one the following: - ClassInfo: a descriptor for classes
+ * - FuncInfo: a descriptor for functions/methods - AttrInfo: a descriptor for
+ * attributes - GlobalVarInfo: a descriptor for global variables - StackVarInfo:
+ * a descriptor for variables allocated on the stack, such as locals and
+ * parameters
*
- * Since the input program is assumed to be semantically
- * valid and well-typed at this stage, you can always assume that
- * the symbol table contains valid information. For example, in
- * an expression `foo()` you KNOW that sym.get("foo") will either be
- * a FuncInfo or ClassInfo, but not any of the other infos
- * and never null.
+ * Since the input program is assumed to be semantically valid and well-typed at
+ * this stage, you can always assume that the symbol table contains valid
+ * information. For example, in an expression `foo()` you KNOW that
+ * sym.get("foo") will either be a FuncInfo or ClassInfo, but not any of the
+ * other infos and never null.
*
- * The symbol table in funcInfo has already been populated in
- * the base class: CodeGenBase. You do not need to add anything to
- * the symbol table. Simply query it with an identifier name to
- * get a descriptor for a function, class, variable, etc.
+ * The symbol table in funcInfo has already been populated in the base class:
+ * CodeGenBase. You do not need to add anything to the symbol table. Simply
+ * query it with an identifier name to get a descriptor for a function, class,
+ * variable, etc.
*
- * The symbol table also maps nonlocal and global vars, so you
- * only need to lookup one symbol table and it will fetch the
- * appropriate info for the var that is currently in scope.
+ * The symbol table also maps nonlocal and global vars, so you only need to
+ * lookup one symbol table and it will fetch the appropriate info for the var
+ * that is currently in scope.
*/
/** Symbol table for my statements. */
@@ -125,7 +140,10 @@ public class CodeGenImpl extends CodeGenBase {
/** The descriptor for the current function, or null at the top level. */
private final FuncInfo funcInfo;
- /** An analyzer for the function described by FUNCINFO0, which is null for the top level. */
+ /**
+ * An analyzer for the function described by FUNCINFO0, which is null for the
+ * top level.
+ */
StmtAnalyzer(FuncInfo funcInfo0) {
funcInfo = funcInfo0;
if (funcInfo == null) {
@@ -148,6 +166,56 @@ public class CodeGenImpl extends CodeGenBase {
}
// FIXME: More, of course.
+ @Override
+ public Void analyze(AssignStmt node) {
+ if (sym.getParent() == null) {
+ Type t = node.value.getInferredType();
+ for(Expr target: node.targets)
+ {
+
+ GlobalVarInfo gvi=(GlobalVarInfo)sym.get(((Identifier)target).name);
+ if(t==Type.INT_TYPE)
+ {
+ IntegerLiteral lt = (IntegerLiteral)node.value;
+ backend.emitLI(Register.A0, lt.value, "Load integer literal "+lt.value);
+ }
+ else if(t==Type.BOOL_TYPE)
+ {
+ BooleanLiteral lt = (BooleanLiteral)node.value;
+ if(lt.value==true)
+ backend.emitLI(Register.A0, 1, "Load boolean literal "+1);
+ else
+ backend.emitLI(Register.A0, 0, "Load boolean literal "+0);
+ }
+ else
+ {
+ StringLiteral lt = (StringLiteral)node.value;
+ System.out.println(strClass.getClassName()+" "+strClass.getTypeTag()+" "+strClass.getDispatchTableLabel().labelName);
+ Label l = constants.getStrConstant(lt.value);
+ backend.emitLA(Register.A0, l, "Load string literal");
+ }
+ backend.emitSW(Register.A0, gvi.getLabel(), Register.T0, "Assign global: "+gvi.getVarName()+"(using tmp register)");
+
+ }
+ }
+ else
+ {/* TODO: Assignments inside functions
+ for(Expr target: node.targets)
+ {
+
+ backend.emitGlobalLabel("$"+target.kind);
+ backend.emitWordLiteral(node.value);
+ }*/
+ }
+ return null;
+ }
+
+ @Override
+ public Void analyze(BinaryExpr node) {
+ // statement
+ return defaultAction(node);
+ }
+
}