summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--struct.c8
-rw-r--r--struct.h2
-rw-r--r--txr.178
3 files changed, 75 insertions, 13 deletions
diff --git a/struct.c b/struct.c
index 4810d6e5..02fb0e44 100644
--- a/struct.c
+++ b/struct.c
@@ -99,7 +99,7 @@ struct struct_inst {
val struct_type_s, meth_s, print_s, make_struct_lit_s;
val init_k, postinit_k;
-val slot_s;
+val slot_s, derived_s;
static val struct_type_hash;
static val slot_hash;
@@ -110,6 +110,7 @@ static val static_slot_type_hash;
static val struct_type_finalize(val obj);
static_forward(struct cobj_ops struct_type_ops);
+static struct stslot *lookup_static_slot_desc(struct struct_type *st, val sym);
static val make_struct_type_compat(val name, val super, val slots,
val initfun, val boactor);
static val call_super_method(val inst, val sym, struct args *);
@@ -127,6 +128,7 @@ void struct_init(void)
init_k = intern(lit("init"), keyword_package);
postinit_k = intern(lit("postinit"), keyword_package);
slot_s = intern(lit("slot"), user_package);
+ derived_s = intern(lit("derived"), user_package);
struct_type_hash = make_hash(nil, nil, nil);
slot_hash = make_hash(nil, nil, t);
slot_type_hash = make_hash(nil, nil, nil);
@@ -308,6 +310,7 @@ val make_struct_type(val name, val super,
val super_slots = if2(su, su->slots);
val all_slots = uniq(append2(super_slots, append2(static_slots, slots)));
val stype = cobj(coerce(mem_t *, st), struct_type_s, &struct_type_ops);
+ struct stslot *dvmeth = if3(su, lookup_static_slot_desc(su, derived_s), 0);
val iter;
cnum sl, stsl;
cnum stsl_upb = c_num(plus(length(static_slots),
@@ -394,6 +397,9 @@ val make_struct_type(val name, val super,
uw_purge_deferred_warning(cons(struct_type_s, name));
+ if (dvmeth)
+ funcall2(stslot_place(dvmeth), su->self, stype);
+
return stype;
}
}
diff --git a/struct.h b/struct.h
index 09bf6767..d67ce3d7 100644
--- a/struct.h
+++ b/struct.h
@@ -27,7 +27,7 @@
extern val struct_type_s, meth_s, print_s, make_struct_lit_s;
extern val init_k, postinit_k;
-extern val slot_s;
+extern val slot_s, derived_s;
extern struct cobj_ops struct_inst_ops;
val make_struct_type(val name, val super,
val static_slots, val slots,
diff --git a/txr.1 b/txr.1
index dfba7b14..10988926 100644
--- a/txr.1
+++ b/txr.1
@@ -26141,6 +26141,38 @@ form. If a special function or method is defined as an instance slot,
then the behavior of library functions which depend on this method is
unspecified.
+Special functions introduced below by the word "Method" receive an object
+instance as an argument. Their syntax is indicated using the same notation
+which may be used to invoke them, such as:
+
+.verb
+.mets << object .(function-name < arg << ... )
+.brev
+
+However, those introduced as "Function" do not operate on an instance. For
+brevity, their syntax is nevertheless exemplified as
+
+.verb
+.meti << object .'['function-name < arg << ... ']'
+.brev
+
+If such a invocation is actually used, the
+.meta object
+instance only serves for identifying the struct type whose static slot
+.code function-name
+provides the function;
+.meta object
+doesn't participate in the call. An object is not required since
+the function can be called using
+
+.verb
+.meti [(static-slot < type 'function-name) < arg << ... ]
+.brev
+
+which looks up the function in the struct
+.meta type
+directly.
+
.coNP Method @ equal
.synb
.mets << object .(equal)
@@ -26550,17 +26582,6 @@ situations with an argument which is a list object. The function's purpose
is to construct a new instance of the structure type, derived from that
list.
-Note: the
-.code from-list
-function isn't a method; it doesn't receive
-.meta object
-as an argument. In the style of call depicted by the syntax description
-above,
-.meta object
-is used to identify the structure type whose
-.meta from-list
-static slot provides the function definition.
-
The purpose of this function is to allow sequence processing operations
such as
.code mapcar
@@ -26580,6 +26601,41 @@ methods, but does not have a
function, then those sequence-processing operations which return a sequence
will always return a plain list of items.
+.coNP Function @ derived
+.synb
+.mets << object .'['derived < supertype << subtype ']'
+.syne
+.desc
+If a structure type supports a function called
+.metn derived ,
+this function is called whenever a new type is defined which names
+that type as its supertype.
+
+The function is called with two arguments which are both struct types.
+The
+.meta supertype
+argument gives the type that is being inherited from.
+The
+.meta subtype
+gives the new type that is inheriting from
+.metn supertype .
+
+The function is called at most once for the creation of a given
+.metn subtype ,
+only for its immediate supertype, if and only if that supertype
+has defined this function.
+
+The function is not retroactively invoked if it is defined for
+a structure type from which subtypes have already been derived.
+
+Note: the
+.meta supertype
+parameter exists because the
+.code derived
+function is itself inherited. If the same version of this function is shared by
+multiple structure types due to inheritance, this argument informs the function
+which of those types it is being invoked for.
+
.SS* Sequence Manipulation
.coNP Function @ seqp
.synb