summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-02-23 06:19:50 -0800
committerKaz Kylheku <kaz@kylheku.com>2019-02-23 06:19:50 -0800
commit9a53386f3b8b6b41982decf162e4cd271d01ec97 (patch)
tree74085af7b6feefc200e1509f831b234f8bcbd53d /lib.c
parent6af39064ca9d9a78d0e12e64cb817f9080cf3793 (diff)
downloadtxr-9a53386f3b8b6b41982decf162e4cd271d01ec97.tar.gz
txr-9a53386f3b8b6b41982decf162e4cd271d01ec97.tar.bz2
txr-9a53386f3b8b6b41982decf162e4cd271d01ec97.zip
printer: revise package prefix decision.
* lib.c (symbol_needs_prefix): revisiting the wrongheaded requirements codified in 7bc150f, because the ergonomics is bad. In a package that has a local symbol that has the same name as one in a fallback list, that symbol is always printed with a prefix, which is annoying. The new rules are simple: if the symbol being printed is the one which is visible, then it gets no package prefix. Also, this function now handles the full responsibility for the prefix calculation, including for keyword symbols and uninterned symbools. It returns nil to indicate no prefix is needed, or else a character string. Moreover, logic is added to detect symbols which have a home package, but are uninterned from it, which should be printed with the "#" prefix. Lastly, this function is optimized to avoid unnecessary gethash operations. If a symbol S's home package is P, and P contains no hidden symbols (overwhelmingly common situation), then S is interned in P; no need to do the hash lookup to check this. (obj_print_impl): Symbol printing simplified: if symbol_needs_refix returns non-nil, that string value is the prefix.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c74
1 files changed, 50 insertions, 24 deletions
diff --git a/lib.c b/lib.c
index 6e776bb9..00807a85 100644
--- a/lib.c
+++ b/lib.c
@@ -5557,40 +5557,68 @@ val symbol_visible(val package, val sym)
val symbol_needs_prefix(val self, val package, val sym)
{
val name = symbol_name(sym);
+ val sym_pkg = sym->s.package;
type_check (self, package, PKG);
+ if (!sym_pkg)
+ return lit("#");
+
+ if (sym_pkg == keyword_package)
+ return null_string;
+
+ if (sym_pkg == package) {
+ if (us_hash_count(package->pk.hidhash) != zero) {
+ val here_cell = gethash_e(self, package->pk.symhash, name);
+
+ if (here_cell) {
+ int found_here = (eq(cdr(here_cell), sym) != nil);
+ if (found_here)
+ return nil;
+ }
+
+ return lit("#");
+ }
+
+ return nil;
+ }
+
{
- int homed_here = (sym->s.package == package);
- val home_cell = gethash_e(self, package->pk.symhash, name);
- int present_here = (eq(cdr(home_cell), sym) != nil);
val fallback = get_hash_userdata(package->pk.symhash);
- val fb_cell = nil;
- int in_fallback = 0;
for (; fallback; fallback = cdr(fallback)) {
val fb_pkg = car(fallback);
- val cell = gethash_e(self, fb_pkg->pk.symhash, name);
- if (cell) {
- fb_cell = cell;
- if (eq(cdr(cell), sym) != nil) {
- in_fallback = 1;
- break;
+ if (sym_pkg == fb_pkg) {
+ if (us_hash_count(fb_pkg->pk.hidhash) != zero) {
+ val cell = gethash_e(self, fb_pkg->pk.symhash, name);
+ if (cell) {
+ int found_in_fallback = (eq(cdr(cell), sym) != nil);
+ if (found_in_fallback)
+ return nil;
+ break;
+ }
}
+ return nil;
+ } else {
+ if (gethash_e(self, fb_pkg->pk.symhash, name))
+ break;
}
}
+ }
- if (!homed_here && !present_here && !in_fallback)
- return t;
+ if (us_hash_count(sym_pkg->pk.hidhash) != zero) {
+ val home_cell = gethash_e(self, sym_pkg->pk.symhash, name);
- if ((homed_here || present_here) && fb_cell)
- return t;
+ if (home_cell) {
+ int found_in_home = (eq(cdr(home_cell), sym) != nil);
+ if (found_in_home)
+ return sym_pkg->pk.name;
+ }
- if (in_fallback && home_cell)
- return t;
+ return lit("#");
}
- return nil;
+ return sym_pkg->pk.name;
}
val find_symbol(val str, val package_in)
@@ -11504,12 +11532,10 @@ dot:
if (obj->s.package == keyword_package)
put_char(chr(':'), out);
} else {
- if (!obj->s.package) {
- put_string(lit("#:"), out);
- } else if (obj->s.package == keyword_package) {
- put_char(chr(':'), out);
- } else if (symbol_needs_prefix(lit("print"), cur_package, obj)) {
- put_string(obj->s.package->pk.name, out);
+ val prefix = symbol_needs_prefix(lit("print"), cur_package, obj);
+
+ if (prefix) {
+ put_string(prefix, out);
put_char(chr(':'), out);
}
}