summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/parser.c b/parser.c
index 7ed64a6..fff3e07 100644
--- a/parser.c
+++ b/parser.c
@@ -341,14 +341,51 @@ static AST* parseterm(const char *source,int *reslen){
case TT_SYM:
if(tok.len==1&&tok.str[0]=='{'){
- assert(NOT_IMPLEMENTED);
+ node=malloc(sizeof(AST));
+ if(!node)outofmem();
+ node->type=AST_BLOCK;
+ int sz=32;
+ node->b.len=0;
+ node->b.exprs=calloc(sz,sizeof(AST*));
+ if(!node->b.exprs)outofmem();
+ int len;
+ int cursor=0;
+ while(true){
+ if(node->b.len==sz){
+ sz*=2;
+ node->b.exprs=realloc(node->b.exprs,sz*sizeof(AST*));
+ if(!node->b.exprs)outofmem();
+ }
+ AST *n=parseexpr(source+cursor,&len,0,INT_MAX);
+ if(!n){
+ ast_free(node);
+ return NULL;
+ }
+ node->b.exprs[node->b.len++]=n;
+ cursor+=len;
+ const char *src=source+cursor;
+ Token tok=nexttoken(&src,false);
+ DBG(printtoken(stderr,tok,"block ; "));
+ if(tok.type!=TT_ENDSTMT){
+ ast_free(node);
+ return NULL;
+ }
+ cursor=src-source;
+ src=source+cursor;
+ tok=nexttoken(&src,false);
+ if(tok.type==TT_SYM&&tok.len==1&&tok.str[0]=='}'){
+ source=src;
+ DBG(printtoken(stderr,tok,"block } "));
+ break;
+ }
+ }
} else if(tok.len==1&&tok.str[0]=='('){
int len;
node=parseexpr(source,&len,0,INT_MAX);
if(!node)return NULL;
source+=len;
Token aftertok=nexttoken(&source,false);
- DBG(printtoken(stderr,aftertok,"braceclose"));
+ DBG(printtoken(stderr,aftertok,"parenclose"));
if(aftertok.type!=TT_SYM||aftertok.len!=1||aftertok.str[0]!=')'){
ast_free(node);
return NULL;
@@ -622,9 +659,9 @@ static void ast_debug_(FILE *stream,const AST *ast,int indent){
break;
case AST_IF:
- fprintf(stream,"if (");
+ fprintf(stream,"if ");
ast_debug_(stream,ast->i.cond,indent);
- fprintf(stream,")\n");
+ fputc('\n',stream);
indent++;
INDENT
ast_debug_(stream,ast->i.thenb,indent);