aboutsummaryrefslogtreecommitdiffstats
path: root/src/bootstrap/primitives.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-13 20:46:26 +0200
committerBad Diode <bd@badd10de.dev>2021-10-13 20:46:26 +0200
commitd38ae947933fe26773a810d91fba3b23766d4d92 (patch)
tree036d3b100c19210d5e742c7a3334ca83833e209a /src/bootstrap/primitives.c
parent3ed2c60da6ef2e18d7e273cf39056833c5b41c13 (diff)
downloadbdl-d38ae947933fe26773a810d91fba3b23766d4d92.tar.gz
bdl-d38ae947933fe26773a810d91fba3b23766d4d92.zip
Add set! and eval procedures
Diffstat (limited to 'src/bootstrap/primitives.c')
-rw-r--r--src/bootstrap/primitives.c68
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
642Object *
643proc_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
684Object *
685proc_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).