|
|
@ -39,9 +39,9 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
protected final Label strcatLabel = new Label("strcat");
|
|
|
|
protected final Label strcatLabel = new Label("strcat");
|
|
|
|
protected final Label concatLabel = new Label("concat");
|
|
|
|
protected final Label concatLabel = new Label("concat");
|
|
|
|
protected final Label conslistLabel = new Label("conslist");
|
|
|
|
protected final Label conslistLabel = new Label("conslist");
|
|
|
|
|
|
|
|
protected final Label initcharsLabel = new Label("initchars");
|
|
|
|
|
|
|
|
protected final Label allCharsLabel = new Label("allChars");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Operation on None. */
|
|
|
|
/** Operation on None. */
|
|
|
|
private final Label errorNone = new Label("error.None");
|
|
|
|
private final Label errorNone = new Label("error.None");
|
|
|
@ -86,7 +86,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
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.");
|
|
|
|
|
|
|
|
backend.emitJAL(initcharsLabel,"Initialize one-character strings");
|
|
|
|
for (Stmt stmt : statements)
|
|
|
|
for (Stmt stmt : statements)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
stmt.dispatch(stmtAnalyzer);
|
|
|
|
stmt.dispatch(stmtAnalyzer);
|
|
|
@ -1008,7 +1008,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
r=getRegister();
|
|
|
|
r=getRegister();
|
|
|
|
regs.add(r);
|
|
|
|
regs.add(r);
|
|
|
|
Register iter = registerPool[r];
|
|
|
|
Register iter = registerPool[r];
|
|
|
|
backend.emitSW(l, Register.FP, -sp_off*wordSize, "Store index on stack");
|
|
|
|
backend.emitSW(l, Register.FP, -sp_off*wordSize, "Store location on stack");
|
|
|
|
incSp(1);
|
|
|
|
incSp(1);
|
|
|
|
backend.emitMV(iter, Register.ZERO, "Initialize index variable");
|
|
|
|
backend.emitMV(iter, Register.ZERO, "Initialize index variable");
|
|
|
|
backend.emitSW(iter, Register.FP, -sp_off*wordSize, "Store index on stack");
|
|
|
|
backend.emitSW(iter, Register.FP, -sp_off*wordSize, "Store index on stack");
|
|
|
@ -1048,6 +1048,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Label startLoop = generateLocalLabel();
|
|
|
|
Label startLoop = generateLocalLabel();
|
|
|
|
Label endLoop = generateLocalLabel();
|
|
|
|
Label endLoop = generateLocalLabel();
|
|
|
|
|
|
|
|
//Label temp = generateLocalLabel();
|
|
|
|
r=getRegister();
|
|
|
|
r=getRegister();
|
|
|
|
regs.add(r);
|
|
|
|
regs.add(r);
|
|
|
|
Register iden = registerPool[r];
|
|
|
|
Register iden = registerPool[r];
|
|
|
@ -1058,17 +1059,33 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
r=getRegister();
|
|
|
|
r=getRegister();
|
|
|
|
regs.add(r);
|
|
|
|
regs.add(r);
|
|
|
|
Register ln = registerPool[r];
|
|
|
|
Register ln = registerPool[r];
|
|
|
|
|
|
|
|
//backend.emitBNEZ(Register.A0, temp, "Ensure not none");
|
|
|
|
|
|
|
|
//backend.emitJ(errorNone, "Empty String");
|
|
|
|
|
|
|
|
//backend.emitLocalLabel(temp, "Continue execution for for-loop");
|
|
|
|
backend.emitMV(l,Register.A0,"Location of String");
|
|
|
|
backend.emitMV(l,Register.A0,"Location of String");
|
|
|
|
r=getRegister();
|
|
|
|
r=getRegister();
|
|
|
|
regs.add(r);
|
|
|
|
regs.add(r);
|
|
|
|
Register iter = registerPool[r];
|
|
|
|
Register iter = registerPool[r];
|
|
|
|
|
|
|
|
backend.emitSW(l, Register.FP, -sp_off*wordSize, "Store location on stack");
|
|
|
|
|
|
|
|
incSp(1);
|
|
|
|
backend.emitMV(iter, Register.ZERO, "Initialize index variable");
|
|
|
|
backend.emitMV(iter, Register.ZERO, "Initialize index variable");
|
|
|
|
|
|
|
|
backend.emitSW(iter, Register.FP, -sp_off*wordSize, "Store index on stack");
|
|
|
|
|
|
|
|
incSp(1);
|
|
|
|
backend.emitLocalLabel(startLoop, "Start for loop");
|
|
|
|
backend.emitLocalLabel(startLoop, "Start for loop");
|
|
|
|
|
|
|
|
backend.emitLW(iter, Register.FP, -(sp_off-1)*wordSize, "Load index from stack");
|
|
|
|
|
|
|
|
backend.emitLW(l, Register.FP, -(sp_off-2)*wordSize, "Store string location from stack");
|
|
|
|
backend.emitLW(ln, l, getAttrOffset(strClass, "__len__"), "Get attribute __len__");
|
|
|
|
backend.emitLW(ln, l, getAttrOffset(strClass, "__len__"), "Get attribute __len__");
|
|
|
|
backend.emitBGE(iter, ln, endLoop, "Jump to end loop if counter exceeds length");
|
|
|
|
backend.emitBGEU(iter, ln, endLoop, "Jump to end loop if counter exceeds length");
|
|
|
|
|
|
|
|
backend.emitADDI(iter, iter, 1, "Increment counter");
|
|
|
|
|
|
|
|
backend.emitSW(iter, Register.FP, -sp_off*wordSize, "Store index on stack");
|
|
|
|
|
|
|
|
incSp(1);
|
|
|
|
backend.emitADDI(iden, iter, 4 * wordSize, "Convert index to offset to char in bytes");
|
|
|
|
backend.emitADDI(iden, iter, 4 * wordSize, "Convert index to offset to char in bytes");
|
|
|
|
|
|
|
|
backend.emitADD(iden, l, iden, "Get pointer to char");
|
|
|
|
backend.emitLBU(iden, iden, 0, "Load character");
|
|
|
|
backend.emitLBU(iden, iden, 0, "Load character");
|
|
|
|
|
|
|
|
backend.emitLI(iter, 20, "Load register");
|
|
|
|
|
|
|
|
backend.emitMUL(iden, iden, iter, "Multiply by size of String object");
|
|
|
|
|
|
|
|
backend.emitLA(l, allCharsLabel, "Index into single-char table");
|
|
|
|
|
|
|
|
backend.emitADD(l, l, iden, "Add size to chartable index");
|
|
|
|
SymbolInfo info = sym.get(node.identifier.name);
|
|
|
|
SymbolInfo info = sym.get(node.identifier.name);
|
|
|
|
if(info instanceof GlobalVarInfo)
|
|
|
|
if(info instanceof GlobalVarInfo)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -1083,7 +1100,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(Stmt stmt:node.body)
|
|
|
|
for(Stmt stmt:node.body)
|
|
|
|
stmt.dispatch(this);
|
|
|
|
stmt.dispatch(this);
|
|
|
|
backend.emitADDI(iter, iter, 1, "Increment counter");
|
|
|
|
|
|
|
|
backend.emitJ(startLoop, "Jump to beginning of loop");
|
|
|
|
backend.emitJ(startLoop, "Jump to beginning of loop");
|
|
|
|
backend.emitLocalLabel(endLoop, "End of for loop");
|
|
|
|
backend.emitLocalLabel(endLoop, "End of for loop");
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1196,6 +1212,8 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
emitStdFunc("strneql");
|
|
|
|
emitStdFunc("strneql");
|
|
|
|
emitStdFunc("makeint");
|
|
|
|
emitStdFunc("makeint");
|
|
|
|
emitStdFunc("makebool");
|
|
|
|
emitStdFunc("makebool");
|
|
|
|
|
|
|
|
emitStdFunc("initchars");
|
|
|
|
|
|
|
|
emitStdFunc("allChars");
|
|
|
|
|
|
|
|
|
|
|
|
emitErrorFunc(errorNone, "Operation on None");
|
|
|
|
emitErrorFunc(errorNone, "Operation on None");
|
|
|
|
emitErrorFunc(errorDiv, "Division by zero");
|
|
|
|
emitErrorFunc(errorDiv, "Division by zero");
|
|
|
|