From e0831c1aa3c963111859278579a42dba997dc75d Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Mon, 25 Aug 2014 17:10:25 +0900 Subject: [PATCH] change the interface of call/cc --- cont.c | 34 +++++++++------------------------- include/picrin/cont.h | 3 +++ 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/cont.c b/cont.c index 30d26568..b31d54f0 100644 --- a/cont.c +++ b/cont.c @@ -7,7 +7,6 @@ #include #include "picrin.h" -#include "picrin/proc.h" #include "picrin/cont.h" #include "picrin/pair.h" #include "picrin/error.h" @@ -252,23 +251,21 @@ pic_dynamic_wind(pic_state *pic, struct pic_proc *in, struct pic_proc *thunk, st } noreturn static pic_value -cont_call(pic_state *pic) +pic_cont_continue(pic_state *pic) { struct pic_proc *proc; size_t argc; - pic_value *argv; - struct pic_cont *cont; + pic_value cont, *argv; proc = pic_get_proc(pic); - pic_get_args(pic, "*", &argc, &argv); + pic_get_args(pic, "o*", &cont, &argc, &argv); - cont = (struct pic_cont *)pic_ptr(pic_attr_ref(pic, proc, "@@cont")); - cont->results = pic_list_by_array(pic, argc, argv); + pic_assert_type(pic, cont, cont); /* execute guard handlers */ - walk_to_block(pic, pic->blk, cont->blk); + walk_to_block(pic, pic->blk, pic_cont_ptr(cont)->blk); - restore_cont(pic, cont); + restore_cont(pic, pic_cont_ptr(cont)); } pic_value @@ -281,14 +278,7 @@ pic_callcc(pic_state *pic, struct pic_proc *proc) return pic_values_by_list(pic, cont->results); } else { - struct pic_proc *c; - - c = pic_proc_new(pic, cont_call, ""); - - /* save the continuation object in proc */ - pic_attr_set(pic, c, "@@cont", pic_obj_value(cont)); - - return pic_apply1(pic, proc, pic_obj_value(c)); + return pic_apply1(pic, proc, pic_obj_value(cont)); } } @@ -302,14 +292,7 @@ pic_callcc_trampoline(pic_state *pic, struct pic_proc *proc) return pic_values_by_list(pic, cont->results); } else { - struct pic_proc *c; - - c = pic_proc_new(pic, cont_call, ""); - - /* save the continuation object in proc */ - pic_attr_set(pic, c, "@@cont", pic_obj_value(cont)); - - return pic_apply_trampoline(pic, proc, pic_list1(pic, pic_obj_value(c))); + return pic_apply_trampoline(pic, proc, pic_list1(pic, pic_obj_value(cont))); } } @@ -365,6 +348,7 @@ pic_init_cont(pic_state *pic) { pic_defun(pic, "call-with-current-continuation", pic_cont_callcc); pic_defun(pic, "call/cc", pic_cont_callcc); + pic_defun(pic, "continue", pic_cont_continue); pic_defun(pic, "dynamic-wind", pic_cont_dynamic_wind); pic_defun(pic, "values", pic_cont_values); pic_defun(pic, "call-with-values", pic_cont_call_with_values); diff --git a/include/picrin/cont.h b/include/picrin/cont.h index 0a0da9f1..6f35de38 100644 --- a/include/picrin/cont.h +++ b/include/picrin/cont.h @@ -43,6 +43,9 @@ struct pic_cont { pic_value results; }; +#define pic_cont_p(o) (pic_type(o) == PIC_TT_CONT) +#define pic_cont_ptr(o) ((struct pic_cont *)pic_ptr(o)) + pic_value pic_values0(pic_state *); pic_value pic_values1(pic_state *, pic_value); pic_value pic_values2(pic_state *, pic_value, pic_value);