From 9c278889fc8899fd80d75183ac91ee80290d3afb Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 01:17:05 +0900 Subject: [PATCH 01/16] add partial apply funciton --- include/picrin/proc.h | 2 ++ src/proc.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/picrin/proc.h b/include/picrin/proc.h index 11c4ff82..7bf15927 100644 --- a/include/picrin/proc.h +++ b/include/picrin/proc.h @@ -43,6 +43,8 @@ int pic_proc_cv_size(pic_state *, struct pic_proc *); pic_value pic_proc_cv_ref(pic_state *, struct pic_proc *, size_t); void pic_proc_cv_set(pic_state *, struct pic_proc *, size_t, pic_value); +struct pic_proc *pic_papply(pic_state *, struct pic_proc *, pic_value); + #if defined(__cplusplus) } #endif diff --git a/src/proc.c b/src/proc.c index ca4955c1..bb085031 100644 --- a/src/proc.c +++ b/src/proc.c @@ -72,6 +72,36 @@ pic_proc_cv_set(pic_state *pic, struct pic_proc *proc, size_t i, pic_value v) proc->env->values[i] = v; } +static pic_value +papply_call(pic_state *pic) +{ + size_t argc; + pic_value *argv, arg, arg_list; + struct pic_proc *proc; + + pic_get_args(pic, "*", &argc, &argv); + + proc = pic_proc_ptr(pic_proc_cv_ref(pic, pic_get_proc(pic), 0)); + arg = pic_proc_cv_ref(pic, pic_get_proc(pic), 1); + + arg_list = pic_list_by_array(pic, argc, argv); + arg_list = pic_cons(pic, arg, arg_list); + return pic_apply(pic, proc, arg_list); +} + +struct pic_proc * +pic_papply(pic_state *pic, struct pic_proc *proc, pic_value arg) +{ + struct pic_proc *pa_proc; + + pa_proc = pic_proc_new(pic, papply_call); + pic_proc_cv_init(pic, pa_proc, 2); + pic_proc_cv_set(pic, pa_proc, 0, pic_obj_value(proc)); + pic_proc_cv_set(pic, pa_proc, 1, arg); + + return pa_proc; +} + static pic_value pic_proc_proc_p(pic_state *pic) { From ac17dc057684e1ab286711565b242721c00972d0 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 10:37:08 +0900 Subject: [PATCH 02/16] update xhash --- extlib/xhash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extlib/xhash b/extlib/xhash index 44c9f36d..f8599bdc 160000 --- a/extlib/xhash +++ b/extlib/xhash @@ -1 +1 @@ -Subproject commit 44c9f36dca1bbc2b158c812359a7e9d5a5f7e9bb +Subproject commit f8599bdc3978fd3d824a2e9240b3e7b5e096f926 From 527f46480a9746aedbc37757738333055631bc1b Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 10:39:20 +0900 Subject: [PATCH 03/16] rename symbols before macro lookup --- include/picrin.h | 2 + include/picrin/macro.h | 29 +---- src/codegen.c | 10 +- src/gc.c | 17 ++- src/macro.c | 266 +++++++++++++++++++---------------------- src/state.c | 7 ++ 6 files changed, 149 insertions(+), 182 deletions(-) diff --git a/include/picrin.h b/include/picrin.h index db4b823d..ccb7e88a 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -107,6 +107,8 @@ typedef struct { pic_value *globals; size_t glen, gcapa; + xhash *macros; + pic_value lib_tbl; struct pic_lib *lib; diff --git a/include/picrin/macro.h b/include/picrin/macro.h index 3b2f4ab9..2672876b 100644 --- a/include/picrin/macro.h +++ b/include/picrin/macro.h @@ -11,29 +11,12 @@ extern "C" { struct pic_senv { PIC_OBJECT_HEADER + xhash *name; struct pic_senv *up; - /* positive for variables, negative for macros (bitwise-not) */ - xhash *tbl; - struct pic_syntax **stx; - size_t xlen, xcapa; }; struct pic_syntax { PIC_OBJECT_HEADER - enum { - PIC_STX_DEFINE, - PIC_STX_SET, - PIC_STX_QUOTE, - PIC_STX_LAMBDA, - PIC_STX_IF, - PIC_STX_BEGIN, - PIC_STX_MACRO, - PIC_STX_DEFMACRO, - PIC_STX_DEFSYNTAX, - PIC_STX_DEFLIBRARY, - PIC_STX_IMPORT, - PIC_STX_EXPORT - } kind; pic_sym sym; struct pic_proc *macro; struct pic_senv *senv; @@ -55,12 +38,12 @@ struct pic_sc { #define pic_senv_p(v) (pic_type(v) == PIC_TT_SENV) #define pic_senv_ptr(v) ((struct pic_senv *)pic_ptr(v)) -struct pic_senv *pic_null_syntactic_env(pic_state *pic); -struct pic_senv *pic_minimal_syntactic_env(pic_state *pic); -struct pic_senv *pic_core_syntactic_env(pic_state *pic); +struct pic_senv *pic_null_syntactic_env(pic_state *); +struct pic_senv *pic_minimal_syntactic_env(pic_state *); +struct pic_senv *pic_core_syntactic_env(pic_state *); -struct pic_syntax *pic_syntax_new(pic_state *, int kind, pic_sym sym); -struct pic_syntax *pic_syntax_new_macro(pic_state *, pic_sym, struct pic_proc *, struct pic_senv *senv); +struct pic_syntax *pic_syntax_new(pic_state *, pic_sym, struct pic_proc *); +struct pic_syntax *pic_syntax_new_macro(pic_state *, pic_sym, struct pic_proc *, struct pic_senv *); #if defined(__cplusplus) } diff --git a/src/codegen.c b/src/codegen.c index 7bfa7805..195d3b6d 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -98,9 +98,9 @@ static void pop_scope(analyze_state *); state->slot = pic_intern_cstr(pic, name); \ } while (0) -#define register_renamed_symbol(pic, state, slot, lib, name) do { \ - xh_entry *e; \ - if (! (e = xh_get_int(lib->senv->tbl, pic_intern_cstr(pic, name)))) \ +#define register_renamed_symbol(pic, state, slot, lib, id) do { \ + xh_entry *e; \ + if (! (e = xh_get_int(lib->senv->name, pic_intern_cstr(pic, id)))) \ pic_error(pic, "internal error! native VM procedure not found"); \ state->slot = e->val; \ } while (0) @@ -1445,7 +1445,7 @@ global_ref(pic_state *pic, const char *name) pic_sym sym; sym = pic_intern_cstr(pic, name); - if (! (e = xh_get_int(pic->lib->senv->tbl, sym))) { + if (! (e = xh_get_int(pic->lib->senv->name, sym))) { return -1; } assert(e->val >= 0); @@ -1470,7 +1470,7 @@ global_def(pic_state *pic, const char *name) gsym = pic_gensym(pic, sym); /* register to the senv */ - xh_put_int(pic->lib->senv->tbl, sym, gsym); + xh_put_int(pic->lib->senv->name, sym, gsym); /* register to the global table */ gidx = pic->glen++; diff --git a/src/gc.c b/src/gc.c index 62cbd76d..c9ca85ef 100644 --- a/src/gc.c +++ b/src/gc.c @@ -404,13 +404,6 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) if (senv->up) { gc_mark_object(pic, (struct pic_object *)senv->up); } - if (senv->stx) { - size_t i; - - for (i = 0; i < senv->xlen; ++i) { - gc_mark_object(pic, (struct pic_object *)senv->stx[i]); - } - } break; } case PIC_TT_SC: { @@ -476,6 +469,7 @@ gc_mark_phase(pic_state *pic) pic_callinfo *ci; size_t i; int j; + xh_iter it; /* block */ gc_mark_block(pic, pic->blk); @@ -512,6 +506,11 @@ gc_mark_phase(pic_state *pic) gc_mark(pic, pic->globals[i]); } + /* macro objects */ + for (xh_begin(pic->macros, &it); ! xh_isend(&it); xh_next(&it)) { + gc_mark_object(pic, (struct pic_object *)it.e->val); + } + /* library table */ gc_mark(pic, pic->lib_tbl); } @@ -565,9 +564,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj) } case PIC_TT_SENV: { struct pic_senv *senv = (struct pic_senv *)obj; - xh_destroy(senv->tbl); - if (senv->stx) - pic_free(pic, senv->stx); + xh_destroy(senv->name); break; } case PIC_TT_SYNTAX: { diff --git a/src/macro.c b/src/macro.c index a631cc16..12e7cc92 100644 --- a/src/macro.c +++ b/src/macro.c @@ -20,19 +20,14 @@ pic_null_syntactic_env(pic_state *pic) senv = (struct pic_senv *)pic_obj_alloc(pic, sizeof(struct pic_senv), PIC_TT_SENV); senv->up = NULL; - senv->tbl = xh_new_int(); - senv->stx = (struct pic_syntax **)pic_calloc(pic, PIC_MACROS_SIZE, sizeof(struct pic_syntax *)); - senv->xlen = 0; - senv->xcapa = PIC_MACROS_SIZE; + senv->name = xh_new_int(); return senv; } -#define register_core_syntax(pic,senv,kind,name) do { \ - pic_sym sym = pic_intern_cstr(pic, name); \ - senv->stx[senv->xlen] = pic_syntax_new(pic, kind, sym); \ - xh_put_int(senv->tbl, sym, ~senv->xlen); \ - senv->xlen++; \ +#define register_core_syntax(pic,senv,id) do { \ + pic_sym sym = pic_intern_cstr(pic, id); \ + xh_put_int(senv->name, sym, sym); \ } while (0) struct pic_senv * @@ -40,9 +35,9 @@ pic_minimal_syntactic_env(pic_state *pic) { struct pic_senv *senv = pic_null_syntactic_env(pic); - register_core_syntax(pic, senv, PIC_STX_DEFLIBRARY, "define-library"); - register_core_syntax(pic, senv, PIC_STX_IMPORT, "import"); - register_core_syntax(pic, senv, PIC_STX_EXPORT, "export"); + register_core_syntax(pic, senv, "define-library"); + register_core_syntax(pic, senv, "import"); + register_core_syntax(pic, senv, "export"); return senv; } @@ -52,14 +47,14 @@ pic_core_syntactic_env(pic_state *pic) { struct pic_senv *senv = pic_minimal_syntactic_env(pic); - register_core_syntax(pic, senv, PIC_STX_DEFINE, "define"); - register_core_syntax(pic, senv, PIC_STX_SET, "set!"); - register_core_syntax(pic, senv, PIC_STX_QUOTE, "quote"); - register_core_syntax(pic, senv, PIC_STX_LAMBDA, "lambda"); - register_core_syntax(pic, senv, PIC_STX_IF, "if"); - register_core_syntax(pic, senv, PIC_STX_BEGIN, "begin"); - register_core_syntax(pic, senv, PIC_STX_DEFMACRO, "define-macro"); - register_core_syntax(pic, senv, PIC_STX_DEFSYNTAX, "define-syntax"); + register_core_syntax(pic, senv, "define"); + register_core_syntax(pic, senv, "set!"); + register_core_syntax(pic, senv, "quote"); + register_core_syntax(pic, senv, "lambda"); + register_core_syntax(pic, senv, "if"); + register_core_syntax(pic, senv, "begin"); + register_core_syntax(pic, senv, "define-macro"); + register_core_syntax(pic, senv, "define-syntax"); return senv; } @@ -81,10 +76,7 @@ new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) senv = (struct pic_senv *)pic_obj_alloc(pic, sizeof(struct pic_senv), PIC_TT_SENV); senv->up = up; - senv->tbl = xh_new_int(); - senv->stx = NULL; - senv->xlen = 0; - senv->xcapa = 0; + senv->name = xh_new_int(); for (a = formals; pic_pair_p(a); a = pic_cdr(pic, a)) { pic_value v = pic_car(pic, a); @@ -96,14 +88,14 @@ new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) pic_error(pic, "syntax error"); } sym = pic_sym(v); - xh_put_int(senv->tbl, sym, pic_gensym(pic, sym)); + xh_put_int(senv->name, sym, pic_gensym(pic, sym)); } if (! pic_sym_p(a)) { a = macroexpand(pic, a, up); } if (pic_sym_p(a)) { sym = pic_sym(a); - xh_put_int(senv->tbl, sym, pic_gensym(pic, sym)); + xh_put_int(senv->name, sym, pic_gensym(pic, sym)); } else if (! pic_nil_p(a)) { pic_error(pic, "syntax error"); @@ -112,15 +104,14 @@ new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) } struct pic_syntax * -pic_syntax_new(pic_state *pic, int kind, pic_sym sym) +pic_syntax_new(pic_state *pic, pic_sym sym, struct pic_proc *macro) { struct pic_syntax *stx; stx = (struct pic_syntax *)pic_obj_alloc(pic, sizeof(struct pic_syntax), PIC_TT_SYNTAX); - stx->kind = kind; stx->sym = sym; - stx->macro = NULL; stx->senv = NULL; + stx->macro = macro; return stx; } @@ -130,10 +121,9 @@ pic_syntax_new_macro(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct struct pic_syntax *stx; stx = (struct pic_syntax *)pic_obj_alloc(pic, sizeof(struct pic_syntax), PIC_TT_SYNTAX); - stx->kind = PIC_STX_MACRO; stx->sym = sym; - stx->macro = macro; stx->senv = mac_env; + stx->macro = macro; return stx; } @@ -160,20 +150,6 @@ pic_identifier_p(pic_value obj) return false; } -static pic_value -strip(pic_state *pic, pic_value expr) -{ - if (pic_sc_p(expr)) { - return strip(pic, pic_sc(expr)->expr); - } - else if (pic_pair_p(expr)) { - return pic_cons(pic, - strip(pic, pic_car(pic, expr)), - strip(pic, pic_cdr(pic, expr))); - } - return expr; -} - void pic_import(pic_state *pic, pic_value spec) { @@ -185,30 +161,19 @@ pic_import(pic_state *pic, pic_value spec) pic_error(pic, "library not found"); } for (xh_begin(lib->exports, &it); ! xh_isend(&it); xh_next(&it)) { + #if DEBUG if (it.e->val >= 0) { - printf("* importing %s as %s\n", pic_symbol_name(pic, (long)it.e->key), pic_symbol_name(pic, it.e->val)); + printf("* importing %s as %s\n", + pic_symbol_name(pic, (long)it.e->key), + pic_symbol_name(pic, it.e->val)); } else { printf("* importing %s\n", pic_symbol_name(pic, (long)it.e->key)); } #endif - if (it.e->val >= 0) { - xh_put_int(pic->lib->senv->tbl, (long)it.e->key, it.e->val); - } - else { /* syntax object */ - size_t idx; - struct pic_senv *senv = pic->lib->senv; - idx = senv->xlen; - if (idx >= senv->xcapa) { - pic_abort(pic, "macro table overflow"); - } - /* bring macro object from imported lib */ - senv->stx[idx] = lib->senv->stx[~it.e->val]; - xh_put_int(senv->tbl, (long)it.e->key, ~idx); - senv->xlen++; - } + xh_put_int(pic->lib->senv->name, (long)it.e->key, it.e->val); } } @@ -217,7 +182,7 @@ pic_export(pic_state *pic, pic_sym sym) { xh_entry *e; - e = xh_get_int(pic->lib->senv->tbl, sym); + e = xh_get_int(pic->lib->senv->name, sym); if (! e) { pic_error(pic, "symbol not defined"); } @@ -225,29 +190,22 @@ pic_export(pic_state *pic, pic_sym sym) } static void -defsyntax(pic_state *pic, const char *name, struct pic_proc *macro, struct pic_senv *mac_env) +defsyntax(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv *mac_env) { - pic_sym sym; struct pic_syntax *stx; - struct pic_senv *global_senv = pic->lib->senv; - size_t idx; + pic_sym uniq; - sym = pic_intern_cstr(pic, name); + uniq = pic_gensym(pic, sym); stx = pic_syntax_new_macro(pic, sym, macro, mac_env); - idx = global_senv->xlen; - if (idx >= global_senv->xcapa) { - pic_abort(pic, "macro table overflow"); - } - global_senv->stx[idx] = stx; - xh_put_int(global_senv->tbl, sym, ~idx); - global_senv->xlen++; + xh_put_int(pic->lib->senv->name, sym, uniq); + xh_put_int(pic->macros, uniq, (long)stx); } static void defmacro(pic_state *pic, const char *name, struct pic_proc *macro) { - defsyntax(pic, name, macro, NULL); + defsyntax(pic, pic_intern_cstr(pic, name), macro, NULL); } void @@ -259,6 +217,28 @@ pic_defmacro(pic_state *pic, const char *name, struct pic_proc *macro) pic_export(pic, pic_intern_cstr(pic, name)); } +static pic_sym +symbol_rename(pic_state *pic, pic_sym sym, struct pic_senv *senv) +{ + xh_entry *e; + pic_sym uniq; + + if (! pic_interned_p(pic, sym)) { + return sym; + } + while (true) { + if ((e = xh_get_int(senv->name, sym)) != NULL) { + return (pic_sym)e->val; + } + if (! senv->up) + break; + senv = senv->up; + } + uniq = pic_gensym(pic, sym); + xh_put_int(senv->name, sym, uniq); + return uniq; +} + static pic_value macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) { @@ -278,34 +258,17 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) return macroexpand(pic, sc->expr, sc->senv); } case PIC_TT_SYMBOL: { - xh_entry *e; - pic_sym uniq; - - if (! pic_interned_p(pic, pic_sym(expr))) { - return expr; - } - while (true) { - if ((e = xh_get_int(senv->tbl, pic_sym(expr))) != NULL) { - if (e->val >= 0) - return pic_symbol_value(e->val); - else - return pic_obj_value(senv->stx[~e->val]); - } - if (! senv->up) - break; - senv = senv->up; - } - uniq = pic_gensym(pic, pic_sym(expr)); - xh_put_int(senv->tbl, pic_sym(expr), uniq); - return pic_symbol_value(uniq); + return pic_symbol_value(symbol_rename(pic, pic_sym(expr), senv)); } case PIC_TT_PAIR: { pic_value car, v; + xh_entry *e; car = macroexpand(pic, pic_car(pic, expr), senv); - if (pic_syntax_p(car)) { - switch (pic_syntax(car)->kind) { - case PIC_STX_DEFLIBRARY: { + if (pic_sym_p(car)) { + pic_sym tag = pic_sym(car); + + if (tag == pic->sDEFINE_LIBRARY) { struct pic_lib *prev = pic->lib; if (pic_length(pic, expr) < 2) { @@ -335,14 +298,15 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) return pic_none_value(); } - case PIC_STX_IMPORT: { + + else if (tag == pic->sIMPORT) { pic_value spec; pic_for_each (spec, pic_cdr(pic, expr)) { pic_import(pic, spec); } return pic_none_value(); } - case PIC_STX_EXPORT: { + else if (tag == pic->sEXPORT) { pic_value spec; pic_for_each (spec, pic_cdr(pic, expr)) { if (! pic_sym_p(spec)) { @@ -353,7 +317,8 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) } return pic_none_value(); } - case PIC_STX_DEFSYNTAX: { + + else if (tag == pic->sDEFINE_SYNTAX) { pic_value var, val; struct pic_proc *proc; @@ -361,7 +326,7 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) pic_error(pic, "syntax error"); } - var = strip(pic, pic_cadr(pic, expr)); + var = pic_cadr(pic, expr); if (! pic_sym_p(var)) { pic_error(pic, "syntax error"); } @@ -378,12 +343,13 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) abort(); } assert(pic_proc_p(v)); - defsyntax(pic, pic_symbol_name(pic, pic_sym(var)), pic_proc_ptr(v), senv); + defsyntax(pic, pic_sym(var), pic_proc_ptr(v), senv); pic_gc_arena_restore(pic, ai); return pic_none_value(); } - case PIC_STX_DEFMACRO: { + + else if (tag == pic->sDEFINE_MACRO) { pic_value var, val; struct pic_proc *proc; @@ -425,36 +391,11 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) pic_gc_arena_restore(pic, ai); return pic_none_value(); } - case PIC_STX_MACRO: { - if (pic_syntax(car)->senv == NULL) { /* legacy macro */ - v = pic_apply(pic, pic_syntax(car)->macro, pic_cdr(pic, expr)); - if (pic->err) { - printf("macroexpand error: %s\n", pic_errmsg(pic)); - abort(); - } - } - else { - v = pic_apply_argv(pic, pic_syntax(car)->macro, 3, expr, pic_obj_value(senv), pic_obj_value(pic_syntax(car)->senv)); - if (pic->err) { - printf("macroexpand error: %s\n", pic_errmsg(pic)); - abort(); - } - } - pic_gc_arena_restore(pic, ai); - pic_gc_protect(pic, v); -#if DEBUG - puts("after expand-1:"); - pic_debug(pic, v); - puts(""); -#endif - - return macroexpand(pic, v, senv); - } - case PIC_STX_LAMBDA: { + else if (tag == pic->sLAMBDA) { struct pic_senv *in = new_local_senv(pic, pic_cadr(pic, expr), senv); - v = pic_cons(pic, pic_symbol_value(pic_syntax(car)->sym), + v = pic_cons(pic, car, pic_cons(pic, macroexpand_list(pic, pic_cadr(pic, expr), in), macroexpand_list(pic, pic_cddr(pic, expr), in))); @@ -463,7 +404,8 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) pic_gc_protect(pic, v); return v; } - case PIC_STX_DEFINE: { + + else if (tag == pic->sDEFINE) { pic_sym var; pic_value formals; @@ -485,11 +427,11 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) pic_error(pic, "binding to non-symbol object"); } var = pic_sym(a); - xh_put_int(senv->tbl, var, pic_gensym(pic, var)); + xh_put_int(senv->name, var, pic_gensym(pic, var)); /* binding value */ - v = pic_cons(pic, pic_symbol_value(pic_syntax(car)->sym), - pic_cons(pic, + v = pic_cons(pic, car, + pic_cons(pic, macroexpand_list(pic, pic_cadr(pic, expr), in), macroexpand_list(pic, pic_cddr(pic, expr), in))); @@ -506,24 +448,60 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) } var = pic_sym(formals); /* do not make duplicate variable slot */ - if (xh_get_int(senv->tbl, var) == NULL) { - xh_put_int(senv->tbl, var, pic_gensym(pic, var)); + if (xh_get_int(senv->name, var) == NULL) { + xh_put_int(senv->name, var, pic_gensym(pic, var)); } + + v = pic_cons(pic, pic_symbol_value(tag), + macroexpand_list(pic, pic_cdr(pic, expr), senv)); + pic_gc_arena_restore(pic, ai); + pic_gc_protect(pic, v); + return v; } - FALLTHROUGH; - case PIC_STX_SET: - case PIC_STX_IF: - case PIC_STX_BEGIN: - v = pic_cons(pic, pic_symbol_value(pic_syntax(car)->sym), macroexpand_list(pic, pic_cdr(pic, expr), senv)); + + else if (tag == pic->sSETBANG || tag == pic->sIF || tag == pic->sBEGIN) { + v = pic_cons(pic, car, macroexpand_list(pic, pic_cdr(pic, expr), senv)); pic_gc_arena_restore(pic, ai); pic_gc_protect(pic, v); return v; - case PIC_STX_QUOTE: - v = pic_cons(pic, pic_symbol_value(pic_syntax(car)->sym), pic_cdr(pic, expr)); + } + + else if (tag == pic->sQUOTE) { + v = pic_cons(pic, car, pic_cdr(pic, expr)); pic_gc_arena_restore(pic, ai); pic_gc_protect(pic, v); return v; } + + /* macro */ + if ((e = xh_get_int(pic->macros, tag)) != NULL) { + pic_value v; + struct pic_syntax *stx = (struct pic_syntax *)e->val; + if (stx->senv == NULL) { /* legacy macro */ + v = pic_apply(pic, stx->macro, pic_cdr(pic, expr)); + if (pic->err) { + printf("macroexpand error: %s\n", pic_errmsg(pic)); + abort(); + } + } + else { + v = pic_apply_argv(pic, stx->macro, 3, expr, pic_obj_value(senv), pic_obj_value(stx->senv)); + if (pic->err) { + printf("macroexpand error: %s\n", pic_errmsg(pic)); + abort(); + } + } + pic_gc_arena_restore(pic, ai); + pic_gc_protect(pic, v); + +#if DEBUG + puts("after expand-1:"); + pic_debug(pic, v); + puts(""); +#endif + + return macroexpand(pic, v, senv); + } } v = pic_cons(pic, car, macroexpand_list(pic, pic_cdr(pic, expr), senv)); diff --git a/src/state.c b/src/state.c index dadace38..95d6ecbc 100644 --- a/src/state.c +++ b/src/state.c @@ -64,6 +64,9 @@ pic_open(int argc, char *argv[], char **envp) pic->glen = 0; pic->gcapa = PIC_GLOBALS_SIZE; + /* macros */ + pic->macros = xh_new_int(); + /* libraries */ pic->lib_tbl = pic_nil_value(); pic->lib = NULL; @@ -142,9 +145,13 @@ pic_close(pic_state *pic) pic->arena_idx = 0; pic->lib_tbl = pic_undef_value(); + xh_clear(pic->macros); + /* free all values */ pic_gc_run(pic); + xh_destroy(pic->macros); + /* free heaps */ finalize_heap(pic->heap); free(pic->heap); From 013d734033da143608a8489f47345d0c6c846c5c Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 10:39:35 +0900 Subject: [PATCH 04/16] remove unused constant --- include/config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/config.h b/include/config.h index 739b39f9..867cea52 100644 --- a/include/config.h +++ b/include/config.h @@ -23,7 +23,6 @@ #define PIC_STACK_SIZE 1024 #define PIC_RESCUE_SIZE 30 #define PIC_GLOBALS_SIZE 1024 -#define PIC_MACROS_SIZE 1024 #define PIC_SYM_POOL_SIZE 128 #define PIC_IREP_SIZE 8 #define PIC_POOL_SIZE 8 From 9cf7d72e82e643a14813964fc127aee65fee4286 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 10:42:17 +0900 Subject: [PATCH 05/16] inline-expand a small function --- src/macro.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/macro.c b/src/macro.c index 12e7cc92..aa53a480 100644 --- a/src/macro.c +++ b/src/macro.c @@ -61,12 +61,6 @@ pic_core_syntactic_env(pic_state *pic) #undef register_core_syntax -static struct pic_senv * -new_global_senv(pic_state *pic) -{ - return pic->lib->senv; -} - static struct pic_senv * new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) { @@ -553,18 +547,15 @@ macroexpand_list(pic_state *pic, pic_value list, struct pic_senv *senv) pic_value pic_macroexpand(pic_state *pic, pic_value expr) { - struct pic_senv *senv; pic_value v; - senv = new_global_senv(pic); - #if DEBUG puts("before expand:"); pic_debug(pic, expr); puts(""); #endif - v = macroexpand(pic, expr, senv); + v = macroexpand(pic, expr, pic->lib->senv); #if DEBUG puts("after expand:"); From c759fee566296c060abd3f7e8a294c5f21280337 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 10:48:44 +0900 Subject: [PATCH 06/16] add new_senv --- src/macro.c | 86 +++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/src/macro.c b/src/macro.c index aa53a480..6f38b32c 100644 --- a/src/macro.c +++ b/src/macro.c @@ -13,54 +13,18 @@ static pic_value macroexpand(pic_state *, pic_value, struct pic_senv *); static pic_value macroexpand_list(pic_state *, pic_value, struct pic_senv *); -struct pic_senv * -pic_null_syntactic_env(pic_state *pic) +static struct pic_senv * +new_senv(pic_state *pic, struct pic_senv *up) { struct pic_senv *senv; senv = (struct pic_senv *)pic_obj_alloc(pic, sizeof(struct pic_senv), PIC_TT_SENV); - senv->up = NULL; + senv->up = up; senv->name = xh_new_int(); return senv; } -#define register_core_syntax(pic,senv,id) do { \ - pic_sym sym = pic_intern_cstr(pic, id); \ - xh_put_int(senv->name, sym, sym); \ - } while (0) - -struct pic_senv * -pic_minimal_syntactic_env(pic_state *pic) -{ - struct pic_senv *senv = pic_null_syntactic_env(pic); - - register_core_syntax(pic, senv, "define-library"); - register_core_syntax(pic, senv, "import"); - register_core_syntax(pic, senv, "export"); - - return senv; -} - -struct pic_senv * -pic_core_syntactic_env(pic_state *pic) -{ - struct pic_senv *senv = pic_minimal_syntactic_env(pic); - - register_core_syntax(pic, senv, "define"); - register_core_syntax(pic, senv, "set!"); - register_core_syntax(pic, senv, "quote"); - register_core_syntax(pic, senv, "lambda"); - register_core_syntax(pic, senv, "if"); - register_core_syntax(pic, senv, "begin"); - register_core_syntax(pic, senv, "define-macro"); - register_core_syntax(pic, senv, "define-syntax"); - - return senv; -} - -#undef register_core_syntax - static struct pic_senv * new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) { @@ -68,9 +32,7 @@ new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) pic_value a; pic_sym sym; - senv = (struct pic_senv *)pic_obj_alloc(pic, sizeof(struct pic_senv), PIC_TT_SENV); - senv->up = up; - senv->name = xh_new_int(); + senv = new_senv(pic, up); for (a = formals; pic_pair_p(a); a = pic_cdr(pic, a)) { pic_value v = pic_car(pic, a); @@ -566,6 +528,46 @@ pic_macroexpand(pic_state *pic, pic_value expr) return v; } +struct pic_senv * +pic_null_syntactic_env(pic_state *pic) +{ + return new_senv(pic, NULL); +} + +#define register_core_syntax(pic,senv,id) do { \ + pic_sym sym = pic_intern_cstr(pic, id); \ + xh_put_int(senv->name, sym, sym); \ + } while (0) + +struct pic_senv * +pic_minimal_syntactic_env(pic_state *pic) +{ + struct pic_senv *senv = pic_null_syntactic_env(pic); + + register_core_syntax(pic, senv, "define-library"); + register_core_syntax(pic, senv, "import"); + register_core_syntax(pic, senv, "export"); + + return senv; +} + +struct pic_senv * +pic_core_syntactic_env(pic_state *pic) +{ + struct pic_senv *senv = pic_minimal_syntactic_env(pic); + + register_core_syntax(pic, senv, "define"); + register_core_syntax(pic, senv, "set!"); + register_core_syntax(pic, senv, "quote"); + register_core_syntax(pic, senv, "lambda"); + register_core_syntax(pic, senv, "if"); + register_core_syntax(pic, senv, "begin"); + register_core_syntax(pic, senv, "define-macro"); + register_core_syntax(pic, senv, "define-syntax"); + + return senv; +} + /* once read.c is implemented move there */ static pic_value pic_macro_include(pic_state *pic) From a18fe136e1424d91bbb1aacc59652d2c765fa7f7 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 10:50:26 +0900 Subject: [PATCH 07/16] cosmetic fixes --- src/macro.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/macro.c b/src/macro.c index 6f38b32c..fd032921 100644 --- a/src/macro.c +++ b/src/macro.c @@ -95,13 +95,13 @@ sc_new(pic_state *pic, pic_value expr, struct pic_senv *senv) } static bool -pic_identifier_p(pic_value obj) +identifier_p(pic_value obj) { if (pic_sym_p(obj)) { return true; } if (pic_sc_p(obj)) { - return pic_identifier_p(pic_sc(obj)->expr); + return identifier_p(pic_sc(obj)->expr); } return false; } @@ -626,7 +626,7 @@ pic_macro_identifier_p(pic_state *pic) pic_get_args(pic, "o", &obj); - return pic_bool_value(pic_identifier_p(obj)); + return pic_bool_value(identifier_p(obj)); } static pic_value @@ -646,7 +646,7 @@ pic_macro_identifier_eq_p(pic_state *pic) } e2 = pic_senv(f); - if (! (pic_identifier_p(x) && pic_identifier_p(y))) { + if (! (identifier_p(x) && identifier_p(y))) { return pic_false_value(); } From 93a259870cb0e39c693a1285841cfcf7b4f55a8e Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 10:52:33 +0900 Subject: [PATCH 08/16] replace pic_syntax_new with pic_syntax_new_macro --- include/picrin/macro.h | 3 +-- src/macro.c | 16 ++-------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/include/picrin/macro.h b/include/picrin/macro.h index 2672876b..d269776a 100644 --- a/include/picrin/macro.h +++ b/include/picrin/macro.h @@ -42,8 +42,7 @@ struct pic_senv *pic_null_syntactic_env(pic_state *); struct pic_senv *pic_minimal_syntactic_env(pic_state *); struct pic_senv *pic_core_syntactic_env(pic_state *); -struct pic_syntax *pic_syntax_new(pic_state *, pic_sym, struct pic_proc *); -struct pic_syntax *pic_syntax_new_macro(pic_state *, pic_sym, struct pic_proc *, struct pic_senv *); +struct pic_syntax *pic_syntax_new(pic_state *, pic_sym, struct pic_proc *, struct pic_senv *); #if defined(__cplusplus) } diff --git a/src/macro.c b/src/macro.c index fd032921..2f8635f5 100644 --- a/src/macro.c +++ b/src/macro.c @@ -60,19 +60,7 @@ new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) } struct pic_syntax * -pic_syntax_new(pic_state *pic, pic_sym sym, struct pic_proc *macro) -{ - struct pic_syntax *stx; - - stx = (struct pic_syntax *)pic_obj_alloc(pic, sizeof(struct pic_syntax), PIC_TT_SYNTAX); - stx->sym = sym; - stx->senv = NULL; - stx->macro = macro; - return stx; -} - -struct pic_syntax * -pic_syntax_new_macro(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv *mac_env) +pic_syntax_new(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv *mac_env) { struct pic_syntax *stx; @@ -152,7 +140,7 @@ defsyntax(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv * pic_sym uniq; uniq = pic_gensym(pic, sym); - stx = pic_syntax_new_macro(pic, sym, macro, mac_env); + stx = pic_syntax_new(pic, sym, macro, mac_env); xh_put_int(pic->lib->senv->name, sym, uniq); xh_put_int(pic->macros, uniq, (long)stx); From 25ae2ef6b0a818c3f75e2493147f9bf319c1f967 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 10:57:58 +0900 Subject: [PATCH 09/16] add identifier_eq_p --- src/macro.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/macro.c b/src/macro.c index 2f8635f5..526da02f 100644 --- a/src/macro.c +++ b/src/macro.c @@ -94,6 +94,19 @@ identifier_p(pic_value obj) return false; } +static bool +identifier_eq_p(pic_state *pic, struct pic_senv *e1, pic_value x, struct pic_senv *e2, pic_value y) +{ + if (! (identifier_p(x) && identifier_p(y))) { + return false; + } + + x = macroexpand(pic, x, e1); + y = macroexpand(pic, y, e2); + + return pic_eq_p(x, y); +} + void pic_import(pic_state *pic, pic_value spec) { @@ -634,14 +647,7 @@ pic_macro_identifier_eq_p(pic_state *pic) } e2 = pic_senv(f); - if (! (identifier_p(x) && identifier_p(y))) { - return pic_false_value(); - } - - x = macroexpand(pic, x, e1); - y = macroexpand(pic, y, e2); - - return pic_bool_value(pic_eq_p(x, y)); + return pic_bool_value(identifier_eq_p(pic, e1, x, e2, y)); } static pic_value From 3d97e7f7490ff5557418d7566b8b280b7d728390 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 10:59:10 +0900 Subject: [PATCH 10/16] syntax_new is a private API --- include/picrin/macro.h | 2 -- src/macro.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/include/picrin/macro.h b/include/picrin/macro.h index d269776a..65633462 100644 --- a/include/picrin/macro.h +++ b/include/picrin/macro.h @@ -42,8 +42,6 @@ struct pic_senv *pic_null_syntactic_env(pic_state *); struct pic_senv *pic_minimal_syntactic_env(pic_state *); struct pic_senv *pic_core_syntactic_env(pic_state *); -struct pic_syntax *pic_syntax_new(pic_state *, pic_sym, struct pic_proc *, struct pic_senv *); - #if defined(__cplusplus) } #endif diff --git a/src/macro.c b/src/macro.c index 526da02f..e640c2a9 100644 --- a/src/macro.c +++ b/src/macro.c @@ -60,7 +60,7 @@ new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) } struct pic_syntax * -pic_syntax_new(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv *mac_env) +syntax_new(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv *mac_env) { struct pic_syntax *stx; @@ -153,7 +153,7 @@ defsyntax(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv * pic_sym uniq; uniq = pic_gensym(pic, sym); - stx = pic_syntax_new(pic, sym, macro, mac_env); + stx = syntax_new(pic, sym, macro, mac_env); xh_put_int(pic->lib->senv->name, sym, uniq); xh_put_int(pic->macros, uniq, (long)stx); From 6b69e8e74bb53743b692309596f16a85eee0139c Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 11:02:59 +0900 Subject: [PATCH 11/16] stx->sym property is no longer used --- include/picrin/macro.h | 1 - src/macro.c | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/picrin/macro.h b/include/picrin/macro.h index 65633462..1ba04a79 100644 --- a/include/picrin/macro.h +++ b/include/picrin/macro.h @@ -17,7 +17,6 @@ struct pic_senv { struct pic_syntax { PIC_OBJECT_HEADER - pic_sym sym; struct pic_proc *macro; struct pic_senv *senv; }; diff --git a/src/macro.c b/src/macro.c index e640c2a9..ccb7b65c 100644 --- a/src/macro.c +++ b/src/macro.c @@ -60,12 +60,11 @@ new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) } struct pic_syntax * -syntax_new(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv *mac_env) +syntax_new(pic_state *pic, struct pic_proc *macro, struct pic_senv *mac_env) { struct pic_syntax *stx; stx = (struct pic_syntax *)pic_obj_alloc(pic, sizeof(struct pic_syntax), PIC_TT_SYNTAX); - stx->sym = sym; stx->senv = mac_env; stx->macro = macro; return stx; @@ -152,9 +151,9 @@ defsyntax(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv * struct pic_syntax *stx; pic_sym uniq; - uniq = pic_gensym(pic, sym); - stx = syntax_new(pic, sym, macro, mac_env); + stx = syntax_new(pic, macro, mac_env); + uniq = pic_gensym(pic, sym); xh_put_int(pic->lib->senv->name, sym, uniq); xh_put_int(pic->macros, uniq, (long)stx); } From 8ea3a7b544ff1568136d3c645b0df87263f1b4f1 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 11:05:32 +0900 Subject: [PATCH 12/16] rename a property of pic_syntax s/macro/proc/g --- include/picrin/macro.h | 2 +- src/gc.c | 4 ++-- src/macro.c | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/picrin/macro.h b/include/picrin/macro.h index 1ba04a79..04dcfa22 100644 --- a/include/picrin/macro.h +++ b/include/picrin/macro.h @@ -17,7 +17,7 @@ struct pic_senv { struct pic_syntax { PIC_OBJECT_HEADER - struct pic_proc *macro; + struct pic_proc *proc; struct pic_senv *senv; }; diff --git a/src/gc.c b/src/gc.c index c9ca85ef..3499ea80 100644 --- a/src/gc.c +++ b/src/gc.c @@ -390,8 +390,8 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) case PIC_TT_SYNTAX: { struct pic_syntax *stx = (struct pic_syntax *)obj; - if (stx->macro) { - gc_mark_object(pic, (struct pic_object *)stx->macro); + if (stx->proc) { + gc_mark_object(pic, (struct pic_object *)stx->proc); } if (stx->senv) { gc_mark_object(pic, (struct pic_object *)stx->senv); diff --git a/src/macro.c b/src/macro.c index ccb7b65c..7ff08046 100644 --- a/src/macro.c +++ b/src/macro.c @@ -60,13 +60,13 @@ new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) } struct pic_syntax * -syntax_new(pic_state *pic, struct pic_proc *macro, struct pic_senv *mac_env) +syntax_new(pic_state *pic, struct pic_proc *proc, struct pic_senv *mac_env) { struct pic_syntax *stx; stx = (struct pic_syntax *)pic_obj_alloc(pic, sizeof(struct pic_syntax), PIC_TT_SYNTAX); stx->senv = mac_env; - stx->macro = macro; + stx->proc = proc; return stx; } @@ -434,14 +434,14 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) pic_value v; struct pic_syntax *stx = (struct pic_syntax *)e->val; if (stx->senv == NULL) { /* legacy macro */ - v = pic_apply(pic, stx->macro, pic_cdr(pic, expr)); + v = pic_apply(pic, stx->proc, pic_cdr(pic, expr)); if (pic->err) { printf("macroexpand error: %s\n", pic_errmsg(pic)); abort(); } } else { - v = pic_apply_argv(pic, stx->macro, 3, expr, pic_obj_value(senv), pic_obj_value(stx->senv)); + v = pic_apply_argv(pic, stx->proc, 3, expr, pic_obj_value(senv), pic_obj_value(stx->senv)); if (pic->err) { printf("macroexpand error: %s\n", pic_errmsg(pic)); abort(); From 098d5dc0221e01410200bcf111dd3f3a6136afc8 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 11:13:29 +0900 Subject: [PATCH 13/16] s/syntax/macro/g --- include/picrin/macro.h | 6 +++--- include/picrin/value.h | 6 +++--- src/codegen.c | 2 +- src/gc.c | 14 +++++++------- src/macro.c | 40 +++++++++++++++++++++------------------- src/write.c | 4 ++-- 6 files changed, 37 insertions(+), 35 deletions(-) diff --git a/include/picrin/macro.h b/include/picrin/macro.h index 04dcfa22..f1ca1b12 100644 --- a/include/picrin/macro.h +++ b/include/picrin/macro.h @@ -15,7 +15,7 @@ struct pic_senv { struct pic_senv *up; }; -struct pic_syntax { +struct pic_macro { PIC_OBJECT_HEADER struct pic_proc *proc; struct pic_senv *senv; @@ -30,8 +30,8 @@ struct pic_sc { #define pic_sc(v) ((struct pic_sc *)pic_ptr(v)) #define pic_sc_p(v) (pic_type(v) == PIC_TT_SC) -#define pic_syntax(v) ((struct pic_syntax *)pic_ptr(v)) -#define pic_syntax_p(v) (pic_type(v) == PIC_TT_SYNTAX) +#define pic_macro(v) ((struct pic_macro *)pic_ptr(v)) +#define pic_macro_p(v) (pic_type(v) == PIC_TT_MACRO) #define pic_senv(v) ((struct pic_senv *)pic_ptr(v)) #define pic_senv_p(v) (pic_type(v) == PIC_TT_SENV) diff --git a/include/picrin/value.h b/include/picrin/value.h index 0c2dd8aa..9323b2c9 100644 --- a/include/picrin/value.h +++ b/include/picrin/value.h @@ -99,7 +99,7 @@ enum pic_tt { PIC_TT_ENV, PIC_TT_CONT, PIC_TT_SENV, - PIC_TT_SYNTAX, + PIC_TT_MACRO, PIC_TT_SC, PIC_TT_LIB, PIC_TT_VAR, @@ -248,8 +248,8 @@ pic_type_repr(enum pic_tt tt) return "sc"; case PIC_TT_SENV: return "senv"; - case PIC_TT_SYNTAX: - return "syntax"; + case PIC_TT_MACRO: + return "macro"; case PIC_TT_LIB: return "lib"; case PIC_TT_VAR: diff --git a/src/codegen.c b/src/codegen.c index 195d3b6d..0b589820 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -561,7 +561,7 @@ analyze_node(analyze_state *state, pic_value obj, bool tailpos) case PIC_TT_PORT: case PIC_TT_ERROR: case PIC_TT_SENV: - case PIC_TT_SYNTAX: + case PIC_TT_MACRO: case PIC_TT_SC: case PIC_TT_LIB: case PIC_TT_VAR: diff --git a/src/gc.c b/src/gc.c index 3499ea80..36227a44 100644 --- a/src/gc.c +++ b/src/gc.c @@ -387,14 +387,14 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) gc_mark(pic, cont->results); break; } - case PIC_TT_SYNTAX: { - struct pic_syntax *stx = (struct pic_syntax *)obj; + case PIC_TT_MACRO: { + struct pic_macro *mac = (struct pic_macro *)obj; - if (stx->proc) { - gc_mark_object(pic, (struct pic_object *)stx->proc); + if (mac->proc) { + gc_mark_object(pic, (struct pic_object *)mac->proc); } - if (stx->senv) { - gc_mark_object(pic, (struct pic_object *)stx->senv); + if (mac->senv) { + gc_mark_object(pic, (struct pic_object *)mac->senv); } break; } @@ -567,7 +567,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj) xh_destroy(senv->name); break; } - case PIC_TT_SYNTAX: { + case PIC_TT_MACRO: { break; } case PIC_TT_SC: { diff --git a/src/macro.c b/src/macro.c index 7ff08046..87456ffe 100644 --- a/src/macro.c +++ b/src/macro.c @@ -59,15 +59,15 @@ new_local_senv(pic_state *pic, pic_value formals, struct pic_senv *up) return senv; } -struct pic_syntax * -syntax_new(pic_state *pic, struct pic_proc *proc, struct pic_senv *mac_env) +struct pic_macro * +macro_new(pic_state *pic, struct pic_proc *proc, struct pic_senv *mac_env) { - struct pic_syntax *stx; + struct pic_macro *mac; - stx = (struct pic_syntax *)pic_obj_alloc(pic, sizeof(struct pic_syntax), PIC_TT_SYNTAX); - stx->senv = mac_env; - stx->proc = proc; - return stx; + mac = (struct pic_macro *)pic_obj_alloc(pic, sizeof(struct pic_macro), PIC_TT_MACRO); + mac->senv = mac_env; + mac->proc = proc; + return mac; } static struct pic_sc * @@ -148,14 +148,14 @@ pic_export(pic_state *pic, pic_sym sym) static void defsyntax(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv *mac_env) { - struct pic_syntax *stx; + struct pic_macro *mac; pic_sym uniq; - stx = syntax_new(pic, macro, mac_env); + mac = macro_new(pic, macro, mac_env); uniq = pic_gensym(pic, sym); xh_put_int(pic->lib->senv->name, sym, uniq); - xh_put_int(pic->macros, uniq, (long)stx); + xh_put_int(pic->macros, uniq, (long)mac); } static void @@ -432,16 +432,18 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) /* macro */ if ((e = xh_get_int(pic->macros, tag)) != NULL) { pic_value v; - struct pic_syntax *stx = (struct pic_syntax *)e->val; - if (stx->senv == NULL) { /* legacy macro */ - v = pic_apply(pic, stx->proc, pic_cdr(pic, expr)); + struct pic_macro *mac; + + mac = (struct pic_macro *)e->val; + if (mac->senv == NULL) { /* legacy macro */ + v = pic_apply(pic, mac->proc, pic_cdr(pic, expr)); if (pic->err) { printf("macroexpand error: %s\n", pic_errmsg(pic)); abort(); } } else { - v = pic_apply_argv(pic, stx->proc, 3, expr, pic_obj_value(senv), pic_obj_value(stx->senv)); + v = pic_apply_argv(pic, mac->proc, 3, expr, pic_obj_value(senv), pic_obj_value(mac->senv)); if (pic->err) { printf("macroexpand error: %s\n", pic_errmsg(pic)); abort(); @@ -483,7 +485,7 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) case PIC_TT_CONT: case PIC_TT_UNDEF: case PIC_TT_SENV: - case PIC_TT_SYNTAX: + case PIC_TT_MACRO: case PIC_TT_LIB: case PIC_TT_VAR: case PIC_TT_IREP: @@ -661,7 +663,7 @@ er_macro_rename(pic_state *pic) mac_env = pic_senv_ptr(pic_proc_cv_ref(pic, pic_get_proc(pic), 1)); v = macroexpand(pic, pic_symbol_value(sym), mac_env); - if (pic_syntax_p(v)) { + if (pic_macro_p(v)) { return pic_symbol_value(sym); } else { @@ -744,7 +746,7 @@ ir_macro_inject(pic_state *pic) use_env = pic_senv_ptr(pic_proc_cv_ref(pic, pic_get_proc(pic), 0)); v = macroexpand(pic, pic_symbol_value(sym), use_env); - if (pic_syntax_p(v)) { + if (pic_macro_p(v)) { return pic_symbol_value(sym); } else { @@ -793,13 +795,13 @@ ir_macro_wrap(pic_state *pic, pic_value expr, struct pic_senv *use_env, pic_valu static pic_value ir_macro_unwrap(pic_state *pic, pic_value expr, struct pic_senv *mac_env, pic_value *assoc) { - if (pic_sym_p(expr) || pic_syntax_p(expr)) { + if (pic_sym_p(expr) || pic_macro_p(expr)) { pic_value r; if (pic_test(r = pic_assq(pic, expr, *assoc))) { return pic_cdr(pic, r); } r = macroexpand(pic, expr, mac_env); - if (pic_syntax_p(r)) { + if (pic_macro_p(r)) { return expr; } else { diff --git a/src/write.c b/src/write.c index e96cf706..e1827c42 100644 --- a/src/write.c +++ b/src/write.c @@ -134,8 +134,8 @@ write(pic_state *pic, pic_value obj, XFILE *file) case PIC_TT_SENV: xfprintf(file, "#", pic_ptr(obj)); break; - case PIC_TT_SYNTAX: - xfprintf(file, "#", pic_ptr(obj)); + case PIC_TT_MACRO: + xfprintf(file, "#", pic_ptr(obj)); break; case PIC_TT_SC: xfprintf(file, "# Date: Wed, 12 Feb 2014 11:20:38 +0900 Subject: [PATCH 14/16] use symbol_rename function in macro transformers --- src/macro.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/macro.c b/src/macro.c index 87456ffe..dada57d5 100644 --- a/src/macro.c +++ b/src/macro.c @@ -656,19 +656,12 @@ er_macro_rename(pic_state *pic) { pic_sym sym; struct pic_senv *mac_env; - pic_value v; pic_get_args(pic, "m", &sym); mac_env = pic_senv_ptr(pic_proc_cv_ref(pic, pic_get_proc(pic), 1)); - v = macroexpand(pic, pic_symbol_value(sym), mac_env); - if (pic_macro_p(v)) { - return pic_symbol_value(sym); - } - else { - return v; - } + return pic_symbol_value(symbol_rename(pic, sym, mac_env)); } static pic_value @@ -676,6 +669,7 @@ er_macro_compare(pic_state *pic) { pic_value a, b; struct pic_senv *use_env; + pic_sym m, n; pic_get_args(pic, "oo", &a, &b); @@ -684,10 +678,10 @@ er_macro_compare(pic_state *pic) use_env = pic_senv_ptr(pic_proc_cv_ref(pic, pic_get_proc(pic), 0)); - a = macroexpand(pic, a, use_env); - b = macroexpand(pic, b, use_env); + m = symbol_rename(pic, pic_sym(a), use_env); + n = symbol_rename(pic, pic_sym(b), use_env); - return pic_bool_value(pic_eq_p(a, b)); + return pic_bool_value(m == n); } static pic_value @@ -739,19 +733,12 @@ ir_macro_inject(pic_state *pic) { pic_sym sym; struct pic_senv *use_env; - pic_value v; pic_get_args(pic, "m", &sym); use_env = pic_senv_ptr(pic_proc_cv_ref(pic, pic_get_proc(pic), 0)); - v = macroexpand(pic, pic_symbol_value(sym), use_env); - if (pic_macro_p(v)) { - return pic_symbol_value(sym); - } - else { - return v; - } + return pic_symbol_value(symbol_rename(pic, sym, use_env)); } static pic_value @@ -759,6 +746,7 @@ ir_macro_compare(pic_state *pic) { pic_value a, b; struct pic_senv *use_env; + pic_sym m, n; pic_get_args(pic, "oo", &a, &b); @@ -767,10 +755,10 @@ ir_macro_compare(pic_state *pic) use_env = pic_senv_ptr(pic_proc_cv_ref(pic, pic_get_proc(pic), 0)); - a = macroexpand(pic, a, use_env); - b = macroexpand(pic, b, use_env); + m = symbol_rename(pic, pic_sym(a), use_env); + n = symbol_rename(pic, pic_sym(b), use_env); - return pic_bool_value(pic_eq_p(a, b)); + return pic_bool_value(m == n); } static pic_value From b24e1b05c41480826d81c607bea7005b46cb30ad Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 11:30:32 +0900 Subject: [PATCH 15/16] cleanup --- src/macro.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/macro.c b/src/macro.c index dada57d5..6a999aa3 100644 --- a/src/macro.c +++ b/src/macro.c @@ -262,6 +262,7 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) } return pic_none_value(); } + else if (tag == pic->sEXPORT) { pic_value spec; pic_for_each (spec, pic_cdr(pic, expr)) { From 03ef82fd163f6247bebb6c87f3cbc694913b2d52 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Feb 2014 11:32:17 +0900 Subject: [PATCH 16/16] defmacro takes a symbol for the name --- src/macro.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/macro.c b/src/macro.c index 6a999aa3..ae6076b2 100644 --- a/src/macro.c +++ b/src/macro.c @@ -159,15 +159,15 @@ defsyntax(pic_state *pic, pic_sym sym, struct pic_proc *macro, struct pic_senv * } static void -defmacro(pic_state *pic, const char *name, struct pic_proc *macro) +defmacro(pic_state *pic, pic_sym sym, struct pic_proc *macro) { - defsyntax(pic, pic_intern_cstr(pic, name), macro, NULL); + defsyntax(pic, sym, macro, NULL); } void pic_defmacro(pic_state *pic, const char *name, struct pic_proc *macro) { - defmacro(pic, name, macro); + defmacro(pic, pic_intern_cstr(pic, name), macro); /* auto export! */ pic_export(pic, pic_intern_cstr(pic, name)); @@ -343,7 +343,7 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) abort(); } assert(pic_proc_p(v)); - defmacro(pic, pic_symbol_name(pic, pic_sym(var)), pic_proc_ptr(v)); + defmacro(pic, pic_sym(var), pic_proc_ptr(v)); pic_gc_arena_restore(pic, ai); return pic_none_value();