示例#1
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Comment("start of and --------------------");

            BlockLabel returnLabel = new BlockLabel("return");

            block.BeginScope();

            BlockLocal start = block.SavePosition();

            // todo enter

            block.Emit(body.Compile(runtime, state));

            BlockLabel yes = new BlockLabel("yes");

            block.BranchIfNotNo(yes);

            // todo no

            block.LoadNo();
            block.Branch(returnLabel);

            block.MarkLabel(yes);

            // todo yes

            block.RestorePosition(start);
            block.LoadYes();

            block.MarkLabel(returnLabel);

            block.EndScope();

            block.Comment("end of and --------------------");

            return(block);
        }
示例#2
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Comment("start of rep " + reps.Name + " --------------------");

            // todo enter

            block.BeginScope();

            BlockLabel returnLabel = new BlockLabel("return");

            BlockLocal start = block.SavePosition();

            block.NewParseTree();

            BlockLabel reiterate = null;
            BlockLocal matched   = null;

            if (!reps.MaximumOfOne)
            {
                reiterate = new BlockLabel("reiterate");
                block.MarkLabel(reiterate);

                matched = new BlockLocal(typeof(bool));
                block.DeclareLocal(matched);
            }

            BlockLabel breakLabel = new BlockLabel("break");

            block.Emit(body.Compile(runtime, state));

            BlockLabel yes = new BlockLabel("yes");

            block.Dup();
            block.BranchIfNotNo(yes);

            block.Pop();

            block.Branch(breakLabel);

            block.MarkLabel(yes);

            block.Call(typeof(ParseTree).GetMethod("Extend"));

            if (!reps.MaximumOfOne)
            {
                block.Load(true);
                block.StoreLocal(matched);

                block.Branch(reiterate);
            }

            block.MarkLabel(breakLabel);

            if (reps.Minimum > 0)
            {
                BlockLabel enough = new BlockLabel("enough");
                block.LoadLocal(matched);
                block.BranchIfTrue(enough);

                // todo no

                block.RestorePosition(start);

                block.Pop();
                block.LoadNo();

                block.Branch(returnLabel);

                block.MarkLabel(enough);
            }

            // todo yes

            block.MarkLabel(returnLabel);

            block.EndScope();

            block.Comment("end of rep --------------------");

            return(block);
        }
示例#3
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            BlockLabel returnLabel = new BlockLabel("return");

            block.Comment("start of seq --------------------");

            block.BeginScope();

            // Save

            BlockLocal start = block.SavePosition();

            BlockLocal oldLeftHandSide = new BlockLocal(typeof(RuntimeObject));
            BlockLocal oldPrecedenceCanEqualCurrent = new BlockLocal(typeof(bool));
            BlockLocal oldRecursionExclude          = new BlockLocal(typeof(Pattern));

            block.DeclareLocal(oldRecursionExclude);

            if (state.RecursionBehaviour == RecursionBehaviour.RightRecursive)
            {
                block.DeclareLocal(oldPrecedenceCanEqualCurrent);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
                block.StoreLocal(oldPrecedenceCanEqualCurrent);
            }

            if (state.RecursionBehaviour == RecursionBehaviour.LeftRecursive)
            {
                block.DeclareLocal(oldLeftHandSide);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide"));
                block.StoreLocal(oldLeftHandSide);
            }

            block.LoadYes();

            for (int n = 0; n < nodes.Count; n++)
            {
                ParseGraphNode node = nodes[n];

                // Parse the node

                block.Emit(node.Compile(runtime, state));

                // If no

                BlockLabel yes = new BlockLabel("yes");
                block.Dup();    // dup the body tree
                block.BranchIfNotNo(yes);

                block.Pop();    // pop body tree
                block.Pop();    // pop new tree

                Restore(state, block, oldLeftHandSide,
                        oldPrecedenceCanEqualCurrent, oldRecursionExclude);

                block.RestorePosition(start);

                block.LoadNo();
                block.Branch(returnLabel);

                block.MarkLabel(yes);

                // Extend

                block.Call(typeof(ParseTree).GetMethod("Extend"));

                if (n == 0)
                {
                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
                    block.LoadNull();

                    BlockLabel recursionExcludeNull = new BlockLabel("recursionExcludeNull");
                    block.BranchIfEqual(recursionExcludeNull);

                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
                    block.StoreLocal(oldRecursionExclude);

                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
                    block.Call(typeof(Multiset <Pattern>).GetMethod("Remove", new Type[] { typeof(Pattern) }));

                    block.LoadState();
                    block.LoadNull();
                    block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude"));

                    block.MarkLabel(recursionExcludeNull);

                    if (state.RecursionBehaviour == RecursionBehaviour.RightRecursive)
                    {
                        block.Comment("right recursion");

                        block.LoadState();
                        block.Load(1);
                        block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
                    }
                    else if (state.RecursionBehaviour == RecursionBehaviour.LeftRecursive)
                    {
                        block.Comment("left recursion");

                        block.LoadState();
                        block.LoadNull();
                        block.SetProperty(typeof(ParserState).GetProperty("LeftHandSide"));
                    }
                }
            }

            Restore(state, block, oldLeftHandSide,
                    oldPrecedenceCanEqualCurrent, oldRecursionExclude);

            block.EndScope();

            block.MarkLabel(returnLabel);

            block.Comment("end of seq --------------------");

            return(block);
        }
示例#4
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);
        }
示例#5
0
        private void CompileLeftRecurse(Runtime runtime,
                                        StateForCompiler state, ParserBlock block, BlockLocal start,
                                        BlockLocal tree)
        {
            block.BeginScope();

            block.Enter(this, "left recurse");

            BlockLocal finished = block.SavePosition();

            block.LoadState();
            block.LoadLocal(tree);
            block.SetProperty(typeof(ParserState).GetProperty("LeftHandSide"));

            block.LoadState();
            block.LoadLocal(finished);
            block.SetProperty(typeof(ParserState).GetProperty("LeftHandSideEndPos"));

            block.LoadState();
            block.Load(true);
            block.SetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion"));

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

            ParseGraphNode node;

            if (state.LeftRecursiveAlts != null)
            {
                node = state.LeftRecursiveAlts;
            }
            else
            {
                node = recurseNode;
            }

            block.Emit(node.Compile(runtime, state));

            block.LoadState();
            block.Load(false);
            block.SetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion"));

            block.LoadState();
            block.LoadNull();
            block.SetProperty(typeof(ParserState).GetProperty("LeftHandSide"));

            BlockLabel yes = new BlockLabel("yes");

            block.Dup();
            block.BranchIfNotNo(yes);

            block.No(this, start);

            block.Pop();
            block.RestorePosition(finished);

            BlockLabel returnLabel = new BlockLabel("return");

            block.Branch(returnLabel);

            block.MarkLabel(yes);

            block.Yes(this, start);

            block.StoreLocal(tree);

            block.MarkLabel(returnLabel);

            block.EndScope();
        }