#include #include #include #include #include "memory.h" #include "parser.h" 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;ilen;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;inargs;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); }