3 # Copyright (c) 2002 Jerome Quelin <jquelin@cpan.org>
6 # This program is free software; you can redistribute it and/or
7 # modify it under the same terms as Perl itself.
10 package Inline
::Befunge
;
14 Inline::Befunge - write Perl subs in Befunge
21 print "9 + 16 = ", add(9, 16), "\n";
22 print "9 - 16 = ", subtract(9, 16),"\n";
33 The C<Inline::Befunge> module allows you to put Befunge source code
34 directly "inline" in a Perl script or module.
36 This allows you to write cool stuff with all the power of Befunge!
39 =head1 USING Inline::Befunge
41 Using C<Inline::Befunge> will seem very similar to using a another
42 Inline language, thanks to Inline's consistent look and feel.
44 This section will explain how to use C<Inline::Befunge>.
46 For more details on C<Inline>, see C<perldoc Inline>.
49 =head2 Feeding Inline with your code
51 The recommended way of using Inline is the following:
60 Befunge source code goes here.
62 But there are much more ways to use Inline. You'll find them in
66 =head2 Defining functions
68 As a befunge fan, you know that Befunge does not support named
69 subroutines. So, I introduced a little hack (thank goes to Sean
70 O'Rourke) in order for Inline to work: each subroutine definition
71 should be prepended with a comment C<;:subname;> (notice the colon
74 You'll notice how smart it is, since it's enclosed in comments, and
75 therefore the overall meaning of the code isn't changed.
77 You can define your subroutines in any of the four cardinal directions,
78 and the subroutine velocity will be the velocity defined by the
79 comment. That is, if you define a subroutine in a vertical comment
80 from bottom to top, when called, the subroutine will start with a
83 You can add comments after the subname. Thus, C<;:foo - a foo
84 subroutine;> defines a new subroutine C<foo>.
86 So, here's a valid example:
94 ;:hello - print a msg;<q_,#! #:<"Hello world!"a
102 + ;not a valid func def;
106 In this example, I defined three functions: C<hello()>, C<add()> and
107 C<substract>, and you can call them from within perl as if they were
108 valid perl functions. The fourth comment C<;not a valid func def;>
109 isn't a valid function definition since it lacks a colon C<:> just
113 =head2 Passing arguments
115 In order to write useful functions, one should be able to pass
116 arguments. This is possible, and one will find the arguments on the
117 TOSS of the interpreter: this means the stack may not be empty at the
118 beginning of the run. If you're a purist, then you may ignore this and
119 call your functions without arguments, and the stack will be empty.
121 Strings are pushed as 0gnirts.
123 B</!\> Remember, Befunge works with a stack: the first argument will
124 be the first pushed, ie, the deeper in the stack.
126 For example, when calling an inlined Befunge function like this:
127 C<foo( 'bar', 7, 'baz' );>, then the stack will be (bottom->top): C<(0
128 114 97 98 7 0 122 97 98)>.
133 Furthermore, one can return some values from the befunge
134 subroutines... how exciting!
136 To do so, the Befunge semantics have been a little adapted:
142 when an Instruction Pointer reaches a C<q> instruction, one cell will
143 be popped from its stack and will be returned. This works like a
148 when an Instruction Pointer reaches a C<@> instruction, it will be
149 killed (just as in traditional Befunge). But when the B<last> IP
150 reaches a C<@>, then the sub is exited and will return the whole stack
151 of the IP that just died. This works like a list return.
153 B</!\> Be careful, that you will return a list of integer values. You
154 are to decide what to do with those values (especially, you are to
155 convert back to characters with the C<chr> perl builtin function and
156 join the chars if you're waiting for a string!).
161 =head2 Supported options
163 C<Inline::Befunge> supports a DEBUG option, to follow the IP(s) as
164 they are running on the funge-space.
166 Use the following to activate it:
168 use Inline( Befunge => 'DATA',
175 Enter you befunge code here.
180 # A little anal retention ;-)
184 # Modules we relied upon.
185 use Carp
; # This module can't explode :o)
186 require Inline
; # use Inline forbidden.
187 use Language
::Befunge
;
190 use base qw
! Inline
!;
192 # Public variables of the module.
193 our $VERSION = '0.04';
196 =head1 PUBLIC METHODS
200 Register as an Inline Language Support Module.
205 { language
=> 'Befunge',
206 aliases
=> [ 'befunge', 'BEFUNGE', 'bf', 'BF' ],
207 type
=> 'interpreted',
214 Check the params for the Befunge interpreter. Currently no options are
222 $self->{ILSM
}{DEBUG
} = 0;
225 my ($key, $value) = (shift, shift);
226 $key eq "DEBUG" and $self->{ILSM
}{DEBUG
} = $value, next;
227 croak
"Unsupported option found: '$key'.";
234 Register the Befunge as a valid Inline extension.
239 # The magic incantations to register.
240 my $path = $self->{API
}{install_lib
}."/auto/".$self->{API
}{modpname
};
241 $self->mkpath($path) unless -d
$path;
242 my $file = $self->{API
}{location
};
243 open FOO_OBJ
, "> $file" or croak
"Can't open $file for output\n$!";
244 print FOO_OBJ
$self->{API
}{code
};
251 This function actually fetches the Befunge code. It first splits it to
256 # Fetch object and package.
258 my $pkg = $self->{API
}{pkg
} || 'main';
260 # Fetch code and create the interpreter.
261 my $code = $self->{API
}{code
};
262 my $bef = $self->{ILSM
}{bef
} = new Language
::Befunge
;
263 $bef->store_code( $code );
264 $bef->DEBUG( $self->{ILSM
}{DEBUG
} );
267 # Each subroutine should be:
268 # ;:subname1; < @ ,,,,"foo"a
271 my $funcs = $bef->torus->labels_lookup;
272 $self->{ILSM
}{funcs
} = join " ", sort keys %$funcs;
274 foreach my $subname ( keys %$funcs ) {
276 *{"${pkg}::$subname"} =
279 $bef->debug( "\n-= SUBROUTINE $subname =-\n" );
280 $bef->file( "Inline-$subname" );
282 # Create the first Instruction Pointer.
283 my $ip = new Language
::Befunge
::IP
;
285 # Move the IP at the beginning of the function.
286 $ip->curx( $funcs->{$subname}[0] );
287 $ip->cury( $funcs->{$subname}[1] );
288 $ip->dx( $funcs->{$subname}[2] );
289 $ip->dy( $funcs->{$subname}[3] );
291 # Fill the stack with arguments.
292 $ip->spush_args( @_ );
294 # Initialize the interpreter.
295 $bef->ips( [ $ip ] );
299 # Loop as long as there are IPs.
300 $bef->next_tick while scalar @
{ $bef->ips };
302 # Return the exit code and the TOSS.
303 return $bef->lastip->end eq '@' ?
304 @
{ $bef->lastip->toss } # return the TOSS.
305 : $bef->retval; # return exit code.
314 Return a small report about the Befunge code.
320 The following functions have been defined via Inline::Befunge:
332 Jerome Quelin, E<lt>jquelin@cpan.orgE<gt>
335 =head1 ACKNOWLEDGEMENTS
337 I would like to thank:
343 Brian Ingerson, for writing the incredibly cool C<Inline> module, and
344 giving the world's programmers enough rope to hang themselves many
349 Chris Pressey, creator of Befunge, who gave a whole new dimension to
350 both coding and obfuscating.
354 Sean O'Rourke E<lt>seano@alumni.rice.eduE<gt> for his incredible cool
355 idea on defining labels in Befunge code.
362 This program is free software; you can redistribute it and/or modify
363 it under the same terms as Perl itself.
374 =item L<Language::Befunge>