Page 1 of 2

Интерпретатор Brainf#ck

Posted: Tue Feb 15, 2011 1:02 am
by SoUrcerer
Доброго времени суток всем!

Разбираюсь сейчас с работой компилятора GCC и его особенностями при компиляции программ для Колибри. Удалось заставить работать консоль из menuetlibc, и решил попробовать в честь этого перенести в Колибри какую-нибудь простую и может быть кому нибудь полезную программу. В связи с увлекательностью процесса понимания работы GCC и libc, выбор пал на простой интерпретатор языка Brainf#ck, известного наверное всем на этом форуме.

Итак, сказано - сделано. Взял первый попавшийся под руки интерпретатор brainf#ck на Си, и воткнул его в код из testcon. Завелось. Так как в этой библиотеке консоли нет обработки клавиатуры, команду "," просто закомментировал. Если мне кто-нибудь сможет объяснить (в свою очередь, я буду очень благодарен), как подключить console.obj (честное пионерское, пытался прикрутить с помощью console.c из shell, но ничего не вышло, компилятор ругается), то запускаемый файл интерпретатора станет в пару раз легче, и можно будет добавить команду ввода данных, что сделает реализацию полной.

В прикрепленном архиве находится исходный код программы (main.c), скомпилированная и сжатая kpack'ом программа bf.kex и файл 1.bf - это hello world на языке brainf#ck. Запускать bf.kex следует, указывая в качестве параметра имя интерпретируемого файла (с помощью run или ассоциаций), например, так: bf.kex 1.bf. Если имя файла не указать, программа выведет сообщение об ошибке.

[irony] Ура, для Колибри можно писать программы на еще одном языке программирования. [/irony]

*ох, не те исходники сначала прилепил...*

Re: Интерпретатор Brainf#ck

Posted: Tue Feb 15, 2011 1:06 am
by Gluk
можно ввод сделать неинтерактивный - передавать входную строку в параметрах. Сам думал о портировании BF под Колибри в качестве скриптового языка для Панели)

Re: Интерпретатор Brainf#ck

Posted: Tue Feb 15, 2011 1:09 am
by SoUrcerer
Мсье знает толк в извращениях...

Re: Интерпретатор Brainf#ck

Posted: Tue Feb 15, 2011 8:18 am
by Albom
а можно посмотреть на полный проект? какие используются компилятор, библиотеки, скрипты? желательно подробное описание. (а то завести menuetlibc когда-то пробовал, но не получилось) заведу menuetlibc - можно будет подумать над прикручиванием console.obj...

Re: Интерпретатор Brainf#ck

Posted: Tue Feb 15, 2011 8:44 am
by SoUrcerer
Работаю с gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 и GNU ld (GNU Binutils for Ubuntu) 2.20.1-system.20100303.
libc уже не помню какой именно у меня, но кажется, новее, чем libc от Ярека (мне почему-то кажется, что используется 70я функция, а не 58я для работы с ФС), хотя и основан кажется на нем. Где исходный архив - не знаю, но похоже с сайта diamond'а Собрался libc без проблем (почти) - задал export MENUETDEV, зашел в папку, ввел make, подождал и получил скомпилированный binclock и еще пару простых программ. Остальные не компилировались, выдавая ошибки о нехватке библиотек или ругались на undefined __stack_chk_fail. После того, как я добавил void __stack_chk_fail(void) {} в некомпилирующиеся программы и скомпилировал библиотеки, которых не хватало (взял исходники с menuetcd), все остальное тоже заработало. Полный "проект" интерпретатора bf состоит из файла main.c и makefile

Code: Select all

OUTFILE = bf
OBJS = main.o
LIBS = -lcon2
include $(MENUETDEV)/makefiles/Makefile_for_program
Если же говорить о попытках использования console.c: я взял console.c из shell 0.4.1, добавил в него функции из kolibri.c, на которые компилятор ругался "undefined refernce", и теперь получаю

Code: Select all

/home/sourcerer/projects/me/linuxtools/mgcc test.c test.o  -fno-stack-protector
In file included from test.c:6:
/home/sourcerer/projects/me/include/console.c:16: error: expected ‘)’ before ‘con_init’
/home/sourcerer/projects/me/include/console.c:17: error: expected ‘)’ before ‘printf’
/home/sourcerer/projects/me/include/console.c:18: error: expected ‘)’ before ‘_exit’
/home/sourcerer/projects/me/include/console.c:19: error: expected ‘)’ before ‘gets’
/home/sourcerer/projects/me/include/console.c:20: error: expected ‘)’ before ‘getch’
/home/sourcerer/projects/me/include/console.c:21: error: expected ‘)’ before ‘con_get_font_height’
/home/sourcerer/projects/me/include/console.c:22: error: expected ‘)’ before ‘con_set_cursor_height’
/home/sourcerer/projects/me/include/console.c:23: error: expected ‘)’ before ‘con_get_flags’
/home/sourcerer/projects/me/include/console.c:24: error: expected ‘)’ before ‘con_set_flags’
/home/sourcerer/projects/me/include/console.c:25: error: expected ‘)’ before ‘con_cls’
/home/sourcerer/projects/me/include/console.c:34: warning: ‘packed’ attribute ignored for field of type ‘char’
/home/sourcerer/projects/me/include/console.c:36: warning: ‘packed’ attribute ignored
/home/sourcerer/projects/me/include/console.c:42: warning: ‘packed’ attribute ignored
/home/sourcerer/projects/me/include/console.c: In function ‘CONSOLE_INIT’:
/home/sourcerer/projects/me/include/console.c:86: error: ‘con_init’ undeclared (first use in this function)
/home/sourcerer/projects/me/include/console.c:86: error: (Each undeclared identifier is reported only once
/home/sourcerer/projects/me/include/console.c:86: error: for each function it appears in.)
/home/sourcerer/projects/me/include/console.c:86: error: ‘_stdcall’ undeclared (first use in this function)
/home/sourcerer/projects/me/include/console.c:86: error: expected ‘)’ before ‘void’
/home/sourcerer/projects/me/include/console.c:87: error: expected ‘;’ before ‘kol_cofflib_procload’
/home/sourcerer/projects/me/include/console.c:91: error: ‘_cdecl’ undeclared (first use in this function)
/home/sourcerer/projects/me/include/console.c:91: error: expected ‘)’ before ‘void’
/home/sourcerer/projects/me/include/console.c:92: error: expected ‘;’ before ‘kol_cofflib_procload’
/home/sourcerer/projects/me/include/console.c:96: error: ‘_exit’ undeclared (first use in this function)
/home/sourcerer/projects/me/include/console.c:96: error: expected ‘)’ before ‘void’
/home/sourcerer/projects/me/include/console.c:97: error: expected ‘;’ before ‘kol_cofflib_procload’
/home/sourcerer/projects/me/include/console.c:101: error: expected ‘)’ before ‘void’
/home/sourcerer/projects/me/include/console.c:102: error: expected ‘;’ before ‘kol_cofflib_procload’
/home/sourcerer/projects/me/include/console.c:106: error: ‘getch’ undeclared (first use in this function)
/home/sourcerer/projects/me/include/console.c:106: error: expected ‘)’ before ‘int’
/home/sourcerer/projects/me/include/console.c:107: error: expected ‘;’ before ‘kol_cofflib_procload’
/home/sourcerer/projects/me/include/console.c:111: error: ‘con_get_font_height’ undeclared (first use in this function)
/home/sourcerer/projects/me/include/console.c:111: error: expected ‘)’ before ‘int’
/home/sourcerer/projects/me/include/console.c:112: error: expected ‘;’ before ‘kol_cofflib_procload’
/home/sourcerer/projects/me/include/console.c:116: error: ‘con_set_cursor_height’ undeclared (first use in this function)
/home/sourcerer/projects/me/include/console.c:116: error: expected ‘)’ before ‘int’
/home/sourcerer/projects/me/include/console.c:117: error: expected ‘;’ before ‘kol_cofflib_procload’
/home/sourcerer/projects/me/include/console.c:121: error: ‘con_get_flags’ undeclared (first use in this function)
/home/sourcerer/projects/me/include/console.c:121: error: expected ‘)’ before ‘unsigned’
/home/sourcerer/projects/me/include/console.c:122: error: expected ‘;’ before ‘kol_cofflib_procload’
/home/sourcerer/projects/me/include/console.c:126: error: ‘con_set_flags’ undeclared (first use in this function)
/home/sourcerer/projects/me/include/console.c:126: error: expected ‘)’ before ‘unsigned’
/home/sourcerer/projects/me/include/console.c:127: error: expected ‘;’ before ‘kol_cofflib_procload’
/home/sourcerer/projects/me/include/console.c:131: error: ‘con_cls’ undeclared (first use in this function)
/home/sourcerer/projects/me/include/console.c:131: error: expected ‘)’ before ‘void’
/home/sourcerer/projects/me/include/console.c:132: error: expected ‘;’ before ‘kol_cofflib_procload’
make: *** [test.o] Ошибка 1
Начиная с 16й строки:

Code: Select all

void (* _stdcall con_init)(unsigned w_w, unsigned w_h, unsigned s_w, unsigned s_h, const char* t);
void (* _cdecl printf)(const char* format,...);
void (* _stdcall _exit)(char bCloseWindow);
void (* __stdcall gets)(char* str, int n);
 int (* __stdcall getch)(void);
 int (* __stdcall con_get_font_height)(void);
 int (* __stdcall con_set_cursor_height)(int new_height);
unsigned (*__stdcall con_get_flags)(void);
unsigned (*__stdcall con_set_flags)(unsigned new_flags);
void (*__stdcall con_cls)(void);
Кажется, проблема в переопределении функций stdio. Верно? Очень хочется сохранить совместимость со стандартом ANSI по максимуму.. В идеале чтобы работали команды из libc, которые там есть, но еще можно было подключить console.c к исходным кодам, и использовать если не printf, то хотя бы какие-нибудь krpintf и kgetch.

Re: Интерпретатор Brainf#ck

Posted: Tue Feb 15, 2011 9:20 am
by Albom
Спасибо. Буду разбираться. А проблема вроде как из-за __stdcall, который в MinGW. В чистом gcc вроде просто stdcall. Установил на нетбуке (xubuntu 10.10) пакет mingw-gcc, но ещё не пробовал...

Re: Интерпретатор Brainf#ck

Posted: Tue Feb 15, 2011 9:31 am
by SoUrcerer
У меня нет MinGW :( Система у меня Linux Mint 9 на основе Ubuntu 10.04, так что версии компиляторов могут различаться...
Попробовал заменить __stdcall на stdcall - тот же самый вывод компилятора
*тем временем скомпилировал одну из старых версий lua, вроде бы работает, но без нормальной консоли пользоваться невозможно. точу зубы на lua 5.1*

Re: Интерпретатор Brainf#ck

Posted: Tue Feb 15, 2011 1:08 pm
by CleverMouse
__attribute__((stdcall))

Re: Интерпретатор Brainf#ck

Posted: Tue Feb 15, 2011 1:18 pm
by SoUrcerer
Спасибо, кажется, должно помочь!

Re: Интерпретатор Brainf#ck

Posted: Tue Feb 15, 2011 11:52 pm
by SoUrcerer
Свершилось :mrgreen: с помощью многих [даже не знаю как написать] форумчан я наконец смог использовать console.obj. Спасибо всем огромное!
После этого потребовалось всего несколько минут, чтобы доделать интерпретатор. Теперь он поддерживает и ввод с клавиатуры, то есть является полным.
Пакованный бинарник стал легче почти втрое, но я каким-то образом поломал вывод об ошибках. Надеюсь, починю на днях.
Главное, что работает. В архиве кроме исходных кодов (main.c, Makefile, а так же console.c и stdio.h, которые мне дал Albom) присутствует игра крестики-нолики на brainf#ck (файл xo.bf) для проверки ввода с клавиатуры.
Пользуйтесь на здоровье. :D

Re: Интерпретатор Brainf#ck

Posted: Thu Feb 17, 2011 10:31 pm
by SoUrcerer
Just for fun: 99 бутылок пива на brainfuck от Ben Olmstead.
Главное, чтобы хватило терпения дождаться вывода всей песни на экран. Впрочем, у меня в qemu текст выводится как раз со скоростью караоке ;)

Code: Select all


>+++++++++[<+++++++++++>-]<[>[-]>[-]<<[>+>+<<-]>>[<<+>>-]>>>

[-]<<<+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<

-]<<-<-]+++++++++>[<->-]>>+>[<[-]<<+>>>-]>[-]+<<[>+>-<<-]<<<

[>>+>+<<<-]>>>[<<<+>>>-]>[<+>-]<<-[>[-]<[-]]>>+<[>[-]<-]<+++

+++++[<++++++<++++++>>-]>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-

]<<<<<<.>>[-]>[-]++++[<++++++++>-]<.>++++[<++++++++>-]<++.>+

++++[<+++++++++>-]<.><+++++..--------.-------.>>[>>+>+<<<-]>

>>[<<<+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<+++++++

+>-]<.>+++++++++[<+++++++++>-]<--.---------.>+++++++[<------

---->-]<.>++++++[<+++++++++++>-]<.+++..+++++++++++++.>++++++

++[<---------->-]<--.>+++++++++[<+++++++++>-]<--.-.>++++++++

[<---------->-]<++.>++++++++[<++++++++++>-]<++++.-----------

-.---.>+++++++[<---------->-]<+.>++++++++[<+++++++++++>-]<-.

>++[<----------->-]<.+++++++++++..>+++++++++[<---------->-]<

-----.---.>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>>+++

+[<++++++>-]<--.>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<.

><+++++..--------.-------.>>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++

++++++++++++.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<++

+++++++>-]<--.---------.>+++++++[<---------->-]<.>++++++[<++

+++++++++>-]<.+++..+++++++++++++.>++++++++++[<---------->-]<

-.---.>+++++++[<++++++++++>-]<++++.+++++++++++++.++++++++++.

------.>+++++++[<---------->-]<+.>++++++++[<++++++++++>-]<-.

-.---------.>+++++++[<---------->-]<+.>+++++++[<++++++++++>-

]<--.+++++++++++.++++++++.---------.>++++++++[<---------->-]

<++.>+++++[<+++++++++++++>-]<.+++++++++++++.----------.>++++

+++[<---------->-]<++.>++++++++[<++++++++++>-]<.>+++[<----->

-]<.>+++[<++++++>-]<..>+++++++++[<--------->-]<--.>+++++++[<

++++++++++>-]<+++.+++++++++++.>++++++++[<----------->-]<++++

.>+++++[<+++++++++++++>-]<.>+++[<++++++>-]<-.---.++++++.----

---.----------.>++++++++[<----------->-]<+.---.[-]<<<->[-]>[

-]<<[>+>+<<-]>>[<<+>>-]>>>[-]<<<+++++++++<[>>>+<<[>+>[-]<<-]

>[<+>-]>[<<++++++++++>>>+<-]<<-<-]+++++++++>[<->-]>>+>[<[-]<

<+>>>-]>[-]+<<[>+>-<<-]<<<[>>+>+<<<-]>>>[<<<+>>>-]<>>[<+>-]<

<-[>[-]<[-]]>>+<[>[-]<-]<++++++++[<++++++<++++++>>-]>>>[>+>+

<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>[-]>[-]++++[<++++++++>

-]<.>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<.><+++++..---

-----.-------.>>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++++++++++++++

.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<+++++++++>-]<-

-.---------.>+++++++[<---------->-]<.>++++++[<+++++++++++>-]

<.+++..+++++++++++++.>++++++++[<---------->-]<--.>+++++++++[

<+++++++++>-]<--.-.>++++++++[<---------->-]<++.>++++++++[<++

++++++++>-]<++++.------------.---.>+++++++[<---------->-]<+.

>++++++++[<+++++++++++>-]<-.>++[<----------->-]<.+++++++++++

..>+++++++++[<---------->-]<-----.---.+++.---.[-]<<<]

Re: Интерпретатор Brainf#ck

Posted: Fri Feb 18, 2011 10:52 am
by SoUrcerer
Прошлая версия интерпретатора по непонятным причинам получала неправильные значения входных параметров. Немного подправил код... просьба протестировать. Теперь он не должен падать, когда файл не найден. Почему-то по-прежнему падает, когда запускается без параметров. :( Безобразие просто.

Re: Интерпретатор Brainf#ck

Posted: Mon Feb 21, 2011 9:27 pm
by SoUrcerer
Обновленная версия интерпретатора. Использую mingw32 в ubuntu и newlib. Теперь все нормально с argv и argc, но размер файла значительно распух. Возможно, это как-то связано с опциями линковки. Пока что вывод на доску отладки, чтобы прикрутить консоль, нужно немного подправить файл console.c.
Надеюсь, и lua хорошо соберется.

Re: Интерпретатор Brainf#ck

Posted: Mon Feb 21, 2011 9:35 pm
by Albom
Sorcerer wrote:Теперь все нормально с argv и argc
Действительно? А то что-то меня смущает код в crt из newlib:

Code: Select all

    if( __cmdline != 0)
    {
        _argc = 2;
        arg[1] = &__cmdline;
    } else _argc = 1;

    _argv = arg;

Re: Интерпретатор Brainf#ck

Posted: Mon Feb 21, 2011 9:58 pm
by SoUrcerer
На самом деле для bf достаточно просто получать имя файла. Но для lua этого мало (кроме того, в newlib не хватает двух десятков функций, что есть в menuetlibc).
А в версии для Kolibri в crt то же самое?