3 (in-package :cl-tuples
)
6 (defmacro def-tuple
(type-name)
7 "Create an alias for values for this tuple.eg (vector3d-tuple #{ 1.0 0.0 0.0 })"
8 (tuple-expansion-fn type-name
:def-tuple
))
10 (defmacro def-tuple-getter
(type-name)
11 "Create an access macro such as (vector3d vec) that takes an instance of an array and unpacks it to tuples (aka multiple values)"
12 (tuple-expansion-fn type-name
:def-tuple-getter
))
14 (defmacro def-tuple-aref
(type-name)
15 "Create a tuple aref macro for unpacking individual tuple from an array of tuples. eg (vector3d-aref up 5) => (values 0.0 1.0 0.0)"
16 (tuple-expansion-fn type-name
:def-tuple-aref
))
18 (defmacro def-with-tuple
(type-name)
19 "Create a macro that can be used to bind members of a value tuple to symbols to symbols e-g (with-vector thing-vec (x y z w) &body forms)"
20 (tuple-expansion-fn type-name
:def-with-tuple
))
22 (defmacro def-with-tuple
* (type-name)
23 "Create a macro that can be used to bind members of the tuples array to symbols to symbols e-g (with-vector* thing-vec #(x y z w) &body forms)"
24 (tuple-expansion-fn type-name
:def-with-tuple
*))
26 (defmacro def-with-tuple-aref
(type-name)
27 "Create a macro that can be used to bind elements of an array of tuples to symbols to symbols e-g (with-vector3d-aref (thing-vec 5 (x y z w)) (+ x y z w))"
28 (tuple-expansion-fn type-name
:def-with-tuple-aref
))
30 (defmacro def-tuple-setter
(type-name)
31 "Creates a tuple-setter for setting a tuple array from a mutiple-value tuple. eg (vector3d-setter up #{ 0.0 1.0 0.0 })"
32 (tuple-expansion-fn type-name
:def-tuple-setter
))
34 (defmacro def-tuple-aref-setter
(type-name)
35 "Create an aref-setter macro for setting an element in an array of tuples from a multiple-value tuple. eg (vector3d-aref-setter up 2 #{ 0.0 1.0 0.0 })"
36 (tuple-expansion-fn type-name
:def-tuple-aref-setter
))
38 (defmacro def-tuple-vector-push
(type-name)
39 (tuple-expansion-fn type-name
:def-tuple-vector-push
))
41 (defmacro def-tuple-vector-push-extend
(type-name)
42 (tuple-expansion-fn type-name
:def-tuple-vector-push-extend
))
44 (defmacro def-new-tuple
(type-name)
45 "Create a function to create an array suitable for holding an individual tuple. eg (new-vector3d)"
46 (tuple-expansion-fn type-name
:def-new-tuple
))
48 (defmacro def-tuple-maker
(type-name)
49 "Create a function to create an array suitable for holding an individual tuple, and initialise elements from multiple-value tuple. eg (make-vector3d (values 1.0 2.0 2.0 ))"
50 (tuple-expansion-fn type-name
:def-tuple-maker
))
52 (defmacro def-tuple-maker
* (type-name)
53 "Create a function to create an array suitable for holding an individual tuple, and initialise elements from array tuple. eg (make-vector3d* #( 1.0 2.0 2.0 ))"
54 (tuple-expansion-fn type-name
:def-tuple-maker
*))
56 (defmacro def-tuple-array-maker
(type-name)
57 "Create a function to create an array suitable for holding an number of individual tuples. ie an array of array tuples. eg (make-vector3d-array 5 :adjustable t)"
58 (tuple-expansion-fn type-name
:def-tuple-array-maker
))
60 (defmacro def-tuple-array-dimensions
(type-name)
61 "Create a function that will return the number of tuples in the array of array tuples."
62 (tuple-expansion-fn type-name
:def-tuple-array-dimensions
))
64 (defmacro def-tuple-setf
(type-name)
65 "Create generalised variable macros for tuple of type-name with the given elements."
66 (tuple-expansion-fn type-name
:def-tuple-setf
))
68 (defmacro def-tuple-array-setf
(type-name)
69 (tuple-expansion-fn type-name
:def-tuple-array-setf
))
71 (defmacro def-tuple-map
(type-name)
72 "Creates a macro called maps-{tuple-type}-values. Which maps a the
73 function across a list of values, where it expects to recieve the same
74 number of values as the named type.
75 e.g (def-tuple-map vector2d) produces (map-vector2d-values fn &rest values)"
76 (tuple-expansion-fn type-name
:def-tuple-map
))
78 (defmacro def-tuple-reduce
(type-name)
79 "Creates a macro called reduce-{tuple-type}-values. Which applies the reduction function to each value in it's second parameter, where it expects to recieve the same number of values as the named type. e.g (def-tuple-reduce vector2d) produces (reduce-vector2d-values fn tuples)"
80 (tuple-expansion-fn type-name
:def-tuple-reduce
))
82 (defun document-tuple-type (type-name)
84 ;; instead of setf, need some form that can use the symbol in the format
85 (setf (documentation ',(make-suffixed-symbol type-name
"TUPLE") 'function
) "Convert forms to tuple values.")
86 (setf (documentation ',type-name
'function
) "Unpack array and convert to tuple values.")
87 (setf (documentation ','(make-suffixed-symbol type-name
"AREF") 'function
) "Unpack individual tuple from an array of tuples.")
88 (setf (documentation ','(make-adorned-symbol type-name
:prefix
"WITH") 'function
) "Bind members of the tuple values to symbols.")))
91 (defmacro make-tuple-operations
(type-name)
93 (def-tuple ,type-name
)
94 (def-tuple-array-dimensions ,type-name
)
95 (def-tuple-getter ,type-name
)
96 (def-tuple-aref ,type-name
)
97 (def-with-tuple ,type-name
)
98 (def-with-tuple* ,type-name
)
99 (def-with-tuple-aref ,type-name
)
100 (def-tuple-setter ,type-name
)
101 (def-tuple-aref-setter ,type-name
)
102 (def-tuple-vector-push ,type-name
)
103 (def-tuple-vector-push-extend ,type-name
)
104 (def-new-tuple ,type-name
)
105 (def-tuple-maker ,type-name
)
106 (def-tuple-maker* ,type-name
)
107 (def-tuple-array-maker ,type-name
)
108 (def-tuple-setf ,type-name
)
109 (def-tuple-array-setf ,type-name
)
110 (def-tuple-map ,type-name
)
111 (def-tuple-reduce ,type-name
)))
113 (defmacro export-tuple-operations
(type-name)
115 ,@(loop for kw in
*tuple-expander-keywords
* collect
`(export (tuple-symbol (quote ,type-name
) ,kw
)))))
118 ;; possibly we also need a deftype form to describe a tuple array?
120 (defmacro def-tuple-type
(tuple-type-name &key tuple-element-type elements
)
121 "Create a tuple type. To be used from the top level.
122 For example (def-tuple-type vector3d single-float (x y z)) will create several macros and functions. Firstly, the accessor functions (vector3d array) (vector3d-aref array index). Secondly, the context macros (with-vector3d tuple (element-symbols) forms..) and (with-vector3d-array tuple (element-symbols) index forms..), thirdly the constructors (new-vector3d) and (make-vector3d tuple), (make-vector3d-array dimensions &key adjustable fill-pointer), forthly generalised access as in (setf (vector3d array) tuple) and (setf (vector3d-aref array) index tuple), fiftly and finally, the funcional macros (map-vector3d fn tuples..) (reduce-vector3d fn tuple)."
123 `(eval-when (:compile-toplevel
:execute
:load-toplevel
)
124 (make-tuple-symbol ',tuple-type-name
',tuple-element-type
',elements
)
125 (make-tuple-operations ,tuple-type-name
)
126 (document-tuple-type ',tuple-type-name
)))
129 ;; this needs some way of having the names as meaningful symbols
130 ;; also a way of specifying type of return value and non-tuple parameters
131 (defmacro def-tuple-op
(name args
&body forms
)
132 "Macro to define a tuple operator. The name of the operator is
133 name. The operator arguments are determined by args, which is a
134 list of the form ((argument-name argument-type (elements) ..)).
135 Within the forms the tuple value form is bound to the argument-name
136 and the tuple elements are bound to the symbols in the element list"
137 (let ((arg-names (mapcar #'car args
))
138 (arg-typenames (mapcar #'cadr args
))
139 (arg-elements (mapcar #'caddr args
)))
141 (defmacro ,name
,arg-names
142 ,(arg-expander-fn arg-names arg-typenames arg-elements forms
))
143 ,(when (stringp (first forms
))
144 `(setf (documentation ',name
'function
) ,(first forms
))))))