diff options
| author | Erik Naggum | 1996-09-09 02:30:05 +0000 |
|---|---|---|
| committer | Erik Naggum | 1996-09-09 02:30:05 +0000 |
| commit | 4ad679f96da97825a435291c5fb820810e10495b (patch) | |
| tree | cb04ae54720f48bc78341d92c09b3ee8c7ea373f /src | |
| parent | 081e0581b6c36a417d9d1de2fee438c110e4a859 (diff) | |
| download | emacs-4ad679f96da97825a435291c5fb820810e10495b.tar.gz emacs-4ad679f96da97825a435291c5fb820810e10495b.zip | |
Add #n=object, #n#, and #:symbol constructs to reader.
(readevalloop, read, Fread_from_string): Empty list of read objects before
read0 call.
(read1): New variable `uninterned_symbol', which controls how to make
symbols. Support #:, #n=object and #n#.
(make_symbol): New function, used in read1 to make uninterned symbols
(Fintern): Set `obarray' field of interned symbols.
(init_obarray): Explicit set `obarray' field of symbol `nil'.
(syms_of_lread): staticpro read_objects, the list of read objects.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lread.c | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/src/lread.c b/src/lread.c index 21f32863f98..2272b81149e 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -98,6 +98,12 @@ Lisp_Object Vload_file_name; | |||
| 98 | /* Function to use for reading, in `load' and friends. */ | 98 | /* Function to use for reading, in `load' and friends. */ |
| 99 | Lisp_Object Vload_read_function; | 99 | Lisp_Object Vload_read_function; |
| 100 | 100 | ||
| 101 | /* The association list of objects read with the #n=object form. | ||
| 102 | Each member of the list has the form (n . object), and is used to | ||
| 103 | look up the object for the corresponding #n# construct. | ||
| 104 | It must be set to nil before all top-level calls to read0. */ | ||
| 105 | Lisp_Object read_objects; | ||
| 106 | |||
| 101 | /* Nonzero means load should forcibly load all dynamic doc strings. */ | 107 | /* Nonzero means load should forcibly load all dynamic doc strings. */ |
| 102 | static int load_force_doc_strings; | 108 | static int load_force_doc_strings; |
| 103 | 109 | ||
| @@ -802,6 +808,7 @@ readevalloop (readcharfun, stream, sourcename, evalfun, printflag) | |||
| 802 | else | 808 | else |
| 803 | { | 809 | { |
| 804 | UNREAD (c); | 810 | UNREAD (c); |
| 811 | read_objects = Qnil; | ||
| 805 | if (NILP (Vload_read_function)) | 812 | if (NILP (Vload_read_function)) |
| 806 | val = read0 (readcharfun); | 813 | val = read0 (readcharfun); |
| 807 | else | 814 | else |
| @@ -949,6 +956,7 @@ STREAM or the value of `standard-input' may be:\n\ | |||
| 949 | stream = Qread_char; | 956 | stream = Qread_char; |
| 950 | 957 | ||
| 951 | new_backquote_flag = 0; | 958 | new_backquote_flag = 0; |
| 959 | read_objects = Qnil; | ||
| 952 | 960 | ||
| 953 | #ifndef standalone | 961 | #ifndef standalone |
| 954 | if (EQ (stream, Qread_char)) | 962 | if (EQ (stream, Qread_char)) |
| @@ -996,6 +1004,7 @@ START and END optionally delimit a substring of STRING from which to read;\n\ | |||
| 996 | read_from_string_limit = endval; | 1004 | read_from_string_limit = endval; |
| 997 | 1005 | ||
| 998 | new_backquote_flag = 0; | 1006 | new_backquote_flag = 0; |
| 1007 | read_objects = Qnil; | ||
| 999 | 1008 | ||
| 1000 | tem = read0 (string); | 1009 | tem = read0 (string); |
| 1001 | return Fcons (tem, make_number (read_from_string_index)); | 1010 | return Fcons (tem, make_number (read_from_string_index)); |
| @@ -1191,6 +1200,8 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1191 | int first_in_list; | 1200 | int first_in_list; |
| 1192 | { | 1201 | { |
| 1193 | register int c; | 1202 | register int c; |
| 1203 | int uninterned_symbol = 0; | ||
| 1204 | |||
| 1194 | *pch = 0; | 1205 | *pch = 0; |
| 1195 | 1206 | ||
| 1196 | retry: | 1207 | retry: |
| @@ -1353,7 +1364,43 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1353 | return Vload_file_name; | 1364 | return Vload_file_name; |
| 1354 | if (c == '\'') | 1365 | if (c == '\'') |
| 1355 | return Fcons (Qfunction, Fcons (read0 (readcharfun), Qnil)); | 1366 | return Fcons (Qfunction, Fcons (read0 (readcharfun), Qnil)); |
| 1367 | /* #:foo is the uninterned symbol named foo. */ | ||
| 1368 | if (c == ':') | ||
| 1369 | { | ||
| 1370 | uninterned_symbol = 1; | ||
| 1371 | c = READCHAR; | ||
| 1372 | goto default_label; | ||
| 1373 | } | ||
| 1374 | /* Reader forms that can reuse previously read objects. */ | ||
| 1375 | if (c >= '0' && c <= '9') | ||
| 1376 | { | ||
| 1377 | int n = 0; | ||
| 1378 | Lisp_Object tem; | ||
| 1356 | 1379 | ||
| 1380 | /* Read a non-negative integer. */ | ||
| 1381 | while (c >= '0' && c <= '9') | ||
| 1382 | { | ||
| 1383 | n *= 10; | ||
| 1384 | n += c - '0'; | ||
| 1385 | c = READCHAR; | ||
| 1386 | } | ||
| 1387 | /* #n=object returns object, but associates it with n for #n#. */ | ||
| 1388 | if (c == '=') | ||
| 1389 | { | ||
| 1390 | tem = read0 (readcharfun); | ||
| 1391 | read_objects = Fcons (Fcons (make_number (n), tem), read_objects); | ||
| 1392 | return tem; | ||
| 1393 | } | ||
| 1394 | /* #n# returns a previously read object. */ | ||
| 1395 | if (c == '#') | ||
| 1396 | { | ||
| 1397 | tem = Fassq (make_number (n), read_objects); | ||
| 1398 | if (CONSP (tem)) | ||
| 1399 | return XCDR (tem); | ||
| 1400 | /* Fall through to error message. */ | ||
| 1401 | } | ||
| 1402 | /* Fall through to error message. */ | ||
| 1403 | } | ||
| 1357 | 1404 | ||
| 1358 | UNREAD (c); | 1405 | UNREAD (c); |
| 1359 | Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil)); | 1406 | Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil)); |
| @@ -1545,7 +1592,7 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1545 | UNREAD (c); | 1592 | UNREAD (c); |
| 1546 | } | 1593 | } |
| 1547 | 1594 | ||
| 1548 | if (!quoted) | 1595 | if (!quoted && !uninterned_symbol) |
| 1549 | { | 1596 | { |
| 1550 | register char *p1; | 1597 | register char *p1; |
| 1551 | register Lisp_Object val; | 1598 | register Lisp_Object val; |
| @@ -1581,7 +1628,10 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1581 | #endif | 1628 | #endif |
| 1582 | } | 1629 | } |
| 1583 | 1630 | ||
| 1584 | return intern (read_buffer); | 1631 | if (uninterned_symbol) |
| 1632 | return make_symbol (read_buffer); | ||
| 1633 | else | ||
| 1634 | return intern (read_buffer); | ||
| 1585 | } | 1635 | } |
| 1586 | } | 1636 | } |
| 1587 | } | 1637 | } |
| @@ -1865,6 +1915,19 @@ intern (str) | |||
| 1865 | : make_string (str, len)), | 1915 | : make_string (str, len)), |
| 1866 | obarray); | 1916 | obarray); |
| 1867 | } | 1917 | } |
| 1918 | |||
| 1919 | /* Create an uninterned symbol with name STR. */ | ||
| 1920 | |||
| 1921 | Lisp_Object | ||
| 1922 | make_symbol (str) | ||
| 1923 | char *str; | ||
| 1924 | { | ||
| 1925 | int len = strlen (str); | ||
| 1926 | |||
| 1927 | return Fmake_symbol ((!NILP (Vpurify_flag) | ||
| 1928 | ? make_pure_string (str, len) | ||
| 1929 | : make_string (str, len))); | ||
| 1930 | } | ||
| 1868 | 1931 | ||
| 1869 | DEFUN ("intern", Fintern, Sintern, 1, 2, 0, | 1932 | DEFUN ("intern", Fintern, Sintern, 1, 2, 0, |
| 1870 | "Return the canonical symbol whose name is STRING.\n\ | 1933 | "Return the canonical symbol whose name is STRING.\n\ |
| @@ -1888,6 +1951,7 @@ it defaults to the value of `obarray'.") | |||
| 1888 | if (!NILP (Vpurify_flag)) | 1951 | if (!NILP (Vpurify_flag)) |
| 1889 | string = Fpurecopy (string); | 1952 | string = Fpurecopy (string); |
| 1890 | sym = Fmake_symbol (string); | 1953 | sym = Fmake_symbol (string); |
| 1954 | XSYMBOL (sym)->obarray = obarray; | ||
| 1891 | 1955 | ||
| 1892 | ptr = &XVECTOR (obarray)->contents[XINT (tem)]; | 1956 | ptr = &XVECTOR (obarray)->contents[XINT (tem)]; |
| 1893 | if (SYMBOLP (*ptr)) | 1957 | if (SYMBOLP (*ptr)) |
| @@ -2103,6 +2167,7 @@ init_obarray () | |||
| 2103 | initial_obarray = Vobarray; | 2167 | initial_obarray = Vobarray; |
| 2104 | staticpro (&initial_obarray); | 2168 | staticpro (&initial_obarray); |
| 2105 | /* Intern nil in the obarray */ | 2169 | /* Intern nil in the obarray */ |
| 2170 | XSYMBOL (Qnil)->obarray = Vobarray; | ||
| 2106 | /* These locals are to kludge around a pyramid compiler bug. */ | 2171 | /* These locals are to kludge around a pyramid compiler bug. */ |
| 2107 | hash = hash_string ("nil", 3); | 2172 | hash = hash_string ("nil", 3); |
| 2108 | /* Separate statement here to avoid VAXC bug. */ | 2173 | /* Separate statement here to avoid VAXC bug. */ |
| @@ -2505,4 +2570,7 @@ You cannot count on them to still be there!"); | |||
| 2505 | staticpro (&Qload_file_name); | 2570 | staticpro (&Qload_file_name); |
| 2506 | 2571 | ||
| 2507 | staticpro (&dump_path); | 2572 | staticpro (&dump_path); |
| 2573 | |||
| 2574 | staticpro (&read_objects); | ||
| 2575 | read_objects = Qnil; | ||
| 2508 | } | 2576 | } |