add CodeGenerator
This commit is contained in:
6
.idea/discord.xml
generated
Normal file
6
.idea/discord.xml
generated
Normal 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>
|
@ -1,5 +1,4 @@
|
|||||||
import codegen.sourcegraph.SourceGraph;
|
import codegen.CodeGenerator;
|
||||||
import codegen.sourcegraph.SourceGraphGenerator;
|
|
||||||
import lexer.StupsLexer;
|
import lexer.StupsLexer;
|
||||||
import org.antlr.v4.runtime.CharStreams;
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
import org.antlr.v4.runtime.Lexer;
|
import org.antlr.v4.runtime.Lexer;
|
||||||
@ -78,12 +77,11 @@ public final class StupsCompiler {
|
|||||||
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
||||||
|
|
||||||
// Codegeneration + Output
|
// Codegeneration + Output
|
||||||
final String outputName = filename.replaceFirst("stups", "j");
|
final String outputName = filename.replaceFirst("\\.stups", ".j");
|
||||||
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, filename);
|
final String sourceCode = CodeGenerator.generateCode(tree, nodeTable, filename);
|
||||||
final SourceGraph graph = gen.generateCode();
|
|
||||||
try {
|
try {
|
||||||
final Path outputFile = Paths.get(System.getProperty("user.dir") + "/" + outputName);
|
final Path outputFile = Paths.get(System.getProperty("user.dir") + "/" + outputName);
|
||||||
Files.writeString(outputFile, graph.toString());
|
Files.writeString(outputFile, sourceCode);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("Datei konnte nicht geschrieben werden.");
|
System.out.println("Datei konnte nicht geschrieben werden.");
|
||||||
return;
|
return;
|
||||||
|
20
src/main/java/codegen/CodeGenerator.java
Normal file
20
src/main/java/codegen/CodeGenerator.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
@ -25,16 +25,16 @@ public final class SourceGraphGenerator {
|
|||||||
try {
|
try {
|
||||||
final Class<?> gen = SourceGraphGenerator.class;
|
final Class<?> gen = SourceGraphGenerator.class;
|
||||||
map = Map.ofEntries(
|
map = Map.ofEntries(
|
||||||
entry("cond", gen.getDeclaredMethod("cond", ASTNode.class)),
|
entry("cond", gen.getDeclaredMethod("condNode", ASTNode.class)),
|
||||||
entry("loop", gen.getDeclaredMethod("loop", ASTNode.class)),
|
entry("loop", gen.getDeclaredMethod("loopNode", ASTNode.class)),
|
||||||
entry("assignment", gen.getDeclaredMethod("assign", ASTNode.class)),
|
entry("assignment", gen.getDeclaredMethod("assignNode", ASTNode.class)),
|
||||||
entry("expr", gen.getDeclaredMethod("expr", ASTNode.class)),
|
entry("expr", gen.getDeclaredMethod("exprNode", ASTNode.class)),
|
||||||
// Leafs
|
// Leafs
|
||||||
entry("INTEGER_LIT", gen.getDeclaredMethod("intStringLiteral", ASTNode.class)),
|
entry("INTEGER_LIT", gen.getDeclaredMethod("intStringLiteralNode", ASTNode.class)),
|
||||||
entry("BOOLEAN_LIT", gen.getDeclaredMethod("boolLiteral", ASTNode.class)),
|
entry("BOOLEAN_LIT", gen.getDeclaredMethod("boolLiteralNode", ASTNode.class)),
|
||||||
entry("STRING_LIT", gen.getDeclaredMethod("intStringLiteral", ASTNode.class)),
|
entry("STRING_LIT", gen.getDeclaredMethod("intStringLiteralNode", ASTNode.class)),
|
||||||
entry("IDENTIFIER", gen.getDeclaredMethod("identifier", ASTNode.class)),
|
entry("IDENTIFIER", gen.getDeclaredMethod("identifierNode", ASTNode.class)),
|
||||||
entry("print", gen.getDeclaredMethod("println", ASTNode.class))
|
entry("print", gen.getDeclaredMethod("printlnNode", ASTNode.class))
|
||||||
);
|
);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
map = null;
|
map = null;
|
||||||
@ -43,20 +43,18 @@ public final class SourceGraphGenerator {
|
|||||||
methodMap = map;
|
methodMap = map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final AST tree;
|
||||||
private final Map<String, Integer> varMap;
|
private final Map<String, Integer> varMap;
|
||||||
private final Map<ASTNode, String> nodeTypeMap;
|
private final Map<ASTNode, String> nodeTypeMap;
|
||||||
private final String source;
|
|
||||||
private final AST tree;
|
|
||||||
private final SourceGraph graph;
|
private final SourceGraph graph;
|
||||||
|
|
||||||
private int labelCounter;
|
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.varMap = varMap;
|
||||||
this.tree = tree;
|
this.tree = tree;
|
||||||
this.nodeTypeMap = nodeTypeMap;
|
this.nodeTypeMap = nodeTypeMap;
|
||||||
this.graph = graph;
|
this.graph = graph;
|
||||||
this.source = source;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SourceGraphGenerator fromAST(AST tree, Map<ASTNode, String> nodeTypeMap, String 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 int localCount = varMap.size() + 1;
|
||||||
final SourceGraph graph = new SourceGraph(bytecodeVersion, source, clazz, stackSize, localCount);
|
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) {
|
private static Map<String, Integer> varMapFromAST(AST tree) {
|
||||||
@ -99,14 +97,13 @@ public final class SourceGraphGenerator {
|
|||||||
return Collections.unmodifiableMap(varMap);
|
return Collections.unmodifiableMap(varMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceGraph generateCode() {
|
public SourceGraph generateGraph() {
|
||||||
System.out.println(" - Generating Jasmin assembler...");
|
System.out.println(" - Generating Source Graph...");
|
||||||
|
|
||||||
this.generateNode(this.tree.getRoot().getChildren().get(3).getChildren().get(11));
|
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\nSourceGraph print:\n" + "-".repeat(100) + "\n" + this.graph.print() + "-".repeat(100));
|
||||||
log("\n\nFlowGraph print:\n" + "-".repeat(100) + "\n" + this.graph.print() + "-".repeat(100));
|
System.out.println("Graph-generation successful.");
|
||||||
System.out.println("Code-generation successful.");
|
|
||||||
|
|
||||||
return this.graph;
|
return this.graph;
|
||||||
}
|
}
|
||||||
@ -125,7 +122,7 @@ public final class SourceGraphGenerator {
|
|||||||
|
|
||||||
// ifeq - if value is 0
|
// ifeq - if value is 0
|
||||||
// ifne - if value is not 0
|
// ifne - if value is not 0
|
||||||
private void cond(ASTNode node) {
|
private void condNode(ASTNode node) {
|
||||||
final int currentLabel = this.labelCounter;
|
final int currentLabel = this.labelCounter;
|
||||||
this.labelCounter++;
|
this.labelCounter++;
|
||||||
|
|
||||||
@ -151,7 +148,7 @@ public final class SourceGraphGenerator {
|
|||||||
this.graph.addLabel("IFend" + currentLabel);
|
this.graph.addLabel("IFend" + currentLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loop(ASTNode node) {
|
private void loopNode(ASTNode node) {
|
||||||
final int currentLabel = this.labelCounter;
|
final int currentLabel = this.labelCounter;
|
||||||
this.labelCounter++;
|
this.labelCounter++;
|
||||||
|
|
||||||
@ -171,7 +168,7 @@ public final class SourceGraphGenerator {
|
|||||||
this.graph.addLabel("LOOPend" + currentLabel);
|
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));
|
this.generateNode(node.getChildren().get(0));
|
||||||
|
|
||||||
final String type = this.nodeTypeMap.get(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());
|
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))) {
|
if ("INTEGER_TYPE".equals(this.nodeTypeMap.get(node))) {
|
||||||
this.intExpr(node);
|
this.intExpr(node);
|
||||||
} else if ("BOOLEAN_TYPE".equals(this.nodeTypeMap.get(node))) {
|
} else if ("BOOLEAN_TYPE".equals(this.nodeTypeMap.get(node))) {
|
||||||
@ -289,14 +286,14 @@ public final class SourceGraphGenerator {
|
|||||||
|
|
||||||
// Leafs
|
// Leafs
|
||||||
|
|
||||||
private void intStringLiteral(ASTNode node) { //! Stack + 1
|
private void intStringLiteralNode(ASTNode node) { //! Stack + 1
|
||||||
log("literal(): " + node.getName() + ": " + node.getValue() + " => ldc");
|
log("intStringLiteral(): " + node.getName() + ": " + node.getValue() + " => ldc");
|
||||||
|
|
||||||
// bipush only pushes 1 byte as int
|
// bipush only pushes 1 byte as int
|
||||||
this.graph.addInst("ldc", node.getValue());
|
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");
|
log("booleanLiteral(): " + node.getName() + ": " + node.getValue() + " => ldc");
|
||||||
|
|
||||||
final String val = "true".equals(node.getValue()) ? "1" : "0";
|
final String val = "true".equals(node.getValue()) ? "1" : "0";
|
||||||
@ -304,7 +301,7 @@ public final class SourceGraphGenerator {
|
|||||||
this.graph.addInst("ldc", val);
|
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 type = this.nodeTypeMap.get(node);
|
||||||
final String inst = switch (type) {
|
final String inst = switch (type) {
|
||||||
case "INTEGER_TYPE", "BOOLEAN_TYPE" -> "iload";
|
case "INTEGER_TYPE", "BOOLEAN_TYPE" -> "iload";
|
||||||
@ -317,7 +314,7 @@ public final class SourceGraphGenerator {
|
|||||||
this.graph.addInst(inst, this.varMap.get(node.getValue()).toString());
|
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;");
|
this.graph.addInst("getstatic", "java/lang/System/out", "Ljava/io/PrintStream;");
|
||||||
|
|
||||||
final ASTNode expr = node.getChildren().get(1).getChildren().get(1);
|
final ASTNode expr = node.getChildren().get(1).getChildren().get(1);
|
||||||
|
@ -243,7 +243,7 @@ class SourceGraphGeneratorTest {
|
|||||||
final AST tree = lexParseProgram(program);
|
final AST tree = lexParseProgram(program);
|
||||||
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
||||||
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutpu");
|
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutpu");
|
||||||
final SourceGraph srcProg = gen.generateCode();
|
final SourceGraph srcProg = gen.generateGraph();
|
||||||
|
|
||||||
compileJasmin(srcProg.toString());
|
compileJasmin(srcProg.toString());
|
||||||
assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result);
|
assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result);
|
||||||
@ -258,7 +258,7 @@ class SourceGraphGeneratorTest {
|
|||||||
final AST tree = lexParseProgram(program);
|
final AST tree = lexParseProgram(program);
|
||||||
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
||||||
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
||||||
final SourceGraph srcProg = gen.generateCode();
|
final SourceGraph srcProg = gen.generateGraph();
|
||||||
|
|
||||||
compileJasmin(srcProg.toString());
|
compileJasmin(srcProg.toString());
|
||||||
assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result);
|
assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result);
|
||||||
@ -273,7 +273,7 @@ class SourceGraphGeneratorTest {
|
|||||||
final AST tree = lexParseProgram(program);
|
final AST tree = lexParseProgram(program);
|
||||||
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
||||||
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
||||||
final SourceGraph srcProg = gen.generateCode();
|
final SourceGraph srcProg = gen.generateGraph();
|
||||||
|
|
||||||
compileJasmin(srcProg.toString());
|
compileJasmin(srcProg.toString());
|
||||||
assertThat(Boolean.parseBoolean(executeCompiledProgram())).isEqualTo(result);
|
assertThat(Boolean.parseBoolean(executeCompiledProgram())).isEqualTo(result);
|
||||||
@ -288,7 +288,7 @@ class SourceGraphGeneratorTest {
|
|||||||
final AST tree = lexParseProgram(program);
|
final AST tree = lexParseProgram(program);
|
||||||
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
||||||
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
||||||
final SourceGraph srcProg = gen.generateCode();
|
final SourceGraph srcProg = gen.generateGraph();
|
||||||
|
|
||||||
compileJasmin(srcProg.toString());
|
compileJasmin(srcProg.toString());
|
||||||
assertThat(executeCompiledProgram()).isEqualTo(result);
|
assertThat(executeCompiledProgram()).isEqualTo(result);
|
||||||
@ -303,7 +303,7 @@ class SourceGraphGeneratorTest {
|
|||||||
final AST tree = lexParseProgram(program);
|
final AST tree = lexParseProgram(program);
|
||||||
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
||||||
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
final SourceGraphGenerator gen = SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
||||||
final SourceGraph srcProg = gen.generateCode();
|
final SourceGraph srcProg = gen.generateGraph();
|
||||||
|
|
||||||
compileJasmin(srcProg.toString());
|
compileJasmin(srcProg.toString());
|
||||||
assertThat(executeCompiledProgram()).isEqualTo(result);
|
assertThat(executeCompiledProgram()).isEqualTo(result);
|
||||||
|
Reference in New Issue
Block a user