Exemplo n.º 1
0
 public override Block CompileNewState(Runtime runtime,
     StateForCompiler state)
 {
     ParserBlock block = new ParserBlock();
     
     block.Comment("start of any --------------------");
     
     BlockLabel returnLabel = new BlockLabel("return");
     
     // todo enter
     
     block.BeginScope();
     
     block.LoadLexer();
     block.Call(typeof(Lexer).GetMethod("Peek", new Type[]{}));
     
     BlockLabel failed = new BlockLabel("failed");
     block.BranchIfFalse(failed);
     
     block.LoadLexer();
     block.Call(typeof(Lexer).GetMethod("Read"));
     
     // todo yes
     
     if (state.BuildTextNodes)
     {
         block.Call(typeof(Convert).GetMethod("ToString", new Type[]{typeof(char)}));
         block.New(typeof(ParseTree).GetConstructor(new Type[]{typeof(object)}));
     }
     else
     {
         block.Pop();
         block.LoadYes();
     }
     
     block.Branch(returnLabel);
     
     block.MarkLabel(failed);
     
     // todo no
     
     block.LoadNo();
     
     block.MarkLabel(returnLabel);
     
     block.EndScope();
     
     block.Comment("end of any --------------------");
     
     return block;
 }
Exemplo n.º 2
0
        public override Block CompileNew(Runtime runtime, StateForCompiler state)
        {
            ParserBlock block = new ParserBlock(runtime);
            
            block.Comment("start of concrete pattern -------------");
            
            BlockLabel returnLabel = new BlockLabel("return");
            
            block.BeginScope();
            
            block.Enter(this, Type.Name);
            
            BlockLocal start = block.SavePosition();
            
            BlockLabel notExcluded = new BlockLabel("notExcluded");
            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
            block.Load(this);
            block.Call(typeof(Multiset<Pattern>).GetMethod("Contains"));
            block.BranchIfFalse(notExcluded);
            
            block.No(this, "Excluded");
            
            block.LoadNo();
            block.Branch(returnLabel);
            
            block.MarkLabel(notExcluded);
            
            BlockLocal key = new BlockLocal(typeof(ParserMemoryKey));
            block.DeclareLocal(key);
            block.Load(this);
            block.LoadLocal(start);
            block.New(typeof(ParserMemoryKey).GetConstructor(new Type[]{typeof(ConcretePattern), typeof(int)}));
            block.StoreLocal(key);
            
            BlockLocal oldSkipMemoryForLeftRecursion = new BlockLocal(typeof(bool));
            block.DeclareLocal(oldSkipMemoryForLeftRecursion);
            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion"));
            block.Dup();
            block.StoreLocal(oldSkipMemoryForLeftRecursion);
            
            BlockLabel checkMemory = new BlockLabel("checkMemory");
            block.BranchIfFalse(checkMemory);
            
            block.LoadState();
            block.Load(false);
            block.SetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion"));
            
            BlockLabel setRecursion = new BlockLabel("setRecursion");
            block.Branch(setRecursion);
            
            block.MarkLabel(checkMemory);
            
            block.BeginScope();
            
            BlockLocal entry = new BlockLocal(typeof(ParserMemoryEntry));
            block.DeclareLocal(entry);
            
            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("Memory"));
            block.LoadLocal(key);
            block.LoadLocalAddress(entry);
            block.Call(typeof(Dictionary<ParserMemoryKey, ParserMemoryEntry>).GetMethod("TryGetValue"));
            block.BranchIfFalse(setRecursion);
            
            // todo link next
            
            BlockLabel memoryYes = new BlockLabel("memoryYes");
            block.LoadLocal(entry);
            block.GetProperty(typeof(ParserMemoryEntry).GetProperty("Tree"));
            
            BlockLabel returnTree = new BlockLabel("returnTree");
            block.BranchIfNotNo(memoryYes);
            
            block.No(this, start, "from memory");
            
            block.Branch(returnTree);
            
            block.MarkLabel(memoryYes);
            
            block.Yes(this, start, "from memory");
            
            block.LoadLexer();
            block.LoadLocal(entry);
            block.GetProperty(typeof(ParserMemoryEntry).GetProperty("End"));
            block.SetProperty(typeof(Lexer).GetProperty("Position"));
            
            block.MarkLabel(returnTree);
            
            block.LoadLocal(entry);
            block.GetProperty(typeof(ParserMemoryEntry).GetProperty("Tree"));
            
            block.Branch(returnLabel);
            
            block.MarkLabel(setRecursion);
            
            BlockLocal oldRecursionExclude = new BlockLocal(typeof(ConcretePattern));
            block.DeclareLocal(oldRecursionExclude);
            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
            block.StoreLocal(oldRecursionExclude);
            
            if (RecursionBehaviour != RecursionBehaviour.Recursive)
            {
                BlockLabel recursionExcludeSaveNull = new BlockLabel("recursionExcludeSaveNull");
                block.LoadLocal(oldRecursionExclude);
                block.BranchIfNull(recursionExcludeSaveNull);
                
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
                block.LoadLocal(oldRecursionExclude);
                block.Call(typeof(Multiset<Pattern>).GetMethod("Remove", new Type[]{typeof(Pattern)}));
                
                block.MarkLabel(recursionExcludeSaveNull);
                
                block.LoadState();
                block.Load(this);
                block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
                
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
                block.Load(this);
                block.Call(typeof(Multiset<Pattern>).GetMethod("Add", new Type[]{typeof(Pattern)}));
            }
            
            BlockLocal oldRecursionBehaviour = new BlockLocal(typeof(RecursionBehaviour));
            block.DeclareLocal(oldRecursionBehaviour);
            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("RecursionBehaviour"));
            block.StoreLocal(oldRecursionBehaviour);
            
            block.LoadState();
            block.Load(Convert.ToInt32(RecursionBehaviour));
            block.SetProperty(typeof(ParserState).GetProperty("RecursionBehaviour"));
            
            RecursionBehaviour oldRecursionBehaviourState = state.RecursionBehaviour;
            state.RecursionBehaviour = RecursionBehaviour;
            
            BlockLocal oldCurrentPrecedence = new BlockLocal(typeof(Precedence));
            block.DeclareLocal(oldCurrentPrecedence);
            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
            block.StoreLocal(oldCurrentPrecedence);
            
            BlockLabel doesntOverwrite = new BlockLabel("doesntOverwrite");
            block.Load(Precedence);
            block.LoadLocal(oldCurrentPrecedence);
            block.Call(typeof(Precedence).GetMethod("Overwrites"));
            block.BranchIfFalse(doesntOverwrite);

            block.LoadState();
            block.Load(Precedence);
            block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
            
            block.MarkLabel(doesntOverwrite);
            
            BlockLocal oldPrecedenceCanEqualCurrent = new BlockLocal(typeof(bool));
            block.DeclareLocal(oldPrecedenceCanEqualCurrent);
            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
            block.StoreLocal(oldPrecedenceCanEqualCurrent);
            
            block.LoadState();
            block.Load(RecursionBehaviour == RecursionBehaviour.Recursive);
            block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
            
            BlockLocal tree = new BlockLocal(typeof(ParseTree));
            block.DeclareLocal(tree);
            block.Emit(ParseGraph.Compile(runtime, state));
            block.StoreLocal(tree);
            
            block.LoadState();
            block.LoadLocal(oldCurrentPrecedence);
            block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
            
            block.LoadState();
            block.LoadLocal(oldPrecedenceCanEqualCurrent);
            block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
            
            block.LoadState();
            block.LoadLocal(oldRecursionBehaviour);
            block.SetProperty(typeof(ParserState).GetProperty("RecursionBehaviour"));
            
            state.RecursionBehaviour = oldRecursionBehaviourState;
            
            block.LoadState();
            block.LoadLocal(oldRecursionExclude);
            block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
            
            block.LoadState();
            block.LoadLocal(oldSkipMemoryForLeftRecursion);
            block.SetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion"));
            
            if (RecursionBehaviour != RecursionBehaviour.Recursive)
            {
                BlockLabel recursionExcludeRestoreNull = new BlockLabel("recursionExcludeRestoreNull");
                block.LoadLocal(oldRecursionExclude);
                block.BranchIfNull(recursionExcludeRestoreNull);
                
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
                block.LoadLocal(oldRecursionExclude);
                block.Call(typeof(Multiset<Pattern>).GetMethod("Add", new Type[]{typeof(Pattern)}));
                
                block.MarkLabel(recursionExcludeRestoreNull);
                
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
                block.Load(this);
                block.Call(typeof(Multiset<Pattern>).GetMethod("Remove", new Type[]{typeof(Pattern)}));
            }
            
            BlockLabel no = new BlockLabel("yes1");
            block.LoadLocal(tree);
            block.BranchIfNo(no);
            
            block.Whitespace(runtime, state);
            
            CompileInstantiate(block, start, tree);
            
            block.MarkLabel(no);
            
            BlockLocal nextTag = new BlockLocal(typeof(object));
            block.DeclareLocal(nextTag);
            block.New(typeof(object));
            block.StoreLocal(nextTag);
            
            // todo tag next
            
            BlockLabel yes = new BlockLabel("yes");
            block.LoadLocal(tree);
            block.BranchIfNotNo(yes);
            
            block.No(this, start, "a");
            
            BlockLabel finish = new BlockLabel("finish");
            block.Branch(finish);
            
            block.MarkLabel(yes);
            
            block.Yes(this, start);
            
            if (RecursionBehaviour == RecursionBehaviour.LeftRecursive)
                CompileLeftRecurse(runtime, state, block, start, tree);
            
            block.MarkLabel(finish);
            
            if (ShouldRemember)
            {
                // TODO - can remove some other code if not remembering
                
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("Memory"));
                block.LoadLocal(key);
            
                block.LoadLocal(tree);
                block.LoadLexer();
                block.GetProperty(typeof(Lexer).GetProperty("Position"));
                block.LoadLocal(nextTag);
                block.New(typeof(ParserMemoryEntry).GetConstructor(new Type[]{typeof(ParseTree), typeof(int), typeof(object)}));
            
                block.SetProperty(typeof(Dictionary<ParserMemoryKey, ParserMemoryEntry>).GetProperty("Item"));
            }
            
            block.LoadLocal(tree);
             
            block.EndScope();
            
            block.MarkLabel(returnLabel);
            
            block.Comment("end of concrete pattern -------------");
            
            return block;
        }
Exemplo n.º 3
0
 public override Block CompileNew(Runtime runtime, StateForCompiler state)
 {
     ParserBlock block = new ParserBlock(runtime);
     
     block.Comment("start of abstract pattern -------------");
     
     BlockLabel returnLabel = new BlockLabel("return");
     
     block.Enter(this, Type.Name);
     
     block.BeginScope();
     
     BlockLocal start = block.SavePosition();
     
     BlockLabel notExcluded = new BlockLabel("notExcluded");
     block.LoadState();
     block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
     block.Load(this);
     block.Call(typeof(Multiset<Pattern>).GetMethod("Contains"));
     block.BranchIfFalse(notExcluded);
     
     block.No(this);
     
     block.LoadNo();
     block.Branch(returnLabel);
     
     block.MarkLabel(notExcluded);
     
     BlockLocal oldCurrentPrecedence = new BlockLocal(typeof(Precedence));
     block.DeclareLocal(oldCurrentPrecedence);
     block.LoadState();
     block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
     block.StoreLocal(oldCurrentPrecedence);
     
     BlockLabel doesntOverwrite = new BlockLabel("doesntOverwrite");
     block.Load(Precedence);
     block.LoadLocal(oldCurrentPrecedence);
     block.Call(typeof(Precedence).GetMethod("Overwrites"));
     block.BranchIfFalse(doesntOverwrite);
     
     block.LoadState();
     block.Load(Precedence);
     block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
     
     block.MarkLabel(doesntOverwrite);
     
     block.Emit(ParseGraph.Compile(runtime, state));
     
     block.LoadState();
     block.LoadLocal(oldCurrentPrecedence);
     block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
     
     block.Dup();
     
     BlockLabel yes = new BlockLabel("yes");
     block.BranchIfNotNo(yes);
     
     block.No(this, start);
     
     block.Branch(returnLabel);
     
     block.MarkLabel(yes);
     
     block.Yes(this, start);
     
     block.EndScope();
     
     block.MarkLabel(returnLabel);
     
     block.Comment("end of abstract pattern -------------");
     
     return block;
 }