File Coverage

blib/lib/Befunge/Interpreter.pm
Criterion Covered Total %
statement 0 263 0.0
branch 0 106 0.0
condition n/a
subroutine 0 28 0.0
pod 0 28 0.0
total 0 425 0.0


line stmt bran cond sub pod time code
1             package Befunge::Interpreter;
2             # Josh's Really Cool Befunge Interpreter For Common Everyday Use
3              
4             # Let's lay down the law here with some variables
5              
6             # This is the program counter initialization to +1, 0;
7              
8              
9             $VERSION = "0.01c";
10              
11             sub new
12             {
13 0     0 0   my $self = {};
14 0           bless $self;
15 0           return $self;
16             }
17              
18             $pc{'x'} = 1;
19             $pc{'y'} = 0;
20              
21             # Let's initialize the 'torus'.
22             @torus = " ";
23              
24             # stack too
25             @stack = 0;
26              
27             $MAX_TORUS_X = 79;
28             $MAX_TORUS_Y = 24;
29              
30             # position
31             $tx, $ty = 0;
32              
33             sub spush {
34 0     0 0   my @ARGZ = shift @_;
35 0           my $value = $ARGZ[0];
36 0           my $length = $#stack++;
37 0           $stack[$#stack] = $value;
38             }
39            
40             sub spop {
41 0 0   0 0   if ($#stack == -1)
42             {
43 0           spush(0);
44             }
45 0           my $result = $stack[$#stack];
46 0           $#stack--;
47 0           return $result;
48             }
49              
50             sub get_befunge {
51 0     0 0   my $self = shift;
52 0           my $FILENAME = shift;
53             #print "got $FILENAME\n";
54 0 0         open (BFPROG, $FILENAME) or die "program $FILENAME not found!";
55 0           my $counter = 0;
56 0           my $x, $y = 0;
57             # To avoid weird errors, I'll let them input as much as they want
58             # but then cruelly truncate it to 80x25.
59 0           while (chomp($curline = ))
60             {
61 0           $befunge[$counter++] = $curline;
62             }
63 0           $counter = 0;
64 0           while ($y <= $MAX_TORUS_Y)
65             {
66 0 0         if ($x <= $MAX_TORUS_X)
67             {
68 0           $torus[$x++][$y] = substr $befunge[$y], $x, 1;
69             } else {
70 0           $y++;
71 0           $x = 0;
72             }
73             }
74 0           return $torus;
75             }
76              
77             sub stack_add {
78 0     0 0   my $value2 = spop();
79 0           my $value1 = spop();
80 0           my $result = $value1 + $value2;
81 0           spush($result);
82             }
83              
84             sub stack_sub {
85 0     0 0   my $value2 = spop();
86 0           my $value1 = spop();
87 0           my $result = $value1 - $value2;
88 0           spush($result);
89             }
90              
91             sub stack_mul {
92 0     0 0   my $value2 = spop();
93 0           my $value1 = spop();
94 0           my $result = $value1 * $value2;
95 0           spush($result);
96             }
97              
98             sub stack_div {
99 0     0 0   my $value2 = spop();
100 0           my $value1 = spop();
101 0           my $result = int($value1 / $value2);
102 0           spush($result);
103             }
104              
105             sub stack_mod {
106 0     0 0   my $value2 = spop;
107 0           my $value1 = spop;
108 0           my $result = int($value1 % $value2);
109 0           spush($result);
110             }
111              
112             sub stack_not {
113 0     0 0   my $value1 = spop();
114 0 0         if ($value1 == 0)
115             {
116 0           spush(1);
117             }
118             else
119             {
120 0           spush(0);
121             }
122             }
123              
124             sub stack_gre {
125 0     0 0   my $value2 = spop();
126 0           my $value1 = spop();
127 0 0         if ($value1 > $value2)
128             {
129 0           spush(1);
130             } else
131             {
132 0           spush(0);
133             }
134             }
135              
136             sub pc_rand {
137 0     0 0   $randnum = int(rand(4));
138             SWITCH2: {
139 0 0         ($randnum == 0) && do { $pc{'x'} = 1; $pc{'y'} = 0; };
  0            
  0            
  0            
140 0 0         ($randnum == 1) && do { $pc{'x'} = -1; $pc{'y'} = 0; };
  0            
  0            
141 0 0         ($randnum == 2) && do { $pc{'x'} = 0; $pc{'y'} = 1; };
  0            
  0            
142 0 0         ($randnum == 3) && do { $pc{'x'} = 0; $pc{'y'} = -1; };
  0            
  0            
143             }
144             }
145              
146             sub horiz_if {
147 0     0 0   my $value1 = pop @stack;
148 0 0         if ($value1 == 0)
149             {
150 0           $pc{'x'} = 1;
151 0           $pc{'y'} = 0;
152             } else
153             {
154 0           $pc{'x'} = -1;
155 0           $pc{'y'} = 0;
156             }
157             }
158              
159             sub vert_if {
160 0     0 0   my $value1 = pop @stack;
161 0 0         if ($value1 == 0)
162             {
163 0           $pc{'x'} = 0;
164 0           $pc{'y'} = 1;
165             }
166             else
167             {
168 0           $pc{'x'} = 0;
169 0           $pc{'y'} = -1;
170             }
171             }
172              
173             # safe incrementing of position x
174              
175             sub siopx {
176 0     0 0   my @argz = @_;
177 0           my $curx = $argz[0];
178 0           my $amt = $argz[1];
179 0           $curx += $amt;
180 0 0         if ($curx > $MAX_TORUS_X)
181             {
182 0           $curx -= $MAX_TORUS_X + 1;
183             }
184 0 0         if ($curx < 0)
185             {
186 0           $curx += $MAX_TORUS_X;
187             }
188 0           return $curx;
189             }
190              
191             # same thing for y
192              
193             sub siopy {
194 0     0 0   my @argz = @_;
195 0           my $cury = $argz[0];
196 0           my $amt = $argz[1];
197 0           $cury += $amt;
198 0 0         if ($cury > $MAX_TORUS_Y)
199             {
200 0           $cury -= $MAX_TORUS_Y + 1;
201             }
202 0 0         if ($cury < 0)
203             {
204 0           $cury += $MAX_TORUS_Y;
205             }
206 0           return $cury;
207             }
208            
209              
210             sub string_mode {
211 0     0 0   $lookloc = "fnerk!";
212             # Here's where we found the first quote
213 0           my @argz = @_;
214 0           $curlocx = $argz[0];
215 0           $curlocy = $argz[1];
216 0           $looklocx = siopx($curlocx, $pc{'x'});
217 0           $looklocy = siopy($curlocy, $pc{'y'});
218 0           while ($lookloc ne "\"")
219             {
220 0           $lookloc = $torus[$looklocx][$looklocy];
221 0 0         if ($lookloc eq "\"")
222             {
223 0           $tx = $looklocx;
224 0           $ty = $looklocy;
225             }
226             else
227             {
228 0           spush ord $lookloc;
229 0           $looklocx = siopx($looklocx, $pc{'x'});
230 0           $looklocy = siopy($looklocy, $pc{'y'});
231             }
232             }
233 0           return $tx, $ty;
234             }
235              
236             sub stack_dup {
237 0     0 0   my $value1 = spop();
238 0           spush($value1);
239 0           spush($value1);
240             }
241              
242             sub stack_swap {
243 0     0 0   my $value2 = spop;
244 0           my $value1 = spop;
245 0           spush($value2);
246 0           spush($value1);
247             }
248              
249             sub stack_pop {
250 0     0 0   spop();
251             }
252              
253             sub output_int {
254 0     0 0   my $value1 = int(spop());
255 0           print $value1;
256             }
257              
258             sub output_ASCII {
259 0     0 0   my $value1 = spop();
260 0           print chr($value1);
261             }
262              
263             sub torus_get {
264 0     0 0   my $y = spop();
265 0           my $x = spop();
266 0           spush($torus[$x][$y]);
267             }
268              
269             sub torus_put {
270 0     0 0   my $y = spop();
271 0           my $x = spop();
272 0           my $value = spop();
273 0           $torus[$x][$y] = $value;
274             }
275              
276              
277             sub input_int {
278 0     0 0   my $number = ;
279 0           spush($number);
280             }
281            
282             sub input_ASCII {
283 0     0 0   my $ascii = ;
284 0           $ascii = ord $ascii;
285 0           spush($ascii);
286             }
287              
288             sub push_num {
289 0     0 0   spush($curchar);
290             }
291              
292             sub process_befunge {
293 0     0 0   $tx, $ty = 0;
294 0           $skipnext = 0;
295 0           $done = 0;
296 0           while ($done == 0)
297             {
298 0           $curchar = $torus[$tx][$ty];
299             # Ugly processing routine about to follow. I suggest most of you close
300             # your eyes.
301             SWITCH: {
302 0 0         if ($skipnext == 1) { $curchar = ' '; $skipnext = 0; last; };
  0            
  0            
  0            
  0            
303 0 0         if ($curchar eq '>') { $pc{'x'} = 1; $pc{'y'} = 0; last;};
  0            
  0            
  0            
304 0 0         if ($curchar eq '<') { $pc{'x'} = -1; $pc{'y'} = 0; last;};
  0            
  0            
  0            
305 0 0         if ($curchar eq '^') { $pc{'x'} = 0; $pc{'y'} = -1; last;};
  0            
  0            
  0            
306 0 0         if ($curchar eq 'v') { $pc{'x'} = 0; $pc{'y'} = 1; last;};
  0            
  0            
  0            
307 0 0         if ($curchar eq '?') { pc_rand(); last;};
  0            
  0            
308 0 0         if ($curchar eq '+') { stack_add(); last;};
  0            
  0            
309 0 0         if ($curchar eq '-') { stack_sub(); last;};
  0            
  0            
310 0 0         if ($curchar eq '/') { stack_div(); last;};
  0            
  0            
311 0 0         if ($curchar eq "\*") { stack_mul(); last;};
  0            
  0            
312 0 0         if ($curchar eq '%') { stack_mod(); last;};
  0            
  0            
313 0 0         if ($curchar eq '!') { stack_not(); last;};
  0            
  0            
314 0 0         if ($curchar eq "\'") { stack_gre(); last;};
  0            
  0            
315 0 0         if ($curchar eq '_') { horiz_if(); last;};
  0            
  0            
316 0 0         if ($curchar eq '|') { vert_if(); last;};
  0            
  0            
317 0 0         if ($curchar eq "\"") {
318 0           ($tx, $ty) = (string_mode($tx, $ty));
319 0           last;
320             }
321 0 0         if ($curchar eq ':') { stack_dup(); last; };
  0            
  0            
322 0 0         if ($curchar eq "\\") { stack_swap(); last;};
  0            
  0            
323 0 0         if ($curchar eq "\$") { stack_pop(); last;};
  0            
  0            
324 0 0         if ($curchar eq '.') { output_int(); last;};
  0            
  0            
325 0 0         if ($curchar eq ',') { output_ASCII(); last; };
  0            
  0            
326 0 0         if ($curchar eq "\#") { $skipnext = 1; last; };
  0            
  0            
327 0 0         if ($curchar eq 'g') { torus_get(); last;};
  0            
  0            
328 0 0         if ($curchar eq 'p') { torus_put(); last;};
  0            
  0            
329 0 0         if ($curchar eq "\&") { input_int(); last;};
  0            
  0            
330 0 0         if ($curchar eq "\~") { input_ASCII(); last;};
  0            
  0            
331 0 0         if ($curchar eq "\@") { $done = 1; exit; };
  0            
  0            
332 0 0         if ($curchar eq '0' ) { push_num(); last; };
  0            
  0            
333 0 0         if ($curchar eq '1' ) { push_num(); last; };
  0            
  0            
334 0 0         if ($curchar eq '2' ) { push_num(); last; };
  0            
  0            
335 0 0         if ($curchar eq '3' ) { push_num(); last; };
  0            
  0            
336 0 0         if ($curchar eq '4' ) { push_num(); last; };
  0            
  0            
337 0 0         if ($curchar eq '5' ) { push_num(); last; };
  0            
  0            
338 0 0         if ($curchar eq '6' ) { push_num(); last; };
  0            
  0            
339 0 0         if ($curchar eq '7' ) { push_num(); last; };
  0            
  0            
340 0 0         if ($curchar eq '8' ) { push_num(); last; };
  0            
  0            
341 0 0         if ($curchar eq '9' ) { push_num(); last; };
  0            
  0            
342             }
343 0           $tx = siopx($tx, $pc{'x'});
344 0           $ty = siopy($ty, $pc{'y'});
345             }
346             }
347              
348              
349             1;
350             __END__