diff options
-rw-r--r-- | stdlib/struct.tl | 18 | ||||
-rw-r--r-- | tests/012/fini.expected | 40 | ||||
-rw-r--r-- | tests/012/fini.tl | 4 | ||||
-rw-r--r-- | txr.1 | 51 |
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))))) @@ -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 |