File Coverage

blib/lib/Lox/Environment.pm
Criterion Covered Total %
statement 15 36 41.6
branch 2 10 20.0
condition n/a
subroutine 6 11 54.5
pod 0 9 0.0
total 23 66 34.8


line stmt bran cond sub pod time code
1             package Lox::Environment;
2 1     1   5 use strict;
  1         2  
  1         40  
3 1     1   4 use warnings;
  1         1  
  1         438  
4             our $VERSION = 0.02;
5              
6             sub new {
7 1     1 0 4 my ($class, $args) = @_;
8 1         4 return bless {
9             values => {},
10             %$args,
11             }, $class;
12             }
13              
14 0     0 0 0 sub enclosing { $_[0]->{enclosing} }
15 4     4 0 14 sub values { $_[0]->{values} }
16              
17             sub define {
18 2     2 0 5 my ($self, $name, $value) = @_;
19 2         6 $self->values->{$name} = $value;
20             }
21              
22             sub ancestor {
23 0     0 0 0 my ($self, $distance) = @_;
24 0         0 my $environment = $self;
25 0         0 for (1..$distance) {
26 0         0 $environment = $environment->enclosing;
27             }
28 0         0 return $environment;
29             }
30              
31             sub get_at {
32 0     0 0 0 my ($self, $distance, $token_lexeme) = @_;
33 0         0 return $self->ancestor($distance)->values->{$token_lexeme};
34             }
35              
36             sub assign_at {
37 0     0 0 0 my ($self, $distance, $token, $value) = @_;
38 0         0 $self->ancestor($distance)->values->{$token->lexeme} = $value;
39             }
40              
41             sub get {
42 1     1 0 3 my ($self, $token) = @_;
43 1 50       3 if (exists $self->values->{$token->lexeme}) {
44 1         12 my $v = $self->values->{$token->lexeme};
45 1 50       5 return $v if defined $v;
46 0           Lox::runtime_error($token, sprintf 'Uninitialized variable \'%s\'', $token->lexeme);
47             }
48 0 0         if ($self->enclosing) {
49 0           return $self->enclosing->get($token);
50             }
51 0           Lox::runtime_error($token, sprintf 'Undefined variable \'%s\'', $token->lexeme);
52             }
53              
54             sub assign {
55 0     0 0   my ($self, $token, $value) = @_;
56 0 0         if (exists $self->values->{$token->lexeme}) {
57 0           $self->values->{$token->lexeme} = $value;
58 0           return;
59             }
60              
61 0 0         if ($self->enclosing) {
62 0           return $self->enclosing->assign($token, $value);
63             }
64 0           Lox::runtime_error($token, sprintf 'Undefined variable "%s"', $token->lexeme);
65             }
66              
67             1;