diff options
| author | João Távora | 2020-09-19 22:16:38 +0100 |
|---|---|---|
| committer | João Távora | 2021-09-27 01:07:11 +0100 |
| commit | 71857d410635743d437ce1ee73dff69de50030d6 (patch) | |
| tree | fa5491b2f0c8106dfbc3efaa6e01d363871eefef /src | |
| parent | 6237bad419a23fcbefb2c33728522b1bb52cb557 (diff) | |
| download | emacs-71857d410635743d437ce1ee73dff69de50030d6.tar.gz emacs-71857d410635743d437ce1ee73dff69de50030d6.zip | |
Move most of the shorthand implementation to C code
It passes the tests designed for the previous Elisp implementation.
Likely, this isn't the final form of the implementation. For one, the
reader is much slower and allocates a Lisp string for every atom read,
regardless if its already interned or not. This has the potential to
be catastrophic in terms of GC.
Also rename the main variable to elisp-shorthands, from the
repetitive shorthand-shorthands.
For some reason, I had to put 'hack-elisp-shorthands' and
'load-with-shorthands-and-code-conversion', the new source-file
loading functions, in lisp/international/mule.el.
Otherwise, lisp/loadup.el wouldn't see them, for some reason that I
didn't investigate. This should probably be fixed.
* lisp/shorthand.el: Remove.
* test/lisp/shorthand-tests.el: Remove.
* src/lread.c:
(read1, Fintern, Fintern_soft, Funintern): Use
oblookup_considering_shorthand.
(oblookup_considering_shorthand): New helper.
(syms_of_lread): Declare elisp-shorthands.
* lisp/progmodes/elisp-mode.el (elisp-shorthands):
Put a safe-local-variable spec.
* test/lisp/progmodes/elisp-mode-tests.el (elisp-shorthand-read-buffer)
(elisp-shorthand-read-from-string)
(elisp-shorthand-byte-compile-a-file)
(elisp-shorthand-load-a-file): New tests.
* test/lisp/progmodes/elisp-resources/simple-shorthand-test.el: New file
* lisp/loadup.el (load-source-file-function): Set to
load-with-shorthands-and-code-conversion.
* lisp/international/mule.el (hack-elisp-shorthands): Move here.
(load-with-shorthands-and-code-conversion): And here.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lread.c | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/src/lread.c b/src/lread.c index 2abe2fd91ab..0c0c4f34ba3 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -2956,6 +2956,7 @@ read_integer (Lisp_Object readcharfun, int radix, | |||
| 2956 | return unbind_to (count, string_to_number (read_buffer, radix, NULL)); | 2956 | return unbind_to (count, string_to_number (read_buffer, radix, NULL)); |
| 2957 | } | 2957 | } |
| 2958 | 2958 | ||
| 2959 | Lisp_Object oblookup_considering_shorthand (Lisp_Object, Lisp_Object*); | ||
| 2959 | 2960 | ||
| 2960 | /* If the next token is ')' or ']' or '.', we store that character | 2961 | /* If the next token is ')' or ']' or '.', we store that character |
| 2961 | in *PCH and the return value is not interesting. Else, we store | 2962 | in *PCH and the return value is not interesting. Else, we store |
| @@ -3781,23 +3782,17 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 3781 | } | 3782 | } |
| 3782 | else | 3783 | else |
| 3783 | { | 3784 | { |
| 3784 | /* Don't create the string object for the name unless | 3785 | /* Like intern_1 but supports multibyte names. */ |
| 3785 | we're going to retain it in a new symbol. | ||
| 3786 | |||
| 3787 | Like intern_1 but supports multibyte names. */ | ||
| 3788 | Lisp_Object obarray = check_obarray (Vobarray); | 3786 | Lisp_Object obarray = check_obarray (Vobarray); |
| 3789 | Lisp_Object tem = oblookup (obarray, read_buffer, | 3787 | Lisp_Object name |
| 3790 | nchars, nbytes); | 3788 | = make_specified_string (read_buffer, nchars, nbytes, |
| 3789 | multibyte); | ||
| 3790 | Lisp_Object tem = oblookup_considering_shorthand (obarray, &name); | ||
| 3791 | 3791 | ||
| 3792 | if (SYMBOLP (tem)) | 3792 | if (SYMBOLP (tem)) |
| 3793 | result = tem; | 3793 | result = tem; |
| 3794 | else | 3794 | else |
| 3795 | { | 3795 | result = intern_driver (name, obarray, tem); |
| 3796 | Lisp_Object name | ||
| 3797 | = make_specified_string (read_buffer, nchars, nbytes, | ||
| 3798 | multibyte); | ||
| 3799 | result = intern_driver (name, obarray, tem); | ||
| 3800 | } | ||
| 3801 | } | 3796 | } |
| 3802 | 3797 | ||
| 3803 | if (EQ (Vread_with_symbol_positions, Qt) | 3798 | if (EQ (Vread_with_symbol_positions, Qt) |
| @@ -4407,7 +4402,7 @@ it defaults to the value of `obarray'. */) | |||
| 4407 | obarray = check_obarray (NILP (obarray) ? Vobarray : obarray); | 4402 | obarray = check_obarray (NILP (obarray) ? Vobarray : obarray); |
| 4408 | CHECK_STRING (string); | 4403 | CHECK_STRING (string); |
| 4409 | 4404 | ||
| 4410 | tem = oblookup (obarray, SSDATA (string), SCHARS (string), SBYTES (string)); | 4405 | tem = oblookup_considering_shorthand (obarray, &string); |
| 4411 | if (!SYMBOLP (tem)) | 4406 | if (!SYMBOLP (tem)) |
| 4412 | tem = intern_driver (NILP (Vpurify_flag) ? string : Fpurecopy (string), | 4407 | tem = intern_driver (NILP (Vpurify_flag) ? string : Fpurecopy (string), |
| 4413 | obarray, tem); | 4408 | obarray, tem); |
| @@ -4435,7 +4430,7 @@ it defaults to the value of `obarray'. */) | |||
| 4435 | else | 4430 | else |
| 4436 | string = SYMBOL_NAME (name); | 4431 | string = SYMBOL_NAME (name); |
| 4437 | 4432 | ||
| 4438 | tem = oblookup (obarray, SSDATA (string), SCHARS (string), SBYTES (string)); | 4433 | tem = oblookup_considering_shorthand (obarray, &string); |
| 4439 | if (FIXNUMP (tem) || (SYMBOLP (name) && !EQ (name, tem))) | 4434 | if (FIXNUMP (tem) || (SYMBOLP (name) && !EQ (name, tem))) |
| 4440 | return Qnil; | 4435 | return Qnil; |
| 4441 | else | 4436 | else |
| @@ -4451,7 +4446,8 @@ OBARRAY, if nil, defaults to the value of the variable `obarray'. | |||
| 4451 | usage: (unintern NAME OBARRAY) */) | 4446 | usage: (unintern NAME OBARRAY) */) |
| 4452 | (Lisp_Object name, Lisp_Object obarray) | 4447 | (Lisp_Object name, Lisp_Object obarray) |
| 4453 | { | 4448 | { |
| 4454 | register Lisp_Object string, tem; | 4449 | register Lisp_Object tem; |
| 4450 | Lisp_Object string; | ||
| 4455 | size_t hash; | 4451 | size_t hash; |
| 4456 | 4452 | ||
| 4457 | if (NILP (obarray)) obarray = Vobarray; | 4453 | if (NILP (obarray)) obarray = Vobarray; |
| @@ -4465,9 +4461,7 @@ usage: (unintern NAME OBARRAY) */) | |||
| 4465 | string = name; | 4461 | string = name; |
| 4466 | } | 4462 | } |
| 4467 | 4463 | ||
| 4468 | tem = oblookup (obarray, SSDATA (string), | 4464 | tem = oblookup_considering_shorthand (obarray, &string); |
| 4469 | SCHARS (string), | ||
| 4470 | SBYTES (string)); | ||
| 4471 | if (FIXNUMP (tem)) | 4465 | if (FIXNUMP (tem)) |
| 4472 | return Qnil; | 4466 | return Qnil; |
| 4473 | /* If arg was a symbol, don't delete anything but that symbol itself. */ | 4467 | /* If arg was a symbol, don't delete anything but that symbol itself. */ |
| @@ -4554,6 +4548,37 @@ oblookup (Lisp_Object obarray, register const char *ptr, ptrdiff_t size, ptrdiff | |||
| 4554 | XSETINT (tem, hash); | 4548 | XSETINT (tem, hash); |
| 4555 | return tem; | 4549 | return tem; |
| 4556 | } | 4550 | } |
| 4551 | |||
| 4552 | Lisp_Object | ||
| 4553 | oblookup_considering_shorthand (Lisp_Object obarray, Lisp_Object* string) | ||
| 4554 | { | ||
| 4555 | Lisp_Object original = *string; /* Save pointer to original string... */ | ||
| 4556 | Lisp_Object tail = Velisp_shorthands; | ||
| 4557 | FOR_EACH_TAIL_SAFE(tail) | ||
| 4558 | { | ||
| 4559 | Lisp_Object pair = XCAR (tail); | ||
| 4560 | if (!CONSP (pair)) goto undo; | ||
| 4561 | Lisp_Object shorthand = XCAR (pair); | ||
| 4562 | Lisp_Object longhand = XCDR (pair); | ||
| 4563 | if (!STRINGP (shorthand) || !STRINGP (longhand)) goto undo; | ||
| 4564 | Lisp_Object match = Fstring_match (shorthand, *string, Qnil); | ||
| 4565 | if (!NILP(match)){ | ||
| 4566 | *string = Freplace_match(longhand, Qnil, Qnil, *string, Qnil); | ||
| 4567 | } | ||
| 4568 | } | ||
| 4569 | goto fine; | ||
| 4570 | undo: | ||
| 4571 | { | ||
| 4572 | static const char* warn = | ||
| 4573 | "Fishy value of `elisp-shorthands'. " | ||
| 4574 | "Consider reviewing before evaluating code."; | ||
| 4575 | message_dolog (warn, sizeof(warn), 0, 0); | ||
| 4576 | *string = original; /* ...so we can any failed trickery here. */ | ||
| 4577 | } | ||
| 4578 | fine: | ||
| 4579 | return oblookup(obarray, SSDATA (*string), SCHARS (*string), SBYTES (*string)); | ||
| 4580 | } | ||
| 4581 | |||
| 4557 | 4582 | ||
| 4558 | void | 4583 | void |
| 4559 | map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Object arg) | 4584 | map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Object arg) |
| @@ -5310,4 +5335,8 @@ that are loaded before your customizations are read! */); | |||
| 5310 | DEFSYM (Qrehash_threshold, "rehash-threshold"); | 5335 | DEFSYM (Qrehash_threshold, "rehash-threshold"); |
| 5311 | 5336 | ||
| 5312 | DEFSYM (Qchar_from_name, "char-from-name"); | 5337 | DEFSYM (Qchar_from_name, "char-from-name"); |
| 5338 | |||
| 5339 | DEFVAR_LISP ("elisp-shorthands", Velisp_shorthands, | ||
| 5340 | doc: /* Alist of known symbol name shorthands*/); | ||
| 5341 | Velisp_shorthands = Qnil; | ||
| 5313 | } | 5342 | } |