你当然可以写一些需要在引用s表达式和输出转换为带引号的S-表达。
首先将格式良好的列表'(#\C#\a #\d #\r)
简单地翻译成您的第一个/ rest表达式。
立即建立与符号的溶液?,符号 - >串,正则表达式匹配#rx “^ C(A | d)+ R $”,与字符串>列表,并且映射
遍历输入。如果是符号,请检查正则表达式(如果失败则按原样返回),转换为列表并使用起始翻译器。递归嵌套表达式。
编辑:这里的一些糟糕的代码,可以转换源到源(假设目的是要读取输出)
;; 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)))
正如在评论中提到的,我很好奇,为什么你要一个宏。如果目的是将源代码转换为可读的内容,那么您是否想捕获输出来替换原始代码?
如果我能够,我会多次+1。非常好! – 2012-02-06 07:04:24
优秀!这个解决方案是我想要的,谢谢!球拍是一个真正美丽而强大的语言。 – 2012-02-06 15:06:24
@RacketNoob大多数Racket开发人员推荐如何设计程序。这不是一个球拍手册,它可能不包括'#%top',但它仍然是一本有用的书。 – 2012-02-06 16:50:48