2017-07-27 10 views
1

は、私がこのようなマクロがあるとしましょう:余分なかっこなしのマクロ内でのマッピングですか?

(define-syntax (choose stx) 
    (define data (syntax->datum stx)) 
    (define args (cadr data)) 
    (define body (cddr data)) 
    (define output 
    `(apply (case (car ,args) 
       ,(map (lambda (choice) 
          `((,(car choice)) ,(cadr choice))) 
         body) 
       (else (displayln "error"))) 
      (cdr ,args))) 
    (println output) 
    #'(void)) 

私はこの(より多くのオプションがあるかもしれない)のようなもので、これを使用する場合:

(choose args 
     ("run" runsomething) 
     ("del" delsomethingelse)) 

それは

(apply 
(case (car args) 
    ((("run") runsomething) 
    (("del") delsomethingelse)) 
    (else (displayln "error"))) 
(cdr args)) 
にそれを変換し

これは有効なコードではありません。マップが余分なカッコを付けたためです。代わりに、私にこのことを教えてください:

(apply 
(case (car args) 
    (("run") runsomething) 
    (("del") delsomethingelse) 
    (else (displayln "error"))) 
(cdr args)) 

どうすればいいですか?

答えて

2

unquote-splicing(別名,@)を使用すると、mapのリストを削除できます。

例:私はあなたが入力構文変圧器のstxsyntax->datumを使用することに注意してくださいしかし

(define xs '(a b c)) 
`(1 2 ,xs 3 4) ; => '(1 2 (a b c) 3 4) 
`(1 2 ,@xs 3 4) ; => '(1 2 a b c 3 4) 

。これにより、語彙情報が削除され、 が問題を引き起こす可能性があります。パターンマッチングを使用して入力構文とテンプレートの要素 を選択して出力を生成するsyntax-case またはsyntax-parseのいずれかを使用することをお勧めします。

(define-syntax (choose stx) 
    (syntax-case stx() 
    [(_choose args 
       (datum fun-expr) 
       ...) 
    #'(apply (case (car args) 
       [(datum) fun-expr] 
       ...) 
       (cdr args))])) 

(define (run-it . xs) (list 'ran-it xs)) 
(define (del-it . xs) (list 'delt-it xs)) 

(choose (list "run" 1 2 3) 
     ("run" run-it) 
     ("del" del-it)) 

Output: '(ran-it (1 2 3)) 
+0

あなたはそれが 'syntax-> datum'は、語彙情報を削除しますが、それは' datum->はsyntaxの最初のパラメータ( 'ctxt')によって解決されていないと言いますか? – Wysaard

+0

いいえ。datum->構文アプローチは、すべてのものに対して同じコンテキスト(選択フォームを使用する)を与えます。 argsとfun-exprsは異なるコンテキストを持つかもしれません。 – soegaard

+0

例:あるマクロでargsを生成し、別のマクロでfun-exprsを生成すると、コンテキストは異なります。 – soegaard