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 * 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; struct pic_irep *irep;
size_t ai = pic_gc_arena_preserve(pic); 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 #endif
/* macroexpand */ /* macroexpand */
obj = pic_macroexpand(pic, obj, lib); obj = pic_macroexpand(pic, obj, env);
#if DEBUG #if DEBUG
fprintf(stdout, "## macroexpand completed\n"); fprintf(stdout, "## macroexpand completed\n");
pic_debug(pic, obj); pic_debug(pic, obj);

View File

@ -5,13 +5,13 @@
#include "picrin.h" #include "picrin.h"
pic_value 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; 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 static pic_value
@ -26,7 +26,7 @@ pic_eval_eval(pic_state *pic)
if (lib == NULL) { if (lib == NULL) {
pic_errorf(pic, "no library found: ~s", spec); pic_errorf(pic, "no library found: ~s", spec);
} }
return pic_eval(pic, program, lib); return pic_eval(pic, program, lib->env);
} }
void 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_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_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_apply_trampoline(pic_state *, struct pic_proc *, pic_value);
pic_value pic_eval(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_lib *); struct pic_proc *pic_compile(pic_state *, pic_value, struct pic_env *);
pic_value pic_macroexpand(pic_state *, pic_value, struct pic_lib *); 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_make_library(pic_state *, pic_value);
struct pic_lib *pic_find_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_proc;
struct pic_port; struct pic_port;
struct pic_error; struct pic_error;
struct pic_env;
/* set aliases to basic types */ /* set aliases to basic types */
typedef pic_value pic_list; typedef pic_value pic_list;

View File

@ -299,7 +299,7 @@ pic_lib_define_library(pic_state *pic)
pic->lib = lib; pic->lib = lib;
for (i = 0; i < argc; ++i) { 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; 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); size_t ai = pic_gc_arena_preserve(pic);
while (! pic_eof_p(form = pic_read(pic, port))) { 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); 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)); val = pic_cadr(pic, pic_cdr(pic, expr));
pic_try { pic_try {
val = pic_eval(pic, val, pic->lib); val = pic_eval(pic, val, env);
} pic_catch { } pic_catch {
pic_errorf(pic, "macroexpand error while definition: %s", pic_errmsg(pic)); 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_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; pic_value v;
#if DEBUG #if DEBUG
@ -414,17 +413,12 @@ pic_macroexpand(pic_state *pic, pic_value expr, struct pic_lib *lib)
puts(""); puts("");
#endif #endif
/* change library for macro-expansion time processing */ /* expansion can fail with non-local exit so env->defer should be cleared every time */
prev = pic->lib; env->defer = pic_nil_value();
pic->lib = lib;
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, env);
macroexpand_deferred(pic, lib->env);
pic->lib = prev;
#if DEBUG #if DEBUG
puts("after expand:"); 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)); form = read(pic, port, next(port));
return pic_eval(pic, form, pic->lib); return pic_eval(pic, form, pic->lib->env);
} }
static pic_value static pic_value