diff options
-rw-r--r-- | struct.c | 8 | ||||
-rw-r--r-- | struct.h | 2 | ||||
-rw-r--r-- | txr.1 | 78 |
3 files changed, 75 insertions, 13 deletions
@@ -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; } } @@ -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, @@ -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 |