summaryrefslogtreecommitdiff
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
parentee04f72b83ecd869148d57871af570fc704951ec (diff)
Stuff
-rw-r--r--main.c2
-rw-r--r--memory.c5
-rw-r--r--memory.h3
-rw-r--r--parser.c81
-rw-r--r--parser.h7
5 files changed, 91 insertions, 7 deletions
diff --git a/main.c b/main.c
index 7def025..6945950 100644
--- a/main.c
+++ b/main.c
@@ -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);
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);
}
diff --git a/parser.h b/parser.h
index 40bbc8d..a1b655f 100644
--- a/parser.h
+++ b/parser.h
@@ -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);