diff options
| author | Richard M. Stallman | 1995-05-04 17:13:20 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-05-04 17:13:20 +0000 |
| commit | 176348460d640ae96b0b21567df0de1457aa962b (patch) | |
| tree | 8808bbf11a5a5a6b5e47a7a3ca7f8cfa90f67ec5 /src | |
| parent | ec0faad26604f07fdc117fbc7956f74a4aae492a (diff) | |
| download | emacs-176348460d640ae96b0b21567df0de1457aa962b.tar.gz emacs-176348460d640ae96b0b21567df0de1457aa962b.zip | |
(read1): New arg FIRST_IN_LIST; all callers changed.
Special handling for backquote and comma.
(Qbackquote, Qcomma, Qcomma_at, Qcomma_dot): New variables.
(syms_of_lread): Initialize and staticpro them.
(Fread, Fread_from_string): Initialize new_backquote_flag.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lread.c | 87 |
1 files changed, 78 insertions, 9 deletions
diff --git a/src/lread.c b/src/lread.c index 57231df36e6..81670ebe048 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -68,6 +68,7 @@ extern int errno; | |||
| 68 | Lisp_Object Qread_char, Qget_file_char, Qstandard_input, Qcurrent_load_list; | 68 | Lisp_Object Qread_char, Qget_file_char, Qstandard_input, Qcurrent_load_list; |
| 69 | Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist; | 69 | Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist; |
| 70 | Lisp_Object Qascii_character, Qload, Qload_file_name; | 70 | Lisp_Object Qascii_character, Qload, Qload_file_name; |
| 71 | Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot; | ||
| 71 | 72 | ||
| 72 | extern Lisp_Object Qevent_symbol_element_mask; | 73 | extern Lisp_Object Qevent_symbol_element_mask; |
| 73 | 74 | ||
| @@ -102,6 +103,12 @@ static int read_pure; | |||
| 102 | /* For use within read-from-string (this reader is non-reentrant!!) */ | 103 | /* For use within read-from-string (this reader is non-reentrant!!) */ |
| 103 | static int read_from_string_index; | 104 | static int read_from_string_index; |
| 104 | static int read_from_string_limit; | 105 | static int read_from_string_limit; |
| 106 | |||
| 107 | /* Nonzero means inside a new-style backquote | ||
| 108 | with no surrounding parentheses. | ||
| 109 | Fread initializes this to zero, so we need not specbind it | ||
| 110 | or worry about what happens to it when there is an error. */ | ||
| 111 | static int new_backquote_flag; | ||
| 105 | 112 | ||
| 106 | /* Handle unreading and rereading of characters. | 113 | /* Handle unreading and rereading of characters. |
| 107 | Write READCHAR to read a character, | 114 | Write READCHAR to read a character, |
| @@ -892,6 +899,8 @@ STREAM or the value of `standard-input' may be:\n\ | |||
| 892 | if (EQ (readcharfun, Qt)) | 899 | if (EQ (readcharfun, Qt)) |
| 893 | readcharfun = Qread_char; | 900 | readcharfun = Qread_char; |
| 894 | 901 | ||
| 902 | new_backquote_flag = 0; | ||
| 903 | |||
| 895 | #ifndef standalone | 904 | #ifndef standalone |
| 896 | if (EQ (readcharfun, Qread_char)) | 905 | if (EQ (readcharfun, Qread_char)) |
| 897 | return Fread_minibuffer (build_string ("Lisp expression: "), Qnil); | 906 | return Fread_minibuffer (build_string ("Lisp expression: "), Qnil); |
| @@ -937,6 +946,8 @@ START and END optionally delimit a substring of STRING from which to read;\n\ | |||
| 937 | read_from_string_index = startval; | 946 | read_from_string_index = startval; |
| 938 | read_from_string_limit = endval; | 947 | read_from_string_limit = endval; |
| 939 | 948 | ||
| 949 | new_backquote_flag = 0; | ||
| 950 | |||
| 940 | tem = read0 (string); | 951 | tem = read0 (string); |
| 941 | return Fcons (tem, make_number (read_from_string_index)); | 952 | return Fcons (tem, make_number (read_from_string_index)); |
| 942 | } | 953 | } |
| @@ -950,7 +961,7 @@ read0 (readcharfun) | |||
| 950 | register Lisp_Object val; | 961 | register Lisp_Object val; |
| 951 | char c; | 962 | char c; |
| 952 | 963 | ||
| 953 | val = read1 (readcharfun, &c); | 964 | val = read1 (readcharfun, &c, 0); |
| 954 | if (c) | 965 | if (c) |
| 955 | Fsignal (Qinvalid_read_syntax, Fcons (make_string (&c, 1), Qnil)); | 966 | Fsignal (Qinvalid_read_syntax, Fcons (make_string (&c, 1), Qnil)); |
| 956 | 967 | ||
| @@ -1117,11 +1128,15 @@ read_escape (readcharfun) | |||
| 1117 | 1128 | ||
| 1118 | /* If the next token is ')' or ']' or '.', we store that character | 1129 | /* If the next token is ')' or ']' or '.', we store that character |
| 1119 | in *PCH and the return value is not interesting. Else, we store | 1130 | in *PCH and the return value is not interesting. Else, we store |
| 1120 | zero in *PCH and we read and return one lisp object. */ | 1131 | zero in *PCH and we read and return one lisp object. |
| 1132 | |||
| 1133 | FIRST_IN_LIST is nonzero if this is the first element of a list. */ | ||
| 1134 | |||
| 1121 | static Lisp_Object | 1135 | static Lisp_Object |
| 1122 | read1 (readcharfun, pch) | 1136 | read1 (readcharfun, pch, first_in_list) |
| 1123 | register Lisp_Object readcharfun; | 1137 | register Lisp_Object readcharfun; |
| 1124 | char *pch; | 1138 | char *pch; |
| 1139 | int first_in_list; | ||
| 1125 | { | 1140 | { |
| 1126 | register int c; | 1141 | register int c; |
| 1127 | *pch = 0; | 1142 | *pch = 0; |
| @@ -1165,7 +1180,7 @@ read1 (readcharfun, pch) | |||
| 1165 | char ch; | 1180 | char ch; |
| 1166 | 1181 | ||
| 1167 | /* Read the string itself. */ | 1182 | /* Read the string itself. */ |
| 1168 | tmp = read1 (readcharfun, &ch); | 1183 | tmp = read1 (readcharfun, &ch, 0); |
| 1169 | if (ch != 0 || !STRINGP (tmp)) | 1184 | if (ch != 0 || !STRINGP (tmp)) |
| 1170 | Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil)); | 1185 | Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil)); |
| 1171 | GCPRO1 (tmp); | 1186 | GCPRO1 (tmp); |
| @@ -1174,13 +1189,13 @@ read1 (readcharfun, pch) | |||
| 1174 | { | 1189 | { |
| 1175 | Lisp_Object beg, end, plist; | 1190 | Lisp_Object beg, end, plist; |
| 1176 | 1191 | ||
| 1177 | beg = read1 (readcharfun, &ch); | 1192 | beg = read1 (readcharfun, &ch, 0); |
| 1178 | if (ch == ')') | 1193 | if (ch == ')') |
| 1179 | break; | 1194 | break; |
| 1180 | if (ch == 0) | 1195 | if (ch == 0) |
| 1181 | end = read1 (readcharfun, &ch); | 1196 | end = read1 (readcharfun, &ch, 0); |
| 1182 | if (ch == 0) | 1197 | if (ch == 0) |
| 1183 | plist = read1 (readcharfun, &ch); | 1198 | plist = read1 (readcharfun, &ch, 0); |
| 1184 | if (ch) | 1199 | if (ch) |
| 1185 | Fsignal (Qinvalid_read_syntax, | 1200 | Fsignal (Qinvalid_read_syntax, |
| 1186 | Fcons (build_string ("invalid string property list"), | 1201 | Fcons (build_string ("invalid string property list"), |
| @@ -1228,6 +1243,45 @@ read1 (readcharfun, pch) | |||
| 1228 | return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil)); | 1243 | return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil)); |
| 1229 | } | 1244 | } |
| 1230 | 1245 | ||
| 1246 | case '`': | ||
| 1247 | if (first_in_list) | ||
| 1248 | goto default_label; | ||
| 1249 | else | ||
| 1250 | { | ||
| 1251 | Lisp_Object value; | ||
| 1252 | |||
| 1253 | new_backquote_flag = 1; | ||
| 1254 | value = read0 (readcharfun); | ||
| 1255 | new_backquote_flag = 0; | ||
| 1256 | |||
| 1257 | return Fcons (Qbackquote, Fcons (value, Qnil)); | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | case ',': | ||
| 1261 | if (new_backquote_flag) | ||
| 1262 | { | ||
| 1263 | Lisp_Object comma_type = Qnil; | ||
| 1264 | Lisp_Object value; | ||
| 1265 | int ch = READCHAR; | ||
| 1266 | |||
| 1267 | if (ch == '@') | ||
| 1268 | comma_type = Qcomma_at; | ||
| 1269 | else if (ch == '.') | ||
| 1270 | comma_type = Qcomma_dot; | ||
| 1271 | else | ||
| 1272 | { | ||
| 1273 | if (ch >= 0) UNREAD (ch); | ||
| 1274 | comma_type = Qcomma; | ||
| 1275 | } | ||
| 1276 | |||
| 1277 | new_backquote_flag = 0; | ||
| 1278 | value = read0 (readcharfun); | ||
| 1279 | new_backquote_flag = 1; | ||
| 1280 | return Fcons (comma_type, Fcons (value, Qnil)); | ||
| 1281 | } | ||
| 1282 | else | ||
| 1283 | goto default_label; | ||
| 1284 | |||
| 1231 | case '?': | 1285 | case '?': |
| 1232 | { | 1286 | { |
| 1233 | register Lisp_Object val; | 1287 | register Lisp_Object val; |
| @@ -1319,6 +1373,7 @@ read1 (readcharfun, pch) | |||
| 1319 | try to UNREAD two characters in a row. */ | 1373 | try to UNREAD two characters in a row. */ |
| 1320 | } | 1374 | } |
| 1321 | default: | 1375 | default: |
| 1376 | default_label: | ||
| 1322 | if (c <= 040) goto retry; | 1377 | if (c <= 040) goto retry; |
| 1323 | { | 1378 | { |
| 1324 | register char *p = read_buffer; | 1379 | register char *p = read_buffer; |
| @@ -1506,6 +1561,9 @@ read_list (flag, readcharfun) | |||
| 1506 | struct gcpro gcpro1, gcpro2; | 1561 | struct gcpro gcpro1, gcpro2; |
| 1507 | int cancel = 0; | 1562 | int cancel = 0; |
| 1508 | 1563 | ||
| 1564 | /* Initialize this to 1 if we are reading a list. */ | ||
| 1565 | int first_in_list = flag <= 0; | ||
| 1566 | |||
| 1509 | val = Qnil; | 1567 | val = Qnil; |
| 1510 | tail = Qnil; | 1568 | tail = Qnil; |
| 1511 | 1569 | ||
| @@ -1513,9 +1571,11 @@ read_list (flag, readcharfun) | |||
| 1513 | { | 1571 | { |
| 1514 | char ch; | 1572 | char ch; |
| 1515 | GCPRO2 (val, tail); | 1573 | GCPRO2 (val, tail); |
| 1516 | elt = read1 (readcharfun, &ch); | 1574 | elt = read1 (readcharfun, &ch, first_in_list); |
| 1517 | UNGCPRO; | 1575 | UNGCPRO; |
| 1518 | 1576 | ||
| 1577 | first_in_list = 0; | ||
| 1578 | |||
| 1519 | /* If purifying, and the list starts with #$, | 1579 | /* If purifying, and the list starts with #$, |
| 1520 | return 0 instead. This is a doc string reference | 1580 | return 0 instead. This is a doc string reference |
| 1521 | and it will be replaced anyway by Snarf-documentation, | 1581 | and it will be replaced anyway by Snarf-documentation, |
| @@ -1541,7 +1601,7 @@ read_list (flag, readcharfun) | |||
| 1541 | XCONS (tail)->cdr = read0 (readcharfun); | 1601 | XCONS (tail)->cdr = read0 (readcharfun); |
| 1542 | else | 1602 | else |
| 1543 | val = read0 (readcharfun); | 1603 | val = read0 (readcharfun); |
| 1544 | read1 (readcharfun, &ch); | 1604 | read1 (readcharfun, &ch, 0); |
| 1545 | UNGCPRO; | 1605 | UNGCPRO; |
| 1546 | if (ch == ')') | 1606 | if (ch == ')') |
| 1547 | return (cancel ? make_number (0) : val); | 1607 | return (cancel ? make_number (0) : val); |
| @@ -2191,6 +2251,15 @@ The default is nil, which means use the function `read'."); | |||
| 2191 | Qget_file_char = intern ("get-file-char"); | 2251 | Qget_file_char = intern ("get-file-char"); |
| 2192 | staticpro (&Qget_file_char); | 2252 | staticpro (&Qget_file_char); |
| 2193 | 2253 | ||
| 2254 | Qbackquote = intern ("`"); | ||
| 2255 | staticpro (&Qbackquote); | ||
| 2256 | Qcomma = intern (","); | ||
| 2257 | staticpro (&Qcomma); | ||
| 2258 | Qcomma_at = intern (",@"); | ||
| 2259 | staticpro (&Qcomma_at); | ||
| 2260 | Qcomma_dot = intern (",."); | ||
| 2261 | staticpro (&Qcomma_dot); | ||
| 2262 | |||
| 2194 | Qascii_character = intern ("ascii-character"); | 2263 | Qascii_character = intern ("ascii-character"); |
| 2195 | staticpro (&Qascii_character); | 2264 | staticpro (&Qascii_character); |
| 2196 | 2265 | ||