Skip to content

Commit

Permalink
Fixing bug in TranspilerNode creation inside IF-THEN clauses, since s…
Browse files Browse the repository at this point in the history
…tatements are no longer wrapped in ConditionalStatementContext objects
  • Loading branch information
avishek-sen-gupta committed Nov 16, 2024
1 parent 5769acb commit 856c4e3
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public String description() {
return String.format("if(%s) %n then %n{%n %s %n}%n %nelse %n{%n %s %n}%n", condition.description(), ifThenBlock.description(), ifElseBlock.description());
}

@Override
public List<TranspilerNode> astChildren() {
return super.astChildren();
}

@Override
public Collection<TranspilerNode> internalElements() {
return ImmutableList.of(condition, ifThenBlock, ifElseBlock);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
import java.util.stream.Stream;

public class CallRangesTask {
private final TranspilerCodeBlockNode tree;
private final TranspilerNode tree;
private final List<TranspilerInstruction> instructions;

public CallRangesTask(TranspilerCodeBlockNode tree, List<TranspilerInstruction> instructions) {
public CallRangesTask(TranspilerNode tree, List<TranspilerInstruction> instructions) {
this.tree = tree;
this.instructions = instructions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
import java.util.stream.Collectors;

public class ProcedureBodyTask {
private final TranspilerCodeBlockNode program;
private final TranspilerNode program;
private final List<TranspilerInstruction> instructions;
private final Graph<TranspilerInstruction, DefaultEdge> instructionFlowgraph;

public ProcedureBodyTask(TranspilerCodeBlockNode program, List<TranspilerInstruction> instructions, Graph<TranspilerInstruction, DefaultEdge> instructionFlowgraph) {
public ProcedureBodyTask(TranspilerNode program, List<TranspilerInstruction> instructions, Graph<TranspilerInstruction, DefaultEdge> instructionFlowgraph) {
this.program = program;
this.instructions = instructions;
this.instructionFlowgraph = instructionFlowgraph;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.smojol.toolkit.examples;

import com.google.common.collect.ImmutableList;
import org.apache.commons.lang3.tuple.Pair;
import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultEdge;
import org.smojol.common.dialect.LanguageDialect;
import org.smojol.common.flowchart.FlowchartOutputFormat;
import org.smojol.common.id.IncrementingIdProvider;
import org.smojol.common.id.UUIDProvider;
import org.smojol.common.pseudocode.BasicBlock;
import org.smojol.common.resource.LocalFilesystemOperations;
import org.smojol.common.transpiler.*;
import org.smojol.toolkit.analysis.pipeline.ProgramSearch;
import org.smojol.toolkit.analysis.task.analysis.CodeTaskRunner;
import org.smojol.toolkit.analysis.task.transpiler.BuildTranspilerInstructionsFromIntermediateTreeTask;
import org.smojol.toolkit.analysis.task.transpiler.ProcedureBodyTask;
import org.smojol.toolkit.interpreter.FullProgram;
import org.smojol.toolkit.interpreter.structure.OccursIgnoringFormat1DataStructureBuilder;
import org.smojol.toolkit.task.AnalysisTaskResult;
import org.smojol.toolkit.task.AnalysisTaskResultOK;
import org.smojol.toolkit.task.CommandLineAnalysisTask;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.smojol.toolkit.task.CommandLineAnalysisTask.*;

public class SLIFORangeMain {
public static void main(String[] args) throws IOException, InterruptedException {
String programName = "actually-reducible-but-bug-perform.cbl";
UUIDProvider idProvider = new UUIDProvider();
Map<String, List<AnalysisTaskResult>> result = new CodeTaskRunner("/Users/asgupta/code/smojol/smojol-test-code",
"/Users/asgupta/code/smojol/out/report",
ImmutableList.of(new File("/Users/asgupta/code/smojol/smojol-test-code")),
"/Users/asgupta/code/smojol/che-che4z-lsp-for-cobol-integration/server/dialect-idms/target/dialect-idms.jar",
LanguageDialect.IDMS, new FullProgram(FlowchartOutputFormat.MERMAID, idProvider), idProvider, new OccursIgnoringFormat1DataStructureBuilder(), new ProgramSearch(), new LocalFilesystemOperations())
.runForPrograms(ImmutableList.of(BUILD_BASE_ANALYSIS, CommandLineAnalysisTask.BUILD_TRANSPILER_FLOWGRAPH), ImmutableList.of(programName));
List<AnalysisTaskResult> results = result.get(programName);
TranspilerFlowgraph transpilerFlowgraph = ((AnalysisTaskResultOK) results.get(1)).getDetail();
TranspilerNode tree = transpilerFlowgraph.transpilerTree();
List<TranspilerInstruction> instructions = new BuildTranspilerInstructionsFromIntermediateTreeTask(tree, new IncrementingIdProvider()).run();
Graph<TranspilerInstruction, DefaultEdge> implicitCFG = new BuildImplicitInstructionControlFlowgraphTask(instructions, ImmutableList.of()).run();
Set<Pair<ProcedureRange, Set<ProcedureRange>>> rangesWithChildren = new ProcedureBodyTask(tree, instructions, implicitCFG).run();
SLIFORangeCriterionTask task = new SLIFORangeCriterionTask(rangesWithChildren);
Set<Pair<ProcedureRange, Set<ProcedureRange>>> allSLIFORanges = task.allSLIFORanges(rangesWithChildren);

System.out.println("DONE");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static TranspilerNode build(IfFlowNode n, CobolDataStructure dataStructur
CobolExpression condition = n.getConditionExpression();
TranspilerExpressionBuilder nodeBuilder = new TranspilerExpressionBuilder(dataStructures);
TranspilerNode transpilerCondition = nodeBuilder.build(condition);
TranspilerCodeBlockNode ifThenBlock = new DetachedTranspilerCodeBlockNode(n.getIfThenBlock().astChildren().stream().filter(c -> c instanceof ConditionalStatementFlowNode).map(stmt -> TranspilerTreeBuilder.flowToTranspiler(stmt, dataStructures)).toList());
TranspilerCodeBlockNode ifThenBlock = new DetachedTranspilerCodeBlockNode(n.getIfThenBlock().astChildren().stream().map(stmt -> TranspilerTreeBuilder.flowToTranspiler(stmt, dataStructures)).toList());
TranspilerCodeBlockNode ifElseBlock = n.getIfElseBlock() != null ? new DetachedTranspilerCodeBlockNode(n.getIfElseBlock().astChildren().stream().filter(c -> c instanceof ConditionalStatementFlowNode).map(stmt -> TranspilerTreeBuilder.flowToTranspiler(stmt, dataStructures)).toList()) : new TranspilerCodeBlockNode();
return new IfTranspilerNode(transpilerCondition, ifThenBlock, ifElseBlock);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,79 +88,6 @@ public void canCalculateRangeBodyGivenRanges() {
assertEquals(ImmutableSet.of(range21, range33), range33WithChildren.getRight());
}

@Test
public void canDetermineSLIFORangeBaseCase() {
JumpTranspilerNode jump_B1 = new JumpTranspilerNode(new NamedLocationNode("B1"), new NamedLocationNode("B1"));
LabelledTranspilerCodeBlockNode a1 = new LabelledTranspilerCodeBlockNode("A1", ImmutableList.of(p(), p(), jump_B1, new JumpTranspilerNode(new ProgramTerminalLocationNode())), ImmutableMap.of());
LabelledTranspilerCodeBlockNode b1 = new LabelledTranspilerCodeBlockNode("B1", ImmutableList.of(p(), p()), ImmutableMap.of());
LabelledTranspilerCodeBlockNode c1 = new LabelledTranspilerCodeBlockNode("C1", ImmutableList.of(p(), p()), ImmutableMap.of());
TranspilerCodeBlockNode program = new TranspilerCodeBlockNode(ImmutableList.of(a1, b1, c1));
block_(
labelledBlock_(
print_(),
print_(),
jump_(),
jump_()
),
labelledBlock_(
print_(),
print_()
),
labelledBlock_(
print_(),
print_()
)
).verify(program);

List<TranspilerInstruction> instructions = new BuildTranspilerInstructionsFromIntermediateTreeTask(program, new IncrementingIdProvider()).run();
Graph<TranspilerInstruction, DefaultEdge> implicitCFG = new BuildImplicitInstructionControlFlowgraphTask(instructions, ImmutableList.of()).run();

Set<Pair<ProcedureRange, Set<ProcedureRange>>> rangesWithChildren = new ProcedureBodyTask(program, instructions, implicitCFG).run();
SLIFORangeCriterionTask slifoRangeCriterionTask = new SLIFORangeCriterionTask(rangesWithChildren);
assertEquals(1, rangesWithChildren.size());
Pair<ProcedureRange, Set<ProcedureRange>> rangeWithChildren = rangesWithChildren.stream().findFirst().get();
ProcedureRange range = rangeWithChildren.getLeft();
Set<ProcedureRange> rangesTerminatingInRange = slifoRangeCriterionTask.rangesTerminatingIn(range);
assertEquals(ImmutableSet.of(), rangesTerminatingInRange);
assertEquals(ImmutableSet.of(), rangeWithChildren.getRight());
assertTrue(slifoRangeCriterionTask.isSLIFO(rangeWithChildren, ImmutableSet.of()));
}

@Test
public void canDetermineSLIFORangesInductively() {
JumpTranspilerNode jump_B1 = new JumpTranspilerNode(new NamedLocationNode("B1"), new NamedLocationNode("B1"));
JumpTranspilerNode jump_C1 = new JumpTranspilerNode(new NamedLocationNode("C1"), new NamedLocationNode("C1"));
LabelledTranspilerCodeBlockNode a1 = new LabelledTranspilerCodeBlockNode("A1", ImmutableList.of(p(), p(), jump_B1, new JumpTranspilerNode(new ProgramTerminalLocationNode())), ImmutableMap.of());
LabelledTranspilerCodeBlockNode b1 = new LabelledTranspilerCodeBlockNode("B1", ImmutableList.of(p(), p(), jump_C1), ImmutableMap.of());
LabelledTranspilerCodeBlockNode c1 = new LabelledTranspilerCodeBlockNode("C1", ImmutableList.of(p(), p()), ImmutableMap.of());
TranspilerCodeBlockNode program = new TranspilerCodeBlockNode(ImmutableList.of(a1, b1, c1));
block_(
labelledBlock_(
print_(),
print_(),
jump_(),
jump_()
),
labelledBlock_(
print_(),
print_(),
jump_()
),
labelledBlock_(
print_(),
print_()
)
).verify(program);

List<TranspilerInstruction> instructions = new BuildTranspilerInstructionsFromIntermediateTreeTask(program, new IncrementingIdProvider()).run();
Graph<TranspilerInstruction, DefaultEdge> implicitCFG = new BuildImplicitInstructionControlFlowgraphTask(instructions, ImmutableList.of()).run();
Set<Pair<ProcedureRange, Set<ProcedureRange>>> rangesWithChildren = new ProcedureBodyTask(program, instructions, implicitCFG).run();
SLIFORangeCriterionTask task = new SLIFORangeCriterionTask(rangesWithChildren);
assertEquals(2, rangesWithChildren.size());
Set<Pair<ProcedureRange, Set<ProcedureRange>>> allSLIFORanges = task.allSLIFORanges(rangesWithChildren);
assertEquals(2, allSLIFORanges.size());
}

private static PrintTranspilerNode p() {
return new PrintTranspilerNode(ImmutableList.of());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package org.smojol.toolkit.analysis.task;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.tuple.Pair;
import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultEdge;
import org.junit.jupiter.api.Test;
import org.smojol.common.id.IncrementingIdProvider;
import org.smojol.common.transpiler.*;
import org.smojol.toolkit.analysis.task.transpiler.BuildTranspilerInstructionsFromIntermediateTreeTask;
import org.smojol.toolkit.analysis.task.transpiler.ProcedureBodyTask;
import org.smojol.toolkit.analysis.task.transpiler.RangeBodyTask;

import java.util.List;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.smojol.common.transpiler.TreeMatcher.*;

public class SLIFORangeTaskTest {
@Test
public void canDetermineSLIFORangeBaseCase() {
JumpTranspilerNode jump_B1 = new JumpTranspilerNode(new NamedLocationNode("B1"), new NamedLocationNode("B1"));
LabelledTranspilerCodeBlockNode a1 = new LabelledTranspilerCodeBlockNode("A1", ImmutableList.of(p(), p(), jump_B1, new JumpTranspilerNode(new ProgramTerminalLocationNode())), ImmutableMap.of());
LabelledTranspilerCodeBlockNode b1 = new LabelledTranspilerCodeBlockNode("B1", ImmutableList.of(p(), p()), ImmutableMap.of());
LabelledTranspilerCodeBlockNode c1 = new LabelledTranspilerCodeBlockNode("C1", ImmutableList.of(p(), p()), ImmutableMap.of());
TranspilerCodeBlockNode program = new TranspilerCodeBlockNode(ImmutableList.of(a1, b1, c1));
block_(
labelledBlock_(
print_(),
print_(),
jump_(),
jump_()
),
labelledBlock_(
print_(),
print_()
),
labelledBlock_(
print_(),
print_()
)
).verify(program);

List<TranspilerInstruction> instructions = new BuildTranspilerInstructionsFromIntermediateTreeTask(program, new IncrementingIdProvider()).run();
Graph<TranspilerInstruction, DefaultEdge> implicitCFG = new BuildImplicitInstructionControlFlowgraphTask(instructions, ImmutableList.of()).run();

Set<Pair<ProcedureRange, Set<ProcedureRange>>> rangesWithChildren = new ProcedureBodyTask(program, instructions, implicitCFG).run();
SLIFORangeCriterionTask slifoRangeCriterionTask = new SLIFORangeCriterionTask(rangesWithChildren);
assertEquals(1, rangesWithChildren.size());
Pair<ProcedureRange, Set<ProcedureRange>> rangeWithChildren = rangesWithChildren.stream().findFirst().get();
ProcedureRange range = rangeWithChildren.getLeft();
Set<ProcedureRange> rangesTerminatingInRange = slifoRangeCriterionTask.rangesTerminatingIn(range);
assertEquals(ImmutableSet.of(), rangesTerminatingInRange);
assertEquals(ImmutableSet.of(), rangeWithChildren.getRight());
assertTrue(slifoRangeCriterionTask.isSLIFO(rangeWithChildren, ImmutableSet.of()));
}

@Test
public void canDetermineSLIFORangesInductively() {
JumpTranspilerNode jump_B1 = new JumpTranspilerNode(new NamedLocationNode("B1"), new NamedLocationNode("B1"));
JumpTranspilerNode jump_C1 = new JumpTranspilerNode(new NamedLocationNode("C1"), new NamedLocationNode("C1"));
LabelledTranspilerCodeBlockNode a1 = new LabelledTranspilerCodeBlockNode("A1", ImmutableList.of(p(), p(), jump_B1, new JumpTranspilerNode(new ProgramTerminalLocationNode())), ImmutableMap.of());
LabelledTranspilerCodeBlockNode b1 = new LabelledTranspilerCodeBlockNode("B1", ImmutableList.of(p(), p(), jump_C1), ImmutableMap.of());
LabelledTranspilerCodeBlockNode c1 = new LabelledTranspilerCodeBlockNode("C1", ImmutableList.of(p(), p()), ImmutableMap.of());
TranspilerCodeBlockNode program = new TranspilerCodeBlockNode(ImmutableList.of(a1, b1, c1));
block_(
labelledBlock_(
print_(),
print_(),
jump_(),
jump_()
),
labelledBlock_(
print_(),
print_(),
jump_()
),
labelledBlock_(
print_(),
print_()
)
).verify(program);

List<TranspilerInstruction> instructions = new BuildTranspilerInstructionsFromIntermediateTreeTask(program, new IncrementingIdProvider()).run();
Graph<TranspilerInstruction, DefaultEdge> implicitCFG = new BuildImplicitInstructionControlFlowgraphTask(instructions, ImmutableList.of()).run();
Set<Pair<ProcedureRange, Set<ProcedureRange>>> rangesWithChildren = new ProcedureBodyTask(program, instructions, implicitCFG).run();
SLIFORangeCriterionTask task = new SLIFORangeCriterionTask(rangesWithChildren);
assertEquals(2, rangesWithChildren.size());
Set<Pair<ProcedureRange, Set<ProcedureRange>>> allSLIFORanges = task.allSLIFORanges(rangesWithChildren);
assertEquals(2, allSLIFORanges.size());
}

private static PrintTranspilerNode p() {
return new PrintTranspilerNode(ImmutableList.of());
}
}

0 comments on commit 856c4e3

Please sign in to comment.