Merge branch 'bill/class' into apoorva/conditional

This commit is contained in:
bill
2021-04-30 22:44:19 +08:00
89 changed files with 63574 additions and 61 deletions
+109 -61
View File
@@ -13,36 +13,15 @@ import java.util.Map;
import chocopy.common.analysis.AbstractNodeAnalyzer;
import chocopy.common.analysis.SymbolTable;
import chocopy.common.analysis.types.Type;
import chocopy.common.astnodes.AssignStmt;
import chocopy.common.astnodes.BinaryExpr;
import chocopy.common.astnodes.BooleanLiteral;
import chocopy.common.astnodes.Expr;
import chocopy.common.astnodes.ExprStmt;
import chocopy.common.astnodes.ForStmt;
import chocopy.common.astnodes.Identifier;
import chocopy.common.astnodes.IfExpr;
import chocopy.common.astnodes.IfStmt;
import chocopy.common.astnodes.IndexExpr;
import chocopy.common.astnodes.IntegerLiteral;
import chocopy.common.astnodes.ListExpr;
import chocopy.common.astnodes.ListType;
import chocopy.common.astnodes.NoneLiteral;
import chocopy.common.astnodes.ReturnStmt;
import chocopy.common.astnodes.Stmt;
import chocopy.common.astnodes.StringLiteral;
import chocopy.common.astnodes.TypedVar;
import chocopy.common.astnodes.UnaryExpr;
import chocopy.common.astnodes.VarDef;
import chocopy.common.astnodes.WhileStmt;
import chocopy.common.codegen.CodeGenBase;
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.astnodes.*;
import chocopy.common.analysis.types.*;
import chocopy.common.codegen.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import chocopy.common.codegen.RiscVBackend.Register;
import chocopy.common.codegen.SymbolInfo;
/**
* This is where the main implementation of PA3 will live.
@@ -130,8 +109,7 @@ public class CodeGenImpl extends CodeGenBase
}
/** An analyzer that encapsulates code generation for statements. */
private class StmtAnalyzer extends AbstractNodeAnalyzer<Register>
{
private class StmtAnalyzer extends AbstractNodeAnalyzer<Register> {
/*
* 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
@@ -178,28 +156,67 @@ public class CodeGenImpl extends CodeGenBase
* An analyzer for the function described by FUNCINFO0, which is null for the
* top level.
*/
StmtAnalyzer(FuncInfo funcInfo0)
{
private final String size_label;
private int sp_off, max_sp;
/** Variable to store offset from frame pointer to identify next
* empty space on stack frame to store variable*/
/** An analyzer for the function described by FUNCINFO0, which is null for the top level. */
StmtAnalyzer(FuncInfo funcInfo0) {
funcInfo = funcInfo0;
if (funcInfo == null) {
sym = globalSymbols;
sp_off = max_sp = 2;
size_label = "@..main.size";
} else {
sym = funcInfo.getSymbolTable();
sp_off = max_sp = funcInfo0.getLocals().size() + 2;
size_label = "@"+funcInfo0.getFuncName()+".size";
}
epilogue = generateLocalLabel();
}
// FIXME: Example of statement.
@Override
public Register 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
// RISC-V instruction.
backend.emitMV(ZERO, ZERO, "No-op");
return null;
private void incSp(int i){
sp_off+=i+1;
max_sp = max_sp >= sp_off?max_sp:sp_off;
}
public Register analyze(CallExpr node) {
SymbolInfo Ty = globalSymbols.get(node.function.name);
if(Ty instanceof ClassInfo){
//object create
ClassInfo cls = (ClassInfo) Ty;
/**
la a0, $DoublingVector$prototype # Load pointer to prototype of: DoublingVector
jal alloc # Allocate new object in A0
sw a0, -12(fp) # Push on stack slot 3
sw a0, -16(fp) # Push argument 0 from last.
addi sp, fp, -16 # Set SP to last argument.
lw a1, 8(a0) # Load address of object's dispatch table
lw a1, 0(a1) # Load address of method: DoublingVector.__init__
jalr a1 # Invoke method: DoublingVector.__init__
addi sp, fp, -@..main.size # Set SP to stack frame top.
lw a0, -12(fp) # Pop stack slot 3
*/
backend.emitLA(A0, cls.getPrototypeLabel(),
String.format("Load pointer to prototype of: %s", cls.getClassName()));
backend.emitJAL(objectAllocLabel, "Allocate new object in A0");
backend.emitSW(A0, FP, -sp_off*wordSize, String.format("Push on stack slot %d", sp_off));
incSp(0);
backend.emitSW(A0, FP, -sp_off*wordSize, "Push argument 0 from last.");
backend.emitADDI(SP, FP, sp_off, "Set SP to last argument.");
backend.emitLW(A1, A0, getDispatchTableOffset(), "Load address of object's dispatch table");
backend.emitLW(A1, A1, getMethodOffset(cls, "__init__"), String.format("Load address of method: %s.__init__", cls.getClassName()));
backend.emitJALR(A1, String.format("Invoke method: %s.__init", cls.getClassName()));
backend.emitADDI(SP, FP, "-"+size_label, "Set SP to stack frame top.");
-- sp_off;
backend.emitLW(A0, FP, -sp_off*wordSize, String.format("Pop stack slot %d", sp_off));
} else {
//func call
}
return A0;
}
@Override
public Register analyze(NoneLiteral node)
@@ -376,11 +393,7 @@ public class CodeGenImpl extends CodeGenBase
offset++;
return null;
}
@Override
public Register analyze(TypedVar node)
{
return null;
}
@Override
public Register analyze(WhileStmt node)
{
@@ -430,29 +443,64 @@ public class CodeGenImpl extends CodeGenBase
}
@Override
public Register analyze(IndexExpr node) {
System.out.println(node);
return defaultAction(node);
}
public Register analyze(MemberExpr node) {
ClassInfo objectClass = (ClassInfo) globalSymbols.get(node.object.getInferredType().className());
Label label = generateLocalLabel();
Register obj = node.object.dispatch(this);
backend.emitBNEZ(obj, label, "Ensure not None");
backend.emitJ(errorNone, "Go to error handler");
backend.emitLocalLabel(label, "Not None");
backend.emitLW(A0, obj, getAttrOffset(objectClass, node.member.name),
String.format("Get attribute: %s.%s", objectClass.getClassName(), node.member.name));
return A0;
}
public Register analyze(MethodCallExpr node) {
Register obj = node.method.object.dispatch(this);
int n_args = node.args.size();
return defaultAction(node);
}
@Override
public Register analyze(ListType node) {
System.out.println(node);
return defaultAction(node);
}
Label label = generateLocalLabel();
backend.emitBNEZ(obj, label, "Ensure not None");
backend.emitJ(errorNone, "Go to error handler");
backend.emitLocalLabel(label, "Not None");
incSp(n_args+1);
backend.emitSW(obj, FP, (n_args - sp_off) *wordSize, String.format("Push argument %d from last.", n_args));
for (int i = 0; i < n_args; ++i)
backend.emitSW(node.args.get(i).dispatch(this), FP, (n_args - i - 1 - sp_off) * wordSize,
String.format("Push argument %d from last.", n_args - i - 1));
backend.emitLW(A0, FP, (n_args- sp_off) * wordSize, String.format("Peek stack slot %d", sp_off - (n_args + 1)));
ClassInfo objectClass = (ClassInfo)sym.get(((Identifier)node.method.object).name);
backend.emitLW(A1, A0, getDispatchTableOffset(), "Load address of object's dispatch table");
backend.emitLW(A1, A1, getMethodOffset(objectClass, node.method.member.name),
String.format("Load address of method: %s.%s", objectClass.getClassName(), node.method.member.name));
backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument.");
backend.emitJALR(A1, String.format("Invoke method: %s.%s", objectClass.getClassName(), node.method.member.name));
backend.emitInsn(String.format("addi sp, fp, -%s", size_label), "Set SP to stack frame top.");
sp_off -= n_args+1;
return A0;
}
public Register analyze(ReturnStmt node) {
return null;
}
// FIXME: More, of course.
}