summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-11-16 05:32:47 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-11-16 05:32:47 -0800
commitcf0ac2826bc7dc06d3c63e956ec8922a358f4f80 (patch)
tree50063036810b493a2bca9d5892ea992f02d82360 /lib.c
parent704664e60d7d548d9ce5c44b34d0d2b60db1e31c (diff)
downloadtxr-cf0ac2826bc7dc06d3c63e956ec8922a358f4f80.tar.gz
txr-cf0ac2826bc7dc06d3c63e956ec8922a358f4f80.tar.bz2
txr-cf0ac2826bc7dc06d3c63e956ec8922a358f4f80.zip
Start of fallback package list implementation.
* eval.c (eval_init): Register package-fallback-list and set-package-fallback-list intrinsics. * lib.c (package_fallback_list, set_package_fallback_list, intern_fallback): New functions * lib.h (package_fallback_list, set_package_fallback_list, intern_fallback): Declared. * parser.y (sym_helper): Slightly restructure function so that the symbol interning is done separately in the various cases. In the unqualified symbol case, use intern_fallback to search the fallback list of the current package. * share/txr/stdlib/package.tl (defpackage): Implement :fallback clause.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index cdc6564b..233e3d3b 100644
--- a/lib.c
+++ b/lib.c
@@ -5089,6 +5089,59 @@ val rehome_sym(val sym, val package_in)
return sym;
}
+val package_fallback_list(val package_in)
+{
+ val package = get_package(lit("package-fallback-list"), package_in, t);
+ return get_hash_userdata(package->pk.symhash);
+}
+
+val set_package_fallback_list(val package_in, val list_in)
+{
+ val self = lit("set-package-fallback-list");
+ val package = get_package(self, package_in, t);
+ val list = resolve_package_designators(self, list_in);
+ return set_hash_userdata(package->pk.symhash, list);
+}
+
+val intern_fallback(val str, val package_in)
+{
+ val self = lit("intern-fallback");
+ val package = get_package(self, package_in, nil);
+ val fblist = get_hash_userdata(package->pk.symhash);
+
+ if (!stringp(str))
+ uw_throwf(error_s, lit("~s: name ~s isn't a string"), self, str, nao);
+
+ if (fblist) {
+ val found;
+ val sym;
+
+ if ((sym = gethash_f(package->pk.symhash, str, mkcloc(found))) || found)
+ return sym;
+
+ for (; fblist; fblist = cdr(fblist)) {
+ val otherpkg = car(fblist);
+ if ((sym = gethash_f(otherpkg->pk.symhash, str, mkcloc(found))) || found)
+ return sym;
+ }
+ }
+
+ {
+ val new_p;
+ loc place;
+
+ place = gethash_l(package->pk.symhash, str, mkcloc(new_p));
+
+ if (!new_p) {
+ return deref(place);
+ } else {
+ val newsym = make_sym(str);
+ newsym->s.package = package;
+ return set(place, newsym);
+ }
+ }
+}
+
val symbolp(val sym)
{
switch (type(sym)) {