2011-08-20 99 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