[Brainfuck] Интерпритатор BrainFuck на Prolog(VIP 5.2) - Программирование

Узнай цену своей работы

Формулировка задачи:

Была у нас такая лаба(точнее должна быть в декбре). Решил я поделится с вами кодом,мб кому-то пригодится.
Вводим путь к текстовому файлу с кодом и будет нам счястье.

Решение задачи: «[Brainfuck] Интерпритатор BrainFuck на Prolog(VIP 5.2)»

textual
Листинг программы
domains
        c=c(integer,integer).
        l=c*
        file=f
predicates
        nondeterm cout %вывод значения текущей ячейки
        nondeterm cin   %ввод значения в ячейку
        nondeterm add  %инкрементация значения ячейки
        nondeterm sub  %декрементация значения ячейки
        nondeterm do    %покомандная интерпритация исходного кода
        nondeterm step(char)%вызов выполнения команды
        nondeterm next  %переход в ячейку с номером N+1
        nondeterm prev  %переход в ячейку с номером N-1
        nondeterm goto  %окночание цикла
        nondeterm repeat%начало нового цикла
database
        circle(l)              %список позиций начал циклов
        pos(integer)        %текущий номер ячейки
        data(integer,integer)% 1 агрумент - номер ячейки
                                     %2 - значение
clauses 
        cout:-pos(N),data(N,X),writef("%c",X). %определяем позицию ячейки и значение в ней, после чего выводим его
                
        cin:-pos(N),retract(data(N,_)),cin.       %определяем позицию ячейки, удаляем значение в ней
        cin:-pos(N),readdevice(keyboard),readchar(X),readdevice(f),assert(data(N,X)).%после чего вводим новое
             %можно слить эти 2 правила
                
        add:-pos(N),retract(data(N,X)),Y=X+1,assert(data(N,Y)).%заменяем значение в текущей ячейке из Х на Х+1
        
        sub:-pos(N),retract(data(N,X)),Y=X-1,assert(data(N,Y)).%заменяем значение в текущей ячейке из Х на Х-1
        
        next:-pos(X),Y=X+1,data(Y,_),!,retract(pos(X)),assert(pos(Y)).%если следуюющяя ячейка существует, то переходим в нее
        next:-retract(pos(X)),Y=X+1,assert(pos(Y)),assert(data(Y,0)).%если нет выделяем для нее память и переходим в нее
        
        prev:-pos(X),Y=X-1,data(Y,_),!,retract(pos(X)),assert(pos(Y)).%аналогично next только для предыдущей
        prev:-retract(pos(X)),Y=X-1,assert(pos(Y)),assert(data(Y,0)).
        
        goto:-circle([_|L]),pos(N),data(N,X),X=0,!,retract(circle([_|L])),assert(circle(L)).%если по окончании цылка текущяя ячейка 0 удаляем 
                                                                                                                     %последний указатель на вход в цикл
        goto:-circle([c(N,_)|_]),filepos(f,N,0).                                                          %иначе переходим в него
        
        repeat:-circle(L),retract(circle(L)),filepos(f,N,0),pos(X),data(X,D),assert(circle([c(N,D)|L])).%создаем новый указатель на начало цикла
                                                                                                                                   %дата используется для определения нужно ли    
                                                                                                                                    %выполнять команды в нем
        do:-readchar(X),step(X),not(eof(f)),!,do.            %проход текстового файла с исходным кодом
        do:-exit.                                                        %если файл закончился выйти и программы
        
        
        %отсечение используется для не попадания в step(_).
        step('['):-repeat,!.  %вход в цикл
        step(']'):-goto,!.     %выход из цикла или переход в его начало
        step(_):-circle([c(_,X)|_]),X=0,!. %если мы в цикле и значение ячейки при входе было 0, то ничего в нутри его не надо выполнять 
        step('>'):-next,!. %Все
        step('<'):-prev,!. %эти 
        step(','):-cin,!.    %правила
        step('.'):-cout,!.  %описаны
        step('+'):-add,!.   %выше
        step('-'):-sub,!.    %
        step(_).  % если символ - не команда, то просто пропускаем его.
goal
        write("Input Path of BrainFuck Code: "),readln(Path),openread(f,Path),readdevice(f),nl,write("Interupt..."),nl,nl,
        assert(pos(1)),assert(data(1,0)),assert(circle([c(0,1)])),do.

Оцени полезность:

13   голосов , оценка 3.846 из 5
Похожие ответы