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