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/proc.h"
|
||||||
#include "picrin/lib.h"
|
#include "picrin/lib.h"
|
||||||
#include "picrin/macro.h"
|
#include "picrin/macro.h"
|
||||||
|
#include "picrin/dict.h"
|
||||||
|
|
||||||
#if PIC_NONE_IS_FALSE
|
#if PIC_NONE_IS_FALSE
|
||||||
# define OP_PUSHNONE OP_PUSHFALSE
|
# define OP_PUSHNONE OP_PUSHFALSE
|
||||||
|
@ -63,7 +64,7 @@ static analyze_state *
|
||||||
new_analyze_state(pic_state *pic)
|
new_analyze_state(pic_state *pic)
|
||||||
{
|
{
|
||||||
analyze_state *state;
|
analyze_state *state;
|
||||||
xh_entry *it;
|
pic_sym sym;
|
||||||
|
|
||||||
state = pic_alloc(pic, sizeof(analyze_state));
|
state = pic_alloc(pic, sizeof(analyze_state));
|
||||||
state->pic = pic;
|
state->pic = pic;
|
||||||
|
@ -101,8 +102,7 @@ new_analyze_state(pic_state *pic)
|
||||||
/* push initial scope */
|
/* push initial scope */
|
||||||
push_scope(state, pic_nil_value());
|
push_scope(state, pic_nil_value());
|
||||||
|
|
||||||
for (it = xh_begin(&pic->globals); it != NULL; it = xh_next(it)) {
|
pic_dict_for_each (sym, pic->globals) {
|
||||||
pic_sym sym = xh_key(it, pic_sym);
|
|
||||||
xv_push(&state->scope->locals, &sym);
|
xv_push(&state->scope->locals, &sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -549,13 +549,13 @@ gc_mark_phase(pic_state *pic)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
for (it = xh_begin(&pic->globals); it != NULL; it = xh_next(it)) {
|
if (pic->globals) {
|
||||||
gc_mark(pic, xh_val(it, pic_value));
|
gc_mark_object(pic, (struct pic_object *)pic->globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* macro objects */
|
/* macro objects */
|
||||||
for (it = xh_begin(&pic->macros); it != NULL; it = xh_next(it)) {
|
if (pic->macros) {
|
||||||
gc_mark_object(pic, xh_val(it, struct pic_object *));
|
gc_mark_object(pic, (struct pic_object *)pic->macros);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error object */
|
/* error object */
|
||||||
|
|
|
@ -116,8 +116,8 @@ typedef struct {
|
||||||
int sym_cnt;
|
int sym_cnt;
|
||||||
int uniq_sym_cnt;
|
int uniq_sym_cnt;
|
||||||
|
|
||||||
xhash globals;
|
struct pic_dict *globals;
|
||||||
xhash macros;
|
struct pic_dict *macros;
|
||||||
pic_value libs;
|
pic_value libs;
|
||||||
xhash attrs;
|
xhash attrs;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,13 @@ struct pic_dict {
|
||||||
|
|
||||||
struct pic_dict *pic_make_dict(pic_state *);
|
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);
|
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_set(pic_state *, struct pic_dict *, pic_sym, pic_value);
|
||||||
void pic_dict_del(pic_state *, struct pic_dict *, pic_sym);
|
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
|
static void
|
||||||
define_macro(pic_state *pic, pic_sym rename, struct pic_proc *mac)
|
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 *
|
static struct pic_proc *
|
||||||
find_macro(pic_state *pic, pic_sym rename)
|
find_macro(pic_state *pic, pic_sym rename)
|
||||||
{
|
{
|
||||||
xh_entry *e;
|
if (! pic_dict_has(pic, pic->macros, rename)) {
|
||||||
|
|
||||||
if ((e = xh_get_int(&pic->macros, rename)) == NULL) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return xh_val(e, struct pic_proc *);
|
return pic_proc_ptr(pic_dict_ref(pic, pic->macros, rename));
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_sym
|
static pic_sym
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "picrin/cont.h"
|
#include "picrin/cont.h"
|
||||||
#include "picrin/port.h"
|
#include "picrin/port.h"
|
||||||
#include "picrin/error.h"
|
#include "picrin/error.h"
|
||||||
|
#include "picrin/dict.h"
|
||||||
|
|
||||||
void pic_init_core(pic_state *);
|
void pic_init_core(pic_state *);
|
||||||
|
|
||||||
|
@ -54,10 +55,10 @@ pic_open(int argc, char *argv[], char **envp)
|
||||||
pic->uniq_sym_cnt = 0;
|
pic->uniq_sym_cnt = 0;
|
||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
xh_init_int(&pic->globals, sizeof(pic_value));
|
pic->globals = NULL;
|
||||||
|
|
||||||
/* macros */
|
/* macros */
|
||||||
xh_init_int(&pic->macros, sizeof(struct pic_macro *));
|
pic->macros = NULL;
|
||||||
|
|
||||||
/* attributes */
|
/* attributes */
|
||||||
xh_init_ptr(&pic->attrs, sizeof(struct pic_dict *));
|
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");
|
R(rCOND_EXPAND, "cond-expand");
|
||||||
pic_gc_arena_restore(pic, ai);
|
pic_gc_arena_restore(pic, ai);
|
||||||
|
|
||||||
|
/* root tables */
|
||||||
|
pic->globals = pic_make_dict(pic);
|
||||||
|
pic->macros = pic_make_dict(pic);
|
||||||
|
|
||||||
/* root block */
|
/* root block */
|
||||||
pic->wind = pic_alloc(pic, sizeof(struct pic_winder));
|
pic->wind = pic_alloc(pic, sizeof(struct pic_winder));
|
||||||
pic->wind->prev = NULL;
|
pic->wind->prev = NULL;
|
||||||
|
@ -198,8 +203,8 @@ pic_close(pic_state *pic)
|
||||||
pic->xp = pic->xpbase;
|
pic->xp = pic->xpbase;
|
||||||
pic->arena_idx = 0;
|
pic->arena_idx = 0;
|
||||||
pic->err = pic_undef_value();
|
pic->err = pic_undef_value();
|
||||||
xh_clear(&pic->globals);
|
pic->globals = NULL;
|
||||||
xh_clear(&pic->macros);
|
pic->macros = NULL;
|
||||||
xh_clear(&pic->attrs);
|
xh_clear(&pic->attrs);
|
||||||
pic->features = pic_nil_value();
|
pic->features = pic_nil_value();
|
||||||
pic->libs = pic_nil_value();
|
pic->libs = pic_nil_value();
|
||||||
|
@ -222,8 +227,6 @@ pic_close(pic_state *pic)
|
||||||
|
|
||||||
/* free global stacks */
|
/* free global stacks */
|
||||||
xh_destroy(&pic->syms);
|
xh_destroy(&pic->syms);
|
||||||
xh_destroy(&pic->globals);
|
|
||||||
xh_destroy(&pic->macros);
|
|
||||||
xh_destroy(&pic->attrs);
|
xh_destroy(&pic->attrs);
|
||||||
|
|
||||||
/* free GC arena */
|
/* free GC arena */
|
||||||
|
|
|
@ -442,7 +442,7 @@ pic_define_noexport(pic_state *pic, const char *name, pic_value val)
|
||||||
pic_warn(pic, "redefining global");
|
pic_warn(pic, "redefining global");
|
||||||
}
|
}
|
||||||
|
|
||||||
xh_put_int(&pic->globals, rename, &val);
|
pic_dict_set(pic, pic->globals, rename, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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);
|
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
|
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);
|
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
|
pic_value
|
||||||
|
@ -766,19 +766,17 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_GREF) {
|
CASE(OP_GREF) {
|
||||||
xh_entry *e;
|
if (! pic_dict_has(pic, pic->globals, c.u.i)) {
|
||||||
|
|
||||||
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));
|
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;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_GSET) {
|
CASE(OP_GSET) {
|
||||||
pic_value val;
|
pic_value val;
|
||||||
|
|
||||||
val = POP();
|
val = POP();
|
||||||
xh_put_int(&pic->globals, c.u.i, &val);
|
pic_dict_set(pic, pic->globals, c.u.i, val);
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_LREF) {
|
CASE(OP_LREF) {
|
||||||
|
|
Loading…
Reference in New Issue