diff options
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 81 |
1 files changed, 78 insertions, 3 deletions
@@ -1,10 +1,85 @@ #include <stdio.h> +#include <stdlib.h> #include <string.h> +#include <ctype.h> +#include "memory.h" #include "parser.h" -AST* parse(const char *source){ - (void)source; - return NULL; +ASTblock* parse(const char *source){ + ASTblock *bl=malloc(sizeof(ASTblock)); + int sz=32; + bl->len=0; + bl->exprs=calloc(sz,sizeof(AST*)); + if(!bl->exprs)outofmem(); + int reslen; + int cursor=0; + while(true){ + if(bl->len==sz){ + sz*=2; + bl->exprs=realloc(bl->exprs,sz*sizeof(AST*)); + if(!bl->exprs)outofmem(); + } + while(source[cursor]&isspace(source[cursor]))cursor++; + if(!source[cursor])break; + AST *node=parsestmt(source+cursor,&reslen); + if(!node){ + ast_free((AST*)bl); + return NULL; + } + bl->exprs[bl->len++]=node; + cursor+=reslen; + } + return bl; +} + +void ast_free(AST *ast){ + switch(ast->type){ + case AST_BLOCK:{ ASTblock *ast=ast; + for(int i=0;i<ast->len;i++)if(ast->exprs[i])ast_free(ast->exprs[i]); + free(ast->exprs); + break; + } + + case AST_OP:{ ASTop *ast=ast; + if(ast->left)ast_free(ast->left); + if(ast->right)ast_free(ast->right); + break; + } + + case AST_NUM: + break; + + case AST_STR:{ ASTstr *ast=ast; + if(ast->str)free(ast->str); + break; + } + + case AST_VAR:{ ASTvar *ast=ast; + if(ast->name)free(ast->name); + break; + } + + case AST_CALL:{ ASTcall *ast=ast; + if(ast->func)free(ast->func); + for(int i=0;i<ast->nargs;i++)if(ast->args[i])ast_free(ast->args[i]); + free(ast->args); + break; + } + + case AST_IF:{ ASTif *ast=ast; + if(ast->cond)free(ast->cond); + if(ast->thenb)free(ast->thenb); + if(ast->elseb)free(ast->elseb); + break; + } + + case AST_WHILE:{ ASTwhile *ast=ast; + if(ast->cond)free(ast->cond); + if(ast->body)free(ast->body); + break; + } + } + free(ast); } |