merged in bill/merge-cond-cls
This commit is contained in:
@@ -147,3 +147,9 @@ tramp
|
|||||||
Session.vim
|
Session.vim
|
||||||
.netrwhist
|
.netrwhist
|
||||||
*~
|
*~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Exclude ###
|
||||||
|
!src/main/asm/chocopy/common
|
||||||
|
|||||||
Vendored
+2
-1
@@ -12,7 +12,8 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"classPaths": ["chocopy-ref.jar:target/assignment.jar"],
|
"classPaths": ["chocopy-ref.jar:target/assignment.jar"],
|
||||||
"mainClass": "chocopy.ChocoPy",
|
"mainClass": "chocopy.ChocoPy",
|
||||||
"args": [ "--pass=rrs", "--test","--dir", "src/test/data/pa3/sample/list_set_element_oob_1.py"],
|
//"args": [ "--pass=rrs", "--test","--dir", "src/test/data/pa3/sample/list_set_element_oob_1.py"],
|
||||||
|
"args": [ "--pass=rrs", "--test","--dir", "test.py"],
|
||||||
"sourcePaths": []
|
"sourcePaths": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
addi sp, sp, -8
|
||||||
|
sw ra, 4(sp)
|
||||||
|
sw fp, 0(sp)
|
||||||
|
addi fp, sp, 8
|
||||||
|
lw a1, 0(fp)
|
||||||
|
la a0, $.list$prototype
|
||||||
|
beqz a1, conslist_done
|
||||||
|
addi a1, a1, @listHeaderWords
|
||||||
|
jal alloc2
|
||||||
|
lw t0, 0(fp)
|
||||||
|
sw t0, @.__len__(a0)
|
||||||
|
slli t1, t0, 2
|
||||||
|
add t1, t1, fp
|
||||||
|
addi t2, a0, @.__elts__
|
||||||
|
conslist_1:
|
||||||
|
lw t3, 0(t1)
|
||||||
|
sw t3, 0(t2)
|
||||||
|
addi t1, t1, -4
|
||||||
|
addi t2, t2, 4
|
||||||
|
addi t0, t0, -1
|
||||||
|
bnez t0, conslist_1
|
||||||
|
conslist_done:
|
||||||
|
lw ra, -4(fp)
|
||||||
|
lw fp, -8(fp)
|
||||||
|
addi sp, sp, 8
|
||||||
|
jr ra
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
addi sp, sp, -32
|
||||||
|
sw ra, 28(sp)
|
||||||
|
sw fp, 24(sp)
|
||||||
|
addi fp, sp, 32
|
||||||
|
sw s1, -12(fp)
|
||||||
|
sw s2, -16(fp)
|
||||||
|
sw s3, -20(fp)
|
||||||
|
sw s4, -24(fp)
|
||||||
|
sw s5, -28(fp)
|
||||||
|
lw t0, 4(fp)
|
||||||
|
lw t1, 0(fp)
|
||||||
|
beqz t0, concat_none
|
||||||
|
beqz t1, concat_none
|
||||||
|
lw t0, @.__len__(t0)
|
||||||
|
lw t1, @.__len__(t1)
|
||||||
|
add s5, t0, t1
|
||||||
|
addi a1, s5, @listHeaderWords
|
||||||
|
la a0, $.list$prototype
|
||||||
|
jal alloc2
|
||||||
|
sw s5, @.__len__(a0)
|
||||||
|
mv s5, a0
|
||||||
|
addi s3, s5, @.__elts__
|
||||||
|
lw s1, 4(fp)
|
||||||
|
lw s2, @.__len__(s1)
|
||||||
|
addi s1, s1, @.__elts__
|
||||||
|
lw s4, 12(fp)
|
||||||
|
concat_1:
|
||||||
|
beqz s2, concat_2
|
||||||
|
lw a0, 0(s1)
|
||||||
|
jalr ra, s4, 0
|
||||||
|
sw a0, 0(s3)
|
||||||
|
addi s2, s2, -1
|
||||||
|
addi s1, s1, 4
|
||||||
|
addi s3, s3, 4
|
||||||
|
j concat_1
|
||||||
|
concat_2:
|
||||||
|
lw s1, 0(fp)
|
||||||
|
lw s2, @.__len__(s1)
|
||||||
|
addi s1, s1, @.__elts__
|
||||||
|
lw s4, 8(fp)
|
||||||
|
concat_3:
|
||||||
|
beqz s2, concat_4
|
||||||
|
lw a0, 0(s1)
|
||||||
|
jalr ra, s4, 0
|
||||||
|
sw a0, 0(s3)
|
||||||
|
addi s2, s2, -1
|
||||||
|
addi s1, s1, 4
|
||||||
|
addi s3, s3, 4
|
||||||
|
j concat_3
|
||||||
|
concat_4:
|
||||||
|
mv a0, s5
|
||||||
|
lw s1, -12(fp)
|
||||||
|
lw s2, -16(fp)
|
||||||
|
lw s3, -20(fp)
|
||||||
|
lw s4, -24(fp)
|
||||||
|
lw s5, -28(fp)
|
||||||
|
lw ra, -4(fp)
|
||||||
|
lw fp, -8(fp)
|
||||||
|
addi sp, sp, 32
|
||||||
|
jr ra
|
||||||
|
concat_none:
|
||||||
|
j error.None
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
addi sp, sp, -8
|
||||||
|
sw ra, 4(sp)
|
||||||
|
sw fp, 0(sp)
|
||||||
|
addi fp, sp, 8
|
||||||
|
lw a1, 0(fp)
|
||||||
|
la a0, $.list$prototype
|
||||||
|
beqz a1, conslist_done
|
||||||
|
addi a1, a1, @listHeaderWords
|
||||||
|
jal alloc2
|
||||||
|
lw t0, 0(fp)
|
||||||
|
sw t0, @.__len__(a0)
|
||||||
|
slli t1, t0, 2
|
||||||
|
add t1, t1, fp
|
||||||
|
addi t2, a0, @.__elts__
|
||||||
|
conslist_1:
|
||||||
|
lw t3, 0(t1)
|
||||||
|
sw t3, 0(t2)
|
||||||
|
addi t1, t1, -4
|
||||||
|
addi t2, t2, 4
|
||||||
|
addi t0, t0, -1
|
||||||
|
bnez t0, conslist_1
|
||||||
|
conslist_done:
|
||||||
|
lw ra, -4(fp)
|
||||||
|
lw fp, -8(fp)
|
||||||
|
addi sp, sp, 8
|
||||||
|
jr ra
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
slli a0, a0, 4
|
||||||
|
la t0, @bool.False
|
||||||
|
add a0, a0, t0
|
||||||
|
jr ra
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
# Box integer
|
# Box integer
|
||||||
addi sp, sp, -8
|
addi sp, sp, -8
|
||||||
sw ra, 4(sp)
|
sw ra, 4(sp)
|
||||||
@@ -9,3 +10,16 @@
|
|||||||
lw ra, 4(sp)
|
lw ra, 4(sp)
|
||||||
addi sp, sp, 8
|
addi sp, sp, 8
|
||||||
jr ra
|
jr ra
|
||||||
|
=======
|
||||||
|
|
||||||
|
addi sp, sp, -8
|
||||||
|
sw ra, 4(sp)
|
||||||
|
sw a0, 0(sp)
|
||||||
|
la a0, $int$prototype
|
||||||
|
jal ra, alloc
|
||||||
|
lw t0, 0(sp)
|
||||||
|
sw t0, @.__int__(a0)
|
||||||
|
lw ra, 4(sp)
|
||||||
|
addi sp, sp, 8
|
||||||
|
jr ra
|
||||||
|
>>>>>>> origin/bill/merge-cond-cls
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
addi sp, sp, -12
|
||||||
|
sw ra, 8(sp)
|
||||||
|
sw fp, 4(sp)
|
||||||
|
addi fp, sp, 12
|
||||||
|
lw t0, 4(fp)
|
||||||
|
lw t1, 0(fp)
|
||||||
|
lw t0, @.__len__(t0)
|
||||||
|
beqz t0, strcat_4
|
||||||
|
lw t1, @.__len__(t1)
|
||||||
|
beqz t1, strcat_5
|
||||||
|
add t1, t0, t1
|
||||||
|
sw t1, -12(fp)
|
||||||
|
addi t1, t1, 4
|
||||||
|
srli t1, t1, 2
|
||||||
|
addi a1, t1, @listHeaderWords
|
||||||
|
la a0, $str$prototype
|
||||||
|
jal alloc2
|
||||||
|
lw t0, -12(fp)
|
||||||
|
sw t0, @.__len__(a0)
|
||||||
|
addi t2, a0, 16
|
||||||
|
lw t0, 4(fp)
|
||||||
|
lw t1, @.__len__(t0)
|
||||||
|
addi t0, t0, @.__str__
|
||||||
|
strcat_1:
|
||||||
|
beqz t1, strcat_2
|
||||||
|
lbu t3, 0(t0)
|
||||||
|
sb t3, 0(t2)
|
||||||
|
addi t1, t1, -1
|
||||||
|
addi t0, t0, 1
|
||||||
|
addi t2, t2, 1
|
||||||
|
j strcat_1
|
||||||
|
strcat_2:
|
||||||
|
lw t0, 0(fp)
|
||||||
|
lw t1, 12(t0)
|
||||||
|
addi t0, t0, 16
|
||||||
|
strcat_3:
|
||||||
|
beqz t1, strcat_6
|
||||||
|
lbu t3, 0(t0)
|
||||||
|
sb t3, 0(t2)
|
||||||
|
addi t1, t1, -1
|
||||||
|
addi t0, t0, 1
|
||||||
|
addi t2, t2, 1
|
||||||
|
j strcat_3
|
||||||
|
strcat_4:
|
||||||
|
lw a0, 0(fp)
|
||||||
|
j strcat_7
|
||||||
|
strcat_5:
|
||||||
|
lw a0, 4(fp)
|
||||||
|
j strcat_7
|
||||||
|
strcat_6:
|
||||||
|
sb zero, 0(t2)
|
||||||
|
strcat_7:
|
||||||
|
lw ra, -4(fp)
|
||||||
|
lw fp, -8(fp)
|
||||||
|
addi sp, sp, 12
|
||||||
|
jr ra
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
addi sp, sp, -8
|
||||||
|
sw ra, 4(sp)
|
||||||
|
sw fp, 0(sp)
|
||||||
|
addi fp, sp, 8
|
||||||
|
lw a1, 4(fp)
|
||||||
|
lw a2, 0(fp)
|
||||||
|
lw t0, @.__len__(a1)
|
||||||
|
lw t1, @.__len__(a2)
|
||||||
|
bne t0, t1, streql_no
|
||||||
|
streql_1:
|
||||||
|
lbu t2, @.__str__(a1)
|
||||||
|
lbu t3, @.__str__(a2)
|
||||||
|
bne t2, t3, streql_no
|
||||||
|
addi a1, a1, 1
|
||||||
|
addi a2, a2, 1
|
||||||
|
addi t0, t0, -1
|
||||||
|
bgtz t0, streql_1
|
||||||
|
li a0, 1
|
||||||
|
j streql_end
|
||||||
|
streql_no:
|
||||||
|
xor a0, a0, a0
|
||||||
|
streql_end:
|
||||||
|
lw ra, -4(fp)
|
||||||
|
lw fp, -8(fp)
|
||||||
|
addi sp, sp, 8
|
||||||
|
jr ra
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
addi sp, sp, -8
|
||||||
|
sw ra, 4(sp)
|
||||||
|
sw fp, 0(sp)
|
||||||
|
addi fp, sp, 8
|
||||||
|
lw a1, 4(fp)
|
||||||
|
lw a2, 0(fp)
|
||||||
|
lw t0, @.__len__(a1)
|
||||||
|
lw t1, @.__len__(a2)
|
||||||
|
bne t0, t1, strneql_yes
|
||||||
|
strneql_1:
|
||||||
|
lbu t2, @.__str__(a1)
|
||||||
|
lbu t3, @.__str__(a2)
|
||||||
|
bne t2, t3, strneql_yes
|
||||||
|
addi a1, a1, 1
|
||||||
|
addi a2, a2, 1
|
||||||
|
addi t0, t0, -1
|
||||||
|
bgtz t0, strneql_1
|
||||||
|
xor a0, a0, a0
|
||||||
|
j strneql_end
|
||||||
|
strneql_yes:
|
||||||
|
li a0, 1
|
||||||
|
strneql_end:
|
||||||
|
lw ra, -4(fp)
|
||||||
|
lw fp, -8(fp)
|
||||||
|
addi sp, sp, 8
|
||||||
|
jr ra
|
||||||
@@ -1,53 +1,16 @@
|
|||||||
package chocopy.pa3;
|
package chocopy.pa3;
|
||||||
|
|
||||||
|
import java.net.Socket;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import chocopy.common.analysis.AbstractNodeAnalyzer;
|
import chocopy.common.analysis.AbstractNodeAnalyzer;
|
||||||
import chocopy.common.analysis.SymbolTable;
|
import chocopy.common.analysis.SymbolTable;
|
||||||
import chocopy.common.astnodes.AssignStmt;
|
|
||||||
import chocopy.common.astnodes.BinaryExpr;
|
|
||||||
import chocopy.common.astnodes.BooleanLiteral;
|
|
||||||
import chocopy.common.astnodes.CallExpr;
|
|
||||||
import chocopy.common.astnodes.ClassDef;
|
|
||||||
import chocopy.common.astnodes.ClassType;
|
|
||||||
import chocopy.common.astnodes.CompilerError;
|
|
||||||
import chocopy.common.astnodes.Errors;
|
|
||||||
import chocopy.common.astnodes.Expr;
|
|
||||||
import chocopy.common.astnodes.ExprStmt;
|
|
||||||
import chocopy.common.astnodes.ForStmt;
|
|
||||||
import chocopy.common.astnodes.FuncDef;
|
|
||||||
import chocopy.common.astnodes.GlobalDecl;
|
|
||||||
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.MemberExpr;
|
|
||||||
import chocopy.common.astnodes.MethodCallExpr;
|
|
||||||
import chocopy.common.astnodes.NonLocalDecl;
|
|
||||||
import chocopy.common.astnodes.NoneLiteral;
|
|
||||||
import chocopy.common.astnodes.Program;
|
|
||||||
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.astnodes.*;
|
import chocopy.common.astnodes.*;
|
||||||
import chocopy.common.analysis.types.*;
|
import chocopy.common.analysis.types.*;
|
||||||
import chocopy.common.codegen.*;
|
import chocopy.common.codegen.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import static chocopy.common.codegen.RiscVBackend.Register.*;
|
import static chocopy.common.codegen.RiscVBackend.Register.*;
|
||||||
import chocopy.common.codegen.RiscVBackend.Register;
|
import chocopy.common.codegen.RiscVBackend.Register;
|
||||||
|
|
||||||
@@ -68,74 +31,17 @@ import chocopy.common.codegen.RiscVBackend.Register;
|
|||||||
*/
|
*/
|
||||||
public class CodeGenImpl extends CodeGenBase
|
public class CodeGenImpl extends CodeGenBase
|
||||||
{
|
{
|
||||||
|
/** Label for built-in routines. */
|
||||||
|
protected final Label makeintLabel = new Label("makeint");
|
||||||
|
protected final Label strneqlLablel = new Label("strneql");
|
||||||
|
protected final Label streqlLablel = new Label("streql");
|
||||||
|
protected final Label makeboolLablel = new Label("makebool");
|
||||||
|
protected final Label strcatLablel = new Label("strcat");
|
||||||
|
protected final Label concatLablel = new Label("concat");
|
||||||
|
protected final Label conslistLablel = new Label("conslist");
|
||||||
|
|
||||||
/** A code generator emitting instructions to BACKEND. */
|
|
||||||
public CodeGenImpl(RiscVBackend backend)
|
|
||||||
{
|
|
||||||
super(backend);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates assembly code for PROGRAM.
|
|
||||||
*
|
|
||||||
* <p>This is the main driver that calls internal methods for emitting DATA section (globals,
|
|
||||||
* constants, prototypes, etc) as well as the the CODE section (predefined functions, built-in
|
|
||||||
* routines, and user-defined functions).
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void generate(Program program) {
|
|
||||||
System.out.println("Inside generate");
|
|
||||||
analyzeProgram(program);
|
|
||||||
|
|
||||||
backend.startData();
|
|
||||||
|
|
||||||
for (ClassInfo classInfo : this.classes) {
|
|
||||||
emitPrototype(classInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ClassInfo classInfo : this.classes) {
|
|
||||||
emitDispatchTable(classInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (GlobalVarInfo global : this.globalVars) {
|
|
||||||
backend.emitGlobalLabel(global.getLabel());
|
|
||||||
emitConstant(
|
|
||||||
global.getInitialValue(),
|
|
||||||
global.getVarType(),
|
|
||||||
String.format("Initial value of global var: %s", global.getVarName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
backend.startCode();
|
|
||||||
|
|
||||||
Label mainLabel = new Label("main");
|
|
||||||
backend.emitGlobalLabel(mainLabel);
|
|
||||||
backend.emitLUI(A0, HEAP_SIZE_BYTES >> 12, "Initialize heap size (in multiples of 4KB)");
|
|
||||||
backend.emitADD(S11, S11, A0, "Save heap size");
|
|
||||||
backend.emitJAL(heapInitLabel, "Call heap.init routine");
|
|
||||||
backend.emitMV(GP, A0, "Initialize heap pointer");
|
|
||||||
backend.emitMV(S10, GP, "Set beginning of heap");
|
|
||||||
backend.emitADD(S11, S10, S11, "Set end of heap (= start of heap + heap size)");
|
|
||||||
backend.emitMV(RA, ZERO, "No normal return from main program.");
|
|
||||||
backend.emitMV(FP, ZERO, "No preceding frame.");
|
|
||||||
|
|
||||||
emitTopLevel(program.statements);
|
|
||||||
|
|
||||||
for (FuncInfo funcInfo : this.functions) {
|
|
||||||
funcInfo.emitBody();
|
|
||||||
}
|
|
||||||
|
|
||||||
emitStdFunc("alloc");
|
|
||||||
emitStdFunc("alloc2");
|
|
||||||
emitStdFunc("abort");
|
|
||||||
emitStdFunc("heap.init");
|
|
||||||
emitStdFunc("makeint");
|
|
||||||
|
|
||||||
emitCustomCode();
|
|
||||||
|
|
||||||
backend.startData();
|
|
||||||
emitConstants();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Operation on None. */
|
/** Operation on None. */
|
||||||
private final Label errorNone = new Label("error.None");
|
private final Label errorNone = new Label("error.None");
|
||||||
@@ -144,10 +50,15 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
/** Index out of bounds. */
|
/** Index out of bounds. */
|
||||||
private final Label errorOob = new Label("error.OOB");
|
private final Label errorOob = new Label("error.OOB");
|
||||||
|
|
||||||
|
/** Let's try to implement everything first.*/
|
||||||
|
private final Label errorNI = new Label("error.NI");
|
||||||
|
|
||||||
|
/** A code generator emitting instructions to BACKEND. */
|
||||||
|
public CodeGenImpl(RiscVBackend backend)
|
||||||
|
{
|
||||||
|
super(backend);
|
||||||
|
|
||||||
/** Label for built-in routine: makeint. */
|
}
|
||||||
protected final Label makeIntLabel = new Label("makeint");
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -378,36 +289,6 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
return A0;
|
return A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Register analyze(FuncDef node) {
|
|
||||||
backend.emitLW(T6, FP, 0, "Inside FuncDef: " + node.name);
|
|
||||||
// function
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Register analyze(GlobalDecl node) {
|
|
||||||
backend.emitLW(T6, FP, 0, "Inside GlobalDecl: ");
|
|
||||||
// function
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Register analyze(NonLocalDecl node) {
|
|
||||||
backend.emitLW(T6, FP, 0, "Inside NonLocalDecl: ");
|
|
||||||
// function
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Register analyze(MethodCallExpr node) {
|
public Register analyze(MethodCallExpr node) {
|
||||||
backend.emitLW(T6, FP, 0, "Inside MethodCallExpr: " + node.method.member.name);
|
backend.emitLW(T6, FP, 0, "Inside MethodCallExpr: " + node.method.member.name);
|
||||||
Register obj = node.method.object.dispatch(this);
|
Register obj = node.method.object.dispatch(this);
|
||||||
@@ -450,6 +331,7 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
|
|
||||||
// All expressions should save their end result in A0
|
// All expressions should save their end result in A0
|
||||||
expr.dispatch(this);
|
expr.dispatch(this);
|
||||||
|
|
||||||
return A0;
|
return A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,15 +356,6 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
return Register.A0;
|
return Register.A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME: This is not correct. We need to use $int$prototype to create an integer literal, so commenting it
|
|
||||||
// @Override
|
|
||||||
// public Register analyze(IntegerLiteral node)
|
|
||||||
// {
|
|
||||||
// backend.emitLI(Register.A0, node.value, "Load integer literal "+node.value);
|
|
||||||
// return Register.A0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Register analyze(BooleanLiteral node)
|
public Register analyze(BooleanLiteral node)
|
||||||
{
|
{
|
||||||
@@ -494,20 +367,31 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
return Register.A0;
|
return Register.A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Register analyze(AssignStmt node)
|
public Register analyze(AssignStmt node)
|
||||||
{
|
{
|
||||||
backend.emitLW(T6, FP, 0, "Inside AssignStmt: ");
|
backend.emitLW(T6, FP, 0, "Inside AssignStmt: ");
|
||||||
Type t = node.value.getInferredType();
|
Type t = node.value.getInferredType();
|
||||||
if(t.isSpecialType() || t.isListType())
|
// if(t.isSpecialType() || t.isListType())
|
||||||
{
|
{
|
||||||
node.value.dispatch(this);
|
Register reg = node.value.dispatch(this);
|
||||||
|
if (reg == null)
|
||||||
|
reg = A0;
|
||||||
if (sym.getParent() == null)
|
if (sym.getParent() == null)
|
||||||
{
|
{
|
||||||
for(Expr target: node.targets)
|
for(Expr target: node.targets)
|
||||||
{
|
{
|
||||||
GlobalVarInfo gvi=(GlobalVarInfo)sym.get(((Identifier)target).name);
|
if(target instanceof Identifier)
|
||||||
backend.emitSW(Register.A0, gvi.getLabel(), Register.T0, "Assign global: "+gvi.getVarName()+"(using tmp register)");
|
{
|
||||||
|
GlobalVarInfo gvi=(GlobalVarInfo)sym.get(((Identifier)target).name);
|
||||||
|
backend.emitSW(reg, gvi.getLabel(), Register.T0, "Assign global: "+gvi.getVarName()+"(using tmp register)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Register ret = target.dispatch(this);
|
||||||
|
backend.emitSW(T1, ret, 0, "Set list element");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -516,13 +400,9 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
{
|
{
|
||||||
StackVarInfo svi = (StackVarInfo) sym.get(((Identifier)target).name);
|
StackVarInfo svi = (StackVarInfo) sym.get(((Identifier)target).name);
|
||||||
int loc = offsetMap.get(svi);
|
int loc = offsetMap.get(svi);
|
||||||
backend.emitSW(Register.A0, Register.FP, -loc*4, "Load local variable: "+svi.getVarName());
|
backend.emitSW(reg, Register.FP, -loc*4, "Load local variable: "+svi.getVarName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{//TODO: Object Assignment
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return Register.A0;
|
return Register.A0;
|
||||||
}
|
}
|
||||||
@@ -545,7 +425,7 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
backend.emitLocalLabel(elseBlock, "Else part of if expression");
|
backend.emitLocalLabel(elseBlock, "Else part of if expression");
|
||||||
node.elseExpr.dispatch(this);
|
node.elseExpr.dispatch(this);
|
||||||
backend.emitLocalLabel(ln, "End of if expression");
|
backend.emitLocalLabel(ln, "End of if expression");
|
||||||
return null;
|
return A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -562,63 +442,247 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
backend.emitLocalLabel(ln, "End of if statement");
|
backend.emitLocalLabel(ln, "End of if statement");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
public void copyList(Register dest, Register src, Register size) {
|
||||||
|
Label begin = generateLocalLabel();
|
||||||
|
Label exit = generateLocalLabel();
|
||||||
|
backend.emitLocalLabel(begin, "Start loop for copying");
|
||||||
|
backend.emitBEQ(size, Register.ZERO, exit, "Exit when copy completes");
|
||||||
|
backend.emitLW(Register.A2, src, 0, "Load Word from Source");
|
||||||
|
backend.emitSW(Register.A2, dest, 0, "Store Word in Destination");
|
||||||
|
backend.emitADDI(src, src, wordSize, "Increment Source Address");
|
||||||
|
backend.emitADDI(dest, dest, wordSize, "Increment Destination Address");
|
||||||
|
backend.emitADDI(size, size, -1, "Decrement size left to copy");
|
||||||
|
backend.emitJ(begin, "Jump to beginning of loop");
|
||||||
|
backend.emitLocalLabel(exit,"Exit loop for copying");
|
||||||
|
}
|
||||||
|
private Register addLists() {
|
||||||
|
// Check for Null operands
|
||||||
|
Label label = generateLocalLabel();
|
||||||
|
backend.emitBNEZ(Register.A0, label, "Left operand is NULL");
|
||||||
|
backend.emitBNEZ(Register.T0, label, "Right operand is NULL");
|
||||||
|
backend.emitJAL(errorNone, "Operand is Null");
|
||||||
|
backend.emitLocalLabel(label, "List Addition");
|
||||||
|
|
||||||
|
//Get lengths of the two lists
|
||||||
|
backend.emitLW(Register.T1, Register.A0,0,"Load length of first list");
|
||||||
|
backend.emitLW(Register.T2, Register.T0,0,"Load length of second list");
|
||||||
|
backend.emitADD(Register.A1, Register.T2,Register.T1,"Add lengths of lists");
|
||||||
|
backend.emitMV(Register.T3,Register.A1,"Store total length combined list");
|
||||||
|
backend.emitADDI(Register.A1, Register.A1,1,"Add 1 to store length of new list");
|
||||||
|
|
||||||
|
//Store address and length of lists on stack
|
||||||
|
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Store address of first list");
|
||||||
|
sp_off++;
|
||||||
|
backend.emitSW(Register.T0, Register.FP, -sp_off*wordSize, "Store address of second list");
|
||||||
|
sp_off++;
|
||||||
|
backend.emitSW(Register.T3, Register.FP, -sp_off*wordSize, "Store length of combined list");
|
||||||
|
sp_off++;
|
||||||
|
|
||||||
|
//Allocate space on heap
|
||||||
|
backend.emitLA(Register.A0, listClass.getPrototypeLabel(), "Load empty list");
|
||||||
|
backend.emitJAL(objectAllocResizeLabel, "Allocate list");
|
||||||
|
backend.emitMV(Register.A1, Register.A0, "Store address of allocated space");
|
||||||
|
backend.emitMV(Register.T5, Register.A1, "Make a copy of address of allocated space");
|
||||||
|
|
||||||
|
//Pop length and address from stack
|
||||||
|
sp_off--;
|
||||||
|
backend.emitLW(Register.T3, Register.FP, -sp_off*wordSize, "Load length of combined list");
|
||||||
|
sp_off--;
|
||||||
|
backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Load address of second list");
|
||||||
|
sp_off--;
|
||||||
|
backend.emitLW(Register.A0, Register.FP, -sp_off*wordSize, "Load address of first list");
|
||||||
|
|
||||||
|
backend.emitLW(Register.T1, Register.A0,0,"Load length of first list");
|
||||||
|
backend.emitLW(Register.T2, Register.T0,0,"Load length of second list");
|
||||||
|
|
||||||
|
//Copy each list in newly allocated space
|
||||||
|
backend.emitSW(Register.T3,Register.T5,0,"Store length of combined list ");
|
||||||
|
backend.emitADDI(Register.T5,Register.T5,wordSize,"Increment address");
|
||||||
|
backend.emitADDI(Register.A0,Register.A0,wordSize,"Increment address");
|
||||||
|
copyList(Register.T5, Register.A0, Register.T1);
|
||||||
|
backend.emitADDI(Register.T0,Register.T0,wordSize,"Increment address");
|
||||||
|
copyList(Register.T5, Register.T0, Register.T2);
|
||||||
|
|
||||||
|
backend.emitMV(Register.A0,Register.A1,"Load address of combined list");
|
||||||
|
return Register.A0;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public Register analyze(BinaryExpr node)
|
public Register analyze(BinaryExpr node)
|
||||||
{
|
{
|
||||||
backend.emitLW(T6, FP, 0, "Inside BinaryExpr: ");
|
String operator = node.operator;
|
||||||
node.left.dispatch(this);
|
backend.emitLW(T6, FP, 0, "Inside BinaryExpr: ");
|
||||||
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
|
|
||||||
sp_off++;
|
if(node.left.getInferredType().equals(Type.INT_TYPE) && node.right.getInferredType().equals(Type.INT_TYPE))
|
||||||
node.right.dispatch(this);
|
{
|
||||||
sp_off--;
|
node.right.dispatch(this);
|
||||||
backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
|
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
|
||||||
// Arithmetic Operators
|
sp_off++;
|
||||||
if(node.operator.equals("+"))
|
node.left.dispatch(this);
|
||||||
backend.emitADD(Register.A0, Register.A0, Register.T0, "Add operation");
|
sp_off--;
|
||||||
else if(node.operator.equals("-"))
|
backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
|
||||||
backend.emitSUB(Register.A0, Register.A0, Register.T0, "Sub operation");
|
|
||||||
else if(node.operator.equals("*"))
|
// Arithmetic Operators
|
||||||
backend.emitMUL(Register.A0, Register.A0, Register.T0, "Mul operation");
|
if(operator.equals("+"))
|
||||||
else if(node.operator.equals("/"))
|
backend.emitADD(Register.A0, Register.A0, Register.T0, "Add operation");
|
||||||
backend.emitDIV(Register.A0, Register.A0, Register.T0, "Div operation");
|
else if(operator.equals("-"))
|
||||||
else
|
backend.emitSUB(Register.A0, Register.A0, Register.T0, "Sub operation");
|
||||||
{ // Comparison operators
|
else if(operator.equals("*"))
|
||||||
elseBlock = generateLocalLabel();
|
backend.emitMUL(Register.A0, Register.A0, Register.T0, "Mul operation");
|
||||||
String comment="Branch on not "+node.operator;
|
else if(operator.equals("//"))
|
||||||
if(node.operator.equals("=="))
|
|
||||||
backend.emitBNE(Register.A0, Register.T0,elseBlock, comment);
|
|
||||||
else if(node.operator.equals("!="))
|
|
||||||
backend.emitBEQ(Register.A0, Register.T0,elseBlock, comment);
|
|
||||||
else if(node.operator.equals("<"))
|
|
||||||
backend.emitBGE(Register.A0, Register.T0,elseBlock, comment);
|
|
||||||
else if(node.operator.equals(">"))
|
|
||||||
{
|
{
|
||||||
backend.emitBLT(Register.A0, Register.T0,elseBlock, comment);
|
Label label = generateLocalLabel();
|
||||||
backend.emitBEQ(Register.A0, Register.T0,elseBlock, comment);
|
backend.emitBNEZ(Register.T0, label, "Check for Divide-by-zero");
|
||||||
|
backend.emitJAL(errorDiv, "Divide-by-zero error");
|
||||||
|
backend.emitLocalLabel(label, "Divide since divisor not zero");
|
||||||
|
backend.emitDIV(Register.A0, Register.A0, Register.T0, "Divide operation");
|
||||||
}
|
}
|
||||||
else if(node.operator.equals(">="))
|
else if(operator.equals("%"))
|
||||||
backend.emitBLT(Register.A0, Register.T0,elseBlock, comment);
|
|
||||||
else if(node.operator.equals("<="))
|
|
||||||
{
|
{
|
||||||
Label temp = generateLocalLabel();
|
Label label = generateLocalLabel();
|
||||||
backend.emitBEQ(Register.A0, Register.T0,temp, "Branch on "+node.operator);
|
backend.emitBNEZ(Register.T0, label, "Check for Divide-by-zero");
|
||||||
backend.emitBGE(Register.A0, Register.T0,elseBlock, comment);
|
backend.emitJAL(errorDiv, "Divide-by-zero error");
|
||||||
backend.emitLocalLabel(temp, "True part of if check");
|
backend.emitLocalLabel(label, "Divide since divisor not zero");
|
||||||
|
backend.emitREM(Register.A0, Register.A0, Register.T0, "Modulus operation");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Comparison operators
|
||||||
|
String comment="Operator: "+operator;
|
||||||
|
if(operator.equals("=="))
|
||||||
|
{
|
||||||
|
backend.emitXOR(Register.A0, Register.A0, Register.T0, "Check for equality");
|
||||||
|
backend.emitSEQZ(Register.A0, Register.A0, "Result is True if XOR equals 0");
|
||||||
|
}
|
||||||
|
else if(operator.equals("!="))
|
||||||
|
{
|
||||||
|
backend.emitXOR(Register.A0, Register.A0, Register.T0, "Check for inequality");
|
||||||
|
backend.emitSNEZ(Register.A0, Register.A0, "Result is True if XOR does not equal 0");
|
||||||
|
}
|
||||||
|
else if(operator.equals("<"))
|
||||||
|
backend.emitSLT(Register.A0,Register.A0, Register.T0, comment);
|
||||||
|
else if(operator.equals(">"))
|
||||||
|
backend.emitSLT(Register.A0, Register.T0, Register.A0, comment);
|
||||||
|
else if(operator.equals("<="))
|
||||||
|
{
|
||||||
|
backend.emitADDI(Register.T0,Register.T0, 1, "Increment by 1");
|
||||||
|
backend.emitSLT(Register.A0, Register.A0, Register.T0, comment);
|
||||||
|
}
|
||||||
|
else if(operator.equals(">="))
|
||||||
|
{
|
||||||
|
backend.emitADDI(Register.A0,Register.A0, 1, "Increment by 1");
|
||||||
|
backend.emitSLT(Register.A0, Register.A0, Register.T0, comment);
|
||||||
|
}
|
||||||
|
else if(operator.equals("is"))
|
||||||
|
{
|
||||||
|
backend.emitXOR(Register.A0, Register.A0, Register.T0, comment);
|
||||||
|
backend.emitSEQZ(Register.A0, Register.A0, "Result is True if XOR equals 0");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
backend.emitJAL(errorNI, "Operator not implemented for integer operands");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
else if(node.left.getInferredType().equals(Type.BOOL_TYPE) && node.right.getInferredType().equals(Type.BOOL_TYPE))
|
||||||
|
{
|
||||||
|
|
||||||
|
// Comparison operators
|
||||||
|
String comment="Operator: "+operator;
|
||||||
|
if(operator.equals("=="))
|
||||||
|
{
|
||||||
|
node.right.dispatch(this);
|
||||||
|
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
|
||||||
|
sp_off++;
|
||||||
|
node.left.dispatch(this);
|
||||||
|
sp_off--;
|
||||||
|
backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
|
||||||
|
backend.emitXOR(Register.A0, Register.A0, Register.T0, "Check for equality");
|
||||||
|
backend.emitSEQZ(Register.A0, Register.A0, "Result is True if XOR equals 0");
|
||||||
|
}
|
||||||
|
else if(operator.equals("!="))
|
||||||
|
{
|
||||||
|
node.right.dispatch(this);
|
||||||
|
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
|
||||||
|
sp_off++;
|
||||||
|
node.left.dispatch(this);
|
||||||
|
sp_off--;
|
||||||
|
backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
|
||||||
|
backend.emitXOR(Register.A0, Register.A0, Register.T0, "Check for inequality");
|
||||||
|
backend.emitSNEZ(Register.A0, Register.A0, "Result is True if XOR does not equal 0");
|
||||||
|
}
|
||||||
|
else if(operator.equals("and"))
|
||||||
|
{
|
||||||
|
Label label = generateLocalLabel();
|
||||||
|
node.left.dispatch(this);
|
||||||
|
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
|
||||||
|
sp_off++;
|
||||||
|
backend.emitBEQZ(Register.A0, label, "If first operand is false, don't check second");
|
||||||
|
node.right.dispatch(this);
|
||||||
|
sp_off--;
|
||||||
|
backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
|
||||||
|
backend.emitAND(Register.A0, Register.A0, Register.T0, "AND operation");
|
||||||
|
backend.emitLocalLabel(label, "Next step after AND");
|
||||||
|
}
|
||||||
|
else if(operator.equals("or"))
|
||||||
|
{
|
||||||
|
Label label = generateLocalLabel();
|
||||||
|
node.left.dispatch(this);
|
||||||
|
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
|
||||||
|
sp_off++;
|
||||||
|
backend.emitBNEZ(Register.A0, label, "If first operand is true, don't check second");
|
||||||
|
node.right.dispatch(this);
|
||||||
|
sp_off--;
|
||||||
|
backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
|
||||||
|
backend.emitOR(Register.A0, Register.A0, Register.T0, "OR operation");
|
||||||
|
backend.emitLocalLabel(label, "Next step after OR");
|
||||||
|
}
|
||||||
|
else if(operator.equals("is"))
|
||||||
|
{
|
||||||
|
backend.emitXOR(Register.A0, Register.A0, Register.T0, comment);
|
||||||
|
backend.emitSEQZ(Register.A0, Register.A0, "Result is True if XOR equals 0");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
backend.emitJAL(errorNI, "Operator not implemented for boolean operands");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(node.left.getInferredType().isListType() && node.right.getInferredType().isListType())
|
||||||
|
{
|
||||||
|
node.right.dispatch(this);
|
||||||
|
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
|
||||||
|
sp_off++;
|
||||||
|
node.left.dispatch(this);
|
||||||
|
sp_off--;
|
||||||
|
backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
|
||||||
|
if(operator.equals("+"))
|
||||||
|
addLists();
|
||||||
|
}
|
||||||
|
else if(node.left.getInferredType().equals(Type.STR_TYPE) && node.right.getInferredType().equals(Type.STR_TYPE))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
backend.emitJAL(errorNI, "Operator not implemented");
|
||||||
|
}
|
||||||
|
return A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Register analyze(UnaryExpr node)
|
public Register analyze(UnaryExpr node)
|
||||||
{
|
{
|
||||||
node.operand.dispatch(this);
|
if(node.operator.equals("-") && node.getInferredType().equals(Type.INT_TYPE))
|
||||||
if(node.operator.equals("-"))
|
|
||||||
{
|
{
|
||||||
|
node.operand.dispatch(this);
|
||||||
backend.emitLI(Register.T0, -1, "Set value of Register T0 to -1");
|
backend.emitLI(Register.T0, -1, "Set value of Register T0 to -1");
|
||||||
backend.emitMUL(Register.A0, Register.A0, Register.T0, "Multiply by -1");
|
backend.emitMUL(Register.A0, Register.A0, Register.T0, "Multiply by -1");
|
||||||
}
|
}
|
||||||
|
else if(node.operator.equals("not") && node.getInferredType().equals(Type.BOOL_TYPE))
|
||||||
|
{
|
||||||
|
node.operand.dispatch(this);
|
||||||
|
backend.emitSEQZ(Register.T0, Register.A0, "Not operation on Register A0");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return null;
|
||||||
return Register.A0;
|
return Register.A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,19 +734,25 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
@Override
|
@Override
|
||||||
public Register analyze(ListExpr node) {
|
public Register analyze(ListExpr node) {
|
||||||
int l = node.elements.size();
|
int l = node.elements.size();
|
||||||
|
backend.emitLI(Register.A1, l+1, "Load length of list+1 in words");
|
||||||
|
backend.emitLA(Register.A0, listClass.getPrototypeLabel(), "Load empty list");
|
||||||
|
backend.emitJAL(objectAllocResizeLabel, "Allocate list");
|
||||||
|
backend.emitMV(Register.A1, Register.A0, "Store address of allocated space");
|
||||||
|
backend.emitMV(Register.T0, Register.A1, "Make a copy of address of allocated space");
|
||||||
|
|
||||||
int i = l;
|
int i = l;
|
||||||
|
backend.emitLI(Register.A0,l,"Load length of list in words");
|
||||||
|
backend.emitSW(Register.A0,Register.T0,0,"Store length of list: "+i);
|
||||||
|
backend.emitADDI(Register.T0,Register.T0,wordSize,"Increment address");
|
||||||
|
|
||||||
for(Expr exp:node.elements)
|
for(Expr exp:node.elements)
|
||||||
{
|
{
|
||||||
Register r = exp.dispatch(this);
|
Register r = exp.dispatch(this);
|
||||||
backend.emitSW(r,Register.FP,-sp_off*wordSize,"Push argument "+i+" from last.");
|
backend.emitSW(r,Register.T0,0,"Store element "+i+" from last.");
|
||||||
sp_off++;
|
backend.emitADDI(Register.T0,Register.T0,wordSize,"Increment address");
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
backend.emitLI(Register.A0, l, "Pass list length");
|
backend.emitMV(Register.A0,Register.A1,"Load address of list");
|
||||||
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push argument "+i+" from last.");
|
|
||||||
sp_off++;
|
|
||||||
backend.emitADDI(Register.SP, Register.SP, -sp_off*wordSize, "Set SP to last argument.");
|
|
||||||
//TODO: Store reference to variable
|
|
||||||
return Register.A0;
|
return Register.A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -692,7 +762,7 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
public Register analyze(IntegerLiteral node) {
|
public Register analyze(IntegerLiteral node) {
|
||||||
backend.emitLW(T6, FP, 0, "Inside IntegerLiteral: " + node.value);
|
backend.emitLW(T6, FP, 0, "Inside IntegerLiteral: " + node.value);
|
||||||
backend.emitLI(A0, node.value, "Load integer literal " + node.value);
|
backend.emitLI(A0, node.value, "Load integer literal " + node.value);
|
||||||
backend.emitJAL(makeIntLabel, "Box integer");
|
//backend.emitJAL(makeintLabel, "Box integer");
|
||||||
return A0;
|
return A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,12 +784,35 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Register analyze(IndexExpr node)
|
public Register analyze(IndexExpr node)
|
||||||
{
|
{
|
||||||
//System.out.println(node);
|
// incSp(1);
|
||||||
return defaultAction(node);
|
// Register listObj = node.list.dispatch(this);
|
||||||
}
|
// backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off));
|
||||||
|
// Register index = node.index.dispatch(this);
|
||||||
|
// Register vacantReg = (index != A0) ? A0 : A1;
|
||||||
|
//
|
||||||
|
// if (node.list.getInferredType().isListType()) {
|
||||||
|
// backend.emitLW(vacantReg, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
|
||||||
|
//
|
||||||
|
// this.d(vacantReg);
|
||||||
|
// return this.a(vacantReg, index, A0, false);
|
||||||
|
// }else{
|
||||||
|
// this.a(0, vacantReg);
|
||||||
|
// Register a = a(index);
|
||||||
|
// Label ch = generateLocalLabel();
|
||||||
|
// backend.emitLW(a, vacantReg, getAttrOffset(strClass, "__len__"), "Load attribute: __len__");
|
||||||
|
// backend.emitBLTU(index, a, ch, "Ensure 0 <= idx < len");
|
||||||
|
// backend.emitJ(f, "Go to error handler");
|
||||||
|
// backend.emitLocalLabel(ch, "Index within bounds");
|
||||||
|
// this.c(index);
|
||||||
|
// Register a2 = this.a(false);
|
||||||
|
// this.a(1);
|
||||||
|
// return a2;
|
||||||
|
// }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public Register analyze(MemberExpr node)
|
public Register analyze(MemberExpr node)
|
||||||
{
|
{
|
||||||
@@ -755,9 +848,19 @@ public class CodeGenImpl extends CodeGenBase
|
|||||||
* to out-of-bounds error and abort");
|
* to out-of-bounds error and abort");
|
||||||
*/
|
*/
|
||||||
protected void emitCustomCode() {
|
protected void emitCustomCode() {
|
||||||
|
|
||||||
|
emitStdFunc("concat");
|
||||||
|
emitStdFunc("conslist");
|
||||||
|
emitStdFunc("strcat");
|
||||||
|
emitStdFunc("streql");
|
||||||
|
emitStdFunc("strneql");
|
||||||
|
emitStdFunc("makeint");
|
||||||
|
emitStdFunc("makebool");
|
||||||
|
|
||||||
emitErrorFunc(errorNone, "Operation on None");
|
emitErrorFunc(errorNone, "Operation on None");
|
||||||
emitErrorFunc(errorDiv, "Division by zero");
|
emitErrorFunc(errorDiv, "Division by zero");
|
||||||
emitErrorFunc(errorOob, "Index out of bounds");
|
emitErrorFunc(errorOob, "Index out of bounds");
|
||||||
|
emitErrorFunc(errorNI, "Not Implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Emit an error routine labeled ERRLABEL that aborts with message MSG. */
|
/** Emit an error routine labeled ERRLABEL that aborts with message MSG. */
|
||||||
|
|||||||
Reference in New Issue
Block a user