diff options
| author | Elizabeth Alexander Hunt <me@liz.coffee> | 2026-07-02 11:55:17 -0700 |
|---|---|---|
| committer | Elizabeth Alexander Hunt <me@liz.coffee> | 2026-07-02 11:55:17 -0700 |
| commit | 6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6 (patch) | |
| tree | ed97e39ec77c5231ffd2c394493e68d00ddac5a4 /Homework/cs5300/compiler/p5-compiler/submit/ast/Call.java | |
| download | misc-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.java | 139 |
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(); + } +} |
