/******************************************************************************/
/* This file is generated by the templates/template.rb script and should not  */
/* be modified manually. See                                                  */
/* templates/include/prism/ast.h.erb                                          */
/* if you are looking to modify the                                           */
/* template                                                                   */
/******************************************************************************/
/**
 * @file ast.h
 *
 * The abstract syntax tree.
 */
#ifndef PRISM_AST_H
#define PRISM_AST_H

#include "prism/defines.h"
#include "prism/util/pm_constant_pool.h"
#include "prism/util/pm_string.h"

#include <assert.h>
#include <stddef.h>
#include <stdint.h>

/**
 * This enum represents every type of token in the Ruby source.
 */
typedef enum pm_token_type {
    /** final token in the file */
    PM_TOKEN_EOF = 1,

    /** a token that was expected but not found */
    PM_TOKEN_MISSING,

    /** a token that was not present but it is okay */
    PM_TOKEN_NOT_PROVIDED,

    /** & */
    PM_TOKEN_AMPERSAND,

    /** && */
    PM_TOKEN_AMPERSAND_AMPERSAND,

    /** &&= */
    PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL,

    /** &. */
    PM_TOKEN_AMPERSAND_DOT,

    /** &= */
    PM_TOKEN_AMPERSAND_EQUAL,

    /** ` */
    PM_TOKEN_BACKTICK,

    /** a back reference */
    PM_TOKEN_BACK_REFERENCE,

    /** ! or !@ */
    PM_TOKEN_BANG,

    /** != */
    PM_TOKEN_BANG_EQUAL,

    /** !~ */
    PM_TOKEN_BANG_TILDE,

    /** { */
    PM_TOKEN_BRACE_LEFT,

    /** } */
    PM_TOKEN_BRACE_RIGHT,

    /** [ */
    PM_TOKEN_BRACKET_LEFT,

    /** [ for the beginning of an array */
    PM_TOKEN_BRACKET_LEFT_ARRAY,

    /** [] */
    PM_TOKEN_BRACKET_LEFT_RIGHT,

    /** []= */
    PM_TOKEN_BRACKET_LEFT_RIGHT_EQUAL,

    /** ] */
    PM_TOKEN_BRACKET_RIGHT,

    /** ^ */
    PM_TOKEN_CARET,

    /** ^= */
    PM_TOKEN_CARET_EQUAL,

    /** a character literal */
    PM_TOKEN_CHARACTER_LITERAL,

    /** a class variable */
    PM_TOKEN_CLASS_VARIABLE,

    /** : */
    PM_TOKEN_COLON,

    /** :: */
    PM_TOKEN_COLON_COLON,

    /** , */
    PM_TOKEN_COMMA,

    /** a comment */
    PM_TOKEN_COMMENT,

    /** a constant */
    PM_TOKEN_CONSTANT,

    /** the . call operator */
    PM_TOKEN_DOT,

    /** the .. range operator */
    PM_TOKEN_DOT_DOT,

    /** the ... range operator or forwarding parameter */
    PM_TOKEN_DOT_DOT_DOT,

    /** =begin */
    PM_TOKEN_EMBDOC_BEGIN,

    /** =end */
    PM_TOKEN_EMBDOC_END,

    /** a line inside of embedded documentation */
    PM_TOKEN_EMBDOC_LINE,

    /** #{ */
    PM_TOKEN_EMBEXPR_BEGIN,

    /** } */
    PM_TOKEN_EMBEXPR_END,

    /** # */
    PM_TOKEN_EMBVAR,

    /** = */
    PM_TOKEN_EQUAL,

    /** == */
    PM_TOKEN_EQUAL_EQUAL,

    /** === */
    PM_TOKEN_EQUAL_EQUAL_EQUAL,

    /** => */
    PM_TOKEN_EQUAL_GREATER,

    /** =~ */
    PM_TOKEN_EQUAL_TILDE,

    /** a floating point number */
    PM_TOKEN_FLOAT,

    /** a floating pointer number with an imaginary suffix */
    PM_TOKEN_FLOAT_IMAGINARY,

    /** a floating pointer number with a rational suffix */
    PM_TOKEN_FLOAT_RATIONAL,

    /** a floating pointer number with a rational and imaginary suffix */
    PM_TOKEN_FLOAT_RATIONAL_IMAGINARY,

    /** a global variable */
    PM_TOKEN_GLOBAL_VARIABLE,

    /** > */
    PM_TOKEN_GREATER,

    /** >= */
    PM_TOKEN_GREATER_EQUAL,

    /** >> */
    PM_TOKEN_GREATER_GREATER,

    /** >>= */
    PM_TOKEN_GREATER_GREATER_EQUAL,

    /** the end of a heredoc */
    PM_TOKEN_HEREDOC_END,

    /** the start of a heredoc */
    PM_TOKEN_HEREDOC_START,

    /** an identifier */
    PM_TOKEN_IDENTIFIER,

    /** an ignored newline */
    PM_TOKEN_IGNORED_NEWLINE,

    /** an instance variable */
    PM_TOKEN_INSTANCE_VARIABLE,

    /** an integer (any base) */
    PM_TOKEN_INTEGER,

    /** an integer with an imaginary suffix */
    PM_TOKEN_INTEGER_IMAGINARY,

    /** an integer with a rational suffix */
    PM_TOKEN_INTEGER_RATIONAL,

    /** an integer with a rational and imaginary suffix */
    PM_TOKEN_INTEGER_RATIONAL_IMAGINARY,

    /** alias */
    PM_TOKEN_KEYWORD_ALIAS,

    /** and */
    PM_TOKEN_KEYWORD_AND,

    /** begin */
    PM_TOKEN_KEYWORD_BEGIN,

    /** BEGIN */
    PM_TOKEN_KEYWORD_BEGIN_UPCASE,

    /** break */
    PM_TOKEN_KEYWORD_BREAK,

    /** case */
    PM_TOKEN_KEYWORD_CASE,

    /** class */
    PM_TOKEN_KEYWORD_CLASS,

    /** def */
    PM_TOKEN_KEYWORD_DEF,

    /** defined? */
    PM_TOKEN_KEYWORD_DEFINED,

    /** do */
    PM_TOKEN_KEYWORD_DO,

    /** do keyword for a predicate in a while, until, or for loop */
    PM_TOKEN_KEYWORD_DO_LOOP,

    /** else */
    PM_TOKEN_KEYWORD_ELSE,

    /** elsif */
    PM_TOKEN_KEYWORD_ELSIF,

    /** end */
    PM_TOKEN_KEYWORD_END,

    /** END */
    PM_TOKEN_KEYWORD_END_UPCASE,

    /** ensure */
    PM_TOKEN_KEYWORD_ENSURE,

    /** false */
    PM_TOKEN_KEYWORD_FALSE,

    /** for */
    PM_TOKEN_KEYWORD_FOR,

    /** if */
    PM_TOKEN_KEYWORD_IF,

    /** if in the modifier form */
    PM_TOKEN_KEYWORD_IF_MODIFIER,

    /** in */
    PM_TOKEN_KEYWORD_IN,

    /** module */
    PM_TOKEN_KEYWORD_MODULE,

    /** next */
    PM_TOKEN_KEYWORD_NEXT,

    /** nil */
    PM_TOKEN_KEYWORD_NIL,

    /** not */
    PM_TOKEN_KEYWORD_NOT,

    /** or */
    PM_TOKEN_KEYWORD_OR,

    /** redo */
    PM_TOKEN_KEYWORD_REDO,

    /** rescue */
    PM_TOKEN_KEYWORD_RESCUE,

    /** rescue in the modifier form */
    PM_TOKEN_KEYWORD_RESCUE_MODIFIER,

    /** retry */
    PM_TOKEN_KEYWORD_RETRY,

    /** return */
    PM_TOKEN_KEYWORD_RETURN,

    /** self */
    PM_TOKEN_KEYWORD_SELF,

    /** super */
    PM_TOKEN_KEYWORD_SUPER,

    /** then */
    PM_TOKEN_KEYWORD_THEN,

    /** true */
    PM_TOKEN_KEYWORD_TRUE,

    /** undef */
    PM_TOKEN_KEYWORD_UNDEF,

    /** unless */
    PM_TOKEN_KEYWORD_UNLESS,

    /** unless in the modifier form */
    PM_TOKEN_KEYWORD_UNLESS_MODIFIER,

    /** until */
    PM_TOKEN_KEYWORD_UNTIL,

    /** until in the modifier form */
    PM_TOKEN_KEYWORD_UNTIL_MODIFIER,

    /** when */
    PM_TOKEN_KEYWORD_WHEN,

    /** while */
    PM_TOKEN_KEYWORD_WHILE,

    /** while in the modifier form */
    PM_TOKEN_KEYWORD_WHILE_MODIFIER,

    /** yield */
    PM_TOKEN_KEYWORD_YIELD,

    /** __ENCODING__ */
    PM_TOKEN_KEYWORD___ENCODING__,

    /** __FILE__ */
    PM_TOKEN_KEYWORD___FILE__,

    /** __LINE__ */
    PM_TOKEN_KEYWORD___LINE__,

    /** a label */
    PM_TOKEN_LABEL,

    /** the end of a label */
    PM_TOKEN_LABEL_END,

    /** { */
    PM_TOKEN_LAMBDA_BEGIN,

    /** < */
    PM_TOKEN_LESS,

    /** <= */
    PM_TOKEN_LESS_EQUAL,

    /** <=> */
    PM_TOKEN_LESS_EQUAL_GREATER,

    /** << */
    PM_TOKEN_LESS_LESS,

    /** <<= */
    PM_TOKEN_LESS_LESS_EQUAL,

    /** a method name */
    PM_TOKEN_METHOD_NAME,

    /** - */
    PM_TOKEN_MINUS,

    /** -= */
    PM_TOKEN_MINUS_EQUAL,

    /** -> */
    PM_TOKEN_MINUS_GREATER,

    /** a newline character outside of other tokens */
    PM_TOKEN_NEWLINE,

    /** a numbered reference to a capture group in the previous regular expression match */
    PM_TOKEN_NUMBERED_REFERENCE,

    /** ( */
    PM_TOKEN_PARENTHESIS_LEFT,

    /** ( for a parentheses node */
    PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES,

    /** ) */
    PM_TOKEN_PARENTHESIS_RIGHT,

    /** % */
    PM_TOKEN_PERCENT,

    /** %= */
    PM_TOKEN_PERCENT_EQUAL,

    /** %i */
    PM_TOKEN_PERCENT_LOWER_I,

    /** %w */
    PM_TOKEN_PERCENT_LOWER_W,

    /** %x */
    PM_TOKEN_PERCENT_LOWER_X,

    /** %I */
    PM_TOKEN_PERCENT_UPPER_I,

    /** %W */
    PM_TOKEN_PERCENT_UPPER_W,

    /** | */
    PM_TOKEN_PIPE,

    /** |= */
    PM_TOKEN_PIPE_EQUAL,

    /** || */
    PM_TOKEN_PIPE_PIPE,

    /** ||= */
    PM_TOKEN_PIPE_PIPE_EQUAL,

    /** + */
    PM_TOKEN_PLUS,

    /** += */
    PM_TOKEN_PLUS_EQUAL,

    /** ? */
    PM_TOKEN_QUESTION_MARK,

    /** the beginning of a regular expression */
    PM_TOKEN_REGEXP_BEGIN,

    /** the end of a regular expression */
    PM_TOKEN_REGEXP_END,

    /** ; */
    PM_TOKEN_SEMICOLON,

    /** / */
    PM_TOKEN_SLASH,

    /** /= */
    PM_TOKEN_SLASH_EQUAL,

    /** * */
    PM_TOKEN_STAR,

    /** *= */
    PM_TOKEN_STAR_EQUAL,

    /** ** */
    PM_TOKEN_STAR_STAR,

    /** **= */
    PM_TOKEN_STAR_STAR_EQUAL,

    /** the beginning of a string */
    PM_TOKEN_STRING_BEGIN,

    /** the contents of a string */
    PM_TOKEN_STRING_CONTENT,

    /** the end of a string */
    PM_TOKEN_STRING_END,

    /** the beginning of a symbol */
    PM_TOKEN_SYMBOL_BEGIN,

    /** ~ or ~@ */
    PM_TOKEN_TILDE,

    /** unary & */
    PM_TOKEN_UAMPERSAND,

    /** unary :: */
    PM_TOKEN_UCOLON_COLON,

    /** unary .. operator */
    PM_TOKEN_UDOT_DOT,

    /** unary ... operator */
    PM_TOKEN_UDOT_DOT_DOT,

    /** -@ */
    PM_TOKEN_UMINUS,

    /** -@ for a number */
    PM_TOKEN_UMINUS_NUM,

    /** +@ */
    PM_TOKEN_UPLUS,

    /** unary * */
    PM_TOKEN_USTAR,

    /** unary ** */
    PM_TOKEN_USTAR_STAR,

    /** a separator between words in a list */
    PM_TOKEN_WORDS_SEP,

    /** marker for the point in the file at which the parser should stop */
    PM_TOKEN___END__,

    /** The maximum token value. */
    PM_TOKEN_MAXIMUM,
} pm_token_type_t;

/**
 * This struct represents a token in the Ruby source. We use it to track both
 * type and location information.
 */
typedef struct {
    /** The type of the token. */
    pm_token_type_t type;

    /** A pointer to the start location of the token in the source. */
    const uint8_t *start;

    /** A pointer to the end location of the token in the source. */
    const uint8_t *end;
} pm_token_t;

/**
 * This represents a range of bytes in the source string to which a node or
 * token corresponds.
 */
typedef struct {
    /** A pointer to the start location of the range in the source. */
    const uint8_t *start;

    /** A pointer to the end location of the range in the source. */
    const uint8_t *end;
} pm_location_t;

struct pm_node;

/**
 * A list of nodes in the source, most often used for lists of children.
 */
typedef struct pm_node_list {
    /** The number of nodes in the list. */
    size_t size;

    /** The capacity of the list that has been allocated. */
    size_t capacity;

    /** The nodes in the list. */
    struct pm_node **nodes;
} pm_node_list_t;

/**
 * This enum represents every type of node in the Ruby syntax tree.
 */
enum pm_node_type {
    /** AliasGlobalVariableNode */
    PM_ALIAS_GLOBAL_VARIABLE_NODE = 1,

    /** AliasMethodNode */
    PM_ALIAS_METHOD_NODE = 2,

    /** AlternationPatternNode */
    PM_ALTERNATION_PATTERN_NODE = 3,

    /** AndNode */
    PM_AND_NODE = 4,

    /** ArgumentsNode */
    PM_ARGUMENTS_NODE = 5,

    /** ArrayNode */
    PM_ARRAY_NODE = 6,

    /** ArrayPatternNode */
    PM_ARRAY_PATTERN_NODE = 7,

    /** AssocNode */
    PM_ASSOC_NODE = 8,

    /** AssocSplatNode */
    PM_ASSOC_SPLAT_NODE = 9,

    /** BackReferenceReadNode */
    PM_BACK_REFERENCE_READ_NODE = 10,

    /** BeginNode */
    PM_BEGIN_NODE = 11,

    /** BlockArgumentNode */
    PM_BLOCK_ARGUMENT_NODE = 12,

    /** BlockLocalVariableNode */
    PM_BLOCK_LOCAL_VARIABLE_NODE = 13,

    /** BlockNode */
    PM_BLOCK_NODE = 14,

    /** BlockParameterNode */
    PM_BLOCK_PARAMETER_NODE = 15,

    /** BlockParametersNode */
    PM_BLOCK_PARAMETERS_NODE = 16,

    /** BreakNode */
    PM_BREAK_NODE = 17,

    /** CallAndWriteNode */
    PM_CALL_AND_WRITE_NODE = 18,

    /** CallNode */
    PM_CALL_NODE = 19,

    /** CallOperatorWriteNode */
    PM_CALL_OPERATOR_WRITE_NODE = 20,

    /** CallOrWriteNode */
    PM_CALL_OR_WRITE_NODE = 21,

    /** CallTargetNode */
    PM_CALL_TARGET_NODE = 22,

    /** CapturePatternNode */
    PM_CAPTURE_PATTERN_NODE = 23,

    /** CaseMatchNode */
    PM_CASE_MATCH_NODE = 24,

    /** CaseNode */
    PM_CASE_NODE = 25,

    /** ClassNode */
    PM_CLASS_NODE = 26,

    /** ClassVariableAndWriteNode */
    PM_CLASS_VARIABLE_AND_WRITE_NODE = 27,

    /** ClassVariableOperatorWriteNode */
    PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE = 28,

    /** ClassVariableOrWriteNode */
    PM_CLASS_VARIABLE_OR_WRITE_NODE = 29,

    /** ClassVariableReadNode */
    PM_CLASS_VARIABLE_READ_NODE = 30,

    /** ClassVariableTargetNode */
    PM_CLASS_VARIABLE_TARGET_NODE = 31,

    /** ClassVariableWriteNode */
    PM_CLASS_VARIABLE_WRITE_NODE = 32,

    /** ConstantAndWriteNode */
    PM_CONSTANT_AND_WRITE_NODE = 33,

    /** ConstantOperatorWriteNode */
    PM_CONSTANT_OPERATOR_WRITE_NODE = 34,

    /** ConstantOrWriteNode */
    PM_CONSTANT_OR_WRITE_NODE = 35,

    /** ConstantPathAndWriteNode */
    PM_CONSTANT_PATH_AND_WRITE_NODE = 36,

    /** ConstantPathNode */
    PM_CONSTANT_PATH_NODE = 37,

    /** ConstantPathOperatorWriteNode */
    PM_CONSTANT_PATH_OPERATOR_WRITE_NODE = 38,

    /** ConstantPathOrWriteNode */
    PM_CONSTANT_PATH_OR_WRITE_NODE = 39,

    /** ConstantPathTargetNode */
    PM_CONSTANT_PATH_TARGET_NODE = 40,

    /** ConstantPathWriteNode */
    PM_CONSTANT_PATH_WRITE_NODE = 41,

    /** ConstantReadNode */
    PM_CONSTANT_READ_NODE = 42,

    /** ConstantTargetNode */
    PM_CONSTANT_TARGET_NODE = 43,

    /** ConstantWriteNode */
    PM_CONSTANT_WRITE_NODE = 44,

    /** DefNode */
    PM_DEF_NODE = 45,

    /** DefinedNode */
    PM_DEFINED_NODE = 46,

    /** ElseNode */
    PM_ELSE_NODE = 47,

    /** EmbeddedStatementsNode */
    PM_EMBEDDED_STATEMENTS_NODE = 48,

    /** EmbeddedVariableNode */
    PM_EMBEDDED_VARIABLE_NODE = 49,

    /** EnsureNode */
    PM_ENSURE_NODE = 50,

    /** FalseNode */
    PM_FALSE_NODE = 51,

    /** FindPatternNode */
    PM_FIND_PATTERN_NODE = 52,

    /** FlipFlopNode */
    PM_FLIP_FLOP_NODE = 53,

    /** FloatNode */
    PM_FLOAT_NODE = 54,

    /** ForNode */
    PM_FOR_NODE = 55,

    /** ForwardingArgumentsNode */
    PM_FORWARDING_ARGUMENTS_NODE = 56,

    /** ForwardingParameterNode */
    PM_FORWARDING_PARAMETER_NODE = 57,

    /** ForwardingSuperNode */
    PM_FORWARDING_SUPER_NODE = 58,

    /** GlobalVariableAndWriteNode */
    PM_GLOBAL_VARIABLE_AND_WRITE_NODE = 59,

    /** GlobalVariableOperatorWriteNode */
    PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE = 60,

    /** GlobalVariableOrWriteNode */
    PM_GLOBAL_VARIABLE_OR_WRITE_NODE = 61,

    /** GlobalVariableReadNode */
    PM_GLOBAL_VARIABLE_READ_NODE = 62,

    /** GlobalVariableTargetNode */
    PM_GLOBAL_VARIABLE_TARGET_NODE = 63,

    /** GlobalVariableWriteNode */
    PM_GLOBAL_VARIABLE_WRITE_NODE = 64,

    /** HashNode */
    PM_HASH_NODE = 65,

    /** HashPatternNode */
    PM_HASH_PATTERN_NODE = 66,

    /** IfNode */
    PM_IF_NODE = 67,

    /** ImaginaryNode */
    PM_IMAGINARY_NODE = 68,

    /** ImplicitNode */
    PM_IMPLICIT_NODE = 69,

    /** ImplicitRestNode */
    PM_IMPLICIT_REST_NODE = 70,

    /** InNode */
    PM_IN_NODE = 71,

    /** IndexAndWriteNode */
    PM_INDEX_AND_WRITE_NODE = 72,

    /** IndexOperatorWriteNode */
    PM_INDEX_OPERATOR_WRITE_NODE = 73,

    /** IndexOrWriteNode */
    PM_INDEX_OR_WRITE_NODE = 74,

    /** IndexTargetNode */
    PM_INDEX_TARGET_NODE = 75,

    /** InstanceVariableAndWriteNode */
    PM_INSTANCE_VARIABLE_AND_WRITE_NODE = 76,

    /** InstanceVariableOperatorWriteNode */
    PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE = 77,

    /** InstanceVariableOrWriteNode */
    PM_INSTANCE_VARIABLE_OR_WRITE_NODE = 78,

    /** InstanceVariableReadNode */
    PM_INSTANCE_VARIABLE_READ_NODE = 79,

    /** InstanceVariableTargetNode */
    PM_INSTANCE_VARIABLE_TARGET_NODE = 80,

    /** InstanceVariableWriteNode */
    PM_INSTANCE_VARIABLE_WRITE_NODE = 81,

    /** IntegerNode */
    PM_INTEGER_NODE = 82,

    /** InterpolatedMatchLastLineNode */
    PM_INTERPOLATED_MATCH_LAST_LINE_NODE = 83,

    /** InterpolatedRegularExpressionNode */
    PM_INTERPOLATED_REGULAR_EXPRESSION_NODE = 84,

    /** InterpolatedStringNode */
    PM_INTERPOLATED_STRING_NODE = 85,

    /** InterpolatedSymbolNode */
    PM_INTERPOLATED_SYMBOL_NODE = 86,

    /** InterpolatedXStringNode */
    PM_INTERPOLATED_X_STRING_NODE = 87,

    /** KeywordHashNode */
    PM_KEYWORD_HASH_NODE = 88,

    /** KeywordRestParameterNode */
    PM_KEYWORD_REST_PARAMETER_NODE = 89,

    /** LambdaNode */
    PM_LAMBDA_NODE = 90,

    /** LocalVariableAndWriteNode */
    PM_LOCAL_VARIABLE_AND_WRITE_NODE = 91,

    /** LocalVariableOperatorWriteNode */
    PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE = 92,

    /** LocalVariableOrWriteNode */
    PM_LOCAL_VARIABLE_OR_WRITE_NODE = 93,

    /** LocalVariableReadNode */
    PM_LOCAL_VARIABLE_READ_NODE = 94,

    /** LocalVariableTargetNode */
    PM_LOCAL_VARIABLE_TARGET_NODE = 95,

    /** LocalVariableWriteNode */
    PM_LOCAL_VARIABLE_WRITE_NODE = 96,

    /** MatchLastLineNode */
    PM_MATCH_LAST_LINE_NODE = 97,

    /** MatchPredicateNode */
    PM_MATCH_PREDICATE_NODE = 98,

    /** MatchRequiredNode */
    PM_MATCH_REQUIRED_NODE = 99,

    /** MatchWriteNode */
    PM_MATCH_WRITE_NODE = 100,

    /** MissingNode */
    PM_MISSING_NODE = 101,

    /** ModuleNode */
    PM_MODULE_NODE = 102,

    /** MultiTargetNode */
    PM_MULTI_TARGET_NODE = 103,

    /** MultiWriteNode */
    PM_MULTI_WRITE_NODE = 104,

    /** NextNode */
    PM_NEXT_NODE = 105,

    /** NilNode */
    PM_NIL_NODE = 106,

    /** NoKeywordsParameterNode */
    PM_NO_KEYWORDS_PARAMETER_NODE = 107,

    /** NumberedParametersNode */
    PM_NUMBERED_PARAMETERS_NODE = 108,

    /** NumberedReferenceReadNode */
    PM_NUMBERED_REFERENCE_READ_NODE = 109,

    /** OptionalKeywordParameterNode */
    PM_OPTIONAL_KEYWORD_PARAMETER_NODE = 110,

    /** OptionalParameterNode */
    PM_OPTIONAL_PARAMETER_NODE = 111,

    /** OrNode */
    PM_OR_NODE = 112,

    /** ParametersNode */
    PM_PARAMETERS_NODE = 113,

    /** ParenthesesNode */
    PM_PARENTHESES_NODE = 114,

    /** PinnedExpressionNode */
    PM_PINNED_EXPRESSION_NODE = 115,

    /** PinnedVariableNode */
    PM_PINNED_VARIABLE_NODE = 116,

    /** PostExecutionNode */
    PM_POST_EXECUTION_NODE = 117,

    /** PreExecutionNode */
    PM_PRE_EXECUTION_NODE = 118,

    /** ProgramNode */
    PM_PROGRAM_NODE = 119,

    /** RangeNode */
    PM_RANGE_NODE = 120,

    /** RationalNode */
    PM_RATIONAL_NODE = 121,

    /** RedoNode */
    PM_REDO_NODE = 122,

    /** RegularExpressionNode */
    PM_REGULAR_EXPRESSION_NODE = 123,

    /** RequiredKeywordParameterNode */
    PM_REQUIRED_KEYWORD_PARAMETER_NODE = 124,

    /** RequiredParameterNode */
    PM_REQUIRED_PARAMETER_NODE = 125,

    /** RescueModifierNode */
    PM_RESCUE_MODIFIER_NODE = 126,

    /** RescueNode */
    PM_RESCUE_NODE = 127,

    /** RestParameterNode */
    PM_REST_PARAMETER_NODE = 128,

    /** RetryNode */
    PM_RETRY_NODE = 129,

    /** ReturnNode */
    PM_RETURN_NODE = 130,

    /** SelfNode */
    PM_SELF_NODE = 131,

    /** SingletonClassNode */
    PM_SINGLETON_CLASS_NODE = 132,

    /** SourceEncodingNode */
    PM_SOURCE_ENCODING_NODE = 133,

    /** SourceFileNode */
    PM_SOURCE_FILE_NODE = 134,

    /** SourceLineNode */
    PM_SOURCE_LINE_NODE = 135,

    /** SplatNode */
    PM_SPLAT_NODE = 136,

    /** StatementsNode */
    PM_STATEMENTS_NODE = 137,

    /** StringNode */
    PM_STRING_NODE = 138,

    /** SuperNode */
    PM_SUPER_NODE = 139,

    /** SymbolNode */
    PM_SYMBOL_NODE = 140,

    /** TrueNode */
    PM_TRUE_NODE = 141,

    /** UndefNode */
    PM_UNDEF_NODE = 142,

    /** UnlessNode */
    PM_UNLESS_NODE = 143,

    /** UntilNode */
    PM_UNTIL_NODE = 144,

    /** WhenNode */
    PM_WHEN_NODE = 145,

    /** WhileNode */
    PM_WHILE_NODE = 146,

    /** XStringNode */
    PM_X_STRING_NODE = 147,

    /** YieldNode */
    PM_YIELD_NODE = 148,

    /** A special kind of node used for compilation. */
    PM_SCOPE_NODE
};

/**
 * This is the type of node embedded in the node struct. We explicitly control
 * the size of it here to avoid having the variable-width enum.
 */
typedef uint16_t pm_node_type_t;

/**
 * These are the flags embedded in the node struct. We explicitly control the
 * size of it here to avoid having the variable-width enum.
 */
typedef uint16_t pm_node_flags_t;

/**
 * We store the flags enum in every node in the tree. Some flags are common to
 * all nodes (the ones listed below). Others are specific to certain node types.
 */
#define PM_NODE_FLAG_BITS (sizeof(pm_node_flags_t) * 8)

static const pm_node_flags_t PM_NODE_FLAG_NEWLINE = (1 << (PM_NODE_FLAG_BITS - 1));
static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = (1 << (PM_NODE_FLAG_BITS - 2));
static const pm_node_flags_t PM_NODE_FLAG_COMMON_MASK = (1 << (PM_NODE_FLAG_BITS - 1)) | (1 << (PM_NODE_FLAG_BITS - 2));

/**
 * Cast the type to an enum to allow the compiler to provide exhaustiveness
 * checking.
 */
#define PM_NODE_TYPE(node) ((enum pm_node_type) node->type)

/**
 * Return true if the type of the given node matches the given type.
 */
#define PM_NODE_TYPE_P(node, type) (PM_NODE_TYPE(node) == (type))

/**
 * Return true if the given flag is set on the given node.
 */
#define PM_NODE_FLAG_P(node, flag) ((((pm_node_t *)(node))->flags & (flag)) != 0)

/**
 * This is the base structure that represents a node in the syntax tree. It is
 * embedded into every node type.
 */
typedef struct pm_node {
    /**
     * This represents the type of the node. It somewhat maps to the nodes that
     * existed in the original grammar and ripper, but it's not a 1:1 mapping.
     */
    pm_node_type_t type;

    /**
     * This represents any flags on the node. Some are common to all nodes, and
     * some are specific to the type of node.
     */
    pm_node_flags_t flags;

    /**
     * This is the location of the node in the source. It's a range of bytes
     * containing a start and an end.
     */
    pm_location_t location;
} pm_node_t;

/**
 * AliasGlobalVariableNode
 *
 * Type: PM_ALIAS_GLOBAL_VARIABLE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_alias_global_variable_node {
    /** The embedded base node. */
    pm_node_t base;

    /** AliasGlobalVariableNode#new_name */
    struct pm_node *new_name;

    /** AliasGlobalVariableNode#old_name */
    struct pm_node *old_name;

    /** AliasGlobalVariableNode#keyword_loc */
    pm_location_t keyword_loc;
} pm_alias_global_variable_node_t;

/**
 * AliasMethodNode
 *
 * Type: PM_ALIAS_METHOD_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_alias_method_node {
    /** The embedded base node. */
    pm_node_t base;

    /** AliasMethodNode#new_name */
    struct pm_node *new_name;

    /** AliasMethodNode#old_name */
    struct pm_node *old_name;

    /** AliasMethodNode#keyword_loc */
    pm_location_t keyword_loc;
} pm_alias_method_node_t;

/**
 * AlternationPatternNode
 *
 * Type: PM_ALTERNATION_PATTERN_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_alternation_pattern_node {
    /** The embedded base node. */
    pm_node_t base;

    /** AlternationPatternNode#left */
    struct pm_node *left;

    /** AlternationPatternNode#right */
    struct pm_node *right;

    /** AlternationPatternNode#operator_loc */
    pm_location_t operator_loc;
} pm_alternation_pattern_node_t;

/**
 * AndNode
 *
 * Type: PM_AND_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_and_node {
    /** The embedded base node. */
    pm_node_t base;

    /** AndNode#left */
    struct pm_node *left;

    /** AndNode#right */
    struct pm_node *right;

    /** AndNode#operator_loc */
    pm_location_t operator_loc;
} pm_and_node_t;

/**
 * ArgumentsNode
 *
 * Type: PM_ARGUMENTS_NODE
 * Flags:
 *    PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT
 *
 * @extends pm_node_t
 */
typedef struct pm_arguments_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ArgumentsNode#arguments */
    struct pm_node_list arguments;
} pm_arguments_node_t;

/**
 * ArrayNode
 *
 * Type: PM_ARRAY_NODE
 * Flags:
 *    PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT
 *
 * @extends pm_node_t
 */
typedef struct pm_array_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ArrayNode#elements */
    struct pm_node_list elements;

    /** ArrayNode#opening_loc */
    pm_location_t opening_loc;

    /** ArrayNode#closing_loc */
    pm_location_t closing_loc;
} pm_array_node_t;

/**
 * ArrayPatternNode
 *
 * Type: PM_ARRAY_PATTERN_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_array_pattern_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ArrayPatternNode#constant */
    struct pm_node *constant;

    /** ArrayPatternNode#requireds */
    struct pm_node_list requireds;

    /** ArrayPatternNode#rest */
    struct pm_node *rest;

    /** ArrayPatternNode#posts */
    struct pm_node_list posts;

    /** ArrayPatternNode#opening_loc */
    pm_location_t opening_loc;

    /** ArrayPatternNode#closing_loc */
    pm_location_t closing_loc;
} pm_array_pattern_node_t;

/**
 * AssocNode
 *
 * Type: PM_ASSOC_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_assoc_node {
    /** The embedded base node. */
    pm_node_t base;

    /** AssocNode#key */
    struct pm_node *key;

    /** AssocNode#value */
    struct pm_node *value;

    /** AssocNode#operator_loc */
    pm_location_t operator_loc;
} pm_assoc_node_t;

/**
 * AssocSplatNode
 *
 * Type: PM_ASSOC_SPLAT_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_assoc_splat_node {
    /** The embedded base node. */
    pm_node_t base;

    /** AssocSplatNode#value */
    struct pm_node *value;

    /** AssocSplatNode#operator_loc */
    pm_location_t operator_loc;
} pm_assoc_splat_node_t;

/**
 * BackReferenceReadNode
 *
 * Type: PM_BACK_REFERENCE_READ_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_back_reference_read_node {
    /** The embedded base node. */
    pm_node_t base;

    /** BackReferenceReadNode#name */
    pm_constant_id_t name;
} pm_back_reference_read_node_t;

/**
 * BeginNode
 *
 * Type: PM_BEGIN_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_begin_node {
    /** The embedded base node. */
    pm_node_t base;

    /** BeginNode#begin_keyword_loc */
    pm_location_t begin_keyword_loc;

    /** BeginNode#statements */
    struct pm_statements_node *statements;

    /** BeginNode#rescue_clause */
    struct pm_rescue_node *rescue_clause;

    /** BeginNode#else_clause */
    struct pm_else_node *else_clause;

    /** BeginNode#ensure_clause */
    struct pm_ensure_node *ensure_clause;

    /** BeginNode#end_keyword_loc */
    pm_location_t end_keyword_loc;
} pm_begin_node_t;

/**
 * BlockArgumentNode
 *
 * Type: PM_BLOCK_ARGUMENT_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_block_argument_node {
    /** The embedded base node. */
    pm_node_t base;

    /** BlockArgumentNode#expression */
    struct pm_node *expression;

    /** BlockArgumentNode#operator_loc */
    pm_location_t operator_loc;
} pm_block_argument_node_t;

/**
 * BlockLocalVariableNode
 *
 * Type: PM_BLOCK_LOCAL_VARIABLE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_block_local_variable_node {
    /** The embedded base node. */
    pm_node_t base;

    /** BlockLocalVariableNode#name */
    pm_constant_id_t name;
} pm_block_local_variable_node_t;

/**
 * BlockNode
 *
 * Type: PM_BLOCK_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_block_node {
    /** The embedded base node. */
    pm_node_t base;

    /** BlockNode#locals */
    pm_constant_id_list_t locals;

    /** BlockNode#locals_body_index */
    uint32_t locals_body_index;

    /** BlockNode#parameters */
    struct pm_node *parameters;

    /** BlockNode#body */
    struct pm_node *body;

    /** BlockNode#opening_loc */
    pm_location_t opening_loc;

    /** BlockNode#closing_loc */
    pm_location_t closing_loc;
} pm_block_node_t;

/**
 * BlockParameterNode
 *
 * Type: PM_BLOCK_PARAMETER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_block_parameter_node {
    /** The embedded base node. */
    pm_node_t base;

    /** BlockParameterNode#name */
    pm_constant_id_t name;

    /** BlockParameterNode#name_loc */
    pm_location_t name_loc;

    /** BlockParameterNode#operator_loc */
    pm_location_t operator_loc;
} pm_block_parameter_node_t;

/**
 * BlockParametersNode
 *
 * Type: PM_BLOCK_PARAMETERS_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_block_parameters_node {
    /** The embedded base node. */
    pm_node_t base;

    /** BlockParametersNode#parameters */
    struct pm_parameters_node *parameters;

    /** BlockParametersNode#locals */
    struct pm_node_list locals;

    /** BlockParametersNode#opening_loc */
    pm_location_t opening_loc;

    /** BlockParametersNode#closing_loc */
    pm_location_t closing_loc;
} pm_block_parameters_node_t;

/**
 * BreakNode
 *
 * Type: PM_BREAK_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_break_node {
    /** The embedded base node. */
    pm_node_t base;

    /** BreakNode#arguments */
    struct pm_arguments_node *arguments;

    /** BreakNode#keyword_loc */
    pm_location_t keyword_loc;
} pm_break_node_t;

/**
 * CallAndWriteNode
 *
 * Type: PM_CALL_AND_WRITE_NODE
 * Flags:
 *    PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
 *    PM_CALL_NODE_FLAGS_VARIABLE_CALL
 *    PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE
 *
 * @extends pm_node_t
 */
typedef struct pm_call_and_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** CallAndWriteNode#receiver */
    struct pm_node *receiver;

    /** CallAndWriteNode#call_operator_loc */
    pm_location_t call_operator_loc;

    /** CallAndWriteNode#message_loc */
    pm_location_t message_loc;

    /** CallAndWriteNode#read_name */
    pm_constant_id_t read_name;

    /** CallAndWriteNode#write_name */
    pm_constant_id_t write_name;

    /** CallAndWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** CallAndWriteNode#value */
    struct pm_node *value;
} pm_call_and_write_node_t;

/**
 * CallNode
 *
 * Type: PM_CALL_NODE
 * Flags:
 *    PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
 *    PM_CALL_NODE_FLAGS_VARIABLE_CALL
 *    PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE
 *
 * @extends pm_node_t
 */
typedef struct pm_call_node {
    /** The embedded base node. */
    pm_node_t base;

    /** CallNode#receiver */
    struct pm_node *receiver;

    /** CallNode#call_operator_loc */
    pm_location_t call_operator_loc;

    /** CallNode#name */
    pm_constant_id_t name;

    /** CallNode#message_loc */
    pm_location_t message_loc;

    /** CallNode#opening_loc */
    pm_location_t opening_loc;

    /** CallNode#arguments */
    struct pm_arguments_node *arguments;

    /** CallNode#closing_loc */
    pm_location_t closing_loc;

    /** CallNode#block */
    struct pm_node *block;
} pm_call_node_t;

/**
 * CallOperatorWriteNode
 *
 * Type: PM_CALL_OPERATOR_WRITE_NODE
 * Flags:
 *    PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
 *    PM_CALL_NODE_FLAGS_VARIABLE_CALL
 *    PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE
 *
 * @extends pm_node_t
 */
typedef struct pm_call_operator_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** CallOperatorWriteNode#receiver */
    struct pm_node *receiver;

    /** CallOperatorWriteNode#call_operator_loc */
    pm_location_t call_operator_loc;

    /** CallOperatorWriteNode#message_loc */
    pm_location_t message_loc;

    /** CallOperatorWriteNode#read_name */
    pm_constant_id_t read_name;

    /** CallOperatorWriteNode#write_name */
    pm_constant_id_t write_name;

    /** CallOperatorWriteNode#operator */
    pm_constant_id_t operator;

    /** CallOperatorWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** CallOperatorWriteNode#value */
    struct pm_node *value;
} pm_call_operator_write_node_t;

/**
 * CallOrWriteNode
 *
 * Type: PM_CALL_OR_WRITE_NODE
 * Flags:
 *    PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
 *    PM_CALL_NODE_FLAGS_VARIABLE_CALL
 *    PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE
 *
 * @extends pm_node_t
 */
typedef struct pm_call_or_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** CallOrWriteNode#receiver */
    struct pm_node *receiver;

    /** CallOrWriteNode#call_operator_loc */
    pm_location_t call_operator_loc;

    /** CallOrWriteNode#message_loc */
    pm_location_t message_loc;

    /** CallOrWriteNode#read_name */
    pm_constant_id_t read_name;

    /** CallOrWriteNode#write_name */
    pm_constant_id_t write_name;

    /** CallOrWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** CallOrWriteNode#value */
    struct pm_node *value;
} pm_call_or_write_node_t;

/**
 * CallTargetNode
 *
 * Type: PM_CALL_TARGET_NODE
 * Flags:
 *    PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
 *    PM_CALL_NODE_FLAGS_VARIABLE_CALL
 *    PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE
 *
 * @extends pm_node_t
 */
typedef struct pm_call_target_node {
    /** The embedded base node. */
    pm_node_t base;

    /** CallTargetNode#receiver */
    struct pm_node *receiver;

    /** CallTargetNode#call_operator_loc */
    pm_location_t call_operator_loc;

    /** CallTargetNode#name */
    pm_constant_id_t name;

    /** CallTargetNode#message_loc */
    pm_location_t message_loc;
} pm_call_target_node_t;

/**
 * CapturePatternNode
 *
 * Type: PM_CAPTURE_PATTERN_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_capture_pattern_node {
    /** The embedded base node. */
    pm_node_t base;

    /** CapturePatternNode#value */
    struct pm_node *value;

    /** CapturePatternNode#target */
    struct pm_node *target;

    /** CapturePatternNode#operator_loc */
    pm_location_t operator_loc;
} pm_capture_pattern_node_t;

/**
 * CaseMatchNode
 *
 * Type: PM_CASE_MATCH_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_case_match_node {
    /** The embedded base node. */
    pm_node_t base;

    /** CaseMatchNode#predicate */
    struct pm_node *predicate;

    /** CaseMatchNode#conditions */
    struct pm_node_list conditions;

    /** CaseMatchNode#consequent */
    struct pm_else_node *consequent;

    /** CaseMatchNode#case_keyword_loc */
    pm_location_t case_keyword_loc;

    /** CaseMatchNode#end_keyword_loc */
    pm_location_t end_keyword_loc;
} pm_case_match_node_t;

/**
 * CaseNode
 *
 * Type: PM_CASE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_case_node {
    /** The embedded base node. */
    pm_node_t base;

    /** CaseNode#predicate */
    struct pm_node *predicate;

    /** CaseNode#conditions */
    struct pm_node_list conditions;

    /** CaseNode#consequent */
    struct pm_else_node *consequent;

    /** CaseNode#case_keyword_loc */
    pm_location_t case_keyword_loc;

    /** CaseNode#end_keyword_loc */
    pm_location_t end_keyword_loc;
} pm_case_node_t;

/**
 * ClassNode
 *
 * Type: PM_CLASS_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_class_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ClassNode#locals */
    pm_constant_id_list_t locals;

    /** ClassNode#class_keyword_loc */
    pm_location_t class_keyword_loc;

    /** ClassNode#constant_path */
    struct pm_node *constant_path;

    /** ClassNode#inheritance_operator_loc */
    pm_location_t inheritance_operator_loc;

    /** ClassNode#superclass */
    struct pm_node *superclass;

    /** ClassNode#body */
    struct pm_node *body;

    /** ClassNode#end_keyword_loc */
    pm_location_t end_keyword_loc;

    /** ClassNode#name */
    pm_constant_id_t name;
} pm_class_node_t;

/**
 * ClassVariableAndWriteNode
 *
 * Type: PM_CLASS_VARIABLE_AND_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_class_variable_and_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ClassVariableAndWriteNode#name */
    pm_constant_id_t name;

    /** ClassVariableAndWriteNode#name_loc */
    pm_location_t name_loc;

    /** ClassVariableAndWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** ClassVariableAndWriteNode#value */
    struct pm_node *value;
} pm_class_variable_and_write_node_t;

/**
 * ClassVariableOperatorWriteNode
 *
 * Type: PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_class_variable_operator_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ClassVariableOperatorWriteNode#name */
    pm_constant_id_t name;

    /** ClassVariableOperatorWriteNode#name_loc */
    pm_location_t name_loc;

    /** ClassVariableOperatorWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** ClassVariableOperatorWriteNode#value */
    struct pm_node *value;

    /** ClassVariableOperatorWriteNode#operator */
    pm_constant_id_t operator;
} pm_class_variable_operator_write_node_t;

/**
 * ClassVariableOrWriteNode
 *
 * Type: PM_CLASS_VARIABLE_OR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_class_variable_or_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ClassVariableOrWriteNode#name */
    pm_constant_id_t name;

    /** ClassVariableOrWriteNode#name_loc */
    pm_location_t name_loc;

    /** ClassVariableOrWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** ClassVariableOrWriteNode#value */
    struct pm_node *value;
} pm_class_variable_or_write_node_t;

/**
 * ClassVariableReadNode
 *
 * Type: PM_CLASS_VARIABLE_READ_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_class_variable_read_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ClassVariableReadNode#name */
    pm_constant_id_t name;
} pm_class_variable_read_node_t;

/**
 * ClassVariableTargetNode
 *
 * Type: PM_CLASS_VARIABLE_TARGET_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_class_variable_target_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ClassVariableTargetNode#name */
    pm_constant_id_t name;
} pm_class_variable_target_node_t;

/**
 * ClassVariableWriteNode
 *
 * Type: PM_CLASS_VARIABLE_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_class_variable_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ClassVariableWriteNode#name */
    pm_constant_id_t name;

    /** ClassVariableWriteNode#name_loc */
    pm_location_t name_loc;

    /** ClassVariableWriteNode#value */
    struct pm_node *value;

    /** ClassVariableWriteNode#operator_loc */
    pm_location_t operator_loc;
} pm_class_variable_write_node_t;

/**
 * ConstantAndWriteNode
 *
 * Type: PM_CONSTANT_AND_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_and_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantAndWriteNode#name */
    pm_constant_id_t name;

    /** ConstantAndWriteNode#name_loc */
    pm_location_t name_loc;

    /** ConstantAndWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** ConstantAndWriteNode#value */
    struct pm_node *value;
} pm_constant_and_write_node_t;

/**
 * ConstantOperatorWriteNode
 *
 * Type: PM_CONSTANT_OPERATOR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_operator_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantOperatorWriteNode#name */
    pm_constant_id_t name;

    /** ConstantOperatorWriteNode#name_loc */
    pm_location_t name_loc;

    /** ConstantOperatorWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** ConstantOperatorWriteNode#value */
    struct pm_node *value;

    /** ConstantOperatorWriteNode#operator */
    pm_constant_id_t operator;
} pm_constant_operator_write_node_t;

/**
 * ConstantOrWriteNode
 *
 * Type: PM_CONSTANT_OR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_or_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantOrWriteNode#name */
    pm_constant_id_t name;

    /** ConstantOrWriteNode#name_loc */
    pm_location_t name_loc;

    /** ConstantOrWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** ConstantOrWriteNode#value */
    struct pm_node *value;
} pm_constant_or_write_node_t;

/**
 * ConstantPathAndWriteNode
 *
 * Type: PM_CONSTANT_PATH_AND_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_path_and_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantPathAndWriteNode#target */
    struct pm_constant_path_node *target;

    /** ConstantPathAndWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** ConstantPathAndWriteNode#value */
    struct pm_node *value;
} pm_constant_path_and_write_node_t;

/**
 * ConstantPathNode
 *
 * Type: PM_CONSTANT_PATH_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_path_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantPathNode#parent */
    struct pm_node *parent;

    /** ConstantPathNode#child */
    struct pm_node *child;

    /** ConstantPathNode#delimiter_loc */
    pm_location_t delimiter_loc;
} pm_constant_path_node_t;

/**
 * ConstantPathOperatorWriteNode
 *
 * Type: PM_CONSTANT_PATH_OPERATOR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_path_operator_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantPathOperatorWriteNode#target */
    struct pm_constant_path_node *target;

    /** ConstantPathOperatorWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** ConstantPathOperatorWriteNode#value */
    struct pm_node *value;

    /** ConstantPathOperatorWriteNode#operator */
    pm_constant_id_t operator;
} pm_constant_path_operator_write_node_t;

/**
 * ConstantPathOrWriteNode
 *
 * Type: PM_CONSTANT_PATH_OR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_path_or_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantPathOrWriteNode#target */
    struct pm_constant_path_node *target;

    /** ConstantPathOrWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** ConstantPathOrWriteNode#value */
    struct pm_node *value;
} pm_constant_path_or_write_node_t;

/**
 * ConstantPathTargetNode
 *
 * Type: PM_CONSTANT_PATH_TARGET_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_path_target_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantPathTargetNode#parent */
    struct pm_node *parent;

    /** ConstantPathTargetNode#child */
    struct pm_node *child;

    /** ConstantPathTargetNode#delimiter_loc */
    pm_location_t delimiter_loc;
} pm_constant_path_target_node_t;

/**
 * ConstantPathWriteNode
 *
 * Type: PM_CONSTANT_PATH_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_path_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantPathWriteNode#target */
    struct pm_constant_path_node *target;

    /** ConstantPathWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** ConstantPathWriteNode#value */
    struct pm_node *value;
} pm_constant_path_write_node_t;

/**
 * ConstantReadNode
 *
 * Type: PM_CONSTANT_READ_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_read_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantReadNode#name */
    pm_constant_id_t name;
} pm_constant_read_node_t;

/**
 * ConstantTargetNode
 *
 * Type: PM_CONSTANT_TARGET_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_target_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantTargetNode#name */
    pm_constant_id_t name;
} pm_constant_target_node_t;

/**
 * ConstantWriteNode
 *
 * Type: PM_CONSTANT_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_constant_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ConstantWriteNode#name */
    pm_constant_id_t name;

    /** ConstantWriteNode#name_loc */
    pm_location_t name_loc;

    /** ConstantWriteNode#value */
    struct pm_node *value;

    /** ConstantWriteNode#operator_loc */
    pm_location_t operator_loc;
} pm_constant_write_node_t;

/**
 * DefNode
 *
 * Type: PM_DEF_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_def_node {
    /** The embedded base node. */
    pm_node_t base;

    /** DefNode#name */
    pm_constant_id_t name;

    /** DefNode#name_loc */
    pm_location_t name_loc;

    /** DefNode#receiver */
    struct pm_node *receiver;

    /** DefNode#parameters */
    struct pm_parameters_node *parameters;

    /** DefNode#body */
    struct pm_node *body;

    /** DefNode#locals */
    pm_constant_id_list_t locals;

    /** DefNode#locals_body_index */
    uint32_t locals_body_index;

    /** DefNode#def_keyword_loc */
    pm_location_t def_keyword_loc;

    /** DefNode#operator_loc */
    pm_location_t operator_loc;

    /** DefNode#lparen_loc */
    pm_location_t lparen_loc;

    /** DefNode#rparen_loc */
    pm_location_t rparen_loc;

    /** DefNode#equal_loc */
    pm_location_t equal_loc;

    /** DefNode#end_keyword_loc */
    pm_location_t end_keyword_loc;
} pm_def_node_t;

/**
 * DefinedNode
 *
 * Type: PM_DEFINED_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_defined_node {
    /** The embedded base node. */
    pm_node_t base;

    /** DefinedNode#lparen_loc */
    pm_location_t lparen_loc;

    /** DefinedNode#value */
    struct pm_node *value;

    /** DefinedNode#rparen_loc */
    pm_location_t rparen_loc;

    /** DefinedNode#keyword_loc */
    pm_location_t keyword_loc;
} pm_defined_node_t;

/**
 * ElseNode
 *
 * Type: PM_ELSE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_else_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ElseNode#else_keyword_loc */
    pm_location_t else_keyword_loc;

    /** ElseNode#statements */
    struct pm_statements_node *statements;

    /** ElseNode#end_keyword_loc */
    pm_location_t end_keyword_loc;
} pm_else_node_t;

/**
 * EmbeddedStatementsNode
 *
 * Type: PM_EMBEDDED_STATEMENTS_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_embedded_statements_node {
    /** The embedded base node. */
    pm_node_t base;

    /** EmbeddedStatementsNode#opening_loc */
    pm_location_t opening_loc;

    /** EmbeddedStatementsNode#statements */
    struct pm_statements_node *statements;

    /** EmbeddedStatementsNode#closing_loc */
    pm_location_t closing_loc;
} pm_embedded_statements_node_t;

/**
 * EmbeddedVariableNode
 *
 * Type: PM_EMBEDDED_VARIABLE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_embedded_variable_node {
    /** The embedded base node. */
    pm_node_t base;

    /** EmbeddedVariableNode#operator_loc */
    pm_location_t operator_loc;

    /** EmbeddedVariableNode#variable */
    struct pm_node *variable;
} pm_embedded_variable_node_t;

/**
 * EnsureNode
 *
 * Type: PM_ENSURE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_ensure_node {
    /** The embedded base node. */
    pm_node_t base;

    /** EnsureNode#ensure_keyword_loc */
    pm_location_t ensure_keyword_loc;

    /** EnsureNode#statements */
    struct pm_statements_node *statements;

    /** EnsureNode#end_keyword_loc */
    pm_location_t end_keyword_loc;
} pm_ensure_node_t;

/**
 * FalseNode
 *
 * Type: PM_FALSE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_false_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_false_node_t;

/**
 * FindPatternNode
 *
 * Type: PM_FIND_PATTERN_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_find_pattern_node {
    /** The embedded base node. */
    pm_node_t base;

    /** FindPatternNode#constant */
    struct pm_node *constant;

    /** FindPatternNode#left */
    struct pm_node *left;

    /** FindPatternNode#requireds */
    struct pm_node_list requireds;

    /** FindPatternNode#right */
    struct pm_node *right;

    /** FindPatternNode#opening_loc */
    pm_location_t opening_loc;

    /** FindPatternNode#closing_loc */
    pm_location_t closing_loc;
} pm_find_pattern_node_t;

/**
 * FlipFlopNode
 *
 * Type: PM_FLIP_FLOP_NODE
 * Flags:
 *    PM_RANGE_FLAGS_EXCLUDE_END
 *
 * @extends pm_node_t
 */
typedef struct pm_flip_flop_node {
    /** The embedded base node. */
    pm_node_t base;

    /** FlipFlopNode#left */
    struct pm_node *left;

    /** FlipFlopNode#right */
    struct pm_node *right;

    /** FlipFlopNode#operator_loc */
    pm_location_t operator_loc;
} pm_flip_flop_node_t;

/**
 * FloatNode
 *
 * Type: PM_FLOAT_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_float_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_float_node_t;

/**
 * ForNode
 *
 * Type: PM_FOR_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_for_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ForNode#index */
    struct pm_node *index;

    /** ForNode#collection */
    struct pm_node *collection;

    /** ForNode#statements */
    struct pm_statements_node *statements;

    /** ForNode#for_keyword_loc */
    pm_location_t for_keyword_loc;

    /** ForNode#in_keyword_loc */
    pm_location_t in_keyword_loc;

    /** ForNode#do_keyword_loc */
    pm_location_t do_keyword_loc;

    /** ForNode#end_keyword_loc */
    pm_location_t end_keyword_loc;
} pm_for_node_t;

/**
 * ForwardingArgumentsNode
 *
 * Type: PM_FORWARDING_ARGUMENTS_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_forwarding_arguments_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_forwarding_arguments_node_t;

/**
 * ForwardingParameterNode
 *
 * Type: PM_FORWARDING_PARAMETER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_forwarding_parameter_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_forwarding_parameter_node_t;

/**
 * ForwardingSuperNode
 *
 * Type: PM_FORWARDING_SUPER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_forwarding_super_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ForwardingSuperNode#block */
    struct pm_block_node *block;
} pm_forwarding_super_node_t;

/**
 * GlobalVariableAndWriteNode
 *
 * Type: PM_GLOBAL_VARIABLE_AND_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_global_variable_and_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** GlobalVariableAndWriteNode#name */
    pm_constant_id_t name;

    /** GlobalVariableAndWriteNode#name_loc */
    pm_location_t name_loc;

    /** GlobalVariableAndWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** GlobalVariableAndWriteNode#value */
    struct pm_node *value;
} pm_global_variable_and_write_node_t;

/**
 * GlobalVariableOperatorWriteNode
 *
 * Type: PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_global_variable_operator_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** GlobalVariableOperatorWriteNode#name */
    pm_constant_id_t name;

    /** GlobalVariableOperatorWriteNode#name_loc */
    pm_location_t name_loc;

    /** GlobalVariableOperatorWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** GlobalVariableOperatorWriteNode#value */
    struct pm_node *value;

    /** GlobalVariableOperatorWriteNode#operator */
    pm_constant_id_t operator;
} pm_global_variable_operator_write_node_t;

/**
 * GlobalVariableOrWriteNode
 *
 * Type: PM_GLOBAL_VARIABLE_OR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_global_variable_or_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** GlobalVariableOrWriteNode#name */
    pm_constant_id_t name;

    /** GlobalVariableOrWriteNode#name_loc */
    pm_location_t name_loc;

    /** GlobalVariableOrWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** GlobalVariableOrWriteNode#value */
    struct pm_node *value;
} pm_global_variable_or_write_node_t;

/**
 * GlobalVariableReadNode
 *
 * Type: PM_GLOBAL_VARIABLE_READ_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_global_variable_read_node {
    /** The embedded base node. */
    pm_node_t base;

    /** GlobalVariableReadNode#name */
    pm_constant_id_t name;
} pm_global_variable_read_node_t;

/**
 * GlobalVariableTargetNode
 *
 * Type: PM_GLOBAL_VARIABLE_TARGET_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_global_variable_target_node {
    /** The embedded base node. */
    pm_node_t base;

    /** GlobalVariableTargetNode#name */
    pm_constant_id_t name;
} pm_global_variable_target_node_t;

/**
 * GlobalVariableWriteNode
 *
 * Type: PM_GLOBAL_VARIABLE_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_global_variable_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** GlobalVariableWriteNode#name */
    pm_constant_id_t name;

    /** GlobalVariableWriteNode#name_loc */
    pm_location_t name_loc;

    /** GlobalVariableWriteNode#value */
    struct pm_node *value;

    /** GlobalVariableWriteNode#operator_loc */
    pm_location_t operator_loc;
} pm_global_variable_write_node_t;

/**
 * HashNode
 *
 * Type: PM_HASH_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_hash_node {
    /** The embedded base node. */
    pm_node_t base;

    /** HashNode#opening_loc */
    pm_location_t opening_loc;

    /** HashNode#elements */
    struct pm_node_list elements;

    /** HashNode#closing_loc */
    pm_location_t closing_loc;
} pm_hash_node_t;

/**
 * HashPatternNode
 *
 * Type: PM_HASH_PATTERN_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_hash_pattern_node {
    /** The embedded base node. */
    pm_node_t base;

    /** HashPatternNode#constant */
    struct pm_node *constant;

    /** HashPatternNode#elements */
    struct pm_node_list elements;

    /** HashPatternNode#rest */
    struct pm_node *rest;

    /** HashPatternNode#opening_loc */
    pm_location_t opening_loc;

    /** HashPatternNode#closing_loc */
    pm_location_t closing_loc;
} pm_hash_pattern_node_t;

/**
 * IfNode
 *
 * Type: PM_IF_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_if_node {
    /** The embedded base node. */
    pm_node_t base;

    /** IfNode#if_keyword_loc */
    pm_location_t if_keyword_loc;

    /** IfNode#predicate */
    struct pm_node *predicate;

    /** IfNode#then_keyword_loc */
    pm_location_t then_keyword_loc;

    /** IfNode#statements */
    struct pm_statements_node *statements;

    /** IfNode#consequent */
    struct pm_node *consequent;

    /** IfNode#end_keyword_loc */
    pm_location_t end_keyword_loc;
} pm_if_node_t;

/**
 * ImaginaryNode
 *
 * Type: PM_IMAGINARY_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_imaginary_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ImaginaryNode#numeric */
    struct pm_node *numeric;
} pm_imaginary_node_t;

/**
 * ImplicitNode
 *
 * Type: PM_IMPLICIT_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_implicit_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ImplicitNode#value */
    struct pm_node *value;
} pm_implicit_node_t;

/**
 * ImplicitRestNode
 *
 * Type: PM_IMPLICIT_REST_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_implicit_rest_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_implicit_rest_node_t;

/**
 * InNode
 *
 * Type: PM_IN_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_in_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InNode#pattern */
    struct pm_node *pattern;

    /** InNode#statements */
    struct pm_statements_node *statements;

    /** InNode#in_loc */
    pm_location_t in_loc;

    /** InNode#then_loc */
    pm_location_t then_loc;
} pm_in_node_t;

/**
 * IndexAndWriteNode
 *
 * Type: PM_INDEX_AND_WRITE_NODE
 * Flags:
 *    PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
 *    PM_CALL_NODE_FLAGS_VARIABLE_CALL
 *    PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE
 *
 * @extends pm_node_t
 */
typedef struct pm_index_and_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** IndexAndWriteNode#receiver */
    struct pm_node *receiver;

    /** IndexAndWriteNode#call_operator_loc */
    pm_location_t call_operator_loc;

    /** IndexAndWriteNode#opening_loc */
    pm_location_t opening_loc;

    /** IndexAndWriteNode#arguments */
    struct pm_arguments_node *arguments;

    /** IndexAndWriteNode#closing_loc */
    pm_location_t closing_loc;

    /** IndexAndWriteNode#block */
    struct pm_node *block;

    /** IndexAndWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** IndexAndWriteNode#value */
    struct pm_node *value;
} pm_index_and_write_node_t;

/**
 * IndexOperatorWriteNode
 *
 * Type: PM_INDEX_OPERATOR_WRITE_NODE
 * Flags:
 *    PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
 *    PM_CALL_NODE_FLAGS_VARIABLE_CALL
 *    PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE
 *
 * @extends pm_node_t
 */
typedef struct pm_index_operator_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** IndexOperatorWriteNode#receiver */
    struct pm_node *receiver;

    /** IndexOperatorWriteNode#call_operator_loc */
    pm_location_t call_operator_loc;

    /** IndexOperatorWriteNode#opening_loc */
    pm_location_t opening_loc;

    /** IndexOperatorWriteNode#arguments */
    struct pm_arguments_node *arguments;

    /** IndexOperatorWriteNode#closing_loc */
    pm_location_t closing_loc;

    /** IndexOperatorWriteNode#block */
    struct pm_node *block;

    /** IndexOperatorWriteNode#operator */
    pm_constant_id_t operator;

    /** IndexOperatorWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** IndexOperatorWriteNode#value */
    struct pm_node *value;
} pm_index_operator_write_node_t;

/**
 * IndexOrWriteNode
 *
 * Type: PM_INDEX_OR_WRITE_NODE
 * Flags:
 *    PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
 *    PM_CALL_NODE_FLAGS_VARIABLE_CALL
 *    PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE
 *
 * @extends pm_node_t
 */
typedef struct pm_index_or_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** IndexOrWriteNode#receiver */
    struct pm_node *receiver;

    /** IndexOrWriteNode#call_operator_loc */
    pm_location_t call_operator_loc;

    /** IndexOrWriteNode#opening_loc */
    pm_location_t opening_loc;

    /** IndexOrWriteNode#arguments */
    struct pm_arguments_node *arguments;

    /** IndexOrWriteNode#closing_loc */
    pm_location_t closing_loc;

    /** IndexOrWriteNode#block */
    struct pm_node *block;

    /** IndexOrWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** IndexOrWriteNode#value */
    struct pm_node *value;
} pm_index_or_write_node_t;

/**
 * IndexTargetNode
 *
 * Type: PM_INDEX_TARGET_NODE
 * Flags:
 *    PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
 *    PM_CALL_NODE_FLAGS_VARIABLE_CALL
 *    PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE
 *
 * @extends pm_node_t
 */
typedef struct pm_index_target_node {
    /** The embedded base node. */
    pm_node_t base;

    /** IndexTargetNode#receiver */
    struct pm_node *receiver;

    /** IndexTargetNode#opening_loc */
    pm_location_t opening_loc;

    /** IndexTargetNode#arguments */
    struct pm_arguments_node *arguments;

    /** IndexTargetNode#closing_loc */
    pm_location_t closing_loc;

    /** IndexTargetNode#block */
    struct pm_node *block;
} pm_index_target_node_t;

/**
 * InstanceVariableAndWriteNode
 *
 * Type: PM_INSTANCE_VARIABLE_AND_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_instance_variable_and_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InstanceVariableAndWriteNode#name */
    pm_constant_id_t name;

    /** InstanceVariableAndWriteNode#name_loc */
    pm_location_t name_loc;

    /** InstanceVariableAndWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** InstanceVariableAndWriteNode#value */
    struct pm_node *value;
} pm_instance_variable_and_write_node_t;

/**
 * InstanceVariableOperatorWriteNode
 *
 * Type: PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_instance_variable_operator_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InstanceVariableOperatorWriteNode#name */
    pm_constant_id_t name;

    /** InstanceVariableOperatorWriteNode#name_loc */
    pm_location_t name_loc;

    /** InstanceVariableOperatorWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** InstanceVariableOperatorWriteNode#value */
    struct pm_node *value;

    /** InstanceVariableOperatorWriteNode#operator */
    pm_constant_id_t operator;
} pm_instance_variable_operator_write_node_t;

/**
 * InstanceVariableOrWriteNode
 *
 * Type: PM_INSTANCE_VARIABLE_OR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_instance_variable_or_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InstanceVariableOrWriteNode#name */
    pm_constant_id_t name;

    /** InstanceVariableOrWriteNode#name_loc */
    pm_location_t name_loc;

    /** InstanceVariableOrWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** InstanceVariableOrWriteNode#value */
    struct pm_node *value;
} pm_instance_variable_or_write_node_t;

/**
 * InstanceVariableReadNode
 *
 * Type: PM_INSTANCE_VARIABLE_READ_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_instance_variable_read_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InstanceVariableReadNode#name */
    pm_constant_id_t name;
} pm_instance_variable_read_node_t;

/**
 * InstanceVariableTargetNode
 *
 * Type: PM_INSTANCE_VARIABLE_TARGET_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_instance_variable_target_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InstanceVariableTargetNode#name */
    pm_constant_id_t name;
} pm_instance_variable_target_node_t;

/**
 * InstanceVariableWriteNode
 *
 * Type: PM_INSTANCE_VARIABLE_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_instance_variable_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InstanceVariableWriteNode#name */
    pm_constant_id_t name;

    /** InstanceVariableWriteNode#name_loc */
    pm_location_t name_loc;

    /** InstanceVariableWriteNode#value */
    struct pm_node *value;

    /** InstanceVariableWriteNode#operator_loc */
    pm_location_t operator_loc;
} pm_instance_variable_write_node_t;

/**
 * IntegerNode
 *
 * Type: PM_INTEGER_NODE
 * Flags:
 *    PM_INTEGER_BASE_FLAGS_BINARY
 *    PM_INTEGER_BASE_FLAGS_DECIMAL
 *    PM_INTEGER_BASE_FLAGS_OCTAL
 *    PM_INTEGER_BASE_FLAGS_HEXADECIMAL
 *
 * @extends pm_node_t
 */
typedef struct pm_integer_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_integer_node_t;

/**
 * InterpolatedMatchLastLineNode
 *
 * Type: PM_INTERPOLATED_MATCH_LAST_LINE_NODE
 * Flags:
 *    PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE
 *    PM_REGULAR_EXPRESSION_FLAGS_EXTENDED
 *    PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE
 *    PM_REGULAR_EXPRESSION_FLAGS_ONCE
 *    PM_REGULAR_EXPRESSION_FLAGS_EUC_JP
 *    PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT
 *    PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J
 *    PM_REGULAR_EXPRESSION_FLAGS_UTF_8
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING
 *
 * @extends pm_node_t
 */
typedef struct pm_interpolated_match_last_line_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InterpolatedMatchLastLineNode#opening_loc */
    pm_location_t opening_loc;

    /** InterpolatedMatchLastLineNode#parts */
    struct pm_node_list parts;

    /** InterpolatedMatchLastLineNode#closing_loc */
    pm_location_t closing_loc;
} pm_interpolated_match_last_line_node_t;

/**
 * InterpolatedRegularExpressionNode
 *
 * Type: PM_INTERPOLATED_REGULAR_EXPRESSION_NODE
 * Flags:
 *    PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE
 *    PM_REGULAR_EXPRESSION_FLAGS_EXTENDED
 *    PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE
 *    PM_REGULAR_EXPRESSION_FLAGS_ONCE
 *    PM_REGULAR_EXPRESSION_FLAGS_EUC_JP
 *    PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT
 *    PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J
 *    PM_REGULAR_EXPRESSION_FLAGS_UTF_8
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING
 *
 * @extends pm_node_t
 */
typedef struct pm_interpolated_regular_expression_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InterpolatedRegularExpressionNode#opening_loc */
    pm_location_t opening_loc;

    /** InterpolatedRegularExpressionNode#parts */
    struct pm_node_list parts;

    /** InterpolatedRegularExpressionNode#closing_loc */
    pm_location_t closing_loc;
} pm_interpolated_regular_expression_node_t;

/**
 * InterpolatedStringNode
 *
 * Type: PM_INTERPOLATED_STRING_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_interpolated_string_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InterpolatedStringNode#opening_loc */
    pm_location_t opening_loc;

    /** InterpolatedStringNode#parts */
    struct pm_node_list parts;

    /** InterpolatedStringNode#closing_loc */
    pm_location_t closing_loc;
} pm_interpolated_string_node_t;

/**
 * InterpolatedSymbolNode
 *
 * Type: PM_INTERPOLATED_SYMBOL_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_interpolated_symbol_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InterpolatedSymbolNode#opening_loc */
    pm_location_t opening_loc;

    /** InterpolatedSymbolNode#parts */
    struct pm_node_list parts;

    /** InterpolatedSymbolNode#closing_loc */
    pm_location_t closing_loc;
} pm_interpolated_symbol_node_t;

/**
 * InterpolatedXStringNode
 *
 * Type: PM_INTERPOLATED_X_STRING_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_interpolated_x_string_node {
    /** The embedded base node. */
    pm_node_t base;

    /** InterpolatedXStringNode#opening_loc */
    pm_location_t opening_loc;

    /** InterpolatedXStringNode#parts */
    struct pm_node_list parts;

    /** InterpolatedXStringNode#closing_loc */
    pm_location_t closing_loc;
} pm_interpolated_x_string_node_t;

/**
 * KeywordHashNode
 *
 * Type: PM_KEYWORD_HASH_NODE
 * Flags:
 *    PM_KEYWORD_HASH_NODE_FLAGS_STATIC_KEYS
 *
 * @extends pm_node_t
 */
typedef struct pm_keyword_hash_node {
    /** The embedded base node. */
    pm_node_t base;

    /** KeywordHashNode#elements */
    struct pm_node_list elements;
} pm_keyword_hash_node_t;

/**
 * KeywordRestParameterNode
 *
 * Type: PM_KEYWORD_REST_PARAMETER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_keyword_rest_parameter_node {
    /** The embedded base node. */
    pm_node_t base;

    /** KeywordRestParameterNode#name */
    pm_constant_id_t name;

    /** KeywordRestParameterNode#name_loc */
    pm_location_t name_loc;

    /** KeywordRestParameterNode#operator_loc */
    pm_location_t operator_loc;
} pm_keyword_rest_parameter_node_t;

/**
 * LambdaNode
 *
 * Type: PM_LAMBDA_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_lambda_node {
    /** The embedded base node. */
    pm_node_t base;

    /** LambdaNode#locals */
    pm_constant_id_list_t locals;

    /** LambdaNode#locals_body_index */
    uint32_t locals_body_index;

    /** LambdaNode#operator_loc */
    pm_location_t operator_loc;

    /** LambdaNode#opening_loc */
    pm_location_t opening_loc;

    /** LambdaNode#closing_loc */
    pm_location_t closing_loc;

    /** LambdaNode#parameters */
    struct pm_node *parameters;

    /** LambdaNode#body */
    struct pm_node *body;
} pm_lambda_node_t;

/**
 * LocalVariableAndWriteNode
 *
 * Type: PM_LOCAL_VARIABLE_AND_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_local_variable_and_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** LocalVariableAndWriteNode#name_loc */
    pm_location_t name_loc;

    /** LocalVariableAndWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** LocalVariableAndWriteNode#value */
    struct pm_node *value;

    /** LocalVariableAndWriteNode#name */
    pm_constant_id_t name;

    /** LocalVariableAndWriteNode#depth */
    uint32_t depth;
} pm_local_variable_and_write_node_t;

/**
 * LocalVariableOperatorWriteNode
 *
 * Type: PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_local_variable_operator_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** LocalVariableOperatorWriteNode#name_loc */
    pm_location_t name_loc;

    /** LocalVariableOperatorWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** LocalVariableOperatorWriteNode#value */
    struct pm_node *value;

    /** LocalVariableOperatorWriteNode#name */
    pm_constant_id_t name;

    /** LocalVariableOperatorWriteNode#operator */
    pm_constant_id_t operator;

    /** LocalVariableOperatorWriteNode#depth */
    uint32_t depth;
} pm_local_variable_operator_write_node_t;

/**
 * LocalVariableOrWriteNode
 *
 * Type: PM_LOCAL_VARIABLE_OR_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_local_variable_or_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** LocalVariableOrWriteNode#name_loc */
    pm_location_t name_loc;

    /** LocalVariableOrWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** LocalVariableOrWriteNode#value */
    struct pm_node *value;

    /** LocalVariableOrWriteNode#name */
    pm_constant_id_t name;

    /** LocalVariableOrWriteNode#depth */
    uint32_t depth;
} pm_local_variable_or_write_node_t;

/**
 * LocalVariableReadNode
 *
 * Type: PM_LOCAL_VARIABLE_READ_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_local_variable_read_node {
    /** The embedded base node. */
    pm_node_t base;

    /** LocalVariableReadNode#name */
    pm_constant_id_t name;

    /** LocalVariableReadNode#depth */
    uint32_t depth;
} pm_local_variable_read_node_t;

/**
 * LocalVariableTargetNode
 *
 * Type: PM_LOCAL_VARIABLE_TARGET_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_local_variable_target_node {
    /** The embedded base node. */
    pm_node_t base;

    /** LocalVariableTargetNode#name */
    pm_constant_id_t name;

    /** LocalVariableTargetNode#depth */
    uint32_t depth;
} pm_local_variable_target_node_t;

/**
 * LocalVariableWriteNode
 *
 * Type: PM_LOCAL_VARIABLE_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_local_variable_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** LocalVariableWriteNode#name */
    pm_constant_id_t name;

    /** LocalVariableWriteNode#depth */
    uint32_t depth;

    /** LocalVariableWriteNode#name_loc */
    pm_location_t name_loc;

    /** LocalVariableWriteNode#value */
    struct pm_node *value;

    /** LocalVariableWriteNode#operator_loc */
    pm_location_t operator_loc;
} pm_local_variable_write_node_t;

/**
 * MatchLastLineNode
 *
 * Type: PM_MATCH_LAST_LINE_NODE
 * Flags:
 *    PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE
 *    PM_REGULAR_EXPRESSION_FLAGS_EXTENDED
 *    PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE
 *    PM_REGULAR_EXPRESSION_FLAGS_ONCE
 *    PM_REGULAR_EXPRESSION_FLAGS_EUC_JP
 *    PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT
 *    PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J
 *    PM_REGULAR_EXPRESSION_FLAGS_UTF_8
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING
 *
 * @extends pm_node_t
 */
typedef struct pm_match_last_line_node {
    /** The embedded base node. */
    pm_node_t base;

    /** MatchLastLineNode#opening_loc */
    pm_location_t opening_loc;

    /** MatchLastLineNode#content_loc */
    pm_location_t content_loc;

    /** MatchLastLineNode#closing_loc */
    pm_location_t closing_loc;

    /** MatchLastLineNode#unescaped */
    pm_string_t unescaped;
} pm_match_last_line_node_t;

/**
 * MatchPredicateNode
 *
 * Type: PM_MATCH_PREDICATE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_match_predicate_node {
    /** The embedded base node. */
    pm_node_t base;

    /** MatchPredicateNode#value */
    struct pm_node *value;

    /** MatchPredicateNode#pattern */
    struct pm_node *pattern;

    /** MatchPredicateNode#operator_loc */
    pm_location_t operator_loc;
} pm_match_predicate_node_t;

/**
 * MatchRequiredNode
 *
 * Type: PM_MATCH_REQUIRED_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_match_required_node {
    /** The embedded base node. */
    pm_node_t base;

    /** MatchRequiredNode#value */
    struct pm_node *value;

    /** MatchRequiredNode#pattern */
    struct pm_node *pattern;

    /** MatchRequiredNode#operator_loc */
    pm_location_t operator_loc;
} pm_match_required_node_t;

/**
 * MatchWriteNode
 *
 * Type: PM_MATCH_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_match_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** MatchWriteNode#call */
    struct pm_call_node *call;

    /** MatchWriteNode#targets */
    struct pm_node_list targets;
} pm_match_write_node_t;

/**
 * MissingNode
 *
 * Type: PM_MISSING_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_missing_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_missing_node_t;

/**
 * ModuleNode
 *
 * Type: PM_MODULE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_module_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ModuleNode#locals */
    pm_constant_id_list_t locals;

    /** ModuleNode#module_keyword_loc */
    pm_location_t module_keyword_loc;

    /** ModuleNode#constant_path */
    struct pm_node *constant_path;

    /** ModuleNode#body */
    struct pm_node *body;

    /** ModuleNode#end_keyword_loc */
    pm_location_t end_keyword_loc;

    /** ModuleNode#name */
    pm_constant_id_t name;
} pm_module_node_t;

/**
 * MultiTargetNode
 *
 * Type: PM_MULTI_TARGET_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_multi_target_node {
    /** The embedded base node. */
    pm_node_t base;

    /** MultiTargetNode#lefts */
    struct pm_node_list lefts;

    /** MultiTargetNode#rest */
    struct pm_node *rest;

    /** MultiTargetNode#rights */
    struct pm_node_list rights;

    /** MultiTargetNode#lparen_loc */
    pm_location_t lparen_loc;

    /** MultiTargetNode#rparen_loc */
    pm_location_t rparen_loc;
} pm_multi_target_node_t;

/**
 * MultiWriteNode
 *
 * Type: PM_MULTI_WRITE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_multi_write_node {
    /** The embedded base node. */
    pm_node_t base;

    /** MultiWriteNode#lefts */
    struct pm_node_list lefts;

    /** MultiWriteNode#rest */
    struct pm_node *rest;

    /** MultiWriteNode#rights */
    struct pm_node_list rights;

    /** MultiWriteNode#lparen_loc */
    pm_location_t lparen_loc;

    /** MultiWriteNode#rparen_loc */
    pm_location_t rparen_loc;

    /** MultiWriteNode#operator_loc */
    pm_location_t operator_loc;

    /** MultiWriteNode#value */
    struct pm_node *value;
} pm_multi_write_node_t;

/**
 * NextNode
 *
 * Type: PM_NEXT_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_next_node {
    /** The embedded base node. */
    pm_node_t base;

    /** NextNode#arguments */
    struct pm_arguments_node *arguments;

    /** NextNode#keyword_loc */
    pm_location_t keyword_loc;
} pm_next_node_t;

/**
 * NilNode
 *
 * Type: PM_NIL_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_nil_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_nil_node_t;

/**
 * NoKeywordsParameterNode
 *
 * Type: PM_NO_KEYWORDS_PARAMETER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_no_keywords_parameter_node {
    /** The embedded base node. */
    pm_node_t base;

    /** NoKeywordsParameterNode#operator_loc */
    pm_location_t operator_loc;

    /** NoKeywordsParameterNode#keyword_loc */
    pm_location_t keyword_loc;
} pm_no_keywords_parameter_node_t;

/**
 * NumberedParametersNode
 *
 * Type: PM_NUMBERED_PARAMETERS_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_numbered_parameters_node {
    /** The embedded base node. */
    pm_node_t base;

    /** NumberedParametersNode#maximum */
    uint8_t maximum;
} pm_numbered_parameters_node_t;

/**
 * NumberedReferenceReadNode
 *
 * Type: PM_NUMBERED_REFERENCE_READ_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_numbered_reference_read_node {
    /** The embedded base node. */
    pm_node_t base;

    /** NumberedReferenceReadNode#number */
    uint32_t number;
} pm_numbered_reference_read_node_t;

/**
 * OptionalKeywordParameterNode
 *
 * Type: PM_OPTIONAL_KEYWORD_PARAMETER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_optional_keyword_parameter_node {
    /** The embedded base node. */
    pm_node_t base;

    /** OptionalKeywordParameterNode#name */
    pm_constant_id_t name;

    /** OptionalKeywordParameterNode#name_loc */
    pm_location_t name_loc;

    /** OptionalKeywordParameterNode#value */
    struct pm_node *value;
} pm_optional_keyword_parameter_node_t;

/**
 * OptionalParameterNode
 *
 * Type: PM_OPTIONAL_PARAMETER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_optional_parameter_node {
    /** The embedded base node. */
    pm_node_t base;

    /** OptionalParameterNode#name */
    pm_constant_id_t name;

    /** OptionalParameterNode#name_loc */
    pm_location_t name_loc;

    /** OptionalParameterNode#operator_loc */
    pm_location_t operator_loc;

    /** OptionalParameterNode#value */
    struct pm_node *value;
} pm_optional_parameter_node_t;

/**
 * OrNode
 *
 * Type: PM_OR_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_or_node {
    /** The embedded base node. */
    pm_node_t base;

    /** OrNode#left */
    struct pm_node *left;

    /** OrNode#right */
    struct pm_node *right;

    /** OrNode#operator_loc */
    pm_location_t operator_loc;
} pm_or_node_t;

/**
 * ParametersNode
 *
 * Type: PM_PARAMETERS_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_parameters_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ParametersNode#requireds */
    struct pm_node_list requireds;

    /** ParametersNode#optionals */
    struct pm_node_list optionals;

    /** ParametersNode#rest */
    struct pm_node *rest;

    /** ParametersNode#posts */
    struct pm_node_list posts;

    /** ParametersNode#keywords */
    struct pm_node_list keywords;

    /** ParametersNode#keyword_rest */
    struct pm_node *keyword_rest;

    /** ParametersNode#block */
    struct pm_block_parameter_node *block;
} pm_parameters_node_t;

/**
 * ParenthesesNode
 *
 * Type: PM_PARENTHESES_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_parentheses_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ParenthesesNode#body */
    struct pm_node *body;

    /** ParenthesesNode#opening_loc */
    pm_location_t opening_loc;

    /** ParenthesesNode#closing_loc */
    pm_location_t closing_loc;
} pm_parentheses_node_t;

/**
 * PinnedExpressionNode
 *
 * Type: PM_PINNED_EXPRESSION_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_pinned_expression_node {
    /** The embedded base node. */
    pm_node_t base;

    /** PinnedExpressionNode#expression */
    struct pm_node *expression;

    /** PinnedExpressionNode#operator_loc */
    pm_location_t operator_loc;

    /** PinnedExpressionNode#lparen_loc */
    pm_location_t lparen_loc;

    /** PinnedExpressionNode#rparen_loc */
    pm_location_t rparen_loc;
} pm_pinned_expression_node_t;

/**
 * PinnedVariableNode
 *
 * Type: PM_PINNED_VARIABLE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_pinned_variable_node {
    /** The embedded base node. */
    pm_node_t base;

    /** PinnedVariableNode#variable */
    struct pm_node *variable;

    /** PinnedVariableNode#operator_loc */
    pm_location_t operator_loc;
} pm_pinned_variable_node_t;

/**
 * PostExecutionNode
 *
 * Type: PM_POST_EXECUTION_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_post_execution_node {
    /** The embedded base node. */
    pm_node_t base;

    /** PostExecutionNode#statements */
    struct pm_statements_node *statements;

    /** PostExecutionNode#keyword_loc */
    pm_location_t keyword_loc;

    /** PostExecutionNode#opening_loc */
    pm_location_t opening_loc;

    /** PostExecutionNode#closing_loc */
    pm_location_t closing_loc;
} pm_post_execution_node_t;

/**
 * PreExecutionNode
 *
 * Type: PM_PRE_EXECUTION_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_pre_execution_node {
    /** The embedded base node. */
    pm_node_t base;

    /** PreExecutionNode#statements */
    struct pm_statements_node *statements;

    /** PreExecutionNode#keyword_loc */
    pm_location_t keyword_loc;

    /** PreExecutionNode#opening_loc */
    pm_location_t opening_loc;

    /** PreExecutionNode#closing_loc */
    pm_location_t closing_loc;
} pm_pre_execution_node_t;

/**
 * ProgramNode
 *
 * Type: PM_PROGRAM_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_program_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ProgramNode#locals */
    pm_constant_id_list_t locals;

    /** ProgramNode#statements */
    struct pm_statements_node *statements;
} pm_program_node_t;

/**
 * RangeNode
 *
 * Type: PM_RANGE_NODE
 * Flags:
 *    PM_RANGE_FLAGS_EXCLUDE_END
 *
 * @extends pm_node_t
 */
typedef struct pm_range_node {
    /** The embedded base node. */
    pm_node_t base;

    /** RangeNode#left */
    struct pm_node *left;

    /** RangeNode#right */
    struct pm_node *right;

    /** RangeNode#operator_loc */
    pm_location_t operator_loc;
} pm_range_node_t;

/**
 * RationalNode
 *
 * Type: PM_RATIONAL_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_rational_node {
    /** The embedded base node. */
    pm_node_t base;

    /** RationalNode#numeric */
    struct pm_node *numeric;
} pm_rational_node_t;

/**
 * RedoNode
 *
 * Type: PM_REDO_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_redo_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_redo_node_t;

/**
 * RegularExpressionNode
 *
 * Type: PM_REGULAR_EXPRESSION_NODE
 * Flags:
 *    PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE
 *    PM_REGULAR_EXPRESSION_FLAGS_EXTENDED
 *    PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE
 *    PM_REGULAR_EXPRESSION_FLAGS_ONCE
 *    PM_REGULAR_EXPRESSION_FLAGS_EUC_JP
 *    PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT
 *    PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J
 *    PM_REGULAR_EXPRESSION_FLAGS_UTF_8
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING
 *    PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING
 *
 * @extends pm_node_t
 */
typedef struct pm_regular_expression_node {
    /** The embedded base node. */
    pm_node_t base;

    /** RegularExpressionNode#opening_loc */
    pm_location_t opening_loc;

    /** RegularExpressionNode#content_loc */
    pm_location_t content_loc;

    /** RegularExpressionNode#closing_loc */
    pm_location_t closing_loc;

    /** RegularExpressionNode#unescaped */
    pm_string_t unescaped;
} pm_regular_expression_node_t;

/**
 * RequiredKeywordParameterNode
 *
 * Type: PM_REQUIRED_KEYWORD_PARAMETER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_required_keyword_parameter_node {
    /** The embedded base node. */
    pm_node_t base;

    /** RequiredKeywordParameterNode#name */
    pm_constant_id_t name;

    /** RequiredKeywordParameterNode#name_loc */
    pm_location_t name_loc;
} pm_required_keyword_parameter_node_t;

/**
 * RequiredParameterNode
 *
 * Type: PM_REQUIRED_PARAMETER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_required_parameter_node {
    /** The embedded base node. */
    pm_node_t base;

    /** RequiredParameterNode#name */
    pm_constant_id_t name;
} pm_required_parameter_node_t;

/**
 * RescueModifierNode
 *
 * Type: PM_RESCUE_MODIFIER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_rescue_modifier_node {
    /** The embedded base node. */
    pm_node_t base;

    /** RescueModifierNode#expression */
    struct pm_node *expression;

    /** RescueModifierNode#keyword_loc */
    pm_location_t keyword_loc;

    /** RescueModifierNode#rescue_expression */
    struct pm_node *rescue_expression;
} pm_rescue_modifier_node_t;

/**
 * RescueNode
 *
 * Type: PM_RESCUE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_rescue_node {
    /** The embedded base node. */
    pm_node_t base;

    /** RescueNode#keyword_loc */
    pm_location_t keyword_loc;

    /** RescueNode#exceptions */
    struct pm_node_list exceptions;

    /** RescueNode#operator_loc */
    pm_location_t operator_loc;

    /** RescueNode#reference */
    struct pm_node *reference;

    /** RescueNode#statements */
    struct pm_statements_node *statements;

    /** RescueNode#consequent */
    struct pm_rescue_node *consequent;
} pm_rescue_node_t;

/**
 * RestParameterNode
 *
 * Type: PM_REST_PARAMETER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_rest_parameter_node {
    /** The embedded base node. */
    pm_node_t base;

    /** RestParameterNode#name */
    pm_constant_id_t name;

    /** RestParameterNode#name_loc */
    pm_location_t name_loc;

    /** RestParameterNode#operator_loc */
    pm_location_t operator_loc;
} pm_rest_parameter_node_t;

/**
 * RetryNode
 *
 * Type: PM_RETRY_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_retry_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_retry_node_t;

/**
 * ReturnNode
 *
 * Type: PM_RETURN_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_return_node {
    /** The embedded base node. */
    pm_node_t base;

    /** ReturnNode#keyword_loc */
    pm_location_t keyword_loc;

    /** ReturnNode#arguments */
    struct pm_arguments_node *arguments;
} pm_return_node_t;

/**
 * SelfNode
 *
 * Type: PM_SELF_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_self_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_self_node_t;

/**
 * SingletonClassNode
 *
 * Type: PM_SINGLETON_CLASS_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_singleton_class_node {
    /** The embedded base node. */
    pm_node_t base;

    /** SingletonClassNode#locals */
    pm_constant_id_list_t locals;

    /** SingletonClassNode#class_keyword_loc */
    pm_location_t class_keyword_loc;

    /** SingletonClassNode#operator_loc */
    pm_location_t operator_loc;

    /** SingletonClassNode#expression */
    struct pm_node *expression;

    /** SingletonClassNode#body */
    struct pm_node *body;

    /** SingletonClassNode#end_keyword_loc */
    pm_location_t end_keyword_loc;
} pm_singleton_class_node_t;

/**
 * SourceEncodingNode
 *
 * Type: PM_SOURCE_ENCODING_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_source_encoding_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_source_encoding_node_t;

/**
 * SourceFileNode
 *
 * Type: PM_SOURCE_FILE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_source_file_node {
    /** The embedded base node. */
    pm_node_t base;

    /** SourceFileNode#filepath */
    pm_string_t filepath;
} pm_source_file_node_t;

/**
 * SourceLineNode
 *
 * Type: PM_SOURCE_LINE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_source_line_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_source_line_node_t;

/**
 * SplatNode
 *
 * Type: PM_SPLAT_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_splat_node {
    /** The embedded base node. */
    pm_node_t base;

    /** SplatNode#operator_loc */
    pm_location_t operator_loc;

    /** SplatNode#expression */
    struct pm_node *expression;
} pm_splat_node_t;

/**
 * StatementsNode
 *
 * Type: PM_STATEMENTS_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_statements_node {
    /** The embedded base node. */
    pm_node_t base;

    /** StatementsNode#body */
    struct pm_node_list body;
} pm_statements_node_t;

/**
 * StringNode
 *
 * Type: PM_STRING_NODE
 * Flags:
 *    PM_STRING_FLAGS_FORCED_UTF8_ENCODING
 *    PM_STRING_FLAGS_FORCED_BINARY_ENCODING
 *    PM_STRING_FLAGS_FROZEN
 *
 * @extends pm_node_t
 */
typedef struct pm_string_node {
    /** The embedded base node. */
    pm_node_t base;

    /** StringNode#opening_loc */
    pm_location_t opening_loc;

    /** StringNode#content_loc */
    pm_location_t content_loc;

    /** StringNode#closing_loc */
    pm_location_t closing_loc;

    /** StringNode#unescaped */
    pm_string_t unescaped;
} pm_string_node_t;

/**
 * SuperNode
 *
 * Type: PM_SUPER_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_super_node {
    /** The embedded base node. */
    pm_node_t base;

    /** SuperNode#keyword_loc */
    pm_location_t keyword_loc;

    /** SuperNode#lparen_loc */
    pm_location_t lparen_loc;

    /** SuperNode#arguments */
    struct pm_arguments_node *arguments;

    /** SuperNode#rparen_loc */
    pm_location_t rparen_loc;

    /** SuperNode#block */
    struct pm_node *block;
} pm_super_node_t;

/**
 * SymbolNode
 *
 * Type: PM_SYMBOL_NODE
 * Flags:
 *    PM_SYMBOL_FLAGS_FORCED_UTF8_ENCODING
 *    PM_SYMBOL_FLAGS_FORCED_BINARY_ENCODING
 *    PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING
 *
 * @extends pm_node_t
 */
typedef struct pm_symbol_node {
    /** The embedded base node. */
    pm_node_t base;

    /** SymbolNode#opening_loc */
    pm_location_t opening_loc;

    /** SymbolNode#value_loc */
    pm_location_t value_loc;

    /** SymbolNode#closing_loc */
    pm_location_t closing_loc;

    /** SymbolNode#unescaped */
    pm_string_t unescaped;
} pm_symbol_node_t;

/**
 * TrueNode
 *
 * Type: PM_TRUE_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_true_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_true_node_t;

/**
 * UndefNode
 *
 * Type: PM_UNDEF_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_undef_node {
    /** The embedded base node. */
    pm_node_t base;

    /** UndefNode#names */
    struct pm_node_list names;

    /** UndefNode#keyword_loc */
    pm_location_t keyword_loc;
} pm_undef_node_t;

/**
 * UnlessNode
 *
 * Type: PM_UNLESS_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_unless_node {
    /** The embedded base node. */
    pm_node_t base;

    /** UnlessNode#keyword_loc */
    pm_location_t keyword_loc;

    /** UnlessNode#predicate */
    struct pm_node *predicate;

    /** UnlessNode#then_keyword_loc */
    pm_location_t then_keyword_loc;

    /** UnlessNode#statements */
    struct pm_statements_node *statements;

    /** UnlessNode#consequent */
    struct pm_else_node *consequent;

    /** UnlessNode#end_keyword_loc */
    pm_location_t end_keyword_loc;
} pm_unless_node_t;

/**
 * UntilNode
 *
 * Type: PM_UNTIL_NODE
 * Flags:
 *    PM_LOOP_FLAGS_BEGIN_MODIFIER
 *
 * @extends pm_node_t
 */
typedef struct pm_until_node {
    /** The embedded base node. */
    pm_node_t base;

    /** UntilNode#keyword_loc */
    pm_location_t keyword_loc;

    /** UntilNode#closing_loc */
    pm_location_t closing_loc;

    /** UntilNode#predicate */
    struct pm_node *predicate;

    /** UntilNode#statements */
    struct pm_statements_node *statements;
} pm_until_node_t;

/**
 * WhenNode
 *
 * Type: PM_WHEN_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_when_node {
    /** The embedded base node. */
    pm_node_t base;

    /** WhenNode#keyword_loc */
    pm_location_t keyword_loc;

    /** WhenNode#conditions */
    struct pm_node_list conditions;

    /** WhenNode#statements */
    struct pm_statements_node *statements;
} pm_when_node_t;

/**
 * WhileNode
 *
 * Type: PM_WHILE_NODE
 * Flags:
 *    PM_LOOP_FLAGS_BEGIN_MODIFIER
 *
 * @extends pm_node_t
 */
typedef struct pm_while_node {
    /** The embedded base node. */
    pm_node_t base;

    /** WhileNode#keyword_loc */
    pm_location_t keyword_loc;

    /** WhileNode#closing_loc */
    pm_location_t closing_loc;

    /** WhileNode#predicate */
    struct pm_node *predicate;

    /** WhileNode#statements */
    struct pm_statements_node *statements;
} pm_while_node_t;

/**
 * XStringNode
 *
 * Type: PM_X_STRING_NODE
 * Flags:
 *    PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING
 *    PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING
 *
 * @extends pm_node_t
 */
typedef struct pm_x_string_node {
    /** The embedded base node. */
    pm_node_t base;

    /** XStringNode#opening_loc */
    pm_location_t opening_loc;

    /** XStringNode#content_loc */
    pm_location_t content_loc;

    /** XStringNode#closing_loc */
    pm_location_t closing_loc;

    /** XStringNode#unescaped */
    pm_string_t unescaped;
} pm_x_string_node_t;

/**
 * YieldNode
 *
 * Type: PM_YIELD_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_yield_node {
    /** The embedded base node. */
    pm_node_t base;

    /** YieldNode#keyword_loc */
    pm_location_t keyword_loc;

    /** YieldNode#lparen_loc */
    pm_location_t lparen_loc;

    /** YieldNode#arguments */
    struct pm_arguments_node *arguments;

    /** YieldNode#rparen_loc */
    pm_location_t rparen_loc;
} pm_yield_node_t;

/**
 * Flags for arguments nodes.
 */
typedef enum pm_arguments_node_flags {
    /** if arguments contain keyword splat */
    PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT = 1,
} pm_arguments_node_flags_t;

/**
 * Flags for array nodes.
 */
typedef enum pm_array_node_flags {
    /** if array contains splat nodes */
    PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT = 1,
} pm_array_node_flags_t;

/**
 * Flags for call nodes.
 */
typedef enum pm_call_node_flags {
    /** &. operator */
    PM_CALL_NODE_FLAGS_SAFE_NAVIGATION = 1,

    /** a call that could have been a local variable */
    PM_CALL_NODE_FLAGS_VARIABLE_CALL = 2,

    /** a call that is an attribute write, so the value being written should be returned */
    PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE = 4,
} pm_call_node_flags_t;

/**
 * Flags for nodes that have unescaped content.
 */
typedef enum pm_encoding_flags {
    /** internal bytes forced the encoding to UTF-8 */
    PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING = 1,

    /** internal bytes forced the encoding to binary */
    PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING = 2,
} pm_encoding_flags_t;

/**
 * Flags for integer nodes that correspond to the base of the integer.
 */
typedef enum pm_integer_base_flags {
    /** 0b prefix */
    PM_INTEGER_BASE_FLAGS_BINARY = 1,

    /** 0d or no prefix */
    PM_INTEGER_BASE_FLAGS_DECIMAL = 2,

    /** 0o or 0 prefix */
    PM_INTEGER_BASE_FLAGS_OCTAL = 4,

    /** 0x prefix */
    PM_INTEGER_BASE_FLAGS_HEXADECIMAL = 8,
} pm_integer_base_flags_t;

/**
 * Flags for keyword hash nodes.
 */
typedef enum pm_keyword_hash_node_flags {
    /** a keyword hash which only has `AssocNode` elements all with static literal keys, which means the elements can be treated as keyword arguments */
    PM_KEYWORD_HASH_NODE_FLAGS_STATIC_KEYS = 1,
} pm_keyword_hash_node_flags_t;

/**
 * Flags for while and until loop nodes.
 */
typedef enum pm_loop_flags {
    /** a loop after a begin statement, so the body is executed first before the condition */
    PM_LOOP_FLAGS_BEGIN_MODIFIER = 1,
} pm_loop_flags_t;

/**
 * Flags for range and flip-flop nodes.
 */
typedef enum pm_range_flags {
    /** ... operator */
    PM_RANGE_FLAGS_EXCLUDE_END = 1,
} pm_range_flags_t;

/**
 * Flags for regular expression and match last line nodes.
 */
typedef enum pm_regular_expression_flags {
    /** i - ignores the case of characters when matching */
    PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE = 1,

    /** x - ignores whitespace and allows comments in regular expressions */
    PM_REGULAR_EXPRESSION_FLAGS_EXTENDED = 2,

    /** m - allows $ to match the end of lines within strings */
    PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE = 4,

    /** o - only interpolates values into the regular expression once */
    PM_REGULAR_EXPRESSION_FLAGS_ONCE = 8,

    /** e - forces the EUC-JP encoding */
    PM_REGULAR_EXPRESSION_FLAGS_EUC_JP = 16,

    /** n - forces the ASCII-8BIT encoding */
    PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT = 32,

    /** s - forces the Windows-31J encoding */
    PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J = 64,

    /** u - forces the UTF-8 encoding */
    PM_REGULAR_EXPRESSION_FLAGS_UTF_8 = 128,

    /** internal bytes forced the encoding to UTF-8 */
    PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING = 256,

    /** internal bytes forced the encoding to binary */
    PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING = 512,

    /** internal bytes forced the encoding to US-ASCII */
    PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING = 1024,
} pm_regular_expression_flags_t;

/**
 * Flags for string nodes.
 */
typedef enum pm_string_flags {
    /** internal bytes forced the encoding to UTF-8 */
    PM_STRING_FLAGS_FORCED_UTF8_ENCODING = 1,

    /** internal bytes forced the encoding to binary */
    PM_STRING_FLAGS_FORCED_BINARY_ENCODING = 2,

    /** frozen by virtue of a `frozen_string_literal` comment */
    PM_STRING_FLAGS_FROZEN = 4,
} pm_string_flags_t;

/**
 * Flags for symbol nodes.
 */
typedef enum pm_symbol_flags {
    /** internal bytes forced the encoding to UTF-8 */
    PM_SYMBOL_FLAGS_FORCED_UTF8_ENCODING = 1,

    /** internal bytes forced the encoding to binary */
    PM_SYMBOL_FLAGS_FORCED_BINARY_ENCODING = 2,

    /** internal bytes forced the encoding to US-ASCII */
    PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING = 4,
} pm_symbol_flags_t;

/**
 * When we're serializing to Java, we want to skip serializing the location
 * fields as they won't be used by JRuby or TruffleRuby. This boolean allows us
 * to specify that through the environment. It will never be true except for in
 * those build systems.
 */
#define PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS false

#endif
