Jak mogę zmodyfikować czytnik Elisp?

12

Modyfikacja czytnika pozwoliłaby na wprowadzenie nowej składni odczytu (takiej jak #(hash table)i '(quoted)). Wiele Lisps ma taką możliwość, ale wydaje się, że nie ma takiej możliwości dla elisp.

Sean Allred
źródło
Zhakuj źródła C.
wasamasa,
3
Emacs Lisp nie ma czytnika programowalnego w Lisp.
Drew
@wasamasa Cóż, to zawsze jest opcja :) Nie przenośna , ale opcja.
Sean Allred
Myślę, że „wielu Lispsów ma to”. nie jest faktycznym pytaniem. Wolałbym mieć prawdziwe pytanie. Sugeruję skrócenie tytułu i sformułowanie go w ciele.
YoungFrog,
@YoungFrog wprowadza zmiany mile widziane. Nie mogłem wymyślić nic bardziej bezpośredniego lub odpowiedniego bez nadmiernego niepokoju. Pytanie jest proste; nie musi być długo.
Sean Allred,

Odpowiedzi:

11

Okazuje się, że instrukcja sugeruje, że nie można tak naprawdę robić makr czytników.

Zgodnie z dodatkiem C Porting Common Lisp :

Makra czytelników. Common Lisp zawiera drugi typ makra, który działa na poziomie pojedynczych znaków. Na przykład Common Lisp implementuje notację cytatu przez makro czytelnika o nazwie ', podczas gdy parser Emacsa Lispa traktuje cytat jako szczególny przypadek. Niektóre pakiety Lisp używają makr czytników, aby tworzyć dla siebie specjalne składnie, których parser Emacsa nie jest w stanie odczytać.

Dan
źródło
Myślę, że chodzi tu o oprogramowanie Common Lisp, które używają specjalnych makr czytających, a nie Elisp. Strona dotyczy przeniesienia kodu CL na Elisp. I tak, oficjalnie czytnika nie można dostosowywać, ale zobacz moją odpowiedź poniżej ...
mishoo,
Innym problemem jest to, że nawet jeśli w jakiś sposób wprowadziłeś nową składnię czytnika, reszta Emacsa nie jest tego świadoma, więc musisz też naprawić syntax.c...
wasamasa
9

Najwyraźniej można to zrobić, ale przygotuj się na dużo pracy. (lub nie, bo poradzę sobie z tym w weekend ;-).

(defvar *orig-read* (symbol-function 'read))

(defun read (&optional in)
  (message "reading from %s" load-file-name)
  (funcall *orig-read* in))

(setq load-read-function (symbol-function 'read))

Teraz „wszystko”, co pozostało do zrobienia, to wdrożyć kompletny czytnik Lisp, który obsługuje wszystko, co robi Elisp i cokolwiek chcesz więcej. Myślę, że można to wykorzystać do dostarczenia defpackagesymboli CL i wewnętrznych symboli, jako jednego z przykładów. Specjalna składnia wyrażeń regularnych to coś, co bardzo chcę zrobić (a dokładniej, niektóre składnie łańcuchowe, które nie interpretują ukośników odwrotnych).

Edycja: oto implementacja sprawdzonej koncepcji: https://github.com/mishoo/elisp-reader.el

mishoo
źródło
Prawdopodobnie najlepiej nie publikować tego jako odpowiedzi, dopóki nie zaimplementujesz kompletnego czytnika Lisp, jak sugerowałeś (co, jak sądzę, nie jest trywialnym przedsięwzięciem).
Dan
@ Dan To wykonalne, po prostu robienie tego w C jest o wiele bardziej bolesne, ponieważ jest do bani dla przetwarzania łańcucha.
wasamasa
1
@ Dan działał, zredagowałem odpowiedź, aby dodać link do implementacji.
mishoo,