allocate new locals in consider instead of up-front
Matt S Trout [Sun, 8 Apr 2018 17:35:58 +0000 (17:35 +0000)]
lib/DX/QueryState.pm
lib/DX/Step/ConsiderProposition.pm

index cc438e7..cd54b82 100644 (file)
@@ -31,19 +31,8 @@ sub new_search_process_for {
   my $scope = DX::Scope->new(
     predicates => $self->predicates,
     globals => $self->globals,
-    locals => [
-      dict(
-        map +($_ => DX::Value::Unset->new(
-                      action_builder => DX::ActionBuilder::UnsetValue->new(
-                        target_path => [ 0, $_ ],
-                      )
-                    )
-        ), @local_names
-      )
-    ],
-    lex_map => {
-      map +($_ => [ 0, $_ ]), @local_names
-    }
+    locals => [ dict() ],
+    lex_map => { }
   );
   my $hyp = DX::Hypothesis->new(
     scope => $scope,
index 485d14b..386048c 100644 (file)
@@ -15,7 +15,36 @@ sub apply_to {
       @{$self->proposition->for_deparse->[1]},
     ],
   ];
-  return $ss->but(next_step => $self->proposition->resolve_for($hyp->scope));
+  my $old_scope = (my $old_hyp = $ss->current_hypothesis)->scope;
+  my @old_locals = @{$old_scope->locals};
+  my $top_level = $#old_locals;
+  my $top = pop @old_locals;
+  my $top_members = $top->members;
+  my @new_names = grep !exists $top_members->{$_},
+                    keys %{$self->proposition->introduced_names};
+  my $new_scope = $old_scope->but(
+    locals => [
+      @old_locals,
+      $top->but(members => {
+        %{$top_members},
+        map +($_ => DX::Value::Unset->new(
+                      action_builder => DX::ActionBuilder::UnsetValue->new(
+                        target_path => [ $top_level, $_ ],
+                      )
+                    )
+        ), @new_names
+      }),
+    ],
+    lex_map => {
+      %{$old_scope->lex_map},
+      map +($_ => [ $top_level, $_ ]), @new_names
+    }
+  );
+  my $new_hyp = $old_hyp->but(scope => $new_scope);
+  return $ss->but(
+    current_hypothesis => $new_hyp,
+    next_step => $self->proposition->resolve_for($new_scope)
+  );
 }
 
 1;