diff options
Diffstat (limited to 'src/bootstrap/primitives.c')
-rw-r--r-- | src/bootstrap/primitives.c | 68 |
1 files changed, 64 insertions, 4 deletions
diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c index af8e9da..a3b69f6 100644 --- a/src/bootstrap/primitives.c +++ b/src/bootstrap/primitives.c | |||
@@ -630,15 +630,75 @@ proc_define(Environment *env, Object *obj) { | |||
630 | } | 630 | } |
631 | 631 | ||
632 | // Make a copy of the symbol and to make them permanent in the environment. | 632 | // Make a copy of the symbol and to make them permanent in the environment. |
633 | env_update_symbol(env, obj_duplicate(symbol), obj_duplicate(value)); | 633 | ssize_t index = env_symbol_index_in_current_env(env, symbol); |
634 | if (index == -1) { | ||
635 | env_add_symbol(env, obj_duplicate(symbol), obj_duplicate(value)); | ||
636 | } else { | ||
637 | env->buf[index].value = obj_duplicate(value); | ||
638 | } | ||
639 | return obj_nil; | ||
640 | } | ||
641 | |||
642 | Object * | ||
643 | proc_set(Environment *env, Object *obj) { | ||
644 | if (obj == obj_nil || obj->cdr == obj_nil) { | ||
645 | error_push((Error){ | ||
646 | .type = ERR_TYPE_RUNTIME, | ||
647 | .value = ERR_NOT_ENOUGH_ARGS, | ||
648 | }); | ||
649 | return obj_err; | ||
650 | } | ||
651 | |||
652 | Object *symbol = obj->car; | ||
653 | if (symbol->type != OBJ_TYPE_SYMBOL) { | ||
654 | error_push((Error){ | ||
655 | .type = ERR_TYPE_RUNTIME, | ||
656 | .value = ERR_WRONG_ARG_TYPE, | ||
657 | }); | ||
658 | return obj_err; | ||
659 | } | ||
660 | |||
661 | Object *value = eval(env, obj->cdr->car); | ||
662 | if (value == obj_err) { | ||
663 | return obj_err; | ||
664 | } | ||
665 | |||
666 | ssize_t index = env_symbol_index_in_current_env(env, symbol); | ||
667 | if (index == -1) { | ||
668 | error_push((Error){ | ||
669 | .type = ERR_TYPE_RUNTIME, | ||
670 | .value = ERR_SYMBOL_NOT_FOUND, | ||
671 | }); | ||
672 | return obj_err; | ||
673 | } | ||
674 | |||
675 | env->buf[index].value = obj_duplicate(value); | ||
634 | return obj_nil; | 676 | return obj_nil; |
635 | } | 677 | } |
636 | 678 | ||
679 | |||
680 | // | ||
681 | // Evaluation. | ||
682 | // | ||
683 | |||
684 | Object * | ||
685 | proc_eval(Environment *env, Object *obj) { | ||
686 | if (obj == obj_nil) { | ||
687 | error_push((Error){ | ||
688 | .type = ERR_TYPE_RUNTIME, | ||
689 | .value = ERR_NOT_ENOUGH_ARGS, | ||
690 | }); | ||
691 | return obj_err; | ||
692 | } | ||
693 | return eval(env, eval(env, obj->car)); | ||
694 | } | ||
695 | |||
696 | // TODO: map | ||
697 | // TODO: apply | ||
698 | // TODO: filter | ||
699 | |||
637 | // TODO: fixnum left/right shift, mask, invert | 700 | // TODO: fixnum left/right shift, mask, invert |
638 | // TODO: add primitives for type transforms: string->symbol, symbol->string, etc | 701 | // TODO: add primitives for type transforms: string->symbol, symbol->string, etc |
639 | // TODO: implement support for semi-quotes | 702 | // TODO: implement support for semi-quotes |
640 | // TODO: LAMBDA | 703 | // TODO: LAMBDA |
641 | // TODO: let | 704 | // TODO: let |
642 | // TODO: Revise all instances where we are returning an object, since currently | ||
643 | // we may be returning a pointer to an object instead of a new one. Check also | ||
644 | // on eval function and everytime we do make_xxx(obj). | ||