Madbrain

From Esolang
Jump to: navigation, search

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 first argument
d (1 Argument): Decreases the horizontal instruction pointer by the first argument
x: Terminates the program
r: Reads a single digit from stdin and pushes it as an integer on to the stack
* (2 Arguments): Performs multiplication
/ (2 Arguments): Performs division
+ (2 Arguments): Performs addition
- (2 Arguments): Perform subtraction
p (1 Argument): Print as number
c (1 Argument): Print as 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 first argument is greater than zero, the horizontal instruction pointer is increased by one.
! (1 Argument): If the first argument is greater than zero, the horizontal instruction pointer is decreased by one.
: (1 Argument): If the first argument is zero, the horizontal instruction pointer is increased by one.
; (1 Argument): If the first argument is zero, the horizontal instruction pointer is decreased by one.
. (1 Argument): If the first argument is less than zero, the horizontal instruction pointer is increased by one.
, (1 Argument): If the first 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.
@ (@ Arguments): If the first argument is not equal to the second, the horizontal instruction pointer is decreased by one.
Any character which is not a opcode is a nop.

Negative integers as instruction pointers are undefined or implementation dependent behavior

Example

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.

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)

#!/usr/bin/python
import sys
f=open(sys.argv[1],"rb");u=f.read();s=[];c=u.split("\n");i=0;ptr=0;
while(ptr<len(c)):
 l=c[ptr]
 if(i>=len(l)): break;
 if(l[i]=="9"):s.append(9)
 elif(l[i]=="8"):s.append(8)
 elif(l[i]=="7"):s.append(7)
 elif(l[i]=="6"):s.append(6)
 elif(l[i]=="5"):s.append(5)
 elif(l[i]=="4"):s.append(4)
 elif(l[i]=="3"):s.append(3)
 elif(l[i]=="2"):s.append(2)
 elif(l[i]=="1"):s.append(1)
 elif(l[i]=="0"):s.append(0)
 elif(l[i]=="j"):a=s[-1]; ptr = a; del s[-1]; continue
 elif(l[i]=="g"):a=s[-1]; b=s[0]; del s[-1],s[0]; i+=b; ptr =a; continue
 elif(l[i]=="q"):a=s[-1]; b=s[0]; del s[-1],s[0]; i-=b; ptr =a; continue
 elif(l[i]=="i"):i+=s[-1]; del s[-1];
 elif(l[i]=="d"):i-=s[-1]; del s[-1];
 elif(l[i]=="x"):break
 elif(l[i]=="r"):s.append(int(sys.stdin.read(1))) 
 elif(l[i]=="*"):
  if(len(s)<2): break;
  a=s[-1];b=s[0];del s[-1],s[0];s.append(a*b)
 elif(l[i]=="+"):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];s.append(a+b)
 elif(l[i]=="p"):
  if(len(s)<1):break;
  sys.stdout.write(str(s[-1])); del s[-1]
 elif(l[i]=="c"):
  if(len(s)<1):break;
  if(s[-1]<256):sys.stdout.write(str(chr(s[-1]))); del s[-1]
 elif(l[i]=="/"):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];s.append(a/b)
 elif(l[i]=="-"):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];s.append(a-b)
 elif(l[i]==">"):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];
  if(a>b):i+=1
 elif(l[i]=="<"):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];
  if(a<b):i+=1
 elif(l[i]=="^"):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];
  if(a>b):i-=1
 elif(l[i]=="v"):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];
  if(a<b):i-=1
 elif(l[i]=="?"):
  if(len(s)<1):break;
  a=s[-1];del s[-1];
  if(a>0):i+=1
 elif(l[i]=="!"):
  if(len(s)<1):break;
  a=s[-1];del s[-1];
  if(a>0):i-=1
 elif(l[i]==":"):
  if(len(s)<1):break;
  a=s[-1];del s[-1];
  if(a==0):i+=1
 elif(l[i]==";"):
  if(len(s)<1):break;
  a=s[-1];del s[-1];
  if(a==0):i-=1
 elif(l[i]=="."):
  if(len(s)<1):break;
  a=s[-1];del s[-1];
  if(a<0):i+=1
 elif(l[i]==","):
  if(len(s)<1):break;
  a=s[-1];del s[-1];
  if(a<0):i-=1
 elif(l[i]=="="):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];
  if(a==b):i+=1
 elif(l[i]=="_"):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];
  if(a==b):i-=1
 elif(l[i]=="#"):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];
  if(a!=b):i+=1
 elif(l[i]=="@"):
  if(len(s)<2):break;
  a=s[-1];b=s[0];del s[-1],s[0];
  if(a==b):i-=1

 ptr+=1