Verified Commit a2074e51 authored by Recolic Keghart's avatar Recolic Keghart 🎱

theirs

parent f14dfd0f
package chocopy.pa3;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import chocopy.common.analysis.SymbolTable;
import chocopy.common.analysis.AbstractNodeAnalyzer;
import chocopy.common.astnodes.Stmt;
import chocopy.common.astnodes.ReturnStmt;
import chocopy.common.codegen.CodeGenBase;
import chocopy.common.codegen.FuncInfo;
import chocopy.common.codegen.Label;
import chocopy.common.codegen.RiscVBackend;
import chocopy.common.codegen.SymbolInfo;
import chocopy.common.analysis.types.SymbolType;
import chocopy.common.astnodes.*;
import chocopy.common.codegen.*;
import static chocopy.common.codegen.RiscVBackend.Register.*;
......@@ -60,7 +58,6 @@ public class CodeGenImpl extends CodeGenBase {
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) {
stmt.dispatch(stmtAnalyzer);
}
......@@ -80,7 +77,13 @@ public class CodeGenImpl extends CodeGenBase {
protected void emitUserDefinedFunction(FuncInfo funcInfo) {
backend.emitGlobalLabel(funcInfo.getCodeLabel());
StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(funcInfo);
// Prologue:
backend.emitSW(FP, SP, 0, "Save old FP");
backend.emitSW(RA, SP, -4, "Save RA");
backend.emitADDI(SP, SP, -8, "Increment stack pointer 2 places");
backend.emitADDI(FP, SP, 4, "FP is one slot below top of stack");
// Emit code for function stmts
for (Stmt stmt : funcInfo.getStatements()) {
stmt.dispatch(stmtAnalyzer);
}
......@@ -89,11 +92,13 @@ public class CodeGenImpl extends CodeGenBase {
backend.emitLocalLabel(stmtAnalyzer.epilogue, "Epilogue");
// FIXME: {... reset fp etc. ...}
backend.emitLW(RA, FP, 0, "Restore RA");
backend.emitLW(FP, FP, 4, "Restore old FP");
backend.emitJR(RA, "Return to caller");
}
/** An analyzer that encapsulates code generation for statments. */
private class StmtAnalyzer extends AbstractNodeAnalyzer<Void> {
private class StmtAnalyzer extends AbstractNodeAnalyzer<Object> {
/*
* The symbol table has all the info you need to determine
* what a given identifier 'x' in the current scope is. You can
......@@ -158,6 +163,97 @@ public class CodeGenImpl extends CodeGenBase {
return null;
}
@Override
public Void analyze(ExprStmt exprStmt) {
exprStmt.expr.dispatch(this);
return null;
}
@Override
public Void analyze(CallExpr callExpr) {
// NOT DONE
if (globalSymbols.get(callExpr.function.name) instanceof FuncInfo) {
FuncInfo func = (FuncInfo) globalSymbols.get(callExpr.function.name);
for (Expr e : callExpr.args) {
backend.emitADDI(SP, SP, -4, "Increment stack ptr by 1");
e.dispatch(this);
}
// Push parameters onto stack
backend.emitJAL(func.getCodeLabel(), "Invoke function");
// Restore SP
for (Expr e : callExpr.args) {
backend.emitADDI(SP, SP, 4, "Increment stack ptr by 1");
}
}
return null;
}
@Override
public Void analyze(BooleanLiteral literal) {
  • literals: remove my version, to fit theirs. I create a new object on stack just because I don't know constants.getBoolConstant.

    Edited by Recolic Keghart
Please register or sign in to reply
/* Push boolean literal onto stack, incrementing stack pointer*/
backend.emitLA(A0, constants.getBoolConstant(literal.value), "Load boolean literal into a0");
backend.emitSW(A0, SP, 0, "Push on stack");
return null;
}
@Override
public Void analyze(IntegerLiteral literal) {
backend.emitLA(A0, constants.getIntConstant(literal.value), "Load integer literal into a0");
backend.emitSW(A0, SP, 0, "Push on stack");
return null;
}
@Override
public Void analyze(StringLiteral literal) {
backend.emitLA(A0, constants.getStrConstant(literal.value), "Load string literal into a0");
backend.emitSW(A0, SP, 0, "Push on stack");
return null;
}
@Override
public Void analyze(Identifier id) {
// NOT DONE
SymbolInfo ident;
// global var case
if (this.funcInfo == null) {
ident = globalSymbols.get(id.name);
backend.emitLW(A0, ((GlobalVarInfo) ident).getLabel(), "Load identifier");
backend.emitSW(A0, SP, 0, "Push to stack");
} else { // local variable
ident = this.funcInfo.getSymbolTable().get(id.name);
}
return null;
}
@Override
public Void analyze(BinaryExpr binaryExpr) {
switch (binaryExpr.operator) {
case "+":
// needs to be extended string concatenation, list concatenation
backend.emitADDI(SP, SP, -4, "Increment stack ptr for first operand");
binaryExpr.left.dispatch(this);
backend.emitADDI(SP, SP, -4, "Increment stack ptr for second operand");
binaryExpr.right.dispatch(this);
backend.emitLW(T0, SP, 0, "Load operand 2 into t0");
backend.emitLW(T0, T0, "@.__int__", "Load value of operand 2 into t0");
backend.emitADDI(SP, SP, 4, "Decrement stack ptr for first operand");
backend.emitLW(T1, SP, 0, "Load operand 1 into t1");
backend.emitLW(T1, T1, "@.__int__", "Load value of operand 1 into t1");
backend.emitADDI(SP, SP, 4, "Decrement stack ptr for second operand");
backend.emitADD(T0, T0, T1, "Add operands");
backend.emitJAL(((FuncInfo) globalSymbols.get("int-alloc")).getCodeLabel(), "Jump to int alloc routine");
backend.emitSW(T0, SP, 0, "Push result on stack");
}
return null;
}
@Override
public Void analyze(AssignStmt assignStmt) {
return null;
}
// FIXME: More, of course.
}
......@@ -186,6 +282,17 @@ public class CodeGenImpl extends CodeGenBase {
*
*/
protected void emitCustomCode() {
backend.emitGlobalLabel(new Label("int-alloc"));
backend.emitLA(A0, intClass.getPrototypeLabel(), "Get int prototype address");
backend.emitJAL(objectAllocLabel, "Allocate int");
FuncInfo allocInt = makeFuncInfo("int-alloc", 0, SymbolType.OBJECT_TYPE,
globalSymbols, null, this::emitStdFunc);
allocInt.addParam(makeStackVarInfo("arg", SymbolType.OBJECT_TYPE,
null, allocInt));
functions.add(allocInt);
System.out.println(allocInt.getBaseName());
globalSymbols.put(allocInt.getBaseName(), allocInt);
emitErrorFunc(errorNone, "Operation on None");
emitErrorFunc(errorDiv, "Divison by zero");
emitErrorFunc(errorOob, "Index out of bounds");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment