Added nondeternministic jump to several labels instruction to pseudocode

This commit is contained in:
svtk
2011-10-21 15:38:01 +04:00
parent 1aad0077d7
commit e5bd34c7b0
4 changed files with 98 additions and 36 deletions
@@ -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();
@@ -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);
}
}
@@ -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);
}