2008-08-21 11 views
6

He estado tratando de comprender cómo funcionan los bloques de Ruby, y para hacer eso que he estado tratando de ponerlas en práctica en C.Rubí bloques/cierres de Java en C

Una forma fácil de implementar cierres es pasar a void* a la pila adjunta al cierre/función pero los bloques Ruby también parecen manejar declaraciones de devoluciones y fallas del alcance que usa el bloque.

loop do 
    break i if (i >= 4000) 
    i *= 2 
end 

Creo que una de las propuestas de cierres para Java funciona así también.

Entonces, ¿cómo implementaría Ruby-blocks/Java-closures en C?

+0

"Entonces, ¿cómo implementaría Ruby-blocks/Java-closures en C?" Al menos hasta que se lance Java 7, no hay tal cosa como los cierres de Java. –

+0

Sí, es por eso que dije "propuestas de cierres para Java" justo antes. –

Respuesta

10

El concepto de cierres requiere el concepto de contextos. El contexto de C se basa en la pila y los registros de la CPU, por lo que para crear un bloqueo/cierre, debe ser capaz de manipular el puntero de la pila de una manera correcta (y reentrada), y almacenar/restaurar registros según sea necesario.

La manera en que lo hacen los intérpretes o las máquinas virtuales es tener una estructura context o algo similar, y no usar la pila y registrarse directamente. Esta estructura realiza un seguimiento de una pila y, opcionalmente, algunos registros, si está diseñando una máquina virtual basada en registros. Al menos, esa es la forma más simple de hacerlo (aunque un poco menos eficiente que realmente mapear cosas correctamente).

2

Hay una buena serie de diapositivas sobre el Ruby bloques como parte de los "rieles con pasión" por supuesto:

Ruby_Blocks.pdf

Esto cubre lo que representa un bloque, la forma en que van pasando los argumentos y ejecutados, y aún más en cosas como objetos Proc. Está muy claramente explicado.

Podría ser de interés observar cómo los chicos de JRuby manejaron esto en su análisis a Java. Eche un vistazo a la fuente en codehaus.

3

No he implementado nada de esto, así que tómelo con un poco de sal.

Hay dos partes para un cierre: el entorno de datos y el entorno de código. Como dijiste, probablemente puedas pasar un vacío * para manejar las referencias a los datos. Probablemente podría usar setjmp y longjmp para implementar los saltos de flujo de control no lineales que requiere el salto de Ruby.

Si desea cierres, probablemente deba programar en un lenguaje que realmente los admita. :-)

ACTUALIZACIÓN: Cosas interesantes están sucediendo en Clang. Han creado un prototipo de un cierre para C. http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html podría ser una lectura interesante.