pervasive type constraints
[scpubgit/DX.git] / lib / DX / Scope.pm
index 95fb3e3..489f9a3 100644 (file)
@@ -2,11 +2,13 @@ package DX::Scope;
 
 use DX::Class;
 
-has predicates => (is => 'ro', required => 1);
+has predicates => (is => 'ro', isa => HashRef[Predicate], required => 1);
 
-has globals => (is => 'ro', required => 1);
+has globals => (is => 'ro', isa => DictValue, required => 1);
 
-has locals => (is => 'ro', required => 1);
+has locals => (is => 'ro', isa => ArrayRef[DictValue], required => 1);
+
+has lex_map => (is => 'ro', isa => HashRef[ArrayRef[Str]], required => 1);
 
 #has known_facts => (is => 'ro', required => 1);
 
@@ -16,10 +18,16 @@ sub lookup_predicate {
 }
 
 sub lookup {
-  my ($self, $name) = @_;
-  my $lookup_in = ($name =~ /^[_A-Z]/ ? $self->locals->[-1] : $self->globals);
-  return $lookup_in->get_member_at($name)
-   or die "No such name in scope: $name";
+  my ($self, $symbol) = @_;
+  if ($symbol =~ /^[_A-Z]/) {
+    my @mapped = @{$self->lex_map->{$symbol}||[]}
+      or die "No such name in scope: $symbol";
+    my $targ = $self;
+    $targ = $targ->get_member_at($_) for @mapped;
+    return $targ;
+  }
+  return $self->globals->get_member_at($symbol)
+   || die "No such name in scope: $symbol";
 }
 
 sub depth { $#{$_[0]->locals} }
@@ -51,4 +59,12 @@ sub with_member_at {
   );
 }
 
+sub apply_updates {
+  my ($self, @updates) = @_;
+  my @events;
+  my $scope = $self;
+  ($scope, @events) = ($_->apply_to($scope), @events) for @updates;
+  return ($scope, @events);
+}
+
 1;