]]> ]]>

befungee

Реализация языка программирования Befunge

befungee — интерпретатор Befunge-93, написанный на Python и распространяющийся под лицензией GNU GPL. Автор реализации — Curtis McEnroe. Первая версия была выпущена 14 января 2010 года.

Особенности реализации:

  • интерпретатор запускается командой python befungee.py <имя программы на Befunge>.
  • для запуска встроенного отладчика можно использовать опцию --debug --delay=100.
  • элементы стека хранятся как числа произвольного размера (за счет реализации на Python).
  • содержимое ячеек программы хранится как беззнаковое целое 0…255.
  • при посимвольном чтении из потока ввода символ с ASCII-кодом #13 игнорируется.

Интерпретатор befungee с отладчиком
Интерпретатор befungee с отладчиком

Примеры:

Hello, World!:

Пример для версий befungee 0.2.0

Первая часть примера (до пробела) размещает в стеке нужные значения. 25* помещает в стек значение 10 (ASCII-код перевода строки), затем " переводит программу в строковый режим: каждый следующий символ (до вторых кавычек) добавляет в стек свой ASCII-код.

Вторая часть примера — цикл, выводящий на печать все значения в стеке, начиная с самых верхних. > возвращает указатель инструкций к движению вправо (после конца одной итерации). : копирует верхний элемент стека (т.е. текущий символ), из-за моста # выполняется только при движении вправо. , выводит верхний элемент стека (выполняется только при движении влево). _ пропускает указатель инструкций к @ (концу программы), если верхний элемент стека — 0, и отражает его влево в противном случае. Последовательность действий в одной итерации следующая:

  • скопировать верхний элемент стека,
  • проверить, равен ли он 0; если равен, выйти из цикла (при этом в любом случае копия элемента удаляется из стека),
  • напечатать верхний элемент стека.
25*"!dlroW ,olleH" >:#,_@

Hello, World!:

Пример для версий befungee 0.2.0

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

89*,45*99*+,39*99*+::,,56*99*+,29+4*,48*,92+8*1-,56*99*+:,3+,,25*:*,56*3+,25*,@

Факториал:

Пример для версий befungee 0.2.0

Программа состоит из двух циклов — первый вычисляет числа от 16 до 1, второй — собственно факториалы.

Прежде всего в стек заносится 16 (как 4*4) — максимальное число, факториал которого нужно вычислить. Затем следует первый цикл, выполняющийся по часовой стрелке. За одну итерацию в стек дописывается число, равное предыдущему, уменьшенному на 1. Когда это число становится нулем, цикл прерывается (_ во второй строке), и указатель инструкций направляется вправо.

Перед входом во второй цикл из стека удаляется верхний элемент (0) и добавляется 1 (текущее значение факториала). Затем следует второй цикл, выполняющийся против часовой стрелки. За одну итерацию происходит следующее:

  • \ — два верхних элемента (ранее вычисленный факториал и следующее число) стека меняются местами (число становится верхним элементом). Если в стеке всего один элемент, поверх него записывается 0.
  • :_ — если следующее число — 0 (или стек пуст), цикл прерывается.
  • . — следующее число выводится на печать (копия остается в стеке).
  • блок ,,,,"! = " — помещает в стек символы строки и сразу же их выводит. Строка проходится справа налево, но и символы выводятся от самого верхнего к нижним, так что для программиста строка выглядит так же, как на печати.
  • .:* — вычисляется новый факториал и выводится на печать (копия остается в стеке).
  • ,*25 — вывод перевода строки.
44* >:1-:v    v ,*25 .:* ,,,,"! = ".:_ @ 
    ^    _ $1 > \:                   ^ 

Числа Фибоначчи:

Пример для версий befungee 0.2.0

Используется итеративное определение чисел Фибоначчи.

В этом примере используются команды p и g, предназначенные для модификации исходного кода программы в процессе выполнения, — они записывают заданный символ в заданную клетку программы и считывают его оттуда в стек, соответственно. В данном случае это используется для хранения вычисленных чисел Фибоначчи (счетчик цикла все время хранится в стеке). При записи чисел как ASCII-кодов символов большие числа искажаются, поэтому выводятся только первые 13 штук.

031p132p 94+ > 31g 32g :. + 32g v
             | :-1,,", "p23 p13 <
             > "."::,,,25*,@

CamelCase:

Пример для версий befungee 0.2.0

Программа реализует посимвольную обработку введенной строки. Код снаружи цикла 152p записывает в ячейку программы (5,2) значение 1, соответствующее логическому true — начало строки считается пробелом.

Основная часть программы — цикл. В одной итерации цикла считывается (~) и обрабатывается один символ. Выход из цикла осуществляется, если ASCII-код введенного символа равен 10 (: 25*- #v_ @), в противном случае указатель инструкций отправляется во вторую строку (команда v). Если символ — буква нижнего регистра, он переводится в верхний — для единообразия последующей обработки (часть программы до первого квадратного блока и сам блок). Затем аналогичным способом проверяется, является ли символ буквой верхнего регистра. Если нет (переход в первую строку), в ячейку (5,2) снова записывается 1, символ удаляется из стека, и цикл заканчивается. Если да (переход в третью строку), выполняется еще одна проверка — на значение ячейки (5,2), в зависимости от которого символ остается собой или переводится в нижний регистр. Наконец, символ выводится, и цикл заканчивается.

152p > ~ : 25*- #v_ @               >48*-v                    >152p $        v
                 > :: "`"` \"{"\` * |    > :: "@"` \"["\` * ! |    >    v
                                    >    ^                    >52g |    >052p,v
                                                                   >48*+^
     ^                                                                        <
 ( )
  |
  was last character a space? (5,2)

Комментарии

]]>

blog comments powered by Disqus

]]>

Работа программистам