diff --git a/src/ast/ast.c b/src/ast/ast.c index db600ee..2397f34 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -1,10 +1,11 @@ #include +#include #include #include #include -struct AST_Node_t *AST_new_node(void) { +struct AST_Node_t *AST_new_node(enum AST_SyntaxElement_t kind, const char* value) { struct AST_Node_t *node = malloc(sizeof(struct AST_Node_t)); if (node == NULL) { @@ -15,10 +16,36 @@ struct AST_Node_t *AST_new_node(void) { node->parent = NULL; node->children = NULL; node->child_count = 0; + node->kind = kind; + node->value = value; return node; } +const char* AST_node_to_string(struct AST_Node_t* node) { + const char* string = "unknown"; + + switch (node->kind) { + case AST_Expression: + string = "expression"; + break; + case AST_Statement: + string = "statement"; + break; + case AST_Branch: + string = "if"; + break; + case AST_IntegerLiteral: + string = node->value; + break; + case AST_OperatorAdd: + string = "+"; + break; + } + + return string; +} + 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) { @@ -54,8 +81,16 @@ struct AST_Node_t *AST_get_node(struct AST_Node_t *owner, size_t idx) { return child; } -void AST_delete_node(struct AST_Node_t *_) { -#warning "FIXME: not implemented" +void AST_delete_node(struct AST_Node_t *node) { + if (node == NULL) { + PANIC("Node to free is NULL"); + } + + if (node->children != NULL) { + for (size_t i = 0; i < node->child_count; i++) { + AST_delete_node(node->children[i]); + } + } } static void __AST_visit_nodes_recurse2(struct AST_Node_t *root, @@ -74,3 +109,33 @@ void AST_visit_nodes_recurse(struct AST_Node_t *root, size_t depth)) { __AST_visit_nodes_recurse2(root, for_each, 0); } + +void AST_fprint_graphviz_node_definition(FILE* stream, struct AST_Node_t* node) { + + fprintf(stream, "\tnode%p [label=\"%s\"]\n", (void*) node, AST_node_to_string(node)); + + if (node->children != NULL) { + for (size_t i = 0; i < node->child_count; i++) { + AST_fprint_graphviz_node_definition(stream, node->children[i]); + } + } +} + +void AST_fprint_graphviz_node_connection(FILE* stream, struct AST_Node_t* node) { + + if (node->children != NULL) { + for (size_t i = 0; i < node->child_count; i++) { + fprintf(stream, "\tnode%p -- node%p\n", (void*) node, (void*) node->children[i]); + AST_fprint_graphviz_node_connection(stream, node->children[i]); + } + } +} + +void AST_fprint_graphviz(FILE* stream, struct AST_Node_t* root) { + fprintf(stream, "graph {\n"); + + AST_fprint_graphviz_node_definition(stream, root); + AST_fprint_graphviz_node_connection(stream, root); + + fprintf(stream, "}\n"); +} diff --git a/src/ast/ast.h b/src/ast/ast.h index a222832..e07ff19 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -4,10 +4,24 @@ #include +// Syntax elements which are stored in a syntax tree +enum AST_SyntaxElement_t { + AST_Statement, + AST_Expression, + AST_Branch, + AST_OperatorAdd, + AST_IntegerLiteral +}; + struct AST_Node_t { // parent node that owns this node struct AST_Node_t *parent; + // type of AST node: if, declration, ... + enum AST_SyntaxElement_t kind; + // optional value: integer literal, string literal, ... + const char* value; + // number of child nodes ownd by this node // length of children array size_t child_count; @@ -15,8 +29,12 @@ struct AST_Node_t { struct AST_Node_t **children; }; +// return a string representation of the nodes type and its value +// does not take into account its children or parent +const char* AST_node_to_string(struct AST_Node_t* node); + // create a new initialized (empty) node -struct AST_Node_t *AST_new_node(void); +struct AST_Node_t *AST_new_node(enum AST_SyntaxElement_t kind, const char* value); void AST_delete_node(struct AST_Node_t *); @@ -32,4 +50,7 @@ void AST_visit_nodes_recurse(struct AST_Node_t *root, void (*for_each)(struct AST_Node_t *node, size_t depth)); +// print a graphviz diagram of the supplied node (as root node) into stream +void AST_fprint_graphviz(FILE* stream, struct AST_Node_t* node); + #endif diff --git a/src/main.c b/src/main.c index 8bb8127..b94149a 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -36,6 +38,26 @@ void setup(void) int main(void) { setup(); - yyparse(); + struct AST_Node_t* node = AST_new_node(AST_Branch, NULL); + + struct AST_Node_t* child = AST_new_node(AST_OperatorAdd, NULL); + AST_push_node(child, AST_new_node(AST_IntegerLiteral, "43")); + AST_push_node(child, AST_new_node(AST_IntegerLiteral, "9")); + + AST_push_node(node, child); + AST_push_node(node, AST_new_node(AST_Expression, NULL)); + AST_push_node(node, AST_new_node(AST_Expression, NULL)); + + FILE* out = fopen("ast.gv", "w+"); + // convert this file ^^^^^^ + // to an svg with: `dot -Tsvg ast.gv > graph.svg` + + AST_fprint_graphviz(out, node); + + AST_delete_node(node); + + fflush(out); + fclose(out); + return 0; }