4107
Return other values along with the current continuation.
This commit is contained in:
parent
504292f6f1
commit
4c5136859d
|
@ -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
39
continuation4.mu
Normal 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
|
||||
}
|
||||
]
|
Loading…
Reference in New Issue
Block a user