summaryrefslogtreecommitdiff
path: root/Homework/cs5300/compiler/p5-compiler/submit/ast/Call.java
diff options
context:
space:
mode:
authorElizabeth Alexander Hunt <me@liz.coffee>2026-07-02 11:55:17 -0700
committerElizabeth Alexander Hunt <me@liz.coffee>2026-07-02 11:55:17 -0700
commit6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6 (patch)
treeed97e39ec77c5231ffd2c394493e68d00ddac5a4 /Homework/cs5300/compiler/p5-compiler/submit/ast/Call.java
downloadmisc-undergrad-main.tar.gz
misc-undergrad-main.zip
Diffstat (limited to 'Homework/cs5300/compiler/p5-compiler/submit/ast/Call.java')
-rw-r--r--Homework/cs5300/compiler/p5-compiler/submit/ast/Call.java139
1 files changed, 139 insertions, 0 deletions
diff --git a/Homework/cs5300/compiler/p5-compiler/submit/ast/Call.java b/Homework/cs5300/compiler/p5-compiler/submit/ast/Call.java
new file mode 100644
index 0000000..7da86cd
--- /dev/null
+++ b/Homework/cs5300/compiler/p5-compiler/submit/ast/Call.java
@@ -0,0 +1,139 @@
+/*
+ * Code formatter project
+ * CS 4481
+ */
+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 implements Expression {
+
+ private final String id;
+ private final List<Expression> args;
+
+ public Call(String id, List<Expression> args) {
+ this.id = id;
+ this.args = new ArrayList<>(args);
+ }
+
+ private void println(List<MIPSResult> mipsResults, StringBuilder code,
+ StringBuilder data, SymbolTable symbolTable,
+ RegisterAllocator registerAllocator) {
+ code.append("# println\n");
+
+ for (MIPSResult result : mipsResults) {
+ if (result.getRegister() == null && result.getAddress() != null) {
+ if (result.getAddress().startsWith("$")) {
+ // Hack - might be a register
+ registerAllocator.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("(");
+ for (Expression arg : args) {
+ arg.toCminus(builder, prefix);
+ builder.append(", ");
+ }
+ if (!args.isEmpty()) {
+ builder.setLength(builder.length() - 2);
+ }
+ builder.append(")");
+ }
+
+ @Override
+ public MIPSResult toMIPS(StringBuilder code, StringBuilder data,
+ SymbolTable symbolTable,
+ RegisterAllocator registerAllocator) {
+ List<MIPSResult> argMips;
+ String resultRegister = null;
+
+ if (this.id.equals("println")) {
+ argMips =
+ args.stream()
+ .map(e -> e.toMIPS(code, data, symbolTable, registerAllocator))
+ .collect(Collectors.toList());
+ this.println(argMips, code, data, symbolTable, registerAllocator);
+ } else {
+ argMips = new ArrayList<MIPSResult>();
+ String returnAddr = registerAllocator.getAny();
+ code.append(String.format("move %s $ra\n", returnAddr));
+ int savedRegistersOffset = registerAllocator.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, registerAllocator);
+ argMips.add(mipsResult);
+ i -= 4;
+
+ String reg =
+ registerAllocator.getRegisterOrLoadIntoRegister(mipsResult, code);
+ code.append(String.format("sw %s %d($sp)\n", reg, i));
+
+ registerAllocator.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));
+
+ registerAllocator.saveRestore(code, -symbolTable.getOffset(), false,
+ false);
+ code.append(String.format("# symbol table size - %d\n", i));
+
+ resultRegister = registerAllocator.getAny();
+ registerAllocator.loadIntoRegisterWithOffset(
+ MIPSResult.createAddressResult("$sp", VarType.INT), code,
+ resultRegister, i - 4);
+
+ code.append(String.format("move $ra %s\n", returnAddr));
+ registerAllocator.clear(returnAddr);
+ }
+
+ for (MIPSResult arg : argMips)
+ if (arg.getRegister() != null)
+ registerAllocator.clear(arg.getRegister());
+
+ if (resultRegister != null) {
+ VarType returnType = symbolTable.find(id).getType();
+ return MIPSResult.createRegisterResult(resultRegister, returnType);
+ }
+
+ return MIPSResult.createVoidResult();
+ }
+}