summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2016-08-01 20:06:37 +0200
committerTom Smeding <tom.smeding@gmail.com>2016-08-01 20:06:37 +0200
commitf83ea28ae6a04f1121b8328f7bdc5dad94628328 (patch)
tree1123121d3591c64076d20d9301e9a54b28c835a7 /parser.c
parentee04f72b83ecd869148d57871af570fc704951ec (diff)
Stuff
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c81
1 files changed, 78 insertions, 3 deletions
diff --git a/parser.c b/parser.c
index 421a044..e099e98 100644
--- a/parser.c
+++ b/parser.c
@@ -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);
}