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:
| M | bf.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.