15
\$\begingroup\$

I overloaded some C# operators to get a pseudo version of the Brainfuck symbols in the effort of understanding the flow of this language.

I got this version:

void Main()
{
    /*
    *   Write `Hello World!`
    *           using operators overloading for brainfuck symbols
    */
    var _ = new brainfuck();


    _ = + + + + +    + + + + +     _        ; // set cell #0 to 10

    while (_)
    {
        _ =     + + + + +    + +       (_ > 1)              ; // add 7 to #1
        _ =     + + + + +    + + + + + (_ > 1)              ; // add 10 to #2
        _ =     + + +                  (_ > 1)              ; // add 3 to #3
        _ =     +                      (_ > 1)              ; // add 1 to #4

        _ =     -                      (_ < 1 < 1 < 1 < 1)  ; // decrement 0
    }
    _ =     ~   + +                    (_ > 1)              ; // write 'H'
    _ =     ~   +                      (_ > 1)              ; // write 'e'
    _ =     ~   + + + + +    + +        _                   ; //write 'l'
    _ =     ~                           _                   ; //write 'l'
    _ =     ~   + + +                   _                   ; // write 'o'
    _ =     ~   + +                     (_ > 1)             ; // write ' '
    _ =     ~   + + + + +    + + + + +   + + + + +      (_ < 1 < 1)     ; // write 'W'
    _ =     ~                           (_ > 1)             ; // write 'o'
    _ =     ~   + + +                   _               ; // write 'r'
    _ =     ~   - - - - -    -          _               ; // write 'l'
    _ =     ~   - - - - -    - - -      _               ; // write 'd'
    _ =     ~   +                       (_ > 1)         ; // write '!'
    _ =     ~                           (_ > 1)         ; // write '\n'
}
public class brainfuck
{
    private List<int> cells;
    private int currentCell;
    public brainfuck()
    {
        cells = new List<int>{0};
    }

    public static brainfuck operator + (brainfuck bf) 
    {
        bf.plus();
        return bf;
    }
    public static brainfuck operator - (brainfuck bf) 
    {
        bf.minus();
        return bf;
    }
    public static brainfuck operator > (brainfuck bf, int pos = 1) 
    {
        bf.right();
        return bf;
    }
    public static brainfuck operator < (brainfuck bf, int pos = 1) 
    {
        bf.left();
        return bf;
    }


    public static brainfuck operator ~ (brainfuck bf) 
    {
        bf.write();
        return bf;
    }
    public static brainfuck operator ! (brainfuck bf) 
    {
        bf.read();
        return bf;
    }
    public static implicit operator bool (brainfuck bf) 
    {
        return bf.has_data();
    }

    private int plus()
    {
        return ++cells[currentCell];
    }
    private int minus()
    {
        return --cells[currentCell];        
    }
    private void right()
    {
        if (currentCell + 1 == cells.Count)
            cells.Add(0);
        currentCell++;
    }
    private void left()
    {
        if (currentCell > 0)
            currentCell--;
    }
    private int current()
    {
        return cells[currentCell];
    }
    private void write()
    {
        Console.Write((char)current());
    }
    private void read()
    {
        var input = Console.ReadLine();
        int value = Int32.TryParse(input, out value) ? value : 0;
        current(value);
    }
    private bool has_data()
    {
        return current() > 0;
    }
    private void current(int value)
    {
        cells[currentCell] = value;
    }




    public override string ToString()
    {
        return String.Join(",",cells);
    }
}

I had to cheat with the [] command pair using the while statement and the flow is very odd from the point of Brainfuck reader, since the <,> commands are before the +,- in the original Hello World! example, and with C# program are in the opposite way.

Do you think I can get a closer version to Brainfuck than the current one?

\$\endgroup\$
  • 8
    \$\begingroup\$ Welcome to Code Review! I hope you get some great answers. \$\endgroup\$ – Phrancis Aug 29 '16 at 23:48
6
\$\begingroup\$

You could get slightly closer with the [] command pair.

It's actually quite trivial:

Add an indexer to your brainfuck class (public void this[Action bf]) and put your while loop in there.

The indexer would look like:

public brainfuck this[Action action]
{
    get
    {
        while (this)
        {
            action.Invoke();
        }

        return this;
    }
}

You would call it as:

_ = _[() => {
    _ =     + + + + +    + +       (_ > 1)              ; // add 7 to #1
    _ =     + + + + +    + + + + + (_ > 1)              ; // add 10 to #2
    _ =     + + +                  (_ > 1)              ; // add 3 to #3
    _ =     +                      (_ > 1)              ; // add 1 to #4

    _ =     -                      (_ < 1 < 1 < 1 < 1)  ; // decrement 0
}];

Is it a pain in the rear to use? Yes. Is it in the Brainfuck spirit? Yes.

It's still not true brainfuck syntax, but you won't get there with C#.


After that, you have a real mess here that needs cleaned.

First: capitalization. In C# we PascalCase public members and types (and all methods), and camelCase private and local members and types.

public class Brainfuck
private bool HasData()

Since "Brainfuck" is one word, the "F" in "fuck" is not capitalized.

The optional argument defaults in operator > and operator < are not at all going to work, remove them.

public static brainfuck operator > (brainfuck bf, int pos) 
{
    bf.right();
    return bf;
}
public static brainfuck operator < (brainfuck bf, int pos) 
{
    bf.left();
    return bf;
}

Always use braces, even when you don't need them.

private void Right()
{
    if (currentCell + 1 == cells.Count)
    {
        cells.Add(0);
    }

    currentCell++;
}

Use int instead of Int32 everywhere.

int value = int.TryParse(input, out value) ? value : 0;

Once we apply all these changes, fix some spacing, we end up with a not-so-bad looking class:

public class Brainfuck
{
    private List<int> cells;
    private int currentCell;

    public Brainfuck()
    {
        cells = new List<int>{0};
    }

    public Brainfuck this[Action action]
    {
        get
        {
            while (this)
            {
                action.Invoke();
            }

            return this;
        }
    }

    public static Brainfuck operator + (Brainfuck bf) 
    {
        bf.Plus();
        return bf;
    }

    public static Brainfuck operator - (Brainfuck bf) 
    {
        bf.Minus();
        return bf;
    }

    public static Brainfuck operator > (Brainfuck bf, int pos) 
    {
        bf.Right();
        return bf;
    }

    public static Brainfuck operator < (Brainfuck bf, int pos) 
    {
        bf.Left();
        return bf;
    }

    public static Brainfuck operator ~ (Brainfuck bf) 
    {
        bf.Write();
        return bf;
    }

    public static Brainfuck operator ! (Brainfuck bf) 
    {
        bf.Read();
        return bf;
    }

    public static implicit operator bool (Brainfuck bf) 
    {
        return bf.HasData();
    }

    private int Plus()
    {
        return ++cells[currentCell];
    }

    private int Minus()
    {
        return --cells[currentCell];        
    }

    private void Right()
    {
        if (currentCell + 1 == cells.Count)
        {
            cells.Add(0);
        }

        currentCell++;
    }

    private void Left()
    {
        if (currentCell > 0)
        {
            currentCell--;
        }
    }

    private int Current()
    {
        return cells[currentCell];
    }

    private void Write()
    {
        Console.Write((char)Current());
    }

    private void Read()
    {
        var input = Console.ReadLine();
        int value = int.TryParse(input, out value) ? value : 0;
        Current(value);
    }

    private bool HasData()
    {
        return Current() > 0;
    }

    private void Current(int value)
    {
        cells[currentCell] = value;
    }

    public override string ToString()
    {
        return String.Join(",",cells);
    }
}

And our code for the "Hello World" looks like:

void Main()
{
    /*
    *   Write `Hello World!`
    *           using operators overloading for brainfuck symbols
    */
    var _ = new Brainfuck();

    _ = + + + + +    + + + + +     _        ; // set cell #0 to 10

    _ = _[() => {
        _ =     + + + + +    + +       (_ > 1)              ; // add 7 to #1
        _ =     + + + + +    + + + + + (_ > 1)              ; // add 10 to #2
        _ =     + + +                  (_ > 1)              ; // add 3 to #3
        _ =     +                      (_ > 1)              ; // add 1 to #4

        _ =     -                      (_ < 1 < 1 < 1 < 1)  ; // decrement 0
    }];
    _ =     ~   + +                    (_ > 1)              ; // write 'H'
    _ =     ~   +                      (_ > 1)              ; // write 'e'
    _ =     ~   + + + + +    + +        _                   ; //write 'l'
    _ =     ~                           _                   ; //write 'l'
    _ =     ~   + + +                   _                   ; // write 'o'
    _ =     ~   + +                     (_ > 1)             ; // write ' '
    _ =     ~   + + + + +    + + + + +   + + + + +      (_ < 1 < 1)     ; // write 'W'
    _ =     ~                           (_ > 1)             ; // write 'o'
    _ =     ~   + + +                   _               ; // write 'r'
    _ =     ~   - - - - -    -          _               ; // write 'l'
    _ =     ~   - - - - -    - - -      _               ; // write 'd'
    _ =     ~   +                       (_ > 1)         ; // write '!'
    _ =     ~                           (_ > 1)         ; // write '\n'
}

Overall, not too bad. I wouldn't have done it, but that's because I wrote a Brainfuck to C# transpiler. Good work. :)

\$\endgroup\$
  • 1
    \$\begingroup\$ The indexer is a great idea, a good example for when they say to think outside the box. \$\endgroup\$ – Adrian Iftode Dec 8 '16 at 10:18
  • 1
    \$\begingroup\$ @AdrianIftode It's one of those things where we're already abusing the snot out of the language, we may as well abuse it more. :) \$\endgroup\$ – Der Kommissar Dec 14 '16 at 18:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.