http://qs321.pair.com?node_id=480146

This is an Ook interpreter (see http://www.dangermouse.net/esoteric/ook.html). If you are an orangutan in an other worldly library you may find this useful for writing cataloging applications. Enjoy.

For debugging include maximum number of instructions to interpret on the command line: Ook 2000

use warnings; use strict; my %xlate = ( '.?' => \&DoRight, '?.' => \&DoLeft, '..' => \&DoInc, '!!' => \&DoDec, '!.' => \&DoOut, '.!' => \&DoIn, '!?' => \&DoWhile, '?!' => \&DoElihw ); my @tape = 0; # Storage "Tape" my $head = 0; # Read / Write head my $pc = 0; # Program counter my @stack; # Optimise loop handling my $inBuffer; my $debug = shift || 0; my $steps = 0; my $program = join " ", <DATA>; $program =~ s/Ook([.?!])\s*Ook([?.!])\s*/$1$2 /gi; my @code = map {$xlate{$_}} split " ", $program; $code[$pc]->() while ($pc < @code); sub debugPrint { return if ! $debug; print $_[0] . ": PC $pc, Stack depth " . @stack . "\n"; die "Instruction count exceeded\n" if ++$steps > $debug; } sub DoRight { debugPrint ("DoRight"); $tape [++$head] ||= undef; ++$pc; } sub DoLeft { debugPrint ("DoLeft"); unshift @tape, 0 unless $head; --$head if $head; ++$pc; } sub DoInc { debugPrint ("DoInc"); if (++$tape [$head] > 255) {$tape [$head] = -255;} ++$pc; } sub DoDec { debugPrint ("DoDec"); if (--$tape [$head] < -255) {$tape [$head] = 255;} ++$pc; } sub DoOut { debugPrint ("DoOut"); print chr ($tape [$head]); ++$pc; } sub DoIn { debugPrint ("DoIn"); if (! $inBuffer) {$inBuffer = <STDIN>;} $tape [$head] = ord substr $inBuffer, 0, 1, ""; ++$pc; } sub DoWhile { debugPrint ("DoWhile"); if ($tape [$head]) {# Enter the loop push @stack, $pc; ++$pc; return; } # Skip the loop my $nested = 1; # Keeps track of nested loops my $startPc = $pc; do { --$nested if $code [++$pc] == \&DoElihw; ++$nested if $code [$pc] == \&DoWhile; die "Unmatched Ook! Ook? found at instruction $startPc\n" if $pc > @ +code; } while ($nested); ++$pc; } sub DoElihw { debugPrint ("DoElihw"); die "Unmatched Ook? Ook! found at instruction $pc\n" if ! @stack; $pc = $stack [-1]; pop @stack; }
__DATA__ 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. 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! 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. 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. 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. 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. 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! 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! 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. 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! 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. 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. 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! 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. 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. 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! 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! 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. 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! 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. 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. 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. 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. 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! 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? 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? 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. 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. 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! 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. Ook. Ook. Ook. Ook. Ook! Ook.
use warnings; use strict; my $line = "Just another Ook! hacker"; my $OokCode; my @chars = split "", $line; my $curVal = 0; for my $curChr (@chars) { my $delta = ord ($curChr) - $curVal; $curVal = ord ($curChr); if ($delta > 0) {$OokCode .= "+" while $delta--;} elsif ($delta < 0) {$OokCode .= "-" while $delta++;} $OokCode .= "o"; } my @subs = ( ['+' x 96, ">++++[->++++[-<<++++++>>]<]<"], ['+' x 72, ">++++++[->+++[-<<++++>>]<]<"], ['+' x 64, ">++++[->++++[-<<++++>>]<]<"], ['+' x 60, ">++++[->+++++[-<<+++>>]<]<"], ['+' x 48, ">+++[->++++[-<<++++>>]<]<"], ['+' x 36, ">+++[->+++[-<<++++>>]<]<"], ['+' x 32, ">++++[->++++[-<<++>>]<]<"], ['+' x 30, ">++[->+++++[-<<+++>>]<]<"], ['+' x 27, ">+++[->+++[-<<+++>>]<]<"], ); $OokCode =~ s/\Q${$_}[0]\E/${$_}[1]/g for (@subs); ${$_}[0] =~ s/\+/-/g for @subs; ${$_}[1] =~ s/<(\++)/'-' x length ($1)/eg for @subs; #$OokCode =~ s/\Q${$_}[0]\E/${$_}[1]/g for (@subs); $OokCode =~ s/\+/Ook. Ook. /g; $OokCode =~ s/\-/Ook! Ook! /g; $OokCode =~ s/\</Ook? Ook. /g; $OokCode =~ s/\>/Ook. Ook? /g; $OokCode =~ s/\[/Ook! Ook? /g; $OokCode =~ s/\]/Ook? Ook! /g; $OokCode =~ s/i/Ook. Ook! /g; $OokCode =~ s/(?<!O)o/Ook! Ook. /g; print ((substr $OokCode, 0, 70, "") . "\n") while length $OokCode;

Update: add missing WikiPedia link
Update: include debugger and possibly fix Holli's problem
Update: A more interesting Ook! program
Update:Add code for Ook! generator per merlyn's suggestion


Perl is Huffman encoded by design.

Replies are listed 'Best First'.
Re: Ook interpreter
by cog (Parson) on Aug 02, 2005 at 13:34 UTC
Re: Ook interpreter
by Your Mother (Archbishop) on Aug 02, 2005 at 22:59 UTC

    That's quite cool and I'd heard of BF but not Ook! This might be a stupid follow up, but I'm curious if there is an Ook! emitter anywhere. So instead of giving Ook! and getting Perl, you'd give it Perl and get Ook! Scanning the POD, I didn't see that functionality in the CPAN modules cog listed. (Maybe there is no way to do a perfect one--only perl can parse Perl and all--but any bit would be interesting/fun.)

      Ook is Turing Complete so there should be no problem parsing Perl into Ook. I leave that as a exercise for the reader however.


      Perl is Huffman encoded by design.

      I have written an Ook! generator that creates an Ook! program to print a given string. It is currently in GrandFather's scratchpad if you are interested. Now appended to OP.


      Perl is Huffman encoded by design.
Re: Ook interpreter
by holli (Abbot) on Aug 02, 2005 at 12:54 UTC
    On my system (AS Perl 5.8, WinXP), it runs for ages and then segfaults.


    holli, /regexed monk/

      Seems likely to have been due to missing white space after the last instruction in the Ook code. The interpreter should handle that better now.


      Perl is Huffman encoded by design.

      I'm running AS Perl 5.8.7 built for MSWin32-x86-multi-thread. Only thing I can think of is that the data has been corrupted in some fashion. The parsing is not exactly robust :).

      Should I do a "debugging" version that limit the number of instructions executed and traces execution?


      Perl is Huffman encoded by design.
      runs just fine under AS perl, v5.8.6 built for MSWin32-x86-multi-thread (XP prof)
Re: Ook interpreter
by girarde (Hermit) on Jun 07, 2006 at 20:41 UTC
    I expect an Ook debugger would need an -e (--eat) switch.

    Depending on what sort of bug it was.

      I have a message written in Ook. Do you know of any way to translate it into English? Any help would be greatly appreciated. Thanks

        If you mean written in Ook! (the programing language) then you can run it using the code given in the OP Ook interpreter. Simply replace the current sample Ook! code in the __DATA__ section with your Ook! code and execute the program.

        If you mean the language used by the Librarian in Terry Pratchett's Disk World novels, then I suggest you contact Terry Pratchett who may be able to supply a translation.


        DWIM is Perl's answer to Gödel
Re: Ook interpreter
by jkva (Chaplain) on Aug 16, 2005 at 07:19 UTC
    This just rocks so much. Thanks for writing it :)