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