initial skeleton for deparser
[scpubgit/DX.git] / lib / DX / Scope.pm
1 package DX::Scope;
2
3 use DX::Class;
4
5 has predicates => (is => 'ro', required => 1);
6
7 has globals => (is => 'ro', required => 1);
8
9 has locals => (is => 'ro', required => 1);
10
11 #has known_facts => (is => 'ro', required => 1);
12
13 sub lookup_predicate {
14   my ($self, $predicate) = @_;
15   return $self->predicates->{$predicate} || die "No such predicate: $predicate";
16 }
17
18 sub lookup {
19   my ($self, $name) = @_;
20   my $lookup_in = ($name =~ /^[_A-Z]/ ? $self->locals->[-1] : $self->globals);
21   return $lookup_in->get_member_at($name)
22    or die "No such name in scope: $name";
23 }
24
25 sub depth { $#{$_[0]->locals} }
26
27 sub prune_to {
28   my ($self, $to) = @_;
29   $self->but(locals => [ @{$self->locals}[0..$to] ]);
30 }
31
32 sub get_member_at {
33   my ($self, $at) = @_;
34   if ($at =~ /^[0-9]+$/) {
35     return $self->locals->[$at];
36   }
37   return $self->globals->get_member_at($at);
38 }
39
40 sub with_member_at {
41   my ($self, $at, $value) = @_;
42   if ($at =~ /^[0-9]+$/) {
43     my @locals = @{$self->locals};
44     $locals[$at] = $value;
45     return $self->but(
46       locals => \@locals
47     );
48   }
49   return $self->but(
50     globals => $self->globals->with_member_at($at, $value)
51   );
52 }
53
54 sub apply_updates {
55   my ($self, @updates) = @_;
56   my @events;
57   my $scope = $self;
58   ($scope, @events) = ($_->apply_to($scope), @events) for @updates;
59   return ($scope, @events);
60 }
61
62 1;