/******************************************************************************/
/* This file is generated by the templates/template.rb script and should not  */
/* be modified manually. See                                                  */
/* templates/src/node.c.erb                                                   */
/* if you are looking to modify the                                           */
/* template                                                                   */
/******************************************************************************/
#line 2 "node.c.erb"
#include "prism/node.h"

static void
pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize);

/**
 * Calculate the size of the node list in bytes.
 */
static size_t
pm_node_list_memsize(pm_node_list_t *node_list, pm_memsize_t *memsize) {
    size_t size = sizeof(pm_node_list_t) + (node_list->capacity * sizeof(pm_node_t *));
    for (size_t index = 0; index < node_list->size; index++) {
        pm_node_memsize_node(node_list->nodes[index], memsize);
    }
    return size;
}

/**
 * Append a new node onto the end of the node list.
 */
void
pm_node_list_append(pm_node_list_t *list, pm_node_t *node) {
    if (list->size == list->capacity) {
        list->capacity = list->capacity == 0 ? 4 : list->capacity * 2;
        list->nodes = (pm_node_t **) realloc(list->nodes, sizeof(pm_node_t *) * list->capacity);
    }
    list->nodes[list->size++] = node;
}

PRISM_EXPORTED_FUNCTION void
pm_node_destroy(pm_parser_t *parser, pm_node_t *node);

/**
 * Deallocate the inner memory of a list of nodes. The parser argument is not
 * used, but is here for the future possibility of pre-allocating memory pools.
 */
static void
pm_node_list_free(pm_parser_t *parser, pm_node_list_t *list) {
    if (list->capacity > 0) {
        for (size_t index = 0; index < list->size; index++) {
            pm_node_destroy(parser, list->nodes[index]);
        }
        free(list->nodes);
    }
}

/**
 * Deallocate the space for a pm_node_t. Similarly to pm_node_alloc, we're not
 * using the parser argument, but it's there to allow for the future possibility
 * of pre-allocating larger memory pools.
 */
PRISM_EXPORTED_FUNCTION void
pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
    switch (PM_NODE_TYPE(node)) {
#line 58 "node.c.erb"
        case PM_ALIAS_GLOBAL_VARIABLE_NODE: {
            pm_alias_global_variable_node_t *cast = (pm_alias_global_variable_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->new_name);
            pm_node_destroy(parser, (pm_node_t *)cast->old_name);
            break;
        }
#line 58 "node.c.erb"
        case PM_ALIAS_METHOD_NODE: {
            pm_alias_method_node_t *cast = (pm_alias_method_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->new_name);
            pm_node_destroy(parser, (pm_node_t *)cast->old_name);
            break;
        }
#line 58 "node.c.erb"
        case PM_ALTERNATION_PATTERN_NODE: {
            pm_alternation_pattern_node_t *cast = (pm_alternation_pattern_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->left);
            pm_node_destroy(parser, (pm_node_t *)cast->right);
            break;
        }
#line 58 "node.c.erb"
        case PM_AND_NODE: {
            pm_and_node_t *cast = (pm_and_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->left);
            pm_node_destroy(parser, (pm_node_t *)cast->right);
            break;
        }
#line 58 "node.c.erb"
        case PM_ARGUMENTS_NODE: {
            pm_arguments_node_t *cast = (pm_arguments_node_t *) node;
            pm_node_list_free(parser, &cast->arguments);
            break;
        }
#line 58 "node.c.erb"
        case PM_ARRAY_NODE: {
            pm_array_node_t *cast = (pm_array_node_t *) node;
            pm_node_list_free(parser, &cast->elements);
            break;
        }
#line 58 "node.c.erb"
        case PM_ARRAY_PATTERN_NODE: {
            pm_array_pattern_node_t *cast = (pm_array_pattern_node_t *) node;
            if (cast->constant != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->constant);
            }
            pm_node_list_free(parser, &cast->requireds);
            if (cast->rest != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->rest);
            }
            pm_node_list_free(parser, &cast->posts);
            break;
        }
#line 58 "node.c.erb"
        case PM_ASSOC_NODE: {
            pm_assoc_node_t *cast = (pm_assoc_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->key);
            if (cast->value != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->value);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_ASSOC_SPLAT_NODE: {
            pm_assoc_splat_node_t *cast = (pm_assoc_splat_node_t *) node;
            if (cast->value != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->value);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_BACK_REFERENCE_READ_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_BEGIN_NODE: {
            pm_begin_node_t *cast = (pm_begin_node_t *) node;
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            if (cast->rescue_clause != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->rescue_clause);
            }
            if (cast->else_clause != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->else_clause);
            }
            if (cast->ensure_clause != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->ensure_clause);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_BLOCK_ARGUMENT_NODE: {
            pm_block_argument_node_t *cast = (pm_block_argument_node_t *) node;
            if (cast->expression != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->expression);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_BLOCK_LOCAL_VARIABLE_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_BLOCK_NODE: {
            pm_block_node_t *cast = (pm_block_node_t *) node;
            pm_constant_id_list_free(&cast->locals);
            if (cast->parameters != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->parameters);
            }
            if (cast->body != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->body);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_BLOCK_PARAMETER_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_BLOCK_PARAMETERS_NODE: {
            pm_block_parameters_node_t *cast = (pm_block_parameters_node_t *) node;
            if (cast->parameters != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->parameters);
            }
            pm_node_list_free(parser, &cast->locals);
            break;
        }
#line 58 "node.c.erb"
        case PM_BREAK_NODE: {
            pm_break_node_t *cast = (pm_break_node_t *) node;
            if (cast->arguments != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->arguments);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_CALL_AND_WRITE_NODE: {
            pm_call_and_write_node_t *cast = (pm_call_and_write_node_t *) node;
            if (cast->receiver != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->receiver);
            }
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CALL_NODE: {
            pm_call_node_t *cast = (pm_call_node_t *) node;
            if (cast->receiver != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->receiver);
            }
            if (cast->arguments != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->arguments);
            }
            if (cast->block != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->block);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_CALL_OPERATOR_WRITE_NODE: {
            pm_call_operator_write_node_t *cast = (pm_call_operator_write_node_t *) node;
            if (cast->receiver != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->receiver);
            }
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CALL_OR_WRITE_NODE: {
            pm_call_or_write_node_t *cast = (pm_call_or_write_node_t *) node;
            if (cast->receiver != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->receiver);
            }
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CALL_TARGET_NODE: {
            pm_call_target_node_t *cast = (pm_call_target_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->receiver);
            break;
        }
#line 58 "node.c.erb"
        case PM_CAPTURE_PATTERN_NODE: {
            pm_capture_pattern_node_t *cast = (pm_capture_pattern_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            pm_node_destroy(parser, (pm_node_t *)cast->target);
            break;
        }
#line 58 "node.c.erb"
        case PM_CASE_MATCH_NODE: {
            pm_case_match_node_t *cast = (pm_case_match_node_t *) node;
            if (cast->predicate != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->predicate);
            }
            pm_node_list_free(parser, &cast->conditions);
            if (cast->consequent != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->consequent);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_CASE_NODE: {
            pm_case_node_t *cast = (pm_case_node_t *) node;
            if (cast->predicate != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->predicate);
            }
            pm_node_list_free(parser, &cast->conditions);
            if (cast->consequent != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->consequent);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_CLASS_NODE: {
            pm_class_node_t *cast = (pm_class_node_t *) node;
            pm_constant_id_list_free(&cast->locals);
            pm_node_destroy(parser, (pm_node_t *)cast->constant_path);
            if (cast->superclass != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->superclass);
            }
            if (cast->body != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->body);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_CLASS_VARIABLE_AND_WRITE_NODE: {
            pm_class_variable_and_write_node_t *cast = (pm_class_variable_and_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_class_variable_operator_write_node_t *cast = (pm_class_variable_operator_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CLASS_VARIABLE_OR_WRITE_NODE: {
            pm_class_variable_or_write_node_t *cast = (pm_class_variable_or_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CLASS_VARIABLE_READ_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_CLASS_VARIABLE_TARGET_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_CLASS_VARIABLE_WRITE_NODE: {
            pm_class_variable_write_node_t *cast = (pm_class_variable_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_AND_WRITE_NODE: {
            pm_constant_and_write_node_t *cast = (pm_constant_and_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_OPERATOR_WRITE_NODE: {
            pm_constant_operator_write_node_t *cast = (pm_constant_operator_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_OR_WRITE_NODE: {
            pm_constant_or_write_node_t *cast = (pm_constant_or_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_PATH_AND_WRITE_NODE: {
            pm_constant_path_and_write_node_t *cast = (pm_constant_path_and_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->target);
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_PATH_NODE: {
            pm_constant_path_node_t *cast = (pm_constant_path_node_t *) node;
            if (cast->parent != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->parent);
            }
            pm_node_destroy(parser, (pm_node_t *)cast->child);
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: {
            pm_constant_path_operator_write_node_t *cast = (pm_constant_path_operator_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->target);
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_PATH_OR_WRITE_NODE: {
            pm_constant_path_or_write_node_t *cast = (pm_constant_path_or_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->target);
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_PATH_TARGET_NODE: {
            pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *) node;
            if (cast->parent != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->parent);
            }
            pm_node_destroy(parser, (pm_node_t *)cast->child);
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_PATH_WRITE_NODE: {
            pm_constant_path_write_node_t *cast = (pm_constant_path_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->target);
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_READ_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_TARGET_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_CONSTANT_WRITE_NODE: {
            pm_constant_write_node_t *cast = (pm_constant_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_DEF_NODE: {
            pm_def_node_t *cast = (pm_def_node_t *) node;
            if (cast->receiver != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->receiver);
            }
            if (cast->parameters != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->parameters);
            }
            if (cast->body != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->body);
            }
            pm_constant_id_list_free(&cast->locals);
            break;
        }
#line 58 "node.c.erb"
        case PM_DEFINED_NODE: {
            pm_defined_node_t *cast = (pm_defined_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_ELSE_NODE: {
            pm_else_node_t *cast = (pm_else_node_t *) node;
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_EMBEDDED_STATEMENTS_NODE: {
            pm_embedded_statements_node_t *cast = (pm_embedded_statements_node_t *) node;
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_EMBEDDED_VARIABLE_NODE: {
            pm_embedded_variable_node_t *cast = (pm_embedded_variable_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->variable);
            break;
        }
#line 58 "node.c.erb"
        case PM_ENSURE_NODE: {
            pm_ensure_node_t *cast = (pm_ensure_node_t *) node;
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_FALSE_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_FIND_PATTERN_NODE: {
            pm_find_pattern_node_t *cast = (pm_find_pattern_node_t *) node;
            if (cast->constant != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->constant);
            }
            pm_node_destroy(parser, (pm_node_t *)cast->left);
            pm_node_list_free(parser, &cast->requireds);
            pm_node_destroy(parser, (pm_node_t *)cast->right);
            break;
        }
#line 58 "node.c.erb"
        case PM_FLIP_FLOP_NODE: {
            pm_flip_flop_node_t *cast = (pm_flip_flop_node_t *) node;
            if (cast->left != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->left);
            }
            if (cast->right != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->right);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_FLOAT_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_FOR_NODE: {
            pm_for_node_t *cast = (pm_for_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->index);
            pm_node_destroy(parser, (pm_node_t *)cast->collection);
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_FORWARDING_ARGUMENTS_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_FORWARDING_PARAMETER_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_FORWARDING_SUPER_NODE: {
            pm_forwarding_super_node_t *cast = (pm_forwarding_super_node_t *) node;
            if (cast->block != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->block);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: {
            pm_global_variable_and_write_node_t *cast = (pm_global_variable_and_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_global_variable_operator_write_node_t *cast = (pm_global_variable_operator_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: {
            pm_global_variable_or_write_node_t *cast = (pm_global_variable_or_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_GLOBAL_VARIABLE_READ_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_GLOBAL_VARIABLE_TARGET_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_GLOBAL_VARIABLE_WRITE_NODE: {
            pm_global_variable_write_node_t *cast = (pm_global_variable_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_HASH_NODE: {
            pm_hash_node_t *cast = (pm_hash_node_t *) node;
            pm_node_list_free(parser, &cast->elements);
            break;
        }
#line 58 "node.c.erb"
        case PM_HASH_PATTERN_NODE: {
            pm_hash_pattern_node_t *cast = (pm_hash_pattern_node_t *) node;
            if (cast->constant != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->constant);
            }
            pm_node_list_free(parser, &cast->elements);
            if (cast->rest != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->rest);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_IF_NODE: {
            pm_if_node_t *cast = (pm_if_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->predicate);
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            if (cast->consequent != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->consequent);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_IMAGINARY_NODE: {
            pm_imaginary_node_t *cast = (pm_imaginary_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->numeric);
            break;
        }
#line 58 "node.c.erb"
        case PM_IMPLICIT_NODE: {
            pm_implicit_node_t *cast = (pm_implicit_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_IMPLICIT_REST_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_IN_NODE: {
            pm_in_node_t *cast = (pm_in_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->pattern);
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_INDEX_AND_WRITE_NODE: {
            pm_index_and_write_node_t *cast = (pm_index_and_write_node_t *) node;
            if (cast->receiver != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->receiver);
            }
            if (cast->arguments != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->arguments);
            }
            if (cast->block != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->block);
            }
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_INDEX_OPERATOR_WRITE_NODE: {
            pm_index_operator_write_node_t *cast = (pm_index_operator_write_node_t *) node;
            if (cast->receiver != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->receiver);
            }
            if (cast->arguments != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->arguments);
            }
            if (cast->block != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->block);
            }
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_INDEX_OR_WRITE_NODE: {
            pm_index_or_write_node_t *cast = (pm_index_or_write_node_t *) node;
            if (cast->receiver != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->receiver);
            }
            if (cast->arguments != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->arguments);
            }
            if (cast->block != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->block);
            }
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_INDEX_TARGET_NODE: {
            pm_index_target_node_t *cast = (pm_index_target_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->receiver);
            if (cast->arguments != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->arguments);
            }
            if (cast->block != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->block);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
            pm_instance_variable_and_write_node_t *cast = (pm_instance_variable_and_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_instance_variable_operator_write_node_t *cast = (pm_instance_variable_operator_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: {
            pm_instance_variable_or_write_node_t *cast = (pm_instance_variable_or_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_INSTANCE_VARIABLE_READ_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_INSTANCE_VARIABLE_TARGET_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_INSTANCE_VARIABLE_WRITE_NODE: {
            pm_instance_variable_write_node_t *cast = (pm_instance_variable_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_INTEGER_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: {
            pm_interpolated_match_last_line_node_t *cast = (pm_interpolated_match_last_line_node_t *) node;
            pm_node_list_free(parser, &cast->parts);
            break;
        }
#line 58 "node.c.erb"
        case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
            pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node;
            pm_node_list_free(parser, &cast->parts);
            break;
        }
#line 58 "node.c.erb"
        case PM_INTERPOLATED_STRING_NODE: {
            pm_interpolated_string_node_t *cast = (pm_interpolated_string_node_t *) node;
            pm_node_list_free(parser, &cast->parts);
            break;
        }
#line 58 "node.c.erb"
        case PM_INTERPOLATED_SYMBOL_NODE: {
            pm_interpolated_symbol_node_t *cast = (pm_interpolated_symbol_node_t *) node;
            pm_node_list_free(parser, &cast->parts);
            break;
        }
#line 58 "node.c.erb"
        case PM_INTERPOLATED_X_STRING_NODE: {
            pm_interpolated_x_string_node_t *cast = (pm_interpolated_x_string_node_t *) node;
            pm_node_list_free(parser, &cast->parts);
            break;
        }
#line 58 "node.c.erb"
        case PM_KEYWORD_HASH_NODE: {
            pm_keyword_hash_node_t *cast = (pm_keyword_hash_node_t *) node;
            pm_node_list_free(parser, &cast->elements);
            break;
        }
#line 58 "node.c.erb"
        case PM_KEYWORD_REST_PARAMETER_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_LAMBDA_NODE: {
            pm_lambda_node_t *cast = (pm_lambda_node_t *) node;
            pm_constant_id_list_free(&cast->locals);
            if (cast->parameters != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->parameters);
            }
            if (cast->body != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->body);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_LOCAL_VARIABLE_AND_WRITE_NODE: {
            pm_local_variable_and_write_node_t *cast = (pm_local_variable_and_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_local_variable_operator_write_node_t *cast = (pm_local_variable_operator_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_LOCAL_VARIABLE_OR_WRITE_NODE: {
            pm_local_variable_or_write_node_t *cast = (pm_local_variable_or_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_LOCAL_VARIABLE_READ_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_LOCAL_VARIABLE_TARGET_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_LOCAL_VARIABLE_WRITE_NODE: {
            pm_local_variable_write_node_t *cast = (pm_local_variable_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_MATCH_LAST_LINE_NODE: {
            pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) node;
            pm_string_free(&cast->unescaped);
            break;
        }
#line 58 "node.c.erb"
        case PM_MATCH_PREDICATE_NODE: {
            pm_match_predicate_node_t *cast = (pm_match_predicate_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            pm_node_destroy(parser, (pm_node_t *)cast->pattern);
            break;
        }
#line 58 "node.c.erb"
        case PM_MATCH_REQUIRED_NODE: {
            pm_match_required_node_t *cast = (pm_match_required_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            pm_node_destroy(parser, (pm_node_t *)cast->pattern);
            break;
        }
#line 58 "node.c.erb"
        case PM_MATCH_WRITE_NODE: {
            pm_match_write_node_t *cast = (pm_match_write_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->call);
            pm_node_list_free(parser, &cast->targets);
            break;
        }
#line 58 "node.c.erb"
        case PM_MISSING_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_MODULE_NODE: {
            pm_module_node_t *cast = (pm_module_node_t *) node;
            pm_constant_id_list_free(&cast->locals);
            pm_node_destroy(parser, (pm_node_t *)cast->constant_path);
            if (cast->body != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->body);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_MULTI_TARGET_NODE: {
            pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node;
            pm_node_list_free(parser, &cast->lefts);
            if (cast->rest != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->rest);
            }
            pm_node_list_free(parser, &cast->rights);
            break;
        }
#line 58 "node.c.erb"
        case PM_MULTI_WRITE_NODE: {
            pm_multi_write_node_t *cast = (pm_multi_write_node_t *) node;
            pm_node_list_free(parser, &cast->lefts);
            if (cast->rest != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->rest);
            }
            pm_node_list_free(parser, &cast->rights);
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_NEXT_NODE: {
            pm_next_node_t *cast = (pm_next_node_t *) node;
            if (cast->arguments != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->arguments);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_NIL_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_NO_KEYWORDS_PARAMETER_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_NUMBERED_PARAMETERS_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_NUMBERED_REFERENCE_READ_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: {
            pm_optional_keyword_parameter_node_t *cast = (pm_optional_keyword_parameter_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_OPTIONAL_PARAMETER_NODE: {
            pm_optional_parameter_node_t *cast = (pm_optional_parameter_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->value);
            break;
        }
#line 58 "node.c.erb"
        case PM_OR_NODE: {
            pm_or_node_t *cast = (pm_or_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->left);
            pm_node_destroy(parser, (pm_node_t *)cast->right);
            break;
        }
#line 58 "node.c.erb"
        case PM_PARAMETERS_NODE: {
            pm_parameters_node_t *cast = (pm_parameters_node_t *) node;
            pm_node_list_free(parser, &cast->requireds);
            pm_node_list_free(parser, &cast->optionals);
            if (cast->rest != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->rest);
            }
            pm_node_list_free(parser, &cast->posts);
            pm_node_list_free(parser, &cast->keywords);
            if (cast->keyword_rest != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->keyword_rest);
            }
            if (cast->block != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->block);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_PARENTHESES_NODE: {
            pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node;
            if (cast->body != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->body);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_PINNED_EXPRESSION_NODE: {
            pm_pinned_expression_node_t *cast = (pm_pinned_expression_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->expression);
            break;
        }
#line 58 "node.c.erb"
        case PM_PINNED_VARIABLE_NODE: {
            pm_pinned_variable_node_t *cast = (pm_pinned_variable_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->variable);
            break;
        }
#line 58 "node.c.erb"
        case PM_POST_EXECUTION_NODE: {
            pm_post_execution_node_t *cast = (pm_post_execution_node_t *) node;
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_PRE_EXECUTION_NODE: {
            pm_pre_execution_node_t *cast = (pm_pre_execution_node_t *) node;
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_PROGRAM_NODE: {
            pm_program_node_t *cast = (pm_program_node_t *) node;
            pm_constant_id_list_free(&cast->locals);
            pm_node_destroy(parser, (pm_node_t *)cast->statements);
            break;
        }
#line 58 "node.c.erb"
        case PM_RANGE_NODE: {
            pm_range_node_t *cast = (pm_range_node_t *) node;
            if (cast->left != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->left);
            }
            if (cast->right != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->right);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_RATIONAL_NODE: {
            pm_rational_node_t *cast = (pm_rational_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->numeric);
            break;
        }
#line 58 "node.c.erb"
        case PM_REDO_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_REGULAR_EXPRESSION_NODE: {
            pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node;
            pm_string_free(&cast->unescaped);
            break;
        }
#line 58 "node.c.erb"
        case PM_REQUIRED_KEYWORD_PARAMETER_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_REQUIRED_PARAMETER_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_RESCUE_MODIFIER_NODE: {
            pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->expression);
            pm_node_destroy(parser, (pm_node_t *)cast->rescue_expression);
            break;
        }
#line 58 "node.c.erb"
        case PM_RESCUE_NODE: {
            pm_rescue_node_t *cast = (pm_rescue_node_t *) node;
            pm_node_list_free(parser, &cast->exceptions);
            if (cast->reference != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->reference);
            }
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            if (cast->consequent != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->consequent);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_REST_PARAMETER_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_RETRY_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_RETURN_NODE: {
            pm_return_node_t *cast = (pm_return_node_t *) node;
            if (cast->arguments != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->arguments);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_SELF_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_SINGLETON_CLASS_NODE: {
            pm_singleton_class_node_t *cast = (pm_singleton_class_node_t *) node;
            pm_constant_id_list_free(&cast->locals);
            pm_node_destroy(parser, (pm_node_t *)cast->expression);
            if (cast->body != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->body);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_SOURCE_ENCODING_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_SOURCE_FILE_NODE: {
            pm_source_file_node_t *cast = (pm_source_file_node_t *) node;
            pm_string_free(&cast->filepath);
            break;
        }
#line 58 "node.c.erb"
        case PM_SOURCE_LINE_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_SPLAT_NODE: {
            pm_splat_node_t *cast = (pm_splat_node_t *) node;
            if (cast->expression != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->expression);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_STATEMENTS_NODE: {
            pm_statements_node_t *cast = (pm_statements_node_t *) node;
            pm_node_list_free(parser, &cast->body);
            break;
        }
#line 58 "node.c.erb"
        case PM_STRING_NODE: {
            pm_string_node_t *cast = (pm_string_node_t *) node;
            pm_string_free(&cast->unescaped);
            break;
        }
#line 58 "node.c.erb"
        case PM_SUPER_NODE: {
            pm_super_node_t *cast = (pm_super_node_t *) node;
            if (cast->arguments != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->arguments);
            }
            if (cast->block != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->block);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_SYMBOL_NODE: {
            pm_symbol_node_t *cast = (pm_symbol_node_t *) node;
            pm_string_free(&cast->unescaped);
            break;
        }
#line 58 "node.c.erb"
        case PM_TRUE_NODE: {
            break;
        }
#line 58 "node.c.erb"
        case PM_UNDEF_NODE: {
            pm_undef_node_t *cast = (pm_undef_node_t *) node;
            pm_node_list_free(parser, &cast->names);
            break;
        }
#line 58 "node.c.erb"
        case PM_UNLESS_NODE: {
            pm_unless_node_t *cast = (pm_unless_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->predicate);
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            if (cast->consequent != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->consequent);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_UNTIL_NODE: {
            pm_until_node_t *cast = (pm_until_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->predicate);
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_WHEN_NODE: {
            pm_when_node_t *cast = (pm_when_node_t *) node;
            pm_node_list_free(parser, &cast->conditions);
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_WHILE_NODE: {
            pm_while_node_t *cast = (pm_while_node_t *) node;
            pm_node_destroy(parser, (pm_node_t *)cast->predicate);
            if (cast->statements != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->statements);
            }
            break;
        }
#line 58 "node.c.erb"
        case PM_X_STRING_NODE: {
            pm_x_string_node_t *cast = (pm_x_string_node_t *) node;
            pm_string_free(&cast->unescaped);
            break;
        }
#line 58 "node.c.erb"
        case PM_YIELD_NODE: {
            pm_yield_node_t *cast = (pm_yield_node_t *) node;
            if (cast->arguments != NULL) {
                pm_node_destroy(parser, (pm_node_t *)cast->arguments);
            }
            break;
        }
#line 85 "node.c.erb"
        default:
            assert(false && "unreachable");
            break;
    }
    free(node);
}

static void
pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize) {
    memsize->node_count++;

    switch (PM_NODE_TYPE(node)) {
        // We do not calculate memsize of a ScopeNode
        // as it should never be generated
        case PM_SCOPE_NODE:
            return;
#line 103 "node.c.erb"
        case PM_ALIAS_GLOBAL_VARIABLE_NODE: {
            pm_alias_global_variable_node_t *cast = (pm_alias_global_variable_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->new_name, memsize);
            pm_node_memsize_node((pm_node_t *)cast->old_name, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_ALIAS_METHOD_NODE: {
            pm_alias_method_node_t *cast = (pm_alias_method_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->new_name, memsize);
            pm_node_memsize_node((pm_node_t *)cast->old_name, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_ALTERNATION_PATTERN_NODE: {
            pm_alternation_pattern_node_t *cast = (pm_alternation_pattern_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->left, memsize);
            pm_node_memsize_node((pm_node_t *)cast->right, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_AND_NODE: {
            pm_and_node_t *cast = (pm_and_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->left, memsize);
            pm_node_memsize_node((pm_node_t *)cast->right, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_ARGUMENTS_NODE: {
            pm_arguments_node_t *cast = (pm_arguments_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->arguments, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_ARRAY_NODE: {
            pm_array_node_t *cast = (pm_array_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->elements, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_ARRAY_PATTERN_NODE: {
            pm_array_pattern_node_t *cast = (pm_array_pattern_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 2;
            if (cast->constant != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->constant, memsize);
            }
            memsize->memsize += pm_node_list_memsize(&cast->requireds, memsize);
            if (cast->rest != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->rest, memsize);
            }
            memsize->memsize += pm_node_list_memsize(&cast->posts, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_ASSOC_NODE: {
            pm_assoc_node_t *cast = (pm_assoc_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->key, memsize);
            if (cast->value != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_ASSOC_SPLAT_NODE: {
            pm_assoc_splat_node_t *cast = (pm_assoc_splat_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->value != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_BACK_REFERENCE_READ_NODE: {
            pm_back_reference_read_node_t *cast = (pm_back_reference_read_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_BEGIN_NODE: {
            pm_begin_node_t *cast = (pm_begin_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            if (cast->rescue_clause != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->rescue_clause, memsize);
            }
            if (cast->else_clause != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->else_clause, memsize);
            }
            if (cast->ensure_clause != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->ensure_clause, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_BLOCK_ARGUMENT_NODE: {
            pm_block_argument_node_t *cast = (pm_block_argument_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->expression != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->expression, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_BLOCK_LOCAL_VARIABLE_NODE: {
            pm_block_local_variable_node_t *cast = (pm_block_local_variable_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_BLOCK_NODE: {
            pm_block_node_t *cast = (pm_block_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Constant id lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_constant_id_list_t) * 1;
            memsize->memsize += pm_constant_id_list_memsize(&cast->locals);
            if (cast->parameters != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->parameters, memsize);
            }
            if (cast->body != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->body, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_BLOCK_PARAMETER_NODE: {
            pm_block_parameter_node_t *cast = (pm_block_parameter_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_BLOCK_PARAMETERS_NODE: {
            pm_block_parameters_node_t *cast = (pm_block_parameters_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            if (cast->parameters != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->parameters, memsize);
            }
            memsize->memsize += pm_node_list_memsize(&cast->locals, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_BREAK_NODE: {
            pm_break_node_t *cast = (pm_break_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->arguments != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_CALL_AND_WRITE_NODE: {
            pm_call_and_write_node_t *cast = (pm_call_and_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->receiver != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
            }
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CALL_NODE: {
            pm_call_node_t *cast = (pm_call_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->receiver != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
            }
            if (cast->arguments != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
            }
            if (cast->block != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->block, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_CALL_OPERATOR_WRITE_NODE: {
            pm_call_operator_write_node_t *cast = (pm_call_operator_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->receiver != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
            }
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CALL_OR_WRITE_NODE: {
            pm_call_or_write_node_t *cast = (pm_call_or_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->receiver != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
            }
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CALL_TARGET_NODE: {
            pm_call_target_node_t *cast = (pm_call_target_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CAPTURE_PATTERN_NODE: {
            pm_capture_pattern_node_t *cast = (pm_capture_pattern_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            pm_node_memsize_node((pm_node_t *)cast->target, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CASE_MATCH_NODE: {
            pm_case_match_node_t *cast = (pm_case_match_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            if (cast->predicate != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->predicate, memsize);
            }
            memsize->memsize += pm_node_list_memsize(&cast->conditions, memsize);
            if (cast->consequent != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->consequent, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_CASE_NODE: {
            pm_case_node_t *cast = (pm_case_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            if (cast->predicate != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->predicate, memsize);
            }
            memsize->memsize += pm_node_list_memsize(&cast->conditions, memsize);
            if (cast->consequent != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->consequent, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_CLASS_NODE: {
            pm_class_node_t *cast = (pm_class_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Constant id lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_constant_id_list_t) * 1;
            memsize->memsize += pm_constant_id_list_memsize(&cast->locals);
            pm_node_memsize_node((pm_node_t *)cast->constant_path, memsize);
            if (cast->superclass != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->superclass, memsize);
            }
            if (cast->body != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->body, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_CLASS_VARIABLE_AND_WRITE_NODE: {
            pm_class_variable_and_write_node_t *cast = (pm_class_variable_and_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_class_variable_operator_write_node_t *cast = (pm_class_variable_operator_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CLASS_VARIABLE_OR_WRITE_NODE: {
            pm_class_variable_or_write_node_t *cast = (pm_class_variable_or_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CLASS_VARIABLE_READ_NODE: {
            pm_class_variable_read_node_t *cast = (pm_class_variable_read_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_CLASS_VARIABLE_TARGET_NODE: {
            pm_class_variable_target_node_t *cast = (pm_class_variable_target_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_CLASS_VARIABLE_WRITE_NODE: {
            pm_class_variable_write_node_t *cast = (pm_class_variable_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_AND_WRITE_NODE: {
            pm_constant_and_write_node_t *cast = (pm_constant_and_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_OPERATOR_WRITE_NODE: {
            pm_constant_operator_write_node_t *cast = (pm_constant_operator_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_OR_WRITE_NODE: {
            pm_constant_or_write_node_t *cast = (pm_constant_or_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_PATH_AND_WRITE_NODE: {
            pm_constant_path_and_write_node_t *cast = (pm_constant_path_and_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->target, memsize);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_PATH_NODE: {
            pm_constant_path_node_t *cast = (pm_constant_path_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->parent != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->parent, memsize);
            }
            pm_node_memsize_node((pm_node_t *)cast->child, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: {
            pm_constant_path_operator_write_node_t *cast = (pm_constant_path_operator_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->target, memsize);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_PATH_OR_WRITE_NODE: {
            pm_constant_path_or_write_node_t *cast = (pm_constant_path_or_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->target, memsize);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_PATH_TARGET_NODE: {
            pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->parent != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->parent, memsize);
            }
            pm_node_memsize_node((pm_node_t *)cast->child, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_PATH_WRITE_NODE: {
            pm_constant_path_write_node_t *cast = (pm_constant_path_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->target, memsize);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_READ_NODE: {
            pm_constant_read_node_t *cast = (pm_constant_read_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_TARGET_NODE: {
            pm_constant_target_node_t *cast = (pm_constant_target_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_CONSTANT_WRITE_NODE: {
            pm_constant_write_node_t *cast = (pm_constant_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_DEF_NODE: {
            pm_def_node_t *cast = (pm_def_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Constant id lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_constant_id_list_t) * 1;
            if (cast->receiver != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
            }
            if (cast->parameters != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->parameters, memsize);
            }
            if (cast->body != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->body, memsize);
            }
            memsize->memsize += pm_constant_id_list_memsize(&cast->locals);
            break;
        }
#line 103 "node.c.erb"
        case PM_DEFINED_NODE: {
            pm_defined_node_t *cast = (pm_defined_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_ELSE_NODE: {
            pm_else_node_t *cast = (pm_else_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_EMBEDDED_STATEMENTS_NODE: {
            pm_embedded_statements_node_t *cast = (pm_embedded_statements_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_EMBEDDED_VARIABLE_NODE: {
            pm_embedded_variable_node_t *cast = (pm_embedded_variable_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->variable, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_ENSURE_NODE: {
            pm_ensure_node_t *cast = (pm_ensure_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_FALSE_NODE: {
            pm_false_node_t *cast = (pm_false_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_FIND_PATTERN_NODE: {
            pm_find_pattern_node_t *cast = (pm_find_pattern_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            if (cast->constant != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->constant, memsize);
            }
            pm_node_memsize_node((pm_node_t *)cast->left, memsize);
            memsize->memsize += pm_node_list_memsize(&cast->requireds, memsize);
            pm_node_memsize_node((pm_node_t *)cast->right, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_FLIP_FLOP_NODE: {
            pm_flip_flop_node_t *cast = (pm_flip_flop_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->left != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->left, memsize);
            }
            if (cast->right != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->right, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_FLOAT_NODE: {
            pm_float_node_t *cast = (pm_float_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_FOR_NODE: {
            pm_for_node_t *cast = (pm_for_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->index, memsize);
            pm_node_memsize_node((pm_node_t *)cast->collection, memsize);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_FORWARDING_ARGUMENTS_NODE: {
            pm_forwarding_arguments_node_t *cast = (pm_forwarding_arguments_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_FORWARDING_PARAMETER_NODE: {
            pm_forwarding_parameter_node_t *cast = (pm_forwarding_parameter_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_FORWARDING_SUPER_NODE: {
            pm_forwarding_super_node_t *cast = (pm_forwarding_super_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->block != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->block, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: {
            pm_global_variable_and_write_node_t *cast = (pm_global_variable_and_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_global_variable_operator_write_node_t *cast = (pm_global_variable_operator_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: {
            pm_global_variable_or_write_node_t *cast = (pm_global_variable_or_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_GLOBAL_VARIABLE_READ_NODE: {
            pm_global_variable_read_node_t *cast = (pm_global_variable_read_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_GLOBAL_VARIABLE_TARGET_NODE: {
            pm_global_variable_target_node_t *cast = (pm_global_variable_target_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_GLOBAL_VARIABLE_WRITE_NODE: {
            pm_global_variable_write_node_t *cast = (pm_global_variable_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_HASH_NODE: {
            pm_hash_node_t *cast = (pm_hash_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->elements, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_HASH_PATTERN_NODE: {
            pm_hash_pattern_node_t *cast = (pm_hash_pattern_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            if (cast->constant != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->constant, memsize);
            }
            memsize->memsize += pm_node_list_memsize(&cast->elements, memsize);
            if (cast->rest != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->rest, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_IF_NODE: {
            pm_if_node_t *cast = (pm_if_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->predicate, memsize);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            if (cast->consequent != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->consequent, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_IMAGINARY_NODE: {
            pm_imaginary_node_t *cast = (pm_imaginary_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->numeric, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_IMPLICIT_NODE: {
            pm_implicit_node_t *cast = (pm_implicit_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_IMPLICIT_REST_NODE: {
            pm_implicit_rest_node_t *cast = (pm_implicit_rest_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_IN_NODE: {
            pm_in_node_t *cast = (pm_in_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->pattern, memsize);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_INDEX_AND_WRITE_NODE: {
            pm_index_and_write_node_t *cast = (pm_index_and_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->receiver != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
            }
            if (cast->arguments != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
            }
            if (cast->block != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->block, memsize);
            }
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INDEX_OPERATOR_WRITE_NODE: {
            pm_index_operator_write_node_t *cast = (pm_index_operator_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->receiver != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
            }
            if (cast->arguments != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
            }
            if (cast->block != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->block, memsize);
            }
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INDEX_OR_WRITE_NODE: {
            pm_index_or_write_node_t *cast = (pm_index_or_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->receiver != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
            }
            if (cast->arguments != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
            }
            if (cast->block != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->block, memsize);
            }
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INDEX_TARGET_NODE: {
            pm_index_target_node_t *cast = (pm_index_target_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
            if (cast->arguments != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
            }
            if (cast->block != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->block, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
            pm_instance_variable_and_write_node_t *cast = (pm_instance_variable_and_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_instance_variable_operator_write_node_t *cast = (pm_instance_variable_operator_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: {
            pm_instance_variable_or_write_node_t *cast = (pm_instance_variable_or_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INSTANCE_VARIABLE_READ_NODE: {
            pm_instance_variable_read_node_t *cast = (pm_instance_variable_read_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_INSTANCE_VARIABLE_TARGET_NODE: {
            pm_instance_variable_target_node_t *cast = (pm_instance_variable_target_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_INSTANCE_VARIABLE_WRITE_NODE: {
            pm_instance_variable_write_node_t *cast = (pm_instance_variable_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INTEGER_NODE: {
            pm_integer_node_t *cast = (pm_integer_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: {
            pm_interpolated_match_last_line_node_t *cast = (pm_interpolated_match_last_line_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->parts, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
            pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->parts, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INTERPOLATED_STRING_NODE: {
            pm_interpolated_string_node_t *cast = (pm_interpolated_string_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->parts, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INTERPOLATED_SYMBOL_NODE: {
            pm_interpolated_symbol_node_t *cast = (pm_interpolated_symbol_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->parts, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_INTERPOLATED_X_STRING_NODE: {
            pm_interpolated_x_string_node_t *cast = (pm_interpolated_x_string_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->parts, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_KEYWORD_HASH_NODE: {
            pm_keyword_hash_node_t *cast = (pm_keyword_hash_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->elements, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_KEYWORD_REST_PARAMETER_NODE: {
            pm_keyword_rest_parameter_node_t *cast = (pm_keyword_rest_parameter_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_LAMBDA_NODE: {
            pm_lambda_node_t *cast = (pm_lambda_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Constant id lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_constant_id_list_t) * 1;
            memsize->memsize += pm_constant_id_list_memsize(&cast->locals);
            if (cast->parameters != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->parameters, memsize);
            }
            if (cast->body != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->body, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_LOCAL_VARIABLE_AND_WRITE_NODE: {
            pm_local_variable_and_write_node_t *cast = (pm_local_variable_and_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: {
            pm_local_variable_operator_write_node_t *cast = (pm_local_variable_operator_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_LOCAL_VARIABLE_OR_WRITE_NODE: {
            pm_local_variable_or_write_node_t *cast = (pm_local_variable_or_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_LOCAL_VARIABLE_READ_NODE: {
            pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_LOCAL_VARIABLE_TARGET_NODE: {
            pm_local_variable_target_node_t *cast = (pm_local_variable_target_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_LOCAL_VARIABLE_WRITE_NODE: {
            pm_local_variable_write_node_t *cast = (pm_local_variable_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_MATCH_LAST_LINE_NODE: {
            pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) node;
            memsize->memsize += sizeof(*cast);
            memsize->memsize += pm_string_memsize(&cast->unescaped);
            break;
        }
#line 103 "node.c.erb"
        case PM_MATCH_PREDICATE_NODE: {
            pm_match_predicate_node_t *cast = (pm_match_predicate_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            pm_node_memsize_node((pm_node_t *)cast->pattern, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_MATCH_REQUIRED_NODE: {
            pm_match_required_node_t *cast = (pm_match_required_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            pm_node_memsize_node((pm_node_t *)cast->pattern, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_MATCH_WRITE_NODE: {
            pm_match_write_node_t *cast = (pm_match_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            pm_node_memsize_node((pm_node_t *)cast->call, memsize);
            memsize->memsize += pm_node_list_memsize(&cast->targets, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_MISSING_NODE: {
            pm_missing_node_t *cast = (pm_missing_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_MODULE_NODE: {
            pm_module_node_t *cast = (pm_module_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Constant id lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_constant_id_list_t) * 1;
            memsize->memsize += pm_constant_id_list_memsize(&cast->locals);
            pm_node_memsize_node((pm_node_t *)cast->constant_path, memsize);
            if (cast->body != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->body, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_MULTI_TARGET_NODE: {
            pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 2;
            memsize->memsize += pm_node_list_memsize(&cast->lefts, memsize);
            if (cast->rest != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->rest, memsize);
            }
            memsize->memsize += pm_node_list_memsize(&cast->rights, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_MULTI_WRITE_NODE: {
            pm_multi_write_node_t *cast = (pm_multi_write_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 2;
            memsize->memsize += pm_node_list_memsize(&cast->lefts, memsize);
            if (cast->rest != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->rest, memsize);
            }
            memsize->memsize += pm_node_list_memsize(&cast->rights, memsize);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_NEXT_NODE: {
            pm_next_node_t *cast = (pm_next_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->arguments != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_NIL_NODE: {
            pm_nil_node_t *cast = (pm_nil_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_NO_KEYWORDS_PARAMETER_NODE: {
            pm_no_keywords_parameter_node_t *cast = (pm_no_keywords_parameter_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_NUMBERED_PARAMETERS_NODE: {
            pm_numbered_parameters_node_t *cast = (pm_numbered_parameters_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_NUMBERED_REFERENCE_READ_NODE: {
            pm_numbered_reference_read_node_t *cast = (pm_numbered_reference_read_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: {
            pm_optional_keyword_parameter_node_t *cast = (pm_optional_keyword_parameter_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_OPTIONAL_PARAMETER_NODE: {
            pm_optional_parameter_node_t *cast = (pm_optional_parameter_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->value, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_OR_NODE: {
            pm_or_node_t *cast = (pm_or_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->left, memsize);
            pm_node_memsize_node((pm_node_t *)cast->right, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_PARAMETERS_NODE: {
            pm_parameters_node_t *cast = (pm_parameters_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 4;
            memsize->memsize += pm_node_list_memsize(&cast->requireds, memsize);
            memsize->memsize += pm_node_list_memsize(&cast->optionals, memsize);
            if (cast->rest != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->rest, memsize);
            }
            memsize->memsize += pm_node_list_memsize(&cast->posts, memsize);
            memsize->memsize += pm_node_list_memsize(&cast->keywords, memsize);
            if (cast->keyword_rest != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->keyword_rest, memsize);
            }
            if (cast->block != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->block, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_PARENTHESES_NODE: {
            pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->body != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->body, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_PINNED_EXPRESSION_NODE: {
            pm_pinned_expression_node_t *cast = (pm_pinned_expression_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->expression, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_PINNED_VARIABLE_NODE: {
            pm_pinned_variable_node_t *cast = (pm_pinned_variable_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->variable, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_POST_EXECUTION_NODE: {
            pm_post_execution_node_t *cast = (pm_post_execution_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_PRE_EXECUTION_NODE: {
            pm_pre_execution_node_t *cast = (pm_pre_execution_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_PROGRAM_NODE: {
            pm_program_node_t *cast = (pm_program_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Constant id lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_constant_id_list_t) * 1;
            memsize->memsize += pm_constant_id_list_memsize(&cast->locals);
            pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_RANGE_NODE: {
            pm_range_node_t *cast = (pm_range_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->left != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->left, memsize);
            }
            if (cast->right != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->right, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_RATIONAL_NODE: {
            pm_rational_node_t *cast = (pm_rational_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->numeric, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_REDO_NODE: {
            pm_redo_node_t *cast = (pm_redo_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_REGULAR_EXPRESSION_NODE: {
            pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node;
            memsize->memsize += sizeof(*cast);
            memsize->memsize += pm_string_memsize(&cast->unescaped);
            break;
        }
#line 103 "node.c.erb"
        case PM_REQUIRED_KEYWORD_PARAMETER_NODE: {
            pm_required_keyword_parameter_node_t *cast = (pm_required_keyword_parameter_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_REQUIRED_PARAMETER_NODE: {
            pm_required_parameter_node_t *cast = (pm_required_parameter_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_RESCUE_MODIFIER_NODE: {
            pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->expression, memsize);
            pm_node_memsize_node((pm_node_t *)cast->rescue_expression, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_RESCUE_NODE: {
            pm_rescue_node_t *cast = (pm_rescue_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->exceptions, memsize);
            if (cast->reference != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->reference, memsize);
            }
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            if (cast->consequent != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->consequent, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_REST_PARAMETER_NODE: {
            pm_rest_parameter_node_t *cast = (pm_rest_parameter_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_RETRY_NODE: {
            pm_retry_node_t *cast = (pm_retry_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_RETURN_NODE: {
            pm_return_node_t *cast = (pm_return_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->arguments != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_SELF_NODE: {
            pm_self_node_t *cast = (pm_self_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_SINGLETON_CLASS_NODE: {
            pm_singleton_class_node_t *cast = (pm_singleton_class_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Constant id lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_constant_id_list_t) * 1;
            memsize->memsize += pm_constant_id_list_memsize(&cast->locals);
            pm_node_memsize_node((pm_node_t *)cast->expression, memsize);
            if (cast->body != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->body, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_SOURCE_ENCODING_NODE: {
            pm_source_encoding_node_t *cast = (pm_source_encoding_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_SOURCE_FILE_NODE: {
            pm_source_file_node_t *cast = (pm_source_file_node_t *) node;
            memsize->memsize += sizeof(*cast);
            memsize->memsize += pm_string_memsize(&cast->filepath);
            break;
        }
#line 103 "node.c.erb"
        case PM_SOURCE_LINE_NODE: {
            pm_source_line_node_t *cast = (pm_source_line_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_SPLAT_NODE: {
            pm_splat_node_t *cast = (pm_splat_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->expression != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->expression, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_STATEMENTS_NODE: {
            pm_statements_node_t *cast = (pm_statements_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->body, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_STRING_NODE: {
            pm_string_node_t *cast = (pm_string_node_t *) node;
            memsize->memsize += sizeof(*cast);
            memsize->memsize += pm_string_memsize(&cast->unescaped);
            break;
        }
#line 103 "node.c.erb"
        case PM_SUPER_NODE: {
            pm_super_node_t *cast = (pm_super_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->arguments != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
            }
            if (cast->block != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->block, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_SYMBOL_NODE: {
            pm_symbol_node_t *cast = (pm_symbol_node_t *) node;
            memsize->memsize += sizeof(*cast);
            memsize->memsize += pm_string_memsize(&cast->unescaped);
            break;
        }
#line 103 "node.c.erb"
        case PM_TRUE_NODE: {
            pm_true_node_t *cast = (pm_true_node_t *) node;
            memsize->memsize += sizeof(*cast);
            break;
        }
#line 103 "node.c.erb"
        case PM_UNDEF_NODE: {
            pm_undef_node_t *cast = (pm_undef_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->names, memsize);
            break;
        }
#line 103 "node.c.erb"
        case PM_UNLESS_NODE: {
            pm_unless_node_t *cast = (pm_unless_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->predicate, memsize);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            if (cast->consequent != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->consequent, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_UNTIL_NODE: {
            pm_until_node_t *cast = (pm_until_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->predicate, memsize);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_WHEN_NODE: {
            pm_when_node_t *cast = (pm_when_node_t *) node;
            memsize->memsize += sizeof(*cast);
            // Node lists will add in their own sizes below.
            memsize->memsize -= sizeof(pm_node_list_t) * 1;
            memsize->memsize += pm_node_list_memsize(&cast->conditions, memsize);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_WHILE_NODE: {
            pm_while_node_t *cast = (pm_while_node_t *) node;
            memsize->memsize += sizeof(*cast);
            pm_node_memsize_node((pm_node_t *)cast->predicate, memsize);
            if (cast->statements != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->statements, memsize);
            }
            break;
        }
#line 103 "node.c.erb"
        case PM_X_STRING_NODE: {
            pm_x_string_node_t *cast = (pm_x_string_node_t *) node;
            memsize->memsize += sizeof(*cast);
            memsize->memsize += pm_string_memsize(&cast->unescaped);
            break;
        }
#line 103 "node.c.erb"
        case PM_YIELD_NODE: {
            pm_yield_node_t *cast = (pm_yield_node_t *) node;
            memsize->memsize += sizeof(*cast);
            if (cast->arguments != NULL) {
                pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
            }
            break;
        }
#line 137 "node.c.erb"
    }
}

/**
 * Calculates the memory footprint of a given node.
 */
PRISM_EXPORTED_FUNCTION void
pm_node_memsize(pm_node_t *node, pm_memsize_t *memsize) {
    *memsize = (pm_memsize_t) { .memsize = 0, .node_count = 0 };
    pm_node_memsize_node(node, memsize);
}

/**
 * Returns a string representation of the given node type.
 */
PRISM_EXPORTED_FUNCTION const char *
pm_node_type_to_str(pm_node_type_t node_type)
{
    switch (node_type) {
        case PM_ALIAS_GLOBAL_VARIABLE_NODE:
            return "PM_ALIAS_GLOBAL_VARIABLE_NODE";
        case PM_ALIAS_METHOD_NODE:
            return "PM_ALIAS_METHOD_NODE";
        case PM_ALTERNATION_PATTERN_NODE:
            return "PM_ALTERNATION_PATTERN_NODE";
        case PM_AND_NODE:
            return "PM_AND_NODE";
        case PM_ARGUMENTS_NODE:
            return "PM_ARGUMENTS_NODE";
        case PM_ARRAY_NODE:
            return "PM_ARRAY_NODE";
        case PM_ARRAY_PATTERN_NODE:
            return "PM_ARRAY_PATTERN_NODE";
        case PM_ASSOC_NODE:
            return "PM_ASSOC_NODE";
        case PM_ASSOC_SPLAT_NODE:
            return "PM_ASSOC_SPLAT_NODE";
        case PM_BACK_REFERENCE_READ_NODE:
            return "PM_BACK_REFERENCE_READ_NODE";
        case PM_BEGIN_NODE:
            return "PM_BEGIN_NODE";
        case PM_BLOCK_ARGUMENT_NODE:
            return "PM_BLOCK_ARGUMENT_NODE";
        case PM_BLOCK_LOCAL_VARIABLE_NODE:
            return "PM_BLOCK_LOCAL_VARIABLE_NODE";
        case PM_BLOCK_NODE:
            return "PM_BLOCK_NODE";
        case PM_BLOCK_PARAMETER_NODE:
            return "PM_BLOCK_PARAMETER_NODE";
        case PM_BLOCK_PARAMETERS_NODE:
            return "PM_BLOCK_PARAMETERS_NODE";
        case PM_BREAK_NODE:
            return "PM_BREAK_NODE";
        case PM_CALL_AND_WRITE_NODE:
            return "PM_CALL_AND_WRITE_NODE";
        case PM_CALL_NODE:
            return "PM_CALL_NODE";
        case PM_CALL_OPERATOR_WRITE_NODE:
            return "PM_CALL_OPERATOR_WRITE_NODE";
        case PM_CALL_OR_WRITE_NODE:
            return "PM_CALL_OR_WRITE_NODE";
        case PM_CALL_TARGET_NODE:
            return "PM_CALL_TARGET_NODE";
        case PM_CAPTURE_PATTERN_NODE:
            return "PM_CAPTURE_PATTERN_NODE";
        case PM_CASE_MATCH_NODE:
            return "PM_CASE_MATCH_NODE";
        case PM_CASE_NODE:
            return "PM_CASE_NODE";
        case PM_CLASS_NODE:
            return "PM_CLASS_NODE";
        case PM_CLASS_VARIABLE_AND_WRITE_NODE:
            return "PM_CLASS_VARIABLE_AND_WRITE_NODE";
        case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE:
            return "PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE";
        case PM_CLASS_VARIABLE_OR_WRITE_NODE:
            return "PM_CLASS_VARIABLE_OR_WRITE_NODE";
        case PM_CLASS_VARIABLE_READ_NODE:
            return "PM_CLASS_VARIABLE_READ_NODE";
        case PM_CLASS_VARIABLE_TARGET_NODE:
            return "PM_CLASS_VARIABLE_TARGET_NODE";
        case PM_CLASS_VARIABLE_WRITE_NODE:
            return "PM_CLASS_VARIABLE_WRITE_NODE";
        case PM_CONSTANT_AND_WRITE_NODE:
            return "PM_CONSTANT_AND_WRITE_NODE";
        case PM_CONSTANT_OPERATOR_WRITE_NODE:
            return "PM_CONSTANT_OPERATOR_WRITE_NODE";
        case PM_CONSTANT_OR_WRITE_NODE:
            return "PM_CONSTANT_OR_WRITE_NODE";
        case PM_CONSTANT_PATH_AND_WRITE_NODE:
            return "PM_CONSTANT_PATH_AND_WRITE_NODE";
        case PM_CONSTANT_PATH_NODE:
            return "PM_CONSTANT_PATH_NODE";
        case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE:
            return "PM_CONSTANT_PATH_OPERATOR_WRITE_NODE";
        case PM_CONSTANT_PATH_OR_WRITE_NODE:
            return "PM_CONSTANT_PATH_OR_WRITE_NODE";
        case PM_CONSTANT_PATH_TARGET_NODE:
            return "PM_CONSTANT_PATH_TARGET_NODE";
        case PM_CONSTANT_PATH_WRITE_NODE:
            return "PM_CONSTANT_PATH_WRITE_NODE";
        case PM_CONSTANT_READ_NODE:
            return "PM_CONSTANT_READ_NODE";
        case PM_CONSTANT_TARGET_NODE:
            return "PM_CONSTANT_TARGET_NODE";
        case PM_CONSTANT_WRITE_NODE:
            return "PM_CONSTANT_WRITE_NODE";
        case PM_DEF_NODE:
            return "PM_DEF_NODE";
        case PM_DEFINED_NODE:
            return "PM_DEFINED_NODE";
        case PM_ELSE_NODE:
            return "PM_ELSE_NODE";
        case PM_EMBEDDED_STATEMENTS_NODE:
            return "PM_EMBEDDED_STATEMENTS_NODE";
        case PM_EMBEDDED_VARIABLE_NODE:
            return "PM_EMBEDDED_VARIABLE_NODE";
        case PM_ENSURE_NODE:
            return "PM_ENSURE_NODE";
        case PM_FALSE_NODE:
            return "PM_FALSE_NODE";
        case PM_FIND_PATTERN_NODE:
            return "PM_FIND_PATTERN_NODE";
        case PM_FLIP_FLOP_NODE:
            return "PM_FLIP_FLOP_NODE";
        case PM_FLOAT_NODE:
            return "PM_FLOAT_NODE";
        case PM_FOR_NODE:
            return "PM_FOR_NODE";
        case PM_FORWARDING_ARGUMENTS_NODE:
            return "PM_FORWARDING_ARGUMENTS_NODE";
        case PM_FORWARDING_PARAMETER_NODE:
            return "PM_FORWARDING_PARAMETER_NODE";
        case PM_FORWARDING_SUPER_NODE:
            return "PM_FORWARDING_SUPER_NODE";
        case PM_GLOBAL_VARIABLE_AND_WRITE_NODE:
            return "PM_GLOBAL_VARIABLE_AND_WRITE_NODE";
        case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE:
            return "PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE";
        case PM_GLOBAL_VARIABLE_OR_WRITE_NODE:
            return "PM_GLOBAL_VARIABLE_OR_WRITE_NODE";
        case PM_GLOBAL_VARIABLE_READ_NODE:
            return "PM_GLOBAL_VARIABLE_READ_NODE";
        case PM_GLOBAL_VARIABLE_TARGET_NODE:
            return "PM_GLOBAL_VARIABLE_TARGET_NODE";
        case PM_GLOBAL_VARIABLE_WRITE_NODE:
            return "PM_GLOBAL_VARIABLE_WRITE_NODE";
        case PM_HASH_NODE:
            return "PM_HASH_NODE";
        case PM_HASH_PATTERN_NODE:
            return "PM_HASH_PATTERN_NODE";
        case PM_IF_NODE:
            return "PM_IF_NODE";
        case PM_IMAGINARY_NODE:
            return "PM_IMAGINARY_NODE";
        case PM_IMPLICIT_NODE:
            return "PM_IMPLICIT_NODE";
        case PM_IMPLICIT_REST_NODE:
            return "PM_IMPLICIT_REST_NODE";
        case PM_IN_NODE:
            return "PM_IN_NODE";
        case PM_INDEX_AND_WRITE_NODE:
            return "PM_INDEX_AND_WRITE_NODE";
        case PM_INDEX_OPERATOR_WRITE_NODE:
            return "PM_INDEX_OPERATOR_WRITE_NODE";
        case PM_INDEX_OR_WRITE_NODE:
            return "PM_INDEX_OR_WRITE_NODE";
        case PM_INDEX_TARGET_NODE:
            return "PM_INDEX_TARGET_NODE";
        case PM_INSTANCE_VARIABLE_AND_WRITE_NODE:
            return "PM_INSTANCE_VARIABLE_AND_WRITE_NODE";
        case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE:
            return "PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE";
        case PM_INSTANCE_VARIABLE_OR_WRITE_NODE:
            return "PM_INSTANCE_VARIABLE_OR_WRITE_NODE";
        case PM_INSTANCE_VARIABLE_READ_NODE:
            return "PM_INSTANCE_VARIABLE_READ_NODE";
        case PM_INSTANCE_VARIABLE_TARGET_NODE:
            return "PM_INSTANCE_VARIABLE_TARGET_NODE";
        case PM_INSTANCE_VARIABLE_WRITE_NODE:
            return "PM_INSTANCE_VARIABLE_WRITE_NODE";
        case PM_INTEGER_NODE:
            return "PM_INTEGER_NODE";
        case PM_INTERPOLATED_MATCH_LAST_LINE_NODE:
            return "PM_INTERPOLATED_MATCH_LAST_LINE_NODE";
        case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE:
            return "PM_INTERPOLATED_REGULAR_EXPRESSION_NODE";
        case PM_INTERPOLATED_STRING_NODE:
            return "PM_INTERPOLATED_STRING_NODE";
        case PM_INTERPOLATED_SYMBOL_NODE:
            return "PM_INTERPOLATED_SYMBOL_NODE";
        case PM_INTERPOLATED_X_STRING_NODE:
            return "PM_INTERPOLATED_X_STRING_NODE";
        case PM_KEYWORD_HASH_NODE:
            return "PM_KEYWORD_HASH_NODE";
        case PM_KEYWORD_REST_PARAMETER_NODE:
            return "PM_KEYWORD_REST_PARAMETER_NODE";
        case PM_LAMBDA_NODE:
            return "PM_LAMBDA_NODE";
        case PM_LOCAL_VARIABLE_AND_WRITE_NODE:
            return "PM_LOCAL_VARIABLE_AND_WRITE_NODE";
        case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE:
            return "PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE";
        case PM_LOCAL_VARIABLE_OR_WRITE_NODE:
            return "PM_LOCAL_VARIABLE_OR_WRITE_NODE";
        case PM_LOCAL_VARIABLE_READ_NODE:
            return "PM_LOCAL_VARIABLE_READ_NODE";
        case PM_LOCAL_VARIABLE_TARGET_NODE:
            return "PM_LOCAL_VARIABLE_TARGET_NODE";
        case PM_LOCAL_VARIABLE_WRITE_NODE:
            return "PM_LOCAL_VARIABLE_WRITE_NODE";
        case PM_MATCH_LAST_LINE_NODE:
            return "PM_MATCH_LAST_LINE_NODE";
        case PM_MATCH_PREDICATE_NODE:
            return "PM_MATCH_PREDICATE_NODE";
        case PM_MATCH_REQUIRED_NODE:
            return "PM_MATCH_REQUIRED_NODE";
        case PM_MATCH_WRITE_NODE:
            return "PM_MATCH_WRITE_NODE";
        case PM_MISSING_NODE:
            return "PM_MISSING_NODE";
        case PM_MODULE_NODE:
            return "PM_MODULE_NODE";
        case PM_MULTI_TARGET_NODE:
            return "PM_MULTI_TARGET_NODE";
        case PM_MULTI_WRITE_NODE:
            return "PM_MULTI_WRITE_NODE";
        case PM_NEXT_NODE:
            return "PM_NEXT_NODE";
        case PM_NIL_NODE:
            return "PM_NIL_NODE";
        case PM_NO_KEYWORDS_PARAMETER_NODE:
            return "PM_NO_KEYWORDS_PARAMETER_NODE";
        case PM_NUMBERED_PARAMETERS_NODE:
            return "PM_NUMBERED_PARAMETERS_NODE";
        case PM_NUMBERED_REFERENCE_READ_NODE:
            return "PM_NUMBERED_REFERENCE_READ_NODE";
        case PM_OPTIONAL_KEYWORD_PARAMETER_NODE:
            return "PM_OPTIONAL_KEYWORD_PARAMETER_NODE";
        case PM_OPTIONAL_PARAMETER_NODE:
            return "PM_OPTIONAL_PARAMETER_NODE";
        case PM_OR_NODE:
            return "PM_OR_NODE";
        case PM_PARAMETERS_NODE:
            return "PM_PARAMETERS_NODE";
        case PM_PARENTHESES_NODE:
            return "PM_PARENTHESES_NODE";
        case PM_PINNED_EXPRESSION_NODE:
            return "PM_PINNED_EXPRESSION_NODE";
        case PM_PINNED_VARIABLE_NODE:
            return "PM_PINNED_VARIABLE_NODE";
        case PM_POST_EXECUTION_NODE:
            return "PM_POST_EXECUTION_NODE";
        case PM_PRE_EXECUTION_NODE:
            return "PM_PRE_EXECUTION_NODE";
        case PM_PROGRAM_NODE:
            return "PM_PROGRAM_NODE";
        case PM_RANGE_NODE:
            return "PM_RANGE_NODE";
        case PM_RATIONAL_NODE:
            return "PM_RATIONAL_NODE";
        case PM_REDO_NODE:
            return "PM_REDO_NODE";
        case PM_REGULAR_EXPRESSION_NODE:
            return "PM_REGULAR_EXPRESSION_NODE";
        case PM_REQUIRED_KEYWORD_PARAMETER_NODE:
            return "PM_REQUIRED_KEYWORD_PARAMETER_NODE";
        case PM_REQUIRED_PARAMETER_NODE:
            return "PM_REQUIRED_PARAMETER_NODE";
        case PM_RESCUE_MODIFIER_NODE:
            return "PM_RESCUE_MODIFIER_NODE";
        case PM_RESCUE_NODE:
            return "PM_RESCUE_NODE";
        case PM_REST_PARAMETER_NODE:
            return "PM_REST_PARAMETER_NODE";
        case PM_RETRY_NODE:
            return "PM_RETRY_NODE";
        case PM_RETURN_NODE:
            return "PM_RETURN_NODE";
        case PM_SELF_NODE:
            return "PM_SELF_NODE";
        case PM_SINGLETON_CLASS_NODE:
            return "PM_SINGLETON_CLASS_NODE";
        case PM_SOURCE_ENCODING_NODE:
            return "PM_SOURCE_ENCODING_NODE";
        case PM_SOURCE_FILE_NODE:
            return "PM_SOURCE_FILE_NODE";
        case PM_SOURCE_LINE_NODE:
            return "PM_SOURCE_LINE_NODE";
        case PM_SPLAT_NODE:
            return "PM_SPLAT_NODE";
        case PM_STATEMENTS_NODE:
            return "PM_STATEMENTS_NODE";
        case PM_STRING_NODE:
            return "PM_STRING_NODE";
        case PM_SUPER_NODE:
            return "PM_SUPER_NODE";
        case PM_SYMBOL_NODE:
            return "PM_SYMBOL_NODE";
        case PM_TRUE_NODE:
            return "PM_TRUE_NODE";
        case PM_UNDEF_NODE:
            return "PM_UNDEF_NODE";
        case PM_UNLESS_NODE:
            return "PM_UNLESS_NODE";
        case PM_UNTIL_NODE:
            return "PM_UNTIL_NODE";
        case PM_WHEN_NODE:
            return "PM_WHEN_NODE";
        case PM_WHILE_NODE:
            return "PM_WHILE_NODE";
        case PM_X_STRING_NODE:
            return "PM_X_STRING_NODE";
        case PM_YIELD_NODE:
            return "PM_YIELD_NODE";
    }
    return "";
}
