summaryrefslogtreecommitdiff
path: root/pod/perlguts.pod
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2014-06-27 11:52:44 +0100
committerDavid Mitchell <davem@iabyn.com>2014-07-08 16:40:03 +0100
commit29e61fd971cd4373e17cf1dd6e954ddea5171299 (patch)
tree98cedf27877b50dba8ab0a7c7e781bd4a21275f3 /pod/perlguts.pod
parentc4b209751862a812e3cb3d6951c4f9411b0ca0af (diff)
downloadperl-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.pod23
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>.