Mercurial > hg > xemacs-beta
comparison src/elhash.c @ 4820:e6dec75ded0e
Use keywords, not ordinary symbols, in the structure syntax for hash tables.
lisp/ChangeLog addition:
2010-01-09 Aidan Kehoe <kehoea@parhasard.net>
* descr-text.el (describe-char-unihan-field-descriptions):
* cl-macs.el:
Use keywords, not ordinary symbols, in the hash table read syntax,
for compatibility with Common Lisp and recent GNU Emacs.
man/ChangeLog addition:
2010-01-09 Aidan Kehoe <kehoea@parhasard.net>
* lispref/objects.texi (Hash Table Type):
* lispref/hash-tables.texi (Introduction to Hash Tables):
Use keywords, not ordinary symbols, in the hash table read syntax;
document that we do accept the ordinary symbols for the sake of
backward-compatiblity.
2010-01-09 Aidan Kehoe <kehoea@parhasard.net>
* elhash.c:
(print_hash_table, print_hash_table_data)
(hash_table_instantiate)
(structure_type_create_hash_table_structure_name):
(syms_of_elhash):
Use keywords, not ordinary symbols, in the hash table read syntax,
for compatibility with Common Lisp and recent GNU Emacs. Accept
the non-keyword syntax, but don't allow mixing of the two styles.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 09 Jan 2010 17:28:51 +0000 |
parents | fd98353950a4 |
children | 6772ce4d982b 19a72041c5ed |
comparison
equal
deleted
inserted
replaced
4818:1360b0c147c1 | 4820:e6dec75ded0e |
---|---|
90 static Lisp_Object Qrehash_size, Qrehash_threshold; | 90 static Lisp_Object Qrehash_size, Qrehash_threshold; |
91 static Lisp_Object Q_size, Q_test, Q_weakness, Q_rehash_size, Q_rehash_threshold; | 91 static Lisp_Object Q_size, Q_test, Q_weakness, Q_rehash_size, Q_rehash_threshold; |
92 | 92 |
93 /* obsolete as of 19990901 in xemacs-21.2 */ | 93 /* obsolete as of 19990901 in xemacs-21.2 */ |
94 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qkey_or_value_weak; | 94 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qkey_or_value_weak; |
95 static Lisp_Object Qnon_weak, Q_type; | 95 static Lisp_Object Qnon_weak, Q_type, Q_data; |
96 | 96 |
97 struct Lisp_Hash_Table | 97 struct Lisp_Hash_Table |
98 { | 98 { |
99 struct LCRECORD_HEADER header; | 99 struct LCRECORD_HEADER header; |
100 Elemcount size; | 100 Elemcount size; |
302 | 302 |
303 This is non-trivial, because we use a readable structure-style | 303 This is non-trivial, because we use a readable structure-style |
304 syntax for hash tables. This means that a typical hash table will be | 304 syntax for hash tables. This means that a typical hash table will be |
305 readably printed in the form of: | 305 readably printed in the form of: |
306 | 306 |
307 #s(hash-table size 2 data (key1 value1 key2 value2)) | 307 #s(hash-table :size 2 :data (key1 value1 key2 value2)) |
308 | 308 |
309 The supported hash table structure keywords and their values are: | 309 The supported hash table structure keywords and their values are: |
310 `test' (eql (or nil), eq or equal) | 310 `:test' (eql (or nil), eq or equal) |
311 `size' (a natnum or nil) | 311 `:size' (a natnum or nil) |
312 `rehash-size' (a float) | 312 `:rehash-size' (a float) |
313 `rehash-threshold' (a float) | 313 `:rehash-threshold' (a float) |
314 `weakness' (nil, key, value, key-and-value, or key-or-value) | 314 `:weakness' (nil, key, value, key-and-value, or key-or-value) |
315 `data' (a list) | 315 `:data' (a list) |
316 | 316 |
317 If `print-readably' is nil, then a simpler syntax is used, for example | 317 If `print-readably' is nil, then a simpler syntax is used, for example |
318 | 318 |
319 #<hash-table size 2/13 data (key1 value1 key2 value2) 0x874d> | 319 #<hash-table size 2/13 data (key1 value1 key2 value2) 0x874d> |
320 | 320 |
328 print_hash_table_data (Lisp_Hash_Table *ht, Lisp_Object printcharfun) | 328 print_hash_table_data (Lisp_Hash_Table *ht, Lisp_Object printcharfun) |
329 { | 329 { |
330 int count = 0; | 330 int count = 0; |
331 htentry *e, *sentinel; | 331 htentry *e, *sentinel; |
332 | 332 |
333 write_c_string (printcharfun, " data ("); | 333 write_c_string (printcharfun, " :data ("); |
334 | 334 |
335 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) | 335 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) |
336 if (!HTENTRY_CLEAR_P (e)) | 336 if (!HTENTRY_CLEAR_P (e)) |
337 { | 337 { |
338 if (count > 0) | 338 if (count > 0) |
362 | 362 |
363 /* These checks have a kludgy look to them, but they are safe. | 363 /* These checks have a kludgy look to them, but they are safe. |
364 Due to nature of hashing, you cannot use arbitrary | 364 Due to nature of hashing, you cannot use arbitrary |
365 test functions anyway. */ | 365 test functions anyway. */ |
366 if (!ht->test_function) | 366 if (!ht->test_function) |
367 write_c_string (printcharfun, " test eq"); | 367 write_c_string (printcharfun, " :test eq"); |
368 else if (ht->test_function == lisp_object_equal_equal) | 368 else if (ht->test_function == lisp_object_equal_equal) |
369 write_c_string (printcharfun, " test equal"); | 369 write_c_string (printcharfun, " :test equal"); |
370 else if (ht->test_function == lisp_object_eql_equal) | 370 else if (ht->test_function == lisp_object_eql_equal) |
371 DO_NOTHING; | 371 DO_NOTHING; |
372 else | 372 else |
373 ABORT (); | 373 ABORT (); |
374 | 374 |
375 if (ht->count || !print_readably) | 375 if (ht->count || !print_readably) |
376 { | 376 { |
377 if (print_readably) | 377 if (print_readably) |
378 write_fmt_string (printcharfun, " size %ld", (long) ht->count); | 378 write_fmt_string (printcharfun, " :size %ld", (long) ht->count); |
379 else | 379 else |
380 write_fmt_string (printcharfun, " size %ld/%ld", (long) ht->count, | 380 write_fmt_string (printcharfun, " :size %ld/%ld", (long) ht->count, |
381 (long) ht->size); | 381 (long) ht->size); |
382 } | 382 } |
383 | 383 |
384 if (ht->weakness != HASH_TABLE_NON_WEAK) | 384 if (ht->weakness != HASH_TABLE_NON_WEAK) |
385 { | 385 { |
386 write_fmt_string | 386 write_fmt_string |
387 (printcharfun, " weakness %s", | 387 (printcharfun, " :weakness %s", |
388 (ht->weakness == HASH_TABLE_WEAK ? "key-and-value" : | 388 (ht->weakness == HASH_TABLE_WEAK ? "key-and-value" : |
389 ht->weakness == HASH_TABLE_KEY_WEAK ? "key" : | 389 ht->weakness == HASH_TABLE_KEY_WEAK ? "key" : |
390 ht->weakness == HASH_TABLE_VALUE_WEAK ? "value" : | 390 ht->weakness == HASH_TABLE_VALUE_WEAK ? "value" : |
391 ht->weakness == HASH_TABLE_KEY_VALUE_WEAK ? "key-or-value" : | 391 ht->weakness == HASH_TABLE_KEY_VALUE_WEAK ? "key-or-value" : |
392 "you-d-better-not-see-this")); | 392 "you-d-better-not-see-this")); |
393 } | 393 } |
394 | 394 |
395 if (ht->rehash_size != HASH_TABLE_DEFAULT_REHASH_SIZE) | 395 if (ht->rehash_size != HASH_TABLE_DEFAULT_REHASH_SIZE) |
396 { | 396 { |
397 float_to_string (pigbuf, ht->rehash_size); | 397 float_to_string (pigbuf, ht->rehash_size); |
398 write_fmt_string (printcharfun, " rehash-size %s", pigbuf); | 398 write_fmt_string (printcharfun, " :rehash-size %s", pigbuf); |
399 } | 399 } |
400 | 400 |
401 if (ht->rehash_threshold | 401 if (ht->rehash_threshold |
402 != HASH_TABLE_DEFAULT_REHASH_THRESHOLD (ht->size, | 402 != HASH_TABLE_DEFAULT_REHASH_THRESHOLD (ht->size, |
403 ht->test_function)) | 403 ht->test_function)) |
404 { | 404 { |
405 float_to_string (pigbuf, ht->rehash_threshold); | 405 float_to_string (pigbuf, ht->rehash_threshold); |
406 write_fmt_string (printcharfun, " rehash-threshold %s", pigbuf); | 406 write_fmt_string (printcharfun, " :rehash-threshold %s", pigbuf); |
407 } | 407 } |
408 | 408 |
409 if (ht->count) | 409 if (ht->count) |
410 print_hash_table_data (ht, printcharfun); | 410 print_hash_table_data (ht, printcharfun); |
411 | 411 |
843 Lisp_Object rehash_size = Qnil; | 843 Lisp_Object rehash_size = Qnil; |
844 Lisp_Object rehash_threshold = Qnil; | 844 Lisp_Object rehash_threshold = Qnil; |
845 Lisp_Object weakness = Qnil; | 845 Lisp_Object weakness = Qnil; |
846 Lisp_Object data = Qnil; | 846 Lisp_Object data = Qnil; |
847 | 847 |
848 PROPERTY_LIST_LOOP_3 (key, value, plist) | 848 if (KEYWORDP (Fcar (plist))) |
849 { | 849 { |
850 if (EQ (key, Qtest)) test = value; | 850 PROPERTY_LIST_LOOP_3 (key, value, plist) |
851 else if (EQ (key, Qsize)) size = value; | 851 { |
852 else if (EQ (key, Qrehash_size)) rehash_size = value; | 852 if (EQ (key, Q_test)) test = value; |
853 else if (EQ (key, Qrehash_threshold)) rehash_threshold = value; | 853 else if (EQ (key, Q_size)) size = value; |
854 else if (EQ (key, Qweakness)) weakness = value; | 854 else if (EQ (key, Q_rehash_size)) rehash_size = value; |
855 else if (EQ (key, Qdata)) data = value; | 855 else if (EQ (key, Q_rehash_threshold)) rehash_threshold = value; |
856 else if (EQ (key, Qtype))/*obsolete*/ weakness = value; | 856 else if (EQ (key, Q_weakness)) weakness = value; |
857 else | 857 else if (EQ (key, Q_data)) data = value; |
858 ABORT (); | 858 else if (!KEYWORDP (key)) |
859 signal_error (Qinvalid_read_syntax, | |
860 "can't mix keyword and non-keyword hash table syntax", | |
861 key); | |
862 else ABORT(); | |
863 } | |
864 } | |
865 else | |
866 { | |
867 PROPERTY_LIST_LOOP_3 (key, value, plist) | |
868 { | |
869 if (EQ (key, Qtest)) test = value; | |
870 else if (EQ (key, Qsize)) size = value; | |
871 else if (EQ (key, Qrehash_size)) rehash_size = value; | |
872 else if (EQ (key, Qrehash_threshold)) rehash_threshold = value; | |
873 else if (EQ (key, Qweakness)) weakness = value; | |
874 else if (EQ (key, Qdata)) data = value; | |
875 else if (EQ (key, Qtype))/*obsolete*/ weakness = value; | |
876 else if (KEYWORDP (key)) | |
877 signal_error (Qinvalid_read_syntax, | |
878 "can't mix keyword and non-keyword hash table syntax", | |
879 key); | |
880 else ABORT(); | |
881 } | |
859 } | 882 } |
860 | 883 |
861 /* Create the hash table. */ | 884 /* Create the hash table. */ |
862 hash_table = make_standard_lisp_hash_table | 885 hash_table = make_standard_lisp_hash_table |
863 (decode_hash_table_test (test), | 886 (decode_hash_table_test (test), |
889 structure_type_create_hash_table_structure_name (Lisp_Object structure_name) | 912 structure_type_create_hash_table_structure_name (Lisp_Object structure_name) |
890 { | 913 { |
891 struct structure_type *st; | 914 struct structure_type *st; |
892 | 915 |
893 st = define_structure_type (structure_name, 0, hash_table_instantiate); | 916 st = define_structure_type (structure_name, 0, hash_table_instantiate); |
917 | |
918 /* First the keyword syntax: */ | |
919 define_structure_type_keyword (st, Q_test, hash_table_test_validate); | |
920 define_structure_type_keyword (st, Q_size, hash_table_size_validate); | |
921 define_structure_type_keyword (st, Q_rehash_size, hash_table_rehash_size_validate); | |
922 define_structure_type_keyword (st, Q_rehash_threshold, hash_table_rehash_threshold_validate); | |
923 define_structure_type_keyword (st, Q_weakness, hash_table_weakness_validate); | |
924 define_structure_type_keyword (st, Q_data, hash_table_data_validate); | |
925 | |
926 /* Next the mutually exclusive, older, non-keyword syntax: */ | |
894 define_structure_type_keyword (st, Qtest, hash_table_test_validate); | 927 define_structure_type_keyword (st, Qtest, hash_table_test_validate); |
895 define_structure_type_keyword (st, Qsize, hash_table_size_validate); | 928 define_structure_type_keyword (st, Qsize, hash_table_size_validate); |
896 define_structure_type_keyword (st, Qrehash_size, hash_table_rehash_size_validate); | 929 define_structure_type_keyword (st, Qrehash_size, hash_table_rehash_size_validate); |
897 define_structure_type_keyword (st, Qrehash_threshold, hash_table_rehash_threshold_validate); | 930 define_structure_type_keyword (st, Qrehash_threshold, hash_table_rehash_threshold_validate); |
898 define_structure_type_keyword (st, Qweakness, hash_table_weakness_validate); | 931 define_structure_type_keyword (st, Qweakness, hash_table_weakness_validate); |
1849 DEFSYMBOL (Qkey_weak); /* obsolete */ | 1882 DEFSYMBOL (Qkey_weak); /* obsolete */ |
1850 DEFSYMBOL (Qkey_or_value_weak); /* obsolete */ | 1883 DEFSYMBOL (Qkey_or_value_weak); /* obsolete */ |
1851 DEFSYMBOL (Qvalue_weak); /* obsolete */ | 1884 DEFSYMBOL (Qvalue_weak); /* obsolete */ |
1852 DEFSYMBOL (Qnon_weak); /* obsolete */ | 1885 DEFSYMBOL (Qnon_weak); /* obsolete */ |
1853 | 1886 |
1887 DEFKEYWORD (Q_data); | |
1854 DEFKEYWORD (Q_test); | 1888 DEFKEYWORD (Q_test); |
1855 DEFKEYWORD (Q_size); | 1889 DEFKEYWORD (Q_size); |
1856 DEFKEYWORD (Q_rehash_size); | 1890 DEFKEYWORD (Q_rehash_size); |
1857 DEFKEYWORD (Q_rehash_threshold); | 1891 DEFKEYWORD (Q_rehash_threshold); |
1858 DEFKEYWORD (Q_weakness); | 1892 DEFKEYWORD (Q_weakness); |