Escribe un intérprete para 2B

12

Escribe un intérprete para 2B

Me gusta el lenguaje esotérico 2B de David Catt , que tiene memoria almacenada en una cinta donde cada celda es una cinta separada de bytes (la 'subtapa'). ¡Escribe un intérprete para ello!

Especificación de idioma

La especificación oficial se puede encontrar aquí . En esta especificación, "significa un número en el rango 0-9( 0se interpreta como 10) y _significa una cadena de cualquier longitud. Cada celda almacena un valor en el rango 0-255, y el desbordamiento / subflujo se ajusta como si fuera un BF. (Gracias @ MartinBüttner). Para convertir texto a números 0-255, use códigos ASCII . Como no puedo encontrar detalles sobre esto, voy a decir que la longitud de la cinta debe ser 255mínima, pero si sabe lo contrario, 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.                                                                                                  |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------+

Pruebas

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

Debe salida Hello world!


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

Una especie de catprograma, simplemente sin una nueva línea.


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

Primero debe aceptar un nombre, luego, al presionar Return, debe salir Hello name(donde nombre es lo que se ingresó).

El crédito para ese programa va para David Catt .


Estoy trabajando en un programa de prueba completo.

Reglas

  • Las lagunas estándar están prohibidas
  • Su intérprete debe cumplir con todas las especificaciones, excepto los comentarios, que no son obligatorios.

Puntuación

  • Este es el , ¡por lo que gana menos bytes!
  • -10 bytes si su intérprete maneja los comentarios.

Tabla de clasificación

Aquí hay un fragmento de pila para generar una tabla de clasificación regular y una descripción general de los ganadores por idioma.

Para asegurarse de que su respuesta se muestre, comience con un título, usando la siguiente plantilla de Markdown:

# Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

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

JimBobOH
fuente
44
¡Gran idea! Aquí algunas reflexiones: defina el número de celdas por subtape y el número de subtapes que debemos usar en nuestras implementaciones (o especifique si debe ser algún tipo de adaptación / infinito). ¿Cómo se debe convertir una cadena de entrada a los números 0-255? ¿Códigos ASCII tal vez?
falla

Respuestas:

4

Python2, 748 736 731 709 704 691 bytes

Este fue un pequeño desafío divertido, estoy seguro de que puedo hacer que este código sea aún más corto (tal vez lo haga en algún momento más adelante).

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

Esta implementación requiere que las etiquetas y funciones sean declaradas (implementadas) antes de ser llamadas. Funciona perfectamente con las dos pruebas dadas, pero desafortunadamente no funciona con el programa "SayHi.2b" escrito por el autor del lenguaje (incluso después de cambiar el orden de declaración de las funciones). Creo que este problema podría tener que ver con la forma en que entendí el sistema de cintas y subcapas. Cuando se mueve a lo largo de la cinta principal, ¿la posición en la subtapa correspondiente se restablece a 0? En este momento mantengo la posición en la subtape incluso cuando me muevo en la cinta principal.

Aquí está la versión más legible:

#!/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: tenga en cuenta el manejo de comentarios (-10 bytes), arreglando un error por un error. Esta implementación no admite llamadas de función anidadas (podría implementarla si es una característica requerida)

Edit2: Cambió la función del controlador para hacer sumas, restas y movimientos de celdas. ¡Más lambdas! : D (La "versión más legible" puede no estar sincronizada ahora)

Edit3: acabo de darme cuenta de que manejar comentarios me cuesta 5 bytes (teniendo en cuenta el -10). Así que lo acabo de quitar, es una pena que ahora se sienta incompleto.

Edit4: movió la definición de n de lambda a var dentro del controlador h ()

basile-henry
fuente
con tantos +a+podría ser mejor unirse a? También se libraría de tener que asignarlo a una var.
Maltysen
Bueno, excepto que no puedo unir las cadenas en un diccionario en su conjunto y no valdría la pena hacerlo para cada cadena por separado. Asignar la cadena a un es solo un truco para ganar algunos bytes, nada realmente útil para el código.
basile-henry
Supongo que no me puedo quejar sobre el orden de las funciones, ya que en realidad no lo especifiqué, pero trato de que el SayHi.2barchivo funcione. ¿Qué sucede si se cambia para restablecer la subtapa a cero en un turno?
JimBobOH