Вы, конечно, можете написать что-то, что принимает в s-выражение в кавычках и выводит перевод как s-выражение в кавычках.
Начните с простого перевода правильно сформированных списков, таких как '(#\c #\a #\d #\r)
, в ваши первые / остальные s-выражения.
Теперь создайте решение с помощью символа ?, 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)))
Как уже упоминалось в комментариях, мне любопытно, зачем вам нужен макрос. Если цель состоит в том, чтобы перевести источник в нечто читаемое, не хотите ли вы захватить вывод для замены оригинала?