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(); block.Comment("start of rep " + reps.Name + " --------------------"); // todo enter block.BeginScope(); BlockLabel returnLabel = new BlockLabel("return"); BlockLocal start = block.SavePosition(); block.NewParseTree(); BlockLabel reiterate = null; BlockLocal matched = null; if (!reps.MaximumOfOne) { reiterate = new BlockLabel("reiterate"); block.MarkLabel(reiterate); matched = new BlockLocal(typeof(bool)); block.DeclareLocal(matched); } BlockLabel breakLabel = new BlockLabel("break"); block.Emit(body.Compile(runtime, state)); BlockLabel yes = new BlockLabel("yes"); block.Dup(); block.BranchIfNotNo(yes); block.Pop(); block.Branch(breakLabel); block.MarkLabel(yes); block.Call(typeof(ParseTree).GetMethod("Extend")); if (!reps.MaximumOfOne) { block.Load(true); block.StoreLocal(matched); block.Branch(reiterate); } block.MarkLabel(breakLabel); if (reps.Minimum > 0) { BlockLabel enough = new BlockLabel("enough"); block.LoadLocal(matched); block.BranchIfTrue(enough); // todo no block.RestorePosition(start); block.Pop(); block.LoadNo(); block.Branch(returnLabel); block.MarkLabel(enough); } // todo yes block.MarkLabel(returnLabel); block.EndScope(); block.Comment("end of rep --------------------"); return(block); }
public override Block CompileNewState(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(runtime); block.Comment("start of pattern --------------------"); if (simple) { block.Emit(pattern.CompileCall(runtime, state)); } else { BlockLabel returnLabel = new BlockLabel("return"); block.BeginScope(); BlockLocal patternLocal = new BlockLocal(typeof(Pattern)); block.DeclareLocal(patternLocal); block.Load(pattern); block.StoreLocal(patternLocal); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide")); BlockLabel parseNew = new BlockLabel("parseNew"); block.BranchIfNull(parseNew); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide")); block.GetProperty(typeof(ParseTree).GetProperty("Value")); block.Call(typeof(object).GetMethod("GetType")); BlockLocal leftType = new BlockLocal(typeof(Type)); block.DeclareLocal(leftType); block.Dup(); block.StoreLocal(leftType); block.LoadLocal(patternLocal); block.GetProperty(typeof(Pattern).GetProperty("Type")); BlockLocal patternType = new BlockLocal(typeof(Type)); block.DeclareLocal(patternType); block.Dup(); block.StoreLocal(patternType); BlockLabel recurse = new BlockLabel("recurse"); block.BranchIfEqual(recurse); block.LoadLocal(leftType); block.LoadLocal(patternType); block.Call(typeof(Type).GetMethod("IsSubclassOf")); block.BranchIfTrue(recurse); block.Branch(parseNew); block.MarkLabel(recurse); block.Single("left hand side from recursion"); block.LoadLexer(); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftHandSideEndPos")); block.SetProperty(typeof(Lexer).GetProperty("Position")); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide")); block.Branch(returnLabel); block.MarkLabel(parseNew); block.Emit(pattern.CompileCall(runtime, state)); block.MarkLabel(returnLabel); block.EndScope(); } block.Comment("end of pattern ---------------------"); return(block); }