use dictionaries for pic->globals and pic->macros

This commit is contained in:
Yuichi Nishiwaki 2015-01-18 21:25:34 +09:00
parent a3db19c1bf
commit 9209722a5b
7 changed files with 34 additions and 28 deletions

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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) {