public override Block CompileNewState(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(); block.Comment("start of label --------------------"); BlockLabel returnLabel = new BlockLabel("returnLabel"); block.Emit(body.Compile(runtime, state)); block.Dup(); block.BranchIfNo(returnLabel); block.BeginScope(); BlockLocal bodyTree = new BlockLocal(typeof(ParseTree)); block.DeclareLocal(bodyTree); block.StoreLocal(bodyTree); block.NewParseTree(); block.LoadLocal(bodyTree); block.Call(typeof(ParseTree).GetMethod("ExtendFields")); block.Dup(); block.GetProperty(typeof(ParseTree).GetProperty("Fields")); block.Load(label); block.LoadLocal(bodyTree); block.GetProperty(typeof(ParseTree).GetProperty("Value")); block.SetProperty(typeof(Dictionary <string, object>).GetProperty("Item")); block.EndScope(); block.MarkLabel(returnLabel); block.Comment("end of label --------------------"); 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); }