File Coverage

blib/lib/VM/Dreamer/IO.pm
Criterion Covered Total %
statement 9 53 16.9
branch 0 12 0.0
condition n/a
subroutine 3 8 37.5
pod 5 5 100.0
total 17 78 21.7


line stmt bran cond sub pod time code
1             package VM::Dreamer::IO;
2              
3 1     1   6 use strict;
  1         2  
  1         32  
4 1     1   5 use warnings;
  1         2  
  1         38  
5              
6             our $VERSION = '0.851';
7              
8 1     1   7 use VM::Dreamer::Validate qw{ get_valid_input_regex };
  1         1  
  1         611  
9              
10             require Exporter;
11              
12             our @ISA = qw(Exporter);
13             our @EXPORT_OK = qw( get_valid_input_from_user add_input_to_inbox shift_inbox_to_memory add_to_outbox shift_outbox_to_user );
14              
15             sub get_valid_input_from_user {
16 0     0 1   my $machine = shift;
17 0           my $max_tries = 5;
18              
19 0 0         unless ($machine) {
20 0           die "Please pass the machine href to get_input_from_user";
21             }
22              
23 0           my $input;
24 0           my $valid_input = get_valid_input_regex($machine);
25              
26 0           my $greatest_instruction = $machine->{meta}->{greatest}->{instruction};
27 0           my $base = $machine->{meta}->{base};
28 0           my $instruction_width = $machine->{meta}->{width}->{instruction};
29              
30 0           my $tries;
31 0           for ( $tries = 1; $tries <= $max_tries; $tries++ ) {
32 0           print "Please enter a number from 0 to $greatest_instruction in base $base\n";
33              
34 0           $input = readline(*STDIN);
35 0           chomp $input;
36 0           my $length = length($input);
37              
38 0 0         if (!$length) {
    0          
    0          
39 0           print "It doesn't look like you entered any characters. ";
40 0           next;
41             }
42             elsif ( $length > $instruction_width ) {
43 0           print "It looks like you entered too many characters. ";
44 0           next;
45             }
46             elsif ( $length < $instruction_width ) {
47 0           $input = sprintf "%03s", $input;
48             }
49              
50 0 0         if ( $input !~ $valid_input ) {
51 0           print "Your input doesn't look valid. ";
52 0           next;
53             }
54             else {
55 0           last;
56             }
57             }
58              
59 0 0         if ( $tries > $max_tries ) {
60 0           die "Did not receive valid input after $max_tries attempts. Please restart your program\n";
61             }
62             else {
63 0           return $input;
64             }
65             }
66              
67             sub add_input_to_inbox {
68 0     0 1   my ( $machine, $input ) = @_;
69              
70 0           push @{$machine->{inbox}}, $input;
  0            
71              
72 0           return 0;
73              
74             # maybe make this more generic and just call it add_to_inbox
75              
76             # how would I abstract the keyboard / display? what would they
77             # look like? how would I represent them in this code?
78             }
79              
80             sub shift_inbox_to_memory {
81 0     0 1   my ( $machine, $address ) = @_;
82              
83 0           $machine->{memory}->{$address} = shift @{$machine->{inbox}};
  0            
84              
85 0           return 0;
86              
87             # like shift_outbox, maybe make this more generic
88             # at some point and have a target of where to shift
89             # it
90             }
91              
92             sub add_to_outbox {
93 0     0 1   my ( $machine, $operand ) = @_;
94              
95 0           push @{$machine->{outbox}}, $machine->{memory}->{$operand};
  0            
96              
97 0           return 0;
98             }
99              
100             sub shift_outbox_to_user {
101 0     0 1   my $machine = shift;
102              
103 0           print shift ( @{$machine->{outbox}} ) . "\n";
  0            
104              
105 0           return 0;
106              
107             # maybe, at some point, make this more generic
108             # where it is just called shift_outbox and there
109             # is a target of where to shift it to...
110              
111             # consider stripping leading 0's when outputting
112             # to user
113             }
114              
115             1;
116              
117             =pod
118              
119             =head1 NAME
120              
121             VM::Dreamer::IO - IO functionality for Dreamer
122              
123             =head1 SYNOPSIS
124              
125             get_valid_input_from_user($machine)
126             add_input_to_inbox( $machine, $input )
127             shift_inbox_to_memory( $machine, $address )
128              
129             add_to_outbox( $machine, $operand )
130             shift_outbox_to_user($machine)
131              
132             =head1 DESCRIPTION
133              
134             This module handles IO functions for Dreamer. This just means that it can:
135              
136             =over 12
137              
138             =item get input and validate it
139             =item add the input to the Inbox stack
140             =item shift the "oldest" entry in the inbox to an address in memory
141              
142             =item add an item in memory to the Outbox stack
143             =item output the "oldest" entry in the outbox to the user
144              
145             =back
146              
147             =head1 SUBROUTINES
148              
149             =head2 get_valid_input_from_user
150              
151             Prompts the user for input. Valid input is returned otherwise the user is told what they did wrong and asked to try again. Raises an exception if max_tries is exceeded by the user.
152              
153             Note: The user doesn't need to zero-pad their input. They can do so if they like, but the input can't have more digits than the largest number they can enter.
154              
155             I.e. if the largest number they can enter is 999, 15 and 015 are acceptable, but 0015 would be rejected.
156              
157             =head2 add_input_to_inbox
158              
159             Pushes input to the "top" of the Inbox.
160              
161             =head2 shift_inbox_to_memory
162              
163             Shifts the "bottom" of the inbox to an address in memory.
164              
165             =head2 add_to_outbox
166              
167             Adds the information stored at an address in memory to the "top" of the Outbox.
168              
169             =head2 shift_outbox_to_user
170              
171             Putputs the value at the "bottom" of the Outbox to the user. Note all output is zero-padded to have the same number of digits as the "width" of each address in memory.
172              
173             This means that if your memory is 8 digits wide and each digit can be between 0 and 7, the number 715 would be output as 00000715.
174              
175             This may change in a future release.
176              
177             =head1 CONSUMPTION
178              
179             Together, the first three methods are used to implement VM::Dreamer::Instructions::input_to_mb and the last two are used to implemtn VM::Dreamer::Instructions::output_from_mb. These in turn are the INP and OUT operations for Grasshopper.
180              
181             =head1 CAVEATS
182              
183             I've tried to follow the FIFO concept of First In, First Out; however, I don't know how well I understand the underlying concepts. If you know better and see any conceptual issues with the implementation, please let me know.
184              
185             =head1 AUTHOR
186              
187             William Stevenson
188              
189             =head1 SEE ALSO
190              
191             VM::Dreamer::Instructions
192              
193             =head1 COPYRIGHT AND LICENSE
194              
195             This software is Copyright (c) 2013 by William Stevenson.
196              
197             This is free software, licensed under:
198              
199             The Artistic License 2.0 (GPL Compatible)
200            
201             =cut