From d8f5142e5e94bc4e6c23df29d299f5dbd7896346 Mon Sep 17 00:00:00 2001 From: ChUrl Date: Sun, 31 Jan 2021 18:11:56 +0100 Subject: [PATCH] cleanup --- src/main/java/StupsCompiler.java | 10 +++- .../codegen/flowgraph/FlowGraphGenerator.java | 59 +++++++++++++------ src/main/java/parser/ast/AST.java | 6 ++ src/main/java/parser/ast/ASTNode.java | 4 ++ 4 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/main/java/StupsCompiler.java b/src/main/java/StupsCompiler.java index 50d0eec..e2954f2 100644 --- a/src/main/java/StupsCompiler.java +++ b/src/main/java/StupsCompiler.java @@ -10,6 +10,7 @@ import parser.ast.AST; import parser.ast.ASTNode; import parser.grammar.Grammar; import typechecker.TypeChecker; +import util.Logger; import java.io.IOException; import java.nio.file.Files; @@ -44,6 +45,8 @@ public final class StupsCompiler { final FlowGraphGenerator gen = getFlowGraphGen(filename); final FlowGraph graph = gen.generateGraph(); + Logger.call(graph::printToImage); + // Codegeneration + Output final String outputName = filename.replaceFirst("\\.stups", ".j"); final String sourceCode = graph.toString(); @@ -73,7 +76,12 @@ public final class StupsCompiler { final FlowGraphGenerator gen = getFlowGraphGen(filename); final FlowGraph graph = gen.generateGraph(); - final DataFlowGraph dataFlowGraph = DataFlowGraph.fromSourceGraph(graph); + + Logger.call(graph::printToImage); + + final DataFlowGraph dataFlowGraph = DataFlowGraph.fromFlowGraph(graph); + + Logger.call(dataFlowGraph::printToImage); final LivenessAnalysis liveness = LivenessAnalysis.fromDataFlowGraph(dataFlowGraph, gen.getVarMap()); liveness.doLivenessAnalysis(); diff --git a/src/main/java/codegen/flowgraph/FlowGraphGenerator.java b/src/main/java/codegen/flowgraph/FlowGraphGenerator.java index 9e03f2a..7784417 100644 --- a/src/main/java/codegen/flowgraph/FlowGraphGenerator.java +++ b/src/main/java/codegen/flowgraph/FlowGraphGenerator.java @@ -4,7 +4,7 @@ import codegen.CodeGenerationException; import codegen.analysis.StackSizeAnalyzer; import parser.ast.AST; import parser.ast.ASTNode; -import util.Logger; +import typechecker.TypeChecker; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -22,6 +22,9 @@ import static util.Logger.log; */ public final class FlowGraphGenerator { + /** + * Mappt die {@link ASTNode}-Namen auf entsprechende Methoden für die Codeerzeugung. + */ private static final Map methodMap; static { @@ -49,9 +52,20 @@ public final class FlowGraphGenerator { } private final AST tree; - private final Map varMap; + + /** + * Enthält den Rückgabetypen von jedem Expression-Node. + * Wird erstellt im {@link TypeChecker}. + */ private final Map nodeTypeMap; + + /** + * Enthält die Mappings vom Symbol/Variablennamen auf die Position in der JVM-Locals-Tabelle. + */ + private final Map varMap; + private final FlowGraph graph; + private int labelCounter; private FlowGraphGenerator(Map varMap, AST tree, Map nodeTypeMap, FlowGraph graph) { @@ -61,18 +75,16 @@ public final class FlowGraphGenerator { this.graph = graph; } + /** + * @param source Das Source-File, welches compiliert wird (Optionaler Jasmin-Parameter) + */ public static FlowGraphGenerator fromAST(AST tree, Map nodeTypeMap, String source) { - if (!tree.getRoot().hasChildren()) { + if (tree.isEmpty()) { throw new CodeGenerationException("Empty File can't be compiled"); } final Map varMap = initVarMap(tree); - - final String bytecodeVersion = "49.0"; - final String clazz = tree.getRoot().getChildren().get(1).getValue(); - final int stackSize = StackSizeAnalyzer.runStackModel(tree); - final int localCount = varMap.size() + 1; - final FlowGraph graph = new FlowGraph(bytecodeVersion, source, clazz, stackSize, localCount); + final FlowGraph graph = initFlowGraph(tree, varMap, source); return new FlowGraphGenerator(varMap, tree, nodeTypeMap, graph); } @@ -80,19 +92,23 @@ public final class FlowGraphGenerator { private static Map initVarMap(AST tree) { final Map varMap = new HashMap<>(); - // Assign variables to map: Symbol -> jasminLocalVarNr. - int varCount = 0; final Deque stack = new ArrayDeque<>(); stack.push(tree.getRoot()); + + int currentVarNumber = 0; + + // Assign variables to map: Symbol -> jasminLocalVarNr. while (!stack.isEmpty()) { final ASTNode current = stack.pop(); if ("declaration".equals(current.getName())) { - varCount++; - varMap.put(current.getChildren().get(0).getValue(), varCount); + // New variables only come from declarations + + currentVarNumber++; + varMap.put(current.getChildren().get(0).getValue(), currentVarNumber); log("New local " + current.getValue() + " variable " + current.getChildren().get(0).getValue() - + " assigned to slot " + varCount + "."); + + " assigned to slot " + currentVarNumber + "."); } current.getChildren().forEach(stack::push); @@ -101,6 +117,15 @@ public final class FlowGraphGenerator { return Collections.unmodifiableMap(varMap); } + private static FlowGraph initFlowGraph(AST tree, Map varMap, String source) { + final String bytecodeVersion = "49.0"; + final String clazz = tree.getRoot().getChildren().get(1).getValue(); + final int stackSize = StackSizeAnalyzer.runStackModel(tree); + final int localCount = varMap.size() + 1; + + return new FlowGraph(bytecodeVersion, source, clazz, stackSize, localCount); + } + /** * Erzeugt den Flussgraphen für den gespeicherten AST. * Der Flussgraph ist dabei die Graphenform des generierten SourceCodes: @@ -112,9 +137,8 @@ public final class FlowGraphGenerator { // Skip the first 2 identifiers: ClassName, MainArgs this.generateNode(this.tree.getRoot().getChildren().get(3).getChildren().get(11)); this.graph.purgeEmptyBlocks(); - Logger.call(this.graph::printToImage); - log("\n\nSourceGraph print:\n" + "-".repeat(100) + "\n" + this.graph.print() + "-".repeat(100)); + log("\n\nSourceGraph print:\n" + "-".repeat(100) + "\n" + this.graph + "-".repeat(100)); System.out.println("Graph-generation successful."); return this.graph; @@ -137,9 +161,6 @@ public final class FlowGraphGenerator { } } - // ifeq - if value is 0 - // ifne - if value is not 0 - /** * Erzeugt den Teilbaum für einen If-Knoten. */ diff --git a/src/main/java/parser/ast/AST.java b/src/main/java/parser/ast/AST.java index 71a62a7..2a453fa 100644 --- a/src/main/java/parser/ast/AST.java +++ b/src/main/java/parser/ast/AST.java @@ -20,6 +20,10 @@ public class AST { return this.root.size(); } + public boolean isEmpty() { + return this.root.isEmpty(); + } + public void postprocess(Grammar grammar) { ASTCompacter.clean(this, grammar); ASTBalancer.balance(this); @@ -30,6 +34,8 @@ public class AST { return new AST(this.root.deepCopy()); } + // Overrides + @Override public boolean equals(Object obj) { if (obj instanceof AST) { diff --git a/src/main/java/parser/ast/ASTNode.java b/src/main/java/parser/ast/ASTNode.java index 0398468..12b600c 100644 --- a/src/main/java/parser/ast/ASTNode.java +++ b/src/main/java/parser/ast/ASTNode.java @@ -119,4 +119,8 @@ public class ASTNode { return newNode; } + + public boolean isEmpty() { + return this.children.isEmpty(); + } }