|
|
|
@ -130,7 +130,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** An analyzer that encapsulates code generation for statements. */
|
|
|
|
|
private class StmtAnalyzer extends AbstractNodeAnalyzer<Void>
|
|
|
|
|
private class StmtAnalyzer extends AbstractNodeAnalyzer<Register>
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* The symbol table has all the info you need to determine what a given
|
|
|
|
@ -191,7 +191,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
|
|
|
|
|
// FIXME: Example of statement.
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(ReturnStmt stmt)
|
|
|
|
|
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.
|
|
|
|
@ -202,38 +202,38 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(NoneLiteral node)
|
|
|
|
|
public Register analyze(NoneLiteral node)
|
|
|
|
|
{
|
|
|
|
|
backend.emitMV(Register.A0, Register.ZERO, "Load none");
|
|
|
|
|
return null;
|
|
|
|
|
return Register.A0;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(StringLiteral node)
|
|
|
|
|
public Register analyze(StringLiteral node)
|
|
|
|
|
{
|
|
|
|
|
Label l = constants.getStrConstant(node.value);
|
|
|
|
|
backend.emitLA(Register.A0, l, "Load string literal");
|
|
|
|
|
return null;
|
|
|
|
|
return Register.A0;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(IntegerLiteral node)
|
|
|
|
|
public Register analyze(IntegerLiteral node)
|
|
|
|
|
{
|
|
|
|
|
backend.emitLI(Register.A0, node.value, "Load integer literal "+node.value);
|
|
|
|
|
return null;
|
|
|
|
|
return Register.A0;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(BooleanLiteral node)
|
|
|
|
|
public Register analyze(BooleanLiteral node)
|
|
|
|
|
{
|
|
|
|
|
if(node.value==true)
|
|
|
|
|
backend.emitLI(Register.A0, 1, "Load boolean literal: true ");
|
|
|
|
|
else
|
|
|
|
|
backend.emitLI(Register.A0, 0, "Load boolean literal: false ");
|
|
|
|
|
return null;
|
|
|
|
|
return Register.A0;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(AssignStmt node)
|
|
|
|
|
public Register analyze(AssignStmt node)
|
|
|
|
|
{
|
|
|
|
|
Type t = node.value.getInferredType();
|
|
|
|
|
if(t.isSpecialType())
|
|
|
|
|
if(t.isSpecialType() || t.isListType())
|
|
|
|
|
{
|
|
|
|
|
node.value.dispatch(this);
|
|
|
|
|
if (sym.getParent() == null)
|
|
|
|
@ -250,7 +250,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
{
|
|
|
|
|
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());
|
|
|
|
|
backend.emitSW(Register.A0, Register.FP, -loc*4, "Load local variable: "+svi.getVarName());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -258,17 +258,17 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
{//TODO: Object Assignment
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
return Register.A0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(ExprStmt node)
|
|
|
|
|
public Register analyze(ExprStmt node)
|
|
|
|
|
{
|
|
|
|
|
node.expr.dispatch(this);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(IfExpr node)
|
|
|
|
|
public Register analyze(IfExpr node)
|
|
|
|
|
{
|
|
|
|
|
node.condition.dispatch(this);
|
|
|
|
|
Label ln = generateLocalLabel();
|
|
|
|
@ -280,7 +280,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(IfStmt node)
|
|
|
|
|
public Register analyze(IfStmt node)
|
|
|
|
|
{
|
|
|
|
|
node.condition.dispatch(this);
|
|
|
|
|
Label ln = generateLocalLabel();
|
|
|
|
@ -294,14 +294,14 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(BinaryExpr node)
|
|
|
|
|
public Register analyze(BinaryExpr node)
|
|
|
|
|
{
|
|
|
|
|
node.left.dispatch(this);
|
|
|
|
|
backend.emitSW(Register.A0, Register.FP, offset*4, "Push on stack slot "+offset);
|
|
|
|
|
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);
|
|
|
|
|
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");
|
|
|
|
@ -339,7 +339,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(UnaryExpr node)
|
|
|
|
|
public Register analyze(UnaryExpr node)
|
|
|
|
|
{
|
|
|
|
|
node.operand.dispatch(this);
|
|
|
|
|
if(node.operator.equals("-"))
|
|
|
|
@ -347,11 +347,11 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
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;
|
|
|
|
|
return Register.A0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(Identifier node)
|
|
|
|
|
public Register analyze(Identifier node)
|
|
|
|
|
{
|
|
|
|
|
if (sym.getParent() == null)
|
|
|
|
|
{
|
|
|
|
@ -362,27 +362,27 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
{
|
|
|
|
|
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());
|
|
|
|
|
backend.emitLW(Register.A0, Register.FP, -loc*4, "Load local variable: "+svi.getVarName());
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(VarDef node)
|
|
|
|
|
public Register 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");
|
|
|
|
|
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)
|
|
|
|
|
public Register analyze(TypedVar node)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(WhileStmt node)
|
|
|
|
|
public Register analyze(WhileStmt node)
|
|
|
|
|
{
|
|
|
|
|
Label startLoop = generateLocalLabel();
|
|
|
|
|
backend.emitLocalLabel(startLoop, "Beginning of while loop");
|
|
|
|
@ -394,30 +394,57 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
backend.emitLocalLabel(endLoop, "End of while loop");
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public Register analyze(ListExpr node) {
|
|
|
|
|
int l = node.elements.size();
|
|
|
|
|
int i = l;
|
|
|
|
|
for(Expr exp:node.elements)
|
|
|
|
|
{
|
|
|
|
|
Register r = exp.dispatch(this);
|
|
|
|
|
backend.emitSW(r,Register.FP,-offset*4,"Push argument "+i+" from last.");
|
|
|
|
|
offset++;
|
|
|
|
|
i--;
|
|
|
|
|
}
|
|
|
|
|
backend.emitLI(Register.A0, l, "Pass list length");
|
|
|
|
|
backend.emitSW(Register.A0, Register.FP, -offset*4, "Push argument "+i+" from last.");
|
|
|
|
|
offset++;
|
|
|
|
|
backend.emitADDI(Register.SP, Register.SP, -offset*4, "Set SP to last argument.");
|
|
|
|
|
//TODO: Store reference to variable
|
|
|
|
|
return Register.A0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(ForStmt node) {
|
|
|
|
|
// control flow
|
|
|
|
|
return defaultAction(node);
|
|
|
|
|
public Register analyze(ForStmt node) {
|
|
|
|
|
System.out.println(node);
|
|
|
|
|
/*
|
|
|
|
|
node.
|
|
|
|
|
Label startLoop = generateLocalLabel();
|
|
|
|
|
backend.emitLocalLabel(startLoop, "Beginning of while loop");
|
|
|
|
|
node.condition.dispatch(this);
|
|
|
|
|
Label endLoop = elseBlock;
|
|
|
|
|
for(Stmt stmt:node.body)
|
|
|
|
|
stmt.dispatch(this);
|
|
|
|
|
backend.emitJ(startLoop, "Jump to beginning of loop");
|
|
|
|
|
backend.emitLocalLabel(endLoop, "End of while loop");*/
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(IndexExpr node) {
|
|
|
|
|
// statement
|
|
|
|
|
public Register analyze(IndexExpr node) {
|
|
|
|
|
System.out.println(node);
|
|
|
|
|
|
|
|
|
|
return defaultAction(node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(ListExpr node) {
|
|
|
|
|
// statement
|
|
|
|
|
return defaultAction(node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Void analyze(ListType node) {
|
|
|
|
|
// statement
|
|
|
|
|
public Register analyze(ListType node) {
|
|
|
|
|
System.out.println(node);
|
|
|
|
|
return defaultAction(node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|