diff options
Diffstat (limited to 'src/bootstrap/primitives.c')
-rw-r--r-- | src/bootstrap/primitives.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c index 35208b0..abb87e7 100644 --- a/src/bootstrap/primitives.c +++ b/src/bootstrap/primitives.c | |||
@@ -2,7 +2,6 @@ | |||
2 | 2 | ||
3 | Object * | 3 | Object * |
4 | eval(Environment* env, Object *root) { | 4 | eval(Environment* env, Object *root) { |
5 | return obj_nil; // DEBUG: gc | ||
6 | switch (root->type) { | 5 | switch (root->type) { |
7 | case OBJ_TYPE_ERR: | 6 | case OBJ_TYPE_ERR: |
8 | case OBJ_TYPE_PROCEDURE: | 7 | case OBJ_TYPE_PROCEDURE: |
@@ -95,7 +94,8 @@ eval_lambda: | |||
95 | }; | 94 | }; |
96 | root = root->cdr; | 95 | root = root->cdr; |
97 | } | 96 | } |
98 | return eval(env, root->car); | 97 | root = eval(env, root->car); |
98 | return root; | ||
99 | } | 99 | } |
100 | } break; | 100 | } break; |
101 | } | 101 | } |
@@ -630,9 +630,20 @@ proc_cons(Environment *env, Object *obj) { | |||
630 | }); | 630 | }); |
631 | return obj_err; | 631 | return obj_err; |
632 | } | 632 | } |
633 | Object *a = eval(env, obj->car); | 633 | Object *head = make_pair(obj_nil, obj_nil); |
634 | Object *b = eval(env, obj->cdr->car); | 634 | push_root(head); |
635 | return make_pair(a, b); | 635 | head->car = eval(env, obj->car); |
636 | if (head->car == obj_err) { | ||
637 | pop_root(); | ||
638 | return obj_err; | ||
639 | } | ||
640 | head->cdr = eval(env, obj->cdr->car); | ||
641 | if (head->cdr == obj_err) { | ||
642 | pop_root(); | ||
643 | return obj_err; | ||
644 | } | ||
645 | pop_root(); | ||
646 | return head; | ||
636 | } | 647 | } |
637 | 648 | ||
638 | Object * | 649 | Object * |
@@ -640,14 +651,28 @@ proc_list(Environment *env, Object *obj) { | |||
640 | if (obj == obj_nil) { | 651 | if (obj == obj_nil) { |
641 | return obj_nil; | 652 | return obj_nil; |
642 | } | 653 | } |
643 | Object *head = make_pair(eval(env, obj->car), obj_nil); | 654 | |
655 | Object *head = make_pair(obj_nil, obj_nil); | ||
656 | push_root(head); | ||
657 | Object *tmp = eval(env, obj->car); | ||
658 | if (tmp == obj_err) { | ||
659 | pop_root(); | ||
660 | return obj_err; | ||
661 | } | ||
662 | head->car = tmp; | ||
644 | Object *curr = head; | 663 | Object *curr = head; |
645 | obj = obj->cdr; | 664 | obj = obj->cdr; |
646 | while (obj != obj_nil) { | 665 | while (obj != obj_nil) { |
647 | curr->cdr = make_pair(eval(env, obj->car), obj_nil); | 666 | tmp = eval(env, obj->car); |
667 | if (tmp == obj_err) { | ||
668 | pop_root(); | ||
669 | return obj_err; | ||
670 | } | ||
671 | curr->cdr = make_pair(tmp, obj_nil); | ||
648 | curr = curr->cdr; | 672 | curr = curr->cdr; |
649 | obj = obj->cdr; | 673 | obj = obj->cdr; |
650 | } | 674 | } |
675 | pop_root(); | ||
651 | return head; | 676 | return head; |
652 | } | 677 | } |
653 | 678 | ||
@@ -753,8 +778,8 @@ proc_lambda(Environment *env, Object *obj) { | |||
753 | } | 778 | } |
754 | Object *body = obj->cdr; | 779 | Object *body = obj->cdr; |
755 | Object *fun = alloc_object(OBJ_TYPE_LAMBDA); | 780 | Object *fun = alloc_object(OBJ_TYPE_LAMBDA); |
756 | fun->params = obj_duplicate(params); | 781 | fun->params = params; |
757 | fun->body = obj_duplicate(body); | 782 | fun->body = body; |
758 | fun->env = env; | 783 | fun->env = env; |
759 | return fun; | 784 | return fun; |
760 | } | 785 | } |
@@ -788,8 +813,8 @@ proc_fun(Environment *env, Object *obj) { | |||
788 | } | 813 | } |
789 | Object *body = obj->cdr->cdr; | 814 | Object *body = obj->cdr->cdr; |
790 | Object *fun = alloc_object(OBJ_TYPE_LAMBDA); | 815 | Object *fun = alloc_object(OBJ_TYPE_LAMBDA); |
791 | fun->params = obj_duplicate(params); | 816 | fun->params = params; |
792 | fun->body = obj_duplicate(body); | 817 | fun->body = body; |
793 | fun->env = env; | 818 | fun->env = env; |
794 | env_add_or_update_current(env, name, fun); | 819 | env_add_or_update_current(env, name, fun); |
795 | return obj_nil; | 820 | return obj_nil; |