aboutsummaryrefslogtreecommitdiffstats
path: root/src/bootstrap/primitives.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-14 17:05:37 +0200
committerBad Diode <bd@badd10de.dev>2021-10-14 17:05:37 +0200
commit530ed15ec941194e661010498cf30b7842710939 (patch)
treeccd1d771350453b59049e06ac224728f321f2b15 /src/bootstrap/primitives.c
parentab23395b1fc88bbc63bef88de3477cc316857ace (diff)
downloadbdl-530ed15ec941194e661010498cf30b7842710939.tar.gz
bdl-530ed15ec941194e661010498cf30b7842710939.zip
Fix lambda and closures
Diffstat (limited to 'src/bootstrap/primitives.c')
-rw-r--r--src/bootstrap/primitives.c55
1 files changed, 24 insertions, 31 deletions
diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c
index 461799e..4ef56d5 100644
--- a/src/bootstrap/primitives.c
+++ b/src/bootstrap/primitives.c
@@ -1,6 +1,7 @@
1#define DEBUG_OBJ(MSG,OBJ) printf((MSG)); display(OBJ); printf("\n");
2
1Object * 3Object *
2eval(Environment* env, Object *root) { 4eval(Environment* env, Object *root) {
3tailcall:
4 switch (root->type) { 5 switch (root->type) {
5 case OBJ_TYPE_ERR: 6 case OBJ_TYPE_ERR:
6 case OBJ_TYPE_PROCEDURE: 7 case OBJ_TYPE_PROCEDURE:
@@ -35,17 +36,26 @@ tailcall:
35 if (val->type == OBJ_TYPE_PROCEDURE) { 36 if (val->type == OBJ_TYPE_PROCEDURE) {
36 return val->proc(env, root->cdr); 37 return val->proc(env, root->cdr);
37 } 38 }
39 if (val->type == OBJ_TYPE_LAMBDA) {
40 goto eval_lambda;
41 }
38 error_push((Error){ 42 error_push((Error){
39 .type = ERR_TYPE_RUNTIME, 43 .type = ERR_TYPE_RUNTIME,
40 .value = ERR_OBJ_NOT_CALLABLE, 44 .value = ERR_OBJ_NOT_CALLABLE,
41 }); 45 });
42 return obj_err; 46 return obj_err;
43 } 47 }
44 Object* lambda = eval(env, root->car); 48 Object* lambda;
49eval_lambda:
50 lambda = eval(env, root->car);
51 if (lambda == obj_err) {
52 return obj_err;
53 }
45 if (lambda->type == OBJ_TYPE_LAMBDA) { 54 if (lambda->type == OBJ_TYPE_LAMBDA) {
46 Object *fun = lambda; 55 Object *fun = lambda;
47 Object *args = root->cdr; 56 Object *args = root->cdr;
48 Object *params = fun->args; 57 Object *params = fun->args;
58 env = env_extend(fun->env, env);
49 while (params != obj_nil) { 59 while (params != obj_nil) {
50 if (args == obj_nil) { 60 if (args == obj_nil) {
51 error_push((Error){ 61 error_push((Error){
@@ -66,12 +76,7 @@ tailcall:
66 }); 76 });
67 return obj_err; 77 return obj_err;
68 } 78 }
69 ssize_t index = env_symbol_index_in_current_env(fun->env, symbol); 79 env_add_or_update_current(env, symbol, value);
70 if (index == -1) {
71 env_add_symbol(fun->env, obj_duplicate(symbol), obj_duplicate(value));
72 } else {
73 fun->env->buf[index].value = obj_duplicate(value);
74 }
75 args = args->cdr; 80 args = args->cdr;
76 params = params->cdr; 81 params = params->cdr;
77 } 82 }
@@ -82,10 +87,14 @@ tailcall:
82 }); 87 });
83 return obj_err; 88 return obj_err;
84 } 89 }
85
86 env = fun->env;
87 root = fun->body; 90 root = fun->body;
88 goto tailcall; 91 while (root->cdr != obj_nil) {
92 if (eval(env, root->car) == obj_err) {
93 return obj_err;
94 };
95 root = root->cdr;
96 }
97 return eval(env, root->car);
89 } 98 }
90 } break; 99 } break;
91 } 100 }
@@ -693,13 +702,7 @@ proc_define(Environment *env, Object *obj) {
693 return obj_err; 702 return obj_err;
694 } 703 }
695 704
696 // Make a copy of the symbol and to make them permanent in the environment. 705 env_add_or_update_current(env, symbol, value);
697 ssize_t index = env_symbol_index_in_current_env(env, symbol);
698 if (index == -1) {
699 env_add_symbol(env, obj_duplicate(symbol), obj_duplicate(value));
700 } else {
701 env->buf[index].value = obj_duplicate(value);
702 }
703 return obj_nil; 706 return obj_nil;
704} 707}
705 708
@@ -727,17 +730,7 @@ proc_set(Environment *env, Object *obj) {
727 return obj_err; 730 return obj_err;
728 } 731 }
729 732
730 ssize_t index = env_symbol_index_in_current_env(env, symbol); 733 return env_update(env, symbol, value);
731 if (index == -1) {
732 error_push((Error){
733 .type = ERR_TYPE_RUNTIME,
734 .value = ERR_SYMBOL_NOT_FOUND,
735 });
736 return obj_err;
737 }
738
739 env->buf[index].value = obj_duplicate(value);
740 return obj_nil;
741} 734}
742 735
743Object * 736Object *
@@ -757,11 +750,11 @@ proc_lambda(Environment *env, Object *obj) {
757 }); 750 });
758 return obj_err; 751 return obj_err;
759 } 752 }
760 Object *body = obj->cdr->car; 753 Object *body = obj->cdr;
761 Object *fun = alloc_object(OBJ_TYPE_LAMBDA); 754 Object *fun = alloc_object(OBJ_TYPE_LAMBDA);
762 fun->args = obj_duplicate(args); 755 fun->args = obj_duplicate(args);
763 fun->body = obj_duplicate(body); 756 fun->body = obj_duplicate(body);
764 fun->env = env_create(env); 757 fun->env = env;
765 return fun; 758 return fun;
766} 759}
767 760