Creating Brainfuck
Tags: esoteric, esolang, brainfuck, opensource
Published: 2021-06-06 12:43:25

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`. 
```js
const transpile = input => {
    let output = 'let cells = Array(30000).fill(0), ptr=0;';
    return output;
}
```
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:

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

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

```js
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;
}
```

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

```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;
}
```

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:

```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;
        }
    })
    new Function(output)();
}
```
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](https://github.com/FreakC-Foundation/FreakC)".