From 77263f95bbbc9d8c91ab77726f02f445a1e3f367 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Mon, 8 Aug 2016 21:18:52 +0200 Subject: Basic if statements --- code.txt | 9 ++++++++- parser.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/code.txt b/code.txt index 07e132d..783d1b5 100644 --- a/code.txt +++ b/code.txt @@ -8,6 +8,13 @@ x = 1 + 1 + 1 + 1; y = 1 > (1 > 1) == 1; kaas(1,2,"goeiemorgen\x99",sqrt(3**2+4**2)); 1 + 1 + 1; -1 - 1 - 1; +if (2 > 1) 1 - 1 - 1; 1 / 1 / 1; 1 ** 1 ** 1; + +if kaas + doe(dingen) +else if andere(kaas) + doe(andere,dingen) +else + print("rip"); diff --git a/parser.c b/parser.c index 857b11d..7ed64a6 100644 --- a/parser.c +++ b/parser.c @@ -11,7 +11,7 @@ #include "parser.h" -#undef DEBUG +#define DEBUG #ifdef DEBUG #define DBG(...) __VA_ARGS__ @@ -51,7 +51,7 @@ typedef enum Tokentype{ typedef struct Token{ Tokentype type; - const char *str; //Part of another string; not null-terminated, and do not free + const char *str; //Pointer into source string, or NULL if TT_EOF int len; } Token; @@ -253,7 +253,39 @@ static AST* parseterm(const char *source,int *reslen){ } case TT_WORD:{ - if(tok.len==2&&memcmp(tok.str,"if",2)==0)assert(NOT_IMPLEMENTED); + if(tok.len==2&&memcmp(tok.str,"if",2)==0){ + int len; + AST *cond=parseexpr(source,&len,0,INT_MAX); + if(!cond)return NULL; + source+=len; + AST *thenbody=parseexpr(source,&len,0,INT_MAX); + if(!thenbody){ + ast_free(cond); + return NULL; + } + source+=len; + AST *elsebody=NULL; + const char *src=source; + Token elsetok=nexttoken(&src,false); + if(elsetok.type==TT_WORD&&elsetok.len==4&&memcmp(elsetok.str,"else",4)==0){ + DBG(printtoken(stderr,elsetok,"if else ")); + source=src; + elsebody=parseexpr(source,&len,0,INT_MAX); + if(!elsebody){ + ast_free(cond); + ast_free(thenbody); + return NULL; + } + source+=len; + } + node=malloc(sizeof(AST)); + if(!node)outofmem(); + node->type=AST_IF; + node->i.cond=cond; + node->i.thenb=thenbody; + node->i.elseb=elsebody; + break; + } if(tok.len==5&&memcmp(tok.str,"while",2)==0)assert(NOT_IMPLEMENTED); const char *tempsource=source; Token next=nexttoken(&source,false); @@ -381,8 +413,11 @@ static AST* parseexpr_(const char *source,int *reslen,int minprec,int maxprec){ break; } if(tok.type!=TT_OP){ - ast_free(tree); - return NULL; + /*ast_free(tree); + return NULL;*/ + DBGF(" (token undo)\n"); + source=beforeop; + break; } int prec=precedence_len(tok.str,tok.len); if(precb.len;i++){ INDENT ast_debug_(stream,ast->b.exprs[i],indent); - fputc('\n',stream); + fprintf(stream,";\n"); } indent--; INDENT @@ -580,14 +615,29 @@ static void ast_debug_(FILE *stream,const AST *ast,int indent){ case AST_CALL: fprintf(stream,"%s(",ast->c.func); for(int i=0;ic.nargs;i++){ - if(i!=0)fputc(',',stream); + if(i!=0)fprintf(stream,", "); ast_debug_(stream,ast->c.args[i],indent); } fputc(')',stream); break; case AST_IF: - assert(NOT_IMPLEMENTED); + fprintf(stream,"if ("); + ast_debug_(stream,ast->i.cond,indent); + fprintf(stream,")\n"); + indent++; + INDENT + ast_debug_(stream,ast->i.thenb,indent); + indent--; + if(ast->i.elseb){ + fputc('\n',stream); + INDENT + fprintf(stream,"else\n"); + indent++; + INDENT + ast_debug_(stream,ast->i.elseb,indent); + indent--; + } break; case AST_WHILE: -- cgit v1.2.3