2008-08-21 13 views
6

Próbowałam zrozumieć, jak działają bloki Ruby, a do tego ja już próbuje je realizować w C.Ruby bloki/zamknięcia Java w C

Prostym sposobem wdrożenia zamknięć jest do przekazania a void* do zamykającego stosu do zamknięcia/funkcji, ale bloki Ruby również obsługują zwroty i instrukcje break z zakresu, który używa bloku.

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

Myślę, że jedna z propozycji zamknięcia Java działa również w ten sposób.

A więc, w jaki sposób zaimplementowałbyś bloki Ruby/Java-closures w C?

+0

"Jak więc zaimplementować bloki Ruby/Java-closures w C?" Przynajmniej do czasu wydania Java 7, nie ma czegoś takiego jak zamknięcia Java. –

+0

Tak, właśnie dlatego wcześniej powiedziałem "propozycje zamknięcia dla Javy". –

Odpowiedz

10

Koncepcja zamknięć wymaga koncepcji kontekstów. Kontekst C oparty jest na stosie i rejestrach procesora, więc aby utworzyć blok/zamknięcie, trzeba umieć manipulować wskaźnikiem stosu w prawidłowy (i realny) sposób i przechowywać/przywracać rejestry w razie potrzeby.

Sposób, w jaki jest to wykonywane przez interpreterów lub maszyny wirtualne, ma mieć strukturę context lub coś podobnego, a nie używać stosu i rejestruje się bezpośrednio. Ta struktura śledzi stos i opcjonalnie niektóre rejestry, jeśli projektujesz maszynę wirtualną opartą na rejestrze. Przynajmniej jest to najprostszy sposób, aby to zrobić (choć nieco mniej wydajne niż faktycznie mapowanie rzeczy poprawnie).

2

Jest to dobry zestaw slajdów na Ruby bloków w ramach „Rails z pasją” przedmiotu:

Ruby_Blocks.pdf

ta obejmuje reprezentowanie blok, w jaki sposób przejdzie argumenty i wykonane, a nawet dalej do rzeczy takich jak obiekty Proc. Jest to bardzo wyraźnie wyjaśnione.

Może wtedy zainteresować spojrzenie na to, jak JRuby radzą sobie z tymi w ich parsowaniu do Javy. Spójrz na źródło pod adresem codehaus.

3

Nie wprowadziłem żadnej z tych rzeczy, więc weź to z workiem soli.

Są dwie części zamknięcia: środowisko danych i środowisko kodu. Tak jak powiedziałeś, prawdopodobnie możesz przekazać pustkę *, aby obsługiwać odniesienia do danych. Prawdopodobnie możesz użyć setjmp i longjmp do implementacji nieliniowych skoków sterowania, których wymaga złamanie ruby.

Jeśli chcesz zamknięcia, powinieneś prawdopodobnie programować w języku, który je obsługuje. :-)

AKTUALIZACJA: Ciekawe rzeczy dzieją się w Clangu. Prototypowali zamknięcie dla C. http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html może okazać się interesującą lekturą.