Example #1
0
        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));
                }
            }
Example #4
0
            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);
                }
            }
Example #5
0
        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);
        }
Example #6
0
        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));
        }
Example #7
0
        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));
        }
Example #8
0
        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));
        }
Example #9
0
        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)
 {
 }