Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys,random
- class BefungeInterpreter:
- def __init__(self):
- self.direction = '>';
- self.stack = []
- self.stringMode = False
- self.exitStateFound = False
- self.functionDictionary = {\
- '+' : self.add, '-' : self.subtract, '*' : self.multiply, '/' : self.divide,\
- '%' : self.modulus, '!' : self.logicalNot, '`' : self.greaterThan,\
- '>' : self.right, '<' : self.left, '^' : self.up, 'V' : self.down, 'v' : self.down, '?' : self.randomDirection,\
- '_' : self.rightOrLeft, '|' : self.upOrDown, '"' : self.enterStringMode,\
- ':' : self.duplicate, '\\' : self.swap, '$' : self.pop, '.' : self.intPrint, ',' : self.strPrint,\
- '#' : self.jump, 'p' : self.put, 'g' : self.get,\
- '&' : self.inputNumber, '~' : self.inputChar, '@' : self.end, ' ' : self.noop\
- }
- if '-f' in sys.argv or True:
- #self.loadFile(sys.argv[sys.argv.index('-f')+1])
- self.loadFile('befunge.txt')
- #we would theoretically allow more input options here
- #self.charinput = ['"dlrow olleh",,,,,,,,,,,@']
- #self.processCharInput()
- if self.program:
- self.run()
- def loadFile(self,filePath):
- file = open(filePath)
- self.charinput = file.readlines()
- self.processCharInput()
- def processCharInput(self):
- self.program = {}
- for y in range(0,len(self.charinput)):
- for x in range(0,len(self.charinput[y][:-1])):#-1 cuts off newline
- self.program[(x,y)] = self.charinput[y][x]
- def run(self):
- self.pointerPosition = (0,0)
- while not self.exitStateFound:
- #print(self.stack)
- #print("direction: " +self.direction)
- #print("pointer position: " + str(self.pointerPosition))
- currentCommand = self.getChar()
- #print("current command: " + currentCommand)
- self.processCommand(currentCommand)
- def getChar(self):
- x,y = self.pointerPosition
- return self.program.get((x,y),' ')#default nonentered value is space
- def processCommand(self,currentCommand):
- if self.stringMode:
- if currentCommand != '"':
- self.stack.append(ord(currentCommand))
- else:
- self.stringMode = False;
- elif currentCommand in ['0','1','2','3','4','5','6','7','8','9']:#TODO: figure out if int() returns 0 on failure
- self.stack.append(int(currentCommand))#pretty sure we should do int here
- elif currentCommand in self.functionDictionary:#NO PREMATURE OPTIMIZATION
- #print(self.functionDictionary[currentCommand])
- self.functionDictionary[currentCommand]()
- else:
- "" #comment
- #print("unexpected character encountered, " + str(currentCommand))
- self.advance()
- def advance(self):
- def up():
- self.pointerPosition = tuple(map(sum,zip((0,-1),self.pointerPosition)))
- def down():
- self.pointerPosition = tuple(map(sum,zip((0,1),self.pointerPosition)))
- def left():
- self.pointerPosition = tuple(map(sum,zip((-1,0),self.pointerPosition)))
- def right():
- self.pointerPosition = tuple(map(sum,zip((1,0),self.pointerPosition)))
- {'>' : right , 'V' : down , '<' : left, '^' : up }.get(self.direction)()
- #command functions
- def add(self):
- a,b = self.pop(),self.pop()
- self.stack.append(a+b)
- def subtract(self):
- a,b = self.pop(),self.pop()
- self.stack.append(b-a)
- def multiply(self):
- a,b = self.pop(),self.pop()
- self.stack.append(a*b)
- def divide(self):
- a,b = self.pop(),self.pop()
- self.stack.append(b//a)#will error on 0 currently
- def modulus(self):
- a,b = self.pop(),self.pop()
- self.stack.append(b%a)#will error on 0 currently
- def logicalNot(self):#not is reserved
- a = self.pop()
- if a==0:
- a = 1
- else:
- a = 0
- self.stack.append(a)
- def greaterThan(self):
- a,b = self.pop(),self.pop()
- if b>a:
- self.stack.append(1)
- else:
- self.stack.append(0)
- def left(self):
- self.direction = '<'
- def right(self):
- self.direction = '>'
- def up(self):
- self.direction = '^'
- def down(self):
- self.direction = 'V'
- def randomDirection(self):
- self.direction = random.choice(['>','V','<','^'])
- def rightOrLeft(self):
- a = self.pop()
- if a==0:
- self.direction = '>'
- else:
- self.direction = '<'
- def upOrDown(self):
- a = self.pop()
- if a==0:
- self.direction = 'V'
- else:
- self.direction = '^'
- def enterStringMode(self):
- self.stringMode = True;
- def duplicate(self):
- a = self.pop()
- self.stack.append(a)
- self.stack.append(a)
- def swap(self):
- temp = self.stack[-1]
- self.stack[-1] = self.stack[-2]
- self.stack[-2] = temp
- def pop(self):
- try:
- return self.stack.pop()
- except: return 0
- def intPrint(self):
- print(self.pop())
- def strPrint(self):
- print(chr(self.pop()),end="")
- def jump(self):
- self.advance()
- def put(self):
- y,x,v = self.pop(),self.pop(),self.pop()
- self.program[(x,y)] = chr(v)
- def get(self):
- y,x = self.pop(),self.pop()
- self.stack.append(ord(self.program[(x,y)]))
- def inputNumber(self):
- print("input a number")
- self.stack.append(int(input()))
- def inputChar(self):
- print("input a character")
- self.stack.append(ord(input()))
- def end(self):
- self.exitStateFound = True
- def noop(self):
- ""
- b = BefungeInterpreter()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement