public void BuildBody(
            EmitSyntax emit, 
            LanguageData data,
            Ref<Args> tokenId,
            Ref<Args> oldValue,
            Ref<Args> newValue,
            Ref<Args> ctx,
            Ref<Args> lookbackStart)
        {
            var mergers = data.Grammar.Mergers;

            if (mergers.Count == 0)
            {
                emit
                    .Ldarg(oldValue)
                    .Ret();

                return;
            }

            var contextResolverCode = new ContextCode(
                                            emit,
                                            il => il.Ldarg(ctx),
                                            il => il.Ldarg(lookbackStart),
                                            data,
                                            data.Grammar.GlobalContextProvider,
                                            data.LocalParseContexts);

            IActionCode code = new MergeCode(emit, contextResolverCode)
            {
                LoadOldValue = il => il.Ldarg(oldValue),
                LoadNewValue = il => il.Ldarg(newValue),
            };

            var tokenToRuleIndex = new MutableIntMap<int>(
                                        mergers.Select(
                                            merger =>
                                                new IntArrow<int>(merger.Symbol.Index, merger.Index)));
            tokenToRuleIndex.DefaultValue = -1;

            var ids = mergers.Select(m => m.Symbol.Index);
            IntInterval possibleBounds = new IntInterval(ids.Min(), ids.Max());
            var switchGenerator = SwitchGenerator.Sparse(tokenToRuleIndex, possibleBounds);
            switchGenerator.Build(
                emit,
                il => il.Ldarg(tokenId),
                (il, value) =>
                {
                    if (value < 0)
                    {
                        emit
                            .Ldarg(newValue)
                            .Ret();
                    }
                    else
                    {
                        var merger = mergers[value];
                        var binding = merger.Joint.The<CilMerger>();
                        code = code
                            .Do(binding.Context.Load)
                            .Do(binding.ActionBuilder)
                            .Emit(il2 => il2.Ret())
                            ;
                    }
                });

            emit
                .Ret();
        }
Esempio n. 2
0
        public void BuildBody(
            EmitSyntax emit,
            LanguageData data,
            Ref <Args> tokenId,
            Ref <Args> oldValue,
            Ref <Args> newValue,
            Ref <Args> ctx,
            Ref <Args> lookbackStart)
        {
            var mergers = data.Grammar.Mergers;

            if (mergers.Count == 0)
            {
                emit
                .Ldarg(oldValue)
                .Ret();

                return;
            }

            var contextResolverCode = new ContextCode(
                emit,
                il => il.Ldarg(ctx),
                il => il.Ldarg(lookbackStart),
                data,
                data.Grammar.GlobalContextProvider,
                data.LocalParseContexts);

            IActionCode code = new MergeCode(emit, contextResolverCode)
            {
                LoadOldValue = il => il.Ldarg(oldValue),
                LoadNewValue = il => il.Ldarg(newValue),
            };

            var tokenToRuleIndex = new MutableIntMap <int>(
                mergers.Select(
                    merger =>
                    new IntArrow <int>(merger.Symbol.Index, merger.Index)));

            tokenToRuleIndex.DefaultValue = -1;

            var         ids             = mergers.Select(m => m.Symbol.Index);
            IntInterval possibleBounds  = new IntInterval(ids.Min(), ids.Max());
            var         switchGenerator = SwitchGenerator.Sparse(tokenToRuleIndex, possibleBounds);

            switchGenerator.Build(
                emit,
                il => il.Ldarg(tokenId),
                (il, value) =>
            {
                if (value < 0)
                {
                    emit
                    .Ldarg(newValue)
                    .Ret();
                }
                else
                {
                    var merger  = mergers[value];
                    var binding = merger.Joint.The <CilMerger>();
                    code        = code
                                  .Do(binding.Context.Load)
                                  .Do(binding.ActionBuilder)
                                  .Emit(il2 => il2.Ret())
                    ;
                }
            });

            emit
            .Ret();
        }