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.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?$ perl -w bf.pl <(perl bf.pl < bf.pl) Complex regular subexpression recursion limit (32766) exceeded at bf +.pl line 5, <> chunk 1. ...
Another annoyance is with the data sub. It can be written in several ways
The first one appears more expressive, though the array variant is no slower.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
Finally, there may well be some important optimizations I've missed or somesuch. Suggestions are welcome, of course.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Brainfunk. With Regex.
by choroba (Cardinal) on Dec 10, 2013 at 21:08 UTC | |
|
Re: Brainfunk. With Regex.
by ambrus (Abbot) on Dec 11, 2013 at 10:36 UTC | |
|
Re: Brainfunk. With Regex.
by oiskuu (Hermit) on Jul 01, 2015 at 20:55 UTC |