summaryrefslogtreecommitdiff
path: root/submit/ast
diff options
context:
space:
mode:
Diffstat (limited to 'submit/ast')
-rw-r--r--submit/ast/AbstractNode.java2
-rw-r--r--submit/ast/Assignment.java25
-rw-r--r--submit/ast/BinaryOperator.java89
-rw-r--r--submit/ast/BinaryOperatorType.java24
-rw-r--r--submit/ast/BoolConstant.java6
-rw-r--r--submit/ast/Break.java2
-rw-r--r--submit/ast/Call.java104
-rw-r--r--submit/ast/CharConstant.java6
-rw-r--r--submit/ast/CompoundStatement.java31
-rw-r--r--submit/ast/Declaration.java4
-rw-r--r--submit/ast/Expression.java4
-rw-r--r--submit/ast/ExpressionStatement.java11
-rw-r--r--submit/ast/FunDeclaration.java21
-rw-r--r--submit/ast/If.java40
-rw-r--r--submit/ast/Mutable.java16
-rw-r--r--submit/ast/Node.java5
-rw-r--r--submit/ast/NumConstant.java17
-rw-r--r--submit/ast/Param.java13
-rw-r--r--submit/ast/ParenExpression.java10
-rw-r--r--submit/ast/Program.java13
-rw-r--r--submit/ast/Return.java24
-rw-r--r--submit/ast/Statement.java6
-rw-r--r--submit/ast/StringConstant.java17
-rw-r--r--submit/ast/UnaryOperator.java26
-rw-r--r--submit/ast/VarDeclaration.java7
-rw-r--r--submit/ast/VarType.java9
-rw-r--r--submit/ast/While.java27
27 files changed, 494 insertions, 65 deletions
diff --git a/submit/ast/AbstractNode.java b/submit/ast/AbstractNode.java
index 01719aa..0a53882 100644
--- a/submit/ast/AbstractNode.java
+++ b/submit/ast/AbstractNode.java
@@ -10,6 +10,6 @@ public class AbstractNode implements Node {
public MIPSResult toMIPS(StringBuilder code, StringBuilder data, SymbolTable symbolTable,
RegisterAllocator regAllocator) {
- return null;
+ return MIPSResult.createVoidResult();
}
}
diff --git a/submit/ast/Assignment.java b/submit/ast/Assignment.java
index 1a5d172..9c06cbe 100644
--- a/submit/ast/Assignment.java
+++ b/submit/ast/Assignment.java
@@ -4,6 +4,10 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
@@ -30,4 +34,25 @@ public class Assignment extends AbstractNode implements Expression {
}
}
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ MIPSResult mut = mutable.toMIPS(code, data, symbolTable, regAllocator);
+ MIPSResult result = rhs.toMIPS(code, data, symbolTable, regAllocator);
+
+ String registerWithAddressOfMutable = mut.getAddress();
+
+ if (result.getRegister() != null) {
+ code.append(String.format("sw %s 0(%s)\n", result.getRegister(),
+ registerWithAddressOfMutable));
+ regAllocator.clear(result.getRegister());
+ } else if (result.getAddress() != null) {
+ regAllocator.loadIntoRegister(result, code, result.getAddress());
+ regAllocator.clear(result.getAddress());
+ }
+
+ regAllocator.clear(registerWithAddressOfMutable);
+
+ return MIPSResult.createVoidResult();
+ }
}
diff --git a/submit/ast/BinaryOperator.java b/submit/ast/BinaryOperator.java
index d18766b..2545dd0 100644
--- a/submit/ast/BinaryOperator.java
+++ b/submit/ast/BinaryOperator.java
@@ -4,6 +4,10 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
@@ -13,7 +17,8 @@ public class BinaryOperator extends AbstractNode implements Expression {
private final Expression lhs, rhs;
private final BinaryOperatorType type;
- public BinaryOperator(Expression lhs, BinaryOperatorType type, Expression rhs) {
+ public BinaryOperator(Expression lhs, BinaryOperatorType type,
+ Expression rhs) {
this.lhs = lhs;
this.type = type;
this.rhs = rhs;
@@ -32,4 +37,86 @@ public class BinaryOperator extends AbstractNode implements Expression {
rhs.toCminus(builder, prefix);
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ MIPSResult left = lhs.toMIPS(code, data, symbolTable, regAllocator);
+ String leftRegister =
+ regAllocator.getRegisterOrLoadIntoRegister(left, code);
+
+ MIPSResult right = rhs.toMIPS(code, data, symbolTable, regAllocator);
+ String rightRegister =
+ regAllocator.getRegisterOrLoadIntoRegister(right, code);
+ String resultRegister = regAllocator.getAny();
+
+ switch (type) {
+ case PLUS:
+ code.append(String.format("add %s %s %s\n", resultRegister, leftRegister,
+ rightRegister));
+ break;
+ case MINUS:
+ code.append(String.format("sub %s %s %s\n", resultRegister, leftRegister,
+ rightRegister));
+ break;
+ case TIMES:
+ code.append(String.format("mult %s %s\n", leftRegister, rightRegister))
+ .append(String.format("mflo %s\n", resultRegister));
+ break;
+ case DIVIDE:
+ code.append(String.format("div %s %s\n", leftRegister, rightRegister))
+ .append(String.format("mflo %s\n", resultRegister));
+ break;
+ case MOD:
+ code.append(String.format("div %s %s\n", leftRegister, rightRegister))
+ .append(String.format("mfhi %s\n", resultRegister));
+ break;
+ case LT:
+ code.append(String.format("slt %s %s %s\n", resultRegister, leftRegister,
+ rightRegister))
+ .append(
+ String.format("subi %s %s 1\n", resultRegister, resultRegister));
+ break;
+ case GT:
+ code.append(String.format("slt %s %s %s\n", resultRegister, rightRegister,
+ leftRegister))
+ .append(
+ String.format("subi %s %s 1\n", resultRegister, resultRegister));
+ break;
+ case LE:
+ code.append(String.format("slt %s %s %s\n", resultRegister, rightRegister,
+ leftRegister));
+ break;
+ case GE:
+ code.append(String.format("slt %s %s %s\n", resultRegister, leftRegister,
+ rightRegister));
+ break;
+ case EQ:
+ code.append(String.format("sub %s %s %s\n", resultRegister, leftRegister,
+ rightRegister));
+ break;
+ case OR:
+ code.append(String.format("or %s %s %s\n", resultRegister, leftRegister,
+ rightRegister));
+ break;
+ case AND:
+ code.append(String.format("abs %s %s\n", leftRegister, leftRegister))
+ .append(String.format("abs %s %s\n", rightRegister, rightRegister))
+ .append(String.format("add %s %s %s\n", resultRegister, leftRegister,
+ rightRegister));
+ break;
+ case NE:
+ code.append(String.format("xor %s %s %s\n", resultRegister, leftRegister,
+ rightRegister))
+ .append(
+ String.format("sltiu %s %s 1\n", resultRegister, resultRegister));
+ default:
+ break;
+ }
+
+ regAllocator.clear(leftRegister);
+ regAllocator.clear(rightRegister);
+
+ return MIPSResult.createRegisterResult(resultRegister, VarType.INT);
+ }
}
diff --git a/submit/ast/BinaryOperatorType.java b/submit/ast/BinaryOperatorType.java
index 37235c8..fea3d6e 100644
--- a/submit/ast/BinaryOperatorType.java
+++ b/submit/ast/BinaryOperatorType.java
@@ -10,15 +10,23 @@ package submit.ast;
*/
public enum BinaryOperatorType {
- OR("||"), AND("&&"),
- LE("<="), LT("<"), GT(">"), GE(">="), EQ("=="), NE("!="),
- PLUS("+"), MINUS("-"), TIMES("*"), DIVIDE("/"), MOD("%");
+ OR("||"),
+ AND("&&"),
+ LE("<="),
+ LT("<"),
+ GT(">"),
+ GE(">="),
+ EQ("=="),
+ NE("!="),
+ PLUS("+"),
+ MINUS("-"),
+ TIMES("*"),
+ DIVIDE("/"),
+ MOD("%");
private final String value;
- private BinaryOperatorType(String value) {
- this.value = value;
- }
+ private BinaryOperatorType(String value) { this.value = value; }
public static BinaryOperatorType fromString(String s) {
for (BinaryOperatorType at : BinaryOperatorType.values()) {
@@ -26,12 +34,12 @@ public enum BinaryOperatorType {
return at;
}
}
- throw new RuntimeException("Illegal string in OperatorType.fromString(): " + s);
+ throw new RuntimeException("Illegal string in OperatorType.fromString(): " +
+ s);
}
@Override
public String toString() {
return value;
}
-
}
diff --git a/submit/ast/BoolConstant.java b/submit/ast/BoolConstant.java
index 4b0ad2c..2a7a281 100644
--- a/submit/ast/BoolConstant.java
+++ b/submit/ast/BoolConstant.java
@@ -9,12 +9,9 @@ package submit.ast;
* @author edwajohn
*/
public class BoolConstant extends AbstractNode implements Expression {
-
private final boolean value;
- public BoolConstant(boolean value) {
- this.value = value;
- }
+ public BoolConstant(boolean value) { this.value = value; }
public void toCminus(StringBuilder builder, final String prefix) {
if (value) {
@@ -23,5 +20,4 @@ public class BoolConstant extends AbstractNode implements Expression {
builder.append("false");
}
}
-
}
diff --git a/submit/ast/Break.java b/submit/ast/Break.java
index e3f28bc..0582c91 100644
--- a/submit/ast/Break.java
+++ b/submit/ast/Break.java
@@ -9,10 +9,8 @@ package submit.ast;
* @author edwajohn
*/
public class Break extends AbstractNode implements Statement {
-
@Override
public void toCminus(StringBuilder builder, String prefix) {
builder.append(prefix).append("break;\n");
}
-
}
diff --git a/submit/ast/Call.java b/submit/ast/Call.java
index b6e61ba..25ab2ea 100644
--- a/submit/ast/Call.java
+++ b/submit/ast/Call.java
@@ -6,12 +6,16 @@ package submit.ast;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
/**
*
* @author edwajohn
*/
-public class Call extends AbstractNode implements Expression {
+public class Call implements Expression {
private final String id;
private final List<Expression> args;
@@ -21,6 +25,39 @@ public class Call extends AbstractNode implements Expression {
this.args = new ArrayList<>(args);
}
+ private void println(List<MIPSResult> mipsResults, StringBuilder code,
+ StringBuilder data, SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ code.append("# println\n");
+
+ for (MIPSResult result : mipsResults) {
+ if (result.getRegister() == null && result.getAddress() != null) {
+ if (result.getAddress().startsWith("$")) {
+ // Hack - might be a register
+ regAllocator.loadIntoRegister(result, code, "$a0");
+ } else {
+ code.append(String.format("la $a0 %s\n", result.getAddress()));
+ }
+ } else if (result.getRegister() != null) {
+ code.append(String.format("move $a0 %s\n", result.getRegister()));
+ }
+
+ if (result.getType() == VarType.INT) {
+ code.append("li $v0 1\n");
+ } else if (result.getType() == VarType.CHAR) {
+ code.append("li $v0 11\n");
+ } else {
+ code.append("li $v0 4\n");
+ }
+ code.append("syscall\n");
+ }
+
+ // End line with newline
+ code.append(String.format("la $a0 %s\n", "newline"));
+ code.append("li $v0 4\n");
+ code.append("syscall\n");
+ }
+
@Override
public void toCminus(StringBuilder builder, String prefix) {
builder.append(id).append("(");
@@ -34,4 +71,69 @@ public class Call extends AbstractNode implements Expression {
builder.append(")");
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ List<MIPSResult> argMips;
+ String resultRegister = null;
+
+ if (this.id.equals("println")) {
+ argMips =
+ args.stream()
+ .map(e -> e.toMIPS(code, data, symbolTable, regAllocator))
+ .collect(Collectors.toList());
+ this.println(argMips, code, data, symbolTable, regAllocator);
+ } else {
+ argMips = new ArrayList<MIPSResult>();
+ String returnAddr = regAllocator.getAny();
+ code.append(String.format("move %s $ra\n", returnAddr));
+ int savedRegistersOffset = regAllocator.saveRestore(
+ code, -symbolTable.getOffset(), false, true);
+
+ int argsOffset = symbolTable.getOffset() - savedRegistersOffset;
+ int i = argsOffset;
+ for (Expression expression : args) {
+ MIPSResult mipsResult =
+ expression.toMIPS(code, data, symbolTable, regAllocator);
+ argMips.add(mipsResult);
+ i -= 4;
+
+ String reg =
+ regAllocator.getRegisterOrLoadIntoRegister(mipsResult, code);
+ code.append(String.format("sw %s %d($sp)\n", reg, i));
+
+ regAllocator.clear(reg);
+ }
+
+ code.append(String.format("add $sp $sp %d\n", argsOffset));
+
+ code.append(String.format("jal %s\n", id));
+
+ code.append(String.format("add $sp $sp %d\n", -argsOffset));
+
+ regAllocator.saveRestore(code, -symbolTable.getOffset(), false,
+ false);
+ code.append(String.format("# symbol table size - %d\n", i));
+
+ resultRegister = regAllocator.getAny();
+ regAllocator.loadIntoRegisterWithOffset(
+ MIPSResult.createAddressResult("$sp", VarType.INT), code,
+ resultRegister, i - 4);
+
+ code.append(String.format("move $ra %s\n", returnAddr));
+ regAllocator.clear(returnAddr);
+ }
+
+ for (MIPSResult arg : argMips)
+ if (arg.getRegister() != null)
+ regAllocator.clear(arg.getRegister());
+
+ if (resultRegister != null) {
+ VarType returnType = symbolTable.find(id).getType();
+ return MIPSResult.createRegisterResult(resultRegister, returnType);
+ }
+
+ return MIPSResult.createVoidResult();
+ }
}
diff --git a/submit/ast/CharConstant.java b/submit/ast/CharConstant.java
index 8ca801d..5334be2 100644
--- a/submit/ast/CharConstant.java
+++ b/submit/ast/CharConstant.java
@@ -9,15 +9,11 @@ package submit.ast;
* @author edwajohn
*/
public class CharConstant extends AbstractNode implements Expression {
-
private final char value;
- public CharConstant(char value) {
- this.value = value;
- }
+ public CharConstant(char value) { this.value = value; }
public void toCminus(StringBuilder builder, final String prefix) {
builder.append("'").append(value).append("'");
}
-
}
diff --git a/submit/ast/CompoundStatement.java b/submit/ast/CompoundStatement.java
index bd5628a..e8d9256 100644
--- a/submit/ast/CompoundStatement.java
+++ b/submit/ast/CompoundStatement.java
@@ -5,6 +5,9 @@
package submit.ast;
import java.util.List;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
/**
*
@@ -13,11 +16,16 @@ import java.util.List;
public class CompoundStatement extends AbstractNode implements Statement {
private final List<Statement> statements;
+ private SymbolTable symbolTable;
- public CompoundStatement(List<Statement> statements) {
+ public CompoundStatement(List<Statement> statements,
+ SymbolTable symbolTable) {
this.statements = statements;
+ this.symbolTable = symbolTable;
}
+ public SymbolTable getSymbolTable() { return symbolTable; }
+
@Override
public void toCminus(StringBuilder builder, String prefix) {
builder.append(prefix).append("{\n");
@@ -27,4 +35,25 @@ public class CompoundStatement extends AbstractNode implements Statement {
builder.append(prefix).append("}\n");
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ code.append("# Entering a new scope.\n");
+ code.append("# Symbols in symbol table:\n");
+ for (String name : this.symbolTable.symbolNames())
+ code.append(
+ String.format("# %s : %d\n", name, this.symbolTable.offsetOf(name)));
+
+ code.append("# Update the stack pointer.\n");
+ code.append(String.format("addi $sp $sp %d\n", symbolTable.getOffset()));
+
+ for (Statement statement : statements)
+ statement.toMIPS(code, data, this.symbolTable, regAllocator);
+
+ code.append("# Exit scope.\n");
+ code.append(String.format("addi $sp $sp %s\n", -symbolTable.getOffset()));
+
+ return MIPSResult.createVoidResult();
+ }
}
diff --git a/submit/ast/Declaration.java b/submit/ast/Declaration.java
index 32947e6..99c1c1a 100644
--- a/submit/ast/Declaration.java
+++ b/submit/ast/Declaration.java
@@ -8,6 +8,4 @@ package submit.ast;
*
* @author edwajohn
*/
-public interface Declaration extends Statement {
-
-}
+public interface Declaration extends Statement {}
diff --git a/submit/ast/Expression.java b/submit/ast/Expression.java
index 910f6f0..d31753a 100644
--- a/submit/ast/Expression.java
+++ b/submit/ast/Expression.java
@@ -8,6 +8,4 @@ package submit.ast;
*
* @author edwajohn
*/
-public interface Expression extends Node {
-
-}
+public interface Expression extends Node {}
diff --git a/submit/ast/ExpressionStatement.java b/submit/ast/ExpressionStatement.java
index 69071d8..a7ed5d2 100644
--- a/submit/ast/ExpressionStatement.java
+++ b/submit/ast/ExpressionStatement.java
@@ -4,6 +4,10 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
@@ -23,4 +27,11 @@ public class ExpressionStatement extends AbstractNode implements Statement {
builder.append(";\n");
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ expression.toMIPS(code, data, symbolTable, regAllocator);
+ return MIPSResult.createVoidResult();
+ }
}
diff --git a/submit/ast/FunDeclaration.java b/submit/ast/FunDeclaration.java
index 1ec2ca6..3980119 100644
--- a/submit/ast/FunDeclaration.java
+++ b/submit/ast/FunDeclaration.java
@@ -6,6 +6,9 @@ package submit.ast;
import java.util.ArrayList;
import java.util.List;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
/**
*
@@ -19,7 +22,7 @@ public class FunDeclaration extends AbstractNode implements Declaration {
private final Statement statement;
public FunDeclaration(VarType returnType, String id, List<Param> params,
- Statement statement) {
+ Statement statement) {
this.returnType = returnType;
this.id = id;
this.params = new ArrayList<>(params);
@@ -43,4 +46,20 @@ public class FunDeclaration extends AbstractNode implements Declaration {
statement.toCminus(builder, prefix);
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ code.append(id).append(":\n");
+
+ statement.toMIPS(code, data, symbolTable, regAllocator);
+
+ if (id.equals("main"))
+ code.append("li $v0 10\nsyscall\n");
+ else
+ code.append("jr $ra\n");
+ regAllocator.clearAll();
+
+ return MIPSResult.createVoidResult();
+ }
}
diff --git a/submit/ast/If.java b/submit/ast/If.java
index a516c94..0c47ce9 100644
--- a/submit/ast/If.java
+++ b/submit/ast/If.java
@@ -4,6 +4,10 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
@@ -14,7 +18,8 @@ public class If extends AbstractNode implements Statement {
private final Statement trueStatement;
private final Statement falseStatement;
- public If(Expression expression, Statement trueStatement, Statement falseStatement) {
+ public If(Expression expression, Statement trueStatement,
+ Statement falseStatement) {
this.expression = expression;
this.trueStatement = trueStatement;
this.falseStatement = falseStatement;
@@ -41,4 +46,37 @@ public class If extends AbstractNode implements Statement {
}
// builder.append(prefix).append("}");
}
+
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ String continueLabel = "if_" + SymbolTable.nextId();
+ String elseLabel = "else_" + SymbolTable.nextId();
+
+ MIPSResult expressionTruthiness =
+ expression.toMIPS(code, data, symbolTable, regAllocator);
+
+ code.append(String.format("bne %s $zero %s\n",
+ expressionTruthiness.getRegister(), elseLabel));
+ regAllocator.clear(expressionTruthiness.getRegister());
+
+ MIPSResult trueRes =
+ trueStatement.toMIPS(code, data, symbolTable, regAllocator);
+ regAllocator.clear(trueRes.getRegister());
+
+ code.append(String.format("j %s\n", continueLabel))
+ .append(String.format("%s:\n", elseLabel));
+
+ regAllocator.clear(expressionTruthiness.getRegister());
+
+ if (falseStatement != null) {
+ MIPSResult falseRes =
+ falseStatement.toMIPS(code, data, symbolTable, regAllocator);
+ regAllocator.clear(falseRes.getRegister());
+ }
+ code.append(String.format("%s:\n", continueLabel));
+
+ return MIPSResult.createVoidResult();
+ }
}
diff --git a/submit/ast/Mutable.java b/submit/ast/Mutable.java
index d549371..ac9b7ff 100644
--- a/submit/ast/Mutable.java
+++ b/submit/ast/Mutable.java
@@ -4,11 +4,15 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
*/
-public class Mutable extends AbstractNode implements Expression {
+public class Mutable implements Expression {
private final String id;
private final Expression index;
@@ -28,4 +32,14 @@ public class Mutable extends AbstractNode implements Expression {
}
}
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ String stackReg = regAllocator.getAny();
+
+ code.append(String.format("li %s %d\n", stackReg, symbolTable.offsetOf(id)))
+ .append(String.format("add %s %s $sp\n", stackReg, stackReg));
+
+ return MIPSResult.createAddressResult(stackReg, VarType.INT);
+ }
}
diff --git a/submit/ast/Node.java b/submit/ast/Node.java
index 2eed788..cc6c2d5 100644
--- a/submit/ast/Node.java
+++ b/submit/ast/Node.java
@@ -5,7 +5,8 @@ import submit.RegisterAllocator;
import submit.SymbolTable;
public interface Node {
- void toCminus(StringBuilder builder, final String prefix);
+ void toCminus(StringBuilder builder, final String prefix);
- MIPSResult toMIPS(StringBuilder code, StringBuilder data, SymbolTable symbolTable, RegisterAllocator regAllocator);
+ MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable, RegisterAllocator regAllocator);
}
diff --git a/submit/ast/NumConstant.java b/submit/ast/NumConstant.java
index 4e343fd..3287bd5 100644
--- a/submit/ast/NumConstant.java
+++ b/submit/ast/NumConstant.java
@@ -4,6 +4,10 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
@@ -12,12 +16,19 @@ public class NumConstant extends AbstractNode implements Expression {
private final int value;
- public NumConstant(int value) {
- this.value = value;
- }
+ public NumConstant(int value) { this.value = value; }
public void toCminus(StringBuilder builder, final String prefix) {
builder.append(Integer.toString(value));
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ String register = regAllocator.getAny();
+ code.append(String.format("li %s %d\n", register, value));
+
+ return MIPSResult.createRegisterResult(register, VarType.INT);
+ }
}
diff --git a/submit/ast/Param.java b/submit/ast/Param.java
index 478c6e2..921b179 100644
--- a/submit/ast/Param.java
+++ b/submit/ast/Param.java
@@ -20,17 +20,11 @@ public class Param extends AbstractNode implements Node {
this.array = array;
}
- public VarType getType() {
- return type;
- }
+ public VarType getType() { return type; }
- public String getId() {
- return id;
- }
+ public String getId() { return id; }
- public boolean isArray() {
- return array;
- }
+ public boolean isArray() { return array; }
public void toCminus(StringBuilder builder, final String prefix) {
if (isArray()) {
@@ -39,5 +33,4 @@ public class Param extends AbstractNode implements Node {
builder.append(type).append(" ").append(id);
}
}
-
}
diff --git a/submit/ast/ParenExpression.java b/submit/ast/ParenExpression.java
index 2eb0b8f..8d5b65f 100644
--- a/submit/ast/ParenExpression.java
+++ b/submit/ast/ParenExpression.java
@@ -4,6 +4,10 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
@@ -23,4 +27,10 @@ public class ParenExpression extends AbstractNode implements Expression {
builder.append(")");
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ return expression.toMIPS(code, data, symbolTable, regAllocator);
+ }
}
diff --git a/submit/ast/Program.java b/submit/ast/Program.java
index 1478961..74b9ea8 100644
--- a/submit/ast/Program.java
+++ b/submit/ast/Program.java
@@ -6,6 +6,9 @@ package submit.ast;
import java.util.ArrayList;
import java.util.List;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
/**
*
@@ -33,4 +36,14 @@ public class Program extends AbstractNode implements Node {
}
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ data.append("newline: .asciiz \"\\n\"\n");
+
+ for (Declaration declaration : declarations)
+ declaration.toMIPS(code, data, symbolTable, regAllocator);
+ return MIPSResult.createVoidResult();
+ }
}
diff --git a/submit/ast/Return.java b/submit/ast/Return.java
index 47a8c16..ebae15f 100644
--- a/submit/ast/Return.java
+++ b/submit/ast/Return.java
@@ -4,17 +4,18 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
*/
public class Return extends AbstractNode implements Statement {
-
private final Expression expr;
- public Return(Expression expr) {
- this.expr = expr;
- }
+ public Return(Expression expr) { this.expr = expr; }
@Override
public void toCminus(StringBuilder builder, String prefix) {
@@ -28,4 +29,19 @@ public class Return extends AbstractNode implements Statement {
}
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ if (expr != null) {
+ String reg = regAllocator.getRegisterOrLoadIntoRegister(
+ expr.toMIPS(code, data, symbolTable, regAllocator), code);
+ code.append(
+ String.format("# symbol table size - %d\n", symbolTable.getOffset()));
+ code.append(
+ String.format("sw %s %d($sp)\n", reg, symbolTable.getOffset()));
+ code.append("jr $ra\n");
+ }
+ return MIPSResult.createVoidResult();
+ }
}
diff --git a/submit/ast/Statement.java b/submit/ast/Statement.java
index 2e0581e..2daeb9d 100644
--- a/submit/ast/Statement.java
+++ b/submit/ast/Statement.java
@@ -11,6 +11,8 @@ import java.util.ArrayList;
* @author edwajohn
*/
public interface Statement extends Node {
- public static CompoundStatement empty() { return new CompoundStatement(new ArrayList<>()); }
-
+ public static CompoundStatement empty() {
+ submit.SymbolTable newTable = new submit.SymbolTable();
+ return new CompoundStatement(new ArrayList<>(), newTable);
+ }
}
diff --git a/submit/ast/StringConstant.java b/submit/ast/StringConstant.java
index c3b966e..5aaa5c3 100644
--- a/submit/ast/StringConstant.java
+++ b/submit/ast/StringConstant.java
@@ -4,6 +4,10 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
@@ -12,12 +16,19 @@ public class StringConstant extends AbstractNode implements Expression {
private final String value;
- public StringConstant(String value) {
- this.value = value;
- }
+ public StringConstant(String value) { this.value = value; }
public void toCminus(StringBuilder builder, final String prefix) {
builder.append("\"").append(value).append("\"");
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ String label = String.format("string_%s", SymbolTable.nextId());
+ data.append(String.format("%s: .asciiz %s\n", label, value));
+
+ return MIPSResult.createAddressResult(label, null);
+ }
}
diff --git a/submit/ast/UnaryOperator.java b/submit/ast/UnaryOperator.java
index 1b5082a..5195ef0 100644
--- a/submit/ast/UnaryOperator.java
+++ b/submit/ast/UnaryOperator.java
@@ -4,6 +4,10 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
@@ -23,5 +27,27 @@ public class UnaryOperator extends AbstractNode implements Expression {
builder.append(type);
expression.toCminus(builder, prefix);
}
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ MIPSResult result =
+ expression.toMIPS(code, data, symbolTable, regAllocator);
+
+ String reg = regAllocator.getRegisterOrLoadIntoRegister(result, code);
+ switch (type) {
+ case NEG:
+ code.append(String.format("sub %s $zero %s\n", reg, reg));
+ break;
+ case NOT:
+ code.append(String.format("sltu %s $zero %s\n", reg, reg))
+ .append(String.format("xori %s %s 1\n", reg, reg));
+ break;
+ default:
+ break;
+ }
+
+ return MIPSResult.createRegisterResult(reg, VarType.INT);
+ }
}
diff --git a/submit/ast/VarDeclaration.java b/submit/ast/VarDeclaration.java
index d2a5264..809518f 100644
--- a/submit/ast/VarDeclaration.java
+++ b/submit/ast/VarDeclaration.java
@@ -18,7 +18,8 @@ public class VarDeclaration extends AbstractNode implements Declaration {
private final List<Integer> arraySizes;
private final boolean isStatic;
- public VarDeclaration(VarType type, List<String> ids, List<Integer> arraySizes, boolean isStatic) {
+ public VarDeclaration(VarType type, List<String> ids,
+ List<Integer> arraySizes, boolean isStatic) {
this.type = type;
this.ids = new ArrayList<>(ids);
this.arraySizes = arraySizes;
@@ -35,7 +36,8 @@ public class VarDeclaration extends AbstractNode implements Declaration {
final String id = ids.get(i);
final int arraySize = arraySizes.get(i);
if (arraySize >= 0) {
- builder.append(id).append("[").append(arraySize).append("]").append(", ");
+ builder.append(id).append("[").append(arraySize).append("]").append(
+ ", ");
} else {
builder.append(id).append(", ");
}
@@ -43,5 +45,4 @@ public class VarDeclaration extends AbstractNode implements Declaration {
builder.delete(builder.length() - 2, builder.length());
builder.append(";\n");
}
-
}
diff --git a/submit/ast/VarType.java b/submit/ast/VarType.java
index ba28946..e797d50 100644
--- a/submit/ast/VarType.java
+++ b/submit/ast/VarType.java
@@ -10,13 +10,13 @@ package submit.ast;
*/
public enum VarType {
- INT("int"), BOOL("bool"), CHAR("char");
+ INT("int"),
+ BOOL("bool"),
+ CHAR("char");
private final String value;
- private VarType(String value) {
- this.value = value;
- }
+ private VarType(String value) { this.value = value; }
public static VarType fromString(String s) {
for (VarType vt : VarType.values()) {
@@ -31,5 +31,4 @@ public enum VarType {
public String toString() {
return value;
}
-
}
diff --git a/submit/ast/While.java b/submit/ast/While.java
index a37195e..41c3963 100644
--- a/submit/ast/While.java
+++ b/submit/ast/While.java
@@ -4,6 +4,10 @@
*/
package submit.ast;
+import submit.MIPSResult;
+import submit.RegisterAllocator;
+import submit.SymbolTable;
+
/**
*
* @author edwajohn
@@ -28,6 +32,29 @@ public class While extends AbstractNode implements Statement {
} else {
statement.toCminus(builder, prefix + " ");
}
+ }
+
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator regAllocator) {
+ String loopLabel = "while_truthy_" + SymbolTable.nextId();
+ String finishedLabel = "finished_while_" + SymbolTable.nextId();
+
+ code.append(String.format("%s:\n", loopLabel));
+
+ MIPSResult expressionTruthiness =
+ expression.toMIPS(code, data, symbolTable, regAllocator);
+
+ code.append(String.format("bne %s $zero %s\n",
+ expressionTruthiness.getRegister(),
+ finishedLabel));
+
+ MIPSResult inside = statement.toMIPS(code, data, symbolTable, regAllocator);
+ regAllocator.clear(inside.getRegister());
+ code.append(String.format("j %s\n", loopLabel))
+ .append(String.format("%s:\n", finishedLabel));
+ return MIPSResult.createVoidResult();
}
}