diff options
Diffstat (limited to 'ast.c')
-rw-r--r-- | ast.c | 96 |
1 files changed, 96 insertions, 0 deletions
@@ -0,0 +1,96 @@ +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "ast.h" +#include "util.h" + + +void ast_free(AST *ast){ + assert(ast); + switch(ast->type){ + case AST_LIST: + assert(ast->l.len>=0); + for(int i=0;i<ast->l.len;i++){ + assert(ast->l.nodes[i]); + ast_free(ast->l.nodes[i]); + } + break; + + case AST_WORD: + assert(ast->w.word); + free(ast->w.word); + break; + + case AST_NUMBER: + case AST_SYMBOL: + break; + + default: + assert(false); + } + free(ast); +} + + +AST* ast_copy(const AST *ast){ + assert(ast); + switch(ast->type){ + case AST_LIST:{ + assert(ast->l.len>=0); + assert(ast->l.nodes); + AST **nodes=malloc(ast->l.len,AST*); + for(int i=0;i<ast->l.len;i++)nodes[i]=ast_copy(ast->l.nodes[i]); + return ast_list(ast->l.len,nodes); + } + + case AST_WORD: + assert(ast->w.word); + return ast_word(copystring(ast->w.word)); + + case AST_NUMBER: + return ast_number(ast->n.num); + + case AST_SYMBOL:{ + assert(ast->s.name); + AST *sym=ast_symbol(ast->s.name); + sym->s.symid=ast->s.symid; + return sym; + } + + default: + assert(false); + } +} + + +AST* ast_list(int len,AST **nodes){ + assert(len>=0); + assert(nodes); + AST *ast=malloc(1,AST); + ast->l.len=len; + ast->l.nodes=malloc(len,AST*); + memcpy(ast->l.nodes,nodes,len*sizeof(AST*)); + return ast; +} + +AST* ast_word(char *word){ + assert(word); + AST *ast=malloc(1,AST); + ast->w.word=word; + return ast; +} + +AST* ast_number(double num){ + AST *ast=malloc(1,AST); + ast->n.num=num; + return ast; +} + +AST* ast_symbol(char *name){ + assert(name); + AST *ast=malloc(1,AST); + ast->s.name=name; + ast->s.symid=-1; + return ast; +} |