diff options
author | David Mitchell <davem@iabyn.com> | 2014-06-16 14:34:14 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2014-07-08 16:40:03 +0100 |
commit | 3253bf854af27f38b67fb3a8dfeee758885f3ae9 (patch) | |
tree | 9aac72f516a0892094fdcfda8f56b9cdbd7e1bbd /ext/arybase | |
parent | e864b323d8621840aac1fda03b2bf69dba6336ff (diff) | |
download | perl-3253bf854af27f38b67fb3a8dfeee758885f3ae9.tar.gz |
add op_sibling_splice() fn and make core use it
The op_sibling_splice() is a new general-purpose OP manipulation
function designed to edit the children of an op, in an analogous
manner in which the perl splice() function manipulates arrays.
This commit also edits op.c and a few other places to remove most direct
manipulation of op_sibling, op_first and op_last, and replace that with
calls to op_sibling_splice().
This has two advantages. First, by using the one function consistently
throughout, it makes it clearer what a particular piece of of code is
doing, rather than having to decipher lots of of ad-hoc
cLISTOPo->op_first = OP_SIBLING(kid);
style stuff. Second, it will make it easier to later add a facility for
child OPs to find their parent, since the changes now only need to be made
in a few places.
In theory this commit should make no functional change to the code.
Diffstat (limited to 'ext/arybase')
-rw-r--r-- | ext/arybase/arybase.xs | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/ext/arybase/arybase.xs b/ext/arybase/arybase.xs index 48358b564a..a44233dc2c 100644 --- a/ext/arybase/arybase.xs +++ b/ext/arybase/arybase.xs @@ -156,7 +156,8 @@ STATIC void ab_neuter_dollar_bracket(pTHX_ OP *o) { oldc = cUNOPx(o)->op_first; newc = newGVOP(OP_GV, 0, gv_fetchpvs("arybase::leftbrack", GV_ADDMULTI, SVt_PVGV)); - cUNOPx(o)->op_first = newc; + /* replace oldc with newc */ + op_sibling_splice(o, NULL, 1, newc); op_free(oldc); } @@ -378,8 +379,14 @@ static OP *ab_ck_base(pTHX_ OP *o) /* Break the aelemfast optimisation */ if (o->op_type == OP_AELEM) { OP *const first = cBINOPo->op_first; - if ( OP_SIBLING(first)->op_type == OP_CONST) { - OP_SIBLING_set(first, newUNOP(OP_NULL,0,OP_SIBLING(first))); + OP *second = OP_SIBLING(first); + OP *newop; + if (second->op_type == OP_CONST) { + /* cut out second arg and replace it with a new unop which is + * the parent of that arg */ + op_sibling_splice(o, first, 1, NULL); + newop = newUNOP(OP_NULL,0,second); + op_sibling_splice(o, first, 0, newop); } } } |