3 (in-package :cl-tuples
)
6 (defun def-tuple (type-name)
7 (tuple-expansion-fn type-name
:def-tuple
))
9 (defun def-tuple-getter (type-name)
10 "Create an access macro such as (vector3d vec) that takes an instance of an array and unpacks it to tuples (aka multiple values)"
11 (tuple-expansion-fn type-name
:def-tuple-getter
))
13 (defun def-tuple-array-getter (type-name)
14 "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)"
15 (tuple-expansion-fn type-name
:def-tuple-array-getter
))
18 (defun 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 (defun 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 (defun 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 (defun 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 (defun 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 (defun def-new-tuple (type-name)
39 "Create a function to create an array suitable for holding an individual tuple. eg (new-vector3d)"
40 (tuple-expansion-fn type-name
:def-new-tuple
))
42 (defun def-tuple-maker (type-name)
43 "Create a function to create an array suitable for holding an individual tuple, and initialise elements from multiple-value tuple. eg (make-vector3d #{ 1.0 2.0 2.0 })"
44 (tuple-expansion-fn type-name
:def-tuple-maker
))
46 (defun def-tuple-maker* (type-name)
47 "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 ))"
48 (tuple-expansion-fn type-name
:def-tuple-maker
*))
50 (defun def-tuple-array-maker (type-name)
51 "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)"
52 (tuple-expansion-fn type-name
:def-tuple-array-maker
))
54 (defun def-tuple-array-dimensions (type-name)
55 "Create a function that will return the number of tuples in the array of array tuples."
56 (tuple-expansion-fn type-name
:def-tuple-array-dimensions
))
58 (defun def-tuple-setf (type-name)
59 "Create generalised variable macros for tuple of type-name with the given elements."
60 (tuple-expansion-fn type-name
:def-tuple-setf
))
62 (defun def-tuple-array-setf (type-name)
63 (tuple-expansion-fn type-name
:def-tuple-array-setf
))
65 (defun def-tuple-map (type-name)
66 "Creates a macro called maps-{tuple-type}-values. Which maps a the
67 function across a list of values, where it expects to recieve the same
68 number of values as the named type.
69 e.g (def-tuple-map vector2d) produces (map-vector2d-values fn &rest values)"
70 (tuple-expansion-fn type-name
:def-tuple-map
))
73 (defun def-tuple-reduce (type-name)
74 "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)"
75 (tuple-expansion-fn type-name
:def-tuple-reduce
))
77 (defun document-tuple-type (type-name)
79 ;; instead of setf, need some form that can use the symbol in the format
80 (setf (documentation ',(make-suffixed-symbol type-name
"TUPLE") 'function
) "Convert forms to tuple values.")
81 (setf (documentation ',type-name
'function
) "Unpack array and convert to tuple values.")
82 (setf (documentation ','(make-suffixed-symbol type-name
"AREF") 'function
) "Unpack individual tuple from an array of tuples.")
83 (setf (documentation ','(make-adorned-symbol type-name
:prefix
"WITH") 'function
) "Bind members of the tuple values to symbols.")))
86 (defmacro make-tuple-operations
(type-name)
88 (def-tuple ',type-name
)
89 (def-tuple-array-dimensions ',type-name
)
90 (def-tuple-getter ',type-name
)
91 (def-tuple-array-getter ',type-name
)
92 (def-with-tuple ',type-name
)
93 (def-with-tuple* ',type-name
)
94 (def-with-tuple-aref ',type-name
)
95 (def-tuple-setter ',type-name
)
96 (def-tuple-aref-setter ',type-name
)
97 (def-new-tuple ',type-name
)
98 (def-tuple-maker ',type-name
)
99 (def-tuple-maker* ',type-name
)
100 (def-tuple-array-maker ',type-name
)
101 (def-tuple-setf ',type-name
)
102 (def-tuple-array-setf ',type-name
)
103 (def-tuple-map ',type-name
)
104 (def-tuple-reduce ',type-name
)))
106 ;; possibly we also need a deftype form to describe a tuple array?
108 (defmacro def-tuple-type
(tuple-type-name &key tuple-element-type elements
)
109 "Create a tuple type. To be used from the top level.
110 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)."
111 `(eval-when (:compile-toplevel
:execute
:load-toplevel
)
112 (make-tuple-symbol ',tuple-type-name
',tuple-element-type
',elements
)
113 (make-tuple-operations ,tuple-type-name
)
114 (document-tuple-type ',tuple-type-name
)))
117 ;; this needs some way of having the names as meaningful symbols
118 ;; also a way of specifying type of return value and non-tuple parameters
119 (defmacro def-tuple-op
(name args
&body forms
)
120 "Macro to define a tuple operator. The name of the operator is
121 name. The operator arguments are determined by args, which is a
122 list of the form ((argument-name argument-type (elements) ..)).
123 Within the forms the tuple value form is bound to the argument-name
124 and the tuple elements are bound to the symbols in the element list"
125 (let ((arg-names (mapcar #'car args
))
126 (arg-typenames (mapcar #'cadr args
))
127 (arg-elements (mapcar #'caddr args
)))
129 (defmacro ,name
,arg-names
130 ,(arg-expander-fn arg-names arg-typenames arg-elements forms
))
131 ,(when (stringp (first forms
))
132 `(setf (documentation ',name
'function
) ,(first forms
))))))