#!/usr/bin/env python3 import sys rip_mode=False if len(sys.argv)!=2: print("Usage: ./rippy.py ",file=sys.stderr) sys.exit(1) def error(msg): if rip_mode: msg="rip" print(msg,file=sys.stderr) sys.exit(1) def make_jumpmap(source): jm={} stk=[] for i in range(len(source)): if source[i]=="[": stk.append(i) elif source[i]=="]": if len(stk)==0: error("Too many ']' in source") jm[stk[-1]]=i jm[i]=stk[-1] stk.pop() if len(stk)!=0: error("Too many '[' in source") return jm def stack_check(stk,opname,nelems): if len(stk)==0: error(opname+" needs "+nelems+" element"+("s" if nelems!=1 else "")+" on the stack") def stack_pop(stk,opname,nelems): stack_check(stk,opname,nelems) e=stk[-1] stk.pop() return e def rip(source,jm): ip=0 stk=[] cstk=[] lastif=None while ip1: stack_check(stk,"Roll("+str(a)+")",a) stk[-a],stk[-a+1:-1]=stk[-1],stk[-a:-2] elif source[ip]=="R": a=stack_pop(stk,"Reverse roll",1) if a<0: error("Negative reverse roll amount") if a>1: stack_check(stk,"Reverse roll("+str(a)+")",a) stk[-a:-2],stk[-1]=stk[-a+1:-1],stk[-a] elif source[ip]=="l": stk.append(len(stk)) elif source[ip] in "asmqMpGLE": names={ "a": "Add", "s": "Subtract", "m": "Multiply", "q": "Quotient", "M": "Modulo", "p": "Power", "G": "Greater", "L": "Less", "E": "Equal" } funcs={ "a": lambda a,b: a+b, "s": lambda a,b: a-b, "m": lambda a,b: a*b, "q": lambda a,b: a//b, "M": lambda a,b: a%b, "p": lambda a,b: a**b, "G": lambda a,b: a>b, "L": lambda a,b: a255: error("Invalid output byte") print(chr((n%256+256)%256),end="") elif source[ip]=="O": n=stack_pop(stk,"Output number",1) print(n,end="") elif source[ip]=="g": c=sys.stdin.read(1) if len(c)==0: stk.append(-1) else: stk.append(ord(c)) elif source[ip]=="'": if ip+1>=len(source): error("Single-quote at end of file") stk.append(ord(source[ip+1])) ip+=1 else: error("Unrecognised command '"+source[ip]+"'") ip+=1 def main(): sourcefname=sys.argv[1] with open(sourcefname,"r") as f: source=f.read() jm=make_jumpmap(source) rip(source,jm) if __name__=="__main__": main()