.\" -*- mode: troff; coding: utf-8 -*-
.\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.48)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.ie n \{\
.    ds C` ""
.    ds C' ""
'br\}
.el\{\
.    ds C`
.    ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el       .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD.  Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
.    if \nF \{\
.        de IX
.        tm Index:\\$1\t\\n%\t"\\$2"
..
.        if !\nF==2 \{\
.            nr % 0
.            nr F 2
.        \}
.    \}
.\}
.rr rF
.\"
.\" Required to disable full justification in groff 1.23.0.
.if n .ds AD l
.\" ========================================================================
.\"
.IX Title "ExtUtils::ParseXS::Node 3"
.TH ExtUtils::ParseXS::Node 3 2026-07-13 "perl v5.44.0" "Perl Programmers Reference Guide"
.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH NAME
ExtUtils::ParseXS::Node \- Classes for nodes of an Abstract Syntax Tree
.SH SYNOPSIS
.IX Header "SYNOPSIS"
.Vb 3
\&    # Create a node to represent the Foo part of an XS file; then
\&    # top\-down parse it into a subtree; then top\-down emit the
\&    # contents of the subtree as C code.
\&
\&    my $foo = ExtUtils::ParseXS::Node::Foo\->new();
\&    $foo\->parse(...)
\&        or die;
\&    $foo\->as_code(...);
\&    print STDERR $foo\->as_concise(1); # for debugging
.Ve
.SH DESCRIPTION
.IX Header "DESCRIPTION"
This API is currently private and subject to change.
.PP
The \f(CW\*(C`ExtUtils::ParseXS::Node\*(C'\fR class, and its various subclasses, hold the
state for the nodes of an Abstract Syntax Tree (AST), which represents the
parsed state of an XS file.
.PP
Each node is a hash of fields. Which field names are legal varies by the
node type. The hash keys and values can be accessed directly: there are no
getter/setter methods.
.PP
Each node may have a \f(CW\*(C`kids\*(C'\fR field which points to an array of all the
children of that node: this is what provides the tree structure. In
addition, some of those kids may also have direct links from fields for
quick access. For example, the \f(CW\*(C`xsub_decl\*(C'\fR child object of an \f(CW\*(C`xsub\*(C'\fR
object can be accessed in either of these ways:
.PP
.Vb 2
\&    $xsub_object\->{kids}[0]
\&    $xsub_object\->{decl}
.Ve
.PP
Most object\-valued node fields within a tree point only to their direct
children; however, both \f(CW\*(C`INPUT_line\*(C'\fR and \f(CW\*(C`OUTPUT_line\*(C'\fR have an
\&\f(CW\*(C`ioparam\*(C'\fR field which points to the \f(CW\*(C`IO_Param\*(C'\fR object associated with
this line, which is located elsewhere in the tree.
.PP
The various \f(CW\*(C`foo_part\*(C'\fR nodes divide the parsing of the main body of an
XSUB into sections where different sets of keywords are allowable, and
where various bits of code can be conveniently emitted.
.SS Methods
.IX Subsection "Methods"
There are two main methods in addition to \f(CWnew()\fR, which are present in
all subclasses. First, \f(CWparse()\fR consumes lines from the source to
satisfy the construct being parsed. It may itself create objects of
lower\-level constructs and call parse on them. For example,
\&\f(CWNode::xbody::parse()\fR may create a \f(CW\*(C`Node::input_part\*(C'\fR node and call
\&\f(CWparse()\fR on it, which will create \f(CW\*(C`Node::INPUT\*(C'\fR or \f(CW\*(C`Node::PREINIT\*(C'\fR
nodes as appropriate, and so on.
.PP
Secondly, \f(CWas_code()\fR descends its sub\-tree, outputting the tree as C
code.
.PP
The \f(CWas_concise()\fR method returns a line\-per\-node string representation
of the node and any children. Most node classes just inherit this method
from the base \f(CW\*(C`Node\*(C'\fR class. It is intended mainly for debugging.
.PP
Some nodes also have an \f(CWas_boot_code()\fR method for adding any code to
the boot XSUB. This returns two array refs, one containing a list of code
lines to be inserted early into the boot XSUB, and a second for later
lines.
.PP
Finally, in the IO_Param subclass, \f(CWas_code()\fR is replaced with
\&\f(CW\*(C`as_input_code\*(C'\fR and \f(CWas_output_code()\fR, since that node may need to
generate \fItwo\fR sets of C code; one to assign a Perl argument to a C
variable, and the other to return the value of a variable to Perl.
.PP
Note that parsing and code\-generation are done as two separate phases;
\&\f(CWparse()\fR should only build a tree and never emit code.
.PP
In addition to \f(CW$self\fR, methods may commonly have some of these
parameters:
.ie n .IP $pxs 4
.el .IP \f(CW$pxs\fR 4
.IX Item "$pxs"
An \f(CW\*(C`ExtUtils::ParseXS\*(C'\fR object which contains the overall processing
state. In particular, it has warning and croaking methods, and holds the
lines read in from the source file for the current paragraph.
.ie n .IP $xsub 4
.el .IP \f(CW$xsub\fR 4
.IX Item "$xsub"
For nodes related to parsing an XSUB, the current
\&\f(CW\*(C`ExtUtils::ParseXS::xsub\*(C'\fR node being processed.
.ie n .IP $xbody 4
.el .IP \f(CW$xbody\fR 4
.IX Item "$xbody"
For nodes related to parsing an XSUB, the current
\&\f(CW\*(C`ExtUtils::ParseXS::xbody\*(C'\fR node being processed. Note that in the
presence of a \f(CW\*(C`CASE\*(C'\fR keyword, an XSUB can have multiple bodies.
.PP
The \f(CWparse()\fR and \f(CWas_code()\fR methods for some subclasses may have
parameters in addition to those.
.PP
Some subclasses may also have additional helper methods.
.SS "Class Hierachy"
.IX Subsection "Class Hierachy"
\&\f(CW\*(C`Node\*(C'\fR and its sub\-classes form the following inheritance hierarchy.
Various abstract classes are used by concrete subclasses where the
processing and/or fields are similar: for example, \f(CW\*(C`CODE\*(C'\fR, \f(CW\*(C`PPCODE\*(C'\fR etc
all consume a block of uninterpreted lines from the source file until the
next keyword, and emit that code, possibly wrapped in \f(CW\*(C`#line\*(C'\fR directives.
This common behaviour is provided by the \f(CW\*(C`codeblock\*(C'\fR class.
.PP
.Vb 10
\&    Node
\&        XS_file
\&        preamble
\&        C_part
\&        C_part_POD
\&        C_part_code
\&        C_part_postamble
\&        cpp_scope
\&        global_cpp_line
\&        BOOT
\&        TYPEMAP
\&        pre_boot
\&        boot_xsub
\&        xsub
\&        xsub_decl
\&        ReturnType
\&        Param
\&            IO_Param
\&        Params
\&        xbody
\&        input_part
\&        init_part
\&        code_part
\&        output_part
\&        cleanup_part
\&        autocall
\&        oneline
\&            MODULE
\&            REQUIRE
\&            FALLBACK
\&            include
\&                INCLUDE
\&                INCLUDE_COMMAND
\&            NOT_IMPLEMENTED_YET
\&            CASE
\&            enable
\&                EXPORT_XSUB_SYMBOLS
\&                PROTOTYPES
\&                SCOPE
\&                VERSIONCHECK
\&        multiline
\&            multiline_merged
\&                C_ARGS
\&                INTERFACE
\&                INTERFACE_MACRO
\&                OVERLOAD
\&            ATTRS
\&            PROTOTYPE
\&            codeblock
\&                CODE
\&                CLEANUP
\&                INIT
\&                POSTCALL
\&                PPCODE
\&                PREINIT
\&        keylines
\&            ALIAS
\&            INPUT
\&            OUTPUT
\&        keyline
\&            ALIAS_line
\&            INPUT_line
\&            OUTPUT_line
.Ve
.SS "Abstract Syntax Tree structure"
.IX Subsection "Abstract Syntax Tree structure"
A typical XS file might compile to a tree with a node structure similar to
the following. Note that this is unrelated to the inheritance hierarchy
shown above. In this example, the XS file includes another file, and has a
couple of XSUBs within a \f(CW\*(C`#if/#else/#endif\*(C'\fR. Note that a \f(CW\*(C`cpp_scope\*(C'\fR
node is the parent of all the nodes within the same branch of an \f(CW\*(C`#if\*(C'\fR,
or in the absence of \f(CW\*(C`#if\*(C'\fR, within the same file.
.PP
.Vb 10
\&    XS_file
\&        preamble
\&        C_part
\&            C_part_POD
\&            C_part_code
\&        C_part_postamble
\&        cpp_scope: type="main"
\&            MODULE
\&            PROTOTYPES
\&            BOOT
\&            TYPEMAP
\&            INCLUDE
\&                cpp_scope: type="include"
\&                    xsub
\&                        ...
\&            global_cpp_line: directive="ifdef"
\&            cpp_scope: type="if"
\&                xsub
\&                    ...
\&            global_cpp_line: directive="else"
\&            cpp_scope: type="if"
\&                xsub
\&                    ...
\&            global_cpp_line: directive="endif"
\&            xsub
\&                ...
\&        pre_boot
\&        boot_xsub
.Ve
.PP
A typical XSUB might compile to a tree with a structure similar to the
following.
.PP
.Vb 10
\&    xsub
\&        xsub_decl
\&            ReturnType
\&            Params
\&                Param
\&                Param
\&                ...
\&        CASE   # for when a CASE keyword being present implies multiple
\&               # bodies; otherwise, just a bare xbody node.
\&            xbody
\&                # per\-body copy of declaration Params, augmented by
\&                # data from INPUT and OUTPUT sections
\&                Params
\&                    IO_Param
\&                    IO_Param
\&                    ...
\&                input_part
\&                    INPUT
\&                        INPUT_line
\&                        INPUT_line
\&                        ...
\&                    PREINIT
\&                init_part
\&                    INIT
\&                code_part
\&                    CODE
\&                output_part
\&                    OUTPUT
\&                        OUTPUT_line
\&                        OUTPUT_line
\&                        ...
\&                    POSTCALL
\&                cleanup_part
\&                    CLEANUP
\&        CASE
\&            xbody
\&                ...
.Ve
