Написать переводчик для 2B

12

Написать переводчик для 2B

Мне нравится эзотерический язык Дэвида Кэтта 2B, в котором память хранится на ленте, где каждая ячейка представляет собой отдельную ленту байтов («подзаголовок»). Напишите переводчика для этого!

Спецификация языка

Официальную спецификацию можно найти здесь . В этой спецификации "означает число в диапазоне 0-9( 0интерпретируется как 10) и _означает строку любой длины. Каждая ячейка хранит значение в диапазоне 0-255, и переполнение / переполнение оборачивается, как если бы это было BF. (Спасибо @ MartinBüttner). Для преобразования текста в числа 0-255используйте коды ASCII . Поскольку я не могу найти подробностей об этом, я скажу, что длина ленты должна быть 255минимальной, но если вы знаете иначе, пожалуйста, отредактируйте.

+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
| Instruction |                                                              Description                                                               |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
| 0           | Zeroes the current cell and clears the overflow/underflow flag.                                                                        |
| {           | If the current cell is zero, jump to the matching }.                                                                                   |
| }           | A placeholder for the { instruction.                                                                                                   |
| (           | Read a byte from the input stream and place it in the current cell.                                                                    |
| )           | Write the value of the current cell to the console.                                                                                    |
| x           | Store the value of the current cell in a temporary register.                                                                           |
| o           | Write the value of the temporary register to the console.                                                                              |
| !           | If the last addition overflowed, add one to the current cell. If the last subtraction underflowed, subtract one from the current cell. |
| ?           | Performs a binary NOT on the current cell.                                                                                             |
| +"          | Adds an amount to the current cell.                                                                                                    |
| -"          | Subtracts an amount from the current cell.                                                                                             |
| ^"          | Moves the subtape up a number of times.                                                                                                |
| V"          | Moves the subtape down a number of times.                                                                                              |
| <"          | Moves the tape left a number of times.                                                                                                 |
| >"          | Moves the tape right a number of times.                                                                                                |
| :_:         | Defines a label of name _.                                                                                                             |
| *_*         | Jumps to a label of name _.                                                                                                            |
| ~_~         | Defines a function of name _.                                                                                                          |
| @_@         | Calls a function of name _.                                                                                                            |
| %           | Ends a function definition.                                                                                                            |
| #_#         | Is a comment.                                                                                                                          |
| [SPACE]     | Is an NOP.                                                                                                                             |
| [NEWLINE]   | Is treated as whitespace and removed.                                                                                                  |
| [TAB]       | Is treated as whitespace and removed.                                                                                                  |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------+

тесты

+0+0+0+0+0+0+0+2)+0+0+9)+7))+3)-0-0-0-0-0-0-0-9)+0+0+0+0+0+0+0+0+7)-8)+3)-6)-8)-7-0-0-0-0-0-0)

Должен выводить Hello world!


+1:i:{()*i*}

Вроде catпрограмма, просто без перевода строки.


+1:loop:{@ReadChar@*loop*}@PrintHello@@WriteAll@(~ReadChar~(x-0-3<2o^1>1+1>1%~PrintHello~+0+0+0+0+0+0+0+2)-1+0+0+0)+7))+3)+1-0-0-0-0-0-0-0-0)%~WriteAll~<1x:reverse:{<1v1>1-1*reverse*}o-1:print:{-1<1)^1>1*print*}%

Сначала следует принять имя, а затем, при нажатии Return, вывести Hello name(где имя - это то, что было введено).

Кредит на эту программу достается Дэвиду Кэтту .


Я работаю над полной тестовой программой.

правила

  • Стандартные лазейки запрещены
  • Ваш переводчик должен соответствовать всем техническим требованиям, кроме комментариев, которые не требуются.

счет

  • Это , поэтому побеждает меньше байтов!
  • -10 байт, если ваш переводчик обрабатывает комментарии.

Leaderboard

Вот фрагмент стека, который генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

# Language Name, N bytes

где Nразмер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

# Ruby, <s>104</s> <s>101</s> 96 bytes

JimBobOH
источник
4
Отличная идея! Вот некоторые мысли: Пожалуйста, определите количество ячеек на подзапись и количество поднаборов, которые мы должны использовать в наших реализациях (или укажите, должен ли он быть каким-то адаптивным / бесконечным). Как преобразовать входную строку в числа 0-255? ASCII коды возможно?
flawr

Ответы:

4

Python2, 748 736 731 709 704 691 байт

Это была небольшая забавная задача, я уверен, что смогу сделать этот код еще короче (возможно, я сделаю это позже).

from sys import*
w=stdout.write
p=open(argv[1],'r').read()
c,r,s,x,y,t,o=0,0,256,0,0,0,0
g=[[0]*s]*s
e=lambda d:p.find(d,c+1)
def h(i,j=0,k=0):global c,x,y;c+=1;n=1+(int(p[c])-1)%10;l=g[x][y]+n*i;g[x][y]=l%s;o=l/s;x=(x+n*j)%s;y=(y+n*k)%s
a="g[x][y]"
b="[p[c+1:i]]"
l={}
f={}
d={'0':a+"=0",'{':"if "+a+"<1:c=e('}')",'(':"i=stdin.read(1);"+a+"=ord(i)if i else 0",')':"w(chr("+a+"))",'x':"t="+a,'o':"w(chr(t))",'!':a+"+=o",'?':a+"=0if "+a+"else 1",'+':"h(1)",'-':"h(-1)",'^':"h(0,1)",'V':"h(0,-1)",'<':"h(0,0,-1)",'>':"h(0,0,1)",':':"i=e(':');l"+b+"=i;c=i",'*':"i=e('*');c=l"+b,'~':"i=e('~');f"+b+"=i;c=e('%')",'@':"i=e('@');r=i;c=f"+b,'%':"c=r"}
while c<len(p):
    if p[c]in d:exec d[p[c]]
    c+=1

Эта реализация требует, чтобы метки и функции были объявлены (реализованы) перед вызовом. Он отлично работает с двумя приведенными тестами, но, к сожалению, не работает с программой «SayHi.2b», написанной автором языка (даже после изменения порядка объявления функций). Я думаю, что эта проблема, возможно, связана с тем, как я понял систему лент и подзаголовков. При перемещении вдоль основной ленты положение на соответствующем подзаголовке сбрасывается в 0? На данный момент я сохраняю позицию на подзаголовке, даже когда двигаюсь по основной ленте.

Вот более читаемая версия:

#!/usr/bin/python

import sys
w=sys.stdout.write
p=open(sys.argv[1],'r').read()
c,r,s,x,y,t,o=0,0,256,0,0,0,0
# c is the current index in the program string
# r is the return index (for functions)
# s is the size of the tape, subtapes and modulo for ints (max int will be 255)
# x and y are the coordinates in the grid
# t is the temporary register
# o is overflow
g=[[0]*s]*s # initialise a grid 256x256 with 0

e=lambda d:p.find(d,c+1)
def n():global c;c+=1;i=int(p[c]);return i if i>0 else 10 # get the number specified
def h(i):j=g[x][y]+i;g[x][y]=j%s;o=j/s # handle addition and substraction
def m(i,j):global x,y;x=(x+i)%s;y=(y+j)%s # move current cell

a="g[x][y]" # string of current cell
b="[p[c+1:i]]" # key for label or function
l={} # dictionary of labels
f={} # dictionary of functions
d={'0':a+"=0",
   '{':"if "+a+"<1:c=e('}')",
   '(':"i=sys.stdin.read(1);"+a+"=ord(i)if i else 0",
   ')':"w(chr("+a+"))",
   'x':"t="+a,
   'o':"w(chr(t))",
   '!':a+"+=o",
   '?':a+"=0if "+a+"else 1",
   '+':"h(n())",
   '-':"h(-n())",
   '^':"m(n(),0)",
   'V':"m(-n(),0)",
   '<':"m(0,-n())",
   '>':"m(0,n())",
   ':':"i=e(':');l"+b+"=i;c=i",
   '*':"i=e('*');c=l"+b,
   '~':"i=e('~');f"+b+"=i;c=e('%')",
   '@':"i=e('@');r=i;c=f"+b,
   '%':"c=r",
   '#':"c=e('#')"
   }

while c<len(p): # loop while c is not EOF
    # print c, p[c]
    if p[c]in d:exec d[p[c]] # execute code kept as a string
    c+=1 # increment index

Изменить: Учитывать обработку комментариев (-10 байт), исправляя отключение одной ошибкой. Эта реализация не поддерживает вызовы вложенных функций (я мог бы реализовать это, если это требуется)

Edit2: изменена функция обработчика для добавления, вычитания и перемещения ячеек. Больше лямбд! : D («более читаемая версия» теперь может быть не синхронизирована)

Edit3: я только что понял, что обработка комментариев стоит мне 5 байтов (с учетом -10). Так что я просто удалил его, жаль, что теперь он кажется неполным.

Edit4: перенес определение n из лямбды в var внутри обработчика h ()

Базиль-генри
источник
с таким количеством +a+может быть лучше присоединиться a? Это также избавило бы вас от необходимости присваивать его переменной.
Maltysen
Ну, за исключением того, что я не могу объединить строки в словаре в целом, и не стоит делать это для каждой строки отдельно. Присвоение строки a - это просто хитрость, чтобы получить несколько байтов, ничего полезного для кода.
Базили-Генри
Я предполагаю, что не могу пожаловаться на порядок функций, так как на самом деле я не указал это, но постараюсь, чтобы SayHi.2bфайл работал. Что произойдет, если его изменить, чтобы сбросить подзапись на ноль за смену?
JimBobOH