I have a macro that generates another macro. It uses the letrec trick to
generate temporaries to use as binders in the left-hand-side of the
generated syntax-rules.
The following code, when pasted into csi (and chibi, as a test) does the
correct thing:
(define-syntax define-alist-macro
(syntax-rules ()
((_ name (ids ...))
(define-alist-macro "generate" name (ids ...) ()))
((_ "generate" name (id ids ...) (acc ...))
(define-alist-macro "generate" name (ids ...) ((cons id tmp) acc
...)))
((_ "generate" name () ((cons id tmp) ...))
(define-syntax name
(syntax-rules ...* ()
((_ tmp ...) (list (cons (quote id) tmp) ...)))))))
(define-alist-macro test (a b c d))
(display (test 4 3 2 1))
This displays "((d . 4) (c . 3) (b . 2) (a . 1))".
However, if I put the same code in a module:
(module my-test (define-alist-macro test)
(import scheme)
(define-syntax define-alist-macro
(syntax-rules ()
((_ name (ids ...))
(define-alist-macro "generate" name (ids ...) ()))
((_ "generate" name (id ids ...) (acc ...))
(define-alist-macro "generate" name (ids ...) ((cons id tmp) acc
...)))
((_ "generate" name () ((cons id tmp) ...))
(define-syntax name
(syntax-rules ...* ()
((_ tmp ...) (list (cons (quote id) tmp) ...)))))))
(define-alist-macro test (a b c d)))
compile that module with "csc -s tmp-module.scm", and then run in csi
(load "tmp-module.so")
(import my-test)
(display (test 1 2 3 4))
I get "((d . 4) (c . 4) (b . 4) (a . 4))", probably because the compiled
CHICKEN code is turning all of the generated "tmp" variables into a
single identifier.
-----------------------------------------------------------
Chicken Version: 5.4.0
OS: Alpine Linux x86_64
CC: GCC Alpine 13.2.1_git20240309 (using musl libc)