Escreva um intérprete para 2B

12

Escreva um intérprete para 2B

Gosto da linguagem esotérica 2B de David Catt , com memória armazenada em uma fita em que cada célula é uma fita separada de bytes (a 'subtape'). Escreva um intérprete para ele!

Especificação de idioma

Especificações oficiais podem ser encontradas aqui . Nesta especificação, "significa um número no intervalo 0-9( 0é interpretado como 10) e _significa uma sequência de qualquer comprimento. Cada célula armazena um valor no intervalo 0-255e o transbordamento / transbordamento envolve como um BF. (Obrigado @ MartinBüttner). Para converter texto em números 0-255, use códigos ASCII . Como não encontro detalhes sobre isso, vou dizer que o comprimento da fita deve ser 255mínimo, mas se você souber o contrário, edite.

+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
| 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.                                                                                                  |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------+

Testes

+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)

Saída Hello world!


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

Tipo de catprograma, apenas sem uma nova linha.


+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*}%

Primeiro, você deve aceitar um nome e, ao pressionar Return, deve sair Hello name(onde nome é o que foi inserido).

O crédito para esse programa vai para David Catt .


Estou trabalhando em um programa de teste completo.

Regras

  • As brechas padrão são proibidas
  • Seu intérprete deve atender a todas as especificações, exceto comentários, que não são necessários.

Pontuação

  • Isso é , e o menor número de bytes vence!
  • -10 bytes se o seu intérprete manipular comentários.

Entre os melhores

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

JimBobOH
fonte
4
Boa ideia! Aqui estão alguns pensamentos: Defina o número de células por subtape e o número de subtapes que devemos usar em nossas implementações (ou especifique se deve ser algum tipo de adaptação / infinito). Como uma sequência de entrada deve ser convertida nos números 0-255? Códigos ASCII, talvez?
perfil completo de Flawr

Respostas:

4

Python2, 748 736 731 709 704 691 bytes

Esse foi um pequeno desafio divertido, tenho certeza de que posso tornar esse código ainda mais curto (talvez faça isso mais tarde).

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

Essa implementação requer que rótulos e funções sejam declarados (implementados) antes de serem chamados. Ele funciona perfeitamente com os dois testes fornecidos, mas infelizmente não funciona com o programa "SayHi.2b", escrito pelo autor do idioma (mesmo depois de alterar a ordem de declaração das funções). Acho que esse problema pode ter a ver com a maneira como entendi o sistema de fita e subtape. Ao se mover pela fita principal, a posição na subtape correspondente é redefinida para 0? No momento, estou mantendo a posição na subtape mesmo quando movo a fita principal.

Aqui está a versão mais legível:

#!/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

Editar: leve em consideração a manipulação de comentários (-10 bytes), corrigindo um erro por um erro. Esta implementação não suporta chamadas de função aninhadas (eu poderia implementá-la se for um recurso necessário)

Edit2: Alterada a função do manipulador para fazer adição, subtração e movimento da célula. Mais lambdas! : D (a "versão mais legível" pode estar fora de sincronia agora)

Edit3: Acabei de perceber que lidar com comentários me custa 5 bytes (levando em conta o -10). Acabei de removê-lo, é uma pena que agora pareça incompleto.

Edit4: definição movida de n de lambda para var dentro do manipulador h ()

basile-henry
fonte
com tantos +a+, seria melhor participar a? Também eliminaria a necessidade de atribuí-lo a um var.
Maltysen
Bem, exceto que não posso juntar as strings em um dicionário como um todo e não valeria a pena fazer isso para cada string separadamente. Atribuir a string a é apenas um truque para obter alguns bytes, nada realmente útil para o código.
basile-henry
Acho que não posso reclamar da ordem das funções, pois na verdade não especifiquei isso, mas tente fazer o SayHi.2barquivo funcionar. O que acontece se for alterado para redefinir a subtape para zero em um turno?
precisa saber é o seguinte