示例#1
0
        private static void interpretVariableTemplateMatching(
            PatternWithDecoration patternWithDecoration,
            InterpretationContext context,
            InterpretationResult interpretationResult,
            bool multiMatch = false
            )
        {
            Debug.Assert(patternWithDecoration.decoration.type == Decoration.EnumType.VARIABLETEMPLATEMATCHING);     // just debug-assert because it has to be hardly checked by the dispatching logic

            vmAssert(patternWithDecoration.isBranch, true, "Must be branch!");
            vmAssert(patternWithDecoration.referenced.Length >= 1, false, "Must have a pattern to match");

            PatternWithDecoration patterToMatch = patternWithDecoration.referenced[0];

            // we resolve the variable if it is a variable
            if (patterToMatch.@is(PatternWithDecoration.EnumType.VARIABLE))
            {
                ulong variableIdToResolve = patterToMatch.variableId;
                patterToMatch = context.valueByVariable[variableIdToResolve];
            }

            for (int i = 1; i < patternWithDecoration.referenced.Length; i++)
            {
                vmAssert(patternWithDecoration.referenced[i].decoration.type == Decoration.EnumType.TUPLE2, true, "Must be tuple2");
                Debug.Assert(patternWithDecoration.referenced[i].type == PatternWithDecoration.EnumType.BRANCH); // tuples must be branches, just assert because else it is a bug in the creation of tuple2
                Debug.Assert(patternWithDecoration.referenced[i].referenced.Length == 2);                        // just assert because else it is a bug in the creation of tuple2


                PatternWithDecoration templatePattern = patternWithDecoration.referenced[i].referenced[0];
                PatternWithDecoration actionPattern   = patternWithDecoration.referenced[i].referenced[1];

                MatchArguments <Decoration> arguments = new MatchArguments <Decoration>();


                IDictionary </*UniqueIdType*/ ulong, PatternWithDecoration> matches = new Dictionary </*UniqueIdType*/ ulong, PatternWithDecoration>(context.valueByVariable);    // let it know the current variable assignments
                bool isSame;

                arguments.bidirectional   = false;
                arguments.templatePattern = templatePattern;
                arguments.matchingPattern = patterToMatch;
                bool isMatching = Matcher <Decoration> .match(arguments, matches, out isSame);

                if (!isMatching)
                {
                    continue;
                }
                // we are here if it does match

                // excute body
                interpretationDispatch(actionPattern, context, interpretationResult);

                if (!multiMatch)
                {
                    return;                 // we return because we don't need to match the other possibilities
                }
            }
        }
示例#2
0
        // tries to match the 'matchingPattern' to the 'templatePattern'
        // 'matches' doesn't get reseted on entry, this simplifies iterated(recursive) matching
        public static bool match(MatchArguments <DecorationType> arguments, IDictionary </*variableId*/ ulong, Pattern <DecorationType> > matches, out bool isSame)
        {
            bool innerFnMatchVariable(Pattern <DecorationType> variable, Pattern <DecorationType> toMatch)
            {
                // it is possible that the variable is already in the dictionary
                // if this is the case compare the uniqueId to identify a missmatch

                if (
                    matches.ContainsKey(variable.uniqueId) &&
                    !Pattern <DecorationType> .deepCompare(toMatch, matches[variable.uniqueId])
                    )
                {
                    return(false);
                }

                matches[variable.uniqueId] = toMatch;

                return(true);
            }

            isSame = arguments.templatePattern.uniqueId == arguments.matchingPattern.uniqueId;     // OPTIMIZATION

            if (isSame)
            {
                return(true);
            }
            else if (        // OPTIMIZATION< we can do this because uniqueId == variableId
                isSame &&
                arguments.templatePattern.@is(Pattern <DecorationType> .EnumType.VARIABLE) &&
                arguments.matchingPattern.@is(Pattern <DecorationType> .EnumType.VARIABLE)
                )
            {
                Debug.Assert(arguments.templatePattern.variableId == arguments.matchingPattern.variableId);             // verify
                return(true);
            }


            if (arguments.templatePattern.@is(Pattern <DecorationType> .EnumType.DECORATEDVALUE) &&
                arguments.matchingPattern.@is(Pattern <DecorationType> .EnumType.DECORATEDVALUE)
                )
            {
                bool isEqual = arguments.templatePattern.decoration.checkEqualValue(arguments.matchingPattern.decoration);
                return(isEqual);
            }
            else if (
                arguments.templatePattern.@is(Pattern <DecorationType> .EnumType.SYMBOL) &&
                arguments.matchingPattern.@is(Pattern <DecorationType> .EnumType.SYMBOL)
                )
            {
                return(Pattern <DecorationType> .isSameSymbol(arguments.templatePattern.symbol, arguments.matchingPattern.symbol));
            }
            else if (arguments.templatePattern.@is(Pattern <DecorationType> .EnumType.VARIABLE))
            {
                return(innerFnMatchVariable(arguments.templatePattern, arguments.matchingPattern));
            }
            // we match in the other direction too if the flag is set
            else if (arguments.bidirectional && arguments.matchingPattern.@is(Pattern <DecorationType> .EnumType.VARIABLE))
            {
                return(innerFnMatchVariable(arguments.matchingPattern, arguments.templatePattern));
            }
            else if (arguments.templatePattern.isBranch && arguments.matchingPattern.isBranch)                  // recursivly match
            {
                if (arguments.templatePattern.referenced.Length != arguments.matchingPattern.referenced.Length) // OPTIMIZATION
                {
                    return(false);
                }

                int numberOfChildren = arguments.templatePattern.referenced.Length;
                for (int i = 0; i < numberOfChildren; i++)
                {
                    bool calledIsSame;
                    MatchArguments <DecorationType> calledArguments = new MatchArguments <DecorationType>();
                    calledArguments.templatePattern = arguments.templatePattern.referenced[i];
                    calledArguments.matchingPattern = arguments.matchingPattern.referenced[i];
                    calledArguments.bidirectional   = arguments.bidirectional;

                    if (!match(calledArguments, matches, out calledIsSame))
                    {
                        return(false);
                    }
                }

                return(true);
            }
            else
            {
                // if all possibilities failed we return a missmatch
                return(false);
            }
        }