summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-01-03 11:16:48 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-01-03 11:16:48 -0800
commit11ac283d7eda2bac2f19d62d014043f66c8de84c (patch)
tree2b0289573ae6c8337c94734aa58b46b282e916e9 /share
parent629c448f272fe23cefe6eb2b2b90dc8dfb3bbf86 (diff)
downloadtxr-11ac283d7eda2bac2f19d62d014043f66c8de84c.tar.gz
txr-11ac283d7eda2bac2f19d62d014043f66c8de84c.tar.bz2
txr-11ac283d7eda2bac2f19d62d014043f66c8de84c.zip
defstruct: order function slots before other static slots.
This allows the initializer expressions for static slots to instantiate objects, and those instances can rely on methods being set up. * share/txr/stdlib/struct.tl (sys:prune-nil-inits): Recognize :function keyword as denoting a static slot. (defstruct): Represent methods and functions as (:function ...) items rather than (:static ...) so they can be distinguished. Function slots appear before other static slots in the static slot list, and their initializing code is placed into the the static-initfun lambda of the sys:make-struct-type call in this order. * txr.1: Documented.
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/struct.tl32
1 files changed, 17 insertions, 15 deletions
diff --git a/share/txr/stdlib/struct.tl b/share/txr/stdlib/struct.tl
index 7e0d2af1..ee4bfd18 100644
--- a/share/txr/stdlib/struct.tl
+++ b/share/txr/stdlib/struct.tl
@@ -29,7 +29,7 @@
(defun sys:prune-nil-inits (slot-init-forms super-type)
(remove-if (tb ((kind name init-form))
- (and (member kind '(:static :instance))
+ (and (member kind '(:static :instance :function))
(null init-form)
(or (not super-type)
(not (slotp super-type name)))))
@@ -56,13 +56,13 @@
"~s: method ~s needs \
\ at least one parameter"
'defstruct name))
- ^(:static ,name
- (lambda ,args
- (block ,name ,*body))))
- (:function ^(:static ,name
- (lambda ,args
- (block ,name
- ,*body))))
+ ^(:function ,name
+ (lambda ,args
+ (block ,name ,*body))))
+ (:function ^(,word ,name
+ (lambda ,args
+ (block ,name
+ ,*body))))
((:static :instance)
(when body
(sys:bad-slot-syntax slot))
@@ -112,11 +112,15 @@
^(:instance ,name nil))
(name
^(:instance ,name nil)))))
- (stat-si-forms [keep-if (op eq :static) slot-init-forms car])
+ (super-type (find-struct-type super))
+ (stat-si-forms [keep-if (op member @1 '(:static :function))
+ slot-init-forms car])
+ (pruned-si-forms (sys:prune-nil-inits stat-si-forms super-type))
+ (func-si-forms [keep-if (op eq :function) pruned-si-forms car])
+ (val-si-forms [keep-if (op eq :static) pruned-si-forms car])
(inst-si-forms [keep-if (op eq :instance) slot-init-forms car])
(stat-slots [mapcar second stat-si-forms])
- (inst-slots [mapcar second inst-si-forms])
- (super-type (find-struct-type super)))
+ (inst-slots [mapcar second inst-si-forms]))
(whenlet ((bad [find-if [notf bindable]
(append stat-slots inst-slots)]))
(throwf 'eval-error
@@ -124,17 +128,15 @@
"~s: slot name ~s isn't a bindable symbol"
"~s: invalid slot specifier syntax: ~s")
'defstruct bad))
- (set stat-si-forms (sys:prune-nil-inits stat-si-forms super-type))
- (set inst-si-forms (sys:prune-nil-inits inst-si-forms super-type))
(let ((arg-sym (gensym))
(type-sym (gensym)))
^(sys:make-struct-type
',name ',super ',stat-slots ',inst-slots
- ,(if stat-si-forms
+ ,(if (or func-si-forms val-si-forms)
^(lambda (,arg-sym)
,*(mapcar (aret ^(when (static-slot-p ,arg-sym ',@2)
(static-slot-set ,arg-sym ',@2 ,@3)))
- stat-si-forms)))
+ (append func-si-forms val-si-forms))))
,(if (or inst-si-forms instance-init-form instance-fini-form)
^(lambda (,arg-sym)
,*(if (cdr instance-fini-form)