Re: Figuring out enums and structs with foreigners

Kon Lovett via Chicken-users <[email protected]>
Newsgroups gmane.lisp.scheme.chicken
Message-ID <[email protected]>

> On Mar 23, 2025, at 7:13 AM, Diogo via Chicken-users <[email protected]> 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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.