summaryrefslogtreecommitdiff
path: root/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'ast.c')
-rw-r--r--ast.c83
1 files changed, 52 insertions, 31 deletions
diff --git a/ast.c b/ast.c
index 7f97948..44401cb 100644
--- a/ast.c
+++ b/ast.c
@@ -1,11 +1,17 @@
#include "ast.h"
+#include "scope.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->def);
+}
+
static void var_decl_destroy(struct var_decl_node* node) {
free(node->ident);
+ type_destroy(&node->type);
}
static void var_ref_destroy(struct var_ref_node* node) {
@@ -15,10 +21,10 @@ static void var_ref_destroy(struct var_ref_node* node) {
static void lval_destroy(struct lval_node* node) {
switch (node->type) {
case LVAL_VAR_DECL:
- var_decl_destroy(&node->as._var_decl);
+ var_decl_destroy(&node->inner.var_decl);
break;
case LVAL_VAR_REF:
- var_ref_destroy(&node->as._var_ref);
+ var_ref_destroy(&node->inner.var_ref);
break;
}
}
@@ -30,27 +36,37 @@ static void assign_destroy(struct assign_node* node) {
}
static void group_destroy(struct group_node* node) {
- struct stmt_node* body_node = node->body_head;
+ struct stmt_node* body_node = node->head;
while (body_node != NULL) {
struct stmt_node* next = body_node->next;
stmt_destroy(body_node);
free(body_node);
body_node = next;
}
+
+ scope_destroy(node->scope);
+ free(node->scope);
+}
+
+static void args_decl_destroy(struct args_decl_node* node) {
+ if (node != NULL) {
+ var_decl_destroy(node->decl);
+ free(node->decl);
+ args_decl_destroy(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;
- }
+ args_decl_destroy(node->args);
+ free(node->args);
group_destroy(&node->body);
+
+ scope_destroy(node->scope);
+ free(node->scope);
}
static void return_destroy(struct return_node* node) {
@@ -64,17 +80,19 @@ static void str_lit_destroy(struct str_lit_node* node) {
free(node->val);
}
-static void call_destroy(struct call_node* node) {
- /* don't destroy node->called_fn, this is owned by its declaration */
- struct expr_node* args_node = node->args_head;
- while (args_node != NULL) {
- struct expr_node* next = args_node->next;
- expr_destroy(args_node);
- free(args_node);
- args_node = next;
+static void args_list_destroy(struct args_eval_node* node) {
+ if (node != NULL) {
+ expr_destroy(node->expr);
+ free(node->expr);
+ args_list_destroy(node->next);
}
}
+static void call_destroy(struct call_node* node) {
+ args_list_destroy(node->args);
+ free(node->args);
+}
+
static void unary_destroy(struct unary_node* node) {
expr_destroy(node->expr);
free(node->expr);
@@ -95,22 +113,22 @@ static void expr_destroy(struct expr_node* node) {
case EXPR_CHAR_LIT:
break;
case EXPR_STR_LIT:
- str_lit_destroy(&node->as._str_lit);
+ str_lit_destroy(&node->inner.str_lit);
break;
case EXPR_VAR_REF:
- var_ref_destroy(&node->as._var_ref);
+ var_ref_destroy(&node->inner.var_ref);
break;
case EXPR_ASSIGN:
- assign_destroy(&node->as._assign);
+ assign_destroy(&node->inner.assign);
break;
case EXPR_CALL:
- call_destroy(&node->as._call);
+ call_destroy(&node->inner.call);
break;
case EXPR_UNARY:
- unary_destroy(&node->as._unary);
+ unary_destroy(&node->inner.unary);
break;
case EXPR_BINARY:
- binary_destroy(&node->as._binary);
+ binary_destroy(&node->inner.binary);
break;
}
}
@@ -120,33 +138,36 @@ static void stmt_destroy(struct stmt_node* node) {
case STMT_EMPTY:
break;
case STMT_EXPR:
- expr_destroy(&node->as._expr);
+ expr_destroy(&node->inner.expr);
break;
case STMT_VAR_DECL:
- var_decl_destroy(&node->as._var_decl);
+ var_decl_destroy(&node->inner.var_decl);
break;
case STMT_RETURN:
- return_destroy(&node->as._return);
+ return_destroy(&node->inner.return_);
break;
case STMT_GROUP:
- group_destroy(&node->as._group);
+ group_destroy(&node->inner.group);
}
}
static void root_node_destroy(struct root_node* node) {
switch (node->type) {
case ROOT_FN_DECL:
- fn_decl_destroy(&node->as._fn_decl);
+ fn_decl_destroy(&node->inner.fn_decl);
break;
}
}
-void ast_destroy(struct root_node* head) {
- struct root_node* node = head;
+void ast_destroy(struct ast* ast) {
+ struct root_node* node = ast->root_node;
while (node != NULL) {
struct root_node* next = node->next;
root_node_destroy(node);
free(node);
node = next;
}
+
+ scope_destroy(ast->root_scope);
+ free(ast->root_scope);
}