diff --git a/src/ast/ast.c b/src/ast/ast.c new file mode 100644 index 0000000..3a1a8fc --- /dev/null +++ b/src/ast/ast.c @@ -0,0 +1,59 @@ + +#include +#include +#include +#include + +struct AST_Node_t *AST_new_node(void) { + struct AST_Node_t *node = malloc(sizeof(struct AST_Node_t)); + + if (node == NULL) { + PANIC("failed to allocate AST node"); + } + + // init to discrete state + node->parent = NULL; + node->children = NULL; + node->child_count = 0; + + return node; +} + +void AST_push_node(struct AST_Node_t *owner, struct AST_Node_t *child) { + // if there are no children for now + if (owner->child_count == 0) { + owner->children = malloc(sizeof(struct AST_Node_t *)); + + } else { + size_t size = sizeof(struct AST_Node_t *) * (owner->child_count + 1); + owner->children = realloc(owner->children, size); + } + + if (owner->children == NULL) { + PANIC("failed to allocate children array of AST node"); + } + + owner->children[owner->child_count++] = child; +} + +struct AST_Node_t *AST_get_node(struct AST_Node_t *owner, size_t idx) { + if (owner == NULL) { + PANIC("AST owner node is NULL"); + } + + if (owner->children == NULL) { + PANIC("AST owner node has no children"); + } + + struct AST_Node_t *child = owner->children[idx]; + + if (child == NULL) { + PANIC("child node is NULL"); + } + + return child; +} + +void AST_delete_node(struct AST_Node_t *_) { +#warning "FIXME: not implemented" +} diff --git a/src/ast/ast.h b/src/ast/ast.h new file mode 100644 index 0000000..a222832 --- /dev/null +++ b/src/ast/ast.h @@ -0,0 +1,35 @@ + +#ifndef _AST_H_ +#define _AST_H_ + +#include + +struct AST_Node_t { + // parent node that owns this node + struct AST_Node_t *parent; + + // number of child nodes ownd by this node + // length of children array + size_t child_count; + // variable amount of child nodes + struct AST_Node_t **children; +}; + +// create a new initialized (empty) node +struct AST_Node_t *AST_new_node(void); + +void AST_delete_node(struct AST_Node_t *); + +// add a new child node +void AST_push_node(struct AST_Node_t *owner, struct AST_Node_t *child); + +// get a specific child node +struct AST_Node_t *AST_get_node(struct AST_Node_t *owner, size_t idx); + +// visit this and all of its child nodes calling the given function +// for every node +void AST_visit_nodes_recurse(struct AST_Node_t *root, + void (*for_each)(struct AST_Node_t *node, + size_t depth)); + +#endif