2011-08-20 4 views
1

나는 Scheme의 새로운 매크로 시스템을 이해하는데 어려움이있다. 경로의 어딘가에 먼저 함수로 "매크로"를 작성한 다음 나중에 매크로로 적용하기 시작했습니다. 내가 할 것으로 보인다 함수를 작성했습니다이 함수를 매크로로 변환하는 방법은 무엇입니까?

;; 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)) 

: regexpes로 컴파일 일치하는 문자열 cond 시리즈의 이런 종류의 속으로

;; 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")))) 

:

그래서 내 임무는 다음과 같은 구조를 설정하는 것입니다 트릭 :

;; (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))) 

주어진으로 주어진(210 개) 함수가 반환 올바른 보이는 (물론 떨어져 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

매크로로 함수를 변환하는 가장 쉬운 방법은 (명시 적-이름 바꾸기 매크로 위생을 유지하는 데 사용할 수있는 몇 가지 추가 인수를 제외하고) Clojure에서의 defmacro 비슷하게 작동 치킨의 explicit-renaming 매크로 기능을 사용하는 것입니다.

스플 라싱은 기본적으로 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

관련 문제