mirror of
https://github.com/false-schemers/skint.git
synced 2024-12-27 21:58:53 +01:00
call-with-values w/continuation as consumer tail-calls
This commit is contained in:
parent
be7f66fe9d
commit
75e26a58d9
2 changed files with 23 additions and 12 deletions
34
i.c
34
i.c
|
@ -400,23 +400,35 @@ define_instruction(appl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
define_instruction(cwmv) {
|
define_instruction(cwmv) {
|
||||||
obj prd = ac, cns = spop();
|
obj t = ac, x = spop();
|
||||||
/* arrange return to cwmv code w/cns */
|
ckx(t); ckx(x);
|
||||||
ckx(prd); ckx(cns);
|
if (vmcloref(x, 0) == cx_continuation_2Dadapter_2Dcode) {
|
||||||
spush(cns);
|
/* arrange call of t with x as continuation */
|
||||||
spush(cx_callmv_2Dadapter_2Dclosure);
|
int n = vmclolen(x) - 1;
|
||||||
spush(obj_from_fixnum(0));
|
assert((cxg_rend - cxg_regs - VM_REGC) > n);
|
||||||
/* call the producer */
|
sp = r + VM_REGC; /* stack is empty */
|
||||||
rd = prd; rx = obj_from_fixnum(0); ac = obj_from_fixnum(0);
|
memcpy(sp, &vmcloref(x, 1), n*sizeof(obj));
|
||||||
callsubi();
|
sp += n; /* contains n elements now */
|
||||||
|
rd = t; rx = obj_from_fixnum(0);
|
||||||
|
ac = obj_from_fixnum(0);
|
||||||
|
callsubi();
|
||||||
|
} else {
|
||||||
|
/* arrange return to cwmv code w/x */
|
||||||
|
spush(x);
|
||||||
|
spush(cx_callmv_2Dadapter_2Dclosure);
|
||||||
|
spush(obj_from_fixnum(0));
|
||||||
|
/* call the producer */
|
||||||
|
rd = t; rx = obj_from_fixnum(0); ac = obj_from_fixnum(0);
|
||||||
|
callsubi();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
define_instruction(rcmv) {
|
define_instruction(rcmv) {
|
||||||
/* single-value producer call returns here with result in ac, cns on stack */
|
/* single-value producer call returns here with result in ac, cns on stack */
|
||||||
obj val = ac, cns = spop();
|
obj val = ac, x = spop();
|
||||||
/* tail-call the consumer with the returned value */
|
/* tail-call the consumer with the returned value */
|
||||||
spush(val); ac = obj_from_fixnum(1);
|
spush(val); ac = obj_from_fixnum(1);
|
||||||
rd = cns; rx = obj_from_fixnum(0);
|
rd = x; rx = obj_from_fixnum(0);
|
||||||
callsubi();
|
callsubi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
i.h
1
i.h
|
@ -482,7 +482,6 @@ declare_integrable(NULL, "addd", 0, "%cdddar", 1, INLINED)
|
||||||
declare_integrable(NULL, "dddd", 0, "%cddddr", 1, INLINED)
|
declare_integrable(NULL, "dddd", 0, "%cddddr", 1, INLINED)
|
||||||
|
|
||||||
/* globals */
|
/* globals */
|
||||||
declare_integrable(NULL, NULL, 0, "%ccc", 1, "%1K1,.1[11")
|
|
||||||
declare_integrable(NULL, NULL, 0, "%appl", 2, "%2_!K3")
|
declare_integrable(NULL, NULL, 0, "%appl", 2, "%2_!K3")
|
||||||
declare_integrable(NULL, NULL, 0, "%cwmv", 2, "%2_!K4")
|
declare_integrable(NULL, NULL, 0, "%cwmv", 2, "%2_!K4")
|
||||||
declare_integrable(NULL, NULL, 0, "%sdmv", -1, "K6")
|
declare_integrable(NULL, NULL, 0, "%sdmv", -1, "K6")
|
||||||
|
|
Loading…
Reference in a new issue