From 6aa141253aa8a9c0b8f93b38ac225eacfb93566c Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 10 Oct 2015 07:58:00 -0700 Subject: New macro: with-objects. * lisplib.c (with_resources_set_entries): "with-objects" added to name table. * share/txr/stdlib/with-resources.tl (with-objects): New macro. * txr.1: Documented with-objects. Added note to :fini specifier of defstruct pointing to call-finalizers and with-objects. --- lisplib.c | 6 ++++- share/txr/stdlib/with-resources.tl | 8 +++++++ txr.1 | 49 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/lisplib.c b/lisplib.c index 122256f3..81240da3 100644 --- a/lisplib.c +++ b/lisplib.c @@ -130,7 +130,11 @@ static val txr_case_instantiate(val set_fun) static val with_resources_set_entries(val dlt, val fun) { - val name[] = { lit("with-resources"), nil }; + val name[] = { + lit("with-resources"), + lit("with-objects"), + nil + }; set_dlt_entries(dlt, name, fun); return nil; } diff --git a/share/txr/stdlib/with-resources.tl b/share/txr/stdlib/with-resources.tl index 50fc62a7..28cdd6fb 100644 --- a/share/txr/stdlib/with-resources.tl +++ b/share/txr/stdlib/with-resources.tl @@ -40,3 +40,11 @@ (nil ^(progn ,*body)) (other (error "with-resources: bad syntax")))) + +(defmacro with-objects (var-init-forms . body) + (let ((gens (mapcar (ret (gensym)) var-init-forms))) + ^(let ,gens + (unwind-protect + (let* ,(mapcar (aret ^(,@2 (set ,@1 ,@3))) gens var-init-forms) + ,*body) + ,*(reverse (mapcar (ret ^(call-finalizers ,@1)) gens)))))) diff --git a/txr.1 b/txr.1 index c0dd1ce3..c7321f75 100644 --- a/txr.1 +++ b/txr.1 @@ -18052,6 +18052,13 @@ specifier are not surrounded by an implicit .RE .PP +Note that an object's finalizers can be called explicitly with +.codn call-finalizers . +The +.code with-objects +macro arranges for finalizers to be called on objects when the execution +of a scope terminates by any means. + The slot names given in a .code defstruct must all be unique among themselves, but they @@ -19089,6 +19096,48 @@ must name a static slot of that structure type. The object retrieved from that static slot must be callable as a function, and accept the arguments. +.coNP Macro @ with-objects +.synb +.mets (with-objects >> ({( sym << init-form )}*) << body-form *) +.syne +The +.code with-objects +macro provides a binding construct very similar to +.codn let* . + +Each +.meta sym +must be a symbol suitable for use as a variable name. + +Each +.meta init-form +is evaluated in sequence, and a binding is established for its +corresponding +.meta sym +which is initialized with the value of that form. The binding +is visible to subsequent +.metn init-form -s. + +Additionally, the values of the +.meta init-form -s +are noted as they are produced. When the +.code with-objects +form terminates, by any means, the +.code call-finalizers +function is invoked on each value which was returned by an +.meta init-form +and had been noted. These calls are performed in the +reverse order relative to the original evaluation of the forms. + +After the variables are established and initialized, the +.metn body-form -s +are evaluated in the scope of the variables. The value of the +last form is returned, or else +.code nil +if there are no forms. The invocations of +.code call-finalizers +take place just before the value of the last form is returned. + .SS* Sequence Manipulation .coNP Function @ seqp .synb -- cgit v1.2.3