Vague/Quintopia
Jump to navigation
Jump to search
An implementation of Vague by User:Quintopia. This may be considered a reference implementation because no other implementations are correct.
import sys,math from collections import defaultdict # The only standards-compliant implementation of Vague class Vague: def __init__(self,program): self.program = program self.pc=0 self.jump=1 self.data="" self.copymode = False self.stackmode = False self.stack = [] self.commands = defaultdict(self.nop,{'+': self.add, '-': self.dec, '!': self.output, '>': self.right, '<': self.left, '&': self.nand, '=': self.push, '_': self.pop, '.': self.end, '0': self.zero, '*': self.discouraged, '2': self.to2D, '1': self.to1D, 't': self.copyon, 'f': self.copyoff, '(': self.start, ')': self.endp }) def nop(self): return self.nop def step(self): if self.copymode: self.program += self.program[self.pc] self.commands[self.program[self.pc]]() self.pc+=self.jump def run(self): while 0<=self.pc<len(self.program): self.step() def output(self): if isinstance(self.data,str): sys.stdout.write(self.data) else: print() for x in self.data: print(x) def to2D(self): if isinstance(self.data,str): n = max(1,int(math.sqrt(len(self.data)))) self.data=[self.data[i:i+n] for i in range(0, len(self.data), n)] def to1D(self): if isinstance(self.data,list): self.data = "".join(self.data) def add(self): if self.stackmode: if len(self.stack)>=8: num=0 for i in "*"*8: bit = int(self.stack.pop()) num = 2*num+bit if isinstance(self.data,str): self.data += chr(num) else: self.to1D() self.data += chr(num) self.to2D() else: newdata = input() if isinstance(self.data,str): self.data += newdata else: self.to1D() self.data += newdata self.to2D() def right(self): self.jump+=1 def left(self): self.jump-=1 def discouraged(self): for i,b in enumerate(self.stack): if b and i<len(self.data): self.program+=self.data[~i] def copyon(self): if self.stackmode: self.stack.append(True) else: self.copymode = True def copyoff(self): if self.stackmode: self.stack.append(False) else: self.copymode = False def dec(self): if self.stackmode: self.stack.pop(0) else: self.data = self.data[:-1] def zero(self): if self.stackmode: self.stack=[] else: self.data="" def push(self): if self.stackmode: last = self.data[-1][-1] num = ord(last) for i in "*"*8: self.stack.append(bool(num%2)) num//=2 else: if isinstance(self.data,str): if 0<=self.pc+self.jump<len(self.program): self.data += self.program[self.pc+self.jump] self.pc+=self.jump else: if 0<=self.pc+self.jump<len(self.program): self.data += self.program[self.pc+self.jump:self.pc+selfjump*len(self.data[0])+1:self.jump] self.pc+=len(self.data[-1]*self.jump) def pop(self): if self.stackmode: self.stack.pop() else: self.data = self.data[1:] def start(self): self.stackmode = True def endp(self): self.stackmode = False def nand(self): if self.stackmode: if len(self.stack)>=2: b = self.stack.pop() self.stack.append(not (self.stack.pop() and b)) else: self.pc = len(self.program)+~(self.pc&ord(self.data[-1][-1])) def end(self): if self.stackmode: if len(self.stack)>=2: self.stack[-2:]=self.stack[:-3:-1] else: self.pc=len(self.program)-1-self.jump if __name__=="__main__": if len(sys.argv)<2: print("No filename to execute.") else: try: with open(sys.argv[1], "r") as f: listing = f.read() p = Vague(listing) p.run() except IOError: print("File '"+filename+"' not found."); sys.exit(1)