diff options
| author | tomsmeding <tom.smeding@gmail.com> | 2016-08-06 11:17:56 +0200 | 
|---|---|---|
| committer | tomsmeding <tom.smeding@gmail.com> | 2016-08-06 11:17:56 +0200 | 
| commit | 2696105687d9c889ec4cccd449846135f83af404 (patch) | |
| tree | 032c4c114049631767b08df21bc165d0ccbdb8b9 | |
| parent | f67988fbfde6ad8a91466ef5d4227dcf9e5db6ce (diff) | |
Fix (-) handling
| -rw-r--r-- | code.txt | 4 | ||||
| -rw-r--r-- | parser.c | 39 | 
2 files changed, 33 insertions, 10 deletions
| @@ -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); @@ -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; | 
