lookup global variable by name

This commit is contained in:
Yuichi Nishiwaki 2014-07-27 20:51:59 +09:00
parent c646c4e0ed
commit 38076e738e
6 changed files with 44 additions and 74 deletions

View File

@ -88,10 +88,7 @@ typedef struct {
int sym_cnt;
int uniq_sym_cnt;
xhash global_tbl;
pic_value *globals;
size_t glen, gcapa;
xhash globals;
xhash macros;
pic_value lib_tbl;

View File

@ -26,8 +26,6 @@
/* #define PIC_RESCUE_SIZE 30 */
/* #define PIC_GLOBALS_SIZE 1024 */
/* #define PIC_SYM_POOL_SIZE 128 */
/* #define PIC_IREP_SIZE 8 */
@ -93,10 +91,6 @@
# define PIC_RESCUE_SIZE 30
#endif
#ifndef PIC_GLOBALS_SIZE
# define PIC_GLOBALS_SIZE 1024
#endif
#ifndef PIC_SYM_POOL_SIZE
# define PIC_SYM_POOL_SIZE 128
#endif

View File

@ -100,7 +100,7 @@ new_analyze_state(pic_state *pic)
/* push initial scope */
push_scope(state, pic_nil_value());
xh_begin(&it, &pic->global_tbl);
xh_begin(&it, &pic->globals);
while (xh_next(&it)) {
pic_sym sym = xh_key(it.e, pic_sym);
xv_push(&state->scope->locals, &sym);
@ -291,20 +291,8 @@ static pic_value
analyze_global_var(analyze_state *state, pic_sym sym)
{
pic_state *pic = state->pic;
xh_entry *e;
size_t i;
if ((e = xh_get_int(&pic->global_tbl, sym))) {
i = xh_val(e, size_t);
}
else {
i = pic->glen++;
if (i >= pic->gcapa) {
pic_error(pic, "global table overflow");
}
xh_put_int(&pic->global_tbl, sym, &i);
}
return pic_list2(pic, pic_symbol_value(state->sGREF), pic_int_value(i));
return pic_list2(pic, pic_symbol_value(state->sGREF), pic_sym_value(sym));
}
static pic_value
@ -1096,7 +1084,7 @@ codegen(codegen_state *state, pic_value obj)
sym = pic_sym(pic_car(pic, obj));
if (sym == state->sGREF) {
cxt->code[cxt->clen].insn = OP_GREF;
cxt->code[cxt->clen].u.i = pic_int(pic_list_ref(pic, obj, 1));
cxt->code[cxt->clen].u.i = pic_sym(pic_list_ref(pic, obj, 1));
cxt->clen++;
return;
} else if (sym == state->sCREF) {

View File

@ -575,8 +575,9 @@ gc_mark_phase(pic_state *pic)
}
/* global variables */
for (i = 0; i < pic->glen; ++i) {
gc_mark(pic, pic->globals[i]);
xh_begin(&it, &pic->globals);
while (xh_next(&it)) {
gc_mark(pic, xh_val(it.e, pic_value));
}
/* macro objects */

View File

@ -49,10 +49,7 @@ pic_open(int argc, char *argv[], char **envp)
pic->uniq_sym_cnt = 0;
/* global variables */
xh_init_int(&pic->global_tbl, sizeof(size_t));
pic->globals = (pic_value *)calloc(PIC_GLOBALS_SIZE, sizeof(pic_value));
pic->glen = 0;
pic->gcapa = PIC_GLOBALS_SIZE;
xh_init_int(&pic->globals, sizeof(pic_value));
/* macros */
xh_init_int(&pic->macros, sizeof(struct pic_macro *));
@ -164,7 +161,6 @@ pic_close(pic_state *pic)
pic->ci = pic->cibase;
pic->arena_idx = 0;
pic->err = NULL;
pic->glen = 0;
xh_clear(&pic->macros);
pic->lib_tbl = pic_nil_value();
@ -179,10 +175,9 @@ pic_close(pic_state *pic)
free(pic->cibase);
/* free global stacks */
free(pic->globals);
free(pic->try_jmps);
xh_destroy(&pic->syms);
xh_destroy(&pic->global_tbl);
xh_destroy(&pic->globals);
xh_destroy(&pic->macros);
xh_destroy(&pic->rlabels);

View File

@ -387,52 +387,39 @@ pic_get_args(pic_state *pic, const char *format, ...)
return i - 1;
}
static size_t
static xh_entry *
global_ref(pic_state *pic, const char *name)
{
xh_entry *e;
pic_sym sym, rename;
sym = pic_intern_cstr(pic, name);
if (! pic_find_rename(pic, pic->lib->env, sym, &rename)) {
return SIZE_MAX;
return NULL;
}
if (! (e = xh_get_int(&pic->global_tbl, rename))) {
return SIZE_MAX;
}
return xh_val(e, size_t);
return xh_get_int(&pic->globals, rename);
}
static size_t
global_def(pic_state *pic, const char *name)
static void
global_def(pic_state *pic, const char *name, pic_value val)
{
pic_sym sym, rename;
size_t gidx;
sym = pic_intern_cstr(pic, name);
if ((gidx = global_ref(pic, name)) != SIZE_MAX) {
if (! pic_find_rename(pic, pic->lib->env, sym, &rename)) {
rename = pic_add_rename(pic, pic->lib->env, sym);
} else {
pic_warn(pic, "redefining global");
return gidx;
}
/* register to the senv */
rename = pic_add_rename(pic, pic->lib->env, sym);
/* register to the global table */
gidx = pic->glen++;
if (pic->glen >= pic->gcapa) {
pic_error(pic, "global table overflow");
}
xh_put_int(&pic->global_tbl, rename, &gidx);
return gidx;
xh_put_int(&pic->globals, rename, &val);
}
void
pic_define(pic_state *pic, const char *name, pic_value val)
{
/* push to the global arena */
pic->globals[global_def(pic, name)] = val;
global_def(pic, name, val);
/* export! */
pic_export(pic, pic_intern_cstr(pic, name));
@ -441,26 +428,26 @@ pic_define(pic_state *pic, const char *name, pic_value val)
pic_value
pic_ref(pic_state *pic, const char *name)
{
size_t gid;
xh_entry *e;
gid = global_ref(pic, name);
if (gid == SIZE_MAX) {
e = global_ref(pic, name);
if (e == NULL) {
pic_errorf(pic, "symbol \"%s\" not defined", name);
}
return pic->globals[gid];
return xh_val(e, pic_value);
}
void
pic_set(pic_state *pic, const char *name, pic_value value)
{
size_t gid;
/* void */
/* pic_set(pic_state *pic, const char *name, pic_value value) */
/* { */
/* size_t gid; */
gid = global_ref(pic, name);
if (gid == SIZE_MAX) {
pic_error(pic, "symbol not defined");
}
pic->globals[gid] = value;
}
/* gid = global_ref(pic, name); */
/* if (gid == SIZE_MAX) { */
/* pic_error(pic, "symbol not defined"); */
/* } */
/* pic->globals[gid] = value; */
/* } */
pic_value
pic_funcall(pic_state *pic, const char *name, pic_list args)
@ -675,11 +662,19 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
NEXT;
}
CASE(OP_GREF) {
PUSH(pic->globals[c.u.i]);
xh_entry *e;
if ((e = xh_get_int(&pic->globals, c.u.i)) == NULL) {
pic_errorf(pic, "logic flaw; reference to uninitialized global variable: ~s", pic_symbol_name(pic, c.u.i));
}
PUSH(xh_val(e, pic_value));
NEXT;
}
CASE(OP_GSET) {
pic->globals[c.u.i] = POP();
pic_value val;
val = POP();
xh_put_int(&pic->globals, c.u.i, &val);
NEXT;
}
CASE(OP_LREF) {