Hay muchos desafíos que dicen "interpretar X", donde X es un lenguaje simple. En mi opinión, eso es demasiado aburrido. Para darle a todas las personas que postergan las cosas en Internet algo interesante que hacer, puede intentar hacer este desafío:
Reto
Elige un idioma $LANG
. $LANG
puede ser cualquier lenguaje de programación completo o un subconjunto completo de un lenguaje de programación. Tenga en cuenta que si omite una característica de su idioma $LANG
para la interpretación, no debe usarla para su propio programa, ya que su presentación también debe estar escrita $LANG
.
Escriba un compilador / intérprete para $LANG
escrito $LANG
. Puede utilizar todas las facilidades (incluidos eval
y amigos) de su idioma que están disponibles para escribir este compilador. Para hacer la tarea más desafiante, hay una restricción: su programa debe ser capaz de interpretar / compilar todos los programas válidos, $LANG
excepto su propio intérprete / compilador. Si ocurre que el programa a interpretar / compilar es su propio intérprete o compilador (independientemente del nombre del archivo), su programa debe hacer algo completamente ajeno a la funcionalidad de un intérprete o compilador (como barfing o impresión Hello, world!
).
Para hacer esta tarea aún más compleja, su programa no debe leer su propia fuente al compilar o interpretar.
Presupuesto
- Esta tarea es el código de golf. La presentación con la menor cantidad de caracteres que es correcta gana. En caso de empate, la solución que se presentó primero gana.
- Su programa / script debe leer el programa para ser interpretado desde un archivo. Puede codificar su ruta y nombre. Cuando se lee el archivo, puede compilar el archivo en otro archivo (que debe ser ejecutable en su sistema) o ejecutarlo directamente. Si
$LANG
carece de capacidades de lectura de archivos, puede elegir otra forma de leer el código que se ajuste$LANG
. No puede elegir$LANG
como un subconjunto de otro idioma pero con las capacidades de lectura de archivos eliminadas. - Se aplican las reglas habituales de código de golf. Es decir: su lenguaje personal de mascotas que creó solo para resolver este desafío está prohibido, si la solución se vuelve trivial al usarlo (como definir un programa de un solo carácter que implemente exactamente la solución). Se alienta el abuso de las reglas.
fuente
Respuestas:
Rubí, 63
fuente
Perl, 89 caracteres, sin trampas
Tenga en cuenta que este código es extremadamente exigente con lo que cuenta como "en sí mismo". En particular, no se reconocerá si hay líneas nuevas u otros espacios en blanco adicionales en la entrada. Para probarlo, guárdelo en un archivo llamado (por ejemplo)
unquine.pl
y haga esto:Recuerde, el
unquine.pl
archivo debe tener exactamente 89 bytes de longitud, ni más ni menos. Ejecutarlo con algún otro script Perl como entrada solo ejecuta el otro script, como debería:Como su nombre podría sugerir, la implementación se basa en una quine, específicamente, esta:
Este código se establece
$_
igual a sí mismo; el resto del programa (que, por supuesto, debe duplicarse en el interior$_
) simplemente se compara$_
con la entrada, muere si coinciden y evalúa la entrada de otra manera.fuente
&&
/;
par con un ternario (un carácter apagado, duplicado por comillas). ¡Gran idea e implementación!GolfScript, 30 caracteres
Este programa lee el contenido de un archivo nombrado en la línea de comando y, si no coincide exactamente con el código anterior, lo interpreta como GolfScript. Si la entrada es exactamente igual al código anterior, simplemente se imprimirá sin cambios (excepto por una nueva línea adjunta al final).
Esta es una adaptación bastante sencilla de este programa de autoidentificación . Específicamente:
{ }
es un literal de bloque de código en GolfScript..~
, aplicado a un bloque de código, duplica el bloque y ejecuta la copia.Dentro del bloque de código:
`
stringifica la copia del bloque de código.".~"+
le agrega los caracteres.~
, produciendo una cadena que contiene el código fuente del programa."#{$<.read}"
es un hack documentado que permite la ejecución de código Ruby dentro de GolfScript. En este caso, ejecuta la instrucción Ruby$<.read
(robada descaradamente de la solución Ruby de Lowjacker ), que lee y devuelve el contenido de cualquier archivo especificado en la línea de comando. Este truco es necesario porque GolfScript en sí no proporciona capacidades explícitas de E / S de archivos..@
duplica y baraja los elementos en la parte superior de la pila para que la pila contenga dos copias del contenido del archivo seguido del código fuente de este programa.=!
compara los dos primeros elementos de la pila (es decir, el contenido del archivo y la fuente), devolviendo 1 si son diferentes y 0 si son iguales.{~}*
evalúa la copia restante del contenido del archivo como código GolfScript, pero solo si el resultado de la comparación es 1. (Técnicamente, ejecuta el bloque de código{~}
tantas veces como lo indica el número en la pila, es decir, 0 o 1 veces. el bloque,~
es el operador eval de GolfScript).PD. Si se permite leer el código para ejecutar desde stdin, este desafío se puede resolver en 21 caracteres sin tener que pagarle a Ruby:
Este programa leerá una cadena de entrada de stdin y, si no coincide con su propia fuente, la ejecuta (con una entrada vacía). Al igual que el programa anterior, la entrada que coincide con la fuente simplemente se repite.
fuente
Python,
167130118 bytesEste es mi primer intento de jugar golf, así que aquí va! Interpreta cualquier programa excepto él mismo
Versión mejorada:
Si se pone a sí mismo, entonces vomita con:
Creo que esta solución funciona casi de la misma manera que la de Ilmari Karonen, la idea básica es algo así como:
La quine que utilicé se basó en esta:
Pero desde entonces me di cuenta de que una quine mucho más corta es:
Y eso puede ser aún más corto si permite el shell interactivo de Python, en cuyo caso puede hacer:
Como Python no tiene una forma corta de obtener argumentos de línea de comando, utilicé raw_input () (que todavía es bastante largo, pero no tanto como
El uso es:
o
Encontré una quine más corta para usar, pero aquí está mi versión anterior (para la posteridad):
fuente
No puedo leer exactamente de un archivo usando Javascript (ok, podría hacerlo, usando el archivo HTML5 FileReader, pero eso hace las cosas mucho más complicadas de lo que necesito). Entonces, esta es una función que acepta un programa Javascript como una cadena y lo ejecuta.
Esto probablemente no sea tan golfístico como podría ser, pero aquí está de todos modos:
Javascript, 252
Avíseme si alguien conoce una mejor técnica para formar una quina en Javascript.
fuente
45 caracteres de sh (shell POSIX). El código a ejecutar debe estar en el archivo
./c
.El código para el propio intérprete debe estar en el archivo
./p
, así que supongo que hice trampa, aunque el desafío no parece prohibirlo. ¿O esto descalificaría mi "lenguaje" de ser un "lenguaje de programación completo"?Usando una herramienta que normalmente es un ejecutable externo, pero que en teoría podría integrarse en el shell, el código se puede acortar:
Son 18 caracteres, y el
-s
bit es solo para suprimir una línea que de otra manera siempre se imprimiría para programas válidos (no propios).Y luego siempre puede construir una versión del lenguaje de shell que haga lo anterior con una sintaxis más concisa.
Y luego siempre puedes construir un programa que, cuando la entrada consiste en un solo '.' --o demonios, la cadena vacía-- evalúa el contenido de otro archivo como código normal, y llama a esto un lenguaje de programación. Entonces, la cadena vacía sería su solución al desafío, en el lenguaje que creó. De hecho, aquí hay un intérprete para tal lenguaje:
Usando el lenguaje que interpreta el script anterior, la solución es la cadena vacía. Y la ubicación del código ya no necesita ser codificada.
¿Problema?
fuente
./othercode
), y lo hace nada cuando el código es la cadena vacía. No debería haber llamado al archivo ./othercode, es engañoso; es solo el código que interpretará el intérprete escrito en el lenguaje de cadena vacío.JavaScript, 135 caracteres
La solución JavaScript de Peter Olson me inspiró a intentar portar mi solución Perl a JS. Al igual que su solución, este código define una función
c
que acepta una cadena y la evalúa si no es igual al código anterior.Me tomó un tiempo para averiguar una manera buena para hacer frente a la ausencia de delimitadores de cadenas equilibradas en JavaScript, hasta que encontré lo que en retrospectiva es la solución obvia:
unescape()
.Convenientemente, mi código no contiene barras invertidas ni comillas dobles, por lo que puede almacenarse de manera segura en cadenas de comillas dobles. Esto facilita la prueba:
fuente
alert()
con0
para que no haga nada en lugar de alertarundefined
y guardar 13 caracteres.p=>...
lugar defunction c(p)
Lisp común, 59
sbcl --load
)L
, que puede compilar archivos Common Lisp(L <your file>)
, se señala un error mientras lee el archivo.¿Por qué?
Porque la primera vez, introdujo la
:~
palabra clave*features*
. Ahora, su entorno conoce la~
característica, y la macro del lector#+
, al evaluar la~
expresión de la característica , tendrá éxito y leerá el siguiente formulario en lugar de omitirlo como lo hizo la primera vez. En su archivo, el siguiente formulario es#.(#:a)
, que pide evaluar(#:a)
en tiempo de lectura y usar el valor resultante como el código que se está leyendo. Pero(#:a)
llama a la función asociada con el símbolo no interno#:a
. Como no#:a
está conectado, es un símbolo nuevo que no está vinculado a ninguna función (es decir, nofboundp
). Error.fuente
Esquema, 48 o 51 caracteres.
Scheme es un lenguaje con muchas implementaciones diferentes. A pesar de que las implementaciones tienen que ajustarse al último RnRS, el último estándar de trabajo (R6RS) ha sido impopular debido a su falta de minimalismo. El R7RS pronto se lanzará como un remedio, mientras divide el lenguaje en 2. El primer lenguaje es potente y minimalista y el segundo, un superconjunto del primero destinado a proporcionar extensiones de características para la interoperabilidad entre implementaciones. Hasta entonces, confiamos en los SRFI (Solicitudes de esquema para la implementación), que proporcionan (si se implementa en la implementación del host o manualmente (como es común en el esquema)) un medio para llevar a cabo tareas comunes de manera portátil. Todo esto para decir que el primer fragmento de código (51 caracteres), aunque sigue siendo lo más portátil posible, se basa en SRFI-22 (ejecución de scripts de esquema en UNIX) para acceder a los argumentos de la línea de comandos:
o más legible:
El segundo (48 caracteres) es un medio de interpretación sin archivo que no puede evaluarse a sí mismo (en un entorno nulo):
o más legible:
fuente
Groovy, 13 bytes
Esto debería interpretar un subconjunto de Groovy.
Casos de prueba:
Desafortunadamente, aunque ciertamente irrita, lo hace de una manera completamente similar a la de un intérprete, y lo hace por una gran cantidad de información.
fuente
Javascript ES6, 45 bytes
Sigue siendo competitivo! (gracias @Downgoat)
fuente