2015-05-22 9 views

Odpowiedz

3

Upraszczanie Common Lisp's go na inne języki goto jest, za dużo uproszczenia.

W Common Lisp, go można rozwinąć stos. Na przykład:

(tagbody 
    (mapC#'(lambda (el1 el2) 
       (format t "el1: ~a, el2: ~a~%" el1 el2) 
       (when (or (null el1) (null el2)) 
       (go stop))) 
      list1 
      list2) 
    stop) 

Jeśli realizacji Common Lisp w kategoriach C, a następnie non-odwracanie go może być regularne goto, ale odwracanie go wymaga setjmp/longjmp lub równoważną funkcjonalność, z właściwego stosu odwijania , a następnie w razie potrzeby regularny goto, tj. w przypadku, gdy oznakowana forma Lisp nie jest zdaniem C ani wyrażeniem po setjmp.

Prawdopodobnie będziesz chciał skorzystać z obsługi wyjątków systemu operacyjnego, jeśli możesz pozwolić sobie na abstrahowanie czasu. Może się lepiej opłacić, jeśli później chcesz zintegrować się z funkcjami innych języków, takimi jak wyjątki C++, a platforma może już mieć stos procedur obsługi, dzięki czemu automatycznie oczyszcza formularze do określonej klatki stosu.

Jeśli chcesz zachować to przenośne przy minimalnym wysiłku można zarządzać stos wątku lokalnego z setjmp kontekstach gdzie longjmp najnowszego kontekście wystarczającej ilości informacji, aby utrzymać longjmp ing maksymalnie właściwym kontekście, bieganie unwind-protect czyste -up formularze w całym tekście. W ten sposób możesz nadal korzystać z możliwości obsługi wyjątków platformy, ale tylko do konfiguracji odwijania ramek z/do połączeń zagranicznych.

3

Z punktu widzenia realizacji, jeśli jesteś interpretacji Lisp podobny program, można zrobić coś trochę tak:

  • Po wprowadzeniu tagbody, zaczynają tabelę miejsc. (Mapa par symboli → adres)
  • Iteracja każdy formularz w tagbody
  • if (symbolp this-element) i przechowywać adres (wskaźnik do tej postaci) do tabeli
  • inaczej (eval this-element) jak zwykle
  • Po napotkaniu formularz go, wyszukaj symbol miejsca docelowego i (niszcząco) zmień wskaźnik programu "aktualna instrukcja" na tę wartość. Następnie przejdź do rutyny, aby pobrać następną instrukcję.
  • Po opuszczeniu tagbody po prostu odrzuć tabelę docelową.

Tabele docelowe (docelowo) muszą być stosami (określonymi w starszej dokumentacji Lisp jako "lista rozwijana" lub PDL), ponieważ będziesz wyszukiwać w górę za pomocą zakresu dynamicznego, aby znaleźć tag w pytaniu. Należy pamiętać, że w Common Lisp, go znaczniki są osobną przestrzenią nazw ze zmiennych, funkcji, klas i innych.

@jlahd ma poprawne działanie, jest identyczne z (w ograniczonym zakresie) goto w C, ale jeśli interpretujesz kod, faktycznie nadpisujesz wskaźnik "licznika programu" zapisaną wartością.