On this page:
9.1 Representations
source-location?
source-location-list?
source-location-vector?
check-source-location!
build-source-location
build-source-location-list
build-source-location-vector
build-source-location-syntax
source-location-known?
source-location-source
source-location-line
source-location-column
source-location-position
source-location-span
source-location-end
source-location->string
source-location->prefix
9.2 Quoting
quote-srcloc
quote-source-file
quote-line-number
quote-column-number
quote-character-position
quote-character-span
quote-module-path
quote-module-name
Version: 4.2.5

9 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.

9.1 Representations

Carl Eastlund <cce@ccs.neu.edu>

 (require unstable/srcloc)

This library is unstable; compatibility will not be maintained. See Unstable for more information.

This module defines utilities for manipulating representations of source locations, including both srcloc structures and all the values accepted by datum->syntax’s third argument: syntax objects, lists, vectors, and #f.

(source-location? x)  boolean?
  x : any/c
(source-location-list? x)  boolean?
  x : any/c
(source-location-vector? x)  boolean?
  x : any/c
These functions recognize valid source location representations. The first, source-location?, recognizes srcloc structures, syntax objects, lists, and vectors with appropriate structure, as well as #f. The latter predicates recognize only valid lists and vectors, respectively.

Examples:

  > (source-location? #f)

  #t

  > (source-location? #'here)

  #t

  > (source-location? (make-srcloc 'here 1 0 1 0))

  #t

  > (source-location? (make-srcloc 'bad 1 #f 1 0))

  #f

  > (source-location? (list 'here 1 0 1 0))

  #t

  > (source-location? (list* 'bad 1 0 1 0 'tail))

  #f

  > (source-location? (vector 'here 1 0 1 0))

  #t

  > (source-location? (vector 'bad 0 0 0 0))

  #f

(check-source-location! name x)  void?
  name : symbol?
  x : any/c
This procedure checks that its input is a valid source location. If it is, the procedure returns (void). If it is not, check-source-location! raises a detailed error message in terms of name and the problem with x.

Examples:

  > (check-source-location! 'this-example #f)
  > (check-source-location! 'this-example #'here)
  > (check-source-location! 'this-example (make-srcloc 'here 1 0 1 0))
  > (check-source-location! 'this-example (make-srcloc 'bad 1 #f 1 0))

  this-example: expected a source location with line number

  and column number both numeric or both #f; got 1 and #f

  respectively: #(struct:srcloc bad 1 #f 1 0)

  > (check-source-location! 'this-example (list 'here 1 0 1 0))
  > (check-source-location! 'this-example (list* 'bad 1 0 1 0 'tail))

  this-example: expected a source location (a list of 5

  elements); got an improper list: (bad 1 0 1 0 . tail)

  > (check-source-location! 'this-example (vector 'here 1 0 1 0))
  > (check-source-location! 'this-example (vector 'bad 0 0 0 0))

  this-example: expected a source location with a positive

  line number or #f (second element); got line number 0:

  #(bad 0 0 0 0)

These procedures combine multiple (zero or more) source locations, merging locations within the same source and reporting #f for locations that span sources. They also convert the result to the desired representation: srcloc, list, vector, or syntax object, respectively.

Examples:

  > (build-source-location)

  #(struct:srcloc #f #f #f #f #f)

  > (build-source-location-list)

  (#f #f #f #f #f)

  > (build-source-location-vector)

  #(#f #f #f #f #f)

  > (build-source-location-syntax)

  #<syntax ()>

  > (build-source-location #f)

  #(struct:srcloc #f #f #f #f #f)

  > (build-source-location-list #f)

  (#f #f #f #f #f)

  > (build-source-location-vector #f)

  #(#f #f #f #f #f)

  > (build-source-location-syntax #f)

  #<syntax ()>

  > (build-source-location (list 'here 1 2 3 4))

  #(struct:srcloc here 1 2 3 4)

  > (build-source-location-list (make-srcloc 'here 1 2 3 4))

  (here 1 2 3 4)

  > (build-source-location-vector (make-srcloc 'here 1 2 3 4))

  #(here 1 2 3 4)

  > (build-source-location-syntax (make-srcloc 'here 1 2 3 4))

  #<syntax:1:2 ()>

  > (build-source-location (list 'here 1 2 3 4) (vector 'here 5 6 7 8))

  #(struct:srcloc here 1 2 3 12)

  > (build-source-location-list (make-srcloc 'here 1 2 3 4) (vector 'here 5 6 7 8))

  (here 1 2 3 12)

  > (build-source-location-vector (make-srcloc 'here 1 2 3 4) (vector 'here 5 6 7 8))

  #(here 1 2 3 12)

  > (build-source-location-syntax (make-srcloc 'here 1 2 3 4) (vector 'here 5 6 7 8))

  #<syntax:1:2 ()>

  > (build-source-location (list 'here 1 2 3 4) (vector 'there 5 6 7 8))

  #(struct:srcloc #f #f #f #f #f)

  > (build-source-location-list (make-srcloc 'here 1 2 3 4) (vector 'there 5 6 7 8))

  (#f #f #f #f #f)

  > (build-source-location-vector (make-srcloc 'here 1 2 3 4) (vector 'there 5 6 7 8))

  #(#f #f #f #f #f)

  > (build-source-location-syntax (make-srcloc 'here 1 2 3 4) (vector 'there 5 6 7 8))

  #<syntax ()>

This predicate reports whether a given source location contains more information than simply #f.

Examples:

  > (source-location-known? #f)

  #f

  > (source-location-known? (make-srcloc #f #f #f #f #f))

  #f

  > (source-location-known? (make-srcloc 'source 1 2 3 4))

  #t

  > (source-location-known? (list #f #f #f #f #f))

  #f

  > (source-location-known? (vector 'source #f #f #f #f))

  #t

  > (source-location-known? (datum->syntax #f null #f))

  #t

  > (source-location-known? (datum->syntax #f null (list 'source #f #f #f #f)))

  #t

(source-location-source loc)  any/c
  loc : source-location?
(source-location-line loc)
  (or/c orexact-positive-integer? #f)
  loc : source-location?
(source-location-column loc)
  (or/c exact-nonnegative-integer? #f)
  loc : source-location?
(source-location-position loc)
  (or/c exact-positive-integer? #f)
  loc : source-location?
(source-location-span loc)
  (or/c exact-nonnegative-integer? #f)
  loc : source-location?
These accessors extract the fields of a source location.

Examples:

  > (source-location-source #f)

  #f

  > (source-location-line (make-srcloc 'source 1 2 3 4))

  1

  > (source-location-column (list 'source 1 2 3 4))

  2

  > (source-location-position (vector 'source 1 2 3 4))

  3

  > (source-location-span (datum->syntax #f null (list 'source 1 2 3 4)))

  4

This accessor produces the end position of a source location (the sum of its position and span, if both are numbers) or #f.

Examples:

  > (source-location-end #f)

  #f

  > (source-location-end (make-srcloc 'source 1 2 3 4))

  7

  > (source-location-end (list 'source 1 2 3 #f))

  #f

  > (source-location-end (vector 'source 1 2 #f 4))

  #f

These procedures convert source locations to strings for use in error messages. The first produces a string describing the source location; the second appends ": " to the string if it is non-empty.

Examples:

  > (source-location->string (make-srcloc 'here 1 2 3 4))

  "here:1.2"

  > (source-location->string (make-srcloc 'here #f #f 3 4))

  "here::3-7"

  > (source-location->string (make-srcloc 'here #f #f #f #f))

  "here"

  > (source-location->string (make-srcloc #f 1 2 3 4))

  ":1.2"

  > (source-location->string (make-srcloc #f #f #f 3 4))

  "::3-7"

  > (source-location->string (make-srcloc #f #f #f #f #f))

  ""

  > (source-location->prefix (make-srcloc 'here 1 2 3 4))

  "here:1.2: "

  > (source-location->prefix (make-srcloc 'here #f #f 3 4))

  "here::3-7: "

  > (source-location->prefix (make-srcloc 'here #f #f #f #f))

  "here: "

  > (source-location->prefix (make-srcloc #f 1 2 3 4))

  ":1.2: "

  > (source-location->prefix (make-srcloc #f #f #f 3 4))

  "::3-7: "

  > (source-location->prefix (make-srcloc #f #f #f #f #f))

  ""

9.2 Quoting

Carl Eastlund <cce@ccs.neu.edu>

 (require unstable/location)

This library is unstable; compatibility will not be maintained. See Unstable for more information.

This module defines macros that evaluate to various aspects of their own source location.

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.

(quote-srcloc)
(quote-srcloc expr)
This form quotes the source location of expr as a srcloc structure, using the location of the whole (quote-srcloc) expression if no expr is given.

Examples:

  > (quote-srcloc)

  #(struct:srcloc eval 2 0 2 1)

  > (define-syntax (not-here stx) #'(quote-srcloc))
  > (not-here)

  #(struct:srcloc eval 3 0 3 1)

  > (not-here)

  #(struct:srcloc eval 3 0 3 1)

  > (define-syntax (here stx) #`(quote-srcloc #,stx))
  > (here)

  #(struct:srcloc eval 7 0 7 1)

  > (here)

  #(struct:srcloc eval 8 0 8 1)

(quote-source-file)
(quote-source-file expr)
(quote-line-number)
(quote-line-number expr)
(quote-column-number)
(quote-column-number expr)
(quote-character-position)
(quote-character-position expr)
(quote-character-span)
(quote-character-span expr)
These forms quote various fields of the source location of expr, or of the whole macro application if no expr is given.

Examples:

  > (list (quote-source-file)
          (quote-line-number)
          (quote-column-number)
          (quote-character-position)
          (quote-character-span))

  (eval 2 0 2 1)

  > (define-syntax (not-here stx)
      #'(list (quote-source-file)
              (quote-line-number)
              (quote-column-number)
              (quote-character-position)
              (quote-character-span)))
  > (not-here)

  (eval 3 0 3 1)

  > (not-here)

  (eval 3 0 3 1)

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

  (eval 7 0 7 1)

  > (here)

  (eval 8 0 8 1)

(quote-module-path)
This form quotes a module path suitable for use with require which refers to the module in which the macro application occurs. If executed at the top level, it may return 'top-level, or it may return a valid module path if the current namespace was constructed by module->namespace (such as at the DrScheme interactions window).

This macro operates by creating a variable reference (see #%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.

Examples:

  > (quote-module-path)

  top-level

  > (module A scheme
      (require unstable/location)
      (define-syntax-rule (here) (quote-module-path))
      (define a (here))
      (provide a here))
  > (require 'A)
  > a

  'A

  > (module B scheme
      (require unstable/location)
      (require 'A)
      (define b (here))
      (provide b))
  > (require 'B)
  > b

  'B

  > [current-namespace (module->namespace ''A)]
  > (quote-module-path)

  'A

(quote-module-name)
This form quotes the name (path or symbol) of the module in which the macro application occurs, or #f if it occurs at the top level. As with quote-module-path, quote-module-name uses a variable reference, so a top level namespace created by module->namespace will be treated as a module, and the macro will always produce the module name of its final expanded position.

Examples:

  > (quote-module-name)

  #f

  > (module A scheme
      (require unstable/location)
      (define-syntax-rule (here) (quote-module-name))
      (define a (here))
      (provide a here))
  > (require 'A)
  > a

  A

  > (module B scheme
      (require unstable/location)
      (require 'A)
      (define b (here))
      (provide b))
  > (require 'B)
  > b

  B

  > [current-namespace (module->namespace ''A)]
  > (quote-module-name)

  A