1. raw_input все же лучше - меньше мороки при вводе
2.
i=loop_stack[len(loop_stack)-1]
Проще:
i=loop_stack[-1] # при использовании отрицательных индексов отсчет ведется с конца списка
2.
for i in range(len(programm))
...
i=loop_stack
это не Си/Pascal/Java etc. For работает с последовательностями/итератором.
i это просто элемент “выданный” range и присвоение нового значения никак не влияет на сам цикл.
Тоесть в этом случае нужен while
i=0
while i < len(programm):
...
i += 1
даже перед квадратными скобками символ “\”
зря - "\[" это 2 символа,
возвращает 1 символ - итого
всегда false.
Ну и вот этот блок:
if programm[i]=='\[':
if comment==False:
if variables[index]==0:
br_balance+=1
loop_stack.append(i)
loop_ignore=True
else:
loop_stack.append(i)
loop_ignore=False
if programm[i]=='\]':
if comment==False:
if loop_ignore==True:
br_balance-=1
loop_stack.pop()
else:
i = loop_stack[-1] #loop_stack[len(loop_stack)-1]
Stack не “очищается” и растет. Поздравляю с memory leakом
3.
if br_balance>0:
loop_ignore = True
Не хватает
else:
loop_ignore = False
Я особо в саму логику программы не вникал, но после этих исправлений “hello world” по крайней мере выполняется
import sys
def brainfuck_interprer(programm):
#Встроенные компоненты языка
variables=[0] #Переменные языка brainfuck
index=0 #Адрес текущей переменной
comment=False #Флаг комментария
##Цикл
br_balance=0 #Баланс скобок
loop_stack=[] #Стёк адресов (индексов) начальных операторов цикла
loop_ignore=False #Флаг игнорирования цикла
i=0
while i < len(programm):
if br_balance>0:
loop_ignore=True
else:
loop_ignore = False
if programm[i]=='>':
if comment==False and loop_ignore==False:
index+=1
if len(variables)-1<index:
variables.append(0)
if programm[i]=='<':
if comment==False and loop_ignore==False:
index-=1
if programm[i]=='+':
if comment==False and loop_ignore==False:
variables[index]+=1
if programm[i]=='-':
if comment==False and loop_ignore==False:
variables[index]-=1
if programm[i]=='.':
if comment==False and loop_ignore==False:
sys.stdout.write(chr(abs(variables[index]))),
if programm[i]==',':
if comment==False and loop_ignore==False:
variables[index]=ord(raw_input("Введите, пожалуйста, символ\n"))
if programm[i]=='=':
if comment==False and loop_ignore==False:
print(variables[index])
if programm[i]=='_':
if comment==False and loop_ignore==False:
variables[index]=int(raw_input("Введите число, пожалуйста\n"))
if programm[i]=='*':
comment=not comment
if programm[i]=='[':
if comment==False:
if variables[index]==0:
br_balance+=1
loop_stack.append(i)
loop_ignore=True
else:
loop_stack.append(i)
loop_ignore=False
if programm[i]==']':
if comment==False:
if loop_ignore==True:
br_balance-=1
loop_stack.pop()
else:
i = loop_stack.pop() - 1
i += 1
print("""Команды программы-интерпретатора:
'run' - выполнить программу на языке brainfuck
'help' - вызов справки о командах программы и командах языка
'exit' - выход из программы""")
comm_exit=False
commands={'run','exit','help'}
bf_text=""
while comm_exit==False:
line=raw_input()
if line in commands:
if line=='exit':
comm_exit=True
elif line=='run':
brainfuck_interprer(bf_text)
bf_text=""
elif line=='help':
print("""Команды классичекого brainfuck'а:
'<' - перейти к предыдущей ячейке (если текущая чейка с нулевым адресом, то будет переход к самой последней ячейке)
'>' - перейти к следующей ячейке (и создать новую ячейку с нулевым значением(если текущий адрес ячейки максимальный))
'+' - прибавить единицу к значению текущей ячейки
'-' - убавить единицу от значения текущей ячейки
'.' - вывод символа (юникод) по коду из текущей ячейки
',' - запрос ввода символа и помещение его кода в текущую ячейку
'[' - пока значение текущей ячейки не равно нулю, выполнять команды цикла
']' - конец цикла
Дополнительные команды собственного диалекта языка:
'=' - вывод значения текущей ячейки
'_' - запрос ввода значения (численного) для текущей ячейки
Комментарий располагается между звёздочками ('*')
...Остальные символы интерпретатором игнорируются, так что можно писать комментарий и без звёздочек, но тогда вышеперечисленные символы
будут распознаны, как команда, а не просто символ
Прорамма работает в интерфейсе командной строки, как в старых добрых временах DOS 80-х. Команды программы-интерпретатора:
'run' - выполнить программу на языке brainfuck
'help' - вызов справки о командах программы и командах языка
'exit' - выход из программы""")
else:
bf_text=bf_text+str(line)