Skip to content

Commit 47ce93d

Browse files
committed
Somewhat make call/delimited-cc work
1 parent 6cc8c49 commit 47ce93d

File tree

2 files changed

+54
-41
lines changed

2 files changed

+54
-41
lines changed

lib/sagittarius/continuations.scm

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,16 @@
4747
(core macro)
4848
(sagittarius))
4949

50-
(define (call/cc proc :optional (tag (default-continuation-prompt-tag)))
51-
(call-with-composable-continuation
52-
(lambda (ck)
53-
(define (k . args)
54-
(abort-current-continuation tag (lambda () (apply ck args))))
55-
(proc k))
56-
tag))
57-
(define call-with-current-continuation call/cc)
50+
;; (define (call/cc proc :optional (tag (default-continuation-prompt-tag)))
51+
;; (call-with-composable-continuation
52+
;; (lambda (ck)
53+
;; (define (k . args)
54+
;; (abort-current-continuation tag (lambda () (apply ck args))))
55+
;; (proc k))
56+
;; tag))
57+
;; (define call-with-current-continuation call/cc)
58+
(define call/cc call/delimited-cc)
59+
(define call-with-current-continuation call-with-delimited-current-continuation)
5860

5961
(define (abort-current-continuation/keep-prompt tag thunk)
6062
((call-with-continuation-prompt

src/vm.c

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,7 @@ static SgObject throw_delimited_continuation_body(SgObject,
15901590
SgContinuation *,
15911591
SgObject,
15921592
SgPrompt *);
1593+
static SgObject throw_continuation_end(SgVM *, SgObject);
15931594

15941595
static SgObject throw_continuation_body(SgObject handlers,
15951596
SgContinuation *c,
@@ -1643,31 +1644,36 @@ static SgObject throw_continuation_body(SgObject handlers,
16431644
vm->cont = c->cont;
16441645
vm->dynamicWinders = c->winders;
16451646
}
1646-
vm->pc = return_code;
1647-
/* store arguments of the continuation to ac */
1648-
if (SG_NULLP(args)) { /* no value */
1649-
/* does this happen? */
1650-
vm->ac = SG_UNDEF;
1651-
vm->valuesCount = 0;
1652-
} else if (SG_NULLP(SG_CDR(args))) { /* usual case */
1653-
vm->ac = SG_CAR(args);
1654-
vm->valuesCount = 1;
1655-
} else { /* multi values */
1656-
SgObject ap;
1657-
int argc = (int)Sg_Length(args), i;
1658-
/* when argc == DEFAULT_VALUES_SIZE+1, it must be in pre-allocated
1659-
buffer */
1660-
if (argc > DEFAULT_VALUES_SIZE+1) {
1661-
SG_ALLOC_VALUES_BUFFER(vm, argc - DEFAULT_VALUES_SIZE -1);
1662-
}
1663-
vm->ac = SG_CAR(args);
1664-
for (i = 0, ap = SG_CDR(args); SG_PAIRP(ap); i++, ap = SG_CDR(ap)) {
1665-
SG_VALUES_SET(vm, i, SG_CAR(ap));
1666-
}
1667-
vm->valuesCount = argc;
1647+
return throw_continuation_end(vm, args);
1648+
}
1649+
}
1650+
1651+
static SgObject throw_continuation_end(SgVM *vm, SgObject args)
1652+
{
1653+
vm->pc = return_code;
1654+
/* store arguments of the continuation to ac */
1655+
if (SG_NULLP(args)) { /* no value */
1656+
/* does this happen? */
1657+
vm->ac = SG_UNDEF;
1658+
vm->valuesCount = 0;
1659+
} else if (SG_NULLP(SG_CDR(args))) { /* usual case */
1660+
vm->ac = SG_CAR(args);
1661+
vm->valuesCount = 1;
1662+
} else { /* multi values */
1663+
SgObject ap;
1664+
int argc = (int)Sg_Length(args), i;
1665+
/* when argc == DEFAULT_VALUES_SIZE+1, it must be in pre-allocated
1666+
buffer */
1667+
if (argc > DEFAULT_VALUES_SIZE+1) {
1668+
SG_ALLOC_VALUES_BUFFER(vm, argc - DEFAULT_VALUES_SIZE -1);
16681669
}
1669-
return vm->ac;
1670+
vm->ac = SG_CAR(args);
1671+
for (i = 0, ap = SG_CDR(args); SG_PAIRP(ap); i++, ap = SG_CDR(ap)) {
1672+
SG_VALUES_SET(vm, i, SG_CAR(ap));
1673+
}
1674+
vm->valuesCount = argc;
16701675
}
1676+
return vm->ac;
16711677
}
16721678

16731679
static SgObject throw_continuation_cc(SgObject result, void **data)
@@ -2002,17 +2008,22 @@ static SgObject throw_delimited_continuation_body(SgObject handlers,
20022008
PUSH_PROMPT_CONT(vm, new_prompt);
20032009
install_prompt(vm, new_prompt);
20042010

2005-
/* Now compute and run wind-in handlers using the composable
2006-
continuation path. We've already aborted to the prompt, so
2007-
current vm->dynamicWinders is at the prompt's level. We need to
2008-
wind into c's winders. */
2011+
/* If the prompt handler is not set, then don't execute winders
2012+
This behaviour is an emulation of the call/delimited-cc
2013+
implemented with abort/cc and call/comp.
2014+
I believe this is *not* a right solution, but it works...
2015+
*/
2016+
if (!SG_FALSEP(node->prompt->handler)) {
2017+
/* If the prompts are not the same, then it's not an escape,
2018+
so reinstall the continuation by splicing*/
2019+
if (node->prompt != prompt) {
2020+
save_cont(vm);
2021+
vm->cont = splice_cont(vm, c->cont, prompt);
2022+
}
2023+
return throw_continuation_end(vm, args);
2024+
}
2025+
/* here we invoke the continuation like composable continuation */
20092026
SgObject wind_handlers = throw_cont_compute_handlers(c, prompt, vm);
2010-
2011-
/* Sg_Printf(Sg_StandardErrorPort(), UC("delim: vm->dw: %A\n"), vm->dynamicWinders); */
2012-
/* Sg_Printf(Sg_StandardErrorPort(), UC("delim: c->dw: %A\n"), c->winders); */
2013-
/* Sg_Printf(Sg_StandardErrorPort(), UC("delim: hndlrs: %A\n"), wind_handlers); */
2014-
2015-
/* Use the regular composable continuation body to process these handlers */
20162027
return throw_continuation_body(wind_handlers, c, args, prompt);
20172028
}
20182029
}

0 commit comments

Comments
 (0)