diff options
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | lib.c | 57 | ||||
-rw-r--r-- | lib.h | 3 | ||||
-rw-r--r-- | txr.1 | 58 |
4 files changed, 111 insertions, 9 deletions
@@ -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)); @@ -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) @@ -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); @@ -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 ]) |