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()