diff options
| author | Elias Haugsbakk <[email protected]> | 2026-09-18 00:13:13 +0200 |
|---|---|---|
| committer | Elias Haugsbakk <[email protected]> | 2026-09-18 00:13:13 +0200 |
| commit | c7363c58612b7d3183c0ee91d5eee166fd515758 (patch) | |
| tree | 175dfd722168a51c446da7f3a971f4464a3be30b /src/main/java/no/eliashaugsbakk/kompilator | |
| parent | 30b415615740939a7522a20f222699a30f89a22e (diff) | |
implement print("String") for IR to assembly translation
Diffstat (limited to 'src/main/java/no/eliashaugsbakk/kompilator')
| -rw-r--r-- | src/main/java/no/eliashaugsbakk/kompilator/AssemblyBuilder.java | 95 | ||||
| -rw-r--r-- | src/main/java/no/eliashaugsbakk/kompilator/Main.java | 62 |
2 files changed, 126 insertions, 31 deletions
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/AssemblyBuilder.java b/src/main/java/no/eliashaugsbakk/kompilator/AssemblyBuilder.java new file mode 100644 index 0000000..4e89590 --- /dev/null +++ b/src/main/java/no/eliashaugsbakk/kompilator/AssemblyBuilder.java @@ -0,0 +1,95 @@ +package no.eliashaugsbakk.kompilator; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AssemblyBuilder { + Map<String, String> stringVariables = new HashMap<>(); + + StringBuilder finalAssembly; + StringBuilder text; + StringBuilder rodata; + StringBuilder data; + + + private final static String exit = """ + mov rax, 60 + xor rdi, rdi + syscall + """; + + private final static String printHelloWorld = """ + mov rax, 1 + mov rdi, 1 + lea rsi, [hellostring] + lea rdx, [hellolen] + syscall + """; + + public AssemblyBuilder() { + this.finalAssembly = new StringBuilder(".intel_syntax noprefix\n.global _start\n"); + // CPU instructions + this.text = new StringBuilder(".text\n_start:\n\n"); + // Read only data + this.rodata = new StringBuilder("\n.section .rodata\n"); + // Global initialized variables, Read - Write + this.data = new StringBuilder("\n.data\n"); + } + + String createAssembly(List<String> IR) { + for (String line : IR) { + line = line.trim(); + + if (line.startsWith("print")) { + handlePrint(line); + } else if (line.contains("=")) { + handleAssignment(line); + } + } + this.text.append(exit); + this.finalAssembly.append(text); + this.finalAssembly.append(rodata); + this.finalAssembly.append(data); + 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(":")); + + String dataType = line.substring(line.indexOf(":") + 2, line.indexOf("=") - 1); + + String value = line.substring(line.indexOf("=") + 2); + + if (dataType.contains("string")) { + assignString(name, value); + } else { + IO.println("err: Unknown data type: " + dataType); + } + } + + 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); + } + + void handlePrint(String line) { + String variableName = line.substring(line.indexOf("(") + 1, line.lastIndexOf(")")); + + this.text.append(String.format(""" + mov rax, 1 + mov rdi, 1 + lea rsi, [%s] + lea rdx, [%d] + syscall + + """, variableName, this.stringVariables.get(variableName).length())); + } +} diff --git a/src/main/java/no/eliashaugsbakk/kompilator/Main.java b/src/main/java/no/eliashaugsbakk/kompilator/Main.java index f57b13a..be5746c 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/Main.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/Main.java @@ -8,39 +8,41 @@ import java.io.IOException; import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; public class Main { public static final String programFileExtension = "spå"; - private record InputProgram(String programName, String programContent) {} + + private record InputProgram(String programName, String programContent) { + } static void main(String[] args) { if (args.length != 1) { - IO.println("Only accepts one argument: The filename of the input program"); + IO.println("err: Only accepts one argument: The filename of the input program"); System.exit(1); } InputProgram inputProgram = readInputProgram(args[0]); - /* - String IR = createIR(inputFile); - String assembly = createAssembly(IR); - */ + List<String> IR = List.of(); - assemblingAndLInking(inputProgram); + String assembly = new AssemblyBuilder().createAssembly(IR); + + assemblingAndLInking(inputProgram.programName(), assembly); System.exit(0); } - private static void assemblingAndLInking(InputProgram inputProgram) { - String assemblyFileName = inputProgram.programName + ".s"; - String assembledFileName = inputProgram.programContent + ".o"; + private static void assemblingAndLInking(String programName, String assembly) { + String assemblyFileName = programName + ".s"; + String assembledFileName = programName + ".o"; try { FileWriter fw = new FileWriter(assemblyFileName); - fw.write(inputProgram.programContent); + fw.write(assembly); fw.close(); } catch (IOException e) { - IO.println("Could not write file: " + e.getMessage()); + IO.println("err: Could not write file: " + e.getMessage()); } try { @@ -48,39 +50,41 @@ public class Main { ProcessBuilder asPB = new ProcessBuilder("as", "-o", assembledFileName, assemblyFileName); runProcess(asPB); } catch (IOException e) { - IO.println("Failed to invoke GCC\n\n" + e); + IO.println("err: Failed to invoke GCC\n\n" + e); } catch (InterruptedException e) { - IO.println("Failed to wait for gcc output\n\n" + e); + IO.println("err: Failed to wait for gcc output\n\n" + e); } try { // Linking using GNU linker: ld -o program program.o - ProcessBuilder ldPB = new ProcessBuilder("ld", "-o", inputProgram.programName, assembledFileName); + ProcessBuilder ldPB = new ProcessBuilder("ld", "-o", programName, assembledFileName); runProcess(ldPB); } catch (IOException e) { - IO.println("Failed to invoke GCC\n\n" + e); + IO.println("err: Failed to invoke GCC\n\n" + e); } catch (InterruptedException e) { - IO.println("Failed to wait for gcc output\n\n" + e); + IO.println("err: Failed to wait for gcc output\n\n" + e); } // Clean up try { Files.delete(Path.of(assemblyFileName)); } catch (IOException e) { - IO.println("Could not delete assembly file: " + e.getMessage()); + IO.println("err: Could not delete assembly file: " + e.getMessage()); } try { Files.delete(Path.of(assembledFileName)); } catch (IOException e) { - IO.println("Could not delete assembled file: " + e.getMessage()); + IO.println("err: Could not delete assembled file: " + e.getMessage()); } } - private static void runProcess(ProcessBuilder processBuilder) throws IOException, InterruptedException { + private static void runProcess(ProcessBuilder processBuilder) + throws IOException, InterruptedException { Process process = processBuilder.start(); process.waitFor(); if (process.exitValue() != 0) { - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + BufferedReader bufferedReader = + new BufferedReader(new InputStreamReader(process.getErrorStream())); String line; while ((line = bufferedReader.readLine()) != null) { @@ -91,21 +95,17 @@ public class Main { } private static InputProgram readInputProgram(String inputFilePath) { - IO.println("Input file path: " + inputFilePath); - if (!inputFilePath.endsWith("." + programFileExtension)) { - IO.println("Input file must use the file extension: " + programFileExtension); + IO.println("err: Input file must use the file extension: " + programFileExtension); System.exit(1); } - String programName = inputFilePath.substring( - inputFilePath.lastIndexOf("/") + 1, - inputFilePath.lastIndexOf(".")); - IO.println("Program name: " + programName); + String programName = + inputFilePath.substring(inputFilePath.lastIndexOf("/") + 1, inputFilePath.lastIndexOf(".")); String programContent = null; - try(BufferedReader br = new BufferedReader(new FileReader(inputFilePath))) { + try (BufferedReader br = new BufferedReader(new FileReader(inputFilePath))) { StringBuilder sb = new StringBuilder(); String line = br.readLine(); @@ -116,13 +116,13 @@ public class Main { } programContent = sb.toString(); } catch (FileNotFoundException e) { - IO.println("File not found"); + IO.println("err: File not found"); } catch (IOException e) { IO.println(e.getMessage()); } if (programContent == null) { - IO.println("Could not read input file"); + IO.println("err: Could not read input file"); System.exit(1); } |
