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);