go-brainfuck-yourself

A Brainfuck interpreter that I wrote myself in Go
git clone git@abtrout.com:go-brainfuck-yourself.git
Log | Files | Refs | README

commit aa565944a634fe5dbfc933226dc8174a94b5766c
parent 95adca93024128834464c55876fda58676697b23
Author: david cochran <about.trout@gmail.com>
Date:   Tue,  7 Jul 2026 20:05:22 -0700

replace recursive eval with for

fixes stack overflow from complex programs, e.g. mandelbrot.

Diffstat:
Mbf.go | 77+++++++++++++++++++++++++++++++++++++++--------------------------------------
1 file changed, 39 insertions(+), 38 deletions(-)

diff --git a/bf.go b/bf.go @@ -48,47 +48,48 @@ func (bf *Brainfuck) Eval(cmd byte) error { } func (bf *Brainfuck) eval() error { - if n := len(bf.cmds); n == 0 || n <= bf.i { - return nil - } - - switch bf.cmds[bf.i] { - case '>': - bf.d++ - if bf.d >= len(bf.cells) { - bf.d -= len(bf.cells) - } - case '<': - bf.d-- - if bf.d < 0 { - bf.d += len(bf.cells) - } - case '+': - bf.cells[bf.d]++ - case '-': - bf.cells[bf.d]-- - case '.': - if _, err := bf.out.Write([]byte{bf.cells[bf.d]}); err != nil { - return fmt.Errorf("failed to Write output: %v", err) - } - case ',': - input := make([]byte, 1) - if _, err := bf.in.Read(input); err != nil { - return fmt.Errorf("failed to Read input: %v", err) + for { + if n := len(bf.cmds); n == 0 || n <= bf.i { + return nil } - bf.cells[bf.d] = input[0] - case '[': - if bf.cells[bf.d] == 0 { - bf.i = bf.loops[bf.i] - } - case ']': - if bf.cells[bf.d] != 0 { - bf.i = bf.loops[bf.i] + + switch bf.cmds[bf.i] { + case '>': + bf.d++ + if bf.d >= len(bf.cells) { + bf.d -= len(bf.cells) + } + case '<': + bf.d-- + if bf.d < 0 { + bf.d += len(bf.cells) + } + case '+': + bf.cells[bf.d]++ + case '-': + bf.cells[bf.d]-- + case '.': + if _, err := bf.out.Write([]byte{bf.cells[bf.d]}); err != nil { + return fmt.Errorf("failed to Write output: %v", err) + } + case ',': + input := make([]byte, 1) + if _, err := bf.in.Read(input); err != nil { + return fmt.Errorf("failed to Read input: %v", err) + } + bf.cells[bf.d] = input[0] + case '[': + if bf.cells[bf.d] == 0 { + bf.i = bf.loops[bf.i] + } + case ']': + if bf.cells[bf.d] != 0 { + bf.i = bf.loops[bf.i] + } } - } - bf.i++ - return bf.eval() + bf.i++ + } } // Dump interpreter state to caller.