diff --git a/include/picrin/var.h b/include/picrin/var.h index 73afaaba..9926c092 100644 --- a/include/picrin/var.h +++ b/include/picrin/var.h @@ -11,7 +11,7 @@ extern "C" { struct pic_var { PIC_OBJECT_HEADER - pic_value value; + pic_value stack; }; #define pic_var_p(o) (pic_type(o) == PIC_TT_VAR) @@ -21,6 +21,8 @@ struct pic_var *pic_var_new(pic_state *, pic_value); pic_value pic_var_ref(pic_state *, const char *); void pic_var_set(pic_state *, const char *, pic_value); +void pic_var_push(pic_state *, const char *, pic_value); +void pic_var_pop(pic_state *, const char *); #if defined(__cplusplus) } diff --git a/src/gc.c b/src/gc.c index cfaffa60..97532671 100644 --- a/src/gc.c +++ b/src/gc.c @@ -475,7 +475,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) } case PIC_TT_VAR: { struct pic_var *var = (struct pic_var *)obj; - gc_mark(pic, var->value); + gc_mark(pic, var->stack); break; } case PIC_TT_IREP: { diff --git a/src/var.c b/src/var.c index 76d3c297..9cbb00e5 100644 --- a/src/var.c +++ b/src/var.c @@ -3,21 +3,31 @@ */ #include "picrin.h" -#include "picrin/proc.h" #include "picrin/var.h" +#include "picrin/pair.h" static pic_value var_ref(pic_state *pic, struct pic_var *var) { - UNUSED(pic); - return var->value; + return pic_car(pic, var->stack); } static void var_set(pic_state *pic, struct pic_var *var, pic_value value) { - UNUSED(pic); - var->value = value; + pic_set_car(pic, var->stack, value); +} + +static void +var_push(pic_state *pic, struct pic_var *var, pic_value value) +{ + var->stack = pic_cons(pic, value, var->stack); +} + +static void +var_pop(pic_state *pic, struct pic_var *var) +{ + var->stack = pic_cdr(pic, var->stack); } struct pic_var * @@ -26,7 +36,9 @@ pic_var_new(pic_state *pic, pic_value init) struct pic_var *var; var = (struct pic_var *)pic_obj_alloc(pic, sizeof(struct pic_var), PIC_TT_VAR); - var->value = init; + var->stack = pic_nil_value(); + + var_push(pic, var, init); return var; } @@ -61,6 +73,36 @@ pic_var_set(pic_state *pic, const char *name, pic_value value) var_set(pic, var, value); } +void +pic_var_push(pic_state *pic, const char *name, pic_value value) +{ + pic_value v; + struct pic_var *var; + + v = pic_ref(pic, name); + + pic_assert_type(pic, v, var); + + var = pic_var_ptr(v); + + var_push(pic, var, value); +} + +void +pic_var_pop(pic_state *pic, const char *name) +{ + pic_value v; + struct pic_var *var; + + v = pic_ref(pic, name); + + pic_assert_type(pic, v, var); + + var = pic_var_ptr(v); + + var_pop(pic, var); +} + static pic_value pic_var_make_var(pic_state *pic) { @@ -98,7 +140,36 @@ pic_var_var_set(pic_state *pic) var = pic_var_ptr(v); var_set(pic, var, val); + return pic_none_value(); +} +static pic_value +pic_var_var_push(pic_state *pic) +{ + struct pic_var *var; + pic_value v, val; + + pic_get_args(pic, "oo", &v, &val); + + pic_assert_type(pic, v, var); + + var = pic_var_ptr(v); + var_push(pic, var, val); + return pic_none_value(); +} + +static pic_value +pic_var_var_pop(pic_state *pic) +{ + struct pic_var *var; + pic_value v; + + pic_get_args(pic, "o", &v); + + pic_assert_type(pic, v, var); + + var = pic_var_ptr(v); + var_pop(pic, var); return pic_none_value(); } @@ -109,5 +180,7 @@ pic_init_var(pic_state *pic) pic_defun(pic, "make-var", pic_var_make_var); pic_defun(pic, "var-ref", pic_var_var_ref); pic_defun(pic, "var-set!", pic_var_var_set); + pic_defun(pic, "var-push!", pic_var_var_push); + pic_defun(pic, "var-pop!", pic_var_var_pop); } }