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 )