Advertisement
Guest User

befunge python interpreter

a guest
Jun 17th, 2013
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.22 KB | None | 0 0
  1. import sys,random
  2. class BefungeInterpreter:
  3. def __init__(self):
  4. self.direction = '>';
  5. self.stack = []
  6. self.stringMode = False
  7. self.exitStateFound = False
  8. self.functionDictionary = {\
  9. '+' : self.add, '-' : self.subtract, '*' : self.multiply, '/' : self.divide,\
  10. '%' : self.modulus, '!' : self.logicalNot, '`' : self.greaterThan,\
  11. '>' : self.right, '<' : self.left, '^' : self.up, 'V' : self.down, 'v' : self.down, '?' : self.randomDirection,\
  12. '_' : self.rightOrLeft, '|' : self.upOrDown, '"' : self.enterStringMode,\
  13. ':' : self.duplicate, '\\' : self.swap, '$' : self.pop, '.' : self.intPrint, ',' : self.strPrint,\
  14. '#' : self.jump, 'p' : self.put, 'g' : self.get,\
  15. '&' : self.inputNumber, '~' : self.inputChar, '@' : self.end, ' ' : self.noop\
  16. }
  17. if '-f' in sys.argv or True:
  18. #self.loadFile(sys.argv[sys.argv.index('-f')+1])
  19. self.loadFile('befunge.txt')
  20. #we would theoretically allow more input options here
  21.  
  22. #self.charinput = ['"dlrow olleh",,,,,,,,,,,@']
  23. #self.processCharInput()
  24.  
  25. if self.program:
  26. self.run()
  27.  
  28. def loadFile(self,filePath):
  29. file = open(filePath)
  30. self.charinput = file.readlines()
  31. self.processCharInput()
  32.  
  33. def processCharInput(self):
  34. self.program = {}
  35. for y in range(0,len(self.charinput)):
  36. for x in range(0,len(self.charinput[y][:-1])):#-1 cuts off newline
  37. self.program[(x,y)] = self.charinput[y][x]
  38.  
  39. def run(self):
  40. self.pointerPosition = (0,0)
  41.  
  42. while not self.exitStateFound:
  43. #print(self.stack)
  44. #print("direction: " +self.direction)
  45. #print("pointer position: " + str(self.pointerPosition))
  46. currentCommand = self.getChar()
  47. #print("current command: " + currentCommand)
  48. self.processCommand(currentCommand)
  49.  
  50. def getChar(self):
  51. x,y = self.pointerPosition
  52. return self.program.get((x,y),' ')#default nonentered value is space
  53.  
  54. def processCommand(self,currentCommand):
  55. if self.stringMode:
  56. if currentCommand != '"':
  57. self.stack.append(ord(currentCommand))
  58. else:
  59. self.stringMode = False;
  60. elif currentCommand in ['0','1','2','3','4','5','6','7','8','9']:#TODO: figure out if int() returns 0 on failure
  61. self.stack.append(int(currentCommand))#pretty sure we should do int here
  62. elif currentCommand in self.functionDictionary:#NO PREMATURE OPTIMIZATION
  63. #print(self.functionDictionary[currentCommand])
  64. self.functionDictionary[currentCommand]()
  65. else:
  66. "" #comment
  67. #print("unexpected character encountered, " + str(currentCommand))
  68. self.advance()
  69.  
  70. def advance(self):
  71. def up():
  72. self.pointerPosition = tuple(map(sum,zip((0,-1),self.pointerPosition)))
  73. def down():
  74. self.pointerPosition = tuple(map(sum,zip((0,1),self.pointerPosition)))
  75. def left():
  76. self.pointerPosition = tuple(map(sum,zip((-1,0),self.pointerPosition)))
  77. def right():
  78. self.pointerPosition = tuple(map(sum,zip((1,0),self.pointerPosition)))
  79. {'>' : right , 'V' : down , '<' : left, '^' : up }.get(self.direction)()
  80.  
  81.  
  82.  
  83.  
  84.  
  85. #command functions
  86. def add(self):
  87. a,b = self.pop(),self.pop()
  88. self.stack.append(a+b)
  89. def subtract(self):
  90. a,b = self.pop(),self.pop()
  91. self.stack.append(b-a)
  92. def multiply(self):
  93. a,b = self.pop(),self.pop()
  94. self.stack.append(a*b)
  95. def divide(self):
  96. a,b = self.pop(),self.pop()
  97. self.stack.append(b//a)#will error on 0 currently
  98. def modulus(self):
  99. a,b = self.pop(),self.pop()
  100. self.stack.append(b%a)#will error on 0 currently
  101. def logicalNot(self):#not is reserved
  102. a = self.pop()
  103. if a==0:
  104. a = 1
  105. else:
  106. a = 0
  107. self.stack.append(a)
  108. def greaterThan(self):
  109. a,b = self.pop(),self.pop()
  110. if b>a:
  111. self.stack.append(1)
  112. else:
  113. self.stack.append(0)
  114. def left(self):
  115. self.direction = '<'
  116. def right(self):
  117. self.direction = '>'
  118. def up(self):
  119. self.direction = '^'
  120. def down(self):
  121. self.direction = 'V'
  122. def randomDirection(self):
  123. self.direction = random.choice(['>','V','<','^'])
  124. def rightOrLeft(self):
  125. a = self.pop()
  126. if a==0:
  127. self.direction = '>'
  128. else:
  129. self.direction = '<'
  130. def upOrDown(self):
  131. a = self.pop()
  132. if a==0:
  133. self.direction = 'V'
  134. else:
  135. self.direction = '^'
  136. def enterStringMode(self):
  137. self.stringMode = True;
  138. def duplicate(self):
  139. a = self.pop()
  140. self.stack.append(a)
  141. self.stack.append(a)
  142. def swap(self):
  143. temp = self.stack[-1]
  144. self.stack[-1] = self.stack[-2]
  145. self.stack[-2] = temp
  146. def pop(self):
  147. try:
  148. return self.stack.pop()
  149. except: return 0
  150. def intPrint(self):
  151. print(self.pop())
  152. def strPrint(self):
  153. print(chr(self.pop()),end="")
  154. def jump(self):
  155. self.advance()
  156. def put(self):
  157. y,x,v = self.pop(),self.pop(),self.pop()
  158. self.program[(x,y)] = chr(v)
  159. def get(self):
  160. y,x = self.pop(),self.pop()
  161. self.stack.append(ord(self.program[(x,y)]))
  162. def inputNumber(self):
  163. print("input a number")
  164. self.stack.append(int(input()))
  165. def inputChar(self):
  166. print("input a character")
  167. self.stack.append(ord(input()))
  168. def end(self):
  169. self.exitStateFound = True
  170. def noop(self):
  171. ""
  172.  
  173.  
  174.  
  175. b = BefungeInterpreter()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement