diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-10-06 21:13:45 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-10-06 21:13:45 -0700 |
commit | 8beabcd33ac984ee454f0871ffd45b940e279732 (patch) | |
tree | 624c01ce0d390ef86975d88033249d44ab6c0417 | |
parent | 829f02b346d4060e64ec5847cbd0f066edd4a144 (diff) | |
download | txr-8beabcd33ac984ee454f0871ffd45b940e279732.tar.gz txr-8beabcd33ac984ee454f0871ffd45b940e279732.tar.bz2 txr-8beabcd33ac984ee454f0871ffd45b940e279732.zip |
New function: replace-struct.
* struct.c (replace_struct): New function.
(struct_init): Register replace_struct intrinsic.
* struct.h (replace_struct): Declared.
* txr.1: documented replace-struct.
-rw-r--r-- | struct.c | 17 | ||||
-rw-r--r-- | struct.h | 1 | ||||
-rw-r--r-- | txr.1 | 42 |
3 files changed, 60 insertions, 0 deletions
@@ -111,6 +111,7 @@ void struct_init(void) reg_fun(intern(lit("super"), user_package), func_n1(super)); reg_fun(intern(lit("make-struct"), user_package), func_n2v(make_struct)); reg_fun(intern(lit("copy-struct"), user_package), func_n1(copy_struct)); + reg_fun(intern(lit("replace-struct"), user_package), func_n2(replace_struct)); reg_fun(intern(lit("clear-struct"), user_package), func_n2o(clear_struct, 1)); reg_fun(intern(lit("slot"), user_package), func_n2(slot)); reg_fun(intern(lit("slotset"), user_package), func_n3(slotset)); @@ -408,6 +409,22 @@ val clear_struct(val strct, val value) return strct; } +val replace_struct(val target, val source) +{ + const val self = lit("replace-struct"); + struct struct_inst *tsi = struct_handle(target, self); + struct struct_inst *ssi = struct_handle(source, self); + struct struct_type *sst = coerce(struct struct_type *, ssi->type->co.handle); + cnum nslots = sst->nslots; + size_t size = offsetof(struct struct_inst, slot) + sizeof (val) * nslots; + struct struct_inst *ssi_copy = coerce(struct struct_inst *, chk_malloc(size)); + memcpy(ssi_copy, ssi, size); + free(tsi); + target->co.handle = coerce(mem_t *, ssi_copy); + target->co.cls = source->co.cls; + return target; +} + static int cache_set_lookup(slot_cache_entry_t *set, cnum id) { if (set[0].id == id) @@ -33,6 +33,7 @@ val super(val type); val make_struct(val type, val plist, struct args *); val copy_struct(val strct); val clear_struct(val strct, val value); +val replace_struct(val target, val source); val find_struct_type(val sym); val slot(val strct, val sym); val slotset(val strct, val sym, val newval); @@ -18745,6 +18745,48 @@ if omitted. Note that finalizers are not executed prior to replacing the slot values. +.coNP Function @ replace-struct +.synb +.mets (replace-struct < target-obj << source-obj ) +.syne +.desc +The +.code replace-struct +function causes +.meta target-obj +to take on the attributes of +.meta source-obj +without changing its identity. + +The type of +.code target-obj +is changed to that of +.codn source-obj . + +All instance slots of +.code target-obj +are discarded, and it is given new slots, +which are copies of the instance slots of +.codn source-obj . + +Because of the type change, +.code target-obj +implicitly loses all of its original static slots, +and acquires those of +.codn source obj . + +Note that finalizers registered against +.meta target-obj +are not invoked, and remain registered. +If +.meta target-obj +has state which is cleaned up by +finalizers, it is advisable to invoke them using +.code call-finalizers +prior to using +.codn replace-struct , +or to take other measures to handle the situation. + .coNP Function @ method .synb .mets (method < struct-obj << slot-name ) |