about summary refs log tree commit diff stats
path: root/076continuation.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2018-03-15 22:31:13 -0700
committerKartik K. Agaram <vc@akkartik.com>2018-03-15 22:38:15 -0700
commit53ba69a7c0110ffbe1173411a792ecf53c9028bb (patch)
tree1188027481b749415c16f56dfc3cdb115184df4c /076continuation.cc
parentf8f222454e15737ecf164899f8d28fabe6069a31 (diff)
downloadmu-53ba69a7c0110ffbe1173411a792ecf53c9028bb.tar.gz
4226 - example program: exceptions
Pretty klunky; we're violating the type system by prepending an extra result,
so functions we want to catch exceptions around have to be header-less
and check input types at run-time.
Diffstat (limited to '076continuation.cc')
-rw-r--r--076continuation.cc24
1 files changed, 21 insertions, 3 deletions
diff --git a/076continuation.cc b/076continuation.cc
index 8a7b3b87..c08e741a 100644
--- a/076continuation.cc
+++ b/076continuation.cc
@@ -34,6 +34,11 @@
 //:  * Conversely, you can pass ingredients to a continuation when calling it,
 //:    to make it available to products of 'return-continuation-until-mark'.
 //:    See continuation5.mu.
+//:  * There can be multiple continuation marks on the stack at once;
+//:    'call-with-continuation-mark' and 'return-continuation-until-mark' both
+//:    need to pass in a tag to coordinate on the correct mark. This allows us
+//:    to save multiple continuations for different purposes (say if one is
+//:    for exceptions) with overlapping stack frames. See exception.mu.
 //:
 //: Inspired by James and Sabry, "Yield: Mainstream delimited continuations",
 //: Workshop on the Theory and Practice of Delimited Continuations, 2011.
@@ -132,15 +137,28 @@ case CALL_WITH_CONTINUATION_MARK: {
     trace("trace") << "delimited continuation; incrementing callstack depth to " << Trace_stream->callstack_depth << end();
     assert(Trace_stream->callstack_depth < 9000);  // 9998-101 plus cushion
   }
-  const instruction& caller_instruction = current_instruction();
+  instruction/*copy*/ caller_instruction = current_instruction();
   Current_routine->calls.front().continuation_mark_tag = current_instruction().ingredients.at(0).value;
   Current_routine->calls.push_front(call(Recipe_ordinal[current_instruction().ingredients.at(1).name]));
-  ingredients.erase(ingredients.begin());  // drop the mark
-  ingredients.erase(ingredients.begin());  // drop the callee
+  // drop the mark
+  caller_instruction.ingredients.erase(caller_instruction.ingredients.begin());
+  ingredients.erase(ingredients.begin());
+  // drop the callee
+  caller_instruction.ingredients.erase(caller_instruction.ingredients.begin());
+  ingredients.erase(ingredients.begin());
   finish_call_housekeeping(caller_instruction, ingredients);
   continue;
 }
 
+:(scenario next_ingredient_inside_continuation)
+recipe main [
+  call-with-continuation-mark 233/mark, f, 1/true
+]
+recipe f [
+  10:bool <- next-input
+]
++mem: storing 1 in location 10
+
 //: save the slice of current call stack until the 'call-with-continuation-mark'
 //: call, and return it as the result.
 //: todo: implement delimited continuations in Mu's memory