File Coverage

blib/lib/Language/Zcode/Parser/Routine.pm
Criterion Covered Total %
statement 35 39 89.7
branch 9 12 75.0
condition n/a
subroutine 9 10 90.0
pod 8 8 100.0
total 61 69 88.4


line stmt bran cond sub pod time code
1             package Language::Zcode::Parser::Routine;
2            
3 2     2   86 use strict;
  2         5  
  2         66  
4 2     2   11 use warnings;
  2         4  
  2         1439  
5            
6             =head1 NAME
7            
8             Language::Zcode::Parser::Routine - A single Z-code subroutine
9            
10             =head2 SYNOPSIS
11            
12             # New routine at address $start, ends at $end
13             my $routine = new Language::Zcode::Parser::Routine $address;
14             $routine->end($end);
15            
16             # Now actually parse it
17             $routine => parse();
18            
19             # ... and look at the parsed commands (which are simple hashes, not objects)
20             my @commands = $routine->commands();
21             print map {$_->{opcode_address}, " ", $_->{opcode}, "\n"} @commands;
22            
23             =head1 DESCRIPTION
24            
25             A set of Z-code commands at a given address.
26            
27             =cut
28            
29             =head2 new (address)
30            
31             Create a new subroutine at given address. The Z-code will not be parsed until
32             a parse() command is explicitly given.
33            
34             =cut
35            
36             sub new {
37 67     67 1 146 my ($class, $address, %arg) = @_;
38 67         478 my $self = {
39             locals => [], # default values for local variables
40             commands => [], # parsed Z-code commands in this sub
41             txd_commands => [], # commands in this sub read by txd (for debugging)
42             %arg,
43             };
44 67         317 bless $self, $class;
45 67         184 $self->address($address);
46             # print "New $address: ",%$self,"\n";
47 67         285 return $self;
48             }
49            
50             =head2 address (val)
51            
52             get/set start address of the subroutine
53            
54             =cut
55            
56             sub address {
57 708     708 1 2373 my ($self, $val) = @_;
58 708 100       1768 $self->{address} = $val if defined $val;
59 708         2344 return $self->{address};
60             }
61            
62             =head2 end (val)
63            
64             get/set end address (including padding zeroes!) of the subroutine
65            
66             =cut
67            
68             sub end {
69 67     67 1 786 my ($self, $val) = @_;
70 67 50       219 $self->{end} = $val if defined $val;
71 67         178 return $self->{end};
72             }
73            
74             =head2 last_command_address (val)
75            
76             get/set address of last command in the subroutine (needed because "end"
77             may include padding zeroes)
78            
79             =cut
80            
81             sub last_command_address {
82 133     133 1 207 my ($self, $val) = @_;
83 133 100       3361 $self->{last_command_address} = $val if defined $val;
84 133         562 return $self->{last_command_address};
85             }
86            
87             =head2 locals (list of values)
88            
89             get/set default values of this sub's local variables (returns list, not ref)
90            
91             =cut
92            
93             sub locals {
94 134     134 1 218 my $self = shift;
95 134 100       522 $self->{locals} = [@_] if @_;
96 134         190 return @{ $self->{locals} }
  134         669  
97             }
98            
99             =head2 commands (list of values)
100            
101             get/set parsed Z-code commands in this sub (returns list, not ref)
102            
103             =cut
104            
105             sub commands {
106 132     132 1 826 my $self = shift;
107 132 100       1680 $self->{commands} = [@_] if @_;
108 132         218 return @{ $self->{commands} }
  132         494  
109             }
110            
111             =head2 txd_commands (list of values)
112            
113             get/set commands in this sub as returned by the txd Z-code parsing program,
114             to compare with my Pure Perl results. (returns list, not ref)
115            
116             =cut
117            
118             sub txd_commands {
119 0     0 1 0 my $self = shift;
120 0 0       0 $self->{txd_commands} = [@_] if @_;
121 0         0 return @{ $self->{txd_commands} }
  0         0  
122             }
123            
124             =head2 parse()
125            
126             Parse (and store) the commands in this sub
127            
128             =cut
129            
130             sub parse {
131 66     66 1 65872 my $self = shift;
132 66         266 my ($addr, $stop) = ($self->address, $self->last_command_address);
133             # Side effect: moves PC to first command in the sub
134 66         379 $self->locals(&Language::Zcode::Parser::Opcode::parse_sub_header($addr));
135 66         102 my @commands;
136 66         328 push @commands, { &Language::Zcode::Parser::Opcode::parse_command() }
137             until $Language::Zcode::Parser::Opcode::PC > $stop;
138 66         497 $self->commands(@commands);
139 66         658 return;
140             }
141            
142             1;