diff --git a/ps2/src/tree.c b/ps2/src/tree.c index 434a30d..9b08857 100644 --- a/ps2/src/tree.c +++ b/ps2/src/tree.c @@ -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