Diseñé un lenguaje en el que la aritmética de punteros es la herramienta principal de programación.
Aquí hay unos ejemplos.
(print 0 to 8)
=9[>1=9-*-1.>-1-1]
(print 1 to 10 with spaces in between, character literal extension used)
=1[.>1=10-*-1[>1=' '!>-2+1;-2];1]='\n'!
(compute the factorial of 10)
=10>1=*-1-1[>-1**1>1-1]>-1.
(print "hi")
=104!=105!
(print "hi" with extension for arrays)
={104,105,0}[!>1]
(print "Hello, world!" with extension for C-style string literals)
="Hello, world!"[!>1]
Especificación de idioma
La definición del lenguaje es muy simple. Comprenderá muy fácilmente si tiene experiencia con C, pero no supondré que sí.
Cada programa tiene en PointerLang el puntero , en definitiva, P
. Puede pensarlo como una variable global única oculta, que puede controlar mediante el uso de comandos . P
inicialmente apunta al comienzo de la matriz . Cada elemento de la matriz tiene el tipo int
que es un entero con signo de 32 bits.
Para programadores en C
int32_t *P = malloc(1000);
En PointerLang, hay comandos y argumentos . Un argumento es el int
que debe venir después de un comando. Todos los comandos se ejecutan de izquierda a derecha a menos que se especifique lo contrario. La siguiente es la lista de comandos. A
significa argumento. Un comando sin A
medios no toma un argumento. Un comando con A
debe tomar una discusión. Dentro de los paréntesis está la expresión C equivalente.
=A
: asigne A en P (*P = A
)+A
: agregue A en P (*P += A
)-A
: restar A en P (*P -= A
)*A
: multiplicar por A en P (*P *= A
)/A
: dividir por A en P (*P /= A
)>A
: moverseP
porA
(P += A
).
: imprime el entero en P (printf("%d", *P)
)!
: imprime el entero en P como ASCII (printf("%c", (char)*P)
)[
: si el valor en P es 0, vaya al comando después del siguiente]
(while (*P) {
)]
: vaya al anterior[
que es el par coincidente (}
);A
: SiA
es positivo, ir a la orden después de laA
XX]
viene a continuación; siA
es negativo, ve alA
th que[
viene antes; Si A es 0, no haga nada.
Un literal entero es un argumento.
Los siguientes dos son argumentos especiales que toman un argumento.
-A
: evaluado como un argumento que tiene el mismo valor absoluto queA
y el signo opuesto deA
; unario menos*A
: MoverP
porA
, evaluar el valor aP
, moverP
por-A
(P[A]
)
Todos los comentarios en PointerLang están entre paréntesis (comment)
.
Programa de ejemplo
Este programa que cuenta del 1 al 10 es un buen ejemplo para completar su comprensión.
(print 1 to 10 with spaces in between)
=1[.>1=10-*-1[>1=32!>-2+1;-2];1]=10!
Ten cuidado cuando interpretes -*-1
. -
es el comando y *-1
es el argumento. Un literal entero indica efectivamente el final de un par comando-argumento.
Se puede traducir a C con correspondencia 1 a 1 como
int main(void) {
int32_t *P = malloc(1000);
*P = 1; // =1
l:
while (*P) { // [
printf("%d", *P); // .
P += 1; // > 1
*P = 10; // =10
*P -= P[-1]; // -*-1
while (*P) { // [
P += 1; // >1
*P = 32; // =32
printf("%c", (char)*P); // !
P += -2; // >-2
*P += 1; // +1
goto l; // ;-2
} // ]
break; // ;1
} // ]
*P = 10; // =10
printf("%c", (char)*P); // !
return 0;
}
Las extensiones se pueden aplicar a este lenguaje, como literales de caracteres, matrices, literales de cadena, etc., pero no tiene que implementarlas, por simplicidad.
El reto
Debe implementar las funciones principales detalladas en la sección de Especificación de idioma y las NOTAS a continuación. Pruébalo con tu lenguaje de programación favorito, escribiendo el programa más corto posible.
NOTA1: el tamaño de la matriz no está definido. Pero debería ser lo suficientemente grande como para resolver la mayoría de los problemas.
NOTA2: El desbordamiento de enteros no está definido.
NOTA3: La especificación solo define el resultado o efecto de ciertas construcciones de lenguaje. Por ejemplo, no tiene que seguir exactamente los pasos en la definición del argumento *
.
NOTA 4: se ignoran los caracteres que no sean comandos, argumentos o comentarios . =104!=105!
es igual que = 1 0 4! = 1 05 !
por ejemplo.
NOTA5: Los comentarios no están anidados. ((comment))
es un error de sintaxis
NOTA 6: He realizado un cambio importante para arreglar un agujero en mi idioma. El ~
comando ahora no se usa y ;
siempre toma un argumento.
NOTA 7: Cada literal entero es decimal.
fuente
=9[>1=9-*-1.>-1-1]
imprime de 0 a 9? Después de que pone 8 porque P [0] = 1, luego resta 1 justo antes del final del bucle, lo que hace que P [0] = 0 y luego, cuando comienza el bucle nuevamente, debería salir porque P [0] = 0, entonces ejemplo solo debería imprimir de 0 a 8. ¿O estoy realmente confundido?Respuestas:
C 413
Gracias a @ceilingcat por algunas bonitas piezas de golf, ahora incluso más cortas
Pruébalo en línea!
y la versión un poco menos golfizada de mi respuesta original:
fuente
switch(...){case'(':...case'.':...
conj=='('?...:j=='.'?...
y refactorizado llamadas a funciones para encajar dentro del operador ternario.