diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-11-30 06:11:09 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-11-30 06:11:09 -0800 |
commit | d2e883cf32ea9fa82f33768104bc5993bfc60a04 (patch) | |
tree | 66a11ab2a82ffa84b1047c5d2485f53b50acbb4a | |
parent | 72955500f8b3a5bc52585d3f24aa3d71bdca3b19 (diff) | |
download | txr-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.c | 5 | ||||
-rw-r--r-- | struct.c | 26 | ||||
-rw-r--r-- | struct.h | 1 | ||||
-rw-r--r-- | txr.1 | 59 |
4 files changed, 72 insertions, 19 deletions
@@ -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; @@ -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)) @@ -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); @@ -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 |