Assignment for global variables

master
Apoorva Ranade 3 years ago
parent 9f1681bb23
commit 913fd45dc1

@ -4,22 +4,38 @@ import chocopy.common.analysis.AbstractNodeAnalyzer;
import chocopy.common.analysis.SymbolTable; import chocopy.common.analysis.SymbolTable;
import chocopy.common.astnodes.ReturnStmt; import chocopy.common.astnodes.ReturnStmt;
import chocopy.common.astnodes.Stmt; 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.*;
import chocopy.common.codegen.Label;
import chocopy.common.codegen.RiscVBackend.Register;
import java.util.List; import java.util.List;
import chocopy.common.analysis.types.Type;
import static chocopy.common.codegen.RiscVBackend.Register.*; import static chocopy.common.codegen.RiscVBackend.Register.*;
/** /**
* This is where the main implementation of PA3 will live. * This is where the main implementation of PA3 will live.
* *
* <p>A large part of the functionality has already been implemented in the base class, CodeGenBase. * <p>
* Make sure to read through that class, since you will want to use many of its fields and utility * A large part of the functionality has already been implemented in the base
* methods in this class when emitting code. * 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.
* *
* <p>Also read the PDF spec for details on what the base class does and what APIs it exposes for * <p>
* its sub-class (this one). Of particular importance is knowing what all the SymbolInfo classes * Also read the PDF spec for details on what the base class does and what APIs
* contain. * 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 {
@ -38,17 +54,19 @@ public class CodeGenImpl extends CodeGenBase {
/** /**
* Emits the top level of the program. * Emits the top level of the program.
* *
* <p>This method is invoked exactly once, and is surrounded by some boilerplate code that: (1) * <p>
* 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.
* *
* <p>You only need to generate code for statements. * <p>
* You only need to generate code for statements.
* *
* @param statements top level statements * @param statements top level statements
*/ */
protected void emitTopLevel(List<Stmt> statements) { protected void emitTopLevel(List<Stmt> statements) {
StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(null); StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(null);
backend.emitADDI( backend.emitADDI(SP, SP, -2 * backend.getWordSize(), "Saved FP and saved RA (unused at top level).");
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, 0, "Top saved FP is 0.");
backend.emitSW(ZERO, SP, 4, "Top saved RA is 0."); backend.emitSW(ZERO, SP, 4, "Top saved RA is 0.");
backend.emitADDI(FP, SP, 2 * backend.getWordSize(), "Set FP to previous SP."); 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. * Emits the code for a function described by FUNCINFO.
* *
* <p>This method is invoked once per function and method definition. At the code generation * <p>
* stage, nested functions are emitted as separate functions of their own. So if function `bar` * This method is invoked once per function and method definition. At the code
* is nested within function `foo`, you only emit `foo`'s code for `foo` and only emit `bar`'s * generation stage, nested functions are emitted as separate functions of their
* code for `bar`. * 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()); backend.emitGlobalLabel(funcInfo.getCodeLabel());
@ -86,34 +105,30 @@ public class CodeGenImpl extends CodeGenBase {
/** An analyzer that encapsulates code generation for statements. */ /** An analyzer that encapsulates code generation for statements. */
private class StmtAnalyzer extends AbstractNodeAnalyzer<Void> { private class StmtAnalyzer extends AbstractNodeAnalyzer<Void> {
/* /*
* The symbol table has all the info you need to determine * The symbol table has all the info you need to determine what a given
* what a given identifier 'x' in the current scope is. You can * identifier 'x' in the current scope is. You can use it as follows: SymbolInfo
* use it as follows: * x = sym.get("x");
* SymbolInfo x = sym.get("x");
* *
* A SymbolInfo can be one the following: * A SymbolInfo can be one the following: - ClassInfo: a descriptor for classes
* - ClassInfo: a descriptor for classes * - FuncInfo: a descriptor for functions/methods - AttrInfo: a descriptor for
* - FuncInfo: a descriptor for functions/methods * attributes - GlobalVarInfo: a descriptor for global variables - StackVarInfo:
* - AttrInfo: a descriptor for attributes * a descriptor for variables allocated on the stack, such as locals and
* - GlobalVarInfo: a descriptor for global variables * parameters
* - StackVarInfo: a descriptor for variables allocated on the stack,
* such as locals and parameters
* *
* Since the input program is assumed to be semantically * Since the input program is assumed to be semantically valid and well-typed at
* valid and well-typed at this stage, you can always assume that * this stage, you can always assume that the symbol table contains valid
* the symbol table contains valid information. For example, in * information. For example, in an expression `foo()` you KNOW that
* an expression `foo()` you KNOW that sym.get("foo") will either be * sym.get("foo") will either be a FuncInfo or ClassInfo, but not any of the
* a FuncInfo or ClassInfo, but not any of the other infos * other infos and never null.
* and never null.
* *
* The symbol table in funcInfo has already been populated in * The symbol table in funcInfo has already been populated in the base class:
* the base class: CodeGenBase. You do not need to add anything to * CodeGenBase. You do not need to add anything to the symbol table. Simply
* the symbol table. Simply query it with an identifier name to * query it with an identifier name to get a descriptor for a function, class,
* get a descriptor for a function, class, variable, etc. * variable, etc.
* *
* The symbol table also maps nonlocal and global vars, so you * The symbol table also maps nonlocal and global vars, so you only need to
* only need to lookup one symbol table and it will fetch the * lookup one symbol table and it will fetch the appropriate info for the var
* appropriate info for the var that is currently in scope. * that is currently in scope.
*/ */
/** Symbol table for my statements. */ /** 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. */ /** The descriptor for the current function, or null at the top level. */
private final FuncInfo funcInfo; 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) { StmtAnalyzer(FuncInfo funcInfo0) {
funcInfo = funcInfo0; funcInfo = funcInfo0;
if (funcInfo == null) { if (funcInfo == null) {
@ -148,6 +166,56 @@ public class CodeGenImpl extends CodeGenBase {
} }
// FIXME: More, of course. // 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);
}
} }

Loading…
Cancel
Save