UP:
J'ai quelque peu modifié mon code, mais cette fois-ci mon code fait planter IDLE.
Une idée de ce que j'ai pu oublier ?
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
class Machine:
"""
Simple Turing-machine.
To get the current cell's value, use machine.case
You can access directly another cell using machine[cell]
"""
def __init__(self):
self.dict = {}
self.pointeur = 0
def __getitem__(self, index):
return self.dict.get(index,0)
def __setitem__(self, index, value):
self.dict[index] = value
def next(self):
""" Point to next cell"""
self.pointeur += 1
def prev(self):
""" Point to previous cell"""
self.pointeur -= 1
def incr(self):
""" Add one to the cell under the pointer."""
self[self.pointeur] += 1
def desincr(self):
""" Decrease by one the cell under the pointer."""
self[self.pointeur] -= 1
def get_case(self):
return self[self.pointeur]
def set_case(self, value):
self[self.pointeur] = value
case = property(get_case,set_case,doc="the cell under the pointer")
def sublevel(toplevel, i=0):
while toplevel[0:i+1].count("[")!=toplevel[0:i+1].count("]"):
i+=1
return toplevel[1:i]
def del_last(list):
return list[:-1]
def parseur(string, bf, i=-1):
stack = []
while i < len(string)-1:
i = i + 1
if string[i] == "<":
bf.prev()
elif string[i] == ">":
bf.next()
elif string[i] == "+":
bf.incr()
elif string[i] == "-":
bf.desincr()
elif string[i] == ",":
char = raw_input()[0]
bf.case = ord(char)
elif string[i] == ".":
print chr(bf.case)
elif string[i] == "[":
stack.append((i,i+len(sublevel(string[i:]))))
if bf.case: # si la case ne vaut pas 0
pass # on execute
else:
i = stack.pop()[1] # on va à la fin de la boucle, on remonte
# d'un niveau dans l'arborescence du programme
elif string[i] == "]":
try:
i = stack[-1][0]
except IndexError:
print """Error:
no corresponding '[' found for the """+i+"""char."""
return None
if __name__ == '__main__':
foo = Machine()
while True:
test = raw_input("Brainfuck> ")
if not test:
break
else:
parseur(test, foo)
Ta gestion des boucles était incorrecte. Essaie plutôt
elif string[i] == "[":
stack.append((i,i+len(sublevel(string[i:]))))
i = stack[-1][1] # on va à la fin de la boucle, on remonte
# d'un niveau dans l'arborescence du programme
elif string[i] == "]":
try:
if bf.case: # si la case ne vaut pas 0
i = stack[-1][0]
else:
stack.pop()
except IndexError:
print """Error:
no corresponding '[' found for the """+str(i)+"""char."""
return None
Ok, j'ai mis du temps, mais j'ai compris (enfin, je crois).
En fait, tu vas à la fin de la boucle, et selon si il faut exécuter cette dernière, tu remontes au début de la boucle ? C'est ca ?
Mais ca serait pas un poil plus rapide si on décidait d'exécuter ou non la boucle avant de sauter à la fin de la dite boucle ?
A vrai dire il faut décider à deux reprises, avant de rentrer dans la boucle et arrivé à la fin de celle-ci. C'était justement le problème de ta version qui bouclait inconditionnellement à la fin de la boucle.
Aller directement à la fin de la boucle permet de n'avoir qu'un test dans le code (à la fin de la boucle) au lieu de deux.
import sys
import getopt
def main(argv):
bf = ''
try :
opts, args = getopt.getopt(argv, "h<:fl", ["help", "file", "line"])
except getopt.GetoptError:
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
elif opt == '-d' :
global _debug
_debug = True
elif opt in ("-f", "--file"):
f = open(args[0], 'r')
args = ["".join(f.readlines())]
bf = args[0]
buff = [0 for x in xrange(30000)]
stack = []
par = 0
pos = 0
cro = 0
cond = 0
char = bf[0]
while char :
par += 1
if char == '+' :
buff[pos] += 1
elif char == '-' :
buff[pos] -= 1
elif char == '<' :
pos -= 1
elif char == '>' :
pos += 1
elif char == '.' :
sys.stdout.write('%c' % buff[pos])
elif char == ',' :
buff[pos] = ord(sys.stdin.read(1))
elif char == '[' :
stack.append(par)
if buff[pos] == 0 :
while bf[par] != ']' :
par += 1
par += 1
elif char == ']' :
if buff[pos] != 0 :
par = stack.pop()
stack.append(par)
else :
stack.pop()
try :
char = bf[par]
except :
char = None
def usage():
print("-f --file \t give a path of a file to interpreter")
print("-l --line \t give a line to interpreter")
print("-h --help \t show this help")
if __name__ == "__main__":
main(sys.argv[1:])
Si tu veux comparer comme ça
C'est peut-être très mauvais hein, je sais plus quand j'ai fait ça…
Interpreteur Brainfuck: problème
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.