Scheme语法转换

时间:2014-07-09 17:13:40

标签: syntax scheme

我对Scheme很新,我一直在努力解决我认为应该是一个简单的问题。

我正在尝试转换类似

的内容

((qty 30) (name "ham"))(sandwich "@qty" 30) (sandwich "@name" "ham")

此外,这必须是动态的,以允许额外的条款:

((qty 30) (name "ham") (cheese 'no))

这是我到目前为止所做的:

(define-syntax (make-sandwiches x)
        (syntax-case x ()
            [(_ ((col val)...) ) #``(sandwich #,(format "@,~a" (caar #'((col val)...))) #,(cadar #'((col val)...)))] 
            [(_) "make-sandwiches is bad"]))

(制作三明治((数量30)(姓名"火腿")))=> (param" @#(语法数量)" 30)

所以这有点接近,但它只翻译第一个子句,所以我的想法是使用map或类似的东西,但我不确定这是否正确:

(define-syntax (make-sandwiches x)
        (syntax-case x ()
            [(_ ((col val)...)) (map (lambda (cv) #``(sandwich #,(format "@,~a" (caar cv)) #,(cadar cv))) #'((col val)...))] 
            [(_) "make-sandwiches is bad"]))

1 个答案:

答案 0 :(得分:4)

你真的必须使用宏吗?并返回多个值?一个返回列表的简单程序就可以解决问题:

(define (make-sandwiches lst)
  (map (lambda (data)
         (list 'sandwich
               (string-append "@" (symbol->string (car data)))
               (cadr data)))
       lst))

或者更短(你似乎在使用Racket):

(define (make-sandwiches lst)
  (map (lambda (data) `(sandwich ,(format "@~a" (first data)) ,(second data)))
       lst))

例如,使用问题中的示例输入:

(make-sandwiches '((qty 30) (name "ham") (cheese 'no)))
=> '((sandwich "@qty" 30) (sandwich "@name" "ham") (sandwich "@cheese" 'no))