diff options
author | tomsmeding <tom.smeding@gmail.com> | 2016-08-24 21:57:13 +0200 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2016-08-24 21:57:13 +0200 |
commit | 43d1244d4d3f5680c84ed840eb8876292c3fd49c (patch) | |
tree | fff1bb5d05a7ceacfd8aee14da676553a433e7db | |
parent | ba57b2de9e84af94c68a94a5d0be08d5e25ab921 (diff) |
Also run lambda's
-rw-r--r-- | code.lysp | 2 | ||||
-rw-r--r-- | inter_builtins.c | 3 | ||||
-rw-r--r-- | interpreter.c | 42 |
3 files changed, 42 insertions, 5 deletions
@@ -9,5 +9,5 @@ '''''(dit is quoted) 'kaas ;meer commentaar "kazen enzo") - (define 'kaas '(a b) '(print a b)) + (define 'kaas '(a b) '(print (+ a 1) b)) (print (kaas 10 "hoi")))
\ No newline at end of file diff --git a/inter_builtins.c b/inter_builtins.c index 6793c60..ba00935 100644 --- a/inter_builtins.c +++ b/inter_builtins.c @@ -62,14 +62,13 @@ BUILTIN_ARITH_OP(%,remainder,1,floatmod(res,n)); #undef BUILTIN_ARITH_OP -void convert_arguments(AST *ast,int nargs,const char **args){ +static void convert_arguments(AST *ast,int nargs,const char **args){ switch(ast->type){ case AST_LIST: for(int i=0;i<ast->li.len;i++)convert_arguments(ast->li.nodes[i],nargs,args); break; case AST_LAMBDA: - if(ast->la.body)convert_arguments(ast->la.body,nargs,args); break; case AST_WORD:{ diff --git a/interpreter.c b/interpreter.c index fec9087..9f389c1 100644 --- a/interpreter.c +++ b/interpreter.c @@ -147,6 +147,41 @@ InterRet ir_err_c(const char *errstr){ return ir_err(copystring(errstr)); } +static char* replace_arguments(AST *ast,int nargs,AST **args){ + switch(ast->type){ + case AST_LIST: + for(int i=0;i<ast->li.len;i++){ + replace_arguments(ast->li.nodes[i],nargs,args); + } + break; + + case AST_LAMBDAARG:{ + assert(ast->ar.idx>=0); + if(ast->ar.idx>=nargs){ + return copystring("Too few arguments passed to lambda function"); + } + AST *copy=ast_copy(args[ast->ar.idx]); + memcpy(ast,copy,sizeof(AST)); + break; + } + + case AST_QUOTED: + replace_arguments(ast->qu.ast,nargs,args); + break; + + case AST_LAMBDA: + case AST_WORD: + case AST_NUMBER: + case AST_STRING: + case AST_SYMBOL: + break; + + default: + assert(false); + } + return NULL; +} + static InterRet interpret(InterState *is,const AST *ast){ switch(ast->type){ case AST_LIST:{ @@ -169,8 +204,11 @@ static InterRet interpret(InterState *is,const AST *ast){ return ir_err_c("First node in evaluated list not a function"); } -#define NOT_IMPLEMENTED false - if(nodes[0]->la.body)assert(NOT_IMPLEMENTED); + if(nodes[0]->la.body){ + char *errstr=replace_arguments(nodes[0]->la.body,ast->li.len-1,nodes+1); + if(errstr)return ir_err(errstr); + return interpret(is,nodes[0]->la.body); + } InterRet ir=nodes[0]->la.cfunc(is,ast->li.len-1,nodes+1); for(int i=0;i<ast->li.len;i++)ast_free(nodes[i]); |