summaryrefslogtreecommitdiff
path: root/src/main/java/no/eliashaugsbakk/kompilator
diff options
context:
space:
mode:
authorElias Haugsbakk <[email protected]>2026-09-18 19:10:54 +0200
committerElias Haugsbakk <[email protected]>2026-09-19 01:59:23 +0200
commit6dd4036bd828dac87b9f63d0a58693b30c46faed (patch)
treec194ad43c1d9b1a332e28659863b88f463a07a9c /src/main/java/no/eliashaugsbakk/kompilator
parent24f5104f56cfc67cf1e89da3e5913b2954acc36d (diff)
split into separate packages/classes
Diffstat (limited to 'src/main/java/no/eliashaugsbakk/kompilator')
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/IO/File.java4
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriter.java39
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriterException.java7
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/Main.java124
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java (renamed from src/main/java/no/eliashaugsbakk/kompilator/AssemblyBuilder.java)17
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java75
6 files changed, 158 insertions, 108 deletions
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IO/File.java b/src/main/java/no/eliashaugsbakk/kompilator/IO/File.java
new file mode 100644
index 0000000..48f6edf
--- /dev/null
+++ b/src/main/java/no/eliashaugsbakk/kompilator/IO/File.java
@@ -0,0 +1,4 @@
+package no.eliashaugsbakk.kompilator.IO;
+
+public record File(String fileName, String fileBody) {
+}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriter.java b/src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriter.java
new file mode 100644
index 0000000..b25b719
--- /dev/null
+++ b/src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriter.java
@@ -0,0 +1,39 @@
+package no.eliashaugsbakk.kompilator.IO;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class FileReaderWriter {
+
+ public File readFile(String inputFilePath) throws FileReaderWriterException {
+ Path path = Path.of(inputFilePath);
+
+ String rawName = path.getFileName().toString();
+ int dotIndex = rawName.lastIndexOf('.');
+ String fileName = (dotIndex == -1) ? rawName : rawName.substring(0, dotIndex);
+
+ try {
+ String fileBody = Files.readString(path);
+ return new File(fileName, fileBody);
+ } catch (IOException e) {
+ throw new FileReaderWriterException("Failed to read file: " + inputFilePath, e);
+ }
+ }
+
+ public void writeFile(File file) throws FileReaderWriterException {
+ try {
+ Files.writeString(Path.of(file.fileName()), file.fileBody());
+ } catch (IOException e) {
+ throw new FileReaderWriterException("Failed to write file: " + file.fileName(), e);
+ }
+ }
+
+ public void deleteFile(String filePath) throws FileReaderWriterException {
+ try {
+ Files.delete(Path.of(filePath));
+ } catch (IOException e) {
+ throw new FileReaderWriterException("Could not delete file: " + filePath, e);
+ }
+ }
+}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriterException.java b/src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriterException.java
new file mode 100644
index 0000000..1cc5bb8
--- /dev/null
+++ b/src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriterException.java
@@ -0,0 +1,7 @@
+package no.eliashaugsbakk.kompilator.IO;
+
+public class FileReaderWriterException extends Exception {
+ public FileReaderWriterException(String message, Exception e) {
+ super("FileReaderWriter: " + message, e);
+ }
+}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/Main.java b/src/main/java/no/eliashaugsbakk/kompilator/Main.java
index be5746c..aad3753 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/Main.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/Main.java
@@ -1,131 +1,45 @@
package no.eliashaugsbakk.kompilator;
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.util.List;
+import no.eliashaugsbakk.kompilator.IO.File;
+import no.eliashaugsbakk.kompilator.IO.FileReaderWriter;
+import no.eliashaugsbakk.kompilator.IO.FileReaderWriterException;
+import no.eliashaugsbakk.kompilator.asmGeneration.AssemblyBuilder;
+import no.eliashaugsbakk.kompilator.assembleAndLink.AssemblerAndLinker;
public class Main {
public static final String programFileExtension = "spå";
- private record InputProgram(String programName, String programContent) {
- }
-
static void main(String[] args) {
if (args.length != 1) {
IO.println("err: Only accepts one argument: The filename of the input program");
System.exit(1);
}
- InputProgram inputProgram = readInputProgram(args[0]);
-
- List<String> IR = List.of();
-
- String assembly = new AssemblyBuilder().createAssembly(IR);
-
- assemblingAndLInking(inputProgram.programName(), assembly);
-
- System.exit(0);
- }
- private static void assemblingAndLInking(String programName, String assembly) {
- String assemblyFileName = programName + ".s";
- String assembledFileName = programName + ".o";
+ String inputFileName = args[0];
- try {
- FileWriter fw = new FileWriter(assemblyFileName);
- fw.write(assembly);
- fw.close();
- } catch (IOException e) {
- IO.println("err: Could not write file: " + e.getMessage());
- }
-
- try {
- // Assembling using: as -o program.o program.s
- ProcessBuilder asPB = new ProcessBuilder("as", "-o", assembledFileName, assemblyFileName);
- runProcess(asPB);
- } catch (IOException e) {
- IO.println("err: Failed to invoke GCC\n\n" + e);
- } catch (InterruptedException 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", programName, assembledFileName);
- runProcess(ldPB);
- } catch (IOException e) {
- IO.println("err: Failed to invoke GCC\n\n" + e);
- } catch (InterruptedException e) {
- IO.println("err: Failed to wait for gcc output\n\n" + e);
+ if (!inputFileName.endsWith("." + programFileExtension)) {
+ IO.println("err: Input file must use the file extension: " + programFileExtension);
+ System.exit(1);
}
- // Clean up
+ File inputProgram = null;
+ FileReaderWriter fileReaderWriter = new FileReaderWriter();
try {
- Files.delete(Path.of(assemblyFileName));
- } catch (IOException e) {
- IO.println("err: Could not delete assembly file: " + e.getMessage());
- }
- try {
- Files.delete(Path.of(assembledFileName));
- } catch (IOException e) {
- IO.println("err: Could not delete assembled file: " + e.getMessage());
- }
- }
-
- 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()));
-
- String line;
- while ((line = bufferedReader.readLine()) != null) {
- System.out.println(line);
- }
- bufferedReader.close();
- }
- }
-
- private static InputProgram readInputProgram(String inputFilePath) {
- if (!inputFilePath.endsWith("." + programFileExtension)) {
- IO.println("err: Input file must use the file extension: " + programFileExtension);
+ inputProgram = fileReaderWriter.readFile(inputFileName);
+ } catch (FileReaderWriterException e) {
+ IO.println("Could not read input file: " + inputFileName + "\n\n" + e.getMessage());
System.exit(1);
}
- String programName =
- inputFilePath.substring(inputFilePath.lastIndexOf("/") + 1, inputFilePath.lastIndexOf("."));
-
- String programContent = null;
-
- try (BufferedReader br = new BufferedReader(new FileReader(inputFilePath))) {
- StringBuilder sb = new StringBuilder();
- String line = br.readLine();
+ List<String> IR = List.of();
- while (line != null) {
- sb.append(line);
- sb.append(System.lineSeparator());
- line = br.readLine();
- }
- programContent = sb.toString();
- } catch (FileNotFoundException e) {
- IO.println("err: File not found");
- } catch (IOException e) {
- IO.println(e.getMessage());
- }
+ String assembly = new AssemblyBuilder().createAssembly(IR);
- if (programContent == null) {
- IO.println("err: Could not read input file");
- System.exit(1);
- }
+ AssemblerAndLinker assemblerAndLinker = new AssemblerAndLinker();
+ assemblerAndLinker.assembleAndLink(inputProgram.fileName(), assembly);
- return new InputProgram(programName, programContent);
+ System.exit(0);
}
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/AssemblyBuilder.java b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java
index 082f21d..94a753b 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/AssemblyBuilder.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java
@@ -1,4 +1,4 @@
-package no.eliashaugsbakk.kompilator;
+package no.eliashaugsbakk.kompilator.asmGeneration;
import java.util.HashMap;
import java.util.List;
@@ -28,7 +28,7 @@ public class AssemblyBuilder {
this.data = new StringBuilder("\n.data\n");
}
- String createAssembly(List<String> IR) {
+ public String createAssembly(List<String> IR) {
for (String line : IR) {
line = line.trim();
@@ -72,8 +72,19 @@ public class AssemblyBuilder {
}
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.");
+ }
+
this.text.append(String.format("""
mov rax, 1
mov rdi, 1
@@ -81,6 +92,6 @@ public class AssemblyBuilder {
lea rdx, [%d]
syscall
- """, variableName, this.stringVariables.get(variableName).length()));
+ """, variableName, stringLength));
}
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java b/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java
new file mode 100644
index 0000000..5ab0b57
--- /dev/null
+++ b/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java
@@ -0,0 +1,75 @@
+package no.eliashaugsbakk.kompilator.assembleAndLink;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import no.eliashaugsbakk.kompilator.IO.File;
+import no.eliashaugsbakk.kompilator.IO.FileReaderWriter;
+import no.eliashaugsbakk.kompilator.IO.FileReaderWriterException;
+
+public class AssemblerAndLinker {
+ private final FileReaderWriter fileReaderWriter;
+
+ public AssemblerAndLinker() {
+ fileReaderWriter = new FileReaderWriter();
+ }
+
+ public void assembleAndLink(String programName, String assembly) {
+ String assemblyFileName = programName + ".s";
+ String assembledFileName = programName + ".o";
+
+ try {
+ fileReaderWriter.writeFile(new File(assemblyFileName, assembly));
+ } catch (FileReaderWriterException e) {
+ IO.println("err: Could not write file: " + e.getMessage());
+ }
+
+ try {
+ // Assembling using: as -o program.o program.s
+ ProcessBuilder asPB = new ProcessBuilder("as", "-o", assembledFileName, assemblyFileName);
+ runProcess(asPB);
+ } catch (IOException e) {
+ IO.println("err: Failed to invoke GCC\n\n" + e);
+ } catch (InterruptedException 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", programName, assembledFileName);
+ runProcess(ldPB);
+ } catch (IOException e) {
+ IO.println("err: Failed to invoke GCC\n\n" + e);
+ } catch (InterruptedException e) {
+ IO.println("err: Failed to wait for gcc output\n\n" + e);
+ }
+
+ // Clean up
+ try {
+ fileReaderWriter.deleteFile(assemblyFileName);
+ } catch (FileReaderWriterException e) {
+ IO.println("err: Could not delete assembly file: " + e.getMessage());
+ }
+ try {
+ fileReaderWriter.deleteFile(assembledFileName);
+ } catch (FileReaderWriterException e) {
+ IO.println("err: Could not delete assembled file: " + e.getMessage());
+ }
+ }
+
+ 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()));
+
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ System.out.println(line);
+ }
+ bufferedReader.close();
+ }
+ }
+}