¡Tienes que escribir un intérprete para un lenguaje genial llamado Chicken !
Debería leer un programa Chicken de un archivo, entrada estándar, argumentos de programa o función, o lo que sea más conveniente para su idioma, así como la entrada al programa.
Debe imprimir o devolver el resultado de interpretar el programa de acuerdo con las especificaciones del lenguaje Chicken.
Más descripción sobre el idioma .
Descripción general del programa de pollo
Chicken opera en una sola pila, que compone todo su modelo de memoria. A medida que se ejecutan las instrucciones, el programa empujará y extraerá valores de la pila, pero también hay instrucciones que permiten que el programa modifique otras partes de la pila a voluntad.
Hay tres segmentos en la pila:
- Los registros, en los índices 0 y 1. El índice 0 es una referencia a la pila misma, y el índice 1 es una referencia a la entrada del usuario. Principalmente utilizado para la instrucción 6 (ver más abajo).
- El código cargado: para cada línea de código hay una celda en este segmento que contiene el número de "gallinas" en la línea. Esto se rellena con un 0 (código de operación para terminar el programa) al final.
- La pila de programas real, donde los valores se empujan / reventan a medida que se ejecuta el programa. Tenga en cuenta que los segmentos no están aislados, lo que significa que es posible crear código auto modificable o ejecutar código desde este segmento del espacio de la pila.
El pollo ISA
El conjunto de instrucciones de Chicken se basa en la cantidad de veces que aparece la palabra "pollo" en cada línea del programa. Una línea vacía termina el programa e imprime el valor más alto en la pila.
El conjunto de instrucciones Chicken, por número de "pollo" por línea:
- Empuje la cadena literal "pollo" a la pila
- Agregue los dos valores superiores de la pila como números naturales y empuje el resultado.
- Resta los dos valores superiores como números naturales y empuja el resultado.
- Multiplique los dos valores superiores como números naturales y presione el resultado.
- Compare dos valores superiores para la igualdad, presione 1 si son iguales y 0 en caso contrario.
- Mire la siguiente instrucción para determinar desde qué fuente cargar: 0 cargas de la pila, 1 cargas de la entrada del usuario. Parte superior de los puntos de pila para direccionar / indexar para cargar desde la fuente dada; cargar ese valor y empujarlo a la pila. Como se trata de una instrucción de doble ancho, el puntero de instrucción omite la instrucción utilizada para determinar la fuente.
- Parte superior de los puntos de la pila a la dirección / índice para almacenar. El valor a continuación aparecerá y se almacenará en la pila en el índice dado.
- La parte superior de la pila es un desplazamiento relativo para saltar. Si el valor debajo de eso es verdadero, entonces el programa salta por el desplazamiento.
- Interpreta la parte superior de la pila como ascii y empuja el personaje correspondiente.
- (10 + N) Inserta el número literal n-10 en la pila.
Ejemplo
Suponga que el programa es:
chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken
chicken chicken chicken chicken chicken chicken
(an empty line)
(Un programa de gato. Tenga en cuenta que la línea vacía es necesaria debido a que la línea anterior tiene 6 "pollo").
Aporte proporcionado al programa Chicken
Chicken
Salida
Chicken
La implementación de referencia de Chicken.js .
Detección de errores
El intérprete debe dejar un error y finalizar cuando cualquier palabra que no sea "pollo" esté presente en la fuente.
¡Buena suerte!
fuente
Respuestas:
Rubí, 335 bytes
Toma el nombre del archivo de entrada como un argumento de línea de comando y toma la entrada del usuario (para la instrucción # 6) de STDIN.
Debido a que la "verdad" de Ruby (todo excepto
false
ynil
) es diferente de la "verdad" de Javascript (Ruby verdad más0
, cadenas vacías, etc.), puede haber algunos casos extremos donde los programas que funcionan bien en un intérprete JS fallan en este debido a la instrucción # 8, como si""
está en la pila. Sin embargo, he arreglado el caso más grande, que es falso0
.Funciona con el programa de prueba y el programa Hello World en el sitio web de Chicken.
Explicación
El intérprete comienza inmediatamente ejecutando una coincidencia de expresiones regulares
/^(chicken|\s)*$/m
contra todo el archivo ($<.read
), lo que garantiza que el archivo no contenga más que unchicken
espacio en blanco. En Ruby, este operador devuelve el índice de la coincidencia, onil
si no se encontró.Aquí se usan dos trucos para guardar bytes: en lugar de coincidir directamente
chicken
, el operador de sustitución de cadenas#{}
se usa en su lugar para asignar también esa cadena a una variable para más adelante (guarda 1 byte) y al almacenar el contenido del archivo en una variable para procesar , agrega dos líneas nuevas para permitir que lalines
función luego agregue naturalmente un extra0
al final del conjunto de instrucciones. (Se necesitan dos debido a la nueva línea final ignorada, que es necesaria para el programa Chicken).El error utilizado es
NoMethodError: undefined method '+@' for nil:NilClass
, que se realiza envolviendo la coincidencia de expresiones regulares en parens y colocando un+
frente. Si el archivo coincide con el patrón, obtienes+0
, que se evalúa0
y continúa normalmente.A continuación, se ensambla la pila. La lista inicial debe crearse antes de que se pueda asignar la autorreferencia a la pila, de modo que se use un marcador de posición y luego se reemplace. El puntero de instrucción se establece en
1
lugar de2
porque los operadores posteriores al incremento no existen en Ruby.Finalmente, usa el truco lambda de @BassdropCumberwubwubwub para determinar qué empujar en la pila a continuación. Si una operación no introduce nada en la pila, el intérprete simplemente muestra un valor adicional para que la pila permanezca igual. (Esto ahorra bytes al agregar una operación de inserción en cada lambda).
Código sin golf:
fuente
Javascript ES6, 398 bytes
Con mucho, el golf más largo que he hecho, estoy seguro de que esto se puede mejorar, pero mi cerebro no reconoce nada más que
chicken
en este momento.Editaré la explicación cuando mi cerebro comience a funcionar nuevamente. Aquí hay una versión ungolfed por ahora.
Emite un valor falsey (0) para todo lo que no es
chicken
Pruébalo aquí
fuente
if(!/^(chicken\s?)+$/.test(a))throw'There are any words except "chicken".';
justo al comienzo de su intérprete.stderr
o salir del programa con un código distinto de cero. Algo que muestra que algo no está bien. En Javascript, puede lanzar una excepción, devolver un objeto Error, mostrar una alerta, escribir en la consola usandoconsole.erro()
o algo similar.