Acme-Ook
view release on metacpan or search on metacpan
lib/Acme/Ook.pm view on Meta::CPAN
sub optimise {
# Coalesce sequences of increments or decrements
my $prog = $_[1];
# print "Before '$prog'\n";
foreach my $thing ('$Ook', '$Ook[$Ook]') {
foreach my $op ('+', '-') {
my $left = length "$thing$op$op;";
$prog =~ s{((?:\Q$thing$op$op\E;){2,})}
{"$thing$op=".(length ($1)/$left).';'}ges;
}
}
# print "After '$prog'\n";
return $prog;
}
sub _compile {
shift;
chomp $_[0];
$_[0] =~ s/\s*(Ook(.)\s*Ook(.)\s*|(\#.*)|\S.*)/$;=$Ook{$2||@@}{$3||''};$;?$;:defined$4?"$4\n":die"OOK? $_[1]:$_[2] '$1'\n"/eg;
return $_[0];
}
sub compile {
my $self = shift;
my $prog;
$prog .= $self->_compile($$self, "(new)", 0) if defined $$self && length $$self;
if (@_) {
local *OOK;
while (@_) {
my $code = shift;
if (ref $code eq 'IO::Handle') {
while (<$code>) {
$prog .= $self->_compile($_, $code, $.);
}
close(OOK);
} else {
if (open(OOK, $code)) {
while (<OOK>) {
$prog .= $self->_compile($_, $code, $.);
}
close(OOK);
} else {
die "OOK! $code: $!\n";
}
}
}
} else {
while (<STDIN>) {
$prog .= $self->_compile($_, "(stdin)", $.);
}
}
return '{my($Ook,@Ook);local$^W = 0;BEGIN{eval{require bytes;bytes::import()}}' . $prog . '}';
}
sub Ook {
eval $_[0]->optimise(&compile);
}
sub new {
my $class = shift;
bless \$_[0], ref $class || $class;
}
1;
__END__
=pod
=head1 NAME
Acme::Ook - the Ook! programming language
=head1 SYNOPSIS
ook ook.ook
or
use Acme::Ook;
my $Ook = Acme::Ook->new;
$Ook->Ook($Ook);
=head1 DESCRIPTION
As described in http://www.dangermouse.net/esoteric/ook.html
Since the word "ook" can convey entire ideas, emotions, and
abstract thoughts depending on the nuances of inflection, Ook!
has no need of comments. The code itself serves perfectly well to
describe in detail what it does and how it does it. Provided you
are an orang-utan.
Here's for example how to print a file in reverse order:
Ook. Ook. Ook! Ook? Ook. Ook? Ook. Ook! Ook? Ook!
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook. Ook! Ook.
Ook? Ook. Ook! Ook! Ook? Ook!
The language specification can be found from the above URL.
Despite the above, the interpreter does understand comments,
the #-until-end-of-line kind.
=head1 MODULE
The Acme::Ook is the backend for the Ook interpreter.
=head2 Methods
=over 4
=item new
The constructor. One optional argument, a string of Ook! that will
be executed before any code supplied in Ook().
=item Ook
The interpreter. Compiles, optimises and executes the Ook! code. Takes
one or more arguments, either filenames or IO globs, or no arguments, in
which case the stdin is read.
( run in 0.385 second using v1.01-cache-2.11-cpan-6aa56a78535 )