Witam
Od paru dni męczę się z implementacją algorytmu dotyczącego zagnieżdżonych pętli w Brainfucku. Napisałem program, który "interpretuje" kod Brainfucka, ale bez uwzględniania zagnieżdżonych pętli. Chciałbym żeby interpreter był jak najlepiej dopracowany dlatego proszę Was o pomoc. Problem przedstawię dość szczegółowo, aby nic nie zabrakło. To jest cały kod programu:
import sys
def execute(filename):
f = open(filename, 'r')
translate(f.read())
f.close()
def translate(commands):
bf_array, cell_pointer, bf_code_pointer = [0], 0, 0,
bf_code = list(commands)
tmp_bfstack = [] # pozycje nawiasow
while bf_code_pointer < len(bf_code):
if bf_code[bf_code_pointer] == '>':
bf_array.append(0)
cell_pointer += 1
if bf_code[bf_code_pointer] == '<':
cell_pointer -= 1
if bf_code[bf_code_pointer] == '+':
bf_array[cell_pointer] += 1
if bf_code[bf_code_pointer] == '-':
bf_array[cell_pointer] -= 1
if bf_code[bf_code_pointer] == '.': print(chr(bf_array[cell_pointer]))
if bf_code[bf_code_pointer] == ',': bf_array[cell_pointer] = ord(input())
if bf_code[bf_code_pointer] == '[':
tmp_bfstack.append(bf_code_pointer)
print(tmp_bfstack) # TEST
if bf_code[bf_code_pointer] == ']' and bf_array[cell_pointer] != 0:
bf_code_pointer = tmp_bfstack.pop()
bf_code_pointer += 1
print(bf_code_pointer) # TEST
def main():
if len(sys.argv) == 2: execute(sys.argv[1])
else: print('Try:', sys.argv[0], 'filename.')
main()
W tym fragmencie jest problem:
if bf_code[bf_code_pointer] == '[':
tmp_bfstack.append(bf_code_pointer)
print(tmp_bfstack) # TEST
if bf_code[bf_code_pointer] == ']' and bf_array[cell_pointer] != 0:
bf_code_pointer = tmp_bfstack.pop()
bf_code_pointer += 1
Mianowicie pomyślałem, że program ma działać w następujący sposób:
Do listy dodaje pozycję '[' za każdym razem gdy go znajdzie. Jak wiadomo '[' jest punktem inicjalizującym pętlę, a ']' jest punktem kończącym jej działanie. Toteż logika ma być przykładowo taka: >>+[-->><++] '[' jest na pozycji 3, więc 3 zostaje zapisana do listy tmp_bfstack
. Gdy while dotrze do ']' wówczas ustawiamy wskaźnik na pozycję 3 i rozpoczynamy wykonywanie instrukcji między nawiasami do momentu aż wartość bf_array[cell_pointer]
będzie równa 0.
Mam nadzieję, że dobrze wytłumaczyłem :)
Oto przykład błędnego działania i przykład programu dla którego kod źle działa:
,>,>++++++++[<------<------>>-]<<[>[>+>+<<-]>>[<<+>>-]<<<-]>>>++++++[<++++++++>-]<.
2
1
2
2
3
4
5
6
7
8
9
10
11
12
[12]
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
13
'[' jest na pozycji 12 natomiast ']' znajduje się na pozycji 30. Powyżej znajdują się wypisane wskaźniki. Wskaźnik po wykryciu ']' powinien wrócić na pozycję 12 zamiast 13 tak jak jest w przykładzie, aby program działał poprawnie.
No więc próbowałem zrobić coś takiego:
if bf_code[bf_code_pointer] == '[':
tmp_bfstack.append(bf_code_pointer)
print(tmp_bfstack) # TEST
if bf_code[bf_code_pointer] == ']' and bf_array[cell_pointer] != 0:
bf_code_pointer = tmp_bfstack.pop() - 1
bf_code_pointer += 1
bf_code_pointer = tmp_bfstack.pop() - 1
W tym przypadku wskaźnik rzeczywiście wskazuje na poprawną pozycję, ale program się zapętla.
Byłbym wdzięczny za jakąkolwiek pomoc w naprowadzeniu mnie na dobry tor