NAME
Language::Befunge - a Befunge-98 interpreter
SYNOPSIS
use Language::Befunge;
my $interp = Language::Befunge->new( "program.bf" );
$interp->run_code( "param", 7, "foo" );
Or, one can write directly:
my $interp = Language::Befunge->new;
$interp->store_code( <<'END_OF_CODE' );
< @,,,,"foo"a
END_OF_CODE
$interp->run_code;
DESCRIPTION
Enter the realm of topological languages!
This module implements the Funge-98 specifications on a 2D field (also called Befunge). In particular, be aware that this is not a Trefunge implementation (3D).
This Befunge-98 interpreters assumes the stack and Funge-Space cells of this implementation are 32 bits signed integers (I hope your os understand those integers). This means that the torus (or Cartesian Lahey-Space topology to be more precise) looks like the following:
32-bit Befunge-98
=================
^
|-2,147,483,648
|
| x
<-----------+----------->
-2,147,483,648 | 2,147,483,647
|
y|2,147,483,647
v
This implementation is meant to work on unix-like systems, because this interpreters only handle the character which ordinal value is 10 (also known as \n) as an End-Of-Line chars. In particular, no warranty is made neither for Microsoft systems (\r\n) nor for Macs (\r).
This module also implements the Concurrent Funge semantics.
CONSTRUCTOR
new( [filename] )
Create a new Befunge interpreter. If a filename is provided, then read and store the content of the file in the cartesian Lahey space topology of the interpreter.
ACCESSORS
The following is a list of attributes of a Language::Befunge object. For each of them, a method get_foobar
and set_foobar
exists, which does what you can imagine - and if you can't, then i wonder why you are reading this! :-)
- file:
-
the script filename (a string)
- params:
-
the parameters of the script (an array reference)
- retval:
-
the current return value of the interpreter (an integer)
- DEBUG:
-
wether the interpreter should output debug messages (a boolean)
- curip:
-
the current Instruction Pointer processed (a L::B::IP object)
- ips:
-
the current set of IPs travelling in the Lahey space (an array reference)
- newips:
-
the set of IPs that will travel in the Lahey space after the current tick (an array reference)
- torus:
-
the current Lahey space (a L::B::LaheySpace object)
PUBLIC METHODS
Utilities
- move_curip( [regex] )
-
Move the current IP according to its delta on the LaheySpace topology.
If a regex ( a
qr//
object ) is specified, then IP will move as long as the pointed character match the supplied regex.Example: given the code
;foobar;
(assuming the IP points on the first;
) and the regexqr/[^;]/
, the IP will move in order to point on ther
. - abort( reason )
-
Abort the interpreter with the given reason, as well as the current file and coordinate of the offending instruction.
- debug( LIST )
-
Issue a warning if the interpreter has DEBUG enabled.
Code and Data Storage
- read_file( filename )
-
Read a file (given as argument) and store its code.
Side effect: clear the previous code.
- store_code( code )
-
Store the given code in the Lahey space.
Side effect: clear the previous code.
Run methods
- run_code( [params] )
-
Run the current code. That is, create a new Instruction Pointer and move it around the code.
Return the exit code of the program.
- next_tick( )
-
Finish the current tick and stop just before the next tick.
- process_ip( )
-
Process the current ip.
INSTRUCTION IMPLEMENTATIONS
Numbers
Strings
Mathematical operations
- op_math_addition( )
- op_math_substraction( )
- op_math_multiplication( )
- op_math_division( )
- op_math_remainder( )
Direction changing
- op_dir_go_east( )
- op_dir_go_west( )
- op_dir_go_north( )
- op_dir_go_south( )
- op_dir_go_away( )
- op_dir_turn_left( )
-
Turning left, like a car (the specs speak about a bicycle, but perl is _so_ fast that we can speak about cars ;) ).
- op_dir_turn_right( )
-
Turning right, like a car (the specs speak about a bicycle, but perl is _so_ fast that we can speak about cars ;) ).
- op_dir_reverse( )
- op_dir_set_delta( )
-
Hmm, the user seems to know where he wants to go. Let's trust him/her.
Decision making
Flow control
- op_flow_space( )
-
A serie of spaces is to be treated as one NO-OP.
- op_flow_no_op( )
- op_flow_comments( )
-
Bypass comments in one tick.
- op_flow_trampoline( )
- op_flow_jump_to( )
- op_flow_repeat( )
- op_flow_kill_thread( )
- op_flow_quit( )
Stack manipulation
Stack stack manipulation
Funge-space storage
Standard Input/Output
- op_stdio_out_num( )
- op_stdio_out_ascii( )
- op_stdio_in_num( )
- op_stdio_in_ascii( )
- op_stdio_in_file( )
- op_stdio_out_file( )
- op_stdio_sys_exec( )
System info retrieval
Concurrent Funge
Library semantics
TODO
- o
-
Write standard libraries.
BUGS
Although this module comes with a full set of tests, maybe there are subtle bugs - or maybe even I misinterpreted the Funge-98 specs. Please report them to me.
There are some bugs anyway, but they come from the specs:
- o
-
About the 18th cell pushed by the
y
instruction: Funge specs just tell to push onto the stack the size of the stacks, but nothing is said about how user will retrieve the number of stacks. - o
-
About the load semantics. Once a library is loaded, the interpreter is to put onto the TOSS the fingerprint of the just-loaded library. But nothing is said if the fingerprint is bigger than the maximum cell width (here, 4 bytes). This means that libraries can't have a name bigger than
0x80000000
, ie, more than four letters with the first one smaller thanP
(chr(80)
).Since perl is not so rigid, one can build libraries with more than four letters, but perl will issue a warning about non-portability of numbers greater than
0xffffffff
.
AUTHOR
Jerome Quelin, <jquelin@cpan.org>
Development is discussed on <language-befunge@mongueurs.net>
ACKNOWLEDGEMENTS
I would like to thank Chris Pressey, creator of Befunge, who gave a whole new dimension to both coding and obfuscating.
COPYRIGHT
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.