aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoão Távora2020-09-19 22:16:38 +0100
committerJoão Távora2021-09-27 01:07:11 +0100
commit71857d410635743d437ce1ee73dff69de50030d6 (patch)
treefa5491b2f0c8106dfbc3efaa6e01d363871eefef /src
parent6237bad419a23fcbefb2c33728522b1bb52cb557 (diff)
downloademacs-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.c65
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
2959Lisp_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'.
4451usage: (unintern NAME OBARRAY) */) 4446usage: (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
4552Lisp_Object
4553oblookup_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
4558void 4583void
4559map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Object arg) 4584map_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}