Mercurial > emacs
comparison src/lread.c @ 11683:355d0b23a080
(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.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Thu, 04 May 1995 17:13:20 +0000 |
parents | 864c3dea8754 |
children | eb4b842ee557 |
comparison
equal
deleted
inserted
replaced
11682:7eda6c1f3d5e | 11683:355d0b23a080 |
---|---|
66 extern int errno; | 66 extern int errno; |
67 | 67 |
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 |
74 /* non-zero if inside `load' */ | 75 /* non-zero if inside `load' */ |
75 int load_in_progress; | 76 int load_in_progress; |
100 static int read_pure; | 101 static int read_pure; |
101 | 102 |
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, |
108 UNREAD(c) to unread c to be read again. */ | 115 UNREAD(c) to unread c to be read again. */ |
109 | 116 |
890 if (NILP (readcharfun)) | 897 if (NILP (readcharfun)) |
891 readcharfun = Vstandard_input; | 898 readcharfun = Vstandard_input; |
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); |
898 #endif | 907 #endif |
899 | 908 |
935 } | 944 } |
936 | 945 |
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 } |
943 | 954 |
944 /* Use this for recursive reads, in contexts where internal tokens | 955 /* Use this for recursive reads, in contexts where internal tokens |
948 Lisp_Object readcharfun; | 959 Lisp_Object readcharfun; |
949 { | 960 { |
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 |
957 return val; | 968 return val; |
958 } | 969 } |
1115 } | 1126 } |
1116 } | 1127 } |
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; |
1128 | 1143 |
1129 retry: | 1144 retry: |
1163 Lisp_Object tmp; | 1178 Lisp_Object tmp; |
1164 struct gcpro gcpro1; | 1179 struct gcpro gcpro1; |
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); |
1172 /* Read the intervals and their properties. */ | 1187 /* Read the intervals and their properties. */ |
1173 while (1) | 1188 while (1) |
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"), |
1187 Qnil)); | 1202 Qnil)); |
1188 Fset_text_properties (beg, end, plist, tmp); | 1203 Fset_text_properties (beg, end, plist, tmp); |
1225 | 1240 |
1226 case '\'': | 1241 case '\'': |
1227 { | 1242 { |
1228 return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil)); | 1243 return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil)); |
1229 } | 1244 } |
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; | |
1230 | 1284 |
1231 case '?': | 1285 case '?': |
1232 { | 1286 { |
1233 register Lisp_Object val; | 1287 register Lisp_Object val; |
1234 | 1288 |
1317 /* Otherwise, we fall through! Note that the atom-reading loop | 1371 /* Otherwise, we fall through! Note that the atom-reading loop |
1318 below will now loop at least once, assuring that we will not | 1372 below will now loop at least once, assuring that we will not |
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; |
1325 int quoted = 0; | 1380 int quoted = 0; |
1326 | 1381 |
1504 Lisp_Object val, tail; | 1559 Lisp_Object val, tail; |
1505 register Lisp_Object elt, tem; | 1560 register Lisp_Object elt, tem; |
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 |
1512 while (1) | 1570 while (1) |
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; |
1576 | |
1577 first_in_list = 0; | |
1518 | 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, |
1522 so don't waste pure space with it. */ | 1582 so don't waste pure space with it. */ |
1539 GCPRO2 (val, tail); | 1599 GCPRO2 (val, tail); |
1540 if (!NILP (tail)) | 1600 if (!NILP (tail)) |
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); |
1548 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (". in wrong context", 18), Qnil)); | 1608 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (". in wrong context", 18), Qnil)); |
1549 } | 1609 } |
2189 staticpro (&Qread_char); | 2249 staticpro (&Qread_char); |
2190 | 2250 |
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 |
2197 Qload = intern ("load"); | 2266 Qload = intern ("load"); |
2198 staticpro (&Qload); | 2267 staticpro (&Qload); |