summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-07-12 11:29:33 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-07-12 11:29:33 -0700
commit15740ae6b6c8476cd1a9323ffd50f85a3c8ea245 (patch)
treef5eac0226a4e57e1383771c862a23efc0eddfb93 /lib.c
parenta6f6072761d124c60793325bc512048b0f31f5a3 (diff)
downloadtxr-15740ae6b6c8476cd1a9323ffd50f85a3c8ea245.tar.gz
txr-15740ae6b6c8476cd1a9323ffd50f85a3c8ea245.tar.bz2
txr-15740ae6b6c8476cd1a9323ffd50f85a3c8ea245.zip
Support weak semantics in symbol packages.
A package is weak if it holds weak references to symbols, meaning that if there are no references to a symbol other than its entry in a weak package, it can be removed from the package and reclaimed by the garbage collector. * eval.c (eval_init): Update registrations for make-package and sys:make-anon-package to reflect new optional argument. * lib.c (make_package_common): New argument weak. If it is true then both the hashes will have weak values. (make_package, make_anon_package): New optional argument weak. (obj_init): Add nil argument to calls to make_package. All the standard packages are regular, not weak. * lib.h (make_package, make_anon_package): Declarations updated. * txr.1: Documented.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/lib.c b/lib.c
index c1be0e29..4fcd12cc 100644
--- a/lib.c
+++ b/lib.c
@@ -5910,10 +5910,11 @@ val gensym(val prefix)
return make_sym(name);
}
-static val make_package_common(val name)
+static val make_package_common(val name, val weak)
{
- val sh = make_hash(nil, nil, lit("t")); /* don't have t yet! */
- val hh = make_hash(nil, nil, lit("t"));
+ val weak_vals = default_null_arg(weak);
+ val sh = make_hash(nil, weak_vals, lit("t")); /* don't have t yet! */
+ val hh = make_hash(nil, weak_vals, lit("t"));
val obj = make_obj();
obj->pk.type = PKG;
obj->pk.name = name;
@@ -5922,7 +5923,7 @@ static val make_package_common(val name)
return obj;
}
-val make_package(val name)
+val make_package(val name, val weak)
{
if (find_package(name)) {
uw_throwf(error_s, lit("make-package: ~s exists already"), name, nao);
@@ -5932,15 +5933,15 @@ val make_package(val name)
uw_throwf(error_s, lit("make-package: package name can't be empty string"),
nao);
} else {
- val obj = make_package_common(name);
+ val obj = make_package_common(name, weak);
mpush(cons(name, obj), cur_package_alist_loc);
return obj;
}
}
-val make_anon_package(void)
+val make_anon_package(val weak)
{
- return make_package_common(lit("#<anon-package>"));
+ return make_package_common(lit("#<anon-package>"), weak);
}
val packagep(val obj)
@@ -11878,10 +11879,10 @@ static void obj_init(void)
null_list = cons(nil, nil);
hash_s = make_sym(lit("hash"));
- system_package = make_package(lit("sys"));
- keyword_package = make_package(lit("keyword"));
- user_package = make_package(lit("usr"));
- public_package = make_package(lit("pub"));
+ system_package = make_package(lit("sys"), nil);
+ keyword_package = make_package(lit("keyword"), nil);
+ user_package = make_package(lit("usr"), nil);
+ public_package = make_package(lit("pub"), nil);
rehome_sym(hash_s, user_package);