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")); } }
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); }
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); }
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); }
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(); }