2011-08-20 97 views
1

我很難理解Scheme的新宏觀體系。在路徑的某處,我開始首先將我的「宏」作爲函數寫入,然後將其作爲宏應用。如何將此函數轉換爲宏?

所以,我的任務是把以下結構:

;; highlight-rules: rule id, color and the regexp matches 
(define highlight-rules 
    `((important ,(with-esc "[1;33m") ("foo" 
             "bob")) 
    (unimportant ,(with-esc "[1;30m") ("case of unimport")) 
    (urgent  ,(with-esc "[1;31m") ("urgents")))) 

進入這種cond一系列與之相匹配的字符串編譯regexpes:

;; just an example. `line` is an argument bound by the function application 
(cond 
    ((string-match (regexp ".*sudo:session.*") line) 
    (with-color *important* line)) 
    (else line)) 

我寫了似乎做一個函數訣竅:

;; (cdar highlight-rules) -> (colorstring list-of-rules) 
(define (parse-highlight-rules rules) 
    ;; aux function to do one 'class' of patterns 
    (define (class-of-rules colorstr rulelist) 
    (map (lambda (rule) 
     `((string-match ,(regexp rule)) (with-color ,colorstr line))) 
     rulelist)) 
    (define (do-loop accumulator rules) 
    (let* ((highlight-group (cdar rules)) 
      (colorstr  (car highlight-group)) 
      (grouprules  (cadr highlight-group)) 
      (acc*   (append (class-of-rules colorstr grouprules) accumulator)) 
      (rest   (cdr rules))) 
    (if (null? rest) 
     acc* 
     (do-loop acc* rest)))) 
    ; wrap the list in cond. 
    `(apply cond ,(do-loop '() rules))) 

按照給定的highlight-rules在函數返回正確的前瞻性列表(由應用apply得很開 - Clojure中的一個會使用拼接):

CSI> (parse-highlight-rules highlight-rules) 
(apply cond (((string-match #<regexp>) (with-color "\x1b[1;31m" line)) 
      ((string-match #<regexp>) (with-color "\x1b[1;30m" line)) 
      ((string-match #<regexp>) (with-color #0="\x1b[1;33m" line)) 
      ((string-match #<regexp>) (with-color #0# line)))) 

但如何執行該方法?我一直堅持這一點。雞計劃是我的方言。

回答

1

將您的功能成宏的最簡單的方法是使用雞的explicit-renaming宏功能,它的工作方式類似於Clojure的defmacro(除明確,重命名宏都可以用來保存衛生一些附加參數)。

拼接的工作方式與在Clojure中的工作基本相同。語法是,@。因此,以下應該工作:

(define-for-syntax (parse-highlight-rules rules) 
    ;; ... insert missing code here ... 
    `(cond ,@(do-loop '() rules))) 

(define-syntax highlight 
    (er-macro-transformer 
    (lambda (form rename compare) 
     (parse-highlight-rules (cdr form))))) 
+0

謝謝噸。現在我有一個更好的方向......只需稍微修改一下就可以使部分適合:) – progo