summaryrefslogtreecommitdiff
path: root/interpreter.c
diff options
context:
space:
mode:
Diffstat (limited to 'interpreter.c')
-rw-r--r--interpreter.c42
1 files changed, 40 insertions, 2 deletions
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]);