diff --git a/extlib/benz/bool.c b/extlib/benz/bool.c index 15d857e6..f01e65ac 100644 --- a/extlib/benz/bool.c +++ b/extlib/benz/bool.c @@ -100,8 +100,8 @@ internal_equal_p(pic_state *pic, pic_value x, pic_value y, int depth, khash_t(m) id1 = pic_id_ptr(pic, x); id2 = pic_id_ptr(pic, y); - s1 = pic_find_identifier(pic, pic_obj_value(id1->u.id), id1->env); - s2 = pic_find_identifier(pic, pic_obj_value(id2->u.id), id2->env); + s1 = pic_find_identifier(pic, pic_obj_value(id1->u.id), pic_obj_value(id1->env)); + s2 = pic_find_identifier(pic, pic_obj_value(id2->u.id), pic_obj_value(id2->env)); return pic_eq_p(pic, s1, s2); } diff --git a/extlib/benz/eval.c b/extlib/benz/eval.c index d8b86146..9c2638a1 100644 --- a/extlib/benz/eval.c +++ b/extlib/benz/eval.c @@ -876,8 +876,7 @@ pic_value pic_eval(pic_state *pic, pic_value program, const char *lib) { const char *prev_lib = pic_current_library(pic); - struct pic_env *env; - pic_value r; + pic_value env, r; env = pic_library_environment(pic, lib); diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index d650f8db..d0e75128 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -51,10 +51,8 @@ typedef struct { } pic_value; #endif -struct pic_object; struct pic_port; struct pic_error; -struct pic_env; typedef void *(*pic_allocf)(void *userdata, void *ptr, size_t n); @@ -291,9 +289,9 @@ void pic_close_port(pic_state *, struct pic_port *port); pic_value pic_read(pic_state *, struct pic_port *); pic_value pic_read_cstr(pic_state *, const char *); -pic_value pic_expand(pic_state *, pic_value, struct pic_env *); +pic_value pic_expand(pic_state *, pic_value program, pic_value env); -pic_value pic_eval(pic_state *, pic_value, const char *); +pic_value pic_eval(pic_state *, pic_value program, const char *lib); void pic_load(pic_state *, struct pic_port *); void pic_load_cstr(pic_state *, const char *); @@ -360,7 +358,7 @@ void pic_fprintf(pic_state *, struct pic_port *, const char *, ...); pic_value pic_display(pic_state *, pic_value); pic_value pic_fdisplay(pic_state *, pic_value, xFILE *); -struct pic_env *pic_library_environment(pic_state *, const char *); +pic_value pic_library_environment(pic_state *, const char *); #if DEBUG # define pic_debug(pic,obj) pic_fwrite(pic,obj,xstderr) diff --git a/extlib/benz/include/picrin/object.h b/extlib/benz/include/picrin/object.h index b9861401..38a155bc 100644 --- a/extlib/benz/include/picrin/object.h +++ b/extlib/benz/include/picrin/object.h @@ -17,6 +17,8 @@ KHASH_DECLARE(weak, struct pic_object *, pic_value) unsigned char tt; \ char gc_mark; +struct pic_object; /* defined in gc.c */ + struct pic_basic { PIC_OBJECT_HEADER }; @@ -141,11 +143,11 @@ struct pic_checkpoint { #define pic_weak_ptr(pic, o) ((struct pic_weak *)pic_obj_ptr(o)) #define pic_data_ptr(pic, o) ((struct pic_data *)pic_obj_ptr(o)) #define pic_proc_ptr(pic, o) ((struct pic_proc *)pic_obj_ptr(o)) +#define pic_env_ptr(pic, o) ((struct pic_env *)pic_obj_ptr(o)) #define pic_context_ptr(o) ((struct pic_context *)pic_obj_ptr(o)) #define pic_rec_ptr(v) ((struct pic_record *)pic_obj_ptr(v)) #define pic_error_ptr(v) ((struct pic_error *)pic_obj_ptr(v)) #define pic_port_ptr(v) ((struct pic_port *)pic_obj_ptr(v)) -#define pic_env_ptr(v) ((struct pic_env *)pic_obj_ptr(v)) #define pic_obj_p(pic,v) (pic_vtype(pic,v) == PIC_IVAL_END) #define pic_env_p(pic, v) (pic_type(pic, v) == PIC_TYPE_ENV) @@ -168,16 +170,16 @@ struct pic_object *pic_obj_alloc(pic_state *, size_t, int type); if (tolen - at < e - s) pic_errorf(pic, "invalid range"); \ } while (0) -pic_value pic_make_identifier(pic_state *, pic_value id, struct pic_env *); +pic_value pic_make_identifier(pic_state *, pic_value id, pic_value env); pic_value pic_make_proc(pic_state *, pic_func_t, int, pic_value *); pic_value pic_make_proc_irep(pic_state *, struct pic_irep *, struct pic_context *); struct pic_record *pic_make_rec(pic_state *, pic_value, pic_value); struct pic_error *pic_make_error(pic_state *, const char *, const char *, pic_value); -struct pic_env *pic_make_env(pic_state *, struct pic_env *); +pic_value pic_make_env(pic_state *, pic_value env); -pic_value pic_add_identifier(pic_state *, pic_value id, struct pic_env *); -pic_value pic_put_identifier(pic_state *, pic_value id, pic_value uid, struct pic_env *); -pic_value pic_find_identifier(pic_state *, pic_value id, struct pic_env *); +pic_value pic_add_identifier(pic_state *, pic_value id, pic_value env); +pic_value pic_put_identifier(pic_state *, pic_value id, pic_value uid, pic_value env); +pic_value pic_find_identifier(pic_state *, pic_value id, pic_value env); pic_value pic_id_name(pic_state *, pic_value id); void pic_rope_incref(pic_state *, struct pic_rope *); diff --git a/extlib/benz/lib.c b/extlib/benz/lib.c index 2a5d7d34..a7e9336a 100644 --- a/extlib/benz/lib.c +++ b/extlib/benz/lib.c @@ -31,23 +31,26 @@ get_library(pic_state *pic, const char *lib) return libp; } -static struct pic_env * +static pic_value make_library_env(pic_state *pic, pic_value name) { struct pic_env *env; + pic_value e; env = (struct pic_env *)pic_obj_alloc(pic, sizeof(struct pic_env), PIC_TYPE_ENV); env->up = NULL; env->lib = pic_str_ptr(pic, name); kh_init(env, &env->map); - /* set up default environment */ - pic_put_identifier(pic, pic->sDEFINE_LIBRARY, pic->sDEFINE_LIBRARY, env); - pic_put_identifier(pic, pic->sIMPORT, pic->sIMPORT, env); - pic_put_identifier(pic, pic->sEXPORT, pic->sEXPORT, env); - pic_put_identifier(pic, pic->sCOND_EXPAND, pic->sCOND_EXPAND, env); + e = pic_obj_value(env); - return env; + /* set up default environment */ + pic_put_identifier(pic, pic->sDEFINE_LIBRARY, pic->sDEFINE_LIBRARY, e); + pic_put_identifier(pic, pic->sIMPORT, pic->sIMPORT, e); + pic_put_identifier(pic, pic->sEXPORT, pic->sEXPORT, e); + pic_put_identifier(pic, pic->sCOND_EXPAND, pic->sCOND_EXPAND, e); + + return e; } void @@ -55,8 +58,7 @@ pic_make_library(pic_state *pic, const char *lib) { khash_t(ltable) *h = &pic->ltable; const char *old_lib; - struct pic_env *env; - pic_value name, exports; + pic_value name, env, exports; khiter_t it; int ret; @@ -74,7 +76,7 @@ pic_make_library(pic_state *pic, const char *lib) } kh_val(h, it).name = pic_str_ptr(pic, name); - kh_val(h, it).env = env; + kh_val(h, it).env = pic_env_ptr(pic, env); kh_val(h, it).exports = pic_dict_ptr(pic, exports); if (pic->lib) { @@ -100,10 +102,10 @@ pic_current_library(pic_state *pic) return pic_str(pic, pic_obj_value(pic->lib->name)); } -struct pic_env * +pic_value pic_library_environment(pic_state *pic, const char *lib) { - return get_library(pic, lib)->env; + return pic_obj_value(get_library(pic, lib)->env); } void @@ -116,11 +118,11 @@ pic_import(pic_state *pic, const char *lib) libp = get_library(pic, lib); while (pic_dict_next(pic, pic_obj_value(libp->exports), &it, &name, &realname)) { - uid = pic_find_identifier(pic, realname, libp->env); + uid = pic_find_identifier(pic, realname, pic_obj_value(libp->env)); if (! pic_weak_has(pic, pic->globals, uid) && ! pic_weak_has(pic, pic->macros, uid)) { pic_errorf(pic, "attempted to export undefined variable '~s'", realname); } - pic_put_identifier(pic, name, uid, pic->lib->env); + pic_put_identifier(pic, name, uid, pic_obj_value(pic->lib->env)); } } @@ -192,12 +194,12 @@ pic_lib_library_import(pic_state *pic) realname = pic_dict_ref(pic, pic_obj_value(libp->exports), name); } - uid = pic_find_identifier(pic, realname, libp->env); + uid = pic_find_identifier(pic, realname, pic_obj_value(libp->env)); if (! pic_weak_has(pic, pic->globals, uid) && ! pic_weak_has(pic, pic->macros, uid)) { pic_errorf(pic, "attempted to export undefined variable '~s'", realname); } - pic_put_identifier(pic, alias, uid, pic->lib->env); + pic_put_identifier(pic, alias, uid, pic_obj_value(pic->lib->env)); return pic_undef_value(pic); } diff --git a/extlib/benz/macro.c b/extlib/benz/macro.c index c9f69ec0..99ca4de8 100644 --- a/extlib/benz/macro.c +++ b/extlib/benz/macro.c @@ -7,30 +7,29 @@ KHASH_DEFINE(env, pic_id *, pic_sym *, kh_ptr_hash_func, kh_ptr_hash_equal) -struct pic_env * -pic_make_env(pic_state *pic, struct pic_env *up) +pic_value +pic_make_env(pic_state *pic, pic_value up) { struct pic_env *env; - assert(up != NULL); - env = (struct pic_env *)pic_obj_alloc(pic, sizeof(struct pic_env), PIC_TYPE_ENV); - env->up = up; + env->up = pic_env_ptr(pic, up); env->lib = NULL; kh_init(env, &env->map); - return env; + + return pic_obj_value(env); } pic_value -pic_add_identifier(pic_state *pic, pic_value id, struct pic_env *env) +pic_add_identifier(pic_state *pic, pic_value id, pic_value env) { const char *name; pic_value uid, str; name = pic_str(pic, pic_id_name(pic, id)); - if (env->up == NULL && pic_sym_p(pic, id)) { /* toplevel & public */ - str = pic_strf_value(pic, "%s/%s", pic_str(pic, pic_obj_value(env->lib)), name); + if (pic_env_ptr(pic, env)->up == NULL && pic_sym_p(pic, id)) { /* toplevel & public */ + str = pic_strf_value(pic, "~a/%s", pic_obj_value(pic_env_ptr(pic, env)->lib), name); } else { str = pic_strf_value(pic, ".%s.%d", name, pic->ucnt++); } @@ -40,55 +39,63 @@ pic_add_identifier(pic_state *pic, pic_value id, struct pic_env *env) } pic_value -pic_put_identifier(pic_state *pic, pic_value id, pic_value uid, struct pic_env *env) +pic_put_identifier(pic_state *pic, pic_value id, pic_value uid, pic_value env) { khiter_t it; int ret; - it = kh_put(env, &env->map, pic_id_ptr(pic, id), &ret); - kh_val(&env->map, it) = pic_sym_ptr(pic, uid); + it = kh_put(env, &pic_env_ptr(pic, env)->map, pic_id_ptr(pic, id), &ret); + kh_val(&pic_env_ptr(pic, env)->map, it) = pic_sym_ptr(pic, uid); return uid; } static bool -search_scope(pic_state *pic, pic_value id, struct pic_env *env, pic_value *uid) +search_scope(pic_state *pic, pic_value id, pic_value env, pic_value *uid) { khiter_t it; - it = kh_get(env, &env->map, pic_id_ptr(pic, id)); - if (it == kh_end(&env->map)) { + it = kh_get(env, &pic_env_ptr(pic, env)->map, pic_id_ptr(pic, id)); + if (it == kh_end(&pic_env_ptr(pic, env)->map)) { return false; } - *uid = pic_obj_value(kh_val(&env->map, it)); + *uid = pic_obj_value(kh_val(&pic_env_ptr(pic, env)->map, it)); return true; } static bool -search(pic_state *pic, pic_value id, struct pic_env *env, pic_value *uid) +search(pic_state *pic, pic_value id, pic_value env, pic_value *uid) { - while (env != NULL) { - if (search_scope(pic, id, env, uid)) { + struct pic_env *e; + + while (1) { + if (search_scope(pic, id, env, uid)) return true; - } - env = env->up; + e = pic_env_ptr(pic, env)->up; + if (e == NULL) + break; + env = pic_obj_value(e); } return false; } pic_value -pic_find_identifier(pic_state *pic, pic_value id, struct pic_env *env) +pic_find_identifier(pic_state *pic, pic_value id, pic_value env) { + struct pic_env *e; pic_value uid; while (! search(pic, id, env, &uid)) { if (pic_sym_p(pic, id)) { - while (env->up != NULL) { - env = env->up; + while (1) { + e = pic_env_ptr(pic, env); + if (e->up == NULL) + break; + env = pic_obj_value(e->up); } return pic_add_identifier(pic, id, env); } - env = pic_id_ptr(pic, id)->env; /* do not overwrite id first */ + env = pic_obj_value(pic_id_ptr(pic, id)->env); /* do not overwrite id first */ id = pic_obj_value(pic_id_ptr(pic, id)->u.id); } return uid; @@ -127,18 +134,18 @@ shadow_macro(pic_state *pic, pic_value uid) } } -static pic_value expand(pic_state *, pic_value, struct pic_env *, pic_value); -static pic_value expand_lambda(pic_state *, pic_value, struct pic_env *); +static pic_value expand(pic_state *, pic_value expr, pic_value env, pic_value deferred); +static pic_value expand_lambda(pic_state *, pic_value expr, pic_value env); static pic_value -expand_var(pic_state *pic, pic_value id, struct pic_env *env, pic_value deferred) +expand_var(pic_state *pic, pic_value id, pic_value env, pic_value deferred) { pic_value mac, functor; functor = pic_find_identifier(pic, id, env); if (find_macro(pic, functor, &mac)) { - return expand(pic, pic_call(pic, mac, 2, id, pic_obj_value(env)), env, deferred); + return expand(pic, pic_call(pic, mac, 2, id, env), env, deferred); } return functor; } @@ -150,7 +157,7 @@ expand_quote(pic_state *pic, pic_value expr) } static pic_value -expand_list(pic_state *pic, pic_value obj, struct pic_env *env, pic_value deferred) +expand_list(pic_state *pic, pic_value obj, pic_value env, pic_value deferred) { size_t ai = pic_enter(pic); pic_value x, head, tail; @@ -179,7 +186,7 @@ expand_defer(pic_state *pic, pic_value expr, pic_value deferred) } static void -expand_deferred(pic_state *pic, pic_value deferred, struct pic_env *env) +expand_deferred(pic_state *pic, pic_value deferred, pic_value env) { pic_value defer, val, src, dst, it; @@ -198,10 +205,10 @@ expand_deferred(pic_state *pic, pic_value deferred, struct pic_env *env) } static pic_value -expand_lambda(pic_state *pic, pic_value expr, struct pic_env *env) +expand_lambda(pic_state *pic, pic_value expr, pic_value env) { pic_value formal, body; - struct pic_env *in; + pic_value in; pic_value a, deferred; in = pic_make_env(pic, env); @@ -224,7 +231,7 @@ expand_lambda(pic_state *pic, pic_value expr, struct pic_env *env) } static pic_value -expand_define(pic_state *pic, pic_value expr, struct pic_env *env, pic_value deferred) +expand_define(pic_state *pic, pic_value expr, pic_value env, pic_value deferred) { pic_value id, uid, val; @@ -240,7 +247,7 @@ expand_define(pic_state *pic, pic_value expr, struct pic_env *env, pic_value def } static pic_value -expand_defmacro(pic_state *pic, pic_value expr, struct pic_env *env) +expand_defmacro(pic_state *pic, pic_value expr, pic_value env) { pic_value pic_compile(pic_state *, pic_value); pic_value id, uid, val; @@ -261,7 +268,7 @@ expand_defmacro(pic_state *pic, pic_value expr, struct pic_env *env) } static pic_value -expand_node(pic_state *pic, pic_value expr, struct pic_env *env, pic_value deferred) +expand_node(pic_state *pic, pic_value expr, pic_value env, pic_value deferred) { switch (pic_type(pic, expr)) { case PIC_TYPE_ID: @@ -294,7 +301,7 @@ expand_node(pic_state *pic, pic_value expr, struct pic_env *env, pic_value defer } if (find_macro(pic, functor, &mac)) { - return expand(pic, pic_call(pic, mac, 2, expr, pic_obj_value(env)), env, deferred); + return expand(pic, pic_call(pic, mac, 2, expr, env), env, deferred); } } return expand_list(pic, expr, env, deferred); @@ -305,7 +312,7 @@ expand_node(pic_state *pic, pic_value expr, struct pic_env *env, pic_value defer } static pic_value -expand(pic_state *pic, pic_value expr, struct pic_env *env, pic_value deferred) +expand(pic_state *pic, pic_value expr, pic_value env, pic_value deferred) { size_t ai = pic_enter(pic); pic_value v; @@ -318,7 +325,7 @@ expand(pic_state *pic, pic_value expr, struct pic_env *env, pic_value deferred) } pic_value -pic_expand(pic_state *pic, pic_value expr, struct pic_env *env) +pic_expand(pic_state *pic, pic_value expr, pic_value env) { pic_value v, deferred; diff --git a/extlib/benz/proc.c b/extlib/benz/proc.c index f2b758d2..0a1f20db 100644 --- a/extlib/benz/proc.c +++ b/extlib/benz/proc.c @@ -890,8 +890,7 @@ pic_defvar(pic_state *pic, const char *name, pic_value init, pic_value conv) void pic_define(pic_state *pic, const char *lib, const char *name, pic_value val) { - pic_value sym, uid; - struct pic_env *env; + pic_value sym, uid, env; sym = pic_intern_cstr(pic, name); @@ -907,8 +906,7 @@ pic_define(pic_state *pic, const char *lib, const char *name, pic_value val) pic_value pic_ref(pic_state *pic, const char *lib, const char *name) { - pic_value sym, uid; - struct pic_env *env; + pic_value sym, uid, env; sym = pic_intern_cstr(pic, name); @@ -925,8 +923,7 @@ pic_ref(pic_state *pic, const char *lib, const char *name) void pic_set(pic_state *pic, const char *lib, const char *name, pic_value val) { - pic_value sym, uid; - struct pic_env *env; + pic_value sym, uid, env; sym = pic_intern_cstr(pic, name); diff --git a/extlib/benz/state.c b/extlib/benz/state.c index 987d80ab..065ad248 100644 --- a/extlib/benz/state.c +++ b/extlib/benz/state.c @@ -77,17 +77,17 @@ pic_features(pic_state *pic) return pic->features; } -#define import_builtin_syntax(name) do { \ - pic_value nick, real; \ - nick = pic_intern_lit(pic, "builtin:" name); \ - real = pic_intern_lit(pic, name); \ - pic_put_identifier(pic, nick, real, pic->lib->env); \ +#define import_builtin_syntax(name) do { \ + pic_value nick, real; \ + nick = pic_intern_lit(pic, "builtin:" name); \ + real = pic_intern_lit(pic, name); \ + pic_put_identifier(pic, nick, real, pic_obj_value(pic->lib->env)); \ } while (0) -#define declare_vm_procedure(name) do { \ - pic_value sym; \ - sym = pic_intern_lit(pic, name); \ - pic_put_identifier(pic, sym, sym, pic->lib->env); \ +#define declare_vm_procedure(name) do { \ + pic_value sym; \ + sym = pic_intern_lit(pic, name); \ + pic_put_identifier(pic, sym, sym, pic_obj_value(pic->lib->env)); \ } while (0) void pic_init_bool(pic_state *); diff --git a/extlib/benz/symbol.c b/extlib/benz/symbol.c index f8dabf80..20941f70 100644 --- a/extlib/benz/symbol.c +++ b/extlib/benz/symbol.c @@ -35,13 +35,13 @@ pic_intern(pic_state *pic, pic_value str) } pic_value -pic_make_identifier(pic_state *pic, pic_value base, struct pic_env *env) +pic_make_identifier(pic_state *pic, pic_value base, pic_value env) { pic_id *id; id = (pic_id *)pic_obj_alloc(pic, sizeof(pic_id), PIC_TYPE_ID); id->u.id = pic_id_ptr(pic, base); - id->env = env; + id->env = pic_env_ptr(pic, env); return pic_obj_value(id); } @@ -131,7 +131,7 @@ pic_symbol_make_identifier(pic_state *pic) pic_assert_type(pic, id, id); pic_assert_type(pic, env, env); - return pic_make_identifier(pic, id, pic_env_ptr(env)); + return pic_make_identifier(pic, id, env); } static pic_value