Je veux construire une interprète d'un esprit d'hérité (putain de nom) dans mon langage de programmation fraîchement créé pour prouver qu'elle est complétude-complétude. P>
Maintenant, tout est clair jusqu'à présent ( Comment le pseudocode pourrait-il ressembler? Que dois-je faire lorsque l'interprète atteint une boucle de départ ( Vérification si la boucle devrait continuer ou arrêter n'est pas le problème ( Alors que les boucles peuvent être nichées, je suppose que je ne peux pas utiliser une variable contenant la position de départ de la boucle actuelle. P>
J'ai vu de très petits interprètes BF mis en œuvre dans diverses langues, je me demande comment ils ont réussi à faire fonctionner les boucles mais ne peut pas le comprendre. P> <> + - ,. code>) - sauf une chose: les boucles (
[] code>).
Je suppose que vous connaissez la syntaxe BF (extrêmement dure) d'ici: p>
[ code>) ou une extrémité de boucle (
] code>)? P>
Cellule actuelle == 0 code>), mais: p>
5 Réponses :
Lorsque vous atteignez Si c'est faux, vous pouvez numériser pour le prochain em> correspondre em> Si c'est vrai, vous devez suivre sa position afin que vous puissiez revenir dessus plus tard. Je suggère d'utiliser une pile. Appuyez sur la position actuelle du programme sur la pile, puis lorsque vous atteignez Lorsque vous nidez dans les boucles intérieures, la pile enregistrera bien le contexte de chaque boucle. P>
voir pile (wikipedia) . Ceci est analogue à la manière dont les programmes d'assemblage traitent des appels de fonction. P> [ code>, vous testez le pointeur de données. p>
] code>, comptant le nombre
[ code> que vous voyez et en vous assurant de marquer les éteints comme vous voyez chaque
] code>. p>
] code>, testez le pointeur de données. Si c'est vrai, allez à la position du programme le plus haut sur la pile. Si c'est faux, évitez la position de la pile et continuez. P>
J'avais déjà construit dans une pile dans ma langue de programmation, donc c'est génial: d merci pour la réponse
Comment puis-je implémenter les boucles BF dans mon interprète? P> blockQuote>
C'est le point - cela dépend entièrement de votre langue. Pour le cas d'un langage de programmation basé sur une pile (ou d'une langue pouvant utiliser une pile), @RJH a donné une bonne solution. D'autres langues utiliseraient différentes solutions, telles que la récursivité (c'est-à-dire une utilisation implicite d'une pile). P>
Du sommet de ma tête, cela pourrait être des erreurs dedans, mais quelque chose comme ça devrait fonctionner: appeler interpréter avec le code source cerfique * CK. Le pointeur P est à la position de la mémoire actuelle. Faire un appel récursif lorsque vous remarquez A [. Retour de cet appel récursif lorsque vous rencontrez un]. P> p>
Hm .. Seulement s'il ne rencontre jamais de "]", car si c'est le cas, il retournera l'emplacement de ce caractère. Mais obtenir un segfault du tout, même si cela est dû à une entrée non valide, n'est pas très agréable, non :) Encore une fois, illus d'une illustration approximative d'une solution, pas parfaitement sans faille.
Je préfère utiliser une table de saut (ainsi que la conversion de BF brut en «bytecode»). Optimiser les interprètes BF sont clairement la voie à suivre! P>
Voici mon "optimisation" de la version d'interprète, qui compilait les sauts de boucle.
def interpret2(code): data = [0] * 5000 # data memory cp = 0 # code pointer dp = 0 # data pointer # pre-compile a jump table stack = [] jump = [None] * len(code) for i,o in enumerate(code): if o=='[': stack.append(i) elif o==']': jump[i] = stack.pop() jump[jump[i]] = i # execute while cp < len(code): cmd = code[cp] if cmd == '>': dp += 1 elif cmd == '<': dp -= 1 elif cmd == '+': data[dp] += 1 elif cmd == '-': data[dp] -= 1 elif cmd == '.': stdout.write(chr(data[dp])) elif cmd == ',': data[dp] = ord(stdin.read(1)) elif cmd == '[' and not data[dp]: # skip loop if ==0 cp = jump[cp] elif cmd == ']' and data[dp]: # loop back if !=0 cp = jump[cp] cp += 1
Dupliquer: Stackoverflow.com/questions/1055758/...