#include "node.h" RZ_ENUM_C(NodeType, NODE_TYPE); void node_init(node_t* node, NodeType type, char* value, int line) { assert(node); assert(value); node->type = type; str_init(&node->value); str_append(&node->value, value); node->line = line; node->children.size = 0; node->children.cap = 0; node->children.data = NULL; } void node_free(node_t* node) { assert(node); str_free(&node->value); for (size_t i=0; ichildren.size; i++) { node_free((node_t*) node->children.data[i]); free(node->children.data[i]); } free(node->children.data); node->children.size = 0; node->children.cap = 0; } void node_add_new_child(node_t* node, node_t* child) { assert(node); assert(child); if (node->children.cap == 0) { node->children.cap = 2; node->children.data = malloc(sizeof(node_t) * node->children.cap); } if (node->children.size >= node->children.cap) { node->children.cap *= 2; node->children.data = realloc(node->children.data, sizeof(node_t) * node->children.cap); } size_t sz = node->children.size; node->children.data[sz] = (struct node_t*) child; node->children.size++; } node_t* node_child(node_t* node, size_t index) { assert(node); assert(index < node->children.size); return (node_t*) node->children.data[index]; } size_t node_str(node_t* node, char* buffer, size_t size) { assert(node); size_t sz = 0; sz += snprintf(buffer + sz, size - sz, "%s", NodeTypeStr[node->type] + strlen("NODE_")); if (!str_empty(&node->value)) { sz += snprintf(buffer + sz, size - sz, "[%s]", node->value.data); } if (node->children.size > 0) { sz += snprintf(buffer +sz, size - sz, "("); for (size_t i=0; ichildren.size; i++) { if (i > 0) { sz += snprintf(buffer +sz, size - sz, ","); } sz += node_str((node_t*) node->children.data[i], buffer + sz, size - sz); } sz += snprintf(buffer +sz, size - sz, ")"); } return sz; } node_t* node_find_first(node_t* node, NodeType type) { assert(node); if (node->type == type) { return node; } for (size_t i=0; ichildren.size; i++) { node_t* child = node_find_first((node_t*) node->children.data[i], type); if (child) { return child; } } return NULL; }