Madbrain
Madbrain is a stack-based "2D" esoteric programming language invented by User:Feuermonster in 2010.
If an opcode takes 2 arguments, the first argument is taken from the top of the stack, and the second from the bottom of the stack. Madbrain has a horizontal instruction pointer. The code is executed line by line. But only the opcode pointed to by the horizontal instruction pointer is executed.
012 <- 0 will be executed ppp <- p will be executed
If the horizontal instruction pointer is 1
012 <- 1 will be executed ppp <- p (the second) will be executed
4 <- 4 will be executed i <- i will be executed (horizontal instruction pointer is now 4) 12345 <- 5 will be executed p <- prints 5. 4 d <- horizontal instruction pointer is now 0 12345 <- 1 will be executed p <- prints 1
Both instruction pointers are initially set to zero (lines are zero based).
Opcodes
0-9: Pushes the number onto the stack j (1 Argument): Jumps to the line pointed to by the argument g (2 Arguments): Jumps to the line pointed to by the first argument and increases the horizontal instruction pointer by the second argument q (2 Arguments): Jumps to the line pointed to by the first argument and decreases the horizontal instruction pointer by the second argument i (1 Argument): Increases the horizontal instruction pointer by the argument d (1 Argument): Decreases the horizontal instruction pointer by the argument x: Terminates the program r: Reads a single digit from stdin and pushes it onto the stack as an integer * (2 Arguments): Multiplies the arguments together / (2 Arguments): Divides the first argument by the second + (2 Arguments): Adds the arguments together - (2 Arguments): Subtracts the second argument by the first p (1 Argument): Prints the argument as a number c (1 Argument): Prints the argument as a character. Only integers smaller than 256 are printed. Negative integers are undefined or implementation-dependent behavior. > (2 Arguments): If the first argument is greater than the second, the horizontal instruction pointer is increased by one. < (2 Arguments): If the first argument is less than the second, the horizontal instruction pointer is increased by one. ^ (2 Arguments): If the first argument is greater than the second, the horizontal instruction pointer is decreased by one. v (2 Arguments): If the first argument is less than the second, the horizontal instruction pointer is decreased by one. ? (1 Argument): If the argument is greater than zero, the horizontal instruction pointer is increased by one. ! (1 Argument): If the argument is greater than zero, the horizontal instruction pointer is decreased by one. : (1 Argument): If the argument is zero, the horizontal instruction pointer is increased by one. ; (1 Argument): If the argument is zero, the horizontal instruction pointer is decreased by one. . (1 Argument): If the argument is less than zero, the horizontal instruction pointer is increased by one. , (1 Argument): If the argument is less than zero, the horizontal instruction pointer is decreased by one. = (2 Arguments): If the first argument is equal to the second, the horizontal instruction pointer is increased by one. _ (2 Arguments): If the first argument is equal to the second, the horizontal instruction pointer is decreased by one. # (2 Arguments): If the first argument is not equal to the second, the horizontal instruction pointer is increased by one. @ (2 Arguments): If the first argument is not equal to the second, the horizontal instruction pointer is decreased by one.
Any character which is not an opcode is a nop.
Examples
Equality Check
rp 1x r = 01 00 gj
This program asks the user to input two numbers. If they are equal, madbrain will print 1, else 0.
Hello, world!
9 5 9 9 5 7 8 7 5 5 9 5 8 8 5 4 4 3 6 4 4 3 3 4 5 4 * * * * * * * * * * * * * c 4 3 3 2 2 c 4 2 4 3 4 1 2 * * * * + 2 * * + * * + 0 1 c c 7 c 0 7 7 6 c c c g + 2 2 + 2 g + + * 2 2 x c 0 0 3 0 c 3 c 0 0 2 g g * g 2 * 2 g g 0 c 0 c 0 g 2 g 2 g 0 0 g g
Spaces for readability.
Truth-machine
r : 10 pp 2x j
Computational class
Madbrain is Turing complete because it can implement tag systems with an alphabet of up to 8 characters, enough for Turing completeness. (A compiler to produce such implementations is available on the talk page.)
Implementation (Python 3)
#!/usr/bin/env python import sys def main(): f = open(sys.argv[1], 'r') prg = f.read().splitlines() f.close() prgPos = 0 ptr = 0 stk = [] cmds = { '*': 'mul', '/': 'div', '+': 'add', '-': 'sub', '>': 'ga', '<': 'la', '^': 'gs', 'v': 'ls', '?': 'gza', '!': 'gzs', ':': 'eza', ';': 'ezs', '.': 'lza', ',': 'lzs', '=': 'ea', '_': 'es', '#': 'nea', '@': 'nes' } def j(): nonlocal prgPos prgPos = stk.pop() - 1 def g(): nonlocal ptr j() ptr += stk.pop(0) def q(): nonlocal ptr j() ptr -= stk.pop(0) def i(): nonlocal ptr ptr += stk.pop() def d(): nonlocal ptr ptr -= stk.pop() def x(): sys.exit(0) def mul(): stk.append(stk.pop() * stk.pop(0)) def div(): stk.append(stk.pop() / stk.pop(0)) def add(): stk.append(stk.pop() + stk.pop(0)) def sub(): stk.append(stk.pop() - stk.pop(0)) def r(): inp = input('\nAwaiting input: ')[0] while not inp.isdigit(): inp = input('Input must be a digit.\nAwaiting input: ') stk.append(int(inp)) def p(): print(stk.pop(), end='') def c(): i = stk.pop() if 0 <= i <= 255: print(chr(i), end='') def ga(): nonlocal ptr ptr += stk.pop() > stk.pop(0) def la(): nonlocal ptr ptr += stk.pop() < stk.pop(0) def gs(): nonlocal ptr ptr -= stk.pop() > stk.pop(0) def ls(): nonlocal ptr ptr -= stk.pop() < stk.pop(0) def gza(): nonlocal ptr ptr += stk.pop() > 0 def gzs(): nonlocal ptr ptr -= stk.pop() > 0 def eza(): nonlocal ptr ptr += stk.pop() == 0 def ezs(): nonlocal ptr ptr -= stk.pop() == 0 def lza(): nonlocal ptr ptr += stk.pop() < 0 def lzs(): nonlocal ptr ptr -= stk.pop() < 0 def ea(): nonlocal ptr ptr += stk.pop() == stk.pop(0) def es(): nonlocal ptr ptr -= stk.pop() == stk.pop(0) def nea(): nonlocal ptr ptr += stk.pop() != stk.pop(0) def nes(): nonlocal ptr ptr -= stk.pop() != stk.pop(0) while prgPos < len(prg): cmd = prg[prgPos][ptr] if (cmd in 'jidpc?!:;.,' and len(stk) < 1) or (cmd in 'gq*/+-><^v=_#@' and len(stk) < 2): raise IndexError('at ' + cmd + ': insufficient items in stack') if cmd.isdigit(): stk.append(int(cmd)) prgPos += 1 continue try: exec(cmds.get(cmd, cmd) + '()') except NameError: pass prgPos += 1 if __name__ == '__main__': main()