change eval interface: eval takes an expression and an environment

macroexpand should be done in the context in which the expansion is
running. As of now I only changed c interface of eval but should change
the scheme interface as well ASAP.
This commit is contained in:
Yuichi Nishiwaki 2015-06-16 01:52:18 +09:00
parent 867afc9b6f
commit 84a3eaee35
8 changed files with 19 additions and 24 deletions

View File

@ -1420,7 +1420,7 @@ pic_codegen(pic_state *pic, pic_value obj)
}
struct pic_proc *
pic_compile(pic_state *pic, pic_value obj, struct pic_lib *lib)
pic_compile(pic_state *pic, pic_value obj, struct pic_env *env)
{
struct pic_irep *irep;
size_t ai = pic_gc_arena_preserve(pic);
@ -1436,7 +1436,7 @@ pic_compile(pic_state *pic, pic_value obj, struct pic_lib *lib)
#endif
/* macroexpand */
obj = pic_macroexpand(pic, obj, lib);
obj = pic_macroexpand(pic, obj, env);
#if DEBUG
fprintf(stdout, "## macroexpand completed\n");
pic_debug(pic, obj);

View File

@ -5,13 +5,13 @@
#include "picrin.h"
pic_value
pic_eval(pic_state *pic, pic_value program, struct pic_lib *lib)
pic_eval(pic_state *pic, pic_value program, struct pic_env *env)
{
struct pic_proc *proc;
proc = pic_compile(pic, program, lib);
proc = pic_compile(pic, program, env);
return pic_apply(pic, proc, pic_nil_value());
return pic_apply0(pic, proc);
}
static pic_value
@ -26,7 +26,7 @@ pic_eval_eval(pic_state *pic)
if (lib == NULL) {
pic_errorf(pic, "no library found: ~s", spec);
}
return pic_eval(pic, program, lib);
return pic_eval(pic, program, lib->env);
}
void

View File

@ -215,9 +215,9 @@ pic_value pic_apply3(pic_state *, struct pic_proc *, pic_value, pic_value, pic_v
pic_value pic_apply4(pic_state *, struct pic_proc *, pic_value, pic_value, pic_value, pic_value);
pic_value pic_apply5(pic_state *, struct pic_proc *, pic_value, pic_value, pic_value, pic_value, pic_value);
pic_value pic_apply_trampoline(pic_state *, struct pic_proc *, pic_value);
pic_value pic_eval(pic_state *, pic_value, struct pic_lib *);
struct pic_proc *pic_compile(pic_state *, pic_value, struct pic_lib *);
pic_value pic_macroexpand(pic_state *, pic_value, struct pic_lib *);
pic_value pic_eval(pic_state *, pic_value, struct pic_env *);
struct pic_proc *pic_compile(pic_state *, pic_value, struct pic_env *);
pic_value pic_macroexpand(pic_state *, pic_value, struct pic_env *);
struct pic_lib *pic_make_library(pic_state *, pic_value);
struct pic_lib *pic_find_library(pic_state *, pic_value);

View File

@ -184,6 +184,7 @@ struct pic_blob;
struct pic_proc;
struct pic_port;
struct pic_error;
struct pic_env;
/* set aliases to basic types */
typedef pic_value pic_list;

View File

@ -299,7 +299,7 @@ pic_lib_define_library(pic_state *pic)
pic->lib = lib;
for (i = 0; i < argc; ++i) {
pic_void(pic_eval(pic, argv[i], pic->lib));
pic_void(pic_eval(pic, argv[i], pic->lib->env));
}
pic->lib = prev;

View File

@ -13,7 +13,7 @@ pic_load_port(pic_state *pic, struct pic_port *port)
size_t ai = pic_gc_arena_preserve(pic);
while (! pic_eof_p(form = pic_read(pic, port))) {
pic_eval(pic, form, pic->lib);
pic_eval(pic, form, pic->lib->env);
pic_gc_arena_restore(pic, ai);
}

View File

@ -299,7 +299,7 @@ macroexpand_defmacro(pic_state *pic, pic_value expr, struct pic_env *env)
val = pic_cadr(pic, pic_cdr(pic, expr));
pic_try {
val = pic_eval(pic, val, pic->lib);
val = pic_eval(pic, val, env);
} pic_catch {
pic_errorf(pic, "macroexpand error while definition: %s", pic_errmsg(pic));
}
@ -403,9 +403,8 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_env *env)
}
pic_value
pic_macroexpand(pic_state *pic, pic_value expr, struct pic_lib *lib)
pic_macroexpand(pic_state *pic, pic_value expr, struct pic_env *env)
{
struct pic_lib *prev;
pic_value v;
#if DEBUG
@ -414,17 +413,12 @@ pic_macroexpand(pic_state *pic, pic_value expr, struct pic_lib *lib)
puts("");
#endif
/* change library for macro-expansion time processing */
prev = pic->lib;
pic->lib = lib;
/* expansion can fail with non-local exit so env->defer should be cleared every time */
env->defer = pic_nil_value();
lib->env->defer = pic_nil_value(); /* the last expansion could fail and leave defer field old */
v = macroexpand(pic, expr, env);
v = macroexpand(pic, expr, lib->env);
macroexpand_deferred(pic, lib->env);
pic->lib = prev;
macroexpand_deferred(pic, env);
#if DEBUG
puts("after expand:");

View File

@ -153,7 +153,7 @@ read_eval(pic_state *pic, struct pic_port *port, int PIC_UNUSED(c))
form = read(pic, port, next(port));
return pic_eval(pic, form, pic->lib);
return pic_eval(pic, form, pic->lib->env);
}
static pic_value