diff options
Diffstat (limited to 'src/main/java/no')
| -rw-r--r-- | src/main/java/no/eliashaugsbakk/kompilator/IO/File.java | 4 | ||||
| -rw-r--r-- | src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriter.java | 39 | ||||
| -rw-r--r-- | src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriterException.java | 7 | ||||
| -rw-r--r-- | src/main/java/no/eliashaugsbakk/kompilator/Main.java | 124 | ||||
| -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.java | 75 |
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(); + } + } +} |
