diff options
Diffstat (limited to 'src/main/java/no/eliashaugsbakk/kompilator/asmGeneration')
| -rw-r--r-- | src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java | 130 | ||||
| -rw-r--r-- | src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java | 7 |
2 files changed, 98 insertions, 39 deletions
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java index c039bcb..275a683 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java @@ -3,14 +3,22 @@ package no.eliashaugsbakk.kompilator.asmGeneration; import java.util.HashMap; import java.util.List; import java.util.Map; +import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Alloc; +import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Assign; +import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Call; +import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Instruction; public class AssemblyBuilder { - Map<String, String> stringVariables = new HashMap<>(); + Map<String, StringVar> stringVariables = new HashMap<>(); + + record StringVar(String value, boolean mutable) { + } StringBuilder finalAssembly; StringBuilder text; StringBuilder rodata; StringBuilder data; + StringBuilder bss; private final static String exit = """ mov rax, 60 @@ -26,66 +34,109 @@ public class AssemblyBuilder { this.rodata = new StringBuilder("\n.section .rodata\n"); // Global initialized variables, Read - Write this.data = new StringBuilder("\n.data\n"); + // Global uninitialized variables, Read - Write + this.bss = new StringBuilder("\n.section .bss\n"); } - public String createAssembly(List<String> IR) { - for (String line : IR) { - line = line.trim(); - - if (line.startsWith("print")) { - handlePrint(line); - } else if (line.contains("=")) { - handleAssignment(line); + public String createAssembly(List<Instruction> IR) { + for (Instruction inst : IR) { + if (inst instanceof Alloc alloc) { + handleAlloc(alloc); + } else if (inst instanceof Assign assign) { + handleAssign(assign); + } else if (inst instanceof Call call) { + handleCall(call); } } + this.text.append(exit); + this.finalAssembly.append(text); this.finalAssembly.append(rodata); this.finalAssembly.append(data); + this.finalAssembly.append(bss); + return this.finalAssembly.toString(); } - private void handleAssignment(String line) { - /* Example IR: - variable_name: type = data - str1: string = "Hello world" - */ - String name = line.substring(0, line.indexOf(":")); + private void handleAssign(Assign assign) { + String reassignLabel = assign.name() + "_reassign"; + this.stringVariables.put(assign.name(), new StringVar(assign.value(), true)); - String dataType = line.substring(line.indexOf(":") + 2, line.indexOf("=") - 1); + this.rodata.append(String.format(""" + %s: .ascii "%s" + """, reassignLabel, assign.value())); - String value = line.substring(line.indexOf("=") + 2); + this.text.append(String.format(""" + lea rax, [rip + %s] + mov [rip + %s], rax + """, reassignLabel, assign.name())); + } - if (dataType.contains("string")) { - assignString(name, value); + private void handleAlloc(Alloc alloc) { + this.stringVariables.put(alloc.name(), new StringVar(alloc.initializer(), alloc.mutable())); + if (alloc.mutable()) { + handleAllocMut(alloc); } else { - IO.println("err: Unknown data type: " + dataType); + handleAllocRO(alloc); } } - private void assignString(String name, String value) { - value = value.substring(1, value.length() - 1); - this.rodata.append(String.format(""" - %s: .ascii "%s" - """, name, value)); - this.stringVariables.put(name, value); + private void handleAllocMut(Alloc alloc) { + if (alloc.type() == null) { + this.bss.append(String.format(""" + %s: .skip 8 + """, alloc.name())); + } else if (alloc.type().equals("string")) { + String pointer = alloc.name() + "_ptr"; + this.rodata.append(String.format(""" + %s: .ascii "%s" + """, pointer, alloc.initializer())); + this.data.append(String.format(""" + %s: .quad %s + """, alloc.name(), pointer)); + } else { + throw new AssemblyBuilderException("Not a supported type"); + } } - void handlePrint(String line) { - /* Takes in a print statement and constructs the assembly - example input: - print(x) - */ - String variableName = line.substring(line.indexOf("(") + 1, line.lastIndexOf(")")); - - int stringLength = 0; - try { - stringLength = this.stringVariables.get(variableName).length(); - } catch (RuntimeException e) { - IO.println("No variable " + variableName + " initialized in IR."); + private void handleAllocRO(Alloc alloc) { + if (alloc.type().equals("string")) { + this.rodata.append(String.format(""" + %s: .ascii "%s" + """, alloc.name(), alloc.initializer())); + } else { + throw new AssemblyBuilderException("Not a supported type to skriv"); } + } - this.text.append(String.format(""" + private void handleCall(Call call) { + if (call.fn().equals("skriv")) { + handlePrint(call); + } else { + throw new AssemblyBuilderException("unknown call type: " + call.fn()); + } + } + + void handlePrint(Call call) { + if (call.args().size() != 1) { + throw new AssemblyBuilderException("Print only supports one argument"); + } + String variableName = call.args().getFirst(); + StringVar var = this.stringVariables.get(variableName); + int stringLength = var.value().length(); + + if (var.mutable()) { + this.text.append(String.format(""" + mov rsi, [rip + %s] + mov rax, 1 + mov rdi, 1 + mov rdx, %d + syscall + + """, variableName, stringLength)); + } else { + this.text.append(String.format(""" mov rax, 1 mov rdi, 1 lea rsi, %s @@ -93,5 +144,6 @@ public class AssemblyBuilder { syscall """, variableName, stringLength)); + } } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java new file mode 100644 index 0000000..f477423 --- /dev/null +++ b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java @@ -0,0 +1,7 @@ +package no.eliashaugsbakk.kompilator.asmGeneration; + +public class AssemblyBuilderException extends RuntimeException { + public AssemblyBuilderException(String message) { + super(message); + } +} |
