2010-09-17 28 views

Répondre

5

Vous ne pouvez pas le faire de cette façon - cela ne fonctionnera pas pour un certain nombre de contextes. Voici quelques exemples qui ne fonctionnera pas:

(+ (/* foo */) 1 2) 

(define (foo a (/* b */) c) ...) 

(/* foo; bar */) 

(/*x*/) 

(let ((x (/* 1 */) 2)) 
    ...) 

(let ((/* (x 1) */) 
     (x 2)) 
    ...) 

(car '((/* foo */) 1 2 3)) 

Il n'y a pas de commentaire multistandard en ligne dans le schéma des rapports jusqu'à r5rs, mais R6RS a ajouté une syntaxe qui a été largement utilisé de toute façon: #|...|#.

Mais si vous vraiment voulez ...

Voici ce que je parlais dans le commentaire: si vous êtes prêt à envelopper tout le code dans une macro, la macro peut traiter l'ensemble corps, ce qui peut être efficace dans beaucoup plus de contextes. Presque tous, sauf pour essayer de commenter des choses syntaxiquement invalides comme l'exemple du point-virgule ci-dessus, ou une chaîne non terminée. Vous pouvez juger par vous-même si cela en vaut vraiment la peine ...

(Personnellement, autant que j'aime ces jeux, je pense toujours qu'ils sont inutiles.) Mais si vous aimez vraiment ces jeux et vous pensez qu'ils « re utile, puis voir la section ci-dessous devoirs ...)

(define-syntax prog (syntax-rules() [(_ x ...) (prog~ (begin x ...))])) 
(define-syntax prog~ 
    (syntax-rules (/* */) 
    [(prog~ (/* x ...) b ...) 
    ;; comment start => mark it (possibly nested on top of a previous mark) 
    (prog~ (x ...) /* b ...)] 
    [(prog~ (*/ x ...) /* b ...) 
    ;; finished eliminating a comment => continue 
    (prog~ (x ...) b ...)] 
    [(prog~ (*/ x ...) b ...) 
    ;; a comment terminator without a marker => error 
    (unexpected-comment-closing)] 
    [(prog~ (x0 x ...) /* b ...) 
    ;; some expression inside a comment => throw it out 
    (prog~ (x ...) /* b ...)] 
    [(prog~ ((y . ys) x ...) b ...) 
    ;; nested expression start => save the context 
    (prog~ (y . ys) prog~ ((x ...) (b ...)))] 
    [(prog~ (x0 x ...) b ...) 
    ;; atomic element => add it to the body 
    (prog~ (x ...) b ... x0)] 
    [(prog~() prog~ ((x ...) (b ...)) nested ...) 
    ;; nested expression done => restore context 
    (prog~ (x ...) b ... (nested ...))] 
    [(prog~() /* b ...) 
    ;; input done with an active marker => error 
    (unterminated-comment-error)] 
    [(prog~() b ...) 
    ;; all done, no markers, not nested => time for the burp. 
    (b ...)])) 

Et un exemple:

(prog 

(define x 1) 

(display (+ x 2)) (newline) 

/* 
(display (+ x 10)) 
/* nested comment! */ 
(/ 5 0) 
*/ 

(define (show label /* a label to show in the output, before x */ 
       x /* display this (and a newline), then returns it */) 
    (display label) 
    (display x) 
    (newline) 
    x 
    /* this comment doesn't prevent the function from returning x */) 

(let ([x 1] /* some comment here */ [y 2]) 
    (show "result = " /* now display the result of show... */ 
     (show "list = " (list x /* blah blah */ y))) 
    'done /* just a value to return from the `let' expression */) 

(show "and ... " '(even works /* boo! */ inside a quote)) 

) 

devoirs

Pour un crédit supplémentaire, étendez-le afin de pouvoir commenter les parens déséquilibrés. Par exemple, faire ce travail:

(prog 
blah blah /* junk (junk */ blah blah /* junk) junk */ blah blah. 
) 

De toute évidence, l'entrée dans son ensemble devrait avoir parens équilibre - cela signifie qu'il n'y a pas beaucoup d'intérêt à la mise en œuvre de ce genre d'une extension. Même sans cela, à quoi bon commenter un paren déséquilibré?

Mais si quelqu'un est tout le chemin ici, alors vous devez profiter de ce genre d'auto-torture ... non?

+0

Merci beaucoup! Donc, mon code pourrait être utile pour

+0

'(contre '(/ * je cite ce/*) un foo)' – Chuck

+0

S'il vous plaît, donnez-moi l'original contre la construction et ce que vous aimeriez commenter. Désolé, mais votre exemple de code n'a pas de sens pour moi. –

1

MIT, Gnu, R6RS et R7RS en charge les commentaires sur plusieurs lignes comme ceci:

#| 
    This is a comment 
|#