aboutsummaryrefslogtreecommitdiff
path: root/src/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast.c')
-rw-r--r--src/ast.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/ast.c b/src/ast.c
new file mode 100644
index 0000000..acc7c9e
--- /dev/null
+++ b/src/ast.c
@@ -0,0 +1,131 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ast.h"
+
+static ASTNode *new_node(NodeType type) {
+ ASTNode *node = malloc(sizeof(ASTNode));
+ node->type = type;
+ return node;
+}
+
+ASTNode *ast_skip(void) {
+ return new_node(NT_SKIP);
+}
+
+ASTNode *ast_assign(ASTNode *var, ASTNode *aexp) {
+ ASTNode *node = new_node(NT_ASSIGN);
+ node->u.d_assign.var = var;
+ node->u.d_assign.aexp = aexp;
+ return node;
+}
+
+ASTNode *ast_seq(ASTNode *stm1, ASTNode *stm2) {
+ ASTNode *node = new_node(NT_SEQ);
+ node->u.d_seq.stm1 = stm1;
+ node->u.d_seq.stm2 = stm2;
+ return node;
+}
+
+ASTNode *ast_if(ASTNode *bexp, ASTNode *stm1, ASTNode *stm2) {
+ ASTNode *node = new_node(NT_IF);
+ node->u.d_if.bexp = bexp;
+ node->u.d_if.stm1 = stm1;
+ node->u.d_if.stm2 = stm2;
+ return node;
+}
+
+ASTNode *ast_while(ASTNode *bexp, ASTNode *stm) {
+ ASTNode *node = new_node(NT_WHILE);
+ node->u.d_while.bexp = bexp;
+ node->u.d_while.stm = stm;
+ return node;
+}
+
+ASTNode *ast_int(int val) {
+ ASTNode *node = new_node(NT_INT);
+ node->u.d_int.val = val;
+ return node;
+}
+
+ASTNode *ast_var(char *name) {
+ ASTNode *node = new_node(NT_VAR);
+ node->u.d_var.name = strdup(name);
+ return node;
+}
+
+ASTNode *ast_aop(AOp aop, ASTNode *aexp1, ASTNode *aexp2) {
+ ASTNode *node = new_node(NT_AOP);
+ node->u.d_aop.aexp1 = aexp1;
+ node->u.d_aop.aexp2 = aexp2;
+ node->u.d_aop.aop = aop;
+ return node;
+}
+
+ASTNode *ast_bop(BOp bop, ASTNode *bexp1, ASTNode *bexp2) {
+ ASTNode *node = new_node(NT_BOP);
+ node->u.d_bop.bexp1 = bexp1;
+ node->u.d_bop.bexp2 = bexp2;
+ node->u.d_bop.bop = bop;
+ return node;
+}
+
+ASTNode *ast_not(ASTNode *bexp) {
+ ASTNode *node = new_node(NT_NOT);
+ node->u.d_not.bexp = bexp;
+ return node;
+}
+
+ASTNode *ast_rop(ROp rop, ASTNode *aexp1, ASTNode *aexp2) {
+ ASTNode *node = new_node(NT_ROP);
+ node->u.d_rop.aexp1 = aexp1;
+ node->u.d_rop.aexp2 = aexp2;
+ node->u.d_rop.rop = rop;
+ return node;
+}
+
+void free_ast(ASTNode *node) {
+ if (!node) return;
+ switch (node->type) {
+ case NT_SKIP:
+ break;
+ case NT_ASSIGN:
+ free_ast(node->u.d_assign.var);
+ free_ast(node->u.d_assign.aexp);
+ break;
+ case NT_SEQ:
+ free_ast(node->u.d_seq.stm1);
+ free_ast(node->u.d_seq.stm2);
+ break;
+ case NT_IF:
+ free_ast(node->u.d_if.bexp);
+ free_ast(node->u.d_if.stm1);
+ free_ast(node->u.d_if.stm2);
+ break;
+ case NT_WHILE:
+ free_ast(node->u.d_while.bexp);
+ free_ast(node->u.d_while.stm);
+ break;
+ case NT_INT:
+ break;
+ case NT_VAR:
+ free(node->u.d_var.name);
+ break;
+ case NT_AOP:
+ free_ast(node->u.d_aop.aexp1);
+ free_ast(node->u.d_aop.aexp2);
+ break;
+ case NT_BOP:
+ free_ast(node->u.d_bop.bexp1);
+ free_ast(node->u.d_bop.bexp2);
+ break;
+ case NT_ROP:
+ free_ast(node->u.d_rop.aexp1);
+ free_ast(node->u.d_rop.aexp2);
+ break;
+ case NT_NOT:
+ free_ast(node->u.d_not.bexp);
+ break;
+ }
+ free(node);
+} \ No newline at end of file