Brainknot
About brainknot
It's a similar language to Brainfuck and Turing machine made by Users:Mahdoosh1. But with some changes
Syntax
it's the same, but alphabet are not counted as comments, you need a spcific symbol before every comment
What's the difference?
Unlike Brainfuck, brainknot is based on bits instead of bytes, so there are no characters. It uses stack instead of memory line and it has a register called current bit
Memory
even though you only have one bit to work with, you can go to different parts of your code based on that bit, and you can use stacks for memory
Stacks
This language uses stacks for memory. Here are all of them:
- Input stack (pop only)
- Output stack (push only)
- Main stacks
Comments (introduced in VX)
- `/` starts or ends a comment
basic symbols (introduced in V1/V3)
- `>` pops 1 bit from input stack onto current bit (overwrites it)
- `<` pushes current bit to output stack (does not change current bit)
- `-` pops from current working stack to current bit (overwrites it)
- `+` pushes current bit to current working stack (does not change current bit)
- `*` flips current bit (like a not gate. Flips 1 to 0 and flips 0 to 1)
if-else statement (introduced in V1, improved in V2)
- `[` starts if statement (don't get wrong with loops in Brainfuck)
- `]` ends if statement
Example:
[if do, else do]
if current bit is 1, run first segment (segments are splited with comma)
if current bit is 0, run second segment
Note: You don't need to provide both segments. You can use
[do something]
only for if statement, or you can use
[,do something]
only for else statement.
loop (introduced in V2)
- `(` starts while loop (if current bit is 1)
- `)` exits from while loop (if current bit is 0)
- `.` breaks the loop (when pop error occurs, the program automatically breaks the loop)
define a function (introduced in V3)
- `:` defines a function.
Name in the right
Functionality in left (should be in [] to separate rest of the program and functionality, don't get it wrong with if statements)
if you use (parenthesis), function will be called while defining.
while defining a function you can use stack for input/output of function. And you call a function with its name, you don't need anything. But note that you have to separate two adjacent function calls with space. you can define recursive functions as well.
Example:
xor:[ -[-*+] ] main:( >+ >+ xor -< )
Stack changing
numbers are used to change which stack are we using. 0 is default, and you can use multiple numbers, like 11 or 69420.
Turing Complete
Yes, this language is turing complete, even though not proved yet.
Examples
Hello world program in binary (written in VX because of comments):
<*<*<<*<*<<< /H/ /01001000/ <*<<*<<*<*<*< /e/ /01100101/ *<*<<*<*<<*<< /l/ /01101100/ <*<<*<*<<*<< /l/ /01101100/ <*<<*<*<<<< /o/ /01101111/ *<<*<*<*<<*<< /,/ /00101100/ <<*<*<<<<< / / /00100000/ <*<*<*<*<*<<< /W/ /01010111/ *<*<<*<*<<<< /o/ /01101111/ *<*<<<*<<*<*< /r/ /01110010/ <*<<*<*<<*<< /l/ /01101100/ <*<<*<<*<*<< /d/ /01100100/ <<*<*<<<<*< /!/ /00100001/
Hello world program (written in VX using printing):
{Hello, World!}
Cat program:
*(><[,*])
One-time cat program:
><
Truth-machine:
>[(<),<]
Logic gates:
and:[-[,-[*]+]] nand:[-[-*,-[,*]]+] or:[-[-[,*]+]] nor:[-[-[*],-*]+] not:[-*+] xor:[-[not]] xnor:[-[,not]]
Versions (new features)
Version 1
- `>` input (or break loop if nothing to pop)
- `<` output
- `[` if
- `]` end of if
- `*` flip (aka invert/not)
Version 2
- `,` used for else
- `(` while
- `)` end of while
- `.` break loop
Version 3
- `-` pop (or break loop if nothing to pop)
- `+` push
- `abc:[]` define
- `abc:()` define and call
- `abc` call
- ` ` (space or any other whitespace) seprate function calls (or noop)
Version 4
- `0` set current working stack to stack 0
- `1` set current working stack to stack 1
- `12` set current working stack to stack 12
- `[a,b,c]` run c after checking current bit (used if `a` and `b` have the same code at start, making the code shorter)
- Note: execution order is `c` then `a` or `b` (depending on current bit before running `c`)
Version Extra
- `^` put a black/white pixel on screen depending on current bit (0 = black, 1 = white) and go to next pixel
- `\` next line in screen
- `;` update screen/draw frame (and go back to starting pixel)
- `{hi}` print
- `/comment/` put a comment
- `~` pop and push back (except not)
- `_` print current working stack to console
Interpreter
Here is my Github repo containing the interpreter written in python. (It was too long to write it here)