diff options
author | David Mitchell <davem@iabyn.com> | 2014-06-27 11:52:44 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2014-07-08 16:40:03 +0100 |
commit | 29e61fd971cd4373e17cf1dd6e954ddea5171299 (patch) | |
tree | 98cedf27877b50dba8ab0a7c7e781bd4a21275f3 /pod/perlguts.pod | |
parent | c4b209751862a812e3cb3d6951c4f9411b0ca0af (diff) | |
download | perl-29e61fd971cd4373e17cf1dd6e954ddea5171299.tar.gz |
add op_lastsib and -DPERL_OP_PARENT
Add the boolean field op_lastsib to OPs. Within the core, this is set
on the last op in an op_sibling chain (so it is synonymous with op_sibling
being null). By default, its value is set but not used.
In addition, add a new build define (not yet enabled by default),
-DPERL_OP_PARENT, that forces the core to use op_lastsib to detect the
last op in a sibling chain, rather than op_sibling being NULL. This frees
up the last op_sibling pointer in the chain, which rather than being set
to NULL, is now set to point back to the parent of the sibling chain (if
any).
This commit also adds a C-level op_parent() function and B parent()
method; under default builds they just return NULL, under PERL_OP_PARENT
they return the parent of the current op.
Collectively this provides a facility not previously available from B:: nor
C, of being able to follow an op tree up as well as down.
Diffstat (limited to 'pod/perlguts.pod')
-rw-r--r-- | pod/perlguts.pod | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/pod/perlguts.pod b/pod/perlguts.pod index 105e8171d2..4fe07983da 100644 --- a/pod/perlguts.pod +++ b/pod/perlguts.pod @@ -1957,15 +1957,34 @@ C<op_first> field but also an C<op_last> field. The most complex type of op is a C<LISTOP>, which has any number of children. In this case, the first child is pointed to by C<op_first> and the last child by C<op_last>. The children in between can be found by iteratively -following the C<op_sibling> pointer from the first child to the last. +following the C<op_sibling> pointer from the first child to the last 9but +see below). -There are also two other op types: a C<PMOP> holds a regular expression, +There are also some other op types: a C<PMOP> holds a regular expression, and has no children, and a C<LOOP> may or may not have children. If the C<op_children> field is non-zero, it behaves like a C<LISTOP>. To complicate matters, if a C<UNOP> is actually a C<null> op after optimization (see L</Compile pass 2: context propagation>) it will still have children in accordance with its former type. +Finally, there is a C<LOGOP>, or logic op. Like a C<LISTOP>, this has one +or more children, but it doesn't have an C<op_last> field: so you have to +follow C<op_first> and then the C<op_sibling> chain itself to find the +last child. Instead it has an C<op_other> field, which is comparable to +the C<op_next> field described below, and represents an alternate +execution path. Operators like C<and>, C<or> and C<?> are C<LOGOP>s. Note +that in general, C<op_other> may not point to any of the direct children +of the C<LOGOP>. + +Starting in version 5.21.2, perls built with the experimental +define C<-DPERL_OP_PARENT> add an extra boolean flag for each op, +C<op_lastsib>. When set, this indicates that this is the last op in an +C<op_sibling> chain. This frees up the C<op_sibling> field on the last +sibling to point back to the parent op. The macro C<OP_SIBLING(o)> wraps +this special behaviour, and always returns NULL on the last sibling. +With this build the C<op_parent(o)> function can be used to find the +parent of any op. + Another way to examine the tree is to use a compiler back-end module, such as L<B::Concise>. |