ps2/2: add node_{create|finalize} and destory_subtree

This commit is contained in:
2026-02-14 13:31:30 +01:00
parent a426e25c17
commit bc28448fdb

View File

@@ -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