代码之家  ›  专栏  ›  技术社区  ›  gct

绑定函数名作为宏内部的参数

  •  0
  • gct  · 技术社区  · 14 年前

    所以我在玩一个简单的文档字符串系统作为方案的预热,你可以做如下的事情:

    (def-with-doc (foo a b)
      (desc     "Takes two parameters and sums them")
      (param 'a "First parameter")
      (param 'b "Second parameter")
      (return   "Sum of arguments")
      (+ a b)
    

    会变成:

    (begin
      (begin
        (desc   'foo    "Takes two parameters and sums them")
        (param  'foo 'a "First parameter")
        (param  'foo 'b "Second parameter")
        (return 'foo    "Sum of arguments"))
      (begin
         (define (foo a b)
            (+ a b))))
    

    我写的宏:

    (define doc-symbol-list '(param desc return))
    
    (define-macro (def-with-doc arg-list #!rest body)
      ;; Loop over body, splitting into doc calls and everything else
      (let loop ((remaining body) (docs '()) (main '()))
        (if (null? remaining)
           ; Reverse accumulation order of docs and main
           ; And build re-ordered begin tree
           (let ((docs (cons 'begin (reverse docs)))
             (main (cons 'begin (reverse main))))
               (cons 'begin `(,docs ,`(define ,arg-list ,main))))
    
          ; Accumulate into docs list if expression is reserved
          ; Otherwise  into the body list
          (let ((sexp (car remaining)) (rest (cdr remaining)))
            (if (member (car sexp) doc-symbol-list)
            (loop rest (cons sexp docs) main)
            (loop rest  docs (cons sexp main)))))))
    

    获取定义,将param/desc/return调用移动到begin语句包装的顶层,并重新构造函数体,这样,在加载文件时,文档字符串调用只执行一次,而不是每次调用函数时。我知道我可以手动将Doc字符串放到顶层,但我正在尝试模拟python-Doc字符串。

    总之,我最后一个需要做的是将函数名(上面的foo)绑定到Doc字符串调用中,这样(param'a“first parameter”)就变成(param'foo'a“first parameter”),这样每个调用所关联的函数都是已知的。这就是我遇到麻烦的地方,我所做的每一次尝试都没有达到我想要的效果。

    1 回复  |  直到 14 年前
        1
  •  1
  •   erjiang    14 年前

    我建议使用 define-syntax 因为它是卫生的 syntax-rules 很容易理解。 语法规则 是一种模式到结果的格式;如果你能理解 cond ,你可以理解 语法规则 .

    我认为这是你想要的,从前后的片段来看。

    (define-syntax def-with-doc
        (syntax-rules ()
          ;; this pattern
          [(_ (func params ...)
              (tag attributes ...)
              ...
              code)
           ;; is converted into
           (begin
             (tag (quote func) attributes ...)
             ...
             (define (func params ...)
               code))]))
    

    请原谅我的术语,因为我从未使用过文档字符串。 基本上,这与遵循函数+params def模式、0个或多个带有属性的标记以及一个代码语句的任何内容匹配。

    然后,它只是重新排列所有的东西。