diff --git a/extlib/benz/codegen.c b/extlib/benz/codegen.c index 39b4bfc4..f3d34730 100644 --- a/extlib/benz/codegen.c +++ b/extlib/benz/codegen.c @@ -8,6 +8,7 @@ #include "picrin/proc.h" #include "picrin/lib.h" #include "picrin/macro.h" +#include "picrin/dict.h" #if PIC_NONE_IS_FALSE # define OP_PUSHNONE OP_PUSHFALSE @@ -63,7 +64,7 @@ static analyze_state * new_analyze_state(pic_state *pic) { analyze_state *state; - xh_entry *it; + pic_sym sym; state = pic_alloc(pic, sizeof(analyze_state)); state->pic = pic; @@ -101,8 +102,7 @@ new_analyze_state(pic_state *pic) /* push initial scope */ push_scope(state, pic_nil_value()); - for (it = xh_begin(&pic->globals); it != NULL; it = xh_next(it)) { - pic_sym sym = xh_key(it, pic_sym); + pic_dict_for_each (sym, pic->globals) { xv_push(&state->scope->locals, &sym); } diff --git a/extlib/benz/gc.c b/extlib/benz/gc.c index e209ddda..88d2df5a 100644 --- a/extlib/benz/gc.c +++ b/extlib/benz/gc.c @@ -549,13 +549,13 @@ gc_mark_phase(pic_state *pic) } /* global variables */ - for (it = xh_begin(&pic->globals); it != NULL; it = xh_next(it)) { - gc_mark(pic, xh_val(it, pic_value)); + if (pic->globals) { + gc_mark_object(pic, (struct pic_object *)pic->globals); } /* macro objects */ - for (it = xh_begin(&pic->macros); it != NULL; it = xh_next(it)) { - gc_mark_object(pic, xh_val(it, struct pic_object *)); + if (pic->macros) { + gc_mark_object(pic, (struct pic_object *)pic->macros); } /* error object */ diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index 418cff2c..b424ac65 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -116,8 +116,8 @@ typedef struct { int sym_cnt; int uniq_sym_cnt; - xhash globals; - xhash macros; + struct pic_dict *globals; + struct pic_dict *macros; pic_value libs; xhash attrs; diff --git a/extlib/benz/include/picrin/dict.h b/extlib/benz/include/picrin/dict.h index 8d6077af..cfbd4855 100644 --- a/extlib/benz/include/picrin/dict.h +++ b/extlib/benz/include/picrin/dict.h @@ -19,6 +19,13 @@ struct pic_dict { struct pic_dict *pic_make_dict(pic_state *); +#define pic_dict_for_each(sym, dict) \ + pic_dict_for_each_helper_((sym), PIC_GENSYM(tmp), (dict)) +#define pic_dict_for_each_helper_(var, tmp, dict) \ + for (xh_entry *tmp = xh_begin(&dict->hash); \ + (tmp && ((var = xh_key(tmp, pic_sym)), 1)); \ + tmp = xh_next(tmp)) + pic_value pic_dict_ref(pic_state *, struct pic_dict *, pic_sym); void pic_dict_set(pic_state *, struct pic_dict *, pic_sym, pic_value); void pic_dict_del(pic_state *, struct pic_dict *, pic_sym); diff --git a/extlib/benz/macro.c b/extlib/benz/macro.c index d5604635..7e1c7b36 100644 --- a/extlib/benz/macro.c +++ b/extlib/benz/macro.c @@ -49,18 +49,16 @@ pic_find_rename(pic_state *pic, struct pic_senv *senv, pic_sym sym, pic_sym *ren static void define_macro(pic_state *pic, pic_sym rename, struct pic_proc *mac) { - xh_put_int(&pic->macros, rename, &mac); + pic_dict_set(pic, pic->macros, rename, pic_obj_value(mac)); } static struct pic_proc * find_macro(pic_state *pic, pic_sym rename) { - xh_entry *e; - - if ((e = xh_get_int(&pic->macros, rename)) == NULL) { + if (! pic_dict_has(pic, pic->macros, rename)) { return NULL; } - return xh_val(e, struct pic_proc *); + return pic_proc_ptr(pic_dict_ref(pic, pic->macros, rename)); } static pic_sym diff --git a/extlib/benz/state.c b/extlib/benz/state.c index 3f32e1c5..7271c8e7 100644 --- a/extlib/benz/state.c +++ b/extlib/benz/state.c @@ -10,6 +10,7 @@ #include "picrin/cont.h" #include "picrin/port.h" #include "picrin/error.h" +#include "picrin/dict.h" void pic_init_core(pic_state *); @@ -54,10 +55,10 @@ pic_open(int argc, char *argv[], char **envp) pic->uniq_sym_cnt = 0; /* global variables */ - xh_init_int(&pic->globals, sizeof(pic_value)); + pic->globals = NULL; /* macros */ - xh_init_int(&pic->macros, sizeof(struct pic_macro *)); + pic->macros = NULL; /* attributes */ xh_init_ptr(&pic->attrs, sizeof(struct pic_dict *)); @@ -155,6 +156,10 @@ pic_open(int argc, char *argv[], char **envp) R(rCOND_EXPAND, "cond-expand"); pic_gc_arena_restore(pic, ai); + /* root tables */ + pic->globals = pic_make_dict(pic); + pic->macros = pic_make_dict(pic); + /* root block */ pic->wind = pic_alloc(pic, sizeof(struct pic_winder)); pic->wind->prev = NULL; @@ -198,8 +203,8 @@ pic_close(pic_state *pic) pic->xp = pic->xpbase; pic->arena_idx = 0; pic->err = pic_undef_value(); - xh_clear(&pic->globals); - xh_clear(&pic->macros); + pic->globals = NULL; + pic->macros = NULL; xh_clear(&pic->attrs); pic->features = pic_nil_value(); pic->libs = pic_nil_value(); @@ -222,8 +227,6 @@ pic_close(pic_state *pic) /* free global stacks */ xh_destroy(&pic->syms); - xh_destroy(&pic->globals); - xh_destroy(&pic->macros); xh_destroy(&pic->attrs); /* free GC arena */ diff --git a/extlib/benz/vm.c b/extlib/benz/vm.c index ea4821e2..0e5bc7fd 100644 --- a/extlib/benz/vm.c +++ b/extlib/benz/vm.c @@ -442,7 +442,7 @@ pic_define_noexport(pic_state *pic, const char *name, pic_value val) pic_warn(pic, "redefining global"); } - xh_put_int(&pic->globals, rename, &val); + pic_dict_set(pic, pic->globals, rename, val); } void @@ -464,7 +464,7 @@ pic_ref(pic_state *pic, struct pic_lib *lib, const char *name) pic_errorf(pic, "symbol \"%s\" not defined in library ~s", name, lib->name); } - return xh_val(xh_get_int(&pic->globals, rename), pic_value); + return pic_dict_ref(pic, pic->globals, rename); } void @@ -478,7 +478,7 @@ pic_set(pic_state *pic, struct pic_lib *lib, const char *name, pic_value val) pic_errorf(pic, "symbol \"%s\" not defined in library ~s", name, lib->name); } - xh_put_int(&pic->globals, rename, &val); + pic_dict_set(pic, pic->globals, rename, val); } pic_value @@ -766,19 +766,17 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args) NEXT; } CASE(OP_GREF) { - xh_entry *e; - - if ((e = xh_get_int(&pic->globals, c.u.i)) == NULL) { + if (! pic_dict_has(pic, pic->globals, c.u.i)) { pic_errorf(pic, "logic flaw; reference to uninitialized global variable: %s", pic_symbol_name(pic, c.u.i)); } - PUSH(xh_val(e, pic_value)); + PUSH(pic_dict_ref(pic, pic->globals, c.u.i)); NEXT; } CASE(OP_GSET) { pic_value val; val = POP(); - xh_put_int(&pic->globals, c.u.i, &val); + pic_dict_set(pic, pic->globals, c.u.i, val); NEXT; } CASE(OP_LREF) {