8 Check Syntax
Check Syntax is a part of the DrRacket collection, but is implemented via the plugin API. See also drracket/check-syntax.
8.1 Check Syntax Button
(require drracket/syncheck-drracket-button) | |
package: drracket |
value
syncheck-drracket-button :
(list/c string? (is-a?/c bitmap%) (-> (is-a?/c top-level-window<%>) any))
syntax
value
8.2 Syntax Properties that Check Syntax Looks For
Check Syntax collects the values of the syntax-propertys named 'disappeared-use, 'disappeared-binding, 'sub-range-binders, and 'mouse-over-tooltips and uses them to add additional arrows to the program text. These properties are intended for use when a macro discards or manufactures identifiers that, from the programmers perspective, should be binding each other.
For example, here is a macro that discards its arguments, but adds properties to the result syntax object so the arguments are treated as a binding/bound pair by Check Syntax.
(define-syntax (m stx) (syntax-case stx () [(_ id1 id2) (and (identifier? #'id1) (identifier? #'id2)) (syntax-property (syntax-property #'1 'disappeared-use (list (syntax-local-introduce #'id1))) 'disappeared-binding (list (syntax-local-introduce #'id2)))]))
See also current-recorded-disappeared-uses.
(vector/c syntax? exact-nonnegative-integer? exact-nonnegative-integer? (real-in 0 1) (real-in 0 1) syntax? exact-nonnegative-integer? exact-nonnegative-integer? (real-in 0 1) (real-in 0 1))
#lang racket/base (require (for-syntax racket/base)) (define-syntax (define/hyphen stx) (syntax-case stx () [(_ id1 id2 rhs-expr) (let () (define first-part (symbol->string (syntax-e #'id1))) (define second-part (symbol->string (syntax-e #'id2))) (define first-len (string-length first-part)) (define second-len (string-length second-part)) (define hyphenated-id (datum->syntax #'id1 (string->symbol (string-append first-part "-" second-part)))) (syntax-property #`(define #,hyphenated-id rhs-expr) 'sub-range-binders (list (vector (syntax-local-introduce hyphenated-id) 0 first-len 0.5 0.5 (syntax-local-introduce #'id1) 0 first-len 0.5 0.5) (vector (syntax-local-introduce hyphenated-id) (+ first-len 1) second-len 0.5 0 (syntax-local-introduce #'id2) 0 second-len 0.5 1))))])) (define/hyphen big generator 11) (+ big-generator big-generator)
After putting this code in the DrRacket window, mouse over the words “big” and “generator” to see arrows pointing to the individual pieces of the identifier big-generator. The four 0.5s in the first vector put the arrows on big in the center of the identifiers; the 0.5 0 and the 0.5 1 in the second vector put the arrows at the top and bottom center for generator.
Also, for backwards compatibility, if the vector has only six elements, those elements must be everything except the (real 0 1) elements listed above and, in that case, all four numbers are all taken to be 0.5.
(vector/c syntax? exact-nonnegative-integer? exact-nonnegative-integer? (or/c string? (-> string?)))
#lang racket (define-syntax (char-span stx) (syntax-case stx () [(_ a) (syntax-property #'a 'mouse-over-tooltips (vector stx (syntax-position stx) (+ (syntax-position stx) (syntax-span stx)) (format "this expression\nspans ~a chars" (syntax-span stx))))])) (char-span (+ 1 2))
Finally, Check Syntax draws arrows only between identifiers that are syntax-original? or that have the syntax-property 'original-for-check-syntax set to #t.
Changed in version 1.3 of package drracket: Looks for 'sub-range-binders on binding identifiers (not just in expression positions).