diff options
Diffstat (limited to 'src')
13 files changed, 91 insertions, 99 deletions
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/CompilationException.java b/src/main/java/no/eliashaugsbakk/kompilator/CompilationException.java new file mode 100644 index 0000000..6206744 --- /dev/null +++ b/src/main/java/no/eliashaugsbakk/kompilator/CompilationException.java @@ -0,0 +1,11 @@ +package no.eliashaugsbakk.kompilator; + +public class CompilationException extends Exception { + public CompilationException(String message) { + super(message); + } + + public CompilationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriterException.java b/src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriterException.java index fb38408..96afada 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriterException.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/IO/FileReaderWriterException.java @@ -1,6 +1,8 @@ package no.eliashaugsbakk.kompilator.IO; -public class FileReaderWriterException extends Exception { +import no.eliashaugsbakk.kompilator.CompilationException; + +public class FileReaderWriterException extends CompilationException { public FileReaderWriterException(String message, Exception e) { super("Filhåndtering: " + message, e); } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerationException.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerationException.java index 4fef546..0df2ef2 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerationException.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerationException.java @@ -1,15 +1,15 @@ package no.eliashaugsbakk.kompilator.IRGeneration; +import no.eliashaugsbakk.kompilator.CompilationException; import no.eliashaugsbakk.kompilator.tokenization.Position; -public class IRGenerationException extends RuntimeException { +public class IRGenerationException extends CompilationException { public IRGenerationException(Position position, String message) { - String pos; - if (position == null) { - pos = "ukjent posisjon"; - } else { - pos = position.line() + ":" + position.column(); - } - super(pos + ", " + message); + super(format(position, message)); + } + + private static String format(Position position, String message) { + String pos = position == null ? "ukjent posisjon" : position.line() + ":" + position.column(); + return pos + ", " + message; } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java index 04e8564..ec2733e 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java @@ -28,7 +28,7 @@ public class IRGenerator { this.ast = ast; } - public List<Instruction> generate() { + public List<Instruction> generate() throws IRGenerationException { Program program = (Program) ast.root(); for (Statement stmt : program.statements) { @@ -42,7 +42,7 @@ public class IRGenerator { return ir; } - private void generateStatement(Statement stmt) { + private void generateStatement(Statement stmt) throws IRGenerationException { if (stmt instanceof ExpressionStatement exprStmt) { generateExpression(exprStmt.expression); } else if (stmt instanceof Assignment assignment) { @@ -52,7 +52,7 @@ public class IRGenerator { } } - private void generateAssignment(Assignment assignment) { + private void generateAssignment(Assignment assignment) throws IRGenerationException { String value; if (assignment.expression instanceof StringLiteral stringLiteral) { value = stringLiteral.value; @@ -62,7 +62,7 @@ public class IRGenerator { ir.add(new Assign(assignment.identifier, value)); } - private void generateIdentifierDecl(IdentifierDeclaration identifierDecl) { + private void generateIdentifierDecl(IdentifierDeclaration identifierDecl) throws IRGenerationException { String value; if (identifierDecl.initializer instanceof StringLiteral stringLiteral) { value = stringLiteral.value; @@ -73,7 +73,7 @@ public class IRGenerator { value)); } - private void generateExpression(Expression expr) { + private void generateExpression(Expression expr) throws IRGenerationException { if (expr instanceof FunctionCall call) { generateFunctionCall(call); } else { @@ -82,10 +82,10 @@ public class IRGenerator { } - private void generateFunctionCall(FunctionCall fnCall) { + private void generateFunctionCall(FunctionCall fnCall) throws IRGenerationException { List<String> arguments = new ArrayList<>(); - fnCall.arguments.forEach(arg -> { + for (Expression arg : fnCall.arguments) { if (arg instanceof StringLiteral stringLiteral) { String temp = "t" + tempCounter++; ir.add(new Alloc(temp, "streng", false, stringLiteral.value)); @@ -95,7 +95,7 @@ public class IRGenerator { } else { throw new IRGenerationException(fnCall.position, "Ukjent funksjon: " + arg); } - }); + } ir.add(new Call(fnCall.functionName, arguments)); } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/InternalCompilerException.java b/src/main/java/no/eliashaugsbakk/kompilator/InternalCompilerException.java new file mode 100644 index 0000000..3a043fd --- /dev/null +++ b/src/main/java/no/eliashaugsbakk/kompilator/InternalCompilerException.java @@ -0,0 +1,11 @@ +package no.eliashaugsbakk.kompilator; + +public class InternalCompilerException extends RuntimeException { + public InternalCompilerException(String message) { + super(message); + } + + public InternalCompilerException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/no/eliashaugsbakk/kompilator/Main.java b/src/main/java/no/eliashaugsbakk/kompilator/Main.java index 62a93c7..67b97af 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/Main.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/Main.java @@ -4,16 +4,13 @@ import java.util.Arrays; 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.IRGeneration.IRGenerator; import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Instruction; import no.eliashaugsbakk.kompilator.asmGeneration.AssemblyBuilder; import no.eliashaugsbakk.kompilator.assembleAndLink.AssemblerAndLinker; import no.eliashaugsbakk.kompilator.parsing.AST; import no.eliashaugsbakk.kompilator.parsing.Parser; -import no.eliashaugsbakk.kompilator.parsing.ParserException; import no.eliashaugsbakk.kompilator.semanticAnalysis.Analyzer; -import no.eliashaugsbakk.kompilator.semanticAnalysis.SemanticException; import no.eliashaugsbakk.kompilator.tokenization.Lexer; import no.eliashaugsbakk.kompilator.tokenization.Token; @@ -23,52 +20,32 @@ public class Main { static void main(String[] args) { - if (args.length == 0) { - IO.println("feil: Filsti må angis."); + try { + compile(args); + } catch (CompilationException e) { + IO.println("feil: " + e.getMessage()); System.exit(1); } + } - VERBOSE = Arrays.asList(args).contains("--verbose") - || Arrays.asList(args).contains("-v"); + private static void compile(String[] args) throws CompilationException { + if (args.length == 0) { + throw new CompilationException("Filsti må angis."); + } - String inputFileName = args[0]; + VERBOSE = Arrays.asList(args).contains("--verbose") || Arrays.asList(args).contains("-v"); + String inputFileName = args[0]; if (!inputFileName.endsWith("." + programFileExtension)) { - IO.println("feil: Inndatafilen må ha filendelsen: " + programFileExtension); - System.exit(1); - } - - File inputProgram = null; - FileReaderWriter fileReaderWriter = new FileReaderWriter(); - try { - inputProgram = fileReaderWriter.readFile(inputFileName); - } catch (FileReaderWriterException e) { - IO.println("feil: Kunne ikke lese inndatafilen: " + inputFileName + "\n\n" + e.getMessage()); - System.exit(1); + throw new CompilationException("Inndatafilen må ha filendelsen: " + programFileExtension); } + File inputProgram = new FileReaderWriter().readFile(inputFileName); List<Token> tokens = new Lexer(inputProgram.fileBody()).tokenize(); - AST ast = null; - try { - ast = new Parser(tokens).parse(); - } catch (ParserException e) { - IO.println(e.getMessage()); - System.exit(1); - } - - try { - new Analyzer(ast).analyze(); - } catch (SemanticException e) { - IO.println(e.getMessage()); - System.exit(1); - } - + AST ast = new Parser(tokens).parse(); + new Analyzer(ast).analyze(); List<Instruction> IR = new IRGenerator(ast).generate(); - String assembly = new AssemblyBuilder().createAssembly(IR); - new AssemblerAndLinker().assembleAndLink(inputProgram.fileName(), assembly); - - System.exit(0); } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java index f477423..9a4d4ea 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java @@ -1,6 +1,8 @@ package no.eliashaugsbakk.kompilator.asmGeneration; -public class AssemblyBuilderException extends RuntimeException { +import no.eliashaugsbakk.kompilator.InternalCompilerException; + +public class AssemblyBuilderException extends InternalCompilerException { public AssemblyBuilderException(String message) { super(message); } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java b/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java index 42fe1c3..a2375d1 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java @@ -6,6 +6,7 @@ import java.io.InputStreamReader; import no.eliashaugsbakk.kompilator.IO.File; import no.eliashaugsbakk.kompilator.IO.FileReaderWriter; import no.eliashaugsbakk.kompilator.IO.FileReaderWriterException; +import no.eliashaugsbakk.kompilator.CompilationException; import no.eliashaugsbakk.kompilator.Main; public class AssemblerAndLinker { @@ -15,24 +16,21 @@ public class AssemblerAndLinker { fileReaderWriter = new FileReaderWriter(); } - public void assembleAndLink(String programName, String assembly) { + public void assembleAndLink(String programName, String assembly) throws CompilationException { String assemblyFileName = programName + ".s"; String assembledFileName = programName + ".o"; - try { - fileReaderWriter.writeFile(new File(assemblyFileName, assembly)); - } catch (FileReaderWriterException e) { - IO.println("feil: Kunne ikke skrive filen: " + e.getMessage()); - } + fileReaderWriter.writeFile(new File(assemblyFileName, assembly)); try { // Assembling using: as -o program.o program.s ProcessBuilder asPB = new ProcessBuilder("as", "-o", assembledFileName, assemblyFileName); runProcess(asPB); } catch (IOException e) { - IO.println("feil: Kunne ikke starte GCC\n\n" + e); + throw new CompilationException("Kunne ikke starte assembleren", e); } catch (InterruptedException e) { - IO.println("feil: Kunne ikke vente på GCC-utdata\n\n" + e); + Thread.currentThread().interrupt(); + throw new CompilationException("Ventingen på assembleren ble avbrutt", e); } try { @@ -40,28 +38,21 @@ public class AssemblerAndLinker { ProcessBuilder ldPB = new ProcessBuilder("ld", "-o", programName, assembledFileName); runProcess(ldPB); } catch (IOException e) { - IO.println("feil: Kunne ikke starte GCC\n\n" + e); + throw new CompilationException("Kunne ikke starte lenkeren", e); } catch (InterruptedException e) { - IO.println("feil: Kunne ikke vente på GCC-utdata\n\n" + e); + Thread.currentThread().interrupt(); + throw new CompilationException("Ventingen på lenkeren ble avbrutt", e); } // Clean up if (!Main.VERBOSE) { - try { - fileReaderWriter.deleteFile(assemblyFileName); - } catch (FileReaderWriterException e) { - IO.println("feil: Kunne ikke slette assemblerfilen: " + e.getMessage()); - } - try { - fileReaderWriter.deleteFile(assembledFileName); - } catch (FileReaderWriterException e) { - IO.println("feil: Kunne ikke slette objektfilen: " + e.getMessage()); - } + fileReaderWriter.deleteFile(assemblyFileName); + fileReaderWriter.deleteFile(assembledFileName); } } private static void runProcess(ProcessBuilder processBuilder) - throws IOException, InterruptedException { + throws IOException, InterruptedException, CompilationException { Process process = processBuilder.start(); process.waitFor(); if (process.exitValue() != 0) { @@ -70,7 +61,7 @@ public class AssemblerAndLinker { String line; while ((line = bufferedReader.readLine()) != null) { - System.out.println(line); + throw new CompilationException("Prosessen mislyktes:\n" + line); } bufferedReader.close(); } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java index 1f65b38..483cdda 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java @@ -24,7 +24,6 @@ import no.eliashaugsbakk.kompilator.parsing.node.statement.Assignment; import no.eliashaugsbakk.kompilator.parsing.node.statement.ExpressionStatement; import no.eliashaugsbakk.kompilator.parsing.node.statement.IdentifierDeclaration; import no.eliashaugsbakk.kompilator.parsing.node.statement.Statement; -import no.eliashaugsbakk.kompilator.tokenization.Position; import no.eliashaugsbakk.kompilator.tokenization.Token; /* diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java index 562094a..edae1f8 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java @@ -1,15 +1,15 @@ package no.eliashaugsbakk.kompilator.parsing; +import no.eliashaugsbakk.kompilator.CompilationException; import no.eliashaugsbakk.kompilator.tokenization.Position; -public class ParserException extends Exception { +public class ParserException extends CompilationException { public ParserException(Position position, String message) { - String pos; - if (position == null) { - pos = "ukjent posisjon"; - } else { - pos = position.line() + ":" + position.column(); - } - super(pos + ", " + message); + super(format(position, message)); + } + + private static String format(Position position, String message) { + String pos = position == null ? "ukjent posisjon" : position.line() + ":" + position.column(); + return pos + ", " + message; } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/semanticAnalysis/Analyzer.java b/src/main/java/no/eliashaugsbakk/kompilator/semanticAnalysis/Analyzer.java index 2b4dbb9..7b2adf0 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/semanticAnalysis/Analyzer.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/semanticAnalysis/Analyzer.java @@ -153,7 +153,7 @@ public class Analyzer { */ private Type typeOf(Expression expr) throws SemanticException { switch (expr) { - case null -> throw new SemanticException(expr.position, "Uttrykket kan ikke være null"); + case null -> throw new SemanticException(null, "Uttrykket kan ikke være null"); case StringLiteral _ -> { return new Type("streng", false); } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/semanticAnalysis/SemanticException.java b/src/main/java/no/eliashaugsbakk/kompilator/semanticAnalysis/SemanticException.java index 7783fcc..f56522d 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/semanticAnalysis/SemanticException.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/semanticAnalysis/SemanticException.java @@ -1,15 +1,15 @@ package no.eliashaugsbakk.kompilator.semanticAnalysis; +import no.eliashaugsbakk.kompilator.CompilationException; import no.eliashaugsbakk.kompilator.tokenization.Position; -public class SemanticException extends Exception { +public class SemanticException extends CompilationException { public SemanticException(Position position, String message) { - String pos; - if (position == null) { - pos = "ukjent posisjon"; - } else { - pos = position.line() + ":" + position.column(); - } - super(pos + ", " + message); + super(format(position, message)); + } + + private static String format(Position position, String message) { + String pos = position == null ? "ukjent posisjon" : position.line() + ":" + position.column(); + return pos + ", " + message; } } diff --git a/src/test/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGeneratorTest.java b/src/test/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGeneratorTest.java index f07b5ec..8ba99f6 100644 --- a/src/test/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGeneratorTest.java +++ b/src/test/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGeneratorTest.java @@ -11,13 +11,12 @@ import no.eliashaugsbakk.kompilator.parsing.node.Program; import no.eliashaugsbakk.kompilator.parsing.node.expression.FunctionCall; import no.eliashaugsbakk.kompilator.parsing.node.expression.literal.StringLiteral; import no.eliashaugsbakk.kompilator.parsing.node.statement.ExpressionStatement; -import no.eliashaugsbakk.kompilator.tokenization.Position; import org.junit.jupiter.api.Test; class IRGeneratorTest { @Test - void singlePrintStatementGeneratesCorrectIR() { + void singlePrintStatementGeneratesCorrectIR() throws IRGenerationException { AST ast = buildAST("skriv", "hello"); List<Instruction> ir = new IRGenerator(ast).generate(); @@ -27,7 +26,7 @@ class IRGeneratorTest { } @Test - void multiplePrintStatementsGenerateSequentialTempVars() { + void multiplePrintStatementsGenerateSequentialTempVars() throws IRGenerationException { Program program = new Program(null); program.addStatement(buildStatement("skriv", "hello")); program.addStatement(buildStatement("skriv", "world")); |
