File Coverage

blib/lib/Language/P/Toy/Runtime.pm
Criterion Covered Total %
statement 66 68 97.0
branch 4 6 66.6
condition 1 3 33.3
subroutine 15 16 93.7
pod 1 11 9.0
total 87 104 83.6


line stmt bran cond sub pod time code
1             package Language::P::Toy::Runtime;
2              
3 30     30   464661 use strict;
  30         63  
  30         1076  
4 30     30   154 use warnings;
  30         62  
  30         1042  
5 30     30   155 use base qw(Class::Accessor::Fast);
  30         50  
  30         28615  
6              
7 30     30   132907 use Language::P::Toy::Value::MainSymbolTable;
  30         97  
  30         425  
8 30     30   18543 use Language::P::ParseTree qw(:all);
  30         115  
  30         79060  
9              
10             __PACKAGE__->mk_ro_accessors( qw(symbol_table _variables) );
11              
12             our $current;
13              
14             sub new {
15 28     28 1 1259 my( $class, $args ) = @_;
16              
17 28 50       148 Carp::confess( "Only one runtime supported" ) if $current;
18              
19 28         516 my $self = $class->SUPER::new( $args );
20              
21 28   33     1183 $self->{symbol_table} ||= Language::P::Toy::Value::MainSymbolTable->new;
22 28         212 $self->{_variables} = { osname => $^O,
23             };
24              
25 28         123 return $current = $self;
26             }
27              
28             sub set_option {
29 0     0 0 0 my( $class, $option, $value ) = @_;
30              
31 0         0 return 0;
32             }
33              
34             sub reset {
35 6     6 0 44 my( $self ) = @_;
36              
37 6         24 $self->{_stack} = [ [ -1, undef, CXT_VOID ], undef ];
38 6         34 $self->{_frame} = @{$self->{_stack}};
  6         20  
39             }
40              
41             sub run_last_file {
42 15     15 0 155 my( $self, $code ) = @_;
43              
44 15         83 $self->set_bytecode( $code->bytecode );
45 15         80 $self->{_stack} = [ (undef) x $code->stack_size,
46             [ -1, undef, CXT_VOID ], $code->lexicals ];
47 15         168 $self->{_frame} = @{$self->{_stack}};
  15         58  
48 15         83 return $self->run;
49             }
50              
51             sub set_bytecode {
52 6003     6003 0 18612 my( $self, $bytecode ) = @_;
53              
54 6003         8210 $self->{_pc} = 0;
55 6003         13537 $self->{_bytecode} = $bytecode;
56             }
57              
58             sub run_bytecode {
59 6     6 0 29 my( $self, $bytecode ) = @_;
60              
61 6         26 $self->set_bytecode( $bytecode );
62 6         19 $self->run;
63             }
64              
65             sub run {
66 166     166 0 242 my( $self ) = @_;
67              
68 166 50       471 return if $self->{_pc} < 0;
69              
70             # use Data::Dumper;
71             # print Dumper( $self->{_bytecode} );
72              
73 166         214 for(;;) {
74 62879         103224 my $op = $self->{_bytecode}->[$self->{_pc}];
75 62879         301607 my $pc = $op->{function}->( $op, $self, $self->{_pc} );
76              
77 62879 100       130823 last if $pc < 0;
78 62713         96117 $self->{_pc} = $pc;
79             }
80             }
81              
82             sub stack_copy {
83 4     4 0 22 my( $self ) = @_;
84              
85 4         15 return @{$self->{_stack}};
  4         19  
86             }
87              
88             sub push_frame {
89 2991     2991 0 14464 my( $self, $size ) = @_;
90 2991         4323 my $last_frame = $self->{_frame};
91 2991         3053 my $stack_size = $#{$self->{_stack}};
  2991         6306  
92              
93 2991         5290 $#{$self->{_stack}} = $self->{_frame} = $stack_size + $size + 1;
  2991         5226  
94 2991         8377 $self->{_stack}->[$self->{_frame}] = [ $stack_size, $last_frame ];
95              
96             # print "Stack size: $stack_size -> $self->{_frame}\n";
97              
98 2991         6936 return $self->{_frame};
99             }
100              
101             sub pop_frame {
102 2991     2991 0 7910 my( $self, $size ) = @_;
103 2991         5241 my $last_frame = $self->{_stack}->[$self->{_frame}];
104              
105             # print "New stack size: $last_frame->[0]\n";
106              
107             # TODO unwind
108              
109 2991         3330 $#{$self->{_stack}} = $last_frame->[0];
  2991         12075  
110 2991         6925 $self->{_frame} = $last_frame->[1];
111             }
112              
113             sub call_return {
114 2991     2991 0 3402 my( $self ) = @_;
115 2991         6307 my $rpc = $self->{_stack}->[$self->{_frame} - 2][0];
116 2991         5077 my $bytecode = $self->{_stack}->[$self->{_frame} - 2][1];
117              
118 2991         5726 $self->set_bytecode( $bytecode );
119 2991         5277 $self->pop_frame;
120              
121 2991         6575 return $rpc;
122             }
123              
124             1;