Befunge
Befunge es un lenguaje de programación esotérico, funge-oide, reflexivo y basado en pila. Difiere de los lenguajes convencionales en que los programas están dispuestos en una parrilla bidimensional. Las instrucciones "flecha" dirigen el control de flujo hacia arriba, abajo, izquierda o derecha, y los bucles se construyen dirigiendo el control de flujo en círculo.
Historia
Befunge lo creó Chris Pressey en 1993 en un intento de diseñar un lenguaje tan difícil de compilar como humanamente posible fuera (observe que la orden p
introduce la posibilidad de código mutante). Sin embargo se han escrito varios compiladores. También existen varias extensiones a la especificación original "Befunge-93", incluido Funge-98, que extiende el concepto a un número arbitrario de dimensiones y admite múltiples hebras de ejecución, con varios punteros de instrucción operando simultáneamente en el mismo espacio. Las extensiones y variantes de Befunge se denominan Fungeoides o simplemente Funges.
La especificación Befunge-93 restringe cada programa válido a una parrilla de 80*25 instrucciones (horizontal y vertical, respectivamente). Si la ejecución de un programa excede estos límites, "salta" a un punto correspondiente en el otro lado de la parrilla; así, un programa en Befunge es el equivalente topológico de un toro. Dado que un programa en Befunge-93 sólo puede tener una pila y tiene limitado su espacio de almacenamiento, el lenguaje Befunge-93 no es Turing completo, al contrario que la mayoría de lenguajes de máquina. La especificación posterior Funge-98 proporciona Turing-completitud eliminando las restricciones de tamaño del programa: en lugar de simplemente saltar a un punto opuesto en un límite fijo, el movimiento de un puntero de instrucciones Funge-98 sigue un model denominado "espacio de Lahey" en honor a su creador, Chris Lahey. En este modelo, la parrilla se comporta como un toro de tamaño finito con respecto a estos saltos, pero puede ser extendido de forma indefinida.
Código de ejemplo en Befunge-93
Mostramos la técnica de usar flechas para cambiar el control de flujo en el siguiente programa generador de números aleatorios. Siguiendo las flechas, las instrucciones ?
envían el puntero de instrucciones en direcciones cardinales aleatorias hasta que el puntero da con un dígito, introduciéndolo en la pila. Entonces las flechas navegan hasta el .
para extraer el dígito de la pila y devolver el puntero al primer aleatorizador direccional. Observe que no hay código @
para terminar este programa, así que produce números aleatorios de 1 a 9 de forma continua.
vv < < 2 ^ v< v1<?>3v4 ^ ^ > >?> ?>5^ v v v9<?>7v6 v v< 8 . > > ^ ^<
Este es un ejemplo del clásico programa "¡Hola mundo!". Primero se introducen en la pila las letras "olleH" como números ASCII. Luego se extraen de la pila en orden LIFO y se muestran como caracteres de texto para dar "Hello". El espacio es el carácter 32 en ASCII, que aquí se construye multiplicando 4 por 8, antes de comenzar la salida de texto. El resto del código muestra de forma similar "World!", seguido del carácter ASCII 10 (un salto de línea).
> v v ,,,,,"Hello" < >48*, v v,,,,,,"World!"< >25*,@
Lista de instrucciones para Befunge-93
0-9
|
Introduce este número en la pila |
+
|
Suma: Extrae a y b, e introduce a+b |
-
|
Resta: Extrae a y b, e introduce b-a |
*
|
Multiplicación: Extrae a y b, e introduce a*b |
/
|
División entera: Extrae a y b, e introduce b/a, redondeado a la baja. Si a es cero, pregunta al usuario qué resultado desea. |
%
|
Módulo: Extrae a y b, e introduce el resto de la división entera b/a. Si a es cero, pregunta al usuario qué resultado desea. |
!
|
NOT lógico: Extrae un valor. Si es cero, introduce 1; si no, introduce cero. |
`
|
Mayor que: Extrae a y b, e introduce 1 si b>a, o cero en caso contrario. |
> |
Comienza a moverse a la derecha |
< |
Comienza a moverse a la izquierda |
^ |
Comienza a moverse hacia arriba |
v |
Comienza a moverse hacia abajo |
?
|
Comienza a moverse en una dirección aleatoria |
_
|
Extrae un valor; se mueve a la derecha si valor=0, o a la izquierda si no |
|
|
Extrae un valor; se mueve hacia abajo si valor=0, o hacia arriba si no |
"
|
Empieza el modo cadena: introduce cada carácter ASCII hasta que encuentre el siguiente "
|
:
|
Duplica el valor en la cima de la pila |
\
|
Intercambia los dos valores en la cima de la pila |
$ |
Extrae un valor de la pila |
.
|
Extrae un valor y lo muestra como entero |
,
|
Extrae un valor y lo muestra como carácter ASCII |
# |
Trampolín: Omite la siguiente celda |
p
|
Una llamada "put" (una manera de almacenar un valor para uso posterior). Extrae y, x y v, y cambia el carácter en la posición (x, y) del programa por el carácter con el valor ASCII v |
g
|
Una llamada "get" (una manera de recuperar datos almacenados). Extrae y y x, y luego introduce el valor ASCII del carácter que se encuentra en esa posición en el programa |
&
|
Solicita un número al usuario y lo introduce en la pila |
~
|
Solicita al usuario un carácter e introduce su valor ASCII |
@ |
Fin de programa |
Véase también
Enlaces externos
- Especificación oficial Funge-98 Archivado el 25 de diciembre de 2004 en Wayback Machine.
Implementaciones
- Cat's Eye Technologies
- {{}}
- Otro intérprete más para Befunge93 (Intérprete de Befunge93 de fuente abierta, escrito en java)
- Sitio oficial del intérprete Rc/Funge-98
- Language::Befunge Módulo Perl en CPAN que interpreta Befunge-98 (en inglés)
- Language::Befunge::Debugger Depurador gráfico de Befunge escrito en Perl (en inglés)
- Inline::Befunge Módulo Perl en CPAN para insertar código Befunge dentro de Perl (en inglés)