Added recursive free of nodes

main
Øyvind Skaaden 2022-02-13 17:43:10 +01:00
parent 62ba30ec8c
commit 4b69ab87c6
1 changed files with 96 additions and 0 deletions

View File

@ -0,0 +1,96 @@
#include <vslc.h>
static void node_print ( node_t *root, int nesting );
static void node_finalize ( node_t *discard );
static void destroy_subtree ( node_t *discard );
/* External interface */
void
destroy_syntax_tree ( void )
{
destroy_subtree ( root );
}
void
print_syntax_tree ( void )
{
node_print ( root, 0 );
}
void
node_init (node_t *nd, node_index_t type, void *data, uint64_t n_children, ...)
{
// Copy the type
nd->type = type;
// Copy n_children
nd->n_children = n_children;
/*
The memory for this data needs to be
allocated somewhere not here, since this
function does not know the type.
*/
nd->data = data;
// Prepeare the VA list
va_list list_children;
va_start(list_children, n_children);
// Create memory region for the children pointers
nd->children = malloc(n_children * sizeof(node_t*));
// Populate the memory with pointers to children
for (int i = 0; i < n_children; i++)
nd->children[i] = va_arg(list_children, node_t*);
}
static void
node_print ( node_t *root, int nesting )
{
if ( root != NULL )
{
printf ( "%*c%s", nesting, ' ', node_string[root->type] );
if ( root->type == IDENTIFIER_DATA ||
root->type == STRING_DATA ||
root->type == EXPRESSION )
printf ( "(%s)", (char *) root->data );
else if ( root->type == NUMBER_DATA )
printf ( "(%ld)", *((int64_t *)root->data) );
putchar ( '\n' );
for ( int64_t i=0; i<root->n_children; i++ )
node_print ( root->children[i], nesting+1 );
}
else
printf ( "%*c%p\n", nesting, ' ', root );
}
// The discard should have zero children here. If not -> MEMORY LEAK
static void
node_finalize ( node_t *discard )
{
// Free the data and the children lists.
free(discard->data);
free(discard->children);
free(discard);
}
static void
destroy_subtree ( node_t *discard )
{
// Don't do anything if discard is nullptr
if (discard == NULL)
return;
// This will not run if n_children is zero
// If non-zero, destroy all child recursivly
while (discard->n_children--)
destroy_subtree(discard->children[discard->n_children]);
// Finally, destroy yourself
node_finalize(discard);
}