public override Block CompileNewState(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(); block.Comment("begin precedence alt -----------"); // todo enter block.BeginScope(); BlockLabel returnLabel = new BlockLabel("return"); BlockLocal oldLeftRecursiveAlts = new BlockLocal(typeof(IParseable)); block.DeclareLocal(oldLeftRecursiveAlts); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); block.StoreLocal(oldLeftRecursiveAlts); ParseGraphNode oldLeftRecursiveAltsForCompiler = state.LeftRecursiveAlts; foreach (PrecedenceAltGroup group in groups) { block.BeginScope(); BlockLocal groupLocal = new BlockLocal(typeof(PrecedenceAltGroup)); block.DeclareLocal(groupLocal); block.Load(group); block.StoreLocal(groupLocal); BlockLabel apply = new BlockLabel("apply"); BlockLabel continueLabel = new BlockLabel("continue"); BlockLocal currentPrecedence = new BlockLocal(typeof(Precedence)); block.DeclareLocal(currentPrecedence); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.Dup(); block.StoreLocal(currentPrecedence); block.BranchIfNull(apply); BlockLocal groupPrecedence = new BlockLocal(typeof(Precedence)); block.DeclareLocal(groupPrecedence); block.LoadLocal(groupLocal); block.GetProperty(groupLocal.Type.GetProperty("Precedence")); block.Dup(); block.StoreLocal(groupPrecedence); block.BranchIfNull(apply); block.LoadLocal(currentPrecedence); block.GetProperty(currentPrecedence.Type.GetProperty("Group")); block.LoadLocal(groupPrecedence); block.GetProperty(groupPrecedence.Type.GetProperty("Group")); block.BranchIfNotEqual(apply); block.LoadLocal(groupPrecedence); block.LoadLocal(currentPrecedence); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent")); block.LogicalNot(); block.Call(groupPrecedence.Type.GetMethod("IsLowerThan")); block.BranchIfTrue(continueLabel); block.MarkLabel(apply); block.LoadState(); block.LoadLocal(groupLocal); block.GetProperty(groupLocal.Type.GetProperty("LeftRecursiveParseGraph")); block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); state.LeftRecursiveAlts = group.LeftRecursiveParseGraph; block.Emit(group.ParseGraph.Compile(runtime, state)); block.Dup(); BlockLabel no = new BlockLabel("no"); block.BranchIfNo(no); block.LoadState(); block.LoadLocal(oldLeftRecursiveAlts); block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); // todo yes block.Branch(returnLabel); block.MarkLabel(no); block.Pop(); block.MarkLabel(continueLabel); block.EndScope(); } block.LoadState(); block.LoadLocal(oldLeftRecursiveAlts); block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); state.LeftRecursiveAlts = oldLeftRecursiveAltsForCompiler; block.EndScope(); // todo no block.LoadNo(); block.MarkLabel(returnLabel); block.Comment("end precedence alt -----------"); return(block); }
public override Block CompileNewState(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(runtime); block.Comment("start of char --------------------"); block.BeginScope(); block.Whitespace(runtime, state); BlockLocal start = block.SavePosition(); block.Enter(this, range.ToString()); block.LoadLexer(); block.Call(typeof(Lexer).GetMethod("Peek", new Type[] {})); BlockLabel failed = new BlockLabel("failed"); BlockLocal character = null; if (range.Min == range.Max) { if (runtime.TraceParser) { block.Dup(); character = new BlockLocal(typeof(char)); block.DeclareLocal(character); block.StoreLocal(character); } block.Load(range.Min); block.BranchIfNotEqual(failed); } else { character = new BlockLocal(typeof(char)); block.DeclareLocal(character); block.StoreLocal(character); block.LoadLocal(character); block.Load(range.Min); block.BranchIfLess(failed); block.LoadLocal(character); block.Load(range.Max); block.BranchIfGreater(failed); } block.LoadLexer(); block.Call(typeof(Lexer).GetMethod("Read")); if (runtime.TraceParser) { block.LoadParseTrace(); block.Load(this); block.LoadLexer(); block.LoadLocal(start); block.Call(typeof(Lexer).GetMethod("SourceFrom")); block.LoadLocal(character); block.Call(typeof(TextEscape).GetMethod("Quote", new Type[] { typeof(char) })); block.Call(typeof(ParseTrace).GetMethod("Yes", new Type[] { typeof(object), typeof(Source), typeof(string) })); } if (state.BuildTextNodes) { if (range.Min == range.Max) { block.Pop(); block.Load(Convert.ToString(range.Min)); } else { block.Call(typeof(Convert).GetMethod("ToString", new Type[] { typeof(char) })); } block.New(typeof(ParseTree).GetConstructor(new Type[] { typeof(object) })); } else { block.Pop(); block.LoadYes(); } BlockLabel returnLabel = new BlockLabel("return"); block.Branch(returnLabel); block.MarkLabel(failed); if (runtime.TraceParser) { block.LoadParseTrace(); block.Load(this); block.LoadLexer(); block.LoadLocal(start); block.Call(typeof(Lexer).GetMethod("SourceFrom")); block.LoadLocal(character); block.Call(typeof(TextEscape).GetMethod("Quote", new Type[] { typeof(char) })); block.Call(typeof(ParseTrace).GetMethod("No", new Type[] { typeof(object), typeof(Source), typeof(string) })); } // todo error string block.LoadNo(); block.EndScope(); block.MarkLabel(returnLabel); block.Comment("end of char --------------------"); return(block); }