Важная информация
Показано с 1 по 5 из 5

Тема: BrainDuck - язык, компилируемый в BrainF**k

  1. #1 BrainDuck - язык, компилируемый в BrainF**k 
    Супер модератор Аватар для Kakos_nonos
    Регистрация
    07.01.2011
    Адрес
    Кубань
    Сообщений
    1,536
    Сказал(а) спасибо
    126
    Поблагодарили 432 раз(а) в 293 сообщениях
    Записей в блоге
    6
    Одно время я пытался программироваьт на BrainF***-ке, иногда даже что-то получалось, однако было очень неудобно: приходится постоянно помнить где какая ячейка и для чего она нужна, большие алгоритмы тоже было не удобно писать из-за вычисления смещений. Хотелось как-то упростить жизнь.
    Пришла в голову идея сделать некоторое макро-расширение для него, чтоб можно было оперировать целыми алгоритмами и переменными.
    Всю структуру нового языка я в уме проработал ещё в апреле, но начал реализовывать только недавно. В итоге получился довольно неплохой язык, на котором можно писать более-менее сложные программы, при этом не получая название языка оригинала Однако всё что написано транслируется в чистый BF, состоящий из 8-ми команд.

    Что-же тут есть:

    Первое добавление - именованые ячейки.
    Теперь не надо ходить от ячейки к ячейке камандами < и >, достаточно просто написать её имя, и транслятор сам превратит его в нужное смещение. Имена можно создавать/убирать прямо в процессе работы программы. При первом попадании имени ячейка создаётся, имя присваевается к ближайшей от текущего положения ячейке. Чтобы разыменовать ячейку, необходимо написать &имя. Данный идентификатор будет стёрт и далее может снова быть занят.
    Теперь программы могут иметь такой вид:

    Код :
     c[-] t[-]
     a[t+a-]
     t[c+a+t-]
     b[t+b-]
     t[c+b+t-]

    Это сложение двух чисел a и b, результат сохраняется в c, а сами операнды не меняются.

    Но можно улучшить ещё, и были добавлена поддержка "процедур". Почему в кавычках? Потому что здесь нет механизма вызова, тело процедуры просто встраивается в место её вызова, поэтому если её вызвали из 2-х мест, то тело будет присутствовать 2 раза.

    Как это выглядит: "Процедура" объявляется так:

    Код :
    ~name(a,b,c)
    ^x,y,z
     
     
     
    end

    a,b,c - это параметры, передаваемые в процедуру. x,y,z - это локальные переменные. появляются при вызове и исчезают при выходе.
    Например, вот так можно оформить процедуру сложения:
    Код :
    ~add(a,b,c) 
     ^t
     c[-] t[-]
     a[t+a-]
     t[c+a+t-]
     b[t+b-]
     t[c+b+t-]
    end

    Что бы вызвать процедуру, нужно просто её записать:

    add(r,t,u)

    Надо только помнить, что в качестве параметров могут выступать только переменные. Числа и другие процедуры писать нельзя. Также процедуры могут не иметь параметров, чтобы отличать их от переменных, надо в конце дописывать (). Например: func()
    Можно вставлять в процедуры другии процедуры, только нельзя вставлять себя, так как процедуры не вызываются, а вписываются.

    Таким образом можно реализовать сколько угодно сложные функции, такие как умножение, деление,десятичный ввод, вывод.
    Однако я добавил пару функций, которые нельзя реализовать средствами транслятора. Это:

    set(a,10)

    Данная функция устанавливает переменную в нужное значение. После выполнения в переменой а будет значение 10.

    write("строка")

    Эта функция выводит строку.

    Внутри есть несколько примеров. Например, поиск простых чисел (Степлер, привет)

    Код :
    #include "base.bi"
     
    ~isprime(r,me)
    ^h,yu
     h[-]+yu[-]+
     yu[
      h+
      mod(r,h,yu)
     yu]
     equal(r,h,me)
    end
     
     
    write("Prime number founder")
    newline()
    write("From: ")
    input(ua)
    write("To: ")
    input(ub)
    sub(ub,ua,u)
    u+
    for(u)
     isprime(ua,aa)
     if(aa)
      output(ua)
      newline()
     endif(aa)
     ua+
    next(u)
    end

    Мы видим вначале подключение файла с основными алгоритмами, потом объявление процедуры isprime. Она определяет просто ли число и возвращает (записывает во второй операнд) 1 если просто и 0 если не. Это кстати значения для логических функций.
    Дальше, в самом теле программы у нас цикл, где мы перебираем все числа из введённого диапазона и если попдаются простые, выводим. Тут мы видим стандартные конструкции: if, for...

    Трансляция в BF происходит за два этапа. Зв первый раскрываются все процедуры, остаётся только BF+переменные. Вышеописанная программа транслируется в это:
    Код :
     
    ''s[-] ''a[-]++++++++[-''s++++++++++''a]''s.
    ''a[-]++++[-''s++++++++''a]''s++.
    ---------.
    ++++.
    --------.
    ''a[-]++++++[-''s-----------''a]''s---.
    ''a[-]++++++[-''s+++++++++++++''a]''s.
    +++++++.
    --------.
    -----------.
    +++.
    +++++++++++++.
    ''a[-]+++++++++[-''s---------''a]''s-.
    ''a[-]+++++++[-''s++++++++++''a]''s.
    +++++++++.
    ++++++.
    -------.
    ----------.
    +.
    +++++++++++++.
    &''s &''a
    yy'1[-] +++++++++++++
    yy'1.---.
    &yy'1 
    ''s[-] ''a[-]+++++++[-''s++++++++++''a]''s.
    ''a[-]++++[-''s+++++++++++''a]''s.
    ---.
    --.
    ''a[-]+++++[-''s----------''a]''s-.
    ''a[-]+++++[-''s-----''a]''s-.
    &''s &''a
    b'1[-]ua[-]d'1[-]
    c'1,----------
    [b'1++++++[c'1------b'1-]c'1--
    ua[d'1+ua-]d'1[ua++++++++++d'1-]c'1[ua+c'1-]
    c'1,----------]
    &b'1 &c'1 &d'1 
    ''s[-] ''a[-]+++++++[-''s++++++++++++''a]''s.
    ''a[-]+++[-''s+++++++++''a]''s.
    ''a[-]++++[-''s-------------''a]''s-.
    ''a[-]+++++[-''s-----''a]''s-.
    &''s &''a
    b'1[-]ub[-]d'1[-]
    c'1,----------
    [b'1++++++[c'1------b'1-]c'1--
    ub[d'1+ub-]d'1[ub++++++++++d'1-]c'1[ub+c'1-]
    c'1,----------]
    &b'1 &c'1 &d'1 
    u[-] t'1[-]
    ub[t'1+u+ub-]
    t'1[ub+t'1-]
    ua[t'1+ua-]
    t'1[u-ua+t'1-]
    &t'1 
     u+ 
    u[
     
     h'1[-]+yu'1[-]+
    yu'1[
    h'1+
    z'3[-]
    x'2[-]
    ua[z'3+ua-]
    z'3[x'2+ua+z'3-]
    &z'3  z'3[-]
    y'2[-]
    h'1[z'3+h'1-]
    z'3[y'2+h'1+z'3-]
    &z'3  yu'1[-] z'2[-]
    x'2[
     
    y'2-
    yu'1+
    l'3[-]
    y'2[l'3+y'2-]
     
    t'3[-]+
    l'3[t'3[-]y'2+l'3-]
    t'3[z'2[-]+t'3-]
    &l'3 &t'3 
    z'2[
     
    z'3[-]
    y'2[-]
    h'1[z'3+h'1-]
    z'3[y'2+h'1+z'3-]
    &z'3 
    yu'1[-]
    z'2-]
     
    x'2-]
     
    &x'2 &y'2 &z'2 
    yu'1]
    j'2[-] t'3[-]
    ua[t'3+j'2+ua-]
    t'3[ua+t'3-]
    h'1[t'3+h'1-]
    t'3[j'2-h'1+t'3-]
    &t'3 
    aa[-]+
    j'2[aa-j'2[-]]
    &j'2 
    &h'1 &yu'1 
     aa[
     
      a'1[-]++++++++++
    y'1[-]u'1[-]a'1[y'1+u'1+a'1-]
    b'1[-]d1'1[-]d2'1[-]
    ua[a'1+ua-]
    a'1[
     
    y'1-
    l'2[-]
    y'1[l'2+y'1-]
     
    t'2[-]+
    l'2[t'2[-]y'1+l'2-]
    t'2[b'1[-]+t'2-]
    &l'2 &t'2 
    b'1[
     
    d2'1+u'1-
    l'2[-]
    u'1[l'2+u'1-]
     
    t'2[-]+
    l'2[t'2[-]u'1+l'2-]
    t'2[y'1[-]+t'2-]
    &l'2 &t'2 
    y'1[
     
    d1'1+d2'1[-]
    u'1++++++++++
    y'1-]
     
    y'1++++++++++
    b'1-]
     
    ua+
    a'1-]
     
    a'1[-] ''a[-]++++++[-a'1++++++++''a]a'1 &''a
    z'2[-]
    a'1[z'2+a'1-]
    z'2[a'1+d1'1+z'2-]
    &z'2 d1'1.
    z'2[-]
    a'1[z'2+a'1-]
    z'2[a'1+d2'1+z'2-]
    &z'2 d2'1.
    u'1[-]++++++++++
    y'1[u'1-y'1-]
    z'2[-]
    a'1[z'2+a'1-]
    z'2[a'1+u'1+z'2-]
    &z'2 u'1.
    &a'1 &u'1 &y'1 &b'1 &d1'1 &d2'1 &fd'1 
      yy'1[-] +++++++++++++
    yy'1.---.
    &yy'1 
     aa-]
     
      ua+ 
    u-]

    Далее включается второй этап и на выходе чистый bf:

    Код :
    [-]>[-]++++++++[-<++++++++++>]<.>[-]++++[-<++++++++>]<++.-------
    --.++++.--------.>[-]++++++[-<----------->]<---.>[-]++++++[-<+++
    ++++++++++>]<.+++++++.--------.-----------.+++.+++++++++++++.>[-
    ]+++++++++[-<--------->]<-.>[-]+++++++[-<++++++++++>]<.+++++++++
    .++++++.-------.----------.+.+++++++++++++.[-]+++++++++++++.---.
    [-]>[-]+++++++[-<++++++++++>]<.>[-]++++[-<+++++++++++>]<.---.--.
    >[-]+++++[-<---------->]<-.>[-]+++++[-<----->]<-.[-]>[-]>[-]>,--
    --------[<<<++++++[>>>------<<<-]>>>--<<[>+<-]>[<++++++++++>-]>[
    <<+>>-],----------][-]<[-]+++++++[->++++++++++++<]>.<[-]+++[->++
    +++++++<]>.<[-]++++[->-------------<]>-.<[-]+++++[->-----<]>-.[-
    ]<[-]<<[-]>>>>,----------[<++++++[>------<-]>--<<[<<+>>-]<<[>>++
    ++++++++<<-]>>>>[<<+>>-],----------][-]<[-]<[>+>+<<-]>[<+>-]<<[>
    >+<<-]>>[>-<<<+>>-]>+[<[-]+>>[-]+[<<+<<<[-]>>>>>>[-]<<<<<[<+>-]<
    [>>>>>>+<<<<<+<-][-]>>>>>>>[-]<<<<[<<<+>>>-]<<<[>>>>>>>+<<<<+<<<
    -]>>>>>[-]>>>[-]<<[>-<<+>>>>[-]<<[>>+<<-]>>>[-]+<[>[-]<<<+>>-]>[
    <<[-]+>>-]<<[>[-]<<[-]<<<<[>>>>>>+<<<<<<-]>>>>>>[<<+<<<<+>>>>>>-
    ]<<<<[-]>>>-]<<-]<]>[-]>[-]<<<<<<[>>>>>>+<+<<<<<-]>>>>>>[<<<<<<+
    >>>>>>-]<<<<[>>>>+<<<<-]>>>>[<-<<<+>>>>-][-]+<[>-<[-]]>[<[-]++++
    ++++++<[-]<<[-]>>>[<+<<+>>>-]>>[-]>[-]>[-]<<<<<<<<<[>>>>>+<<<<<-
    ]>>>>>[<-<<<<<[-]>>>>>[<<<<<+>>>>>-]>>>>>>[-]+<<<<<<<<<<<[>>>>>>
    >>>>>[-]<<<<<<+<<<<<-]>>>>>>>>>>>[<<<[-]+>>>-]<<<[>>+<<<<<<<-<<<
    [-]>>>[<<<+>>>-]>>>>>>>>[-]+<<<<<<<<<<<[>>>>>>>>>>>[-]<<<<<<<<+<
    <<-]>>>>>>>>>>>[<<<<<<[-]+>>>>>>-]<<<<<<[>>>>+>[-]<<<<<<<+++++++
    +++>>-]++++++++++>>>-]<<<<<<<+>>>>>-][-]>>>>>[-]++++++[-<<<<<+++
    +++++>>>>>][-]<<<<<[>>>>>+<<<<<-]>>>>>[<<<<<+>>>+>>-]<<.>>[-]<<<
    <<[>>>>>+<<<<<-]>>>>>[<<<<<+>>>>+>-]<.<<<<<<<[-]++++++++++>>[<<-
    >>-]<<<<<[-]>>>>>>[<<<<<<+>>>>>>-]<<<<<<[>>>>>>+<<<+<<<-]>>>.[-]
    +++++++++++++.---.>>>>-]<<<<<<+>>>-]

    Хоть код получается немного громоздким и тормознутым (на поиск простых чисел от 1 до 255 уходит 980 миллионов операций), но он работает!
    Вы попробуйте на чистом bf написать такую программу, это надо очень много данных держать в голове, что не просто. А разложив на кирпичики, которые состаят также из кирпичиков можно достичь результата. А то что программа много весит, это вопрос времени, думаю, можно будет оптимизировать алгоритмы.

    Планы на будущее:
    1. Добавить массивы.

    Сейчас в трансляторе нет поддержки массивов, хотя на bf их можно реализовать. Дело в том, что массивыимеют размер более одной ячейки (тут смайлик кэпа очевидность). А реализовать текущими средствами это нельзя. В дальнейшей версии я хочу сделать так: Определяется, сколько программа использует ячеек и запоминается первая свободная ячейка. Далее, из программы можно обращаться к этой ячейке и смещениям от неё, а также именовать их. Так мы сможем выделять себе блоки памяти, использовать массивы и писать сложные программы. Однако, тут есть проблема: Нельзя определить количество занимаемых ячеек, не оттранслировав программу. Поэтому, наверное придётся выполнять второй этап дважды или добавлять ещё один этап. Тут можно обсудить.

    2. В качестве аргументов любые конструкции языка.

    Сейчас в качестве аргументов в процедуры можно передовать только переменные, но далее можно расширить этот круг. Например:
    Код :
    ~writemultiply(a,b)
     for(a) 
      write(b)
      newline()
     next(a)
    end
     
    set(a,10)
    writemultiply(a,"Привет, мир")

    Можно так будет передовать строки, числа, процедуры, команды, алгоритмы, которые будут встраиваться в процедуру. Это увеличит гобкость языка.

    3.Пост-обработка.

    Как вы заметили, выходной код достаточно большой. Также, если внимательно посмотреть, в нём много команд [-]. Это команда очищения текущей ячейки. Она стоит перед каждой локальной переменной при её объявлении. Однако в большинстве случаев локальные переменные после выхода из процедуры остаются обнулёнными. Можно написать программу, которая будет отыскивать вхождения этих символов и определять, не очищалась ли она до этого. Программа будет делать как бы в экскурс в прощлое этой ячейки, она определит все её предыдущие состаяния, и если было хотя б одно что при достижении этого положения ячейка была ненулевая, то эти команды мо оставляем. Если же при всех сценариях она обнуляется, удаляем эту группу.
    Также можно написать ещё одну тулзу, которая будет менять местами ячейки, и смотреть не уменьшился размер программы, ведь bf основан на переходе между ячейками, и чем ячейки дальше, тем больше команд, тем ближе. Так можно посмотреть, уровень обмена между каждыми ячейками и какие более часто обмениваются, те ближе поставить, так мы сэкономин на командах.

    Вот пока всё.
    Позволю себе немного похвастаться, в данном трансляторе помимо строк нет массивов вообще. Все: номера ячеек, процедуры, списки процедур, локальные переменные, всё хранится в динамических типах данных, которые создаются, освобождаются и нет лимита по размеру кроме оъёма памяти. Я специально решил так сделать так как раньше с указателями не работал и вот решил потренироваться.
    Также название интересное. Изменена всего одна буква, а смысл изменился координально, но суровости не убавилось.

    Такие дела. Буду рад вопросам, предложениям и багрепортам.
    Вложения
    [Ссылки могут видеть только зарегистрированные пользователи. ]
    Ответить с цитированием  
     

  2. 3 пользователя(ей) сказали cпасибо:

    >Quiet Snow< (22.10.2014), pingvin (21.10.2014), Абадябер (21.10.2014)

  3. #2  
    Гуру Аватар для Абадябер
    Регистрация
    09.12.2010
    Адрес
    Беларусь, Минск
    Сообщений
    1,219
    Сказал(а) спасибо
    302
    Поблагодарили 176 раз(а) в 144 сообщениях
    Записей в блоге
    5
    Kakos_nonos, огромное спасибо за этот труд. Скачал, поигрался, но пока нет времени зависнуть на, например, также долго, как и со степлером. И сказать, к сожалению, не могу особенно много (что стыдно, учитывая то, как много написано, и как мало я пишу в ответ).
    Все же укажу, что технология сама по себе очень правильная и нужная - по существу это тот же самый компилятор из языка ВУ для одной из реализаций машины тьюринга. Не удивлюсь, если все сложные и объемные программы на брейнфаке писались примерно таким же путем)
    Кстати, за название - отдельное спасибо.
    Дружба-магия-радость!
    Ответить с цитированием  
     

  4. #3  
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,931
    Сказал(а) спасибо
    1,842
    Поблагодарили 982 раз(а) в 840 сообщениях
    Записей в блоге
    1
    и чем ячейки дальше, тем больше команд
    Пока читал те же мысли были.

    Буду рад вопросам, предложениям и багрепортам.
    Ну уж сам стараюсь не лезть в эзотерические языки и машины тьюринга, т.к. мозг на лосося взыграет.
    Эти все штуки в общем нужны только для тренировки мозга, как шахматы и прочие логические вещи.
    Всё таки процессор не примитивная машина тьюринга, позволяет больше и лучше.
    Kakos_nonos, но ты конечно очень крут, уже с лёгкой руки пишешь трансляторы. Вообще это дело
    очень трудоёмкое, если без каких-либо наработок стартовать, один синтаксический анализатор чего
    стоит, я б его год писал и не написал))).

    А кстати что там со степлером? Кто-нибудь использует, продвигает? Коммьюнити же было вроде, даже
    игрушки какие-то с графикой писали.
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

  5. #4  
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,931
    Сказал(а) спасибо
    1,842
    Поблагодарили 982 раз(а) в 840 сообщениях
    Записей в блоге
    1
    Посмотрел сегодня, позапускал примеры. Сначала хотел на семёрке(x64), но компиль мозготраха оказался чисто досовый,
    пришлось тащить на другой комп с XP. Как пожелание - добавить и виндовый x86 компиль(ну и батник для компиляции).

    А так всё супер, минималистично, понятно что-где. Кстати только что допёр почему таки утки концепт концепт,
    надо продвигать.

    P.S: Kakos_nonos, извиняй всё время не найду, чтобы потыкать муз редактор, там просто много времени надо.
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

  6. #5  
    Супер модератор Аватар для Kakos_nonos
    Регистрация
    07.01.2011
    Адрес
    Кубань
    Сообщений
    1,536
    Сказал(а) спасибо
    126
    Поблагодарили 432 раз(а) в 293 сообщениях
    Записей в блоге
    6
    Да, компилятор досовый, на нашёл виндовый.
    [Ссылки могут видеть только зарегистрированные пользователи. ]
    Ответить с цитированием  
     

Информация о теме
Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Немного филологии. Язык компьютерщиков)))
    от Евгения Труайя в разделе Кино, литература
    Ответов: 14
    Последнее сообщение: 15.09.2016, 16:47
  2. Какой язык программирования выбрать?
    от Tim в разделе Общие вопросы программирования
    Ответов: 22
    Последнее сообщение: 14.12.2013, 13:51
  3. Книга: СТЕПЛЕР. Язык программирования.
    от Kakos_nonos в разделе Степлер
    Ответов: 12
    Последнее сообщение: 23.03.2013, 06:43
  4. Выбираем язык
    от lokere в разделе Общие вопросы программирования
    Ответов: 6
    Последнее сообщение: 20.02.2013, 12:31
  5. Язык для начинающих Бегин
    от pingvin в разделе Разработки на C/C++
    Ответов: 47
    Последнее сообщение: 17.12.2011, 02:47
Ваши права
  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •