Exemplo n.º 1
0
        public override Block CompileNewState(Runtime runtime, StateForCompiler state)
        {
            ParserBlock block = new ParserBlock(runtime);

            block.Comment("begin longest alt -----------");

            block.Enter(this, "longest alt");

            block.BeginScope();

            BlockLocal start = block.SavePosition();

            BlockLocal longestTree = new BlockLocal(typeof(ParseTree));

            block.DeclareLocal(longestTree);
            block.LoadNull();
            block.StoreLocal(longestTree);

            BlockLocal longestTreeEnd = new BlockLocal(typeof(int));

            block.DeclareLocal(longestTreeEnd);
            block.Load(-1);
            block.StoreLocal(longestTreeEnd);

            foreach (IParseable alt in alts)
            {
                block.Emit(alt.Compile(runtime, state));

                BlockLabel no = new BlockLabel("no");
                block.Dup();
                block.BranchIfNo(no);

                block.LoadLexer();
                block.GetProperty(typeof(Lexer).GetProperty("Position"));
                block.LoadLocal(longestTreeEnd);

                block.BranchIfLessOrEqual(no);

                block.StoreLocal(longestTree);

                block.LoadLexer();
                block.GetProperty(typeof(Lexer).GetProperty("Position"));
                block.StoreLocal(longestTreeEnd);

                BlockLabel continueLabel = new BlockLabel("continue");
                block.Branch(continueLabel);

                block.MarkLabel(no);
                block.Pop();

                block.MarkLabel(continueLabel);

                block.RestorePosition(start);
            }

            BlockLabel yes = new BlockLabel("null");

            block.LoadLocal(longestTree);
            block.BranchIfNotNull(yes);

            block.Comment("no");

            block.No(this, start, "No alts matched");

            block.LoadNo();

            BlockLabel returnLabel = new BlockLabel("return");

            block.Branch(returnLabel);

            block.Comment("yes");

            block.MarkLabel(yes);

            block.Yes(this, start);

            block.RestorePosition(longestTreeEnd);

            block.LoadLocal(longestTree);

            block.MarkLabel(returnLabel);

            block.Comment("end longest alt -----------");

            return(block);
        }