continuation object is applicable
This commit is contained in:
parent
3a4de8895e
commit
b8b5743589
42
cont.c
42
cont.c
|
@ -250,25 +250,6 @@ pic_dynamic_wind(pic_state *pic, struct pic_proc *in, struct pic_proc *thunk, st
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
noreturn static pic_value
|
|
||||||
pic_cont_continue(pic_state *pic)
|
|
||||||
{
|
|
||||||
struct pic_proc *proc;
|
|
||||||
size_t argc;
|
|
||||||
pic_value cont, *argv;
|
|
||||||
|
|
||||||
proc = pic_get_proc(pic);
|
|
||||||
pic_get_args(pic, "o*", &cont, &argc, &argv);
|
|
||||||
|
|
||||||
pic_assert_type(pic, cont, cont);
|
|
||||||
|
|
||||||
pic_cont_ptr(cont)->results = pic_list_by_array(pic, argc, argv);
|
|
||||||
|
|
||||||
/* execute guard handlers */
|
|
||||||
walk_to_block(pic, pic->blk, pic_cont_ptr(cont)->blk);
|
|
||||||
|
|
||||||
restore_cont(pic, pic_cont_ptr(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
pic_value
|
pic_value
|
||||||
pic_callcc(pic_state *pic, struct pic_proc *proc)
|
pic_callcc(pic_state *pic, struct pic_proc *proc)
|
||||||
|
@ -298,6 +279,16 @@ pic_callcc_trampoline(pic_state *pic, struct pic_proc *proc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
noreturn void
|
||||||
|
pic_continue(pic_state *pic, struct pic_cont *cont, size_t argc, pic_value *argv)
|
||||||
|
{
|
||||||
|
cont->results = pic_list_by_array(pic, argc, argv);
|
||||||
|
|
||||||
|
walk_to_block(pic, pic->blk, cont->blk);
|
||||||
|
|
||||||
|
restore_cont(pic, cont);
|
||||||
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
pic_cont_callcc(pic_state *pic)
|
pic_cont_callcc(pic_state *pic)
|
||||||
{
|
{
|
||||||
|
@ -308,6 +299,19 @@ pic_cont_callcc(pic_state *pic)
|
||||||
return pic_callcc_trampoline(pic, cb);
|
return pic_callcc_trampoline(pic, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
noreturn static pic_value
|
||||||
|
pic_cont_continue(pic_state *pic)
|
||||||
|
{
|
||||||
|
size_t argc;
|
||||||
|
pic_value cont, *argv;
|
||||||
|
|
||||||
|
pic_get_args(pic, "o*", &cont, &argc, &argv);
|
||||||
|
|
||||||
|
pic_assert_type(pic, cont, cont);
|
||||||
|
|
||||||
|
pic_continue(pic, pic_cont_ptr(cont), argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
pic_cont_dynamic_wind(pic_state *pic)
|
pic_cont_dynamic_wind(pic_state *pic)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,6 +57,7 @@ pic_value pic_values_by_list(pic_state *, pic_value);
|
||||||
size_t pic_receive(pic_state *, size_t, pic_value *);
|
size_t pic_receive(pic_state *, size_t, pic_value *);
|
||||||
|
|
||||||
pic_value pic_callcc(pic_state *, struct pic_proc *);
|
pic_value pic_callcc(pic_state *, struct pic_proc *);
|
||||||
|
noreturn void pic_continue(pic_state *, struct pic_cont *, size_t, pic_value *);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
8
vm.c
8
vm.c
|
@ -21,6 +21,7 @@
|
||||||
#include "picrin/error.h"
|
#include "picrin/error.h"
|
||||||
#include "picrin/dict.h"
|
#include "picrin/dict.h"
|
||||||
#include "picrin/record.h"
|
#include "picrin/record.h"
|
||||||
|
#include "picrin/cont.h"
|
||||||
|
|
||||||
#define GET_OPERAND(pic,n) ((pic)->ci->fp[(n)])
|
#define GET_OPERAND(pic,n) ((pic)->ci->fp[(n)])
|
||||||
|
|
||||||
|
@ -752,6 +753,13 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
|
||||||
PUSH(pic_var_ref(pic, pic_var_ptr(x)));
|
PUSH(pic_var_ref(pic, pic_var_ptr(x)));
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
|
if (pic_cont_p(x)) {
|
||||||
|
if (c.u.i >= 1) {
|
||||||
|
pic_errorf(pic, "invalid call-sequence for cont object");
|
||||||
|
}
|
||||||
|
pic_continue(pic, pic_cont_ptr(x), c.u.i - 1, pic->sp - c.u.i + 1);
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
pic_errorf(pic, "invalid application: ~s", x);
|
pic_errorf(pic, "invalid application: ~s", x);
|
||||||
}
|
}
|
||||||
proc = pic_proc_ptr(x);
|
proc = pic_proc_ptr(x);
|
||||||
|
|
Loading…
Reference in New Issue