Added recursive free of nodes
parent
62ba30ec8c
commit
4b69ab87c6
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue