4

我一直在玩 bleadperl 中的新 parse_block 功能,

我可以将几个语句解析成一个列表,它会生成下面的树:

LISTOP (0x1002a00c0) leave [1] 
    OP (0x1002d6220) enter 
    COP (0x1002a0b80) nextstate 
    OP (0x10028c0f0) null 
    LISTOP (0x1002a0170) print 
        OP (0x1002b1a90) pushmark 
        SVOP (0x100327ee0) const  PV (0x100826ec0) "hello\n" 
    COP (0x1002a0c50) nextstate 
    LISTOP (0x100324ee0) print 
        OP (0x100327880) pushmark 
        SVOP (0x100324eb0) const  PV (0x100897688) "world\n"

我需要从我的关键字插件返回一个指向 optree 结构的指针,目前它只包含操作的裸列表。我想将这些操作包装在子例程中并将其分配给存储中的符号。

所以我想我想做这样的事情:

$ perl  -MO=Terse -e "*foo = sub { print 'my listops here' }"

LISTOP (0x10022b5e0) leave [1] 
    OP (0x10022b620) enter 
    COP (0x10022b590) nextstate 
    BINOP (0x100202090) sassign 
        UNOP (0x1002083d0) refgen 
            UNOP (0x100208360) null [146] 
                OP (0x1002083a0) pushmark 
                SVOP (0x100208330) anoncode [1] CV (0x100826d40) 
        UNOP (0x1002085a0) rv2gv 
            SVOP (0x100208550) gv  GV (0x100826d28) *foo 

大概我需要在列表的开头和结尾添加 entersub、leasesub,但我不确定如何在 XS 中构建它?我也不知道如何将生成的 optree 转换为 CV?

我可以找到为 xsubs 生成 CV 的示例,但不能从 optrees 中找到。

谢谢你的帮助。

4

1 回答 1

0

我会看看 eval 在内部做了什么,因为这基本上就是它的作用。特别是, op.c 和 Perl_newPROG( OP *o) 可能是一个很好的起点:

void
Perl_newPROG(pTHX_ OP *o)
{
    ...
    PL_eval_root = newUNOP(OP_LEAVEEVAL,
                   ((PL_in_eval & EVAL_KEEPERR)
                ? OPf_SPECIAL : 0), o);
    PL_eval_start = op_linklist(PL_eval_root);
    PL_eval_root->op_private |= OPpREFCOUNTED;
    OpREFCNT_set(PL_eval_root, 1);
    PL_eval_root->op_next = 0;
    CALL_PEEP(PL_eval_start);
    ...
于 2011-05-09T00:08:29.993 回答