1 ;; utilities that are used in vol to write macros
2 ;; mostly its used to write functions for different ranks or types
7 (let ((type-names '(((complex double-float
) . cdf
)
8 ((complex single-float
) . csf
)
11 ((signed-byte 16) . sb16
)
12 ((unsigned-byte 16) . ub16
)
13 ((unsigned-byte 8) . ub8
))))
14 (defun get-short-type (long-type)
15 (cdr (assoc long-type type-names
)))
16 (defun get-long-type (short-type)
17 (car (rassoc short-type type-names
))))
22 (defmacro format-symbol
(fmt &rest rest
)
23 `(intern (string-upcase (format nil
,fmt
,@rest
))))
25 (defparameter *macro-generated-functions
* nil
)
26 (defun store-new-function (name)
27 (push name
*macro-generated-functions
*))
29 ;; macro that defines another macro that in turn will define functions
30 ;; handling different ranks and types. should be called like this:
31 ;; (def-generator (fftshift rank type) ... ). the name of the new
32 ;; macro will be def-fftshift-rank-type and when it is invoked the
33 ;; generated function name will be pushed into
34 ;; *macro-generated-functions*. this can be used to build the list of
35 ;; exported symbols. if spec contains the symbol type, than a
36 ;; long-type will be generated. the variable name should be used to
37 ;; define the name of the function. here is an example:
39 ;; (def-generator (fftshift (rank type))
41 ;; (declare ((simple-array ,long-type ,rank) in))))
43 ;; now we can interpolate into a function with the following call
45 ;; (def-fftshift-rank-type 2 sf)
47 ;; the new function looks like this:
49 ;; (DEFUN DEF-FFTSHIFT-2-SF (IN)
50 ;; (DECLARE ((SIMPLE-ARRAY SINGLE-FLOAT 2) IN)))
52 ;; when a new macro is needed to generate a lot of functions (and
53 ;; maybe one dispatch function) it should be called def-...-functions.
55 (defmacro def-generator
((name spec
) &body body
)
56 (let ((macro-name (format-symbol "def-~a~{-~a~}" name spec
))
57 (function-fmt (let ((result (format nil
"~a" name
)))
58 (dotimes (i (length spec
))
59 (setf result
(concatenate 'string result
(format nil
"-~~a"))))
61 `(defmacro ,macro-name
,spec
62 (let ((name (format-symbol ,function-fmt
,@spec
))
63 ,(when (member 'type spec
)
64 `(long-type (get-long-type type
))))
65 (store-new-function name
)
69 (def-generator (fftshift (rank type
))
71 (declare ((simple-array ,long-type
,rank
) in
))))
73 (def-fftshift-rank-type 2 sf
)
77 ;; given two lists the following macros get the outer product, a 2d
78 ;; matrix spanning all the combinations. everything is pushed into a
79 ;; 1d stack whose value can be altered by the optional parameter
80 ;; return-sexpr. for use in macros progn is a useful return-sexpr.
82 (defmacro def-outer-cross
(la lb func
&optional return-sexpr
)
86 (when (,predicate
,a
,b
)
90 `(,return-sexpr
,@result
)
93 (def-outer-cross (1 2 3) (sf df csf cdf
) def-fftshift-rank-type progn
)
95 (def-outer-cross (1 2 3) (1 2 3) def
)