|
|
@ -595,16 +595,20 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public Register analyze(IfExpr node)
|
|
|
|
public Register analyze(IfExpr node)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
System.out.println("Inside IfExpr: ");
|
|
|
|
System.out.println("Inside IfExpr: ");
|
|
|
|
Register result = node.condition.dispatch(this);
|
|
|
|
Register result = node.condition.dispatch(this);
|
|
|
|
Label ln = generateLocalLabel();
|
|
|
|
Label ln = generateLocalLabel();
|
|
|
|
backend.emitBEQZ(result, ln,"Jump to end of loop");
|
|
|
|
|
|
|
|
node.thenExpr.dispatch(this);
|
|
|
|
|
|
|
|
backend.emitJ(ln, "Jump to end of if expression");
|
|
|
|
|
|
|
|
elseBlock.push(generateLocalLabel());
|
|
|
|
elseBlock.push(generateLocalLabel());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend.emitBEQZ(result, elseBlock.peek(),"Jump to end of loop");
|
|
|
|
|
|
|
|
result = node.thenExpr.dispatch(this);
|
|
|
|
|
|
|
|
if(result != A0)
|
|
|
|
|
|
|
|
backend.emitMV(A0, result, "move result");
|
|
|
|
|
|
|
|
backend.emitJ(ln, "Jump to end of if expression");
|
|
|
|
backend.emitLocalLabel(elseBlock.peek(), "Else part of if expression");
|
|
|
|
backend.emitLocalLabel(elseBlock.peek(), "Else part of if expression");
|
|
|
|
node.elseExpr.dispatch(this);
|
|
|
|
result = node.elseExpr.dispatch(this);
|
|
|
|
|
|
|
|
if(result != A0)
|
|
|
|
|
|
|
|
backend.emitMV(A0, result, "move result");
|
|
|
|
elseBlock.pop();
|
|
|
|
elseBlock.pop();
|
|
|
|
backend.emitLocalLabel(ln, "End of if expression");
|
|
|
|
backend.emitLocalLabel(ln, "End of if expression");
|
|
|
|
return A0;
|
|
|
|
return A0;
|
|
|
@ -694,7 +698,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
else if(operator.equals(">="))
|
|
|
|
else if(operator.equals(">="))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
backend.emitADDI(Register.A0,Register.A0, 1, "Increment by 1");
|
|
|
|
backend.emitADDI(Register.A0,Register.A0, 1, "Increment by 1");
|
|
|
|
backend.emitSLT(Register.A0, Register.A0, Register.T0, comment);
|
|
|
|
backend.emitSLT(Register.A0, T0, A0, comment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Maybe NA
|
|
|
|
/* Maybe NA
|
|
|
|
else if(operator.equals("is"))
|
|
|
|
else if(operator.equals("is"))
|
|
|
@ -828,14 +832,14 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(operator.equals("is"))
|
|
|
|
else if(operator.equals("is"))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
node.right.dispatch(this);
|
|
|
|
Register l = node.right.dispatch(this);
|
|
|
|
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
|
|
|
|
backend.emitSW(l, FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
|
|
|
|
incSp(1);
|
|
|
|
incSp(1);
|
|
|
|
node.left.dispatch(this);
|
|
|
|
Register r = node.left.dispatch(this);
|
|
|
|
sp_off--;
|
|
|
|
sp_off--;
|
|
|
|
backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
|
|
|
|
backend.emitLW(T0, FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
|
|
|
|
backend.emitXOR(Register.A0, Register.A0, Register.T0, "Operator: is");
|
|
|
|
backend.emitXOR(A0, r, T0, "Operator: is");
|
|
|
|
backend.emitSEQZ(Register.A0, Register.A0, "Result is True if XOR equals 0");
|
|
|
|
backend.emitSEQZ(A0, r, "Result is True if XOR equals 0");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -848,20 +852,12 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
public Register analyze(UnaryExpr node)
|
|
|
|
public Register analyze(UnaryExpr node)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(node.operator.equals("-") && node.getInferredType().equals(Type.INT_TYPE))
|
|
|
|
if(node.operator.equals("-") && node.getInferredType().equals(Type.INT_TYPE))
|
|
|
|
{
|
|
|
|
backend.emitSUB(A0, ZERO, node.operand.dispatch(this), "Unary negation");
|
|
|
|
node.operand.dispatch(this);
|
|
|
|
|
|
|
|
//backend.emitLI(Register.T0, -1, "Set value of Register T0 to -1");
|
|
|
|
|
|
|
|
//backend.emitMUL(Register.A0, Register.A0, Register.T0, "Multiply by -1");
|
|
|
|
|
|
|
|
backend.emitSUB(Register.A0, Register.ZERO, Register.A0, "Unary negation");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if(node.operator.equals("not") && node.getInferredType().equals(Type.BOOL_TYPE))
|
|
|
|
else if(node.operator.equals("not") && node.getInferredType().equals(Type.BOOL_TYPE))
|
|
|
|
{
|
|
|
|
backend.emitSEQZ(A0, node.operand.dispatch(this), "Not operation on Register A0");
|
|
|
|
node.operand.dispatch(this);
|
|
|
|
|
|
|
|
backend.emitSEQZ(Register.T0, Register.A0, "Not operation on Register A0");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
else
|
|
|
|
backend.emitJAL(errorNI, "Operator not implemented");
|
|
|
|
backend.emitJAL(errorNI, "Operator not implemented");
|
|
|
|
return Register.A0;
|
|
|
|
return A0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public Register analyze(Identifier node)
|
|
|
|
public Register analyze(Identifier node)
|
|
|
@ -1078,17 +1074,21 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public Register analyze(IndexExpr node)
|
|
|
|
public Register analyze(IndexExpr node)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
incSp(1);
|
|
|
|
boolean old_lvalue = l_value;
|
|
|
|
|
|
|
|
l_value = false;
|
|
|
|
Register listObj = node.list.dispatch(this);
|
|
|
|
Register listObj = node.list.dispatch(this);
|
|
|
|
backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off));
|
|
|
|
backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off));
|
|
|
|
|
|
|
|
incSp(1);
|
|
|
|
|
|
|
|
|
|
|
|
Register index = node.index.dispatch(this);
|
|
|
|
Register index = node.index.dispatch(this);
|
|
|
|
|
|
|
|
l_value = old_lvalue;
|
|
|
|
Register vacantReg = (index != A0) ? A0 : A1;
|
|
|
|
Register vacantReg = (index != A0) ? A0 : A1;
|
|
|
|
int tmpHandle = getRegister();
|
|
|
|
int tmpHandle = getRegister();
|
|
|
|
Register temp = registerPool[tmpHandle];
|
|
|
|
Register temp = registerPool[tmpHandle];
|
|
|
|
|
|
|
|
|
|
|
|
if (node.list.getInferredType().isListType())
|
|
|
|
if (node.list.getInferredType().isListType())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
backend.emitLW(vacantReg, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
|
|
|
|
backend.emitLW(vacantReg, FP, -(sp_off-1) * wordSize, String.format("Pop stack slot %d", sp_off-1));
|
|
|
|
final Label bp = generateLocalLabel();
|
|
|
|
final Label bp = generateLocalLabel();
|
|
|
|
backend.emitBNEZ(vacantReg, bp, "Ensure not None");
|
|
|
|
backend.emitBNEZ(vacantReg, bp, "Ensure not None");
|
|
|
|
backend.emitJ(errorNone, "Go to error handler");
|
|
|
|
backend.emitJ(errorNone, "Go to error handler");
|
|
|
@ -1102,37 +1102,31 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
backend.emitLI(temp, wordSize, "Word size in bytes");
|
|
|
|
backend.emitLI(temp, wordSize, "Word size in bytes");
|
|
|
|
backend.emitMUL(index, index, temp, "Compute list element offset in bytes");
|
|
|
|
backend.emitMUL(index, index, temp, "Compute list element offset in bytes");
|
|
|
|
backend.emitADD(vacantReg, vacantReg, index, "Pointer to list element");
|
|
|
|
backend.emitADD(vacantReg, vacantReg, index, "Pointer to list element");
|
|
|
|
backend.emitMV(temp,vacantReg,"Copy Result");
|
|
|
|
if(l_value)
|
|
|
|
|
|
|
|
backend.emitMV(A0,vacantReg,"Copy Result");
|
|
|
|
|
|
|
|
else
|
|
|
|
backend.emitLW(A0, vacantReg, 0, "Load list element");
|
|
|
|
backend.emitLW(A0, vacantReg, 0, "Load list element");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
backend.emitLW(vacantReg, FP, - sp_off * wordSize, String.format("Peek stack slot %d", sp_off- 1));
|
|
|
|
backend.emitLW(vacantReg, FP, - (sp_off-1) * wordSize, String.format("Peek stack slot %d", sp_off- 1));
|
|
|
|
Label boundchk = generateLocalLabel();
|
|
|
|
Label boundchk = generateLocalLabel();
|
|
|
|
backend.emitLW(temp, vacantReg, getAttrOffset(strClass, "__len__"), "Load attribute: __len__");
|
|
|
|
backend.emitLW(temp, vacantReg, getAttrOffset(strClass, "__len__"), "Load attribute: __len__");
|
|
|
|
backend.emitBLTU(index, temp, boundchk, "Ensure 0 <= idx < len");
|
|
|
|
backend.emitBLTU(index, temp, boundchk, "Ensure 0 <= idx < len");
|
|
|
|
backend.emitJ(errorOob, "Go to error handler");
|
|
|
|
backend.emitJ(errorOob, "Go to error handler");
|
|
|
|
backend.emitLocalLabel(boundchk, "Index within bounds");
|
|
|
|
backend.emitLocalLabel(boundchk, "Index within bounds");
|
|
|
|
incSp(1);
|
|
|
|
backend.emitADDI(T0, vacantReg, 4 * wordSize, "Convert index to offset to char in bytes");
|
|
|
|
backend.emitSW(index, RiscVBackend.Register.FP, -sp_off * wordSize, String.format("Push on stack slot %d",sp_off));
|
|
|
|
backend.emitADD(T0, T0, index, "load char loc");
|
|
|
|
|
|
|
|
|
|
|
|
getAttrOffset(strClass, "__len__");
|
|
|
|
|
|
|
|
backend.emitLW(T0, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
|
|
|
|
|
|
|
|
--sp_off;
|
|
|
|
|
|
|
|
backend.emitSW(A1, FP, -sp_off*wordSize, String.format("Push Argument %d", sp_off));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend.emitADDI(T0, T0, 4 * wordSize, "Convert index to offset to char in bytes");
|
|
|
|
|
|
|
|
backend.emitLBU(T0, T0, 0, "Load character");
|
|
|
|
backend.emitLBU(T0, T0, 0, "Load character");
|
|
|
|
backend.emitLA(vacantReg, strClass.getPrototypeLabel(), "Create Str for char");
|
|
|
|
backend.emitSLLI(A0, T0, 2, "A0 = T0 * 4");
|
|
|
|
backend.emitJAL(objectAllocLabel, "Alloc char");
|
|
|
|
backend.emitSLLI(T0, T0, 4, "T0 = T0 * 16");
|
|
|
|
backend.emitLI(T1, 1, "str size");
|
|
|
|
backend.emitADD(T0, T0, A0, " T0*20 = offset to all chars");
|
|
|
|
backend.emitSW(T1, vacantReg, 3*wordSize, "len");
|
|
|
|
backend.emitLA(A0, allCharsLabel, "All chars");
|
|
|
|
backend.emitSW(T0, vacantReg, 4*wordSize, "ch");
|
|
|
|
backend.emitADD(A0, A0, T0, "get the char");
|
|
|
|
backend.emitMV(temp,vacantReg,"Copy Result");
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
freeRegister(tmpHandle);
|
|
|
|
freeRegister(tmpHandle);
|
|
|
|
-- sp_off;
|
|
|
|
-- sp_off;
|
|
|
|
return temp;
|
|
|
|
return A0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Register analyze(MemberExpr node)
|
|
|
|
public Register analyze(MemberExpr node)
|
|
|
|