#1 Le 22/08/2012, à 19:16
- PJSimply
[python] ajout d'instructions au brainfuck
Bonjour / Bonsoir tout le monde
Engros je vous explique comment j'en suis arrivé ici : j'ai découvert le brainfuckil y a peu de temps et je voulais essayer donc j'ai trouvé un interpréteur en python sur Internet pour faire mes tests. Seulement pour ceux qui connaissent, c'est assez fastidieux, je me suis donc dit que ça serait cool d'ajouter des intsructions pour aider un petit coup
J'ai donc modifier et fait des ajouts au script pour rajouter les commandes suivantes :
{ code à ajouter } qui permet de stocker du code dans la "case" pointée
! qui exécute le code contenu dans la "case" pointée
: qui sort toutes les cases précédant celle pointée
$nom quelconque$ qui permet de nommer un case du tableau
_nom quelconque_ qui permet de pointer automatiquement sur la case nommée
Voici le code de l'interpréteur :
#!/usr/bin/python
import re
import sys
from collections import deque
class TabCase(object):
def right(self,car):
self.index += 1
if self.index == len(self.cells):
self.cells.append(car)
def left(self,car):
self.index -= 1
if self.index < 0:
self.index = 0
self.cells.appendleft(car)
def getCell(self):
return self.cells[self.index]
def __repr__(self):
return " ".join([str(x) for x in self.cells])
class Value(TabCase):
def __init__(self):
self.cells = deque([0])
self.index=0
def inc(self):
self.cells[self.index] +=1
self.cells[self.index] %=256
def dec(self):
self.cells[self.index] -=1
self.cells[self.index] %=256
def set(self, val):
self.cells[self.index] = val
def aff(self):
i=0
while i <= self.index:
sys.stdout.write(chr(self.cells[i]))
i+=1
class Func(TabCase):
def __init__(self):
self.cells = deque([''])
self.index=0
def add(self, cmd):
self.cells[self.index] += cmd
class MainTab(object):
def __init__(self):
self.value= Value()
self.func= Func()
self.index=0
def right(self):
self.value.right(0)
self.func.right('')
self.index+=1
def left(self):
self.value.left(0)
self.func.left('')
self.index -= 1
if self.index < 0:
self.index = 0
def goto(self,newIndex):
self.index=newIndex
self.value.index=newIndex
self.func.index=newIndex
def getIndex(self):
return self.index
class MatchTab(object):
def __init__(self):
self.table=dict()
def addName(self,name,value):
self.table[name]=value
def shift(self):
for value in self.table.values():
value+=1
class BFInterpreter(object):
def __init__(self):
self.mainTab = MainTab()
self.matchTab = MatchTab()
self.commands = []
def runCommands(self, cmds):
self.commands = cmds
self.command_index = 0
try:
while True:
self.executeNext()
except IndexError:
pass
def executeNext(self):
cmd = self.commands[self.command_index]
# print cmd
if cmd == '[':
if not self.mainTab.value.getCell():
self.gotoMatchinCroch(1)
return
elif cmd == ']':
if self.mainTab.value.getCell():
self.gotoMatchinCroch(-1)
return
elif cmd == '{':
self.assignFunc(self.getBetween(']'))
elif cmd =='}':
print 'unmatched end function definition sign'
else:
self.interpret(cmd)
self.command_index += 1
def gotoMatchinCroch(self, direction):
onstack = 1
while onstack:
self.command_index += direction
if self.commands[self.command_index] == ']':
onstack -= direction
elif self.commands[self.command_index] == '[':
onstack += direction
self.command_index += 1
def assignFunc(self,function):
self.mainTab.func.add(function)
def exe(self):
subs=self.func.getCell()
indice=self.commands.index('!')
self.commands=self.commands[:indice]+subs+self.commands[(indice+1):]
def getBetween(self,endChar):
self.command_index+=1
between=''
while self.commands[self.command_index] != endChar:
between+=self.commands[self.command_index]
self.command_index += 1
return between
def interpret(self, item):
if item == '+':
self.mainTab.value.inc()
elif item == '-':
self.mainTab.value.dec()
elif item == '>':
self.mainTab.right()
elif item == '<':
if self.mainTab.index==0:
self.matchTab
self.mainTab.left()
elif item == ':':
self.mainTab.value.aff()
elif item == '$':
self.matchTab.addName(self.getBetween('$'), self.mainTab.getIndex() )
elif item == '_':
self.mainTab.goto(self.matchTab.table[self.getBetween('_')])
elif item == '.':
sys.stdout.write(chr(self.mainTab.value.getCell()))
elif item == '!':
self.command_index-=1
self.exe()
elif item == ',':
try:
val = ord(raw_input())
self.value.set(val)
except:
# Ignore invalid input
pass
def printUsage():
print "\nUsage: python FLInterp.py [-b|-o] <INPUT_FILE>\n"
if __name__ == '__main__':
if len(sys.argv) < 3 or sys.argv[1] not in ("-o", "-b"):
printUsage()
sys.exit()
fname = sys.argv[2]
listing = file(fname, 'r').read()
interpreter = BFInterpreter()
interpreter.runCommands(listing)
Voila
J'aurais aimé connaître des moyens d'améliorer un peu le code car je suis débutant en python donc j'ai sans doute des défauts et je suis loin de maîtriser toutes les fonctions qui existent
Et aussi j'aurai aimé savoir si vous aviez des idées de choses à ajouter, de fonctions etc
Merci beaucoup de votre lecture et de votre éventuelle aide
Bonne soirée/journée/année/rentrée
PS : le code original est de Johannes Chara mais je n'ai pas l'url, je l'édit dès que je la retrouve !
Hors ligne