From 66f30875304e373c40e9b81aa37041d49bf7abfe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Wed, 22 Sep 2021 23:53:15 +0100 Subject: [PATCH] Add #_ reader macro to escape shorthand renaming * src/lread.c (read1): Add skip_shorthand variable. Add a '#_' case. If skip_shorthand call oblookup instead of oblookup_considering_shorthand. * test/lisp/progmodes/elisp-mode-tests.el (elisp-shorthand-escape): New test. * test/lisp/progmodes/elisp-resources/simple-shorthand-test.el (#_f-test4---): New fixture function. --- src/lread.c | 18 +++++++++++++++--- test/lisp/progmodes/elisp-mode-tests.el | 10 ++++++++++ .../elisp-resources/simple-shorthand-test.el | 5 ++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/lread.c b/src/lread.c index 51a7084821e..db8c847a875 100644 --- a/src/lread.c +++ b/src/lread.c @@ -2972,6 +2972,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) { int c; bool uninterned_symbol = false; + bool skip_shorthand = false; bool multibyte; char stackbuf[stackbufsize]; current_thread->stack_top = stackbuf; @@ -3367,6 +3368,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) if (c == ':') { uninterned_symbol = true; + read_hash_prefixed_symbol: c = READCHAR; if (!(c > 040 && c != NO_BREAK_SPACE @@ -3380,6 +3382,12 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) } goto read_symbol; } + /* #_foo is really the symbol foo, regardless of shorthands */ + if (c == '_') + { + skip_shorthand = true; + goto read_hash_prefixed_symbol; + } /* ## is the empty symbol. */ if (c == '#') return Fintern (empty_unibyte_string, Qnil); @@ -3760,7 +3768,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) ptrdiff_t nbytes = p - read_buffer; UNREAD (c); - if (!quoted && !uninterned_symbol) + if (!quoted && !uninterned_symbol && !skip_shorthand) { ptrdiff_t len; Lisp_Object result = string_to_number (read_buffer, 10, &len); @@ -3795,10 +3803,14 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) ptrdiff_t longhand_chars = 0; ptrdiff_t longhand_bytes = 0; - Lisp_Object tem - = oblookup_considering_shorthand + Lisp_Object tem; + if (skip_shorthand) + tem = oblookup (obarray, read_buffer, nchars, nbytes); + else { + tem = oblookup_considering_shorthand (obarray, read_buffer, nchars, nbytes, &longhand, &longhand_chars, &longhand_bytes); + } if (SYMBOLP (tem)) result = tem; diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el index 9fe583d8cc3..fbf264a715f 100644 --- a/test/lisp/progmodes/elisp-mode-tests.el +++ b/test/lisp/progmodes/elisp-mode-tests.el @@ -1096,5 +1096,15 @@ evaluation of BODY." "elisp--foo-test-complete-me")) (revert-buffer t t)))) +(ert-deftest elisp-shorthand-escape () + (let ((test-file (expand-file-name "simple-shorthand-test.el" + elisp--test-resources-dir))) + (load test-file) + (should (intern-soft "f-test4---")) + (should-not (intern-soft "elisp--foo-test4---")) + (should (= 84 (funcall (intern-soft "f-test4---")))) + (should (unintern "f-test4---")))) + + (provide 'elisp-mode-tests) ;;; elisp-mode-tests.el ends here diff --git a/test/lisp/progmodes/elisp-resources/simple-shorthand-test.el b/test/lisp/progmodes/elisp-resources/simple-shorthand-test.el index cadcb4de89d..ec568093af2 100644 --- a/test/lisp/progmodes/elisp-resources/simple-shorthand-test.el +++ b/test/lisp/progmodes/elisp-resources/simple-shorthand-test.el @@ -16,10 +16,13 @@ (defvar f-test-complete-me 42) +(defun #_f-test4--- () 84) + (when nil (f-test3) (f-test2) - (f-test)) + (f-test) + (#_f-test4---)) ;; Local Variables: -- 2.39.2