引用符で囲まれたs-expressionを取り込んで、引用符で囲まれたs-expressionとして翻訳を出力するものを確実に書くことができます。
のような整形式のリスト'(#\c #\a #\d #\r)を最初の/残りのS式に単純に変換することから始めます。
次に、symbol?、symbol-> string、regexp-match #rx "^ c(a | d)+ r $"、string-> list、およびmapを使用してソリューションを構築します。
入力をトラバースします。シンボルの場合は、正規表現を確認し(失敗した場合はそのまま返します)、リストに変換して、最初のトランスレーターを使用します。ネストされた式を繰り返します。
編集:ソースからソースに変換できるいくつかのひどく書かれたコードがあります(目的が出力を読み取ることであると仮定して)
;; translates a list of characters '(#\c #\a #\d #\r)
;; into first and rest equivalents
;; throw first of rst into call
(define (translate-list lst rst)
(cond [(null? lst) (raise #f)]
[(eq? #\c (first lst)) (translate-list (rest lst) rst)]
[(eq? #\r (first lst)) (first rst)]
[(eq? #\a (first lst)) (cons 'first (cons (translate-list (rest lst) rst) '()))]
[(eq? #\d (first lst)) (cons 'rest (cons (translate-list (rest lst) rst) '()))]
[else (raise #f)]))
;; translate the symbol to first/rest if it matches c(a|d)+r
;; pass through otherwise
(define (maybe-translate sym rst)
(if (regexp-match #rx"^c(a|d)+r$" (symbol->string sym))
(translate-list (string->list (symbol->string sym)) rst)
(cons sym rst)))
;; recursively first-restify a quoted s-expression
(define (translate-expression exp)
(cond [(null? exp) null]
[(symbol? (first exp)) (maybe-translate (first exp) (translate-expression (rest exp)))]
[(pair? (first exp)) (cons (translate-expression (first exp)) (translate-expression (rest exp)))]
[else exp]))
'test-2
(define test-2 '(cadr (1 2 3)))
(maybe-translate (first test-2) (rest test-2))
(translate-expression test-2)
(translate-expression '(car (cdar (list (list 1 2) 3))))
(translate-expression '(translate-list '() '(a b c)))
(translate-expression '(() (1 2)))
コメントで述べたように、なぜマクロが必要なのか興味があります。ソースを読みやすいものに変換することが目的の場合、出力をキャプチャして元の出力を置き換えたくないですか?