diff --git a/collects/unstable/scribblings/srcloc.scrbl b/collects/unstable/scribblings/srcloc.scrbl index f4e69e78c2..551d9fd58c 100644 --- a/collects/unstable/scribblings/srcloc.scrbl +++ b/collects/unstable/scribblings/srcloc.scrbl @@ -1,10 +1,27 @@ #lang scribble/manual @(require scribble/eval "utils.ss" (for-label scheme/base unstable/srcloc)) -@(define evaluator (make-base-eval)) -@(evaluator '(require unstable/srcloc)) +@(define unsyntax #f) -@title[#:tag "srcloc"]{Source Locations} +@(define (new-evaluator) + (let* ([e (make-base-eval)]) + (e '(require (for-syntax scheme/base) + unstable/srcloc + unstable/location)) + e)) + +@(define evaluator (new-evaluator)) + +@(define reference-path + '(lib "scribblings/reference/reference.scrbl")) + +@title{Source Locations} + +There are two libraries in this collection for dealing with source locations; +one for manipulating representations of them, and the other for quoting the +location of a particular piece of source code. + +@section[#:tag "srcloc"]{Representations} @defmodule[unstable/srcloc] @@ -96,6 +113,62 @@ span sources. They also convert the result to the desired representation: } +@defproc[(source-location-known? [loc source-location?]) boolean?]{ + +This predicate reports whether a given source location contains more information +than simply @scheme[#f]. + +@examples[#:eval evaluator +(source-location-known? #f) +(source-location-known? (make-srcloc #f #f #f #f #f)) +(source-location-known? (make-srcloc 'source 1 2 3 4)) +(source-location-known? (list #f #f #f #f #f)) +(source-location-known? (vector 'source #f #f #f #f)) +(source-location-known? (datum->syntax #f null #f)) +(source-location-known? (datum->syntax #f null (list 'source #f #f #f #f))) +] + +} + +@deftogether[( +@defproc[(source-location-source [loc source-location?]) any/c] +@defproc[(source-location-line [loc source-location?]) + (or/c orexact-positive-integer? #f)] +@defproc[(source-location-column [loc source-location?]) + (or/c exact-nonnegative-integer? #f)] +@defproc[(source-location-position [loc source-location?]) + (or/c exact-positive-integer? #f)] +@defproc[(source-location-span [loc source-location?]) + (or/c exact-nonnegative-integer? #f)] +)]{ + +These accessors extract the fields of a source location. + +@examples[#:eval evaluator +(source-location-source #f) +(source-location-line (make-srcloc 'source 1 2 3 4)) +(source-location-column (list 'source 1 2 3 4)) +(source-location-position (vector 'source 1 2 3 4)) +(source-location-span (datum->syntax #f null (list 'source 1 2 3 4))) +] + +} + +@defproc[(source-location-end [loc source-location?]) + (or/c exact-nonnegative-integer? #f)]{ + +This accessor produces the end position of a source location (the sum of its +position and span, if both are numbers) or @scheme[#f]. + +@examples[#:eval evaluator +(source-location-end #f) +(source-location-end (make-srcloc 'source 1 2 3 4)) +(source-location-end (list 'source 1 2 3 #f)) +(source-location-end (vector 'source 1 2 #f 4)) +] + +} + @deftogether[( @defproc[(source-location->string [loc source-location?]) string?]{} @defproc[(source-location->prefix [loc source-location?]) string?]{} @@ -121,3 +194,143 @@ The first produces a string describing the source location; the second appends ] } + +@section[#:tag "location"]{Quoting} + +@defmodule[unstable/location] + +@unstable[@author+email["Carl Eastlund" "cce@ccs.neu.edu"]] + +This module defines macros that evaluate to various aspects of their own source +location. + +@emph{Note:} The examples below illustrate the use of these macros and the +representation of their output. However, due to the mechanism by which they are +generated, each example is considered a single character and thus does not have +realistic line, column, and character positions. + +Furthermore, the examples illustrate the use of source location quoting inside +macros, and the difference between quoting the source location of the macro +definition itself and quoting the source location of the macro's arguments. + +@defform*[[(quote-srcloc) (quote-srcloc expr)]]{ + +This form quotes the source location of @scheme[expr] as a @scheme[srcloc] +structure, using the location of the whole @scheme[(quote-srcloc)] expression if +no @scheme[expr] is given. + +@defexamples[#:eval (new-evaluator) +(quote-srcloc) +(define-syntax (not-here stx) #'(quote-srcloc)) +(not-here) +(not-here) +(define-syntax (here stx) #`(quote-srcloc #,stx)) +(here) +(here) +] + +} + +@deftogether[( +@defform*[[(quote-source-file) (quote-source-file expr)]] +@defform*[[(quote-line-number) (quote-line-number expr)]] +@defform*[[(quote-column-number) (quote-column-number expr)]] +@defform*[[(quote-character-position) (quote-character-position expr)]] +@defform*[[(quote-character-span) (quote-character-span expr)]] +)]{ + +These forms quote various fields of the source location of @scheme[expr], or of +the whole macro application if no @scheme[expr] is given. + +@examples[#:eval (new-evaluator) +(list (quote-source-file) + (quote-line-number) + (quote-column-number) + (quote-character-position) + (quote-character-span)) +(define-syntax (not-here stx) + #'(list (quote-source-file) + (quote-line-number) + (quote-column-number) + (quote-character-position) + (quote-character-span))) +(not-here) +(not-here) +(define-syntax (here stx) + #`(list (quote-source-file #,stx) + (quote-line-number #,stx) + (quote-column-number #,stx) + (quote-character-position #,stx) + (quote-character-span #,stx))) +(here) +(here) +] + +} + +@defform[(quote-module-path)]{ + +This form quotes a module path suitable for use with @scheme[require] which +refers to the module in which the macro application occurs. If executed at the +top level, it may return @scheme['top-level], or it may return a valid module +path if the current namespace was constructed by @scheme[module->namespace] +(such as at the DrScheme interactions window). + +This macro operates by creating a @tech[#:doc reference-path]{variable +reference} (see @scheme[#%variable-reference]) at the point of its application. +It thus automatically describes its final expanded position, rather than the +module of any macro definition that happens to use it. + +@defexamples[#:eval (new-evaluator) +(quote-module-path) +(module A scheme + (require unstable/location) + (define-syntax-rule (here) (quote-module-path)) + (define a (here)) + (provide a here)) +(require 'A) +a +(module B scheme + (require unstable/location) + (require 'A) + (define b (here)) + (provide b)) +(require 'B) +b +[current-namespace (module->namespace (quote 'A))] +(quote-module-path) +] + +} + +@defform[(quote-module-name)]{ + +This form quotes the name (@tech[#:doc reference-path]{path} or @tech[#:doc +reference-path]{symbol}) of the module in which the macro application occurs, or +@scheme[#f] if it occurs at the top level. As with @scheme[quote-module-path], +@scheme[quote-module-name] uses a @tech[#:doc reference-path]{variable +reference}, so a top level namespace created by @scheme[module->namespace] will +be treated as a module, and the macro will always produce the module name of its +final expanded position. + +@defexamples[#:eval (new-evaluator) +(quote-module-name) +(module A scheme + (require unstable/location) + (define-syntax-rule (here) (quote-module-name)) + (define a (here)) + (provide a here)) +(require 'A) +a +(module B scheme + (require unstable/location) + (require 'A) + (define b (here)) + (provide b)) +(require 'B) +b +[current-namespace (module->namespace (quote 'A))] +(quote-module-name) +] + +}