summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stdlib/struct.tl18
-rw-r--r--tests/012/fini.expected40
-rw-r--r--tests/012/fini.tl4
-rw-r--r--txr.151
4 files changed, 106 insertions, 7 deletions
diff --git a/stdlib/struct.tl b/stdlib/struct.tl
index 4f120eef..f0806723 100644
--- a/stdlib/struct.tl
+++ b/stdlib/struct.tl
@@ -48,7 +48,8 @@
(compile-error form "bad syntax: dotted form"))
(let ((instance-init-form nil)
(instance-postinit-form nil)
- (instance-fini-form nil))
+ (instance-fini-form nil)
+ (instance-postfini-form nil))
(labels ((expand-slot (form slot)
(tree-case slot
((op . args)
@@ -102,6 +103,15 @@
(set instance-fini-form
(cons arg body))
^((,word nil nil)))
+ (:postfini
+ (unless (bindable arg)
+ (sys:bad-slot-syntax form slot))
+ (when instance-postfini-form
+ (compile-error form
+ "duplicate :postfini"))
+ (set instance-postfini-form
+ (cons arg body))
+ ^((,word nil nil)))
(t (when body
(sys:bad-slot-syntax form slot))
:)))
@@ -158,12 +168,16 @@
,*(mapcar (aret ^(when (static-slot-p ,arg-sym ',@2)
(static-slot-set ,arg-sym ',@2 ,@3)))
(append func-si-forms val-si-forms))))
- ,(if (or inst-si-forms instance-init-form instance-fini-form)
+ ,(if (or inst-si-forms instance-init-form
+ instance-fini-form instance-postfini-form)
^(lambda (,arg-sym)
,*(if (cdr instance-fini-form)
^((finalize ,arg-sym (lambda (,(car instance-fini-form))
,*(cdr instance-fini-form))
t)))
+ ,*(if (cdr instance-postfini-form)
+ ^((finalize ,arg-sym (lambda (,(car instance-postfini-form))
+ ,*(cdr instance-postfini-form)))))
,*(if inst-si-forms
^((let ((,type-sym (struct-type ,arg-sym)))
,*(mapcar (aret ^(unless (static-slot-p ,type-sym ',@2)
diff --git a/tests/012/fini.expected b/tests/012/fini.expected
index 5e967eb2..a733802b 100644
--- a/tests/012/fini.expected
+++ b/tests/012/fini.expected
@@ -2,44 +2,64 @@ inside with-objects
base:21 finalized
derived:1 derived fini
derived:1 finalized
+derived:1 derived postfini
derived:2 derived fini
derived:2 finalized
+derived:2 derived postfini
derived:3 derived fini
derived:3 finalized
+derived:3 derived postfini
derived:4 derived fini
derived:4 finalized
+derived:4 derived postfini
derived:5 derived fini
derived:5 finalized
+derived:5 derived postfini
derived:6 derived fini
derived:6 finalized
+derived:6 derived postfini
derived:7 derived fini
derived:7 finalized
+derived:7 derived postfini
derived:8 derived fini
derived:8 finalized
+derived:8 derived postfini
derived:9 derived fini
derived:9 finalized
+derived:9 derived postfini
derived:10 derived fini
derived:10 finalized
+derived:10 derived postfini
derived:11 derived fini
derived:11 finalized
+derived:11 derived postfini
derived:12 derived fini
derived:12 finalized
+derived:12 derived postfini
derived:13 derived fini
derived:13 finalized
+derived:13 derived postfini
derived:14 derived fini
derived:14 finalized
+derived:14 derived postfini
derived:15 derived fini
derived:15 finalized
+derived:15 derived postfini
derived:16 derived fini
derived:16 finalized
+derived:16 derived postfini
derived:17 derived fini
derived:17 finalized
+derived:17 derived postfini
derived:18 derived fini
derived:18 finalized
+derived:18 derived postfini
derived:19 derived fini
derived:19 finalized
+derived:19 derived postfini
derived:20 derived fini
derived:20 finalized
+derived:20 derived postfini
after with-objects
derived:41 derived fini
derived:41 finalized
@@ -81,3 +101,23 @@ derived:23 derived fini
derived:23 finalized
derived:22 derived fini
derived:22 finalized
+derived:22 derived postfini
+derived:23 derived postfini
+derived:24 derived postfini
+derived:25 derived postfini
+derived:26 derived postfini
+derived:27 derived postfini
+derived:28 derived postfini
+derived:29 derived postfini
+derived:30 derived postfini
+derived:31 derived postfini
+derived:32 derived postfini
+derived:33 derived postfini
+derived:34 derived postfini
+derived:35 derived postfini
+derived:36 derived postfini
+derived:37 derived postfini
+derived:38 derived postfini
+derived:39 derived postfini
+derived:40 derived postfini
+derived:41 derived postfini
diff --git a/tests/012/fini.tl b/tests/012/fini.tl
index 3aa581f9..775f210f 100644
--- a/tests/012/fini.tl
+++ b/tests/012/fini.tl
@@ -11,7 +11,9 @@
(defstruct derived base
(:fini (me)
- (put-line `@(typeof me):@{me.id} derived fini`)))
+ (put-line `@(typeof me):@{me.id} derived fini`))
+ (:postfini (me)
+ (put-line `@(typeof me):@{me.id} derived postfini`)))
(unwind-protect
(with-objects ((b (new base others (mapcar (ret (new derived)) (range 1 20)))))
diff --git a/txr.1 b/txr.1
index 812aafd4..9b9a9797 100644
--- a/txr.1
+++ b/txr.1
@@ -29375,15 +29375,58 @@ of a
specifier are not surrounded by an implicit
.codn block .
+At most one
+.code :fini
+may be specified.
+
Note that an object's finalizers can be called explicitly with
.codn call-finalizers .
-.RE
-.IP
-The
+Note: the
.code with-objects
macro arranges for finalizers to be called on objects when the execution
of a scope terminates by any means.
-
+.meIP (:postfini <> ( param ) << body-form *)
+Like
+.codn :fini ,
+.code :postfini
+specifier doesn't describe a slot. The syntax is identical to
+.codn :fini .
+Independently of whether
+.code :fini
+is specified, at most one
+.code :postfini
+may be specified. The only difference between
+.code :fini
+and
+.code :postfini
+is that
+.code :postfini
+arranges for a finalizer to be registered as if by the evaluation of the form
+.mono
+.meti (finalize < obj (lambda <> ( param ) << body-form ...))
+.onom
+where
+.meta obj
+denotes the structure instance. Note the that unlike
+.codn :fini ,
+this omits the
+.code t
+parameter, which means that
+.code :postfini
+finalizers of derived structures execute after the execution of inherited
+finalizers. When both
+.code :fini
+and
+.code :postfini
+are specified in the same
+.code defstruct
+form, the
+.code :postfini
+finalizer executes after the
+.code :fini
+finalizer regardless of the order in which they appear.
+.RE
+.IP
The slot names given in a
.code defstruct
must all be unique among themselves, but they