> On Mar 23, 2025, at 7:13 AM, Diogo via Chicken-users 
> <chicken-users@nongnu.org> wrote:
> 
> Dear mailing list,
> 
> I have a beginners question. Using `foreigners` one can easily define 
> structs and enums. But how does one figure out whether a symbol is an
> enum or a struct?

afaik, you cannot; compiler db not persistent, or documented (much). (See 
chicken.compiler.support#register-foreign-type! from the the CHICKEN source)

but taking inspiration from coops-primitive-objects (coops egg):

(define-class <foreign-object>)
(define-class <enum> (<foreign-object>))
(define-class <struct> (<foreign-object>))

(define (class-of? (cls par)
  (and (class? cls)
       (memq par (class-precedence-list cls))
       #t))

(define foreign-object-set!)
(define foreign-object-ref)
(let ((ht (make-hash-table eq?))
  (set! foreign-object-set! (lambda (tag cls)
    (assert (class-of? cls <foreign-object>))
    (hash-table-set! ht tag cls)))
  (set! foreign-object-ref (lambda (tag)
    (hash-table-ref/default ht tag #f))) )

(foreign-object-set! ‘event <enum>)
(foreign-object-set! ‘plan <struct>)

(define (print-type-info type)
(let ((obj (foreign-object-ref type)))
  (cond ((eq? <enum> obj) (printf "~a is enum~n" type))
        ((eq? <struct> obj) (printf "~a is struct~n" type))
        (else (printf "~a is something else~n" type)))))

;`select’ from miscmacros will shorten the above
(define (print-type-info type)
  (select (foreign-object-ref type)
    ((<enum>) (printf "~a is enum~n" type))
    ((<struct>) (printf "~a is struct~n" type))
    (else (printf "~a is something else~n" type))))

;doubtful this procedure possible
(define (foreign-instance? x) (error 'foreign-instance? “never enough 
information” x))

> 
> Here is a small example of what I am trying to do:
> 
> ```
> (import (chicken base)
>        (chicken foreign)
>        foreigners)
> 
> ;; define "enum event" and "struct plan"
> #>
> #define EV_X 111
> #define EV_Y 222
> <#
> 
> (define-foreign-enum-type
> (event unsigned-integer32)
> (event->int int->event)
> ((evx event/x) EV_X)
> ((evy event/y) EV_Y))
> 
> (define-foreign-record-type
> plan
> (integer nxt plan-nxt)
> (c-string msg plan-msg))
> 
> ;; assume this function comes from a library, it doesn't know about event
> ;; or plan:
> (define (print-type-info type)
> (cond ((??) (printf "~a is enum~n" type))
>       ((??) (printf "~a is struct~n" type))
>       (else (printf "~a is something else~n" type))))
> 
> ;; And I'd hope to use it like this
> (print-type-info 'plan)
> (print-type-info 'event)
> 
> ;; Or like this if print-type-info would need to be defined with syntax-rules.
> (print-type-info plan)
> (print-type-info event)
> ```
> 
> Any suggestions?
> 
> Thanks in advance.
> 
> Best,
> -Diogo
> 


Reply via email to