renaming and FlowGraph Update
This commit is contained in:
171
src/main/java/codegen/flowgraph/FlowBasicBlock.java
Normal file
171
src/main/java/codegen/flowgraph/FlowBasicBlock.java
Normal 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;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package codegen.sourcegraph;
|
||||
package codegen.flowgraph;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@ -10,25 +10,25 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SourceGraph {
|
||||
public class FlowGraph {
|
||||
|
||||
private final SourceGraphHead head;
|
||||
private final List<SourceBlock> blocks;
|
||||
private final SourceGraphTail tail;
|
||||
private final FlowGraphHead head;
|
||||
private final List<FlowBasicBlock> blocks;
|
||||
private final FlowGraphTail tail;
|
||||
|
||||
// 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) {
|
||||
this.head = new SourceGraphHead(bytecodeVersion, source, clazz, stackSize, localCount);
|
||||
public FlowGraph(String bytecodeVersion, String source, String clazz, int stackSize, int localCount) {
|
||||
this.head = new FlowGraphHead(bytecodeVersion, source, clazz, stackSize, localCount);
|
||||
this.blocks = new ArrayList<>();
|
||||
this.tail = new SourceGraphTail();
|
||||
this.tail = new FlowGraphTail();
|
||||
this.predecessorMap = new HashMap<>();
|
||||
}
|
||||
|
||||
// Label marks beginning of block
|
||||
public void addLabel(String label) {
|
||||
final SourceBlock newBlock = new SourceBlock(label);
|
||||
final FlowBasicBlock newBlock = new FlowBasicBlock(label);
|
||||
|
||||
|
||||
// Resolve missing successors/predecessors from jumps
|
||||
@ -39,34 +39,37 @@ public class SourceGraph {
|
||||
// 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()) {
|
||||
// Replace empty blocks, we don't need them
|
||||
|
||||
if (this.blocks.size() >= 2) {
|
||||
// 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
|
||||
newBlock.addPredecessors(this.getCurrentBlock().getPredecessors());
|
||||
newBlock.addPredecessors(this.getCurrentBlock().getPredecessorSet());
|
||||
|
||||
this.blocks.set(this.blocks.size() - 1, newBlock); // Replace
|
||||
} else {
|
||||
*/
|
||||
// Append block if last one isn't empty
|
||||
|
||||
newBlock.addPredecessor(this.getCurrentBlock()); // Obvious predecessor of new block
|
||||
this.getCurrentBlock().addSuccessor(newBlock); // Obvious successor of current block
|
||||
|
||||
this.blocks.add(newBlock);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// Jump means end of block
|
||||
public void addJump(String jumpInstruction, String label) {
|
||||
this.addInst(jumpInstruction, label);
|
||||
|
||||
final SourceBlock newBlock = new SourceBlock();
|
||||
final FlowBasicBlock newBlock = new FlowBasicBlock();
|
||||
newBlock.addPredecessor(this.getCurrentBlock()); // Obvious predecessor of new block
|
||||
|
||||
if (!"goto".equals(jumpInstruction)) {
|
||||
@ -76,7 +79,7 @@ public class SourceGraph {
|
||||
}
|
||||
|
||||
// Jumped successor
|
||||
final SourceBlock labelBlock = this.getBlockByLabel(label);
|
||||
final FlowBasicBlock labelBlock = this.getBlockByLabel(label);
|
||||
if (labelBlock != null) {
|
||||
// Successor exists
|
||||
|
||||
@ -93,15 +96,15 @@ public class SourceGraph {
|
||||
|
||||
public void addInst(String instruction, String... args) {
|
||||
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() {
|
||||
final String blocksString = this.blocks.stream()
|
||||
.map(SourceBlock::toString)
|
||||
.map(FlowBasicBlock::toString)
|
||||
.map(string -> string + "-".repeat(50) + "\n")
|
||||
.collect(Collectors.joining());
|
||||
|
||||
@ -116,9 +119,11 @@ public class SourceGraph {
|
||||
dot.append("digraph dfd {\n")
|
||||
.append("node[shape=Mrecord]\n");
|
||||
|
||||
for (SourceBlock block : this.blocks) {
|
||||
for (FlowBasicBlock block : this.blocks) {
|
||||
dot.append(block.getId())
|
||||
.append(" [label=\"{<f0> ")
|
||||
.append(this.blocks.indexOf(block))
|
||||
.append(": ")
|
||||
.append(block.getLabel())
|
||||
.append("|<f1> ")
|
||||
.append(block.printInst())
|
||||
@ -131,8 +136,8 @@ public class SourceGraph {
|
||||
dot.append("START -> ").append(this.blocks.get(0).getId()).append(";\n");
|
||||
dot.append(this.getCurrentBlock().getId()).append(" -> END;\n");
|
||||
|
||||
for (SourceBlock block : this.blocks) {
|
||||
for (SourceBlock succ : block.getSuccessors()) {
|
||||
for (FlowBasicBlock block : this.blocks) {
|
||||
for (FlowBasicBlock succ : block.getSuccessorSet()) {
|
||||
dot.append(block.getId()).append(" -> ").append(succ.getId()).append(";\n");
|
||||
}
|
||||
}
|
||||
@ -141,14 +146,14 @@ public class SourceGraph {
|
||||
|
||||
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 {
|
||||
Files.writeString(dotFile, dotOut);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
final ProcessBuilder dotCompile = new ProcessBuilder("dot", "-Tsvg", "-O", "DotOut.dot");
|
||||
final ProcessBuilder dotCompile = new ProcessBuilder("dot", "-Tsvg", "-oFlowGraph.svg", "FlowGraph.dot");
|
||||
try {
|
||||
dotCompile.start();
|
||||
} catch (IOException e) {
|
||||
@ -161,7 +166,7 @@ public class SourceGraph {
|
||||
@Override
|
||||
public String toString() {
|
||||
final String blocksString = this.blocks.stream()
|
||||
.map(SourceBlock::toString)
|
||||
.map(FlowBasicBlock::toString)
|
||||
.collect(Collectors.joining());
|
||||
|
||||
return this.head
|
||||
@ -169,14 +174,25 @@ public class SourceGraph {
|
||||
+ this.tail;
|
||||
}
|
||||
|
||||
private SourceBlock getBlockByLabel(String label) {
|
||||
private FlowBasicBlock getBlockByLabel(String label) {
|
||||
return this.blocks.stream()
|
||||
.filter(block -> block.getLabel().equals(label))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private SourceBlock getCurrentBlock() {
|
||||
private FlowBasicBlock getCurrentBlock() {
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package codegen.sourcegraph;
|
||||
package codegen.flowgraph;
|
||||
|
||||
import codegen.CodeGenerationException;
|
||||
import codegen.analysis.StackSizeAnalyzer;
|
||||
@ -17,14 +17,14 @@ import java.util.Map;
|
||||
import static java.util.Map.entry;
|
||||
import static util.Logger.log;
|
||||
|
||||
public final class SourceGraphGenerator {
|
||||
public final class FlowGraphGenerator {
|
||||
|
||||
private static final Map<String, Method> methodMap;
|
||||
|
||||
static {
|
||||
Map<String, Method> map;
|
||||
try {
|
||||
final Class<?> gen = SourceGraphGenerator.class;
|
||||
final Class<?> gen = FlowGraphGenerator.class;
|
||||
map = Map.ofEntries(
|
||||
entry("cond", gen.getDeclaredMethod("condNode", ASTNode.class)),
|
||||
entry("loop", gen.getDeclaredMethod("loopNode", ASTNode.class)),
|
||||
@ -47,34 +47,33 @@ public final class SourceGraphGenerator {
|
||||
private final AST tree;
|
||||
private final Map<String, Integer> varMap;
|
||||
private final Map<ASTNode, String> nodeTypeMap;
|
||||
private final SourceGraph graph;
|
||||
|
||||
private final FlowGraph graph;
|
||||
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.tree = tree;
|
||||
this.nodeTypeMap = nodeTypeMap;
|
||||
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()) {
|
||||
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 clazz = tree.getRoot().getChildren().get(1).getValue();
|
||||
final int stackSize = StackSizeAnalyzer.runStackModel(tree);
|
||||
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<>();
|
||||
|
||||
// Assign variables to map
|
||||
@ -98,7 +97,11 @@ public final class SourceGraphGenerator {
|
||||
return Collections.unmodifiableMap(varMap);
|
||||
}
|
||||
|
||||
public SourceGraph generateGraph() {
|
||||
public Map<String, Integer> getVarMap() {
|
||||
return this.varMap;
|
||||
}
|
||||
|
||||
public FlowGraph generateGraph() {
|
||||
System.out.println(" - Generating Source Graph...");
|
||||
|
||||
this.generateNode(this.tree.getRoot().getChildren().get(3).getChildren().get(11));
|
@ -1,6 +1,6 @@
|
||||
package codegen.sourcegraph;
|
||||
package codegen.flowgraph;
|
||||
|
||||
public class SourceGraphHead {
|
||||
public class FlowGraphHead {
|
||||
|
||||
private final String bytecodeVersion;
|
||||
private final String source;
|
||||
@ -8,7 +8,7 @@ public class SourceGraphHead {
|
||||
private final int stackSize;
|
||||
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.source = source;
|
||||
this.clazz = clazz;
|
@ -1,6 +1,6 @@
|
||||
package codegen.sourcegraph;
|
||||
package codegen.flowgraph;
|
||||
|
||||
public class SourceGraphTail {
|
||||
public class FlowGraphTail {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
@ -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[] 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.args = args;
|
||||
}
|
||||
@ -24,4 +28,12 @@ public class SourceInst {
|
||||
public String[] getArgs() {
|
||||
return this.args;
|
||||
}
|
||||
|
||||
public String getBlockId() {
|
||||
return this.blockId;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package codegen;
|
||||
|
||||
import codegen.sourcegraph.SourceGraph;
|
||||
import codegen.sourcegraph.SourceGraphGenerator;
|
||||
import codegen.flowgraph.FlowGraph;
|
||||
import codegen.flowgraph.FlowGraphGenerator;
|
||||
import lexer.StupsLexer;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
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.assertThatThrownBy;
|
||||
|
||||
class SourceGraphGeneratorTest {
|
||||
class FlowGraphGeneratorTest {
|
||||
|
||||
private static StupsParser parser;
|
||||
private static Grammar stupsGrammar;
|
||||
|
||||
@BeforeAll
|
||||
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);
|
||||
parser = StupsParser.fromGrammar(grammar);
|
||||
stupsGrammar = grammar;
|
||||
@ -44,7 +44,7 @@ class SourceGraphGeneratorTest {
|
||||
|
||||
private static String readProgram(String prog) {
|
||||
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);
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -242,8 +242,8 @@ 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.generateGraph();
|
||||
final FlowGraphGenerator gen = FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutpu");
|
||||
final FlowGraph srcProg = gen.generateGraph();
|
||||
|
||||
compileJasmin(srcProg.toString());
|
||||
assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result);
|
||||
@ -257,8 +257,8 @@ 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.generateGraph();
|
||||
final FlowGraphGenerator gen = FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
||||
final FlowGraph srcProg = gen.generateGraph();
|
||||
|
||||
compileJasmin(srcProg.toString());
|
||||
assertThat(Integer.parseInt(executeCompiledProgram())).isEqualTo(result);
|
||||
@ -272,8 +272,8 @@ 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.generateGraph();
|
||||
final FlowGraphGenerator gen = FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
||||
final FlowGraph srcProg = gen.generateGraph();
|
||||
|
||||
compileJasmin(srcProg.toString());
|
||||
assertThat(Boolean.parseBoolean(executeCompiledProgram())).isEqualTo(result);
|
||||
@ -287,8 +287,8 @@ 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.generateGraph();
|
||||
final FlowGraphGenerator gen = FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
||||
final FlowGraph srcProg = gen.generateGraph();
|
||||
|
||||
compileJasmin(srcProg.toString());
|
||||
assertThat(executeCompiledProgram()).isEqualTo(result);
|
||||
@ -302,8 +302,8 @@ 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.generateGraph();
|
||||
final FlowGraphGenerator gen = FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutput");
|
||||
final FlowGraph srcProg = gen.generateGraph();
|
||||
|
||||
compileJasmin(srcProg.toString());
|
||||
assertThat(executeCompiledProgram()).isEqualTo(result);
|
||||
@ -316,7 +316,7 @@ class SourceGraphGeneratorTest {
|
||||
final AST tree = lexParseProgram(program);
|
||||
final Map<ASTNode, String> nodeTable = TypeChecker.validate(tree);
|
||||
|
||||
assertThatThrownBy(() -> SourceGraphGenerator.fromAST(tree, nodeTable, "TestOutput"))
|
||||
assertThatThrownBy(() -> FlowGraphGenerator.fromAST(tree, nodeTable, "TestOutput"))
|
||||
.isInstanceOf(CodeGenerationException.class);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user