basic return stack usage
[scpubgit/DKit.git] / lib / DX / State.pm
index 4815ab2..66287dd 100644 (file)
@@ -54,12 +54,28 @@ sub then {
   $self->new(%$self, next_op => $then);
 }
 
+sub select_next_op {
+  my ($self) = @_;
+  return $self->next_op || do {
+    if (my @stack = @{$self->return_stack}) {
+      my $top = pop @stack;
+      DX::Op::FromCode->new(
+        code => sub {
+          $_[1]->new(%{$_[1]}, return_stack => \@stack, next_op => $top)
+        }
+      );
+    } else {
+      undef;
+    }
+  };
+}
+
 sub run {
   my ($state) = @_;
   with_return {
     my ($return) = @_;
     local our $No_Options_Handler = $return;
-    while (my $op = $state->next_op) {
+    while (my $op = $state->select_next_op) {
       $state = $op->run($state);
     }
     return $state;