2012-11-12 70 views
0

我一直在試圖爲'包裝'功能做一個宏,也就是說,如果我有一個功能,將採取列表和第一個元素的符號'a,它通常會被定義爲lambda(l) (cons'al),但我想要一個宏,它將採用一個函數和一個整數表達式對的列表,並通過創建一個新的函數來接收舊函數的一些參數,並基於對,使用整數作爲位置,表達式作爲賦予函數的值。事情是這樣的:如何使球拍宏採取整數參數?

(wrap list (0 'blah) (2 'bloo) (4 'blee)) 

應擴大到:

(lambda (a1 a2 . rest) 
    (apply list 'blah a1 'bloo a2 'blee rest)) 

問題是,我不知道如何讓宏找到一對整數值,只知道它作爲語法對象。我對宏相當陌生,而且這應該相當簡單,我只是在處理文檔時遇到問題,除了在宏上的簡單教程外,我無法在Web上找到任何信息。任何幫助,將不勝感激。

回答

3

這似乎是一個瘋狂的宏想寫,尤其是當SRFI 26是更直觀的使用。代替(wrap list (0 'blah) (2 'bloo) (4 'blee)),您可以使用:

(cut list 'blah <> 'bloo <> 'blee <...>) 

這肯定會更容易閱讀。


如果你真的必須寫這樣一個宏,這裏有一個方法去了解它,通過變換的wrap用途成cut相當於用法:

(require (for-syntax syntax/parse) srfi/26) 
(define-syntax (wrap stx) 
    (syntax-parse stx 
    ((_ func:expr (idx:nat expr:expr) ...) 
    (let* ((alist (map cons 
         (syntax->datum #'(idx ...)) 
         (syntax-e #'(expr ...)))) 
      (upper (add1 (apply max -1 (map car alist)))) 
      (listfunc (lambda (i) 
         (cond ((assv i alist) => cdr) 
           (else #'<>))))) 
     (with-syntax (((args ...) (build-list upper listfunc))) 
     #'(cut func args ... <...>)))))) 

關鍵要回答你的問題,關於如何獲得給定語法對象的整數,通過使用syntax->datum(用於深層語法剝離)或syntax-e(用於淺層語法剝離)。


(PS(要拍專家閱讀這一點。)我很新的syntax-parse,所以我敢肯定,syntax-parse專家可以找到更好的方法來寫上面的,我原來寫的宏爲syntax-case宏,然後打了syntax-parse語法類。就是這樣。)

+1

這很奇妙。我以前從未見過這個功能。謝謝一堆。我將不得不努力學習語法 - >數據。 – user1815463