Added nondeternministic jump to several labels instruction to pseudocode
This commit is contained in:
@@ -2,9 +2,9 @@ package org.jetbrains.jet.lang.cfg;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetThrowExpression;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -24,6 +24,7 @@ public interface JetControlFlowBuilder {
|
||||
void jumpOnFalse(@NotNull Label label);
|
||||
void jumpOnTrue(@NotNull Label label);
|
||||
void nondeterministicJump(Label label); // Maybe, jump to label
|
||||
void nondeterministicJump(List<Label> label);
|
||||
void jumpToError(JetThrowExpression expression);
|
||||
void jumpToError(JetExpression nothingExpression);
|
||||
|
||||
@@ -43,9 +44,9 @@ public interface JetControlFlowBuilder {
|
||||
void exitTryFinally();
|
||||
|
||||
// Subroutines
|
||||
void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral);
|
||||
void enterSubroutine(@NotNull JetDeclaration subroutine);
|
||||
|
||||
void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral);
|
||||
void exitSubroutine(@NotNull JetDeclaration subroutine);
|
||||
|
||||
@Nullable
|
||||
JetElement getCurrentSubroutine();
|
||||
|
||||
+38
-12
@@ -2,140 +2,166 @@ package org.jetbrains.jet.lang.cfg;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetThrowExpression;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder {
|
||||
protected JetControlFlowBuilder builder;
|
||||
|
||||
public JetControlFlowBuilderAdapter(JetControlFlowBuilder builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
protected @Nullable JetControlFlowBuilder builder;
|
||||
|
||||
@Override
|
||||
public void read(@NotNull JetExpression expression) {
|
||||
assert builder != null;
|
||||
builder.read(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readUnit(@NotNull JetExpression expression) {
|
||||
assert builder != null;
|
||||
builder.readUnit(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Label createUnboundLabel() {
|
||||
assert builder != null;
|
||||
return builder.createUnboundLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindLabel(@NotNull Label label) {
|
||||
assert builder != null;
|
||||
builder.bindLabel(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jump(@NotNull Label label) {
|
||||
assert builder != null;
|
||||
builder.jump(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnFalse(@NotNull Label label) {
|
||||
assert builder != null;
|
||||
builder.jumpOnFalse(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnTrue(@NotNull Label label) {
|
||||
assert builder != null;
|
||||
builder.jumpOnTrue(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(Label label) {
|
||||
assert builder != null;
|
||||
builder.nondeterministicJump(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(List<Label> labels) {
|
||||
assert builder != null;
|
||||
builder.nondeterministicJump(labels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpToError(JetThrowExpression expression) {
|
||||
assert builder != null;
|
||||
builder.jumpToError(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpToError(JetExpression nothingExpression) {
|
||||
assert builder != null;
|
||||
builder.jumpToError(nothingExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label getEntryPoint(@NotNull JetElement labelElement) {
|
||||
assert builder != null;
|
||||
return builder.getEntryPoint(labelElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label getExitPoint(@NotNull JetElement labelElement) {
|
||||
assert builder != null;
|
||||
return builder.getExitPoint(labelElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoopInfo enterLoop(@NotNull JetExpression expression, Label loopExitPoint, Label conditionEntryPoint) {
|
||||
assert builder != null;
|
||||
return builder.enterLoop(expression, loopExitPoint, conditionEntryPoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitLoop(@NotNull JetExpression expression) {
|
||||
assert builder != null;
|
||||
builder.exitLoop(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JetElement getCurrentLoop() {
|
||||
assert builder != null;
|
||||
return builder.getCurrentLoop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterTryFinally(@NotNull GenerationTrigger trigger) {
|
||||
assert builder != null;
|
||||
builder.enterTryFinally(trigger);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitTryFinally() {
|
||||
assert builder != null;
|
||||
builder.exitTryFinally();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral) {
|
||||
builder.enterSubroutine(subroutine, isFunctionLiteral);
|
||||
public void enterSubroutine(@NotNull JetDeclaration subroutine) {
|
||||
assert builder != null;
|
||||
builder.enterSubroutine(subroutine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral) {
|
||||
builder.exitSubroutine(subroutine, functionLiteral);
|
||||
public void exitSubroutine(@NotNull JetDeclaration subroutine) {
|
||||
assert builder != null;
|
||||
builder.exitSubroutine(subroutine);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JetElement getCurrentSubroutine() {
|
||||
assert builder != null;
|
||||
return builder.getCurrentSubroutine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnValue(@NotNull JetExpression returnExpression, @NotNull JetElement subroutine) {
|
||||
assert builder != null;
|
||||
builder.returnValue(returnExpression, subroutine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnNoValue(@NotNull JetElement returnExpression, @NotNull JetElement subroutine) {
|
||||
assert builder != null;
|
||||
builder.returnNoValue(returnExpression, subroutine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsupported(JetElement element) {
|
||||
assert builder != null;
|
||||
builder.unsupported(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull JetElement assignment, @NotNull JetElement lValue) {
|
||||
assert builder != null;
|
||||
builder.write(assignment, lValue);
|
||||
}
|
||||
}
|
||||
|
||||
+47
-15
@@ -1,20 +1,48 @@
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
* @author svtk
|
||||
*/
|
||||
public class NondeterministicJumpInstruction extends AbstractJumpInstruction {
|
||||
|
||||
public class NondeterministicJumpInstruction extends InstructionImpl{
|
||||
private Instruction next;
|
||||
private final List<Label> targetLabels;
|
||||
private final Map<Label, Instruction> resolvedTargets;
|
||||
|
||||
public NondeterministicJumpInstruction(List<Label> targetLabels) {
|
||||
this.targetLabels = targetLabels;
|
||||
resolvedTargets = Maps.newLinkedHashMap();
|
||||
}
|
||||
|
||||
public NondeterministicJumpInstruction(Label targetLabel) {
|
||||
super(targetLabel);
|
||||
this(Lists.newArrayList(targetLabel));
|
||||
}
|
||||
|
||||
public List<Label> getTargetLabels() {
|
||||
return targetLabels;
|
||||
}
|
||||
|
||||
public Map<Label, Instruction> getResolvedTargets() {
|
||||
return resolvedTargets;
|
||||
}
|
||||
|
||||
public void setResolvedTarget(Label label, Instruction resolvedTarget) {
|
||||
Instruction target = outgoingEdgeTo(resolvedTarget);
|
||||
resolvedTargets.put(label, target);
|
||||
}
|
||||
|
||||
public Instruction getNext() {
|
||||
return next;
|
||||
}
|
||||
public void setNext(Instruction next) {
|
||||
this.next = outgoingEdgeTo(next);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -22,22 +50,26 @@ public class NondeterministicJumpInstruction extends AbstractJumpInstruction {
|
||||
visitor.visitNondeterministicJump(this);
|
||||
}
|
||||
|
||||
public Instruction getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(Instruction next) {
|
||||
this.next = outgoingEdgeTo(next);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<Instruction> getNextInstructions() {
|
||||
return Arrays.asList(getResolvedTarget(), getNext());
|
||||
ArrayList<Instruction> targetInstructions = Lists.newArrayList(getResolvedTargets().values());
|
||||
targetInstructions.add(getNext());
|
||||
return targetInstructions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "jmp?(" + getTargetLabel().getName() + ")";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("jmp?(");
|
||||
for (Iterator<Label> iterator = targetLabels.iterator(); iterator.hasNext(); ) {
|
||||
Label targetLabel = iterator.next();
|
||||
sb.append(targetLabel.getName());
|
||||
if (iterator.hasNext()) {
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -78,7 +77,8 @@ public class Pseudocode {
|
||||
public List<Instruction> getInstructions() {
|
||||
return instructions;
|
||||
}
|
||||
|
||||
|
||||
@Deprecated //for tests only
|
||||
public List<PseudocodeLabel> getLabels() {
|
||||
return labels;
|
||||
}
|
||||
@@ -128,7 +128,10 @@ public class Pseudocode {
|
||||
@Override
|
||||
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
||||
instruction.setNext(getNextPosition(currentPosition));
|
||||
visitJump(instruction);
|
||||
List<Label> targetLabels = instruction.getTargetLabels();
|
||||
for (Label targetLabel : targetLabels) {
|
||||
instruction.setResolvedTarget(targetLabel, getJumpTarget(targetLabel));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,7 +150,7 @@ public class Pseudocode {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFunctionLiteralValue(FunctionLiteralValueInstruction instruction) {
|
||||
public void visitFunctionLiteralValue(LocalDeclarationInstruction instruction) {
|
||||
instruction.getBody().postProcess();
|
||||
super.visitFunctionLiteralValue(instruction);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user