summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-11-30 06:11:09 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-11-30 06:11:09 -0800
commitd2e883cf32ea9fa82f33768104bc5993bfc60a04 (patch)
tree66a11ab2a82ffa84b1047c5d2485f53b50acbb4a
parent72955500f8b3a5bc52585d3f24aa3d71bdca3b19 (diff)
downloadtxr-d2e883cf32ea9fa82f33768104bc5993bfc60a04.tar.gz
txr-d2e883cf32ea9fa82f33768104bc5993bfc60a04.tar.bz2
txr-d2e883cf32ea9fa82f33768104bc5993bfc60a04.zip
func-get-name calculates a name for methods.
* eval.c (func_get_name): Use try to use new method_name function, if unable to get name from the lexical or global environment for functions. * struct.c (meth_s): New symbol variable. (struct_init): Initialize meth_s variable. (method_name): New function. * struct.h (method_name): Declared. * txr.1: Re-documented func-get-name.
-rw-r--r--eval.c5
-rw-r--r--struct.c26
-rw-r--r--struct.h1
-rw-r--r--txr.159
4 files changed, 72 insertions, 19 deletions
diff --git a/eval.c b/eval.c
index a1f9a77c..96226331 100644
--- a/eval.c
+++ b/eval.c
@@ -51,6 +51,7 @@
#include "txr.h"
#include "combi.h"
#include "lisplib.h"
+#include "struct.h"
#include "cadr.h"
#include "eval.h"
@@ -345,7 +346,9 @@ val func_get_name(val fun, val env)
return func_get_name(fun, env->e.up_env);
}
} else {
- val name = hash_revget(top_fb, fun, eq_f, cdr_f);
+ uses_or2;
+ val name = or2(hash_revget(top_fb, fun, eq_f, cdr_f),
+ method_name(fun));
if (name)
return name;
diff --git a/struct.c b/struct.c
index f7768756..05a1a372 100644
--- a/struct.c
+++ b/struct.c
@@ -74,7 +74,7 @@ struct struct_inst {
val slot[1];
};
-val struct_type_s;
+val struct_type_s, meth_s;
static cnum struct_id_counter;
static val struct_type_hash;
@@ -95,6 +95,7 @@ void struct_init(void)
protect(&struct_type_hash, &slot_hash, &struct_type_finalize_f,
convert(val *, 0));
struct_type_s = intern(lit("struct-type"), user_package);
+ meth_s = intern(lit("meth"), user_package);
struct_type_hash = make_hash(nil, nil, nil);
slot_hash = make_hash(nil, nil, t);
struct_type_finalize_f = func_n1(struct_type_finalize);
@@ -1044,6 +1045,29 @@ static val struct_inst_equalsub(val obj)
return nil;
}
+val method_name(val fun)
+{
+ val sth_iter = hash_begin(struct_type_hash);
+ val sth_cell;
+
+ while ((sth_cell = hash_next(sth_iter))) {
+ val sym = car(sth_cell);
+ val stype = cdr(sth_cell);
+ val sl_iter;
+ struct struct_type *st = coerce(struct struct_type *, stype->co.handle);
+
+ for (sl_iter = st->slots; sl_iter; sl_iter = cdr(sl_iter)) {
+ val slot = car(sl_iter);
+ loc ptr = lookup_static_slot(stype, st, slot);
+
+ if (!nullocp(ptr) && deref(ptr) == fun)
+ return list(meth_s, sym, slot, nao);
+ }
+ }
+
+ return nil;
+}
+
static_def(struct cobj_ops struct_type_ops =
cobj_ops_init(eq, struct_type_print, struct_type_destroy,
struct_type_mark, cobj_hash_op))
diff --git a/struct.h b/struct.h
index 3d5b1942..f0dacaf7 100644
--- a/struct.h
+++ b/struct.h
@@ -50,4 +50,5 @@ val method(val strct, val slotsym);
val super_method(val strct, val slotsym);
val uslot(val slot);
val umethod(val slot);
+val method_name(val fun);
void struct_init(void);
diff --git a/txr.1 b/txr.1
index 285a3755..163c7745 100644
--- a/txr.1
+++ b/txr.1
@@ -13053,32 +13053,57 @@ which must be an interpreted function. The source code form has the syntax
.coNP Function @ func-get-name
.synb
-.mets (func-get-form << func <> [ env ])
+.mets (func-get-name << func <> [ env ])
.syne
.desc
The
.code func-get-name
tries to resolve the function object
.meta func
-to a name. If that is not possible, it tries to resolve it to
-a lambda expression denoting the source code form of the function.
-If neither a name nor code can be found, then
-.code nil
-is returned.
+to a name. If that is not possible, it returns
+.codn nil .
-The name or code information is searched in the environment
-specified by
-.meta env
-and if it is not found there, it similarly searches through the chain
-of parent environments, and finally the global environment.
-If
+The resolution is performed by an exhaustive search through
+up to three spaces.
+
+If an environment is specified by
+.metn env ,
+then this is searched first. If a binding is found in that
+environment which resolves to the function, then the search
+terminates and the binding's symbol is returned as the
+function's name.
+
+If the search through environment
.meta env
-is omitted, then only the global environment is searched.
+fails, or if that argument is not specified, then the
+global environment is searched for a function binding
+which resolves to
+.metn func .
+If such a binding is found, then the search terminates,
+and the binding's symbol is returned. If two or more
+symbols in the global environment resolve to the function,
+it is not specified which one is returned.
+
+If the global function environment search fails,
+then the function is considered as a possible method.
+The static slot space of all struct types is searched for
+a slot which contains
+.metn func .
+If such a slot is found, then the method name is returned,
+consisting of the syntax
+.cblk
+.meti (meth < type << name )
+.cble
+where
+.meta type
+is a symbol denoting the struct type and
+.meta name
+is the static slot of the struct type which holds
+.metn func .
-If a function binding is found which associates a symbol
-with
-.meta function
-then that symbol is returned. Variable bindings are not considered.
+If all the searches fail, then
+.code nil
+is returned.
.coNP Function @ func-get-env
.synb