Пример #1
0
        public void BuildBody(
            EmitSyntax emit,
            LanguageData data,
            Ref <Args> ruleId,
            Ref <Args> ruleArgs,
            Ref <Args> argsStart,
            Ref <Args> ctx,
            Ref <Args> lookbackStart)
        {
            Def <Labels> returnLabel = emit.Labels.Generate();

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

            IActionCode code = new ProductionCode(
                emit,
                contextCode,
                ldRuleArgs:  il => il.Ldarg(ruleArgs),
                ldArgsStart: il => il.Ldarg(argsStart),
                returnLabel: returnLabel);

            var defaultLabel             = emit.Labels.Generate();
            var endWithSingleResultLabel = emit.Labels.Generate();
            var jumpTable = new Ref <Labels> [data.Grammar.Productions.Count];

            for (int i = 0; i != jumpTable.Length; ++i)
            {
                jumpTable[i] = emit.Labels.Generate().GetRef();
            }

            emit
            .Do(il => il.Ldarg(ruleId))
            .Switch(jumpTable)
            .Br(defaultLabel.GetRef());

            foreach (var prod in data.Grammar.Productions)
            {
                emit.Label(jumpTable[prod.Index].Def);

                if (0 == prod.Actions.Count)
                {
                    // Augumented start rule has null action and should never be invoked.
                    // Also it is possible that for some platforms production may have default
                    // action.
                    emit.Ldnull();
                }
                else
                {
                    foreach (var action in prod.Actions)
                    {
                        code = GenerateActionCode(code, action);
                    }
                }

                emit.Br(endWithSingleResultLabel.GetRef());
            }

            emit
            .Label(defaultLabel)
            .Ldnull()
            .Label(endWithSingleResultLabel)
            .Label(returnLabel)
            .Ret();
        }
        public void BuildBody(
            EmitSyntax emit, 
            LanguageData data,
            Ref<Args> ruleId,
            Ref<Args> ruleArgs,
            Ref<Args> argsStart,
            Ref<Args> ctx,
            Ref<Args> lookbackStart)
        {
            Def<Labels> returnLabel = emit.Labels.Generate();

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

            IActionCode code = new ProductionCode(
                emit,
                contextCode,
                ldRuleArgs:  il => il.Ldarg(ruleArgs),
                ldArgsStart: il => il.Ldarg(argsStart),
                returnLabel: returnLabel);

            var defaultLabel = emit.Labels.Generate();
            var endWithSingleResultLabel = emit.Labels.Generate();
            var jumpTable = new Ref<Labels>[data.Grammar.Productions.Count];
            for (int i = 0; i != jumpTable.Length; ++i)
            {
                jumpTable[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Do(il => il.Ldarg(ruleId))
                .Switch(jumpTable)
                .Br(defaultLabel.GetRef());

            foreach (var prod in data.Grammar.Productions)
            {
                emit.Label(jumpTable[prod.Index].Def);

                if (0 == prod.Actions.Count)
                {
                    // Augumented start rule has null action and should never be invoked.
                    // Also it is possible that for some platforms production may have default
                    // action.
                    emit.Ldnull();
                }
                else
                {
                    foreach (var action in prod.Actions)
                    {
                        code = GenerateActionCode(code, action);
                    }
                }

                emit.Br(endWithSingleResultLabel.GetRef());
            }

            emit
                .Label(defaultLabel)
                .Ldnull()
                .Label(endWithSingleResultLabel)
                .Label(returnLabel)
                .Ret();
        }