File Coverage

blib/lib/Lox/Function.pm
Criterion Covered Total %
statement 18 40 45.0
branch 0 4 0.0
condition n/a
subroutine 6 18 33.3
pod 0 8 0.0
total 24 70 34.2


line stmt bran cond sub pod time code
1             package Lox::Function;
2 1     1   405 use parent 'Lox::Callable';
  1         256  
  1         4  
3 1     1   49 use strict;
  1         2  
  1         14  
4 1     1   4 use warnings;
  1         1  
  1         19  
5 1     1   12 use Lox::Bool;
  1         2  
  1         65  
6 1     1   5 use Lox::Environment;
  1         2  
  1         97  
7             use overload
8 0 0   0     '""' => sub { sprintf '', $_[0]->declaration->can('name')
9             ? $_[0]->declaration->name->lexeme : 'lambda' },
10 0     0     '!' => sub { $False },
11 0     0     'bool' => sub { $True }, # only false and nil are untrue in Lox
12 1     1   6 fallback => 0;
  1         1  
  1         15  
13              
14             our $VERSION = 0.02;
15              
16             sub new {
17 0     0 0   my ($class, $args) = @_;
18 0           return bless { %$args }, $class;
19             }
20              
21 0     0 0   sub declaration { $_[0]->{declaration} }
22 0     0 0   sub closure { $_[0]->{closure} }
23 0     0 0   sub arity { scalar $_[0]->params->@* }
24 0     0 0   sub params { $_[0]->declaration->params }
25 0     0 0   sub body { $_[0]->declaration->body }
26              
27             sub call {
28 0     0 0   my ($self, $interpreter, $args) = @_;
29 0           my $environment = Lox::Environment->new({ enclosing => $self->closure });
30 0           for (my $i = 0; $i < $self->params->@*; $i++) {
31 0           $environment->define($self->params->[$i]->lexeme,$args->[$i]);
32             }
33             my $sub = sub {
34 0     0     $interpreter->execute_block($self->body, $environment);
35 0           };
36 0           my $retval = $self->call_catch_return($interpreter, $sub);
37 0 0         return $self->{is_initializer} ? $self->closure->get_at(0, 'this')
38             : $retval;
39             }
40              
41             sub bind {
42 0     0 0   my ($self, $instance) = @_;
43 0           my $environment = Lox::Environment->new({ enclosing => $self->closure });
44 0           $environment->define('this', $instance);
45             return Lox::Function->new({
46             is_initializer => $self->{is_initializer},
47 0           declaration => $self->declaration,
48             closure => $environment,
49             });
50             }
51              
52             1;