"""PyPy tutorial by Andrew Brownexample4.py - BF interpreter in RPython, translatable by PyPy, with JIT, and with a get_printable_location function"""importosimportsys# So that you can still run this module under standard CPython, I add this# import guard that creates a dummy class instead.try:frompypy.rlib.jitimportJitDriverexceptImportError:classJitDriver(object):def__init__(self,**kw):passdefjit_merge_point(self,**kw):passdefcan_enter_jit(self,**kw):passdefget_location(pc,program,bracket_map):return"%s_%s_%s"%(program[:pc],program[pc],program[pc+1:])jitdriver=JitDriver(greens=['pc','program','bracket_map'],reds=['tape'],get_printable_location=get_location)defmainloop(program,bracket_map):pc=0tape=Tape()whilepc<len(program):jitdriver.jit_merge_point(pc=pc,tape=tape,program=program,bracket_map=bracket_map)code=program[pc]ifcode==">":tape.advance()elifcode=="<":tape.devance()elifcode=="+":tape.inc()elifcode=="-":tape.dec()elifcode==".":# printos.write(1,chr(tape.get()))elifcode==",":# read from stdintape.set(ord(os.read(0,1)[0]))elifcode=="["andtape.get()==0:# Skip forward to the matching ]pc=bracket_map[pc]elifcode=="]"andtape.get()!=0:# Skip back to the matching [pc=bracket_map[pc]pc+=1classTape(object):def__init__(self):self.thetape=[0]self.position=0defget(self):returnself.thetape[self.position]defset(self,val):self.thetape[self.position]=valdefinc(self):self.thetape[self.position]+=1defdec(self):self.thetape[self.position]-=1defadvance(self):self.position+=1iflen(self.thetape)<=self.position:self.thetape.append(0)defdevance(self):self.position-=1defparse(program):parsed=[]bracket_map={}leftstack=[]pc=0forcharinprogram:ifcharin('[',']','<','>','+','-',',','.'):parsed.append(char)ifchar=='[':leftstack.append(pc)elifchar==']':left=leftstack.pop()right=pcbracket_map[left]=rightbracket_map[right]=leftpc+=1return"".join(parsed),bracket_mapdefrun(fp):program_contents=""whileTrue:read=os.read(fp,4096)iflen(read)==0:breakprogram_contents+=reados.close(fp)program,bm=parse(program_contents)mainloop(program,bm)defentry_point(argv):try:filename=argv[1]exceptIndexError:print"You must supply a filename"return1run(os.open(filename,os.O_RDONLY,0777))return0deftarget(*args):returnentry_point,Nonedefjitpolicy(driver):frompypy.jit.codewriter.policyimportJitPolicyreturnJitPolicy()if__name__=="__main__":entry_point(sys.argv)