diff options
Diffstat (limited to 'src/ast.c')
-rw-r--r-- | src/ast.c | 131 |
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 |