lookup global variable by name
This commit is contained in:
parent
c646c4e0ed
commit
38076e738e
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
5
src/gc.c
5
src/gc.c
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
75
src/vm.c
75
src/vm.c
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue