summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-10-12 19:58:58 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-10-12 19:58:58 -0700
commitd499b2062a0f88be35a3ebb2e75c99c695f9f383 (patch)
tree5a8b2481c7db34e768ce550209c78bf90f6697eb
parent4cfe73161d6e00b583c452ef2502862c80d9ce9f (diff)
downloadtxr-d499b2062a0f88be35a3ebb2e75c99c695f9f383.tar.gz
txr-d499b2062a0f88be35a3ebb2e75c99c695f9f383.tar.bz2
txr-d499b2062a0f88be35a3ebb2e75c99c695f9f383.zip
Include user data in hash read syntax.
* hash.c (userdata_k): New keyword symbol variable. (hash_print_op): Print the userdata together with the hash flags as :userdata obj. (hashv): Parse out :userdata obj syntax from the argument list. This takes care of supporting it in the read notation and in the hash function. (hash_init): Initialize userdata_k. * txr.1: Documenting :userdata in hash read notation and hash function.
-rw-r--r--hash.c18
-rw-r--r--txr.130
2 files changed, 40 insertions, 8 deletions
diff --git a/hash.c b/hash.c
index 004cfd0f..18857053 100644
--- a/hash.c
+++ b/hash.c
@@ -41,6 +41,7 @@
#include "unwind.h"
#include "stream.h"
#include "eval.h"
+#include "cadr.h"
#include "hash.h"
typedef enum hash_flags {
@@ -71,7 +72,7 @@ struct hash_iter {
val cons;
};
-val weak_keys_k, weak_vals_k, equal_based_k;
+val weak_keys_k, weak_vals_k, equal_based_k, userdata_k;
/*
* Dynamic lists built up during gc.
@@ -394,6 +395,7 @@ static void hash_print_op(val hash, val out, val pretty)
if (h->flags != hash_weak_none) {
if (need_space)
put_char(chr(' '), out);
+ need_space = 1;
switch (h->flags) {
case hash_weak_both:
obj_print_impl(weak_keys_k, out, pretty);
@@ -408,6 +410,13 @@ static void hash_print_op(val hash, val out, val pretty)
break;
}
}
+ if (h->userdata) {
+ if (need_space)
+ put_char(chr(' '), out);
+ obj_print_impl(userdata_k, out, pretty);
+ put_char(chr(' '), out);
+ obj_print_impl(h->userdata, out, pretty);
+ }
put_string(lit(")"), out);
maphash(curry_123_23(func_n3(print_key_val), out), hash);
put_string(lit(")"), out);
@@ -982,7 +991,11 @@ val hashv(struct args *args)
val wkeys = memq(weak_keys_k, arglist);
val wvals = memq(weak_vals_k, arglist);
val equal = memq(equal_based_k, arglist);
- return make_hash(wkeys, wvals, equal);
+ val userdata = cadr(memq(userdata_k, arglist));
+ val hash = make_hash(wkeys, wvals, equal);
+ if (userdata)
+ set_hash_userdata(hash, userdata);
+ return hash;
}
val hashl(val arglist)
@@ -1340,6 +1353,7 @@ void hash_init(void)
weak_keys_k = intern(lit("weak-keys"), keyword_package);
weak_vals_k = intern(lit("weak-vals"), keyword_package);
equal_based_k = intern(lit("equal-based"), keyword_package);
+ userdata_k = intern(lit("userdata"), keyword_package);
reg_fun(intern(lit("make-hash"), user_package), func_n3(make_hash));
reg_fun(intern(lit("make-similar-hash"), user_package), func_n1(make_similar_hash));
diff --git a/txr.1 b/txr.1
index 095fa482..c6842dd4 100644
--- a/txr.1
+++ b/txr.1
@@ -10414,9 +10414,19 @@ The first item in the syntax is a list of keywords. These are the same
keywords as are used when calling the function hash to construct
a hash table. Allowed keywords are:
.codn :equal-based ,
-.code :weak-keys
+.codn :weak-keys ,
+.codn :weak-values ,
and
-.codn :weak-values .
+.codn :userdata .
+If the
+.code :userdata
+keyword is present,
+it must be followed by an object; that object
+specifies the hash table's user data, which
+can be retrieved using the
+.code get-hash-userdata
+function.
+
An empty list can be specified as
.code nil
or
@@ -33159,7 +33169,8 @@ and
.coNP Functions @ make-hash and @ hash
.synb
.mets (make-hash < weak-keys < weak-vals << equal-based )
-.mets (hash { :weak-keys | :weak-vals | :equal-based }*)
+.mets (hash {:weak-keys | :weak-vals | :equal-based |
+.mets \ \ \ \ \ \ :userdata << obj }*)
.syne
.desc
These functions construct a new hash table.
@@ -33190,15 +33201,22 @@ It is an error to attempt to construct an
hash table which has weak keys.
The hash function provides an alternative interface. It accepts optional
-arguments which are keyword symbols. Any combination of the three symbols
+arguments which are keyword symbols. Any combination of the four symbols
.codn :weak-keys ,
-.code :weak-vals
-and
+.codn :weak-vals ,
.code :equal-based
+and
+.code :userdata
can be specified in any order
to turn on the corresponding properties in the newly constructed hash table.
If any of the keywords is not specified, the corresponding property defaults to
.codn nil .
+If
+.code :userdata
+is present, it must be followed by an argument value; that value
+specifies the user data for the hash table, which can be retrieved using the
+.code get-hash-userdata
+function.
If a hash table has weak keys, this means that from the point of view
of garbage collection, that table holds only weak references to the keys