use dictionaries for pic->globals and pic->macros
This commit is contained in:
parent
a3db19c1bf
commit
9209722a5b
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue