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; |