diff options
-rw-r--r-- | code.txt | 7 | ||||
-rw-r--r-- | parser.c | 83 |
2 files changed, 66 insertions, 24 deletions
@@ -3,6 +3,11 @@ b = !2; c = 1 + (- a - 3 + b > -1); b += 1; b = 3*(b//3-1); - 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; +1 / 1 / 1; +1 ** 1 ** 1; @@ -131,7 +131,7 @@ static Token nexttoken(const char **sourcep,bool expectop){ return lasttoken=tok; } } - if(strchr("(){}",*source)!=NULL){ + if(strchr("(){},",*source)!=NULL){ Token tok={TT_SYM,source,1}; (*sourcep)++; return lasttoken=tok; @@ -180,7 +180,7 @@ static AST* parseexpr(const char *source,int *reslen,int minprec,int maxprec); static AST* parseterm(const char *source,int *reslen){ const char *origsource=source; const Token tok=nexttoken(&source,false); - //printtoken(stderr,tok,"parseterm"); + printtoken(stderr,tok,"parseterm"); AST *node; switch(tok.type){ case TT_NUM:{ @@ -206,13 +206,12 @@ static AST* parseterm(const char *source,int *reslen){ return NULL; } i+=2; - } else { - i++; } } node=malloc(sizeof(AST)); if(!node)outofmem(); node->type=AST_STR; + node->s.len=slen; node->s.str=malloc(slen+1); if(!node->s.str)outofmem(); int j=0; @@ -246,15 +245,53 @@ static AST* parseterm(const char *source,int *reslen){ if(tok.len==5&&memcmp(tok.str,"while",2)==0)assert(NOT_IMPLEMENTED); const char *tempsource=source; Token next=nexttoken(&source,false); - if(next.len==1&&next.str[0]=='(')assert(NOT_IMPLEMENTED); - source=tempsource; - node=malloc(sizeof(AST)); - if(!node)outofmem(); - node->type=AST_VAR; - node->v.name=malloc(tok.len+1); - if(!node->v.name)outofmem(); - memcpy(node->v.name,tok.str,tok.len); - node->v.name[tok.len]='\0'; + if(next.len==1&&next.str[0]=='('){ + printtoken(stderr,next,"function "); + AST **args=malloc(sizeof(AST*)); + int nargs=0; + int len; +#define FREEARGSRETNULL do {for(int i=0;i<nargs;i++)ast_free(args[i]); free(args); return NULL;} while(0) + const char *src=source; + next=nexttoken(&src,false); + if(next.type!=TT_SYM||next.len!=1||next.str[0]!=')'){ + while(true){ + AST *arg=parseexpr(source,&len,0,INT_MAX); + if(!arg)FREEARGSRETNULL; + args=realloc(args,(nargs+1)*sizeof(AST*)); + if(!args)outofmem(); + source+=len; + args[nargs++]=arg; + next=nexttoken(&source,false); + printtoken(stderr,next,"func-sep "); + if(next.type!=TT_SYM||next.len!=1||(next.str[0]!=','&&next.str[0]!=')')){ + FREEARGSRETNULL; + } + if(next.str[0]==')')break; + } + } else { + printtoken(stderr,next,"func-end "); + source=src; + } + node=malloc(sizeof(AST)); + if(!node)outofmem(); + node->type=AST_CALL; + node->c.func=malloc(tok.len+1); + if(!node->c.func)outofmem(); + memcpy(node->c.func,tok.str,tok.len); + node->c.func[tok.len]='\0'; + node->c.nargs=nargs; + node->c.args=args; +#undef FREEARGSRETNULL + } else { + source=tempsource; + node=malloc(sizeof(AST)); + if(!node)outofmem(); + node->type=AST_VAR; + node->v.name=malloc(tok.len+1); + if(!node->v.name)outofmem(); + memcpy(node->v.name,tok.str,tok.len); + node->v.name[tok.len]='\0'; + } break; } @@ -267,7 +304,7 @@ static AST* parseterm(const char *source,int *reslen){ if(!node)return NULL; source+=len; Token aftertok=nexttoken(&source,false); - //printtoken(stderr,aftertok,"braceclose"); + printtoken(stderr,aftertok,"braceclose"); if(aftertok.type!=TT_SYM||aftertok.len!=1||aftertok.str[0]!=')'){ ast_free(node); return NULL; @@ -320,14 +357,14 @@ static AST* parseexpr_(const char *source,int *reslen,int minprec,int maxprec){ while(true){ const char *beforeop=source; Token tok=nexttoken(&source,true); - //printtoken(stderr,tok,"parseEXPR"); + printtoken(stderr,tok,"parseEXPR"); if(tok.type==TT_ENDSTMT){ - //fprintf(stderr," (token undo)\n"); + fprintf(stderr," (token undo)\n"); source=beforeop; break; } - if(tok.type==TT_SYM&&tok.len==1&&tok.str[0]==')'){ - //fprintf(stderr," (token undo)\n"); + if(tok.type==TT_SYM&&tok.len==1&&(tok.str[0]==')'||tok.str[0]==',')){ + fprintf(stderr," (token undo)\n"); source=beforeop; break; } @@ -337,7 +374,7 @@ static AST* parseexpr_(const char *source,int *reslen,int minprec,int maxprec){ } int prec=precedence_len(tok.str,tok.len); if(prec<minprec){ - //fprintf(stderr," (token undo)\n"); + fprintf(stderr," (token undo)\n"); source=beforeop; break; } @@ -379,11 +416,11 @@ static AST* parseexpr_(const char *source,int *reslen,int minprec,int maxprec){ static AST* parseexpr(const char *source,int *reslen,int minprec,int maxprec){ static int depth=0; - //fprintf(stderr,"\x1B[32mEXPR ENTER >>> (%d)\x1B[0m\n",depth); + fprintf(stderr,"\x1B[32mEXPR ENTER >>> (%d)\x1B[0m\n",depth); depth++; AST *r=parseexpr_(source,reslen,minprec,maxprec); depth--; - //fprintf(stderr,"\x1B[32mEXPR LEAVE <<< (%d)\x1B[0m\n",depth); + fprintf(stderr,"\x1B[32mEXPR LEAVE <<< (%d)\x1B[0m\n",depth); return r; } @@ -451,7 +488,7 @@ AST* parse(const char *source,char **errmsg){ cursor+=reslen; const char *src=source+cursor; Token tok=nexttoken(&src,false); - //printtoken(stderr,tok,"parse "); + printtoken(stderr,tok,"parse "); if(tok.type!=TT_ENDSTMT){ ast_free(bl); *errmsg=reportparseerror(source); @@ -518,7 +555,7 @@ static void ast_debug_(FILE *stream,const AST *ast,int indent){ fputc('"',stream); for(int i=0;i<ast->s.len;i++){ if(ast->s.str[i]<32||ast->s.str[i]>126){ - fprintf(stream,"\\x%c%c",hexencode(ast->s.str[i]/16),hexencode(ast->s.str[i]%16)); + fprintf(stream,"\\x%c%c",hexencode((unsigned char)ast->s.str[i]/16),hexencode((unsigned char)ast->s.str[i]%16)); } else fputc(ast->s.str[i],stream); } fputc('"',stream); |