summaryrefslogtreecommitdiff
path: root/ast.c
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-03-26 16:21:29 -0400
committerCarson Fleming <cflems@cflems.net>2026-03-26 16:22:00 -0400
commit7d9fb2c733c8c64f6f74eefa0eea35b36be102cd (patch)
tree16b6cded5f9611e0ff1948395578845c9688b926 /ast.c
parent68db110d34611fc8bb79035d3a11bba07dea43f3 (diff)
downloadccc-7d9fb2c733c8c64f6f74eefa0eea35b36be102cd.tar.gz
let's go we can parse return zero most useful program ever
Diffstat (limited to 'ast.c')
-rw-r--r--ast.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/ast.c b/ast.c
new file mode 100644
index 0000000..3bcc637
--- /dev/null
+++ b/ast.c
@@ -0,0 +1,90 @@
+#include "ast.h"
+#include <stdlib.h>
+
+static void expr_destroy(struct expr_node* node);
+static void stmt_destroy(struct stmt_node* node);
+
+static void type_destroy(struct type_node* node) {
+ free(node->type);
+}
+
+static void var_decl_destroy(struct var_decl_node* node) {
+ type_destroy(&node->type);
+
+ free(node->ident);
+}
+
+static void group_destroy(struct group_node* node) {
+ struct stmt_node* body_node = node->body_head;
+ while (body_node != NULL) {
+ struct stmt_node* next = body_node->next;
+ stmt_destroy(body_node);
+ free(body_node);
+ body_node = next;
+ }
+}
+
+static void fn_decl_destroy(struct fn_decl_node* node) {
+ type_destroy(&node->return_type);
+
+ free(node->name);
+
+ struct var_decl_node* args_node = node->args_head;
+ while (args_node != NULL) {
+ struct var_decl_node* next = args_node->next;
+ var_decl_destroy(args_node);
+ free(args_node);
+ args_node = next;
+ }
+
+ group_destroy(&node->body);
+}
+
+static void return_destroy(struct return_node* node) {
+ if (node->ret_val != NULL) {
+ expr_destroy(node->ret_val);
+ free(node->ret_val);
+ }
+}
+
+static void expr_destroy(struct expr_node* node) {
+ switch (node->type) {
+ case EXPR_EMPTY:
+ case EXPR_INT_LIT:
+ break;
+ case EXPR_VAR_DECL:
+ var_decl_destroy(&node->as._var_decl);
+ break;
+ case EXPR_RETURN:
+ return_destroy(&node->as._return);
+ break;
+ }
+}
+
+static void stmt_destroy(struct stmt_node* node) {
+ switch (node->type) {
+ case STMT_EXPR:
+ expr_destroy(&node->as._expr);
+ break;
+ case STMT_GROUP:
+ group_destroy(&node->as._group);
+ }
+}
+
+static void root_node_destroy(struct root_node* node) {
+ switch (node->type) {
+ case ROOT_FN_DECL:
+ fn_decl_destroy(&node->as._fn_decl);
+ break;
+ }
+}
+
+void ast_destroy(struct root_node* head) {
+ struct root_node* node = head;
+ while (node != NULL) {
+ struct root_node* next = node->next;
+ root_node_destroy(node);
+ free(node);
+ node = next;
+ }
+}