/******************************************************************************/
/* 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_integer.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,

    /** ItParametersNode */
    PM_IT_PARAMETERS_NODE = 88,

    /** KeywordHashNode */
    PM_KEYWORD_HASH_NODE = 89,

    /** KeywordRestParameterNode */
    PM_KEYWORD_REST_PARAMETER_NODE = 90,

    /** LambdaNode */
    PM_LAMBDA_NODE = 91,

    /** LocalVariableAndWriteNode */
    PM_LOCAL_VARIABLE_AND_WRITE_NODE = 92,

    /** LocalVariableOperatorWriteNode */
    PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE = 93,

    /** LocalVariableOrWriteNode */
    PM_LOCAL_VARIABLE_OR_WRITE_NODE = 94,

    /** LocalVariableReadNode */
    PM_LOCAL_VARIABLE_READ_NODE = 95,

    /** LocalVariableTargetNode */
    PM_LOCAL_VARIABLE_TARGET_NODE = 96,

    /** LocalVariableWriteNode */
    PM_LOCAL_VARIABLE_WRITE_NODE = 97,

    /** MatchLastLineNode */
    PM_MATCH_LAST_LINE_NODE = 98,

    /** MatchPredicateNode */
    PM_MATCH_PREDICATE_NODE = 99,

    /** MatchRequiredNode */
    PM_MATCH_REQUIRED_NODE = 100,

    /** MatchWriteNode */
    PM_MATCH_WRITE_NODE = 101,

    /** MissingNode */
    PM_MISSING_NODE = 102,

    /** ModuleNode */
    PM_MODULE_NODE = 103,

    /** MultiTargetNode */
    PM_MULTI_TARGET_NODE = 104,

    /** MultiWriteNode */
    PM_MULTI_WRITE_NODE = 105,

    /** NextNode */
    PM_NEXT_NODE = 106,

    /** NilNode */
    PM_NIL_NODE = 107,

    /** NoKeywordsParameterNode */
    PM_NO_KEYWORDS_PARAMETER_NODE = 108,

    /** NumberedParametersNode */
    PM_NUMBERED_PARAMETERS_NODE = 109,

    /** NumberedReferenceReadNode */
    PM_NUMBERED_REFERENCE_READ_NODE = 110,

    /** OptionalKeywordParameterNode */
    PM_OPTIONAL_KEYWORD_PARAMETER_NODE = 111,

    /** OptionalParameterNode */
    PM_OPTIONAL_PARAMETER_NODE = 112,

    /** OrNode */
    PM_OR_NODE = 113,

    /** ParametersNode */
    PM_PARAMETERS_NODE = 114,

    /** ParenthesesNode */
    PM_PARENTHESES_NODE = 115,

    /** PinnedExpressionNode */
    PM_PINNED_EXPRESSION_NODE = 116,

    /** PinnedVariableNode */
    PM_PINNED_VARIABLE_NODE = 117,

    /** PostExecutionNode */
    PM_POST_EXECUTION_NODE = 118,

    /** PreExecutionNode */
    PM_PRE_EXECUTION_NODE = 119,

    /** ProgramNode */
    PM_PROGRAM_NODE = 120,

    /** RangeNode */
    PM_RANGE_NODE = 121,

    /** RationalNode */
    PM_RATIONAL_NODE = 122,

    /** RedoNode */
    PM_REDO_NODE = 123,

    /** RegularExpressionNode */
    PM_REGULAR_EXPRESSION_NODE = 124,

    /** RequiredKeywordParameterNode */
    PM_REQUIRED_KEYWORD_PARAMETER_NODE = 125,

    /** RequiredParameterNode */
    PM_REQUIRED_PARAMETER_NODE = 126,

    /** RescueModifierNode */
    PM_RESCUE_MODIFIER_NODE = 127,

    /** RescueNode */
    PM_RESCUE_NODE = 128,

    /** RestParameterNode */
    PM_REST_PARAMETER_NODE = 129,

    /** RetryNode */
    PM_RETRY_NODE = 130,

    /** ReturnNode */
    PM_RETURN_NODE = 131,

    /** SelfNode */
    PM_SELF_NODE = 132,

    /** ShareableConstantNode */
    PM_SHAREABLE_CONSTANT_NODE = 133,

    /** SingletonClassNode */
    PM_SINGLETON_CLASS_NODE = 134,

    /** SourceEncodingNode */
    PM_SOURCE_ENCODING_NODE = 135,

    /** SourceFileNode */
    PM_SOURCE_FILE_NODE = 136,

    /** SourceLineNode */
    PM_SOURCE_LINE_NODE = 137,

    /** SplatNode */
    PM_SPLAT_NODE = 138,

    /** StatementsNode */
    PM_STATEMENTS_NODE = 139,

    /** StringNode */
    PM_STRING_NODE = 140,

    /** SuperNode */
    PM_SUPER_NODE = 141,

    /** SymbolNode */
    PM_SYMBOL_NODE = 142,

    /** TrueNode */
    PM_TRUE_NODE = 143,

    /** UndefNode */
    PM_UNDEF_NODE = 144,

    /** UnlessNode */
    PM_UNLESS_NODE = 145,

    /** UntilNode */
    PM_UNTIL_NODE = 146,

    /** WhenNode */
    PM_WHEN_NODE = 147,

    /** WhileNode */
    PM_WHILE_NODE = 148,

    /** XStringNode */
    PM_X_STRING_NODE = 149,

    /** YieldNode */
    PM_YIELD_NODE = 150,

    /** 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
     *
     * Represents the new name of the global variable that can be used after aliasing. This can be either a global variable, a back reference, or a numbered reference.
     *
     *     alias $foo $bar
     *           ^^^^
     */
    struct pm_node *new_name;

    /**
     * AliasGlobalVariableNode#old_name
     *
     * Represents the old name of the global variable that could be used before aliasing. This can be either a global variable, a back reference, or a numbered reference.
     *
     *     alias $foo $bar
     *                ^^^^
     */
    struct pm_node *old_name;

    /**
     * AliasGlobalVariableNode#keyword_loc
     *
     * The location of the `alias` keyword.
     *
     *     alias $foo $bar
     *     ^^^^^
     */
    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
     *
     * Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
     *
     *     left and right
     *     ^^^^
     *
     *     1 && 2
     *     ^
     */
    struct pm_node *left;

    /**
     * AndNode#right
     *
     * Represents the right side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
     *
     *     left && right
     *             ^^^^^
     *
     *     1 and 2
     *           ^
     */
    struct pm_node *right;

    /**
     * AndNode#operator_loc
     *
     * The location of the `and` keyword or the `&&` operator.
     *
     *     left and right
     *          ^^^
     */
    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
     *
     * Represent the list of zero or more [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression) within the array.
     */
    struct pm_node_list elements;

    /**
     * ArrayNode#opening_loc
     *
     * Represents the optional source location for the opening token.
     *
     *     [1,2,3]                 # "["
     *     %w[foo bar baz]         # "%w["
     *     %I(apple orange banana) # "%I("
     *     foo = 1, 2, 3           # nil
     */
    pm_location_t opening_loc;

    /**
     * ArrayNode#closing_loc
     *
     * Represents the optional source location for the closing token.
     *
     *     [1,2,3]                 # "]"
     *     %w[foo bar baz]         # "]"
     *     %I(apple orange banana) # ")"
     *     foo = 1, 2, 3           # nil
     */
    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
     *
     * The key of the association. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
     *
     *     { a: b }
     *       ^
     *
     *     { foo => bar }
     *       ^^^
     *
     *     { def a; end => 1 }
     *       ^^^^^^^^^^
     */
    struct pm_node *key;

    /**
     * AssocNode#value
     *
     * The value of the association, if present. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
     *
     *     { foo => bar }
     *              ^^^
     *
     *     { x: 1 }
     *          ^
     */
    struct pm_node *value;

    /**
     * AssocNode#operator_loc
     *
     * The location of the `=>` operator, if present.
     *
     *     { foo => bar }
     *           ^^
     */
    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
     *
     * The value to be splatted, if present. Will be missing when keyword rest argument forwarding is used.
     *
     *     { **foo }
     *         ^^^
     */
    struct pm_node *value;

    /**
     * AssocSplatNode#operator_loc
     *
     * The location of the `**` operator.
     *
     *     { **x }
     *       ^^
     */
    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
     *
     * The name of the back-reference variable, including the leading `$`.
     *
     *     $& # name `:$&`
     *
     *     $+ # 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
 * Flags:
 *    PM_PARAMETER_FLAGS_REPEATED_PARAMETER
 *
 * @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#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
 * Flags:
 *    PM_PARAMETER_FLAGS_REPEATED_PARAMETER
 *
 * @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
     *
     * The arguments to the break statement, if present. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
     *
     *     break foo
     *           ^^^
     */
    struct pm_arguments_node *arguments;

    /**
     * BreakNode#keyword_loc
     *
     * The location of the `break` keyword.
     *
     *     break foo
     *     ^^^^^
     */
    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
 *    PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY
 *
 * @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
 *    PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY
 *
 * @extends pm_node_t
 */
typedef struct pm_call_node {
    /** The embedded base node. */
    pm_node_t base;

    /**
     * CallNode#receiver
     *
     * The object that the method is being called on. This can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
     *
     *     foo.bar
     *     ^^^
     *
     *     +foo
     *      ^^^
     *
     *     foo + bar
     *     ^^^
     */
    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
 *    PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY
 *
 * @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
 *    PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY
 *
 * @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
 *    PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY
 *
 * @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
     *
     * The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers).
     *
     *     @@abc   # name `:@@abc`
     *
     *     @@_test # name `:@@_test`
     */
    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
     *
     * The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers).
     *
     *     @@abc = 123     # name `@@abc`
     *
     *     @@_test = :test # name `@@_test`
     */
    pm_constant_id_t name;

    /**
     * ClassVariableWriteNode#name_loc
     *
     * The location of the variable name.
     *
     *     @@foo = :bar
     *     ^^^^^
     */
    pm_location_t name_loc;

    /**
     * ClassVariableWriteNode#value
     *
     * The value to assign to the class variable. Can be any node that
     * represents a non-void expression.
     *
     *     @@foo = :bar
     *             ^^^^
     *
     *     @@_xyz = 123
     *              ^^^
     */
    struct pm_node *value;

    /**
     * ClassVariableWriteNode#operator_loc
     *
     * The location of the `=` operator.
     *
     *     @@foo = :bar
     *           ^
     */
    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
     *
     * The name of the [constant](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#constants).
     *
     *     X              # name `:X`
     *
     *     SOME_CONSTANT  # name `:SOME_CONSTANT`
     */
    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#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;

    /**
     * FloatNode#value
     *
     * The value of the floating point number as a Float.
     */
    double value;
} 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
     *
     * The name of the global variable, which is a `$` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifier). Alternatively, it can be one of the special global variables designated by a symbol.
     *
     *     $foo   # name `:$foo`
     *
     *     $_Test # name `:$_Test`
     */
    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
     *
     * The location of the opening brace.
     *
     *     { a => b }
     *     ^
     */
    pm_location_t opening_loc;

    /**
     * HashNode#elements
     *
     * The elements of the hash. These can be either `AssocNode`s or `AssocSplatNode`s.
     *
     *     { a: b }
     *       ^^^^
     *
     *     { **foo }
     *       ^^^^^
     */
    struct pm_node_list elements;

    /**
     * HashNode#closing_loc
     *
     * The location of the closing brace.
     *
     *     { a => b }
     *              ^
     */
    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
     *
     * The location of the `if` keyword if present.
     *
     *     bar if foo
     *         ^^
     *
     * The `if_keyword_loc` field will be `nil` when the `IfNode` represents a ternary expression.
     */
    pm_location_t if_keyword_loc;

    /**
     * IfNode#predicate
     *
     * The node for the condition the `IfNode` is testing.
     *
     *     if foo
     *        ^^^
     *       bar
     *     end
     *
     *     bar if foo
     *            ^^^
     *
     *     foo ? bar : baz
     *     ^^^
     */
    struct pm_node *predicate;

    /**
     * IfNode#then_keyword_loc
     *
     * The location of the `then` keyword (if present) or the `?` in a ternary expression, `nil` otherwise.
     *
     *     if foo then bar end
     *            ^^^^
     *
     *     a ? b : c
     *       ^
     */
    pm_location_t then_keyword_loc;

    /**
     * IfNode#statements
     *
     * Represents the body of statements that will be executed when the predicate is evaluated as truthy. Will be `nil` when no body is provided.
     *
     *     if foo
     *       bar
     *       ^^^
     *       baz
     *       ^^^
     *     end
     */
    struct pm_statements_node *statements;

    /**
     * IfNode#consequent
     *
     * Represents an `ElseNode` or an `IfNode` when there is an `else` or an `elsif` in the `if` statement.
     *
     *     if foo
     *       bar
     *     elsif baz
     *     ^^^^^^^^^
     *       qux
     *       ^^^
     *     end
     *     ^^^
     *
     *     if foo then bar else baz end
     *                     ^^^^^^^^^^^^
     */
    struct pm_node *consequent;

    /**
     * IfNode#end_keyword_loc
     *
     * The location of the `end` keyword if present, `nil` otherwise.
     *
     *     if foo
     *       bar
     *     end
     *     ^^^
     */
    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
 *    PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY
 *
 * @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
 *    PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY
 *
 * @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
 *    PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY
 *
 * @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
 *    PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY
 *
 * @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
     *
     * The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers).
     *
     *     @x     # name `:@x`
     *
     *     @_test # name `:@_test`
     */
    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
     *
     * The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers).
     *
     *     @x = :y       # name `:@x`
     *
     *     @_foo = "bar" # name `@_foo`
     */
    pm_constant_id_t name;

    /**
     * InstanceVariableWriteNode#name_loc
     *
     * The location of the variable name.
     *
     *     @_x = 1
     *     ^^^
     */
    pm_location_t name_loc;

    /**
     * InstanceVariableWriteNode#value
     *
     * The value to assign to the instance variable. Can be any node that
     * represents a non-void expression.
     *
     *     @foo = :bar
     *            ^^^^
     *
     *     @_x = 1234
     *           ^^^^
     */
    struct pm_node *value;

    /**
     * InstanceVariableWriteNode#operator_loc
     *
     * The location of the `=` operator.
     *
     *     @x = y
     *        ^
     */
    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;

    /**
     * IntegerNode#value
     *
     * The value of the integer literal as a number.
     */
    pm_integer_t value;
} 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
 * Flags:
 *    PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN
 *    PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE
 *
 * @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;

/**
 * ItParametersNode
 *
 * Type: PM_IT_PARAMETERS_NODE
 *
 * @extends pm_node_t
 */
typedef struct pm_it_parameters_node {
    /** The embedded base node. */
    pm_node_t base;
} pm_it_parameters_node_t;

/**
 * KeywordHashNode
 *
 * Type: PM_KEYWORD_HASH_NODE
 * Flags:
 *    PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_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
 * Flags:
 *    PM_PARAMETER_FLAGS_REPEATED_PARAMETER
 *
 * @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#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
     *
     * The name of the local variable, which is an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers).
     *
     *     x      # name `:x`
     *
     *     _Test  # name `:_Test`
     *
     * Note that this can also be an underscore followed by a number for the default block parameters.
     *
     *     _1     # name `:_1`
     *
     * Finally, for the default `it` block parameter, the name is `0it`. This is to distinguish it from an `it` local variable that is explicitly declared.
     *
     *     it     # name `:0it`
     */
    pm_constant_id_t name;

    /**
     * LocalVariableReadNode#depth
     *
     * The number of visible scopes that should be searched to find the origin of this local variable.
     *
     *     foo = 1; foo # depth 0
     *
     *     bar = 2; tap { bar } # depth 1
     *
     * The specific rules for calculating the depth may differ from individual Ruby implementations, as they are not specified by the language. For more information, see [the Prism documentation](https://github.com/ruby/prism/blob/main/docs/local_variable_depth.md).
     */
    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
     *
     * The (1-indexed, from the left) number of the capture group. Numbered references that are too large result in this value being `0`.
     *
     *     $1          # number `1`
     *
     *     $5432       # number `5432`
     *
     *     $4294967296 # number `0`
     */
    uint32_t number;
} pm_numbered_reference_read_node_t;

/**
 * OptionalKeywordParameterNode
 *
 * Type: PM_OPTIONAL_KEYWORD_PARAMETER_NODE
 * Flags:
 *    PM_PARAMETER_FLAGS_REPEATED_PARAMETER
 *
 * @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
 * Flags:
 *    PM_PARAMETER_FLAGS_REPEATED_PARAMETER
 *
 * @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
     *
     * Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
     *
     *     left or right
     *     ^^^^
     *
     *     1 || 2
     *     ^
     */
    struct pm_node *left;

    /**
     * OrNode#right
     *
     * Represents the right side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
     *
     *     left || right
     *             ^^^^^
     *
     *     1 or 2
     *          ^
     */
    struct pm_node *right;

    /**
     * OrNode#operator_loc
     *
     * The location of the `or` keyword or the `||` operator.
     *
     *     left or right
     *          ^^
     */
    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
     *
     * The left-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
     *
     *     1...
     *     ^
     *
     *     hello...goodbye
     *     ^^^^^
     */
    struct pm_node *left;

    /**
     * RangeNode#right
     *
     * The right-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
     *
     *     ..5
     *       ^
     *
     *     1...foo
     *         ^^^
     * If neither right-hand or left-hand side was included, this will be a MissingNode.
     */
    struct pm_node *right;

    /**
     * RangeNode#operator_loc
     *
     * The location of the `..` or `...` operator.
     */
    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
 * Flags:
 *    PM_PARAMETER_FLAGS_REPEATED_PARAMETER
 *
 * @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
 * Flags:
 *    PM_PARAMETER_FLAGS_REPEATED_PARAMETER
 *
 * @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
 * Flags:
 *    PM_PARAMETER_FLAGS_REPEATED_PARAMETER
 *
 * @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;

/**
 * ShareableConstantNode
 *
 * Type: PM_SHAREABLE_CONSTANT_NODE
 * Flags:
 *    PM_SHAREABLE_CONSTANT_NODE_FLAGS_LITERAL
 *    PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_EVERYTHING
 *    PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY
 *
 * @extends pm_node_t
 */
typedef struct pm_shareable_constant_node {
    /** The embedded base node. */
    pm_node_t base;

    /**
     * ShareableConstantNode#write
     *
     * The constant write that should be modified with the shareability state.
     */
    struct pm_node *write;
} pm_shareable_constant_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
 * Flags:
 *    PM_STRING_FLAGS_FORCED_UTF8_ENCODING
 *    PM_STRING_FLAGS_FORCED_BINARY_ENCODING
 *    PM_STRING_FLAGS_FROZEN
 *    PM_STRING_FLAGS_MUTABLE
 *
 * @extends pm_node_t
 */
typedef struct pm_source_file_node {
    /** The embedded base node. */
    pm_node_t base;

    /**
     * SourceFileNode#filepath
     *
     * Represents the file path being parsed. This corresponds directly to the `filepath` option given to the various `Prism::parse*` APIs.
     */
    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
 *    PM_STRING_FLAGS_MUTABLE
 *
 * @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
     *
     * The location of the `unless` keyword.
     *
     *     unless cond then bar end
     *     ^^^^^^
     *
     *     bar unless cond
     *         ^^^^^^
     */
    pm_location_t keyword_loc;

    /**
     * UnlessNode#predicate
     *
     * The condition to be evaluated for the unless expression. Can be any
     * kind of node that represents a non-void expression.
     *
     *     unless cond then bar end
     *            ^^^^
     *
     *     bar unless cond
     *                ^^^^
     */
    struct pm_node *predicate;

    /**
     * UnlessNode#then_keyword_loc
     *
     * The location of the `then` keyword, if present.
     * unless cond then bar end ^^^^
     */
    pm_location_t then_keyword_loc;

    /**
     * UnlessNode#statements
     *
     * The body of statements that will executed if the unless condition is
     * falsey. Will be `nil` if no body is provided.
     *
     *     unless cond then bar end
     *                      ^^^
     */
    struct pm_statements_node *statements;

    /**
     * UnlessNode#consequent
     *
     * The else clause of the unless expression, if present.
     *
     *     unless cond then bar else baz end
     *                          ^^^^^^^^
     */
    struct pm_else_node *consequent;

    /**
     * UnlessNode#end_keyword_loc
     *
     * The location of the `end` keyword, if present.
     *
     *     unless cond then bar end
     *                          ^^^
     */
    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#then_keyword_loc
     */
    pm_location_t then_keyword_loc;

    /**
     * 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,

    /** a call that ignores method visibility */
    PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY = 8,
} 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 interpolated string nodes that indicated mutability if they are also marked as literals.
 */
typedef enum pm_interpolated_string_node_flags {
    /** frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` */
    PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN = 1,

    /** mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` */
    PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE = 2,
} pm_interpolated_string_node_flags_t;

/**
 * Flags for keyword hash nodes.
 */
typedef enum pm_keyword_hash_node_flags {
    /** a keyword hash which only has `AssocNode` elements all with symbol keys, which means the elements can be treated as keyword arguments */
    PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_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 parameter nodes.
 */
typedef enum pm_parameter_flags {
    /** a parameter name that has been repeated in the method signature */
    PM_PARAMETER_FLAGS_REPEATED_PARAMETER = 1,
} pm_parameter_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 shareable constant nodes.
 */
typedef enum pm_shareable_constant_node_flags {
    /** constant writes that should be modified with shareable constant value literal */
    PM_SHAREABLE_CONSTANT_NODE_FLAGS_LITERAL = 1,

    /** constant writes that should be modified with shareable constant value experimental everything */
    PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_EVERYTHING = 2,

    /** constant writes that should be modified with shareable constant value experimental copy */
    PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY = 4,
} pm_shareable_constant_node_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: true` comment or `--enable-frozen-string-literal` */
    PM_STRING_FLAGS_FROZEN = 4,

    /** mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal` */
    PM_STRING_FLAGS_MUTABLE = 8,
} 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
