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()
Category:Languages
Category:Implemented
Category:Turing complete
Category:2010
Category:Low-level
Category:Stack-based
Category:Two-dimensional languages