HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Object-oriented Brainfuck interpreter

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
orientedobjectinterpreterbrainfuck

Problem

Inspired by this question, I decided to give it a try and implemented a brainfuck interpreter myself. It includes various improvements:

  • It's object-oriented and modular



  • Unlimited tape size



  • It includes a call stack (no seeking for opening parenthesis)



  • It allows stepping and debugging



  • It throws exceptions on errors



Tape

/// 
/// One-sided, infinite, default-initialized Tape. 
public class Tape
{
    List _tape;
    int _pos;

    public Tape()
    {
        _tape = new List();
        _tape.Add(default(T));
        _pos = 0;
    }

    /// 
    /// Currently selected cell's value. 
    public T Value
    {
        get
        {
            return _tape[_pos];
        }
        set
        {
            _tape[_pos] = value;
        }
    }

    /// 
    /// Step one cell to the left. 
    public void StepLeft()
    {
        if (_pos == 0)
            throw new InvalidOperationException();
        else
            _pos--;
    }

    /// 
    /// Step one cell to the right. 
    public void StepRight()
    {
        _pos++;
        if (_pos == _tape.Count)
            _tape.Add(default(T));
    }

    /// 
    /// Return a full snapshot of the tape without altering anything. 
    public T[] ToArray()
    {
        return _tape.ToArray();
    }
}


Interpreter

```
public class BrainfuckInterpreter
{
Stream _program;
Stream _input;
Stream _output;
Tape _tape;
Stack _callStack;

///
/// Create a new BrainfuckInterpreter.
///
/// Program to be executed. Must be readable and seekable.
///
/// Must be readable. Can be null if the program doesn't take any input.
///
/// Must be writable. Can be null if the program doesn't produce output.
public BrainfuckInterpreter(Stream program, Stream input, Stream output)
{
_program = program;
_input = input;
_output = output;
_tape = new Tape();
_callStack = new Stack();
}

///
/// Run the pr

Solution

switch (command)
{
    …
    case '[': _callStack.Push(_program.Position); break;
    case ']':
        if (_tape.Value == 0)
            _callStack.Pop();
        else
            _program.Position = _callStack.Peek();
        break;
}


A call stack in a tape-based language? Heresy!

Seriously, though, the code is wrong. You have implemented a do { … } while (_tape.Value != 0) loop instead of a while (_tape.Value != 0) { … } loop.

Code Snippets

switch (command)
{
    …
    case '[': _callStack.Push(_program.Position); break;
    case ']':
        if (_tape.Value == 0)
            _callStack.Pop();
        else
            _program.Position = _callStack.Peek();
        break;
}

Context

StackExchange Code Review Q#144900, answer score: 5

Revisions (0)

No revisions yet.