コード例 #1
0
ファイル: LabelNode.cs プロジェクト: tedneward/katahdin
        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);
        }
コード例 #2
0
ファイル: RepNode.cs プロジェクト: tedneward/katahdin
        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);
        }