diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-10-10 07:58:00 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-10-10 07:58:00 -0700 |
commit | 6aa141253aa8a9c0b8f93b38ac225eacfb93566c (patch) | |
tree | 9cbc351c56f4653333ba47293b56b1e3226dcd13 | |
parent | 35c830aa764e6e456530ed9d18ff5a686d10d96c (diff) | |
download | txr-6aa141253aa8a9c0b8f93b38ac225eacfb93566c.tar.gz txr-6aa141253aa8a9c0b8f93b38ac225eacfb93566c.tar.bz2 txr-6aa141253aa8a9c0b8f93b38ac225eacfb93566c.zip |
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.
-rw-r--r-- | lisplib.c | 6 | ||||
-rw-r--r-- | share/txr/stdlib/with-resources.tl | 8 | ||||
-rw-r--r-- | txr.1 | 49 |
3 files changed, 62 insertions, 1 deletions
@@ -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)))))) @@ -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 |