Return other values along with the current continuation.
This commit is contained in:
Kartik K. Agaram 2017-11-05 01:47:03 -08:00
parent 504292f6f1
commit 4c5136859d
2 changed files with 75 additions and 0 deletions

View File

@ -176,6 +176,8 @@ case RETURN_CONTINUATION_UNTIL_MARK: {
// return it as the result of the marked call
products.resize(1);
products.at(0).push_back(Next_delimited_continuation_id);
// return any other ingredients passed in
copy(ingredients.begin(), ingredients.end(), inserter(products, products.end()));
++Next_delimited_continuation_id;
break; // continue to process rest of marked call
}
@ -281,3 +283,37 @@ bool is_mu_continuation(reagent/*copy*/ x) {
canonize_type(x);
return x.type && x.type->atom && x.type->value == get(Type_ordinal, "continuation");
}
:(scenario continuations_can_return_values)
def main [
local-scope
k:continuation, 1:num/raw <- call-with-continuation-mark f
]
def f [
local-scope
g
]
def g [
local-scope
return-continuation-until-mark 34
stash [continuation called]
]
# entering main
+mem: new alloc: 1000
+run: {k: "continuation"}, {1: "number", "raw": ()} <- call-with-continuation-mark {f: "recipe-literal"}
# entering f
+mem: new alloc: 1004
# entering g
+mem: new alloc: 1007
# return control to main
+run: return-continuation-until-mark {34: "literal"}
# no allocs abandoned yet
+mem: storing 34 in location 1
# end of main
# make sure no memory leaks..
+mem: trying to reclaim local k:continuation
+mem: automatically abandoning 1007
+mem: automatically abandoning 1004
+mem: automatically abandoning 1000
# ..even though we never called the continuation
-app: continuation called

39
continuation4.mu Normal file
View File

@ -0,0 +1,39 @@
# example program showing 'return-continuation-until-mark' return other values
# alongside continuations
def main [
local-scope
l:&:list:num <- copy 0
l <- push 3, l
l <- push 2, l
l <- push 1, l
k:continuation, x:num, done?:bool <- call-with-continuation-mark create-yielder, l
{
break-if done?
$print x 10/newline
k, x:num, done?:bool <- call k
loop
}
]
def create-yielder l:&:list:num -> n:num, done?:bool [
local-scope
load-ingredients
{
done? <- equal l, 0
# Our current primitives can lead to gnarly code to ensure that we always
# statically match a continuation call with a 'return-continuation-until-mark'.
# Try to design functions to either always return or always return continuation.
{
# should we have conditional versions of return-continuation-until-mark
# analogous to return-if and return-unless? Names get really long.
break-unless done?
return-continuation-until-mark 0, done?
return 0, done? # just a guard rail; should never execute
}
n <- first l
l <- rest l
return-continuation-until-mark n, done?
loop
}
]