From cac651cd88f8da1e5957b0cc13fa25d79e1887fc Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Tue, 23 Aug 2016 20:58:50 +0200 Subject: Many things - two-letter AST union members - AST_QUOTED - AST_LAMBDA - an interpreter that works - function registering in the interpreter - some builtins --- ast.c | 113 ++++++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 73 insertions(+), 40 deletions(-) (limited to 'ast.c') diff --git a/ast.c b/ast.c index a6f308d..c2ea654 100644 --- a/ast.c +++ b/ast.c @@ -12,27 +12,37 @@ void ast_free(AST *ast){ assert(ast); switch(ast->type){ case AST_LIST: - assert(ast->l.len>=0); - for(int i=0;il.len;i++){ - assert(ast->l.nodes[i]); - ast_free(ast->l.nodes[i]); + assert(ast->li.len>=0); + for(int i=0;ili.len;i++){ + assert(ast->li.nodes[i]); + ast_free(ast->li.nodes[i]); } break; + case AST_LAMBDA: + assert(ast->la.cfunc||ast->la.body); + if(ast->la.body)ast_free(ast->la.body); + break; + case AST_WORD: - assert(ast->w.word); - free(ast->w.word); + assert(ast->wo.word); + free(ast->wo.word); break; case AST_STRING: - assert(ast->S.str); - free(ast->S.str); + assert(ast->st.str); + free(ast->st.str); break; case AST_NUMBER: case AST_SYMBOL: break; + case AST_QUOTED: + assert(ast->qu.ast); + ast_free(ast->qu.ast); + break; + default: assert(false); } @@ -44,32 +54,36 @@ AST* ast_copy(const AST *ast){ assert(ast); switch(ast->type){ case AST_LIST:{ - assert(ast->l.len>=0); - assert(ast->l.nodes); - AST **nodes=malloc(ast->l.len,AST*); - for(int i=0;il.len;i++)nodes[i]=ast_copy(ast->l.nodes[i]); - AST *l=ast_list(ast->l.len,nodes); - l->l.quoted=ast->l.quoted; - return l; + assert(ast->li.len>=0); + assert(ast->li.nodes); + AST **nodes=malloc(ast->li.len,AST*); + for(int i=0;ili.len;i++)nodes[i]=ast_copy(ast->li.nodes[i]); + return ast_list(ast->li.len,nodes); } + case AST_LAMBDA: + return ast_lambda(ast->la.cfunc,ast->la.body?ast_copy(ast->la.body):NULL); + case AST_WORD: - assert(ast->w.word); - return ast_word(copystring(ast->w.word)); + assert(ast->wo.word); + return ast_word(copystring(ast->wo.word)); case AST_NUMBER: - return ast_number(ast->n.num); + return ast_number(ast->nu.num); case AST_STRING: - return ast_string(copybufasstring(ast->S.str,ast->S.len),ast->S.len); + return ast_string(copybufasstring(ast->st.str,ast->st.len),ast->st.len); case AST_SYMBOL:{ - assert(ast->s.name); - AST *sym=ast_symbol(ast->s.name); - sym->s.symid=ast->s.symid; + assert(ast->sy.name); + AST *sym=ast_symbol(ast->sy.name); + sym->sy.symid=ast->sy.symid; return sym; } + case AST_QUOTED: + return ast_quoted(ast_copy(ast->qu.ast)); + default: assert(false); } @@ -114,22 +128,21 @@ static void ast_stringify_(const AST *ast,Buffer *buf){ assert(buf); switch(ast->type){ case AST_LIST: - if(ast->l.quoted)buf_append(buf,"'",1); buf_append(buf,"(",1); - for(int i=0;il.len;i++){ + for(int i=0;ili.len;i++){ if(i!=0)buf_append(buf," ",1); - ast_stringify_(ast->l.nodes[i],buf); + ast_stringify_(ast->li.nodes[i],buf); } buf_append(buf,")",1); break; case AST_WORD: - buf_append(buf,ast->w.word,strlen(ast->w.word)); + buf_append(buf,ast->wo.word,strlen(ast->wo.word)); break; case AST_NUMBER:{ char *s; - int len=asprintf(&s,"%g",ast->n.num); + int len=asprintf(&s,"%g",ast->nu.num); if(!s)outofmem(); buf_append(buf,s,len); free(s); @@ -138,8 +151,8 @@ static void ast_stringify_(const AST *ast,Buffer *buf){ case AST_STRING:{ buf_append(buf,"\"",1); - const char *str=ast->S.str; - for(int i=0;iS.len;i++){ + const char *str=ast->st.str; + for(int i=0;ist.len;i++){ if(str[i]>=32&&str[i]<=126)buf_append(buf,str+i,1); else switch(str[i]){ case '\n': buf_append(buf,"\\n",2); break; @@ -164,7 +177,12 @@ static void ast_stringify_(const AST *ast,Buffer *buf){ case AST_SYMBOL: buf_append(buf,"'",1); - buf_append(buf,ast->s.name,strlen(ast->s.name)); + buf_append(buf,ast->sy.name,strlen(ast->sy.name)); + break; + + case AST_QUOTED: + buf_append(buf,"'",1); + ast_stringify_(ast->qu.ast,buf); break; default: @@ -185,10 +203,17 @@ AST* ast_list(int len,AST **nodes){ assert(nodes); AST *ast=malloc(1,AST); ast->type=AST_LIST; - ast->l.len=len; - ast->l.nodes=malloc(len,AST*); - memcpy(ast->l.nodes,nodes,len*sizeof(AST*)); - ast->l.quoted=false; + ast->li.len=len; + ast->li.nodes=nodes; + return ast; +} + +AST* ast_lambda(lambdafunc_t cfunc,AST *body){ + assert(cfunc||body); + AST *ast=malloc(1,AST); + ast->type=AST_LAMBDA; + ast->la.cfunc=cfunc; + ast->la.body=body; return ast; } @@ -196,22 +221,22 @@ AST* ast_word(char *word){ assert(word); AST *ast=malloc(1,AST); ast->type=AST_WORD; - ast->w.word=word; + ast->wo.word=word; return ast; } AST* ast_number(double num){ AST *ast=malloc(1,AST); ast->type=AST_NUMBER; - ast->n.num=num; + ast->nu.num=num; return ast; } AST* ast_string(char *str,int len){ AST *ast=malloc(1,AST); ast->type=AST_STRING; - ast->S.str=str; - ast->S.len=len; + ast->st.str=str; + ast->st.len=len; return ast; } @@ -219,7 +244,15 @@ AST* ast_symbol(char *name){ assert(name); AST *ast=malloc(1,AST); ast->type=AST_SYMBOL; - ast->s.name=name; - ast->s.symid=-1; + ast->sy.name=name; + ast->sy.symid=-1; + return ast; +} + +AST* ast_quoted(AST *contents){ + assert(contents); + AST *ast=malloc(1,AST); + ast->type=AST_QUOTED; + ast->qu.ast=contents; return ast; } -- cgit v1.2.3-54-g00ecf