public override Block CompileNewState(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(runtime); block.Comment("start of text --------------------"); block.Enter(this, TextEscape.Quote(text)); block.BeginScope(); block.Whitespace(runtime, state); BlockLocal start = block.SavePosition(); BlockLocal n = new BlockLocal(typeof(int)); block.DeclareLocal(n); BlockLabel reitterate = new BlockLabel("reitterate"); block.MarkLabel(reitterate); block.Comment("itteration"); BlockLocal character = new BlockLocal(typeof(char)); block.DeclareLocal(character); block.LoadLexer(); block.LoadLocal(n); block.Call(typeof(Lexer).GetMethod("Peek", new Type[] { typeof(int) })); block.Dup(); block.StoreLocal(character); block.Load(text); block.LoadLocal(n); block.GetProperty(typeof(string).GetProperty("Chars")); BlockLabel matched = new BlockLabel("matched"); block.BranchIfEqual(matched); block.Comment("handle the failure"); // todo error string // todo specifics block.No(this, start); block.LoadNo(); BlockLabel returnLabel = new BlockLabel("return"); block.Branch(returnLabel); block.MarkLabel(matched); block.Comment("increment and check the loop variable"); block.LoadLocal(n); block.Increment(); block.Dup(); block.StoreLocal(n); block.Load(text.Length); block.BranchIfLess(reitterate); block.Comment("skip over the text"); block.LoadLexer(); block.Load(text.Length); block.Call(typeof(Lexer).GetMethod("Skip")); // todo specifics block.Yes(this, start); block.Comment("create the parse tree"); if (state.BuildTextNodes) { block.Load(text); block.New(typeof(ParseTree).GetConstructor( new Type[] { typeof(object) })); } else { block.LoadYes(); } block.EndScope(); block.MarkLabel(returnLabel); block.Comment("end of text --------------------"); 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); }