From 19efb25e52a018f20fe083ed887fe9105642a46a Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Fri, 30 Dec 2016 19:44:27 -0500 Subject: [PATCH] Use #N# syntax for repeated symbols in dumped.elc. Parsing symbol names involves processing for possible multibyte characters and comparisons against other symbol-name strings in the obarray. The #N# syntax is simpler, uses an automatically resized hash table keyed by integers, and is in most cases shorter, so reading can be a little faster. When doing this we have to avoid the special "," syntax because we would wind up printing "#1=,foo" which reads back as setting #1# to ,foo when we really wanted to set #1# to just the comma symbol. * src/print.c (syms_of_print): Define new Lisp variable print-symbols-as-references. (PRINT_CIRCLE_CANDIDATE_P): If it's set, accept interned symbols. (print_preprocess): Update comment. (print_object): When printing "," or related symbols with special syntax, don't use print_object on the special symbol itself. * lisp/loadup.el: Bind print-symbols-as-references to t while creating the dumped.elc file. --- lisp/loadup.el | 1 + src/print.c | 52 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/lisp/loadup.el b/lisp/loadup.el index c5c4c48910b..2c8ab52d673 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -566,6 +566,7 @@ lost after dumping"))) (print-level nil) (print-length nil) (print-escape-newlines t) + (print-symbols-as-references t) (standard-output (current-buffer))) (print '(setq purify-flag nil)) (print '(get-buffer-create "*Messages*")) diff --git a/src/print.c b/src/print.c index 12edf015892..aca808f2750 100644 --- a/src/print.c +++ b/src/print.c @@ -1131,16 +1131,19 @@ print (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) print_object (obj, printcharfun, escapeflag); } -#define PRINT_CIRCLE_CANDIDATE_P(obj) \ - (STRINGP (obj) || CONSP (obj) \ - || (VECTORLIKEP (obj) \ - && (VECTORP (obj) || COMPILEDP (obj) \ - || CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj) \ - || HASH_TABLE_P (obj) || FONTP (obj) \ - || RECORDP (obj))) \ - || (! NILP (Vprint_gensym) \ - && SYMBOLP (obj) \ - && !SYMBOL_INTERNED_P (obj))) +#define PRINT_CIRCLE_CANDIDATE_P(obj) \ + (STRINGP (obj) || CONSP (obj) \ + || (VECTORLIKEP (obj) \ + && (VECTORP (obj) || COMPILEDP (obj) \ + || CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj) \ + || HASH_TABLE_P (obj) || FONTP (obj) \ + || RECORDP (obj))) \ + || (SYMBOLP (obj) \ + && !SYMBOL_INTERNED_P (obj) \ + && ! NILP (Vprint_gensym)) \ + || (SYMBOLP (obj) \ + && SYMBOL_INTERNED_P (obj) \ + && ! NILP (Vprint_symbols_as_references))) /* Construct Vprint_number_table according to the structure of OBJ. OBJ itself and all its elements will be added to Vprint_number_table @@ -1181,8 +1184,9 @@ print_preprocess (Lisp_Object obj) if (!HASH_TABLE_P (Vprint_number_table)) Vprint_number_table = CALLN (Fmake_hash_table, QCtest, Qeq); - /* In case print-circle is nil and print-gensym is t, - add OBJ to Vprint_number_table only when OBJ is a symbol. */ + /* In case print-circle is nil and print-gensym or + print-symbols-as-references is t, add OBJ to Vprint_number_table only + when OBJ is a symbol. */ if (! NILP (Vprint_circle) || SYMBOLP (obj)) { Lisp_Object num = Fgethash (obj, Vprint_number_table, Qnil); @@ -2013,7 +2017,20 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) || EQ (XCAR (obj), Qcomma_at) || EQ (XCAR (obj), Qcomma_dot))) { - print_object (XCAR (obj), printcharfun, false); + /* If print-symbols-as-references is enabled, symbols may + print with "#N=" or "#N#" form. When we print a cons + cell with parens and separated elements, that's fine, but + for comma symbols we depend on the reader to generate the + cons cell from the special syntax. The Lisp reader will + treat "#1=,#2=foo" as setting reference 1 to ",foo", not + to ",", so we can't use print_object to print out the + comma symbols without breaking the ability to read the + result back properly. */ + printchar (',', printcharfun); + if (EQ (XCAR (obj), Qcomma_at)) + printchar ('@', printcharfun); + else if (EQ (XCAR (obj), Qcomma_dot)) + printchar ('.', printcharfun); new_backquote_output--; print_object (XCAR (XCDR (obj)), printcharfun, escapeflag); new_backquote_output++; @@ -2422,6 +2439,15 @@ the value is different from what is guessed in the current charset priorities. */); Vprint_charset_text_property = Qdefault; + DEFVAR_LISP ("print-symbols-as-references", Vprint_symbols_as_references, + doc: /* Non-nil means print interned symbols using #N= and #N# syntax. +If nil, symbols are printed normally. + +Setting this true makes the output harder for a human to read, but may +parse more efficiently as input to the Lisp reader if some symbols appear +in the output many times. */); + Vprint_symbols_as_references = Qnil; + /* prin1_to_string_buffer initialized in init_buffer_once in buffer.c */ staticpro (&Vprin1_to_string_buffer); -- 2.39.5