summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2016-08-06 17:17:37 +0200
committertomsmeding <tom.smeding@gmail.com>2016-08-06 17:17:37 +0200
commitad868f8d0fe0e9ab2512f717bf60a01f1b33bf6a (patch)
treec3a904254a1d6c06a27f24801c4ffc8bdabddf56
parent54ddaaaf7692ccec56184cb2c6958a64019b4c6e (diff)
Function calls
-rw-r--r--code.txt7
-rw-r--r--parser.c83
2 files changed, 66 insertions, 24 deletions
diff --git a/code.txt b/code.txt
index 7ccf12d..07e132d 100644
--- a/code.txt
+++ b/code.txt
@@ -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;
diff --git a/parser.c b/parser.c
index 56a014e..2827211 100644
--- a/parser.c
+++ b/parser.c
@@ -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);