ps2/2: add node_{create|finalize} and destory_subtree
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
#include "vslc.h"
|
||||
|
||||
#include "stdarg.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
/* #include "nodetypes.h" */
|
||||
|
||||
// Global root for abstract syntax tree
|
||||
node_t* root;
|
||||
|
||||
@@ -10,17 +15,19 @@ static void destroy_subtree(node_t* discard);
|
||||
// Initialize a node with the given type and children
|
||||
node_t* node_create(node_type_t type, size_t n_children, ...)
|
||||
{
|
||||
/*
|
||||
* TODO:
|
||||
* Initializer function for a syntax tree node
|
||||
|
||||
* HINT:
|
||||
* Allocate a node_t* using malloc.
|
||||
* Fill its fields with the specified type and children.
|
||||
* See include/tree.h for the node_t struct.
|
||||
* Remember to *allocate* space to hold the list of children children.
|
||||
* To access the parameters passed as ..., look up "C varargs"
|
||||
*/
|
||||
node_t *node = malloc(sizeof(node_t));
|
||||
node->type = type;
|
||||
node->n_children = n_children;
|
||||
node->children = malloc(sizeof(node_t) * n_children);
|
||||
|
||||
va_list args;
|
||||
va_start(args, n_children);
|
||||
for (int i = 0; i < n_children; i++) {
|
||||
node->children[i] = va_arg(args, node_t*);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// Append an element to the given LIST node, returns the list node
|
||||
@@ -111,29 +118,21 @@ static void node_print(node_t* node, int nesting)
|
||||
// Frees the memory owned by the given node, but does not touch its children
|
||||
static void node_finalize(node_t* discard)
|
||||
{
|
||||
/*
|
||||
* TODO:
|
||||
* Remove memory allocated for a single syntax tree node.
|
||||
|
||||
* HINT:
|
||||
* *Free* all fields owned by this node - see tree.h for a description of its fields.
|
||||
* Finally free the memory occupied by the node itself.
|
||||
* Only free the memory owned by this node - do not touch its children.
|
||||
*/
|
||||
if (discard->type == IDENTIFIER || discard->type == STRING_LITERAL)
|
||||
free(&discard->data);
|
||||
free(discard->children);
|
||||
free(discard);
|
||||
}
|
||||
|
||||
// Recursively frees the memory owned by the given node, and all its children
|
||||
static void destroy_subtree(node_t* discard)
|
||||
{
|
||||
/*
|
||||
* TODO:
|
||||
* Remove all nodes in the subtree rooted at a node, recursively.
|
||||
|
||||
* HINT:
|
||||
* Destroy entire *trees* instead of single *nodes*.
|
||||
* It's a good idead to destory the children first.
|
||||
* Seems like you can use the `node_finalize` function in some way here...
|
||||
*/
|
||||
if (discard->n_children == 0)
|
||||
node_finalize(discard);
|
||||
for (int i = 0; i < discard->n_children; i++) {
|
||||
node_t *child = discard->children[i];
|
||||
destroy_subtree(child);
|
||||
}
|
||||
}
|
||||
|
||||
// Definition of the global string array NODE_TYPE_NAMES
|
||||
|
||||
Reference in New Issue
Block a user