# $Id: library.pod 2 2003-02-22 10:17:10Z jquelin $
=head1 Befunge-98 Libraries & Extensions
So you want to write your own Befunge extension?
Help save the world (tm), and send them to me so I can collect them
and redistribute them.
As you'll see, it's not very difficult to write your own
extensions. Currently, one can only write his Befunge libraries in
perl, but maybe I'll provide a mechanism in order to write you
extensions in Befunge. That would be terrific! ]:->
=head1 The fingerprint semantics
First, here's a recall on the fingerprint semantics.
Extension and customization of Funge-98 are accomplished through the
so-called "fingerprint mechanism".
To be more precise, a fingerprint is a unique ID code which indicates
a library of routines (a fingerprinted extension) to be assigned
temporarily to what the instructions A to Z do. Multiple loaded
fingerprints can overlap and overload, so even object-oriented-like
inheritance is possible.
These new semantics and instructions are only available to and only
apply to the IP which loaded them. The C<( Load Semantics> instruction
loads the semantics for a given fingerprint onto any or all of the
instructions A to Z.
C<(> pops a count. It then pops count cells. For each cell that it
pops, it multiplies a temporary value (which is initially zero) by
256, and adds the cell value to it.
In this way, C<(> builds a fingerprint. This mechanism makes it simple
to express large fingerprints like 0x72697679 in printable ASCII such
as "OLEH"4( ... ), while not requiring the use of ASCII as the medium
for all fingerprints.
=head1 Writing your extension in perl
Okay, let's assume you want to write an extension that does two
things:
=over 4
=item o
overloads the C
instruction and binds it to output C
=item o
overloads the C instruction and binds it to store onto the TOSS the
gnirts C
=back
As you can see, this is a must-have extension! :o)
=head2 Choose a fingerprint
The first thing to do is to choose a unique id (aka fingerprint) for
your cool extension.
This fingerprint:
=over 4
=item o
should be unique, and should not be already taken by another
extension. If somebody took the name you planned to use for your cool
extension, check if the stoler's extension doesn't overlap with yours,
and check with its author to know if you can help him/her to develop
his/her extension or if you can take his extension.
B!\> Remember that if you want your extension to be distributed, it
I have a unique fingerprint!
=item o
should be self-explanatory (well, you're not technically forced to,
but it would be better) when transposed in ASCII.
=item o
must B be too long. Remember the ASCII is just a turn-around, but
the real fingerprint is an integer. As such, it is required that it
fits in a cell of Befunge (and this is a 4 bytes Befunge): this means
that the extension fingerprint should not (when transposed in ASCII)
be longer than 4 characters. Well, in fact, you I go with an
extension name as long as 8 chars or even more (depending on your
hardware), but I B discourage such ideas.
=back
Okay, given these rules, we decide to take the name C> for our
extension, and the fingerprint would be C<0x76657765>. This was the
first step.
=head2 Create a new module
Now, the next thing to do is to create a module. The module must be in
the C hierarchy, and be named as your extension
name.
So, we're creating the module C.
B!\> Warning: in order for the perl interpreter to find your cool
module, you are to put it somewhere in C<@INC>.
The new module is quite easy to begin, since you just have to put the
following in the newly-created file:
package Language::Befunge::lib::LAMA;
sub new { return bless {}, shift; }
1;
Don't forget the final C<1;>! Since it's a Perl module, perl needs the
module to return a true value...
Your module is in fact a class, and it should work as a class. That's
why you need a C constructor, even if it's really a basic one, as
shown before.
Once you've done that, your module can be loaded in your Befunge
program! Let's try the exciting program:
< v "ok"0 ( v# 4 "LAMA"
v "not ok"0 <
> :#, _ q
And it should output C. If it outputs C, then you made a
mistake in your module and either it does not compile (does your
module return a true value?) or perl couldn't find it (check C<@INC>).
=head2 Just code your functions!
All you have to do now is to code your functions. Define a new sub for
each binded instruction, named after this instruction.
Thus, in order to overload the C instruction, we just need to add
the following in our module:
sub P {
print "I can see a llama!\n";
}
And that's all! Once your cool module has been loaded, the P
instruction will output your cool sentence... That's definitely
terrific!
=head2 Accessing the IP
Since you may want to interact with the I and/or
the I, or whatever, each method will
be called with the current Befunge interpreter (a C
object).
See L for more documentation about the relevant
methods.
Hey, that's exactly what we needed in order to implement our C
instruction! Let's code it just now:
sub S {
my (undef, $interp) = @_; # Remember it's an OO method.
$ip->spush( reverse map { ord } split //, "I can see a llama!\n".chr(0) );
}
This may be a little complex, but keep in mind that Befunge works with
a stack. Thus, one should reverse the string in order for it to be
stored the right way.
Another thing that may surprise you, is that the stack (as well as the
Lahey space) stores integers. You have to convert them to whatever you
want if you want to interpret them. In this example, we're storing a
serie of characters onto the stack, but in fact we're truly storing
the B values of the chars. This way, they will be displayed
the right way when used with C<,>.
=head2 Be kind to your mates
Nothing else is needed for your cool extension to work. But since you
may want to provide your module to everyone, I recommend you to:
=over 4
=item o
Produce a clean code. This means that C