How do I use a type-specifier in a case statement?

Discussion of Common Lisp
Post Reply
joeish80829
Posts: 153
Joined: Tue Sep 03, 2013 5:32 am

How do I use a type-specifier in a case statement?

Post by joeish80829 » Wed Jul 23, 2014 2:27 am

Code: Select all

;; If I make an array like this

(let ((arr (make-array (list 3 3) :element-type '(unsigned-byte 8)))
     (type 0)
     (cffi-type 0))

;; and set its type to a variable like this:

(setf type (array-element-type arr))

;; How do I write a case or a typecase statement to dispatch based on the 
;; (unsigned-byte 8) type specifier. I would like, in this case, for cffi-type 
;; to equal :uchar

(setf cffi-type (case type
                ((unsigned-byte 8) :uchar)
	        ((signed-byte 8) :char)
	        ((unsigned-byte 16) :ushort)
	        ((signed-byte 16) :short)
	        ((signed-byte 32) :int)
	        ((single-float) :float)
	        ((double-float) :double))))

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Re: How do I use a type-specifier in a case statement?

Post by pjstirling » Wed Jul 23, 2014 8:54 am

You could probably use TYPECASE with SATISFIES types, but that looks likely to be rather verbose. CASE and TYPECASE are thin macros on top of COND, you should probably make your own.

logxor
Posts: 20
Joined: Tue May 27, 2014 10:56 am
Location: Portland, OR

Re: How do I use a type-specifier in a case statement?

Post by logxor » Thu Jul 24, 2014 4:22 pm

It's hard to say without knowing the context of why you're doing this, but one option is to use an association list, like so:

Code: Select all

(setf cffi-type
      (cadr (assoc type
                   '(((unsigned-byte 8) :uchar)
                     ((signed-byte 8) :char)
                     ((unsigned-byte 16) :ushort)
                     ((signed-byte 16) :short)
                     ((signed-byte 32) :int)
                     (single-float :float)
                     (double-float :double))
                   :test #'equal)))
Or if the array itself is available then I could dispatch on the array with TYPECASE:

Code: Select all

(setf cffi-type
      (typecase arr
        ((array (unsigned-byte 8)) :uchar)
        ((array (signed-byte 8)) :char)
        ((array (unsigned-byte 16)) :ushort)
        ((array (signed-byte 16)) :short)
        ((array (signed-byte 32)) :int)
        ((array single-float) :float)
        ((array double-float) :double)))

joeish80829
Posts: 153
Joined: Tue Sep 03, 2013 5:32 am

Re: How do I use a type-specifier in a case statement?

Post by joeish80829 » Thu Jul 24, 2014 8:03 pm

Thanks for the answer, that typecase did the trick:)

Post Reply