diff options
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | memory.c | 5 | ||||
-rw-r--r-- | memory.h | 3 | ||||
-rw-r--r-- | parser.c | 81 | ||||
-rw-r--r-- | parser.h | 7 |
5 files changed, 91 insertions, 7 deletions
@@ -2,8 +2,8 @@ #include <stdlib.h> #include <stdbool.h> #include <string.h> -#include <assert.h> +#include "memory.h" #include "parser.h" char* readfile(const char *fname){ diff --git a/memory.c b/memory.c new file mode 100644 index 0000000..875e2bd --- /dev/null +++ b/memory.c @@ -0,0 +1,5 @@ +#include "memory.h" + +void outofmem(void){ + __asm volatile ("int3\n\t"); +} diff --git a/memory.h b/memory.h new file mode 100644 index 0000000..b5c3f25 --- /dev/null +++ b/memory.h @@ -0,0 +1,3 @@ +#pragma once + +void outofmem(void); @@ -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); } @@ -28,7 +28,7 @@ typedef struct ASTwhile ASTwhile; struct ASTblock{ int len; - AST *exprs; + AST **exprs; }; struct ASTop{ const char *op; // Constant string, does not need to be freed @@ -51,7 +51,7 @@ struct ASTvar{ struct ASTcall{ char *func; int nargs; - AST *args; // Array<AST> + AST **args; }; struct ASTif{ AST *cond; @@ -77,4 +77,5 @@ typedef struct AST{ } AST; -AST* parse(const char *source); +ASTblock* parse(const char *source); +void ast_free(AST *ast); |