# # See POD documentation below for description, copyright and licensing info. # package Inline::Brainfck; use Filter::Simple; use strict; use warnings; #remember to change this in the POD too. our $VERSION = '0.9.0'; # The memory pointer and memory cells of our Turing machine. our $p = 0; our @m = (); # The basic Brainfck instructions. Extras will be added in import(). our $ops = '+-<>,.[]'; # Whether or not we accept extra instructions. our $verbose = 0; # print out filtered text? our $debug = 0; sub import() { shift; foreach (@_) { if (/^verbose$/) { $ops .= '~#'; $verbose = 1; } if (/^debug$/) { $debug = 1; } } } FILTER_ONLY code => sub { my $ret = $_; while ($ret =~ /\s ([\Q$ops\E]+) \s/gsx) { my $code = $1; my $len = length($1); my $at = pos($ret) - ($len + 1); $code =~ s/^/do { /g; $code =~ s/$/P; }; /g; $code =~ s/\+/P++; /g; $code =~ s/\-/P--; /g; $code =~ s//\$Inline::Brainfck::p++; /g; $code =~ s/\./print chr P; /g; $code =~ s/,/P = ord getc;/g; $code =~ s/\[/while(P){/g; $code =~ s/\]/}; /g; if ($verbose) { $code =~ s/~/\$Inline::Brainfck::p = 0;\@Inline::Brainfck::m = (); /g; $code =~ s/\#/print STDERR sprintf\('\$p = %d \$m[\$p]= %d', \$Inline::Brainfck::p, P\), "\\n"; /g; } $code =~ s/P/\$Inline::Brainfck::m\[\$Inline::Brainfck::p\]/g; substr($ret, $at, $len, $code); } $_ = $ret; print $_ if $debug; }; 1; __END__ =pod =head1 NAME Inline::Brainfck - Embed Brainfck in your perl code =head1 SYNOPSIS #!/usr/bin/env perl use Inline::Brainfck; print 'Hello world!', chr ++++++++++. ; =head1 ABSTRACT Brainfck is about the tiniest Turing-complete programming language you can get. A language is Turing-complete if it can model the operations of a Turing machine--an abstract model of a computer defined by the British mathematician Alan Turing in 1936. A Turing machine consists only of an endless sequence of memory cells and a pointer to one particular memory cell. Yet it is theoretically capable of performing any computation. This module will allow you to mix Brainfck with your perl code. =head1 DESCRIPTION =head2 Instructions With this module, you can embed Brainfck instructions delimited by whitespace into your perl code. It will be translated into Perl as parsed. Brainfck has just just 8 instructions (well more in this implementation, see L below.) which are as follows =over 4 =item + Increment Increase the value of the current memory cell by one. =item - Decrement Decrease the value of the current memory cell by one. =item > Forward Move the pointer to the next memory cell. =item < Back Move the pointer to the previous memory cell. =item , Input Read a byte from Standard Input and store it in the current memory cell. =item . Output Write the value of the current memory cell to standard output. =item [ Loop If the value of the current memory cell is 0, continue to the cell after the next ']'. =item ] Next Go back to the last previous '['. =back =head2 Extensions to ANSI Brainfck This implementation has extra instructions available. In order to avoid such terrible bloat, they are only available if you use the I pragma like so: use Inline::Brainfck qw/verbose/; The extra instructions are: =over 4 =item ~ Reset Resets the pointer to the first memory cell and clear all memory cells. =item # Peek Prints the values of the memory pointer and the current memory cell to STDERR. See also L below. =back =head2 Debugging By using the I pragma like this: use Inline::Brainfck qw/debug/; you can dump out the generated perl code. (Caution: it is not pretty.) The key to understanding it is that the memory pointer is represented by I<$p>, and the memory array by I<@m> Therefore the value of the current memory cell is I<$m[$p]>. =head1 RETURN VALUE Each sequence of Brainfck instructions becomes a Perl block and returns the value of the current memory cell. =head1 EXAMPLES =head2 JABH #!/usr/bin/env perl use Inline::Brainfck; print "Just another "; ++++++[>++++++++++++++++<-]> ++.-- >+++[<++++++>-]<.>[-]+++[<------>-]< +.- +++++++++.--------- ++++++++++++++.-------------- ++++++.------ >+++[<+++++++>-]<.>[-]+++[<------->-]< +++.--- +++++++++++.----------- print " hacker.\n"; =head2 Countdown #!/usr/bin/env perl use strict; use Inline::Brainfck qw/verbose/; print "Countdown commencing...\n"; ++++++++++[>+>+<<-] >>+++++++++++++++++++++++++++++++++++++++++++++++<< ++++++++++[>>.-<.<-] print "We have liftoff!\n"; =head2 Reverse #!/usr/bin/env perl use Inline::Brainfck qw/verbose/; while(1) { print "Say something to Backwards Man and then press enter: "; +[->,----------]< print 'Backwards Man says, "'; [+++++++++++.<]< print "\" to you too.\n"; ~ } =head2 Math #!/usr/bin/env perl use Inline::Brainfck; use strict; use warnings; my $answer = +++[>++++++<-]> ; print "3 * 6 = $answer \n"; =head1 VERSION 0.9.0 Aug 29, 2002 =head1 AUTHOR Jaldhar H. Vyas Ejaldhar@braincells.comE =head1 THANKS Urban Mueller - The inventor of Brainfck. Damian Conway - For twisting perl to hitherto unimaginable heights of weirdness. Marco Nippula Ehttp://www.hut.fi/~mnippula/E - Some code in this module comes from his F Mr. Rock - Who has a nice Brainfck tutorial at L. Some of the example code comes from there. =head1 COPYRIGHT AND LICENSE Copyright (c) 2002, Consolidated Braincells Inc. Licensed with no warranties under the Crowley Public License: "Do what thou wilt shall be the whole of the license." =cut