2017-07-21 8 views
4

J'ai travaillé sur un interpréteur BF, en essayant de m'assurer qu'il n'utilise pas de bibliothèques externes, et fonctionne dans une seule fonction.Comment créer un interpréteur Brainfuck en Python?

Le problème que je rencontre est que certains programmes fonctionnent parfaitement, et d'autres pas. Cela rend difficile le débogage, la figuration et ce qui ne va pas.

Le facteur commun semble être qu'il ne peut pas gérer un programme BF avec plus d'un ensemble de parenthèses (bien qu'il y ait quelques exceptions, mais alors les programmes fonctionnent, mais pas complètement).

Le code:

def interpret(code): 
    array = [0] 
    pointerLocation = 0 
    i = 0 
    c = 0 
    print(code) 
    while i < len(code): 
     if code[i] == '<': 
      if pointerLocation > 0: 
       pointerLocation -= 1 
     elif code[i] == '>': 
      pointerLocation += 1 
      if len(array) <= pointerLocation: 
       array.append(0) 
     elif code[i] == '+': 
      array[pointerLocation] += 1 
     elif code[i] == '-': 
      if array[pointerLocation] > 0: 
       array[pointerLocation] -= 1 
     elif code[i] == '.': 
      print(array[pointerLocation], chr(array[pointerLocation])) 
     elif code[i] == ',': 
      x = input("Input:") 
      try: 
       y = int(x) 
      except ValueError: 
       y = ord(x) 
      array[pointerLocation] = y 
     elif code[i] == '[': 
      if array[pointerLocation] == 0: 
       while code[i] != ']': 
        i += 1 
     elif code[i] == ']': 
      if array[pointerLocation] != 0: 
       while code[i] != '[': 
        i -= 1 
     i += 1 
interpret(""" 
        #This is where the BF code goes 
""") 

Je sais que ce n'est pas le meilleur code Python, je pensais juste que je donnerais un aller.

Les programmes qui fonctionnent:

,----------[----------------------.,----------] 

- Converti en minuscules en majuscules

++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. 

- Bonjour tout le monde!

Le programme que je suis en train actuellement de rendre le travail est:

++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[-<<<[->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<<]>.>+[>>]>+] 

Il est conçu pour produire un triangle de Sierpinski avec * s.

Je ne reçois aucune sortie, mais si je produis le tableau, il semble créer un tableau presque infini de 0, 1, 0, 1 ..... etc séquencé.

De l'exécuter à travers un interprète approprié, je sais que le tableau ne devrait se terminer avec une longueur de 120, et je suis dans les milliers en quelques secondes.

Toute aide serait appréciée.

Merci.

+0

Tous les programmes ne fonctionnent pas pour toutes les implémentations brainfuck. Certains programmes reposent sur un comportement d'encapsulation que seules certaines implémentations fournissent. Brainfuck est une langue très mal spécifiée. – Carcigenicate

+0

En regardant à nouveau votre problème, vous devez avoir chamboulé la logique des accolades quelque part. Quel débogage as-tu fait? Aussi, pourquoi tout mettre en une seule fonction? Vous avez intentionnellement rendu le débogage plus difficile. Quand j'ai écrit un interpréteur brainfuck, il était réparti sur plusieurs fichiers avec au moins 20 fonctions.De cette façon, chaque pièce peut être testée indépendamment de tout autre code. – Carcigenicate

+0

Comprenez-vous ce que cette ligne 'code [i]! = [" <", "> "," + "," - ",". ",", "," [","] "]' Fait? –

Répondre

4

Il y a un bug dans votre code à la manipulation et []: Ils ne correspondent pas aux accolades correctes, au lieu qu'ils correspondent à l'accolade la plus proche qui pourrait ajustement si tout est ignoré entre y compris d'autres accolades !!! Cela signifie que vous ne pouvez pas imbriquer vos boucles. J'ai aussi écrit un interpréteur bf en python et j'ai utilisé une variable de compteur open_braces qui commence à 1 et est incrémentée par des accolades ouvertes dans la direction de recherche et décrémentée par des accolades fermées à la direction de recherche. Fixer votre code comme suit:

elif code[i] == '[': 
    if array[pointerLocation] == 0: 
     open_braces = 1 
     while open_braces > 0: 
      i += 1 
      if code[i] == '[': 
       open_braces += 1 
      elif code[i] == ']': 
       open_braces -= 1 
elif code[i] == ']': 
    # you don't need to check array[pointerLocation] because the matching '[' will skip behind this instruction if array[pointerLocation] is zero 
    open_braces = 1 
    while open_braces > 0: 
     i -= 1 
     if code[i] == '[': 
      open_braces -= 1 
     elif code[i] == ']': 
      open_braces += 1 
    # i still gets incremented in your main while loop 
    i -= 1 

S'il vous plaît Notez que vous pouvez garder le if array[pointerLocation] == 0 dans le elif code[i] == ']': -bloc si vous vous souciez de la performance. Si vous le faites, vous n'avez pas besoin de décrémenter i dans la dernière ligne.

+1

Merci! Cependant, les premières open_braces ne devraient-elles PAS être utilisées pour parcourir le code? A part ça, merci beaucoup, je vais mettre en place ce dès que possible. –

+1

oui, vous avez raison - la première boucle devrait augmenter «je». je le réparerai – Aemyl