Найти - Пользователи
Полная версия: Интерпретатор языка brainfuck 6K
Начало » Python проекты » Интерпретатор языка brainfuck 6K
1
DOSfag
Нововведения:
1. Простой интерфейс командной строки, вместо назойливого оповещения о продолжении работы программы, кода brainfuck программы over 9000 символов в строку, справки, которая заполняет окно, чуть менее, чем полностью (вместо этого после запуска программы выводится список (базовых) команд программы-интерпретатора)
2. Поддержка явных комментариев, распологаемых между звёздочками (“*”)
3. Так как интерпретатор разработан для собственного диалекта языка, добавлены команды “_”(ввод числового значения в текущую ячейку) и “=”(вывод числового значения из текущей ячейки)
Команды программы-интерпретатора:
'run' - выполнить программу на языке brainfuck
'help' - вызов справки о командах программы и командах языка
'exit' - выход из программы

З.Ы. Если заметите баг, то можете написать мне в этой теме
DOSfag
З.Ы. Опять таки советую набирать исходный код в текстовом редакторе, т.к. пока удалить часть строки можно только при наборе строки. Уже введённую строку, увы, отредактировать невозможно.
DOSfag
Циклы, к сожалению, пока не работают. Но я обещаю исправить эту проблему.
DOSfag
Вот на днях решил исправить циклы. Алгоритм по идее должен работать правильно, но мой интерпретаторы опять игнорирует операторы цикла. В чём проблема, подскажите, пожалуйста? Я даже перед квадратными скобками символ “\” поставил, и все равно не работает…
EBFE
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 символа,
program[i]
возвращает 1 символ - итого
program[i] =="\[" 
всегда 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)        
DmitriyM
Написал свой интерпретатор brainfuck (http://pythonworld.ru/primery-programm/interpretator-brainfuck.html). Без выкрутасов, но вроде бы работает.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB