diff options
author | Andy Wingo <wingo@pobox.com> | 2012-03-06 11:19:06 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2012-03-06 11:19:06 +0100 |
commit | 4164dd6d1f97505748a8476f2524efff87be4bb0 (patch) | |
tree | c5e472fa6f2b928f575807486e240de0cdccd261 | |
parent | f6e6b5181aaf068d06709d94e765b9ff5ecb2eaa (diff) |
optimize symbol printing
* libguile/print.h: Remove internal declaration of
scm_i_print_symbol_name.
* libguile/print.c (symbol_has_extended_read_syntax): Optimize to avoid
calling symbol_to_string if we know the symbol cannot be mistaken for
a number.
(print_normal_symbol): Optimize to call display_string directly,
instead of jumping through scm_display.
(print_symbol): Rename from scm_i_print_symbol_name.
(scm_print_symbol_name, iprin1): Adapt to print_symbol name change.
-rw-r--r-- | libguile/print.c | 79 | ||||
-rw-r--r-- | libguile/print.h | 3 |
2 files changed, 60 insertions, 22 deletions
diff --git a/libguile/print.c b/libguile/print.c index fd0cc3da9..1f447bb99 100644 --- a/libguile/print.c +++ b/libguile/print.c @@ -332,6 +332,7 @@ quote_keywordish_symbols (void) (INITIAL_IDENTIFIER_MASK \ | UC_CATEGORY_MASK_Nd | UC_CATEGORY_MASK_Mc | UC_CATEGORY_MASK_Me) +/* FIXME: Cache this information on the symbol, somehow. */ static int symbol_has_extended_read_syntax (SCM sym) { @@ -344,26 +345,56 @@ symbol_has_extended_read_syntax (SCM sym) c = scm_i_symbol_ref (sym, 0); - /* Single dot; conflicts with dotted-pair notation. */ - if (len == 1 && c == '.') - return 1; - - /* Other initial-character constraints. */ - if (c == '\'' || c == '`' || c == ',' || c == '"' || c == ';' || c == '#') - return 1; + switch (c) + { + case '\'': + case '`': + case ',': + case '"': + case ';': + case '#': + /* Some initial-character constraints. */ + return 1; - /* Keywords can be identified by trailing colons too. */ - if (c == ':' || scm_i_symbol_ref (sym, len - 1) == ':') - return quote_keywordish_symbols (); + case ':': + /* Symbols that look like keywords. */ + return quote_keywordish_symbols (); - /* Number-ish symbols. */ - if (scm_is_true (scm_i_string_to_number (scm_symbol_to_string (sym), 10))) - return 1; + case '.': + /* Single dot conflicts with dotted-pair notation. */ + if (len == 1) + return 1; + /* Fall through to check numbers. */ + case '+': + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* Number-ish symbols. Numbers with radixes already caught be # + above. */ + if (scm_is_true (scm_i_string_to_number (scm_symbol_to_string (sym), 10))) + return 1; + break; + + default: + break; + } /* Other disallowed first characters. */ if (!uc_is_general_category_withtable (c, INITIAL_IDENTIFIER_MASK)) return 1; + /* Keywords can be identified by trailing colons too. */ + if (scm_i_symbol_ref (sym, len - 1) == ':') + return quote_keywordish_symbols (); + /* Otherwise, any character that's in the identifier category mask is fine to pass through as-is, provided it's not one of the ASCII delimiters like `;'. */ @@ -382,7 +413,16 @@ symbol_has_extended_read_syntax (SCM sym) static void print_normal_symbol (SCM sym, SCM port) { - scm_display (scm_symbol_to_string (sym), port); + size_t len; + scm_t_string_failed_conversion_handler strategy; + + len = scm_i_symbol_length (sym); + strategy = scm_i_get_conversion_strategy (port); + + if (scm_i_is_narrow_symbol (sym)) + display_string (scm_i_symbol_chars (sym), 1, len, port, strategy); + else + display_string (scm_i_symbol_wide_chars (sym), 0, len, port, strategy); } static void @@ -421,8 +461,8 @@ print_extended_symbol (SCM sym, SCM port) } /* FIXME: allow R6RS hex escapes instead of #{...}#. */ -void -scm_i_print_symbol_name (SCM sym, SCM port) +static void +print_symbol (SCM sym, SCM port) { if (symbol_has_extended_read_syntax (sym)) print_extended_symbol (sym, port); @@ -434,7 +474,7 @@ void scm_print_symbol_name (const char *str, size_t len, SCM port) { SCM symbol = scm_from_utf8_symboln (str, len); - scm_i_print_symbol_name (symbol, port); + print_symbol (symbol, port); } /* Print generally. Handles both write and display according to PSTATE. @@ -597,13 +637,13 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate) case scm_tc7_symbol: if (scm_i_symbol_is_interned (exp)) { - scm_i_print_symbol_name (exp, port); + print_symbol (exp, port); scm_remember_upto_here_1 (exp); } else { scm_puts_unlocked ("#<uninterned-symbol ", port); - scm_i_print_symbol_name (exp, port); + print_symbol (exp, port); scm_putc_unlocked (' ', port); scm_uintprint (SCM_UNPACK (exp), 16, port); scm_putc_unlocked ('>', port); @@ -1002,7 +1042,6 @@ static size_t display_string (const void *str, int narrow_p, size_t len, SCM port, scm_t_string_failed_conversion_handler strategy) - { scm_t_port *pt; diff --git a/libguile/print.h b/libguile/print.h index 64d1f4bd8..4a3c2f5c0 100644 --- a/libguile/print.h +++ b/libguile/print.h @@ -3,7 +3,7 @@ #ifndef SCM_PRINT_H #define SCM_PRINT_H -/* Copyright (C) 1995,1996,1998,2000,2001, 2003, 2004, 2006, 2008, 2010 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1998,2000,2001, 2003, 2004, 2006, 2008, 2010, 2012 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -82,7 +82,6 @@ SCM_API void scm_intprint (scm_t_intmax n, int radix, SCM port); SCM_API void scm_uintprint (scm_t_uintmax n, int radix, SCM port); SCM_API void scm_ipruk (char *hdr, SCM ptr, SCM port); SCM_API void scm_iprlist (char *hdr, SCM exp, int tlr, SCM port, scm_print_state *pstate); -SCM_INTERNAL void scm_i_print_symbol_name (SCM sym, SCM port); SCM_API void scm_print_symbol_name (const char *str, size_t len, SCM port); SCM_API void scm_prin1 (SCM exp, SCM port, int writingp); SCM_API void scm_iprin1 (SCM exp, SCM port, scm_print_state *pstate); |