summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-09-29 20:13:43 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-09-29 20:13:43 -0700
commitafb400eff15e7c77c5dd0fa5e35d91173f8df1ad (patch)
treeb29f3217396cdc2b04a55a16721f81d6ce4f43ba /share
parent111650e235ab2e529fa1529b1c9a23688a11cd1f (diff)
downloadtxr-afb400eff15e7c77c5dd0fa5e35d91173f8df1ad.tar.gz
txr-afb400eff15e7c77c5dd0fa5e35d91173f8df1ad.tar.bz2
txr-afb400eff15e7c77c5dd0fa5e35d91173f8df1ad.zip
struct :init :fini specifiers.
* share/txr/stdlib/struct.tl (defstruct): New (:init ...) and (:fini ...) syntax can be used in the slot list to specify an initialization function and a gc-finalization function. * txr.1: Documented.
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/struct.tl38
1 files changed, 35 insertions, 3 deletions
diff --git a/share/txr/stdlib/struct.tl b/share/txr/stdlib/struct.tl
index 6bef4919..d1e42d2a 100644
--- a/share/txr/stdlib/struct.tl
+++ b/share/txr/stdlib/struct.tl
@@ -35,7 +35,8 @@
(throwf 'eval-error "~s: ~s isn't a bindable symbol" 'defstruct name))
(unless (proper-listp slot-specs)
(throwf 'eval-error "~s: bad slot syntax" 'defstruct))
- (let* ((slot-init-forms (collect-each ((slot slot-specs))
+ (let* ((instance-init-form nil) (instance-fini-form nil)
+ (slot-init-forms (collect-each ((slot slot-specs))
(tree-case slot
((word name args . body)
(caseq word
@@ -52,7 +53,32 @@
(when body
(sys:bad-slot-syntax slot))
^(,word ,name ,args))
- (t (sys:bad-slot-syntax slot))))
+ (t :)))
+ ((word (arg) . body)
+ (caseq word
+ (:init
+ (unless (bindable arg)
+ (sys:bad-slot-syntax slot))
+ (when instance-init-form
+ (uw-throwf 'eval-error
+ "~s: duplicate :init"
+ 'defstruct))
+ (set instance-init-form
+ (cons arg body))
+ ^(,word nil nil))
+ (:fini
+ (unless (bindable arg)
+ (sys:bad-slot-syntax slot))
+ (when instance-fini-form
+ (uw-throwf 'eval-error
+ "~s: duplicate :fini"
+ 'defstruct))
+ (set instance-fini-form
+ (cons arg body))
+ ^(,word nil nil))
+ (t (when body
+ (sys:bad-slot-syntax slot))
+ :)))
((word name)
(caseq word
((:static :instance)
@@ -82,7 +108,13 @@
(let ((,type-sym (struct-type ,arg-sym)))
,*(mapcar (aret ^(unless (static-slot-p ,type-sym ',@2)
(slotset ,arg-sym ',@2 ,@3)))
- inst-si-forms)))
+ inst-si-forms))
+ ,*(if (cdr instance-init-form)
+ ^((let ((,(car instance-init-form) ,arg-sym))
+ ,*(cdr instance-init-form))))
+ ,*(if (cdr instance-fini-form)
+ ^((finalize ,arg-sym (lambda (,(car instance-fini-form))
+ ,*(cdr instance-fini-form))))))
,(if args
(let ((gens (mapcar (ret (gensym)) args)))
^(lambda (,arg-sym ,*gens)