From 2696105687d9c889ec4cccd449846135f83af404 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 6 Aug 2016 11:17:56 +0200 Subject: Fix (-) handling --- code.txt | 4 +++- parser.c | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/code.txt b/code.txt index 3b04c0f..ae7ef31 100644 --- a/code.txt +++ b/code.txt @@ -1,3 +1,5 @@ a = 1; b = 2; -c = 1 + -x - 3 > -1; +c = 1 + (- a - 3 + b > -1); +b += 1; +b = 3*(b//3-1); diff --git a/parser.c b/parser.c index 14fd47d..6cced13 100644 --- a/parser.c +++ b/parser.c @@ -79,7 +79,7 @@ static void skipintermediate(const char **sourcep){ *sourcep=source; } -static Token nexttoken(const char **sourcep){ +static Token nexttoken(const char **sourcep,bool expectop){ skipintermediate(sourcep); const char *source=*sourcep; if(*source=='\0'){ @@ -91,7 +91,7 @@ static Token nexttoken(const char **sourcep){ (*sourcep)++; return tok; } - if(isdigit(*source)||(*source=='-'&&isdigit(source[1]))){ + if(isdigit(*source)||(!expectop&&*source=='-'&&isdigit(source[1]))){ char *endp; strtod(source,&endp); assert(endp!=source); @@ -161,9 +161,11 @@ static void printtoken(FILE *stream,Token tok,const char *msg){ } +static AST* parseexpr(const char *source,int *reslen,int minprec); + static AST* parseterm(const char *source,int *reslen){ const char *origsource=source; - const Token tok=nexttoken(&source); + const Token tok=nexttoken(&source,false); printtoken(stderr,tok,"parseterm"); AST *node; switch(tok.type){ @@ -229,7 +231,7 @@ static AST* parseterm(const char *source,int *reslen){ if(tok.len==2&&memcmp(tok.str,"if",2)==0)assert(NOT_IMPLEMENTED); if(tok.len==5&&memcmp(tok.str,"while",2)==0)assert(NOT_IMPLEMENTED); const char *tempsource=source; - Token next=nexttoken(&source); + Token next=nexttoken(&source,false); if(next.len==1&&next.str[0]=='(')assert(NOT_IMPLEMENTED); source=tempsource; node=malloc(sizeof(AST)); @@ -243,7 +245,21 @@ static AST* parseterm(const char *source,int *reslen){ } case TT_SYM: - assert(NOT_IMPLEMENTED); + if(tok.len==1&&tok.str[0]=='{'){ + assert(NOT_IMPLEMENTED); + } else if(tok.len==1&&tok.str[0]=='('){ + int len; + node=parseexpr(source,&len,0); + if(!node)return NULL; + source+=len; + Token aftertok=nexttoken(&source,false); + if(aftertok.type!=TT_SYM||aftertok.len!=1||aftertok.str[0]!=')'){ + ast_free(node); + return NULL; + } + } else { + return NULL; + } break; case TT_OP:{ @@ -287,12 +303,16 @@ static AST* parseexpr(const char *source,int *reslen,int minprec){ source+=len; while(true){ const char *beforeop=source; - Token tok=nexttoken(&source); + Token tok=nexttoken(&source,true); printtoken(stderr,tok,"parseEXPR"); if(tok.type==TT_ENDSTMT){ source=beforeop; break; } + if(tok.type==TT_SYM&&tok.len==1&&tok.str[0]==')'){ + source=beforeop; + break; + } if(tok.type!=TT_OP){ ast_free(tree); return NULL; @@ -362,14 +382,14 @@ AST* parse(const char *source){ bl->b.exprs[bl->b.len++]=node; cursor+=reslen; const char *src=source+cursor; - Token tok=nexttoken(&src); + Token tok=nexttoken(&src,false); if(tok.type!=TT_ENDSTMT){ ast_free(bl); return NULL; } cursor=src-source; src=source+cursor; - tok=nexttoken(&src); + tok=nexttoken(&src,false); if(tok.type==TT_EOF)break; } return bl; @@ -409,10 +429,11 @@ static void ast_debug_(FILE *stream,const AST *ast,int indent){ case AST_OP:{ bool leftp=ast->o.left&&ast->o.left->type==AST_OP&&precedence(ast->o.left->o.op)<=precedence(ast->o.op); bool rightp=ast->o.right&&ast->o.right->type==AST_OP&&precedence(ast->o.right->o.op)<=precedence(ast->o.op); + bool spaces=ast->o.left&&ast->o.right; //fprintf(stderr,"[[op='%s' p=%d lp=%d rp=%d]]",ast->o.op,precedence(ast->o.op),leftp,rightp); if(leftp)fputc('(',stream); if(ast->o.left)ast_debug_(stream,ast->o.left,indent); - fprintf(stream,"%s%s%s",leftp?")":"",ast->o.op,rightp?"(":""); + fprintf(stream,"%s%s%s%s%s",leftp?")":"",spaces?" ":"",ast->o.op,spaces?" ":"",rightp?"(":""); if(ast->o.right)ast_debug_(stream,ast->o.right,indent); if(rightp)fputc(')',stream); break; -- cgit v1.2.3-70-g09d2