http://www.perlmonks.org?node_id=1066494

Greetings

my teacher assigned us a brainfuck interpreter[1]. Here's what I've arrived at.

#! /usr/bin/perl ($dpos, $data, $/) = (0, ""); sub data :lvalue { vec($data, $dpos, 8) } <> =~ m{ (?: [>] (?{++$dpos}) | [+] (?{++(data)}) | [.] (?{print chr data}) | [<] (?{--$dpos}) | [-] (?{--(data)}) | [,] (?{data= ord getc}) | [[] (?(?{data})(?0)|(?1)) []] | [^][<>.,+-] )*+\z | (?(?{data})(?0)|(?1)) | \z((?: [^][] | [[] (?1) []])*) }x; BEGIN { *ARGV = *DATA unless @ARGV } __DATA__ +++++[>+++++++++<-],[[>--.++>+<<-]>+.->[<.>-]<<,]

For timing and testing I have used 392quine.b. This, and some other bf programs found here.

I'd say this regex based interpreter is fairly legible and uncomplicated (*cough*), though couple of snags remain.
First and foremost, the unfortunate "recursion" limit is encountered when long (but non-recursing) code is run:
$ perl -w bf.pl <(perl bf.pl < bf.pl) Complex regular subexpression recursion limit (32766) exceeded at bf +.pl line 5, <> chunk 1. ...
It should output whatever it was fed (bf.pl itself), but goes apeshit midway through. The workaround is to use (?:(?:__)*)*; however, I find this just too disgraceful. In this thread, ikegami hints at possible upcoming fix. Well, that was four years ago, and it sure isn't fixed in v5.18.1, let alone v5.12.3. I wonder if this is solved in more recent perls?

Another annoyance is with the data sub. It can be written in several ways

sub data :lvalue { vec($data,$dpos,8) } # v5.16.1--OK; v5.12.3--Fail sub data :lvalue { vec($data,$dpos,8) //= 0 } # OK my @data; sub data :lvalue { $data[$dpos] &= 255 } # OK
The first one appears more expressive, though the array variant is no slower.

Finally, there may well be some important optimizations I've missed or somesuch. Suggestions are welcome, of course.