Mercurial > emacs
diff src/lread.c @ 111833:f0dfec5bd26b
* src/lread.c (read1): Allow newstyle unquote outside of backquote.
Disallow old-style backquotes inside new-style backquotes.
Don't count unquotes to figure out when we're "syntactically inside
but semantically outside of a backquote" any more.
Extend the restriction no-unescaped-commas-and-backquotes-in-symbols
to all contexts.
| author | Stefan Monnier <monnier@iro.umontreal.ca> |
|---|---|
| date | Mon, 06 Dec 2010 11:37:26 -0500 |
| parents | 141d3f14d8c3 |
| children | a5a188ddc758 |
line wrap: on
line diff
--- a/src/lread.c Mon Dec 06 03:59:56 2010 +0000 +++ b/src/lread.c Mon Dec 06 11:37:26 2010 -0500 @@ -2637,7 +2637,7 @@ old-style. For Emacs-25, we should completely remove this first_in_list exception (old-style can still be obtained via "(\`" anyway). */ - if (first_in_list && next_char == ' ') + if (!new_backquote_flag && first_in_list && next_char == ' ') { Vold_style_backquotes = Qt; goto default_label; @@ -2654,33 +2654,48 @@ } } case ',': - if (new_backquote_flag) - { - Lisp_Object comma_type = Qnil; - Lisp_Object value; - int ch = READCHAR; - - if (ch == '@') - comma_type = Qcomma_at; - else if (ch == '.') - comma_type = Qcomma_dot; - else - { - if (ch >= 0) UNREAD (ch); - comma_type = Qcomma; - } - - new_backquote_flag--; - value = read0 (readcharfun); - new_backquote_flag++; - return Fcons (comma_type, Fcons (value, Qnil)); - } - else - { - Vold_style_backquotes = Qt; - goto default_label; - } - + { + int next_char = READCHAR; + UNREAD (next_char); + /* Transition from old-style to new-style: + It used to be impossible to have a new-style , other than within + a new-style `. This is sufficient when ` and , are used in the + normal way, but ` and , can also appear in args to macros that + will not interpret them in the usual way, in which case , may be + used without any ` anywhere near. + So we now use the same heuristic as for backquote: old-style + unquotes are only recognized when first on a list, and when + followed by a space. + Because it's more difficult to peak 2 chars ahead, a new-style + ,@ can still not be used outside of a `, unless it's in the middle + of a list. */ + if (new_backquote_flag + || !first_in_list + || (next_char != ' ' && next_char != '@')) + { + Lisp_Object comma_type = Qnil; + Lisp_Object value; + int ch = READCHAR; + + if (ch == '@') + comma_type = Qcomma_at; + else if (ch == '.') + comma_type = Qcomma_dot; + else + { + if (ch >= 0) UNREAD (ch); + comma_type = Qcomma; + } + + value = read0 (readcharfun); + return Fcons (comma_type, Fcons (value, Qnil)); + } + else + { + Vold_style_backquotes = Qt; + goto default_label; + } + } case '?': { int modifiers; @@ -2707,26 +2722,9 @@ c |= modifiers; next_char = READCHAR; - if (next_char == '.') - { - /* Only a dotted-pair dot is valid after a char constant. */ - int next_next_char = READCHAR; - UNREAD (next_next_char); - - ok = (next_next_char <= 040 - || (next_next_char < 0200 - && (strchr ("\"';([#?", next_next_char) - || (!first_in_list && next_next_char == '`') - || (new_backquote_flag && next_next_char == ',')))); - } - else - { - ok = (next_char <= 040 - || (next_char < 0200 - && (strchr ("\"';()[]#?", next_char) - || (!first_in_list && next_char == '`') - || (new_backquote_flag && next_char == ',')))); - } + ok = (next_char <= 040 + || (next_char < 0200 + && (strchr ("\"';()[]#?`,.", next_char)))); UNREAD (next_char); if (ok) return make_number (c); @@ -2868,9 +2866,7 @@ if (next_char <= 040 || (next_char < 0200 - && (strchr ("\"';([#?", next_char) - || (!first_in_list && next_char == '`') - || (new_backquote_flag && next_char == ',')))) + && (strchr ("\"';([#?`,", next_char)))) { *pch = c; return Qnil; @@ -2895,9 +2891,7 @@ while (c > 040 && c != 0x8a0 /* NBSP */ && (c >= 0200 - || (!strchr ("\"';()[]#", c) - && !(!first_in_list && c == '`') - && !(new_backquote_flag && c == ',')))) + || !(strchr ("\"';()[]#`,", c)))) { if (end - p < MAX_MULTIBYTE_LENGTH) {
