DEV Community

FreakCdev
FreakCdev

Posted on • Edited on

Creating Brainfuck

Brainfuck is one of the most iconic programming languages out there, and probably the king of esolangs. So today, I will share how to create Brainfuck.

Understanding Brainfuck

So as we all might have known, Brainfuck has 8 commands:

  • ">" increment the data pointer (to point to the next cell to the right).
  • "<" decrement the data pointer (to point to the next cell to the left).
  • "+" increment (increase by one) the byte at the data pointer.
  • "-" decrement (decrease by one) the byte at the data pointer.
  • "." output the byte at the data pointer.
  • "," accept one byte of input, storing its value in the byte at the data pointer.
  • "[" if the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the command after the matching ] command.
  • "]" if the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the command after the matching [ command.

Choosing a way to run our code

Normally, you would have these programs to execute a programming language's codes:

  • Compiler (compiles to machine code)
  • Interpreter
  • Transpiler (compiles to source code)

Compilers are quite complex and they require you to have machine code's understanding which is not our choice when just creating a simple esolang. Interpreters and transpilers are good ones since they are easy to create, especially for esolangs. In this article, I will create a transpiler as it's the easiest.

Creating a transpiler

Language to use

I will use Javascript to create the transpiler, and the compilation target will be Javascript as well. Now, let's get our hand dirty.

Create a transpile function

We just simply create a function which takes all the codes as input, and return the compiled codes to output.

const transpile = input => { let output = 'let cells = Array(30000).fill(0), ptr=0;'; return output; } 
Enter fullscreen mode Exit fullscreen mode

The output variable already has 1 line to declare an array cells which has 30000 elements all start at 0 and a ptr variable which is the pointer of the cell.

Parsing commands

We can create a simple lexer like this:

const transpile = input => { let output = 'let cells = Array(30000).fill(0), ptr=0;'; input.split('').forEach(token => { }) return output; } 
Enter fullscreen mode Exit fullscreen mode

Now, we want to do stuffs which each token (command), we just need to add a switch statement:

const transpile = input => { let output = 'let cells = Array(30000).fill(0), ptr=0;'; input.split('').forEach(token => { switch (token) { case '+': break; case '-': break; case '>': break; case '<': break; case '.': break; case ',': break; case '[': break; case ']': break; } }) return output; } 
Enter fullscreen mode Exit fullscreen mode

Then, we just implement each token's functionality in JS:

const transpile = input => { let output = 'let cells = Array(30000).fill(0), ptr=0;'; input.split('').forEach(token => { switch (token) { case '+': output+='++cells[ptr];'; break; case '-': output+='--cells[ptr];'; break; case '>': output+='++ptr;'; break; case '<': output+='--ptr;'; break; case '.': output+='document.write(String.fromCharCode(cells[ptr]));'; break; case ',': output+='cells[ptr]=prompt();'; break; case '[': output+='while (cells[ptr] > 0) {'; break; case ']': output+='}'; break; } }) return output; } 
Enter fullscreen mode Exit fullscreen mode

There you go, that's how you can create a Brainfuck transpiler, you just need to take the output codes and run them in a browser, then it should work fine.

Running it immediately

If you're tired of copying the output codes and run it in a different place, you can create a version that runs the code immediately like this:

const transpile = input => { let output = 'let cells = Array(30000).fill(0), ptr=0;'; input.split('').forEach(token => { switch (token) { case '+': output+='++cells[ptr];'; break; case '-': output+='--cells[ptr];'; break; case '>': output+='++ptr;'; break; case '<': output+='--ptr;'; break; case '.': output+='document.write(String.fromCharCode(cells[ptr]));'; break; case ',': output+='cells[ptr]=prompt();'; break; case '[': output+='while (cells[ptr] > 0) {'; break; case ']': output+='}'; break; } }) new Function(output)(); } 
Enter fullscreen mode Exit fullscreen mode

Basically, we just create a new function and execute the codes.

Thanks for your time, if you're interested in programming languages, please consider checking out my language "FreakC".

Top comments (0)