Reputation: 459
I'm using Chez Scheme and I'd like to introduce some top-level bindings based on the contents of a directory. The usage of this hypothetical macro might look like this:
(bind-files f "~/my-dir/")
;; Expanding to:
(begin (define f0 "~/my-dir/a.wav")
(define f1 "~/my-dir/b.wav"))
I'm getting comfortable with syntax-case
, datum->syntax
and with-syntax
as described in the Scheme book's examples. But I can't imagine how one could create identifiers based on the result of something 'runtime-y' like (directory-list "~/")
- is it even possible?
(By the way, this is for a live-coding musical application, so there's no need to comment that this is a bad idea for reliable software - it's for a very specific interactive context.)
Upvotes: 1
Views: 782
Reputation: 646
You can use something like this macro:
#!r6rs
(import (rnrs) (chezscheme))
(define-syntax bind-file
(lambda (x)
(define (name&file k dir)
(define (->fn i)
(string->symbol (string-append "f" (number->string i))))
(let ((files (directory-list (syntax->datum dir))))
(datum->syntax k (do ((i 0 (+ i 1)) (files files (cdr files))
(r '() (cons (list (->fn i) (car files)) r)))
((null? files) r)))))
(syntax-case x ()
((k dir)
(string? (syntax->datum #'dir))
(with-syntax ((((name file) ...) (name&file #'k #'dir)))
#'(begin (define name file) ...))))))
(bind-file ".")
#|
;; depending on the number of files
f0 ... fn variables are defined.
|#
Upvotes: 1