about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2017-11-05 01:47:03 -0800
committerKartik K. Agaram <vc@akkartik.com>2017-11-05 01:47:03 -0800
commit4c5136859dce2bc752e60b450f64c62ee7e66815 (patch)
tree20553425d104c12dace3ebf59e515364fe797c4d
parent504292f6f1a283af39de305879b50f16d6180caa (diff)
downloadmu-4c5136859dce2bc752e60b450f64c62ee7e66815.tar.gz
4107
Return other values along with the current continuation.
-rw-r--r--076continuation.cc36
-rw-r--r--continuation4.mu39
2 files changed, 75 insertions, 0 deletions
diff --git a/076continuation.cc b/076continuation.cc
index 39c511f3..d190f9e3 100644
--- a/076continuation.cc
+++ b/076continuation.cc
@@ -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
diff --git a/continuation4.mu b/continuation4.mu
new file mode 100644
index 00000000..5957c1be
--- /dev/null
+++ b/continuation4.mu
@@ -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
+  }
+]