1
0
forked from alex-eg/sex
Files
sex/sex-macros.scm
alex-eg 381ad21d8b separate tags and typedefs
C has two namespaces and the database had one. A typedef of a tag's
name wiped it.

Tags, i.e. struct, enum and union, share one namespace; they move to a
table of their own. A name resolves the way C does: the ordinary
identifier first, the tag when that leads nowhere.

While resolving a typedef, the target was taken apart with cadr
whatever it was, so (typedef points (¤ point 4)) reported point's
fields as its own -- an array of four points claiming to be a point,
and a macro reaching through it with v->x. Only a name and
(struct|union|enum NAME) name a type now.
2026-09-23 14:31:41 +03:00

51 lines
1.4 KiB
Scheme

(import
scheme
(only fmt fmt)
(chicken base)
(chicken plist)
(chicken string))
(define (cat-syms s-1 s-2)
(fmt #f s-1 s-2))
(define (cat sym-1 sym-2)
(string->symbol (cat-syms sym-1 sym-2)))
;;; The reader keeps `;' comments as (comment "...") forms so they can
;;; be re-emitted into the generated C. In a macro body a comment
;;; should be a call which does nothing, hence this one
(define (comment . _)
(void))
(define (register-macro name arglist body)
(put! name 'sex-macro
`(lambda ,arglist
;; A macro body is ordinary Scheme, evaluated at compile
;; time. It gets `cat' for building names, and read access to
;; the type database
(import scheme
(scheme base)
(only sex-macros cat comment)
(only types get-type-info get-tag-info get-fields
get-underlying-type type-match map-fields))
,@body)))
(define (get-macro name)
(eval (get name 'sex-macro)))
(define (macro? form)
(and (list? form)
(symbol? (car form))
(get (car form) 'sex-macro)))
(define (apply-macro form)
(assert (macro? form)
(fmt #f (car form) " is not a macro"))
(apply (get-macro (car form))
(cdr form)))
(define (defmacro form)
(let ((arglist (car form))
(body (cdr form)))
(register-macro (car arglist) (cdr arglist) body)))