Пример #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;
        }
Пример #2
0
 private void Restore(StateForCompiler state, ParserBlock block,
     BlockLocal oldLeftHandSide,
     BlockLocal oldPrecedenceCanEqualCurrent,
     BlockLocal oldRecursionExclude)
 {
     block.LoadState();
     block.LoadLocal(oldRecursionExclude);
     block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
 
     BlockLabel nullLabel = new BlockLabel("null");
 
     block.LoadLocal(oldRecursionExclude);
     block.LoadNull();
     block.BranchIfEqual(nullLabel);
 
     block.LoadState();
     block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
     block.LoadLocal(oldRecursionExclude);
     block.Call(typeof(Multiset<Pattern>).GetMethod("Add"));
 
     block.MarkLabel(nullLabel);
     
     if (state.RecursionBehaviour == RecursionBehaviour.RightRecursive)
     {
         block.LoadState();
         block.LoadLocal(oldPrecedenceCanEqualCurrent);
         block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
     }
     else if (state.RecursionBehaviour == RecursionBehaviour.LeftRecursive)
     {
         block.LoadState();
         block.LoadLocal(oldLeftHandSide);
         block.SetProperty(typeof(ParserState).GetProperty("LeftHandSide"));
     }
 }
Пример #3
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();
 }
Пример #4
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;
        }
Пример #5
0
 public override Block CompileNewState(Runtime runtime,
     StateForCompiler state)
 {
     ParserBlock block = new ParserBlock();
     
     block.Comment("start of options --------------------");
     
     // todo enter
     
     block.BeginScope();
     
     block.Comment("save");
     
     // todo can remove this when no longer mixing jit and aot
     BlockLocal oldBuildTextNodes = null;
     
     BlockLocal oldWhitespace = null;
     BlockLocal excludeLocal = null;
     BlockLocal oldCurrentPrecedence = null;
     BlockLocal oldPrecedenceCanEqualCurrent = null;
     
     if (buildTextNodes.HasValue)
     {
         oldBuildTextNodes = new BlockLocal(typeof(bool));
         block.DeclareLocal(oldBuildTextNodes);
         block.LoadState();
         block.GetProperty(typeof(ParserState).GetProperty("BuildTextNodes"));
         block.StoreLocal(oldBuildTextNodes);
         
         block.LoadState();
         block.Load(buildTextNodes.Value);
         block.SetProperty(typeof(ParserState).GetProperty("BuildTextNodes"));
     }
     
     if (whitespace.HasValue)
     {
         block.Whitespace(runtime, state);
         
         oldWhitespace = new BlockLocal(typeof(Pattern));
         block.DeclareLocal(oldWhitespace);
         
         block.LoadLexer();
         block.GetProperty(typeof(Lexer).GetProperty("WhitespacePattern"));
         block.StoreLocal(oldWhitespace);
         
         block.LoadLexer();
         block.Load(whitespace.Value);
         block.SetProperty(typeof(Lexer).GetProperty("WhitespacePattern"));
     }
     
     if (exclude.HasValue)
     {
         if (exclude.Value == null)
             throw new Exception();
         
         excludeLocal = new BlockLocal(typeof(Pattern));
         block.DeclareLocal(excludeLocal);
         block.Load(exclude.Value);
         block.StoreLocal(excludeLocal);
     
         block.LoadState();
         block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
         block.LoadLocal(excludeLocal);
         block.Call(typeof(Multiset<Pattern>).GetMethod("Add"));
     }
     
     if (dropPrecedence.HasValue && dropPrecedence.Value)
     {
         oldCurrentPrecedence = new BlockLocal(typeof(Precedence));
         block.DeclareLocal(oldCurrentPrecedence);
         block.LoadState();
         block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
         block.StoreLocal(oldCurrentPrecedence);
         
         block.LoadState();
         block.LoadNull();
         block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
         
         oldPrecedenceCanEqualCurrent = new BlockLocal(typeof(bool));
         block.DeclareLocal(oldPrecedenceCanEqualCurrent);
         block.LoadState();
         block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
         block.StoreLocal(oldPrecedenceCanEqualCurrent);
         
         block.LoadState();
         block.Load(false);
         block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
     }
     
     bool oldBuildTextNodesState = state.BuildTextNodes;
     Pattern oldWhitespaceState = state.Whitespace;
     
     if (buildTextNodes.HasValue)
         state.BuildTextNodes = buildTextNodes.Value;
     
     if (whitespace.HasValue)
         state.Whitespace = whitespace.Value;
     
     block.Emit(body.Compile(runtime, state)); 
     
     state.BuildTextNodes = oldBuildTextNodesState;
     state.Whitespace = oldWhitespaceState;
     
     block.Comment("restore");   
 
     if (buildTextNodes.HasValue)
     {
         block.LoadState();
         block.LoadLocal(oldBuildTextNodes);
         block.SetProperty(typeof(ParserState).GetProperty("BuildTextNodes"));
     }     
 
     if (whitespace.HasValue)
     {
         block.LoadLexer();
         block.LoadLocal(oldWhitespace);
         block.SetProperty(typeof(Lexer).GetProperty("WhitespacePattern"));
     }
 
     if (exclude.HasValue)
     {
         block.LoadState();
         block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
         block.LoadLocal(excludeLocal);
         block.Call(typeof(Multiset<Pattern>).GetMethod("Remove", new Type[]{typeof(Pattern)}));
     }
 
     if (dropPrecedence.HasValue && dropPrecedence.Value)
     {
         block.LoadState();
         block.LoadLocal(oldCurrentPrecedence);
         block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
         
         block.LoadState();
         block.LoadLocal(oldPrecedenceCanEqualCurrent);
         block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
     }
     
     // todo yes or no
     
     block.Comment("end of options --------------------");
     
     block.EndScope();
     
     return block;
 }