summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eval.c2
-rw-r--r--lib.c57
-rw-r--r--lib.h3
-rw-r--r--txr.158
4 files changed, 111 insertions, 9 deletions
diff --git a/eval.c b/eval.c
index af3bea23..1e9a5d76 100644
--- a/eval.c
+++ b/eval.c
@@ -6627,6 +6627,8 @@ void eval_init(void)
reg_fun(intern(lit("unuse-package"), user_package), func_n2o(unuse_package, 1));
reg_fun(intern(lit("intern"), user_package), func_n2o(intern, 1));
reg_fun(intern(lit("unintern"), user_package), func_n2o(unintern, 1));
+ reg_fun(intern(lit("find-symbol"), user_package), func_n3o(find_symbol, 1));
+ reg_fun(intern(lit("find-symbol-fb"), user_package), func_n3o(find_symbol_fb, 1));
reg_fun(intern(lit("rehome-sym"), user_package), func_n2o(rehome_sym, 1));
reg_fun(intern(lit("package-fallback-list"), user_package), func_n1(package_fallback_list));
reg_fun(intern(lit("set-package-fallback-list"), user_package), func_n2(set_package_fallback_list));
diff --git a/lib.c b/lib.c
index 5a99d1b0..e2683245 100644
--- a/lib.c
+++ b/lib.c
@@ -5337,19 +5337,60 @@ val symbol_needs_prefix(val self, val package, val sym)
return sym_pkg->pk.name;
}
-val find_symbol(val str, val package_in)
+val find_symbol(val name, val package_in, val notfound_val_in)
{
val self = lit("find-symbol");
- val package = get_package(self, package_in, nil);
- val found;
+ val package = get_package(self, package_in, t);
- if (!stringp(str))
- uw_throwf(error_s, lit("~a: name ~s isn't a string"), self, str, nao);
+ if (!stringp(name))
+ uw_throwf(error_s, lit("~a: name ~s isn't a string"), self, name, nao);
+
+ {
+ val cell = gethash_e(self, package->pk.symhash, name);
+ if (cell)
+ return cdr(cell);
+ }
+
+ {
+ val fallback = get_hash_userdata(package->pk.symhash);
+
+ for (; fallback; fallback = cdr(fallback)) {
+ val fb_pkg = car(fallback);
+ val cell = gethash_e(self, fb_pkg->pk.symhash, name);
+ if (cell)
+ return cdr(cell);
+ }
+ }
- if ((found = gethash_e(self, package->pk.symhash, str)))
- return cdr(found);
+ return default_null_arg(notfound_val_in);
+}
+
+val find_symbol_fb(val name, val package_in, val notfound_val_in)
+{
+ val self = lit("find-symbol-fb");
+ val package = get_package(self, package_in, t);
+
+ if (!stringp(name))
+ uw_throwf(error_s, lit("~a: name ~s isn't a string"), self, name, nao);
+
+ {
+ val cell = gethash_e(self, package->pk.symhash, name);
+ if (cell)
+ return cdr(cell);
+ }
+
+ {
+ val fallback = get_hash_userdata(package->pk.symhash);
+
+ for (; fallback; fallback = cdr(fallback)) {
+ val fb_pkg = car(fallback);
+ val cell = gethash_e(self, fb_pkg->pk.symhash, name);
+ if (cell)
+ return cdr(cell);
+ }
+ }
- return zero;
+ return default_null_arg(notfound_val_in);
}
val intern(val str, val package_in)
diff --git a/lib.h b/lib.h
index c7296b7b..c22e9890 100644
--- a/lib.h
+++ b/lib.h
@@ -891,7 +891,8 @@ val use_package(val use_list, val package);
val unuse_package(val unuse_list, val package);
val symbol_visible(val package, val sym);
val symbol_needs_prefix(val self, val package, val sym);
-val find_symbol(val str, val package);
+val find_symbol(val name, val package, val notfound_val);
+val find_symbol_fb(val name, val package, val notfound_val);
val intern(val str, val package);
val unintern(val sym, val package);
val rehome_sym(val sym, val package);
diff --git a/txr.1 b/txr.1
index 06cb8305..edf1beab 100644
--- a/txr.1
+++ b/txr.1
@@ -51096,6 +51096,64 @@ is not found in the package as either an interned or hidden
symbol, then the function has no effect and returns
.codn nil .
+.coNP Functions @ find-symbol and @ find-symbol-fb
+.synb
+.mets (find-symbol < name >> [ package <> [ notfound-val ]])
+.mets (find-symbol-fb < name >> [ package <> [ notfound-val ]])
+.syne
+.desc
+The
+.code find-symbol
+and
+.code find-symbol-fb
+functions search
+.meta package
+for a symbol called
+.metn name .
+That argument must be a character string.
+
+If the
+.meta package
+argument is omitted, the parameter defaults to the
+current value of
+.codn *package* .
+
+If the symbol is found in
+.meta package
+then it is returned.
+
+If the symbol is not found in
+.metn package ,
+then the function
+.code find-symbol-fb
+also searches the packages listed in the fallback list of
+.meta package
+are searched, in order. Only these packages themselves are searched,
+not their own fallback lists. If a symbol called
+.meta name
+is found, the search terminates and that symbol is returned.
+
+The function
+.code find-symbol
+only searches
+.metn package ,
+ignoring its fallback list.
+
+If a symbol called
+.meta name
+isn't found, then these functions return
+.meta notfound-val
+is returned, which defaults to
+.codn nil .
+
+Note: an ambiguous situation exists when
+.meta notfound-val
+is a symbol, such as its default value
+.codn nil ,
+because if that symbol is successfully found,
+it is indistinguishable from
+.metn notfound-val .
+
.coNP Function @ rehome-sym
.synb
.mets (rehome-sym < symbol <> [ package ])