private static CilMatcher CreateImplicitLiteralMatcher(string literal)
        {
            var outcome = CilSymbolRef.Create(literal);

            // Generate implicit scan rule for the keyword
            var result  = new CilMatcher
            {
                Context         = CilContextRef.None,
                MainOutcome     = outcome,
                AllOutcomes     = { outcome },
                Disambiguation  = Disambiguation.Exclusive,
                Pattern         = ScanPattern.CreateLiteral(literal),
                ActionBuilder   = code => code
                                    .Emit(il => il.Ldnull())
                                    .ReturnFromAction()
            };

            return result;
        }
 internal void AddMatcher(CilMatcher matcher)
 {
     matchers.Add(matcher);
 }
        public override IEnumerable<CilMatcher> GetMatchers()
        {
            var tokenType    = Method.ReturnType;
            var nextConditionType = GetNextConditionType();

            var matcher = new CilMatcher();

            var contextType = GetContextType();
            //var context = CilContextRef.ByType(contextType);

            if (tokenType != typeof(void))
            {
                var outcome = CilSymbolRef.Create(tokenType, LiteralText);
                matcher.MainOutcome = outcome;
                matcher.AllOutcomes.Add(outcome);
            }

            matcher.DefiningMethod = Method;
            matcher.Disambiguation = Disambiguation;
            if (LiteralText == null)
            {
                matcher.Pattern = ScanPattern.CreateRegular(Pattern, RegexPattern);
            }
            else
            {
                matcher.Pattern = ScanPattern.CreateLiteral(LiteralText);
            }

            var parameters = Method.GetParameters().ToList();

            matcher.Context = GetContext();
            matcher.NextConditionType = nextConditionType;
            matcher.ActionBuilder =
                code =>
                {
                    ParameterInfo nextModeParameter;
                    if (parameters.Count != 0 && parameters.Last().IsOut)
                    {
                        nextModeParameter = parameters.Last();
                        parameters.RemoveAt(parameters.Count - 1);
                    }
                    else
                    {
                        nextModeParameter = null;
                    }

                    if (parameters.Count == 0)
                    {
                    }
                    else if (parameters.Count == 1
                            && parameters[0].ParameterType == typeof(string))
                    {
                        code.LdMatcherTokenString();
                    }
                    else if (parameters.Count == 3
                            && parameters[0].ParameterType == typeof(char[])
                            && parameters[1].ParameterType == typeof(int)
                            && parameters[2].ParameterType == typeof(int))
                    {
                        code
                            .LdMatcherBuffer()
                            .LdMatcherStartIndex()
                            .LdMatcherLength();
                    }
                    else
                    {
                        throw new InvalidOperationException(
                            "Unsupported match-method signature: "
                            + string.Join(", ", parameters.Select(p => p.ParameterType.Name)));
                    }

                    Ref<Locals> nextModeVar = null;
                    if (nextModeParameter != null)
                    {
                        code
                            .Emit(il =>
                            {
                                nextModeVar = il.Locals.Generate().GetRef();
                                return il
                                    .Local(nextModeVar.Def, il.Types.Object)
                                    .Ldloca(nextModeVar);
                            });
                    }

                    code.Emit(il => il.Call(Method));

                    if (nextModeParameter != null)
                    {
                        code
                            .Emit(il => il.Ldloc(nextModeVar))
                            .ChangeCondition(nextConditionType);
                    }

                    if (Method.ReturnType == typeof(void))
                    {
                        code.SkipAction();
                    }
                    else
                    {
                        if (Method.ReturnType.IsValueType)
                        {
                            code.Emit(il => il.Box(il.Types.Import(Method.ReturnType)));
                        }

                        code
                            .ReturnFromAction()
                            ;
                    }

                    return code;
                };

            return new[] { matcher };
        }
        public override IEnumerable <CilMatcher> GetMatchers()
        {
            var tokenType         = Method.ReturnType;
            var nextConditionType = GetNextConditionType();

            var matcher = new CilMatcher();

            var contextType = GetContextType();

            //var context = CilContextRef.ByType(contextType);

            if (tokenType != typeof(void))
            {
                var outcome = CilSymbolRef.Create(tokenType, LiteralText);
                matcher.MainOutcome = outcome;
                matcher.AllOutcomes.Add(outcome);
            }

            matcher.DefiningMethod = Method;
            matcher.Disambiguation = Disambiguation;
            if (LiteralText == null)
            {
                matcher.Pattern = ScanPattern.CreateRegular(Pattern, RegexPattern);
            }
            else
            {
                matcher.Pattern = ScanPattern.CreateLiteral(LiteralText);
            }

            var parameters = Method.GetParameters().ToList();

            matcher.Context           = GetContext();
            matcher.NextConditionType = nextConditionType;
            matcher.ActionBuilder     =
                code =>
            {
                ParameterInfo nextModeParameter;
                if (parameters.Count != 0 && parameters.Last().IsOut)
                {
                    nextModeParameter = parameters.Last();
                    parameters.RemoveAt(parameters.Count - 1);
                }
                else
                {
                    nextModeParameter = null;
                }

                if (parameters.Count == 0)
                {
                }
                else if (parameters.Count == 1 &&
                         parameters[0].ParameterType == typeof(string))
                {
                    code.LdMatcherTokenString();
                }
                else if (parameters.Count == 3 &&
                         parameters[0].ParameterType == typeof(char[]) &&
                         parameters[1].ParameterType == typeof(int) &&
                         parameters[2].ParameterType == typeof(int))
                {
                    code
                    .LdMatcherBuffer()
                    .LdMatcherStartIndex()
                    .LdMatcherLength();
                }
                else
                {
                    throw new InvalidOperationException(
                              "Unsupported match-method signature: "
                              + string.Join(", ", parameters.Select(p => p.ParameterType.Name)));
                }

                Ref <Locals> nextModeVar = null;
                if (nextModeParameter != null)
                {
                    code
                    .Emit(il =>
                    {
                        nextModeVar = il.Locals.Generate().GetRef();
                        return(il
                               .Local(nextModeVar.Def, il.Types.Object)
                               .Ldloca(nextModeVar));
                    });
                }

                code.Emit(il => il.Call(Method));

                if (nextModeParameter != null)
                {
                    code
                    .Emit(il => il.Ldloc(nextModeVar))
                    .ChangeCondition(nextConditionType);
                }

                if (Method.ReturnType == typeof(void))
                {
                    code.SkipAction();
                }
                else
                {
                    if (Method.ReturnType.IsValueType)
                    {
                        code.Emit(il => il.Box(il.Types.Import(Method.ReturnType)));
                    }

                    code
                    .ReturnFromAction()
                    ;
                }

                return(code);
            };


            return(new[] { matcher });
        }
        public void AddMatcher(CilMatcher matcher)
        {
            var currentCondition = processedConditions.Peek();
            currentCondition.AddMatcher(matcher);

            if (matcher.NextConditionType != null)
            {
                AddCondition(matcher.NextConditionType);
            }
        }