Vague/AnimaLibera

From Esolang
Jump to navigation Jump to search

An implementation of Vague by User:AnimaLibera. This may be considered a reference implementation because no other implementations are correct.

   """
   The only standards-compliant implementation of Vague
   
   Final version 1
   """
   
   from sys import argv, exit
   from random import randint
   
   if len(argv) <= 1:
       print("usage: python3 vague.py sourcefilename optionalbinarynumber")
       exit(-8)
   
   s = [] if len(argv) < 3 else [c == "1" for c in argv[2]]
   c = open(argv[1]).read().replace("\t", "    ").split("\n")
   x, y = 0, 0
   v = [1, 0]
   d = 1 # number of D
   p = 0 # number of (
   
   while True:
       try:
           k = c[y][x]
       except:
           break
   
       try:
           if k.isspace():
               pass
           elif k == "+": # Add
               s.append(bool(int(s.pop()) + int(s.pop())))
           elif k == "-": # Decrement
               if s[-1] == 0:
                   raise Exception("there are no numbers below 0")
               s[-1] -= 1
           elif k == "!": # Print
               print(int(s[-1]))
           elif k == ">": # Right
               if d == 1 or (d == 2 and p > 0):
                   v[0] = 1
               else:	
                   v = [-v[1], +v[0]]
           elif k == "<": # Left
               if d == 1 or (d == 2 and p > 0):
                   v[0] = -1
               else:	
                   v = [+v[1], -v[0]]
           elif k == "&": # NAND
               s.append(not (s.pop() and s.pop()))
           elif k == "=": # Push
               if s:
                   s.append(s[-1])
           elif k == "_": # Pop
               s.pop()
           elif k == ".": # End
               break
           elif k == "0": # Zero
               s = list((False,))
           elif k == "*": # Discouraged
               if randint(0 + d + p + y, 8 + x + v[0]) == 0:
                   raise Exception("deliberate use of discouraged instruction")
               else:
                   s.append(bool(int(s.pop()) * int(s.pop())))
           elif k == "1": # 1D
               d = 1
               if v[0] == 0:
                   v = list((1, 0))
           elif k == "2": # 2D
               if p == 0:
                   d = 2
                   if abs(v[0]) + abs(v[1]) != 1:
                       v = list((1, 0))
           elif k == "t": # True
               s.append(True)
           elif k == "f": # False
               s.append(False)
           elif k == "(": # Start
               p += 1
           elif k == ")": # End (
               p -= 1
               if p < 0:
                   raise Exception("no `(` to end when `)` used")
           elif k == "u":
               pass
           else:
               pass
       except:
           p -= 1
           if p < 0:
               raise Exception("no `(` to end when error")
   
       if d == 1 or (d == 2 and p > 0):
           x += v[0] if v[0] != 0 else 1
           if x >= len(c[y]):
               x, y = 0, y+1
           elif x < 0:
               y -= 1
               x = len(c[y])-1
       else:
           x, y = x+v[0], y+v[1]
    
   if s:
       print("".join([str(int(v)) for v in s]))