示例#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;
        }