add CodeGenerator

This commit is contained in:
ChUrl
2021-01-28 16:49:22 +01:00
parent c29c807861
commit 5cc40964b6
5 changed files with 60 additions and 39 deletions

6
.idea/discord.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT" />
</component>
</project>

View File

@ -1,5 +1,4 @@
import codegen.sourcegraph.SourceGraph;
import codegen.sourcegraph.SourceGraphGenerator;
import codegen.CodeGenerator;
import lexer.StupsLexer;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.Lexer;
@ -78,12 +77,11 @@ public final class StupsCompiler {
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
// Codegeneration + Output
final String outputName = filename.replaceFirst("stups", "j");
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, filename);
final SourceGraph graph = gen.generateCode();
final String outputName = filename.replaceFirst("\\.stups", ".j");
final String sourceCode = CodeGenerator.generateCode(tree, nodeTable, filename);
try {
final Path outputFile = Paths.get(System.getProperty("user.dir") + "/" + outputName);
Files.writeString(outputFile, graph.toString());
Files.writeString(outputFile, sourceCode);
} catch (IOException e) {
System.out.println("Datei konnte nicht geschrieben werden.");
return;

View File

@ -0,0 +1,20 @@
package codegen;
import codegen.sourcegraph.SourceGraph;
import codegen.sourcegraph.SourceGraphGenerator;
import parser.ast.AST;
import parser.ast.ASTNode;
import java.util.Map;
public final class CodeGenerator {
private CodeGenerator() {}
public static String generateCode(AST tree, Map<ASTNode, String> nodeTypeMap, String source) {
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTypeMap, source);
final SourceGraph graph = gen.generateGraph();
return graph.toString();
}
}

View File

@ -25,16 +25,16 @@ public final class SourceGraphGenerator {
try {
final Class<?> gen = SourceGraphGenerator.class;
map = Map.ofEntries(
entry("cond", gen.getDeclaredMethod("cond", ASTNode.class)),
entry("loop", gen.getDeclaredMethod("loop", ASTNode.class)),
entry("assignment", gen.getDeclaredMethod("assign", ASTNode.class)),
entry("expr", gen.getDeclaredMethod("expr", ASTNode.class)),
entry("cond", gen.getDeclaredMethod("condNode", ASTNode.class)),
entry("loop", gen.getDeclaredMethod("loopNode", ASTNode.class)),
entry("assignment", gen.getDeclaredMethod("assignNode", ASTNode.class)),
entry("expr", gen.getDeclaredMethod("exprNode", ASTNode.class)),
// Leafs
entry("INTEGER_LIT", gen.getDeclaredMethod("intStringLiteral", ASTNode.class)),
entry("BOOLEAN_LIT", gen.getDeclaredMethod("boolLiteral", ASTNode.class)),
entry("STRING_LIT", gen.getDeclaredMethod("intStringLiteral", ASTNode.class)),
entry("IDENTIFIER", gen.getDeclaredMethod("identifier", ASTNode.class)),
entry("print", gen.getDeclaredMethod("println", ASTNode.class))
entry("INTEGER_LIT", gen.getDeclaredMethod("intStringLiteralNode", ASTNode.class)),
entry("BOOLEAN_LIT", gen.getDeclaredMethod("boolLiteralNode", ASTNode.class)),
entry("STRING_LIT", gen.getDeclaredMethod("intStringLiteralNode", ASTNode.class)),
entry("IDENTIFIER", gen.getDeclaredMethod("identifierNode", ASTNode.class)),
entry("print", gen.getDeclaredMethod("printlnNode", ASTNode.class))
);
} catch (NoSuchMethodException e) {
map = null;
@ -43,20 +43,18 @@ public final class SourceGraphGenerator {
methodMap = map;
}
private final AST tree;
private final Map<String, Integer> varMap;
private final Map<ASTNode, String> nodeTypeMap;
private final String source;
private final AST tree;
private final SourceGraph graph;
private int labelCounter;
private SourceGraphGenerator(Map<String, Integer> varMap, AST tree, Map<ASTNode, String> nodeTypeMap, SourceGraph graph, String source) {
private SourceGraphGenerator(Map<String, Integer> varMap, AST tree, Map<ASTNode, String> nodeTypeMap, SourceGraph graph) {
this.varMap = varMap;
this.tree = tree;
this.nodeTypeMap = nodeTypeMap;
this.graph = graph;
this.source = source;
}
public static SourceGraphGenerator fromAST(AST tree, Map<ASTNode, String> nodeTypeMap, String source) {
@ -72,7 +70,7 @@ public final class SourceGraphGenerator {
final int localCount = varMap.size() + 1;
final SourceGraph graph = new SourceGraph(bytecodeVersion, source, clazz, stackSize, localCount);
return new SourceGraphGenerator(varMap, tree, nodeTypeMap, graph, source);
return new SourceGraphGenerator(varMap, tree, nodeTypeMap, graph);
}
private static Map<String, Integer> varMapFromAST(AST tree) {
@ -99,14 +97,13 @@ public final class SourceGraphGenerator {
return Collections.unmodifiableMap(varMap);
}
public SourceGraph generateCode() {
System.out.println(" - Generating Jasmin assembler...");
public SourceGraph generateGraph() {
System.out.println(" - Generating Source Graph...");
this.generateNode(this.tree.getRoot().getChildren().get(3).getChildren().get(11));
log("\n\nJasmin Assembler from FlowGraph:\n" + "-".repeat(100) + "\n" + this.graph + "-".repeat(100));
log("\n\nFlowGraph print:\n" + "-".repeat(100) + "\n" + this.graph.print() + "-".repeat(100));
System.out.println("Code-generation successful.");
log("\n\nSourceGraph print:\n" + "-".repeat(100) + "\n" + this.graph.print() + "-".repeat(100));
System.out.println("Graph-generation successful.");
return this.graph;
}
@ -125,7 +122,7 @@ public final class SourceGraphGenerator {
// ifeq - if value is 0
// ifne - if value is not 0
private void cond(ASTNode node) {
private void condNode(ASTNode node) {
final int currentLabel = this.labelCounter;
this.labelCounter++;
@ -151,7 +148,7 @@ public final class SourceGraphGenerator {
this.graph.addLabel("IFend" + currentLabel);
}
private void loop(ASTNode node) {
private void loopNode(ASTNode node) {
final int currentLabel = this.labelCounter;
this.labelCounter++;
@ -171,7 +168,7 @@ public final class SourceGraphGenerator {
this.graph.addLabel("LOOPend" + currentLabel);
}
private void assign(ASTNode node) { //! Stack - 1
private void assignNode(ASTNode node) { //! Stack - 1
this.generateNode(node.getChildren().get(0));
final String type = this.nodeTypeMap.get(node.getChildren().get(0));
@ -186,7 +183,7 @@ public final class SourceGraphGenerator {
this.graph.addInst(inst, this.varMap.get(node.getValue()).toString());
}
private void expr(ASTNode node) {
private void exprNode(ASTNode node) {
if ("INTEGER_TYPE".equals(this.nodeTypeMap.get(node))) {
this.intExpr(node);
} else if ("BOOLEAN_TYPE".equals(this.nodeTypeMap.get(node))) {
@ -289,14 +286,14 @@ public final class SourceGraphGenerator {
// Leafs
private void intStringLiteral(ASTNode node) { //! Stack + 1
log("literal(): " + node.getName() + ": " + node.getValue() + " => ldc");
private void intStringLiteralNode(ASTNode node) { //! Stack + 1
log("intStringLiteral(): " + node.getName() + ": " + node.getValue() + " => ldc");
// bipush only pushes 1 byte as int
this.graph.addInst("ldc", node.getValue());
}
private void boolLiteral(ASTNode node) { //! Stack + 1
private void boolLiteralNode(ASTNode node) { //! Stack + 1
log("booleanLiteral(): " + node.getName() + ": " + node.getValue() + " => ldc");
final String val = "true".equals(node.getValue()) ? "1" : "0";
@ -304,7 +301,7 @@ public final class SourceGraphGenerator {
this.graph.addInst("ldc", val);
}
private void identifier(ASTNode node) { //! Stack + 1
private void identifierNode(ASTNode node) { //! Stack + 1
final String type = this.nodeTypeMap.get(node);
final String inst = switch (type) {
case "INTEGER_TYPE", "BOOLEAN_TYPE" -> "iload";
@ -317,7 +314,7 @@ public final class SourceGraphGenerator {
this.graph.addInst(inst, this.varMap.get(node.getValue()).toString());
}
private void println(ASTNode node) { //! Stack + 1
private void printlnNode(ASTNode node) { //! Stack + 1
this.graph.addInst("getstatic", "java/lang/System/out", "Ljava/io/PrintStream;");
final ASTNode expr = node.getChildren().get(1).getChildren().get(1);

View File

@ -243,7 +243,7 @@ class SourceGraphGeneratorTest {
final AST tree = lexParseProgram(program);
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutpu");
final SourceGraph srcProg = gen.generateCode();
final SourceGraph srcProg = gen.generateGraph();
compileJasmin(srcProg.toString());
assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result);
@ -258,7 +258,7 @@ class SourceGraphGeneratorTest {
final AST tree = lexParseProgram(program);
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
final SourceGraph srcProg = gen.generateCode();
final SourceGraph srcProg = gen.generateGraph();
compileJasmin(srcProg.toString());
assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result);
@ -273,7 +273,7 @@ class SourceGraphGeneratorTest {
final AST tree = lexParseProgram(program);
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
final SourceGraph srcProg = gen.generateCode();
final SourceGraph srcProg = gen.generateGraph();
compileJasmin(srcProg.toString());
assertThat(Boolean.parseBoolean(executeCompiledProgram())).isEqualTo(result);
@ -288,7 +288,7 @@ class SourceGraphGeneratorTest {
final AST tree = lexParseProgram(program);
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
final SourceGraph srcProg = gen.generateCode();
final SourceGraph srcProg = gen.generateGraph();
compileJasmin(srcProg.toString());
assertThat(executeCompiledProgram()).isEqualTo(result);
@ -303,7 +303,7 @@ class SourceGraphGeneratorTest {
final AST tree = lexParseProgram(program);
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
final SourceGraph srcProg = gen.generateCode();
final SourceGraph srcProg = gen.generateGraph();
compileJasmin(srcProg.toString());
assertThat(executeCompiledProgram()).isEqualTo(result);