- Rust 55.7%
- Brainfuck 44.3%
| src | ||
| tictactoe | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| iteration2.txt | ||
| LICENSE | ||
| README.md | ||
| test.buf | ||
The BUF programing langue
The BUF (brain unfucked) progaming langue was designed to be C-like and compile into brainfuck.
What is brainfuck?
Brainfuck is an esoteric programing language that is notoriously hard to program in. It consists of only eight instructions and accepts no other characters. The language imagines memory as a list of u8 integer memory cells, with a pointer pointing to one cell, known as the current cell.
The instructions are:
| Instruction | Description |
|---|---|
| + | Add one to the current memory cell. |
| - | Remove one from the curent memory cell. |
| [ | If the current memory cell is non 0, execute the code until the matching ]. Otherwise jump to the instruction after the corresponding ]. |
| ] | Jump to the matching previous [. |
| , | Input one character and set its ASCII value to the current cell. |
| . | Expect the current cell to contain an ASCII value. Print the corresponding character. |
| < | Make the cell to the left of the current cell the new current cell. |
| > | Make the cell to the right of the current one the new current cell. |
The purpose BUF
This language was developed for the fun of it, and does not serve any purpose on its own. However, the unique attributes and limitations of brainfuck has shaped this langue to be quite its own challenge to write in. This challenge is different from coding brainfuck on its own, and you may find it interesting or fun to try to develop something in it. If you do develop any project in BUF, please share it.
Learn the language
Below is a full guide of the BUF programing language. It assumes you have some previous experience coding. Under no circumstances should BUF be your first programing language.
Comments
Comments are included in the brainfuck code, so they must not contain any of the characters in the brainfuck language.
/* This is a comment */
Variables
There are two types recognized in BUF.
- int - An integer value between 0 and 255.
- char - An ASCII character. No Unicode here.
Each variable corresponds to a memory cell in brainfuck. Variables are always initialized to 0 unless otherwise declared.
int variable = 4;
char character;
Variables can be lists of memory cells. Lists must be of a constant size. Their size can not be defined, extended or reduced at runtime.
const STRING_SIZE = 5;
int[3] list = [1,2,3];
char[STRING_SIZE] string = "words";
That means the size can only be defined by numbers and constants, never by variables.
Constants
Constants are only used at compile time, and their names are simply replaced with their value. Therefore they are not typed.
const name = "Bob";
const string_size = 3;
char[string_size] string = name;
Pointers
Pointers are typed. To assign the pointer to a memory cell: prefix the pointer name with a * and use the & prefix on the variable. The pointer can be initialized when declared as well.
int *pointer;
*pointer = &variable;
int *pointer2 = &variable;
You can point a pointer to any segment in a list.
int *p = &list[2];
Freeing up memory
When a variable is no longer desired its memory can be given back to the compiler to use for future allocations. This is done automatically when a namespace, such as a function, ends. But it can also be done manually using the free keyword.
int a;
free a;
Variables declared inside of loops belong to the surrounding namespace, and are not freed when the loop ends.
Functions
Brainfuck does not have any jump instructions, nor a stack, and therefore there can be no traditional function calls. In BUF, function code is simply inserted where ever the function is called. The variables and arguments processed in the function belongs to a different namespace, and are unallocated when the function ends.
int function(int arg) {
int var = 4;
return var+1;
}
Functions can be declared as returning char, int or void (no return value). Functions can return lists as well. Functions can however not return pointers.
Pointers as arguments allow you to modify variables from the calling namespace, when return values are not desired.
void function(int* p) {
p = 3;
}
int var = 1;
function(&var);
/* The value of var is now 3 */
The return statement MUST be the last statement in any non void function. You can never return early. Trying to return early will yield unpredictable results.
/* This is NOT how to return in BUF */
int function(int arg) {
if arg < 10 {
return 1;
}
return 0;
}
/* This is how you do it! */
int function(int arg) {
int result; /* Initialized to 0*/
if arg < 10 {
result = 1;
}
return result;
}