Advertisement
enoua5

ffb

Jun 19th, 2017
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.73 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. import sys, getopt
  3. class State:
  4.     def __init__(self, cmd, bar, jmp):
  5.         self.cmd=cmd
  6.         self.bar=bar
  7.         self.jmp=jmp
  8. #close everything up
  9. def close(code=2):
  10.     global p
  11.     global IMET
  12.     global OMET
  13.     global out
  14.     global inFile
  15.     try:
  16.         p.close()
  17.     except NameError:
  18.         pass
  19.     try:
  20.         out.close()
  21.     except NameError:
  22.         pass
  23.     try:
  24.         inFile.close()
  25.     except NameError:
  26.         pass
  27.     sys.exit(code)
  28. #show help
  29. def showHelp():
  30.     print("""Usage: """+sys.argv[0]+""" [OPTION]... [FILE]
  31. Runs a .ffb file
  32. --inputfile=file      specifies a file to get input from, rather than from a user
  33. --outputfile=file     specifies a file to output to, rather than from the console
  34. -h, --help          shows this help page
  35. """)
  36. #run a command
  37. def runCmd(cmd):
  38.     global tape
  39.     global ip
  40.     global IMET
  41.     global OMET
  42.     global inBuffer
  43.     global inFile
  44.     global out
  45.     if cmd=="LFT":
  46.         ip+=1
  47.         if ip==len(tape):
  48.             tape+=[0]
  49.     elif cmd=="RGT":
  50.         if ip==0:
  51.             tape=[0]+tape
  52.         else:
  53.             ip-=1
  54.     elif cmd=="INC":
  55.         tape[ip]+=1
  56.         if tape[ip]>255:
  57.             tape[ip]=0
  58.         if tape[ip]<0:
  59.             tape[ip]=255
  60.     elif cmd=="DEC":
  61.         tape[ip]-=1
  62.         if tape[ip]>255:
  63.             tape[ip]=0
  64.         if tape[ip]<0:
  65.             tape[ip]=255
  66.     elif cmd=="INP":
  67.         while True:
  68.             if len(inBuffer)>0:
  69.                 try:
  70.                     tape[ip]=ord(inBuffer[0])
  71.                 except TypeError:
  72.                     tape[ip]=inBuffer[0]
  73.                 inBuffer=inBuffer[1:]
  74.                 return
  75.             #we need to refill the buffer
  76.             if IMET=="USER":
  77.                 inBuffer=input()
  78.                 if len(inBuffer)==0:
  79.                     #no input
  80.                     inBuffer=[-1]
  81.             else:
  82.                 inBuffer=inFile.read(1)
  83.                 if len(inBuffer)==0:
  84.                     #no input
  85.                     inBuffer=[-1]
  86.     elif cmd=="OUT":
  87.         if OMET=="USER":
  88.             print(chr(max(tape[ip],0)),end="")
  89.         else:
  90.             out.write(bytes([max(tape[ip],0)]))
  91.     elif cmd=="HLT":
  92.         close(0)
  93. #IO methods
  94. IMET="USER"
  95. OMET="USER"
  96. #where we save input that is waiting to be used
  97. inBuffer=""
  98. #get arguments
  99. args=sys.argv[1:]
  100. try:
  101.     opts,args=getopt.getopt(args,"h",["help","inputfile=","outputfile="])
  102. except getopt.GetoptError:
  103.     showHelp()
  104.     close(2)
  105. #read options
  106. for opt, arg in opts:
  107.     if opt in ('-h','--help'):
  108.         showHelp()
  109.         close(0)
  110.     elif opt=="--inputfile":
  111.         IMET="FILE"
  112.         try:
  113.             inFile=open(arg,'rb')
  114.             inBuffer=inFile.read()
  115.         except IOError:
  116.             print("ERROR: Could not open input file.")
  117.             close()
  118.     elif opt=="--outputfile":
  119.         OMET="FILE"
  120.         try:
  121.             out=open(arg,'wb')
  122.         except IOError:
  123.             print("ERROR: Could not open output file.")
  124.             close()
  125. #make sure we were given a file
  126. if len(args)==0:
  127.     print("ERROR: no files given!")
  128.     close()
  129. #and not too many
  130. if len(args)>1:
  131.     print("ERROR: too many files given!")
  132.     close()
  133. #open the program
  134. try:
  135.     p=open(args[0],'rb')
  136. except IOError:
  137.     print("ERROR: could not open file \""+args[0]+"\"!")
  138.     close()
  139. #parse the program
  140. try:
  141.     #get the byte width
  142.     BYTEWIDTH=ord(p.read(1))
  143. except ValueError:
  144.     print("ERROR: program is empty!")
  145.     close()
  146. #state map
  147. states=[]
  148. #read first state
  149. s=p.read(2*BYTEWIDTH+2)
  150. while len(s)==2*BYTEWIDTH+2:
  151.     #get info from the state
  152.     try:
  153.         cmd=("LFT","RGT","INC","DEC","INP","OUT","NOP","HLT")[s[0]]
  154.     except IndexError:
  155.         print("ERROR: unrecognized command byte \""+s[0]+"\"")
  156.         close()
  157.     bar=s[1]
  158.     jmps=s[2:]
  159.     jmp=[jmps[:len(jmps)//2],jmps[len(jmps)//2:]]
  160.     jmp[0]=int.from_bytes(jmp[0], byteorder='big', signed=False)
  161.     jmp[1]=int.from_bytes(jmp[1], byteorder='big', signed=False)
  162.     #add it to the list
  163.     states.append(State(cmd, bar, jmp))
  164.     #read states by chucks
  165.     s=p.read(2*BYTEWIDTH+2)
  166. #run the program!!
  167. tape=[0]
  168. ip=0
  169. state=0
  170. while True:
  171.     try:
  172.         runCmd(states[state].cmd)
  173.     except IndexError:
  174.         print("ERROR: There is no state \""+str(state)+"\"")
  175.         close(2)
  176.     if states[state].bar<=tape[ip]:
  177.         state=states[state].jmp[1]
  178.     else:
  179.         state=states[state].jmp[0]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement