renaming and FlowGraph Update

This commit is contained in:
ChUrl
2021-01-29 21:53:27 +01:00
parent eac739d07c
commit 6ae06c9f63
7 changed files with 264 additions and 62 deletions

View File

@ -0,0 +1,171 @@
package codegen.flowgraph;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
public class FlowBasicBlock {
private final String id;
private final String label;
private final List<FlowInstruction> instructions;
private final Set<FlowBasicBlock> predecessors;
private final Set<FlowBasicBlock> successors;
private int instNr;
public FlowBasicBlock(String label) {
this.label = label;
this.id = String.valueOf(System.nanoTime());
this.instructions = new ArrayList<>();
this.predecessors = new HashSet<>();
this.successors = new HashSet<>();
}
public FlowBasicBlock() {
this("");
}
public boolean isEmpty() {
return this.label.isBlank() && this.instructions.isEmpty();
}
public String getId() {
return this.id;
}
public String getLabel() {
return this.label;
}
public void addInstruction(String instruction, String... args) {
this.instNr++;
this.instructions.add(new FlowInstruction(String.valueOf(Long.parseLong(this.id) + this.instNr), this.id,
instruction, args));
}
public List<FlowInstruction> getInstructions() {
return this.instructions;
}
public void addSuccessor(FlowBasicBlock block) {
this.successors.add(block);
}
public void addSuccessors(Set<FlowBasicBlock> successors) {
this.successors.addAll(successors);
}
public void addPredecessor(FlowBasicBlock block) {
this.predecessors.add(block);
}
public void addPredecessors(Set<FlowBasicBlock> predecessors) {
this.predecessors.addAll(predecessors);
}
public Set<FlowBasicBlock> getSuccessorSet() {
return this.successors;
}
public Set<FlowInstruction> getPredecessors(FlowInstruction inst) {
final int index = this.instructions.indexOf(inst);
if (index == -1) {
return null;
}
if (index > 0 && index <= this.instructions.size() - 1) {
// Instruction is in the middle or end
return Set.of(this.instructions.get(index - 1));
}
// Instruction is at the beginning
return this.predecessors.stream()
.map(FlowBasicBlock::getLastInst)
.filter(Objects::nonNull)
.collect(Collectors.toUnmodifiableSet());
}
public Set<FlowInstruction> getSuccessors(FlowInstruction inst) {
final int index = this.instructions.indexOf(inst);
if (index == -1) {
return null;
}
if (index >= 0 && index < this.instructions.size() - 1) {
// Instruction is in the beginning or middle
return Set.of(this.instructions.get(index + 1));
}
// Instruction is at the end
return this.successors.stream()
.map(FlowBasicBlock::getFirstInst)
.filter(Objects::nonNull)
.collect(Collectors.toUnmodifiableSet());
}
public Set<FlowBasicBlock> getPredecessorSet() {
return this.predecessors;
}
public FlowInstruction getFirstInst() {
if (!this.instructions.isEmpty()) {
return this.instructions.get(0);
}
return null;
}
public FlowInstruction getLastInst() {
if (!this.instructions.isEmpty()) {
return this.instructions.get(this.instructions.size() - 1);
}
return null;
}
// Print + Overrides
public String printInst() {
return this.instructions.stream()
.map(inst -> inst.toString().trim() + "\\n")
.map(inst -> inst.replace("\"", "\\\""))
.collect(Collectors.joining());
}
@Override
public int hashCode() {
return Objects.hash(this.id);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FlowBasicBlock) {
return this.id.equals(((FlowBasicBlock) obj).id);
}
return false;
}
@Override
public String toString() {
final String linesString = this.instructions.stream()
.map(FlowInstruction::toString)
.map(line -> line + "\n")
.collect(Collectors.joining());
if (this.label.isBlank()) {
return linesString;
}
return this.label + ":\n"
+ linesString;
}
}

View File

@ -1,4 +1,4 @@
package codegen.sourcegraph; package codegen.flowgraph;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@ -10,25 +10,25 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class SourceGraph { public class FlowGraph {
private final SourceGraphHead head; private final FlowGraphHead head;
private final List<SourceBlock> blocks; private final List<FlowBasicBlock> blocks;
private final SourceGraphTail tail; private final FlowGraphTail tail;
// If a new block has this label, the value in this map is a predecessor // If a new block has this label, the value in this map is a predecessor
private final Map<String, SourceBlock> predecessorMap; private final Map<String, FlowBasicBlock> predecessorMap;
public SourceGraph(String bytecodeVersion, String source, String clazz, int stackSize, int localCount) { public FlowGraph(String bytecodeVersion, String source, String clazz, int stackSize, int localCount) {
this.head = new SourceGraphHead(bytecodeVersion, source, clazz, stackSize, localCount); this.head = new FlowGraphHead(bytecodeVersion, source, clazz, stackSize, localCount);
this.blocks = new ArrayList<>(); this.blocks = new ArrayList<>();
this.tail = new SourceGraphTail(); this.tail = new FlowGraphTail();
this.predecessorMap = new HashMap<>(); this.predecessorMap = new HashMap<>();
} }
// Label marks beginning of block // Label marks beginning of block
public void addLabel(String label) { public void addLabel(String label) {
final SourceBlock newBlock = new SourceBlock(label); final FlowBasicBlock newBlock = new FlowBasicBlock(label);
// Resolve missing successors/predecessors from jumps // Resolve missing successors/predecessors from jumps
@ -39,34 +39,37 @@ public class SourceGraph {
// this.predecessorMap.remove(label); // Problematic if multiple gotos to same label // this.predecessorMap.remove(label); // Problematic if multiple gotos to same label
} }
/*
TODO: Hier ist ein Bug, welcher im Datenflussgraph zu gotos mit 2 successors führt
if (this.getCurrentBlock().isEmpty()) { if (this.getCurrentBlock().isEmpty()) {
// Replace empty blocks, we don't need them // Replace empty blocks, we don't need them
if (this.blocks.size() >= 2) { if (this.blocks.size() >= 2) {
// This empty blocks successors become the previous blocks successors after replacment // This empty blocks successors become the previous blocks successors after replacment
this.blocks.get(this.blocks.size() - 2).addSuccessors(this.getCurrentBlock().getSuccessors()); this.blocks.get(this.blocks.size() - 2).addSuccessors(this.getCurrentBlock().getSuccessorSet());
} }
// Previous blocks predecessors are also the new blocks predecessors // Previous blocks predecessors are also the new blocks predecessors
newBlock.addPredecessors(this.getCurrentBlock().getPredecessors()); newBlock.addPredecessors(this.getCurrentBlock().getPredecessorSet());
this.blocks.set(this.blocks.size() - 1, newBlock); // Replace this.blocks.set(this.blocks.size() - 1, newBlock); // Replace
} else { } else {
*/
// Append block if last one isn't empty // Append block if last one isn't empty
newBlock.addPredecessor(this.getCurrentBlock()); // Obvious predecessor of new block newBlock.addPredecessor(this.getCurrentBlock()); // Obvious predecessor of new block
this.getCurrentBlock().addSuccessor(newBlock); // Obvious successor of current block this.getCurrentBlock().addSuccessor(newBlock); // Obvious successor of current block
this.blocks.add(newBlock); this.blocks.add(newBlock);
} // }
} }
// Jump means end of block // Jump means end of block
public void addJump(String jumpInstruction, String label) { public void addJump(String jumpInstruction, String label) {
this.addInst(jumpInstruction, label); this.addInst(jumpInstruction, label);
final SourceBlock newBlock = new SourceBlock(); final FlowBasicBlock newBlock = new FlowBasicBlock();
newBlock.addPredecessor(this.getCurrentBlock()); // Obvious predecessor of new block newBlock.addPredecessor(this.getCurrentBlock()); // Obvious predecessor of new block
if (!"goto".equals(jumpInstruction)) { if (!"goto".equals(jumpInstruction)) {
@ -76,7 +79,7 @@ public class SourceGraph {
} }
// Jumped successor // Jumped successor
final SourceBlock labelBlock = this.getBlockByLabel(label); final FlowBasicBlock labelBlock = this.getBlockByLabel(label);
if (labelBlock != null) { if (labelBlock != null) {
// Successor exists // Successor exists
@ -93,15 +96,15 @@ public class SourceGraph {
public void addInst(String instruction, String... args) { public void addInst(String instruction, String... args) {
if (this.blocks.isEmpty()) { if (this.blocks.isEmpty()) {
this.blocks.add(new SourceBlock()); // First block doesn't exist this.blocks.add(new FlowBasicBlock()); // First block doesn't exist
} }
this.getCurrentBlock().addLine(instruction, args); // Add to last block this.getCurrentBlock().addInstruction(instruction, args); // Add to last block
} }
public String print() { public String print() {
final String blocksString = this.blocks.stream() final String blocksString = this.blocks.stream()
.map(SourceBlock::toString) .map(FlowBasicBlock::toString)
.map(string -> string + "-".repeat(50) + "\n") .map(string -> string + "-".repeat(50) + "\n")
.collect(Collectors.joining()); .collect(Collectors.joining());
@ -116,9 +119,11 @@ public class SourceGraph {
dot.append("digraph dfd {\n") dot.append("digraph dfd {\n")
.append("node[shape=Mrecord]\n"); .append("node[shape=Mrecord]\n");
for (SourceBlock block : this.blocks) { for (FlowBasicBlock block : this.blocks) {
dot.append(block.getId()) dot.append(block.getId())
.append(" [label=\"{<f0> ") .append(" [label=\"{<f0> ")
.append(this.blocks.indexOf(block))
.append(": ")
.append(block.getLabel()) .append(block.getLabel())
.append("|<f1> ") .append("|<f1> ")
.append(block.printInst()) .append(block.printInst())
@ -131,8 +136,8 @@ public class SourceGraph {
dot.append("START -> ").append(this.blocks.get(0).getId()).append(";\n"); dot.append("START -> ").append(this.blocks.get(0).getId()).append(";\n");
dot.append(this.getCurrentBlock().getId()).append(" -> END;\n"); dot.append(this.getCurrentBlock().getId()).append(" -> END;\n");
for (SourceBlock block : this.blocks) { for (FlowBasicBlock block : this.blocks) {
for (SourceBlock succ : block.getSuccessors()) { for (FlowBasicBlock succ : block.getSuccessorSet()) {
dot.append(block.getId()).append(" -> ").append(succ.getId()).append(";\n"); dot.append(block.getId()).append(" -> ").append(succ.getId()).append(";\n");
} }
} }
@ -141,14 +146,14 @@ public class SourceGraph {
final String dotOut = dot.toString(); final String dotOut = dot.toString();
final Path dotFile = Paths.get(System.getProperty("user.dir") + "/DotOut.dot"); final Path dotFile = Paths.get(System.getProperty("user.dir") + "/FlowGraph.dot");
try { try {
Files.writeString(dotFile, dotOut); Files.writeString(dotFile, dotOut);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
final ProcessBuilder dotCompile = new ProcessBuilder("dot", "-Tsvg", "-O", "DotOut.dot"); final ProcessBuilder dotCompile = new ProcessBuilder("dot", "-Tsvg", "-oFlowGraph.svg", "FlowGraph.dot");
try { try {
dotCompile.start(); dotCompile.start();
} catch (IOException e) { } catch (IOException e) {
@ -161,7 +166,7 @@ public class SourceGraph {
@Override @Override
public String toString() { public String toString() {
final String blocksString = this.blocks.stream() final String blocksString = this.blocks.stream()
.map(SourceBlock::toString) .map(FlowBasicBlock::toString)
.collect(Collectors.joining()); .collect(Collectors.joining());
return this.head return this.head
@ -169,14 +174,25 @@ public class SourceGraph {
+ this.tail; + this.tail;
} }
private SourceBlock getBlockByLabel(String label) { private FlowBasicBlock getBlockByLabel(String label) {
return this.blocks.stream() return this.blocks.stream()
.filter(block -> block.getLabel().equals(label)) .filter(block -> block.getLabel().equals(label))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
} }
private SourceBlock getCurrentBlock() { private FlowBasicBlock getCurrentBlock() {
return this.blocks.get(this.blocks.size() - 1); return this.blocks.get(this.blocks.size() - 1);
} }
public List<FlowBasicBlock> getBlocks() {
return this.blocks;
}
public FlowBasicBlock getBlockById(String id) {
return this.blocks.stream()
.filter(block -> block.getId().equals(id))
.findFirst()
.orElse(null);
}
} }

View File

@ -1,4 +1,4 @@
package codegen.sourcegraph; package codegen.flowgraph;
import codegen.CodeGenerationException; import codegen.CodeGenerationException;
import codegen.analysis.StackSizeAnalyzer; import codegen.analysis.StackSizeAnalyzer;
@ -17,14 +17,14 @@ import java.util.Map;
import static java.util.Map.entry; import static java.util.Map.entry;
import static util.Logger.log; import static util.Logger.log;
public final class SourceGraphGenerator { public final class FlowGraphGenerator {
private static final Map<String, Method> methodMap; private static final Map<String, Method> methodMap;
static { static {
Map<String, Method> map; Map<String, Method> map;
try { try {
final Class<?> gen = SourceGraphGenerator.class; final Class<?> gen = FlowGraphGenerator.class;
map = Map.ofEntries( map = Map.ofEntries(
entry("cond", gen.getDeclaredMethod("condNode", ASTNode.class)), entry("cond", gen.getDeclaredMethod("condNode", ASTNode.class)),
entry("loop", gen.getDeclaredMethod("loopNode", ASTNode.class)), entry("loop", gen.getDeclaredMethod("loopNode", ASTNode.class)),
@ -47,34 +47,33 @@ public final class SourceGraphGenerator {
private final AST tree; 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 SourceGraph graph; private final FlowGraph graph;
private int labelCounter; private int labelCounter;
private SourceGraphGenerator(Map<String, Integer> varMap, AST tree, Map<ASTNode, String> nodeTypeMap, SourceGraph graph) { private FlowGraphGenerator(Map<String, Integer> varMap, AST tree, Map<ASTNode, String> nodeTypeMap, FlowGraph 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;
} }
public static SourceGraphGenerator fromAST(AST tree, Map<ASTNode, String> nodeTypeMap, String source) { public static FlowGraphGenerator fromAST(AST tree, Map<ASTNode, String> nodeTypeMap, String source) {
if (!tree.getRoot().hasChildren()) { if (!tree.getRoot().hasChildren()) {
throw new CodeGenerationException("Empty File can't be compiled"); throw new CodeGenerationException("Empty File can't be compiled");
} }
final Map<String, Integer> varMap = varMapFromAST(tree); final Map<String, Integer> varMap = initVarMap(tree);
final String bytecodeVersion = "49.0"; final String bytecodeVersion = "49.0";
final String clazz = tree.getRoot().getChildren().get(1).getValue(); final String clazz = tree.getRoot().getChildren().get(1).getValue();
final int stackSize = StackSizeAnalyzer.runStackModel(tree); final int stackSize = StackSizeAnalyzer.runStackModel(tree);
final int localCount = varMap.size() + 1; final int localCount = varMap.size() + 1;
final SourceGraph graph = new SourceGraph(bytecodeVersion, source, clazz, stackSize, localCount); final FlowGraph graph = new FlowGraph(bytecodeVersion, source, clazz, stackSize, localCount);
return new SourceGraphGenerator(varMap, tree, nodeTypeMap, graph); return new FlowGraphGenerator(varMap, tree, nodeTypeMap, graph);
} }
private static Map<String, Integer> varMapFromAST(AST tree) { private static Map<String, Integer> initVarMap(AST tree) {
final Map<String, Integer> varMap = new HashMap<>(); final Map<String, Integer> varMap = new HashMap<>();
// Assign variables to map // Assign variables to map
@ -98,7 +97,11 @@ public final class SourceGraphGenerator {
return Collections.unmodifiableMap(varMap); return Collections.unmodifiableMap(varMap);
} }
public SourceGraph generateGraph() { public Map<String, Integer> getVarMap() {
return this.varMap;
}
public FlowGraph generateGraph() {
System.out.println(" - Generating Source Graph..."); 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));

View File

@ -1,6 +1,6 @@
package codegen.sourcegraph; package codegen.flowgraph;
public class SourceGraphHead { public class FlowGraphHead {
private final String bytecodeVersion; private final String bytecodeVersion;
private final String source; private final String source;
@ -8,7 +8,7 @@ public class SourceGraphHead {
private final int stackSize; private final int stackSize;
private final int localCount; private final int localCount;
public SourceGraphHead(String bytecodeVersion, String source, String clazz, int stackSize, int localCount) { public FlowGraphHead(String bytecodeVersion, String source, String clazz, int stackSize, int localCount) {
this.bytecodeVersion = bytecodeVersion; this.bytecodeVersion = bytecodeVersion;
this.source = source; this.source = source;
this.clazz = clazz; this.clazz = clazz;

View File

@ -1,6 +1,6 @@
package codegen.sourcegraph; package codegen.flowgraph;
public class SourceGraphTail { public class FlowGraphTail {
@Override @Override
public String toString() { public String toString() {

View File

@ -1,11 +1,15 @@
package codegen.sourcegraph; package codegen.flowgraph;
public class SourceInst { public class FlowInstruction {
private final String id;
private final String blockId;
private final String instruction; private final String instruction;
private final String[] args; private final String[] args;
public SourceInst(String instruction, String... args) { public FlowInstruction(String id, String blockId, String instruction, String... args) {
this.id = id;
this.blockId = blockId;
this.instruction = instruction; this.instruction = instruction;
this.args = args; this.args = args;
} }
@ -24,4 +28,12 @@ public class SourceInst {
public String[] getArgs() { public String[] getArgs() {
return this.args; return this.args;
} }
public String getBlockId() {
return this.blockId;
}
public String getId() {
return this.id;
}
} }

View File

@ -1,7 +1,7 @@
package codegen; package codegen;
import codegen.sourcegraph.SourceGraph; import codegen.flowgraph.FlowGraph;
import codegen.sourcegraph.SourceGraphGenerator; import codegen.flowgraph.FlowGraphGenerator;
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;
@ -29,14 +29,14 @@ import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;
class SourceGraphGeneratorTest { class FlowGraphGeneratorTest {
private static StupsParser parser; private static StupsParser parser;
private static Grammar stupsGrammar; private static Grammar stupsGrammar;
@BeforeAll @BeforeAll
static void init() throws IOException, URISyntaxException { static void init() throws IOException, URISyntaxException {
final Path path = Paths.get(SourceGraphGeneratorTest.class.getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI()); final Path path = Paths.get(FlowGraphGeneratorTest.class.getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
final Grammar grammar = Grammar.fromFile(path); final Grammar grammar = Grammar.fromFile(path);
parser = StupsParser.fromGrammar(grammar); parser = StupsParser.fromGrammar(grammar);
stupsGrammar = grammar; stupsGrammar = grammar;
@ -44,7 +44,7 @@ class SourceGraphGeneratorTest {
private static String readProgram(String prog) { private static String readProgram(String prog) {
try { try {
final Path progPath = Paths.get(SourceGraphGeneratorTest.class.getClassLoader().getResource("examplePrograms/" + prog).toURI()); final Path progPath = Paths.get(FlowGraphGeneratorTest.class.getClassLoader().getResource("examplePrograms/" + prog).toURI());
return Files.readString(progPath); return Files.readString(progPath);
} catch (URISyntaxException | IOException e) { } catch (URISyntaxException | IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -242,8 +242,8 @@ 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 FlowGraphGenerator gen = FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutpu");
final SourceGraph srcProg = gen.generateGraph(); final FlowGraph srcProg = gen.generateGraph();
compileJasmin(srcProg.toString()); compileJasmin(srcProg.toString());
assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result); assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result);
@ -257,8 +257,8 @@ 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 FlowGraphGenerator gen = FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
final SourceGraph srcProg = gen.generateGraph(); final FlowGraph srcProg = gen.generateGraph();
compileJasmin(srcProg.toString()); compileJasmin(srcProg.toString());
assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result); assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result);
@ -272,8 +272,8 @@ 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 FlowGraphGenerator gen = FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
final SourceGraph srcProg = gen.generateGraph(); final FlowGraph srcProg = gen.generateGraph();
compileJasmin(srcProg.toString()); compileJasmin(srcProg.toString());
assertThat(Boolean.parseBoolean(executeCompiledProgram())).isEqualTo(result); assertThat(Boolean.parseBoolean(executeCompiledProgram())).isEqualTo(result);
@ -287,8 +287,8 @@ 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 FlowGraphGenerator gen = FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
final SourceGraph srcProg = gen.generateGraph(); final FlowGraph srcProg = gen.generateGraph();
compileJasmin(srcProg.toString()); compileJasmin(srcProg.toString());
assertThat(executeCompiledProgram()).isEqualTo(result); assertThat(executeCompiledProgram()).isEqualTo(result);
@ -302,8 +302,8 @@ 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 FlowGraphGenerator gen = FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
final SourceGraph srcProg = gen.generateGraph(); final FlowGraph srcProg = gen.generateGraph();
compileJasmin(srcProg.toString()); compileJasmin(srcProg.toString());
assertThat(executeCompiledProgram()).isEqualTo(result); assertThat(executeCompiledProgram()).isEqualTo(result);
@ -316,7 +316,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);
assertThatThrownBy(() -> SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput")) assertThatThrownBy(() -> FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutput"))
.isInstanceOf(CodeGenerationException.class); .isInstanceOf(CodeGenerationException.class);
} }
} }