Page 1 of 1

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

Posted: Wed Jul 23, 2014 2:27 am
by joeish80829

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))))

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

Posted: Wed Jul 23, 2014 8:54 am
by pjstirling
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.

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

Posted: Thu Jul 24, 2014 4:22 pm
by logxor
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)))

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

Posted: Thu Jul 24, 2014 8:03 pm
by joeish80829
Thanks for the answer, that typecase did the trick:)