private DecisionTree Add(DecisionTree.Guarded guarded, DecisionMaker makeDecision) { if (guarded.Default != null) { if (guarded.Default.MatchIsComplete) { return(null); } var result = Add(guarded.Default, makeDecision); if (guarded.Default.MatchIsComplete) { guarded.MatchIsComplete = true; } return(result); } else { var result = guarded.Default = makeDecision(guarded.Expression, guarded.Type); if (guarded.Default.MatchIsComplete) { guarded.MatchIsComplete = true; } return(result); } }
private void VisitGuardedDecisionTree(DecisionTree.Guarded guarded) { var initialState = this.State; SetState(initialState.Clone()); // assign pattern variables VisitGuardedPattern(guarded); if (guarded.Guard != null) { VisitCondition(guarded.Guard); SetState(StateWhenTrue); // discard StateWhenFalse } // goto the label for the switch block _pendingBranches.Add(new PendingBranch(guarded.Label, this.State)); // put the state back where we found it for the next case SetState(initialState); // Handle the "default" case when the guard fails VisitDecisionTree(guarded.Default); }
private void LowerDecisionTree(DecisionTree.Guarded guarded) { var sectionBuilder = this.SwitchSections[guarded.Section]; var targetLabel = guarded.Label.Label; Debug.Assert(guarded.Guard?.ConstantValue != ConstantValue.False); if (guarded.Guard == null || guarded.Guard.ConstantValue == ConstantValue.True) { // unconditional if (guarded.Bindings.IsDefaultOrEmpty) { _loweredDecisionTree.Add(_factory.Goto(targetLabel)); } else { // with bindings var matched = _factory.GenerateLabel("matched"); _loweredDecisionTree.Add(_factory.Goto(matched)); sectionBuilder.Add(_factory.Label(matched)); AddBindings(sectionBuilder, guarded.Bindings); sectionBuilder.Add(_factory.Goto(targetLabel)); } } else { var checkGuard = _factory.GenerateLabel("checkGuard"); _loweredDecisionTree.Add(_factory.Goto(checkGuard)); sectionBuilder.Add(_factory.Label(checkGuard)); AddBindings(sectionBuilder, guarded.Bindings); sectionBuilder.Add(_factory.ConditionalGoto(LocalRewriter.VisitExpression(guarded.Guard), targetLabel, true)); var guardFailed = _factory.GenerateLabel("guardFailed"); sectionBuilder.Add(_factory.Goto(guardFailed)); _loweredDecisionTree.Add(_factory.Label(guardFailed)); } }
private void LowerDecisionTree(DecisionTree.Guarded guarded) { var sectionBuilder = this.SwitchSections[guarded.Section]; var targetLabel = guarded.Label.Label; Debug.Assert(guarded.Guard?.ConstantValue != ConstantValue.False); if (guarded.Guard == null || guarded.Guard.ConstantValue == ConstantValue.True) { // unconditional Debug.Assert(guarded.Default == null); if (guarded.Bindings.IsDefaultOrEmpty) { _loweredDecisionTree.Add(_factory.Goto(targetLabel)); } else { // with bindings var matched = _factory.GenerateLabel("matched"); _loweredDecisionTree.Add(_factory.Goto(matched)); sectionBuilder.Add(_factory.Label(matched)); AddBindings(sectionBuilder, guarded.Bindings); sectionBuilder.Add(_factory.Goto(targetLabel)); } } else { var checkGuard = _factory.GenerateLabel("checkGuard"); _loweredDecisionTree.Add(_factory.Goto(checkGuard)); sectionBuilder.Add(_factory.Label(checkGuard)); AddBindings(sectionBuilder, guarded.Bindings); var guardTest = _factory.ConditionalGoto(LocalRewriter.VisitExpression(guarded.Guard), targetLabel, true); // Only add instrumentation (such as a sequence point) if the node is not compiler-generated. if (!guarded.Guard.WasCompilerGenerated && this.LocalRewriter.Instrument) { guardTest = this.LocalRewriter._instrumenter.InstrumentPatternSwitchWhenClauseConditionalGotoBody(guarded.Guard, guardTest); } sectionBuilder.Add(guardTest); var guardFailed = _factory.GenerateLabel("guardFailed"); sectionBuilder.Add(_factory.Goto(guardFailed)); _loweredDecisionTree.Add(_factory.Label(guardFailed)); LowerDecisionTree(guarded.Expression, guarded.Default); } }
private DecisionTree AddByNull(DecisionTree.Guarded guarded, DecisionMaker makeDecision) { if (guarded.Default == null) { guarded.Default = new DecisionTree.ByType(guarded.Expression, guarded.Type, null); } var result = AddByNull(guarded.Default, makeDecision); if (guarded.Default.MatchIsComplete) { guarded.MatchIsComplete = true; } return(result); }
private DecisionTree AddByValue(DecisionTree.Guarded guarded, BoundConstantPattern value, DecisionMaker makeDecision) { if (guarded.Default != null) { Debug.Assert(!guarded.Default.MatchIsComplete); // otherwise we would have given a subsumption error } else { // There is no default at this branch of the decision tree, so we create one. // Before the decision tree can match by value, it needs to test if the input is of the required type. // So we create a ByType node to represent that test. guarded.Default = new DecisionTree.ByType(guarded.Expression, guarded.Type, null); } return(AddByValue(guarded.Default, value, makeDecision)); }
private DecisionTree AddByValue(DecisionTree.Guarded guarded, BoundConstantPattern value, DecisionMaker makeDecision) { if (guarded.Default != null) { if (guarded.Default.MatchIsComplete) { return(null); } } else { guarded.Default = new DecisionTree.ByValue(guarded.Expression, guarded.Type, null); } return(AddByValue(guarded.Default, value, makeDecision)); }
private DecisionTree AddByValue(DecisionTree.Guarded guarded, BoundExpression value, DecisionMaker makeDecision, bool hasErrors) { if (guarded.Default != null) { if (guarded.Default.MatchIsComplete) { return(null); } } else { guarded.Default = new DecisionTree.ByValue(guarded.Expression, guarded.Type, null); } return(AddByValue(guarded.Default, value, makeDecision, hasErrors)); }
private DecisionTree Add(DecisionTree.Guarded guarded, DecisionMaker makeDecision) { if (guarded.Default != null) { Debug.Assert(!guarded.Default.MatchIsComplete); // otherwise we would have given a subsumption error var result = Add(guarded.Default, makeDecision); if (guarded.Default.MatchIsComplete) { guarded.MatchIsComplete = true; } return(result); } else { var result = guarded.Default = makeDecision(guarded.Expression, guarded.Type); if (guarded.Default.MatchIsComplete) { guarded.MatchIsComplete = true; } return(result); } }
protected virtual void VisitGuardedPattern(DecisionTree.Guarded guarded) { }