]> git.eshelyaron.com Git - emacs.git/commitdiff
Use #N# syntax for repeated symbols in dumped.elc.
authorKen Raeburn <raeburn@raeburn.org>
Sat, 31 Dec 2016 00:44:27 +0000 (19:44 -0500)
committerKen Raeburn <raeburn@raeburn.org>
Sat, 22 Jul 2017 08:36:20 +0000 (04:36 -0400)
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
src/print.c

index c5c4c48910b75661085e6539e594453bed179865..2c8ab52d6730da55f24dd48c3e893697b3dc3fb5 100644 (file)
@@ -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*"))
index 12edf01589286c0f601ca782c8e3b46a5f35ca16..aca808f2750795485891175cce5461edc0fe8b71 100644 (file)
@@ -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);