2010-10-24 7 views
0

Je suis jouer avec un système simple doc string comme warm-up dans le schéma, l'idée étant que vous pourriez faire quelque chose comme:nom de la fonction de reliure comme argument à l'intérieur de la macro

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

qui serait tourné en:

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

la macro que j'ai écrit:

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

Prend la définition, déplace le param/desc/retou rn appelle le premier niveau enveloppé dans des instructions begin et reconstruit le corps de la fonction, de cette façon les appels de doc string ne sont exécutés qu'une seule fois lorsque le fichier est chargé plutôt qu'à chaque fois que la fonction est appelée. Je sais que je pourrais mettre manuellement les trucs doc-string au plus haut niveau mais j'essaye d'émuler les doc-strings Python. De toute façon, le dernier pense que je dois faire est de lier le nom de la fonction (foo ci-dessus) dans les appels doc-string, de sorte que (param 'un "Premier paramètre") devient (param' foo 'a " Premier paramètre ") de sorte que la fonction associée à chaque appel est connue. C'est là que j'ai des problèmes, chaque tentative que j'ai faite n'a pas réussi à faire ce que je veux.

+0

Pourriez-vous poster un exemple avant-après? (Vous avez déjà l'avant, mais ce n'est pas évident quel devrait être votre résultat final.) – erjiang

+0

Mise à jour du post avec un exemple montrant mon objectif. –

Répondre

1

Je suggère d'utiliser define-syntax car il est hygiénique et ses syntax-rules sont assez faciles à comprendre. syntax-rules sont dans un format pattern-to-result; Si vous pouvez comprendre cond, vous pouvez comprendre syntax-rules.

Je pense que cela fait ce que vous voulez, à en juger par les snippets avant et après.

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

Pardonnez ma terminologie parce que je n'ai jamais utilisé de doc-string. Fondamentalement, cela correspond à tout ce qui suit ce modèle d'une fonction + params def, 0 ou plusieurs balises avec des attributs, et une instruction de code.

Ensuite, il réarrange tout.

+0

Je vais essayer, merci! –

Questions connexes