summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2016-08-30 20:57:12 +0200
committertomsmeding <tom.smeding@gmail.com>2016-08-30 20:57:12 +0200
commitf0b90a58bf587501a1b5814929b3df33bb8e5a94 (patch)
tree11a3a5907f0c06a6e99950ed2f4eb566d8aebdac
parente7b8610da9c93ec8b2578924eecd4861fcb23eab (diff)
While loop
-rw-r--r--code.txt5
-rw-r--r--parser.c34
2 files changed, 37 insertions, 2 deletions
diff --git a/code.txt b/code.txt
index 0c0ed92..2eedda0 100644
--- a/code.txt
+++ b/code.txt
@@ -20,4 +20,9 @@ def main(argc,argv){
} else {
print("rip");
}
+
+ while a < 10 {
+ print(a);
+ a += 1;
+ }
}
diff --git a/parser.c b/parser.c
index 2c55744..6309e65 100644
--- a/parser.c
+++ b/parser.c
@@ -321,7 +321,33 @@ static AST* parseterm(const char *source,int *reslen){
node->i.elseb=elsebody;
break;
}
- if(tok.len==5&&memcmp(tok.str,"while",2)==0)assert(NOT_IMPLEMENTED);
+ if(tok.len==5&&memcmp(tok.str,"while",2)==0){
+ int len;
+ AST *cond=parseexpr(source,&len,0,INT_MAX);
+ if(!cond)return NULL;
+ source+=len;
+ AST *body=parseexpr(source,&len,0,INT_MAX);
+ if(!body){
+ ast_free(cond);
+ return NULL;
+ }
+ source+=len;
+ if(semicolon_needed_after(body)){
+ Token sctok=nexttoken(&source,false);
+ if(sctok.type!=TT_ENDSTMT){
+ ast_free(cond);
+ ast_free(body);
+ return NULL;
+ }
+ DBG(printtoken(stderr,sctok,"afterwhbd"));
+ }
+ node=malloc(sizeof(AST));
+ if(!node)outofmem();
+ node->type=AST_WHILE;
+ node->w.cond=cond;
+ node->w.body=body;
+ break;
+ }
const char *tempsource=source;
Token next=nexttoken(&source,false);
if(next.len==1&&next.str[0]=='('){
@@ -783,7 +809,11 @@ static void ast_debug_(FILE *stream,const AST *ast,int indent){
break;
case AST_WHILE:
- assert(NOT_IMPLEMENTED);
+ fprintf(stream,"while ");
+ ast_debug_(stream,ast->w.cond,indent);
+ fputc(' ',stream);
+ ast_debug_(stream,ast->w.body,indent);
+ if(semicolon_needed_after(ast->w.body))fputc(';',stream);
break;
case AST_FUNC: