Skip to content

Commit 6c4084a

Browse files
committed
call-with-values is a procedure
1 parent a0c0d8b commit 6c4084a

File tree

7 files changed

+24
-51
lines changed

7 files changed

+24
-51
lines changed

src/alloc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,15 @@ obj Mcallcc_continuation(obj prev, obj env, obj winders) {
187187
return x;
188188
}
189189

190-
obj Mcallwv_continuation(obj prev, obj env, obj consumer) {
190+
obj Mcallwv_continuation(obj prev, obj env, obj producer, obj consumer) {
191191
obj x = GC_malloc(Mcontinuation_callwv_size);
192192
obj_type(x) = CONTINUATON_OBJ_TYPE;
193193
Mcontinuation_type(x) = CALLWV_CONT_TYPE;
194194
Mcontinuation_immutablep(x) = 0;
195195
Mcontinuation_capturedp(x) = 0;
196196
Mcontinuation_prev(x) = prev;
197197
Mcontinuation_env(x) = env;
198-
Mcontinuation_callwv_producer(x) = Mfalse;
198+
Mcontinuation_callwv_producer(x) = producer;
199199
Mcontinuation_callwv_consumer(x) = consumer;
200200
return x;
201201
}

src/check.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,6 @@ static void check_1ary_syntax(obj e) {
2020
bad_syntax_exn(e);
2121
}
2222

23-
// Already assumes `expr` is `(<name> . <???>)`
24-
// Check: `expr` must be `(<name> <datum>)
25-
static void check_2ary_syntax(obj e) {
26-
obj rib;
27-
28-
rib = Mcdr(e);
29-
if (!Mconsp(rib))
30-
bad_syntax_exn(e);
31-
32-
rib = Mcdr(rib);
33-
if (!Mconsp(rib) || !Mnullp(Mcdr(rib)))
34-
bad_syntax_exn(e);
35-
}
36-
3723
// Already assumes `expr` is `(<name> . <???>)`
3824
// Check: `expr` must be `(<name> <datum> <datum> <datum>)
3925
static void check_3ary_syntax(obj e) {
@@ -243,10 +229,6 @@ void check_expr(obj e) {
243229
check_setb(e);
244230
} else if (hd == Mquote_symbol) {
245231
check_1ary_syntax(e);
246-
} else if (hd == Mcallwv_symbol) {
247-
check_2ary_syntax(e);
248-
check_expr(Mcadr(e));
249-
check_expr(Mcaddr(e));
250232
} else if (Mlistp(e)) {
251233
for (it = e; !Mnullp(it); it = Mcdr(it))
252234
check_expr(Mcar(it));

src/eval.c

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -336,11 +336,11 @@ static obj eval_k(obj e) {
336336
// quote
337337
x = Mcadr(e);
338338
goto do_k;
339-
} else if (hd == Mcallwv_symbol) {
340-
// call-with-values
341-
Mtc_cc(tc) = Mcallwv_continuation(Mtc_cc(tc), Mtc_env(tc), Mcaddr(e));
342-
e = Mcadr(e);
343-
goto loop;
339+
// } else if (hd == Mcallwv_symbol) {
340+
// // call-with-values
341+
// Mtc_cc(tc) = Mcallwv_continuation(Mtc_cc(tc), Mtc_env(tc), Mcaddr(e));
342+
// e = Mcadr(e);
343+
// goto loop;
344344
} else {
345345
// application
346346
Mtc_cc(tc) = Mapp_continuation(Mtc_cc(tc), Mtc_env(tc), e);
@@ -381,9 +381,14 @@ static obj eval_k(obj e) {
381381
Mtc_cc(tc) = Mdynwind_continuation(Mtc_cc(tc), Mtc_env(tc), Mcar(args), Mcadr(args), Mcaddr(args));
382382
x = Mvoid;
383383
} else if (f == callcc_prim) {
384+
check_callcc(Mcar(args));
384385
continuation_set_immutable(Mtc_cc(tc)); // freeze the continuation chain
385386
Mtc_cc(tc) = Mcallcc_continuation(Mtc_cc(tc), Mtc_env(tc), Mtc_wnd(tc));
386387
x = Mcar(args);
388+
} else if (f == callwv_prim) {
389+
assert_thunk("call-with-values", Mcar(args));
390+
Mtc_cc(tc) = Mcallwv_continuation(Mtc_cc(tc), Mtc_env(tc), Mcar(args), Mcadr(args));
391+
x = Mvoid;
387392
} else {
388393
x = do_prim(f, args);
389394
}
@@ -462,9 +467,6 @@ static obj eval_k(obj e) {
462467
goto do_k;
463468
} else {
464469
// capturing current continuation
465-
assert_single_value(Mtc_cc(tc), x);
466-
check_callcc(x);
467-
468470
Mtc_cc(tc) = continuation_mutable(Mtc_cc(tc));
469471
Mcontinuation_capturedp(Mtc_cc(tc)) = 1;
470472

@@ -478,27 +480,13 @@ static obj eval_k(obj e) {
478480
// call-with-values expressions
479481
case CALLWV_CONT_TYPE:
480482
Mtc_cc(tc) = continuation_mutable(Mtc_cc(tc));
481-
if (Mfalsep(Mcontinuation_callwv_producer(Mtc_cc(tc)))) {
482-
// evaluated producer syntax
483-
assert_single_value(Mtc_cc(tc), x);
484-
assert_thunk("call-with-values", x);
485-
486-
Mcontinuation_callwv_producer(Mtc_cc(tc)) = x;
487-
e = Mcontinuation_callwv_consumer(Mtc_cc(tc));
488-
Mtc_env(tc) = Mcontinuation_env(Mtc_cc(tc));
489-
goto loop;
490-
} else if (!Mprocp(Mcontinuation_callwv_consumer(Mtc_cc(tc)))) {
491-
// evaluated consumer syntax
492-
assert_single_value(Mtc_cc(tc), x);
493-
if (!Mprocp(x)) {
494-
minim_error1("call-with-values", "expected a procedure", x);
495-
}
496-
497-
Mcontinuation_callwv_consumer(Mtc_cc(tc)) = x;
483+
if (Mprocp(Mcontinuation_callwv_producer(Mtc_cc(tc)))) {
484+
// first time => evaluate producer
498485
f = Mcontinuation_callwv_producer(Mtc_cc(tc));
499486
args = Mnull;
500487

501488
Mtc_env(tc) = Mcontinuation_env(Mtc_cc(tc));
489+
Mcontinuation_callwv_producer(Mtc_cc(tc)) = Mfalse;
502490
goto do_app;
503491
} else {
504492
// evaluated producer procedure

src/expand.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,6 @@ obj expand_expr(obj e) {
288288
return Mlist3(Msetb_symbol, Mcadr(e), expand_expr(Mcaddr(e)));
289289
} else if (hd == Mquote_symbol) {
290290
return e;
291-
} else if (hd == Mcallwv_symbol) {
292-
return Mlist3(Mcallwv_symbol, expand_expr(Mcadr(e)), expand_expr(Mcaddr(e)));
293291
} else {
294292
hd = tl = Mcons(expand_expr(Mcar(e)), Mnull);
295293
for (it = Mcdr(e); !Mnullp(it); it = Mcdr(it)) {

src/global.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ obj Mvalues;
1111
obj Munbound;
1212

1313
obj Mbegin_symbol;
14-
obj Mcallwv_symbol;
1514
obj Mif_symbol;
1615
obj Mlambda_symbol;
1716
obj Mlet_symbol;
@@ -47,7 +46,6 @@ void minim_init(void) {
4746

4847
// intern symbols
4948
Mbegin_symbol = Mintern("begin");
50-
Mcallwv_symbol = Mintern("call-with-values");
5149
Mif_symbol = Mintern("if");
5250
Mlambda_symbol = Mintern("lambda");
5351
Mlet_symbol = Mintern("let");

src/minim.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ typedef void *obj;
5454
// Syntax
5555

5656
extern obj Mbegin_symbol;
57-
extern obj Mcallwv_symbol;
5857
extern obj Mif_symbol;
5958
extern obj Mlambda_symbol;
6059
extern obj Mlet_symbol;
@@ -309,7 +308,7 @@ obj Mseq_continuation(obj prev, obj env, obj seq);
309308
obj Mlet_continuation(obj prev, obj env, obj bindings, obj body);
310309
obj Msetb_continuation(obj prev, obj env, obj name);
311310
obj Mcallcc_continuation(obj prev, obj env, obj winders);
312-
obj Mcallwv_continuation(obj prev, obj env, obj producer);
311+
obj Mcallwv_continuation(obj prev, obj env, obj producer, obj consumer);
313312
obj Mdynwind_continuation(obj prev, obj env, obj pre, obj val, obj post);
314313
obj Mwinders_continuation(obj prev, obj env, obj winders);
315314

@@ -478,6 +477,7 @@ extern obj fx_gt_prim;
478477
extern obj fx_lt_prim;
479478

480479
extern obj callcc_prim;
480+
extern obj callwv_prim;
481481
extern obj dynwind_prim;
482482
extern obj values_prim;
483483

src/prim.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ obj fx_gt_prim;
2424
obj fx_lt_prim;
2525

2626
obj callcc_prim;
27+
obj callwv_prim;
2728
obj dynwind_prim;
2829
obj values_prim;
2930

@@ -40,6 +41,10 @@ static obj callcc_proc() {
4041
minim_error("callcc_proc()", "should never call");
4142
}
4243

44+
static obj callwv_proc() {
45+
minim_error("callwv_proc()", "should never call");
46+
}
47+
4348
static obj dynwind_proc() {
4449
minim_error("dynwind_proc()", "should never call");
4550
}
@@ -73,6 +78,7 @@ void init_prims(void) {
7378
fx_lt_prim = Mprim(Mfx_lt, 2, "fx2<");
7479

7580
callcc_prim = Mprim(callcc_proc, 1, "call-with-current-continuation");
81+
callwv_prim = Mprim(callwv_proc, 2, "call-with-values");
7682
dynwind_prim = Mprim(dynwind_proc, 3, "dynamic-wind");
7783
values_prim = Mprim(values_proc, -1, "values");
7884
}
@@ -106,6 +112,7 @@ obj prim_env(obj env) {
106112

107113
env_insert(env, Mintern("call/cc"), callcc_prim);
108114
env_add_prim(env, callcc_prim);
115+
env_add_prim(env, callwv_prim);
109116
env_add_prim(env, dynwind_prim);
110117
env_add_prim(env, values_prim);
111118

0 commit comments

Comments
 (0)