diff options
Diffstat (limited to 'src/main/java/no/eliashaugsbakk/kompilator')
3 files changed, 89 insertions, 11 deletions
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerationException.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerationException.java new file mode 100644 index 0000000..ab881a0 --- /dev/null +++ b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerationException.java @@ -0,0 +1,7 @@ +package no.eliashaugsbakk.kompilator.IRGeneration; + +public class IRGenerationException extends RuntimeException { + public IRGenerationException(String message) { + super(message); + } +} diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java index ffbccb6..1c42673 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java @@ -6,49 +6,87 @@ import no.eliashaugsbakk.kompilator.parsing.AST; import no.eliashaugsbakk.kompilator.parsing.node.Program; import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression; import no.eliashaugsbakk.kompilator.parsing.node.expression.FunctionCall; +import no.eliashaugsbakk.kompilator.parsing.node.expression.Identifier; import no.eliashaugsbakk.kompilator.parsing.node.expression.literal.StringLiteral; +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; public class IRGenerator { private final AST ast; - private final List<String> ir = new ArrayList<>(); - private int tempVarCounter = 0; + private final List<Instr> ir = new ArrayList<>(); + private int tempCounter = 0; public IRGenerator(AST ast) { this.ast = ast; } - public List<String> generate() { + public List<Instr> generate() { Program program = (Program) ast.getRoot(); for (Statement stmt : program.statements) { generateStatement(stmt); } - return ir; } private void generateStatement(Statement stmt) { if (stmt instanceof ExpressionStatement exprStmt) { generateExpression(exprStmt.expression); + } else if (stmt instanceof Assignment assignment) { + generateAssignment(assignment); + } else if (stmt instanceof IdentifierDeclaration identifierDecl) { + generateIdentifierDecl(identifierDecl); + } + } + + private void generateAssignment(Assignment assignment) { + String value; + if (assignment.expression instanceof StringLiteral stringLiteral) { + value = stringLiteral.value; + } else { + throw new IRGenerationException("Only strings are implemented"); } + ir.add(new Assign(assignment.identifier, value)); + } + + private void generateIdentifierDecl(IdentifierDeclaration identifierDecl) { + String value; + if (identifierDecl.initializer instanceof StringLiteral stringLiteral) { + value = stringLiteral.value; + } else { + throw new IRGenerationException("Unknown function: " + identifierDecl.initializer); + } + ir.add(new Alloc(identifierDecl.identifier, identifierDecl.type.type, identifierDecl.mutable, + value)); } private void generateExpression(Expression expr) { if (expr instanceof FunctionCall call) { generateFunctionCall(call); + } else { + throw new IRGenerationException("Only expression which can stand alone are functions"); } } - private void generateFunctionCall(FunctionCall call) { - for (Expression arg : call.arguments) { - if (arg instanceof StringLiteral stringLit) { - String tempVar = "t" + (tempVarCounter++); - ir.add(tempVar + ": string = \"" + stringLit.value + "\""); - ir.add(String.format("print(%s)", tempVar)); + + private void generateFunctionCall(FunctionCall fnCall) { + List<String> arguments = new ArrayList<>(); + + fnCall.arguments.forEach(arg -> { + if (arg instanceof StringLiteral stringLiteral) { + String temp = "t" + tempCounter++; + ir.add(new Alloc(temp, "string", false, stringLiteral.value)); + arguments.add(temp); + } else if (arg instanceof Identifier identifier) { + arguments.add(identifier.name); + } else { + throw new IRGenerationException("Unknown function: " + arg); } - } + }); + + ir.add(new Call(fnCall.functionName, arguments)); } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instr.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instr.java new file mode 100644 index 0000000..09ed4f6 --- /dev/null +++ b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instr.java @@ -0,0 +1,33 @@ +package no.eliashaugsbakk.kompilator.IRGeneration; + +import java.util.List; + +public sealed interface Instr permits Alloc, Assign, Call { +} + + +// allocate a new variable: set x: string = "Hello"; mut y: string?; +// +// Alloc("x", "string", false, "Hello") // Alloc("y", "string", true, "null") +record Alloc(String name, String type, boolean mutable, String initializer) implements Instr { + @Override + public String toString() { + return "Alloc[name=" + name + ", type=" + type + ", mutable=" + mutable + ", initializer=\"" + initializer + "\"]"; + } +} + + +// assign a value to a variable: x = "Hello"; +// Assign("x", "Hello") +record Assign(String name, String value) implements Instr { + @Override + public String toString() { + return "Assign[name=" + name + ", value=\"" + value + "\"]"; + } +} + + +// call a function: skriv("hello"); +// Call("skriv", ["t1"]) +record Call(String fn, List<String> args) implements Instr { +} |
