summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2016-08-24 21:57:13 +0200
committertomsmeding <tom.smeding@gmail.com>2016-08-24 21:57:13 +0200
commit43d1244d4d3f5680c84ed840eb8876292c3fd49c (patch)
treefff1bb5d05a7ceacfd8aee14da676553a433e7db
parentba57b2de9e84af94c68a94a5d0be08d5e25ab921 (diff)
Also run lambda's
-rw-r--r--code.lysp2
-rw-r--r--inter_builtins.c3
-rw-r--r--interpreter.c42
3 files changed, 42 insertions, 5 deletions
diff --git a/code.lysp b/code.lysp
index 17a3d24..c7891e2 100644
--- a/code.lysp
+++ b/code.lysp
@@ -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]);