Clean up work

This commit is contained in:
Jack Firth 2016-07-30 14:38:56 -07:00
parent 8455976b8b
commit dd162b5723
23 changed files with 197 additions and 213 deletions

15
.gitignore vendored
View File

@ -1,8 +1,9 @@
**/compiled
*.bak
*.html
*.css
*.js
*.2
*~
*.bak
*.css
*.html
*.js
*.rktd
*.sxref
compiled
doc

View File

@ -1,4 +0,0 @@
#lang info
(define name "generic-syntax-expanders")
(define scribblings '(("scribblings/main.scrbl" () (library) "generic-syntax-expanders")))

View File

@ -1,6 +0,0 @@
#lang reprovide
"expander-types.rkt"
"expanders.rkt"
"define-expanders.rkt"
"scoped-transformers.rkt"
"define-scoped-transformers.rkt"

View File

@ -1,33 +0,0 @@
#lang scribble/manual
@(require "example-evaluator.rkt"
package-scribblings-tools
(for-label racket/base
generic-syntax-expanders/expanders
generic-syntax-expanders/expander-types
generic-syntax-expanders/define-expanders))
@module-title[generic-syntax-expanders/define-expanders]{Defining Generic Syntax Expanders}
This module provides a high-level API for creating generic
expanders for use with other macros.
@defform[(define-expander-type id)]{
Creates an expander type and binds several derived values
for working with the expander type:
@itemlist[
@item{@code{id-expander-type} - a new unique @racket[expander-type?]
bound at phase level 1}
@item{@code{make-id-expander} - a procedure bound at phase level 1
that accepts a transformer procedure and returns an @racket[expander?]
with @code{id-expander-type}}
@item{@code{id-expander?} - a predicate bound at phase level 1
recognizing expanders produced by @code{make-id-expander}}
@item{@code{define-id-expander?} - a syntactic form at phase level
0 that takes an identifier and a transformer procedure and binds the
identifier as a @code{id-expander?} for use in a transformer
environment}
@item{@code{expand-all-id-expanders} - a procedure bound at phase
level 1 that's equivalent to @racket[expand-all-expanders-of-type] with
the @code{id-expander-type} as the type argument}
]}

View File

@ -1,20 +0,0 @@
#lang scribble/manual
@(require "example-evaluator.rkt"
package-scribblings-tools
(for-label racket/base
lens
generic-syntax-expanders/scoped-transformers
generic-syntax-expanders/define-scoped-transformers))
@module-title[generic-syntax-expanders/define-scoped-transformers]{Lens Scoped Syntax Transformers - Definition Form}
Syntax definition forms built on @racket[with-scoped-pre-transformer]
and friends.
@defform[(define-syntax-with-scoped-pre-transformers id
([stx-lens pre-transformer] ...)
transformer-expr)]{
Binds @racket[id] as a syntax transformer equivalent to
@racket[with-scoped-pre-transformers transformer-expr ([stx-lens pre-transformer] ...)].
}

View File

@ -1,55 +0,0 @@
#lang scribble/manual
@(require package-scribblings-tools
"example-evaluator.rkt"
(for-label racket/base
generic-syntax-expanders/expanders
generic-syntax-expanders/expander-types))
@module-title[generic-syntax-expanders/expander-types]{Expander Types}
Under the hood, each generic expander defined with this library has
an associated @italic{expander type}. Syntax transformers built
with this library examine this type to determine whether or not
they should expand them.
@defpredicate[expander-type?]{
A predicate for values produced by @racket[make-expander-type] and
variants.
@package-examples[
(expander-type? (make-expander-type))
(expander-type? 'foo)
]}
@defproc[(make-expander-type) expander-type?]{
Creates a unique @racket[expander-type?] for use in defining a new
kind of generic expander.
@package-examples[
(make-expander-type)
]}
@defproc[(make-union-expander-type [type expander-type?] ...+) expander-type?]{
Creates a union @racket[expander-type?]. This union type includes
all of the given types, as well as any union type of a subset of
the given types.
@package-examples[
(make-union-expander-type (make-expander-type) (make-expander-type))
]}
@defproc[(expander-type-includes? [type-1 expander-type?] [type-2 expander-type?]) boolean?]{
Returns @racket[#t] if the two types are either identical, or if either
type is a union type that contains the other, or if both types are
union types and contain a nonempty intersection. Returns @racket[#f]
otherwise.
@package-examples[
(define A (make-expander-type))
(define B (make-expander-type))
(define C (make-expander-type))
(expander-type-includes? A A)
(expander-type-includes? B C)
(define AB (make-union-expander-type A B))
(define BC (make-union-expander-type B C))
(expander-type-includes? AB A)
(expander-type-includes? AB C)
(expander-type-includes? AB BC)
]}

View File

@ -1,44 +0,0 @@
#lang scribble/manual
@(require "example-evaluator.rkt"
package-scribblings-tools
(for-label racket/base
generic-syntax-expanders/expanders
generic-syntax-expanders/expander-types))
@module-title[generic-syntax-expanders/expanders]{Expanders And Transformers}
Generic expanders are implemented as values of the @racket[expander?] struct
bound with @racket[define-syntax], that store both a type and a transformer
procedure. Future versions of this library may support storing an additional
transformer for use outside expander-contexts in normal syntax parsing. This
could be used for better error messages, or for an expander meant to have
meaning in both a particularly typed expansion context and a normal expression
expansion context.
@defstruct[expander ([type expander-type?] [transformer (-> syntax? syntax?)])]{
A structure type for generic syntax expanders. A generic syntax expander
has an associated @italic{type} and @italic{transformer}. The transformer
can be any arbitrary function that accepts a syntax object in the same
manner a transformer given to @racket[define-syntax] would behave.
}
@defproc[(expander-of-type? [type expander-type?] [expander expander?]) boolean?]{
Returns @racket[#t] if the @racket[expander] has type @racket[type],
according to the semantics of @racket[expander-type-includes?], and
returns @racket[#f] otherwise.
@package-examples[
(define A (make-expander-type))
(define exp (expander A (λ (stx) stx)))
(expander-of-type? A exp)
]}
@defproc[(expand-stx-tree-with-expanders-of-type [type expander-type?] [syntax syntax?]) syntax?]{
Recursively searches through @racket[syntax] for identifiers bound to
generic syntax expanders of the given type. When an expander is found,
its transformer is called with the given syntax value of its location
in the tree. The returned syntax object with have all expanders of the
given type fully expanded, but nothing else will be expanded. Due to
how expanders are bound to identifiers, this procedure can only be
called in a transformer environment.
}

View File

@ -1,8 +1,7 @@
#lang info
(define collection 'multi)
(define collection "generic-syntax-expanders")
(define name "generic-syntax-expanders")
(define scribblings '(("main.scrbl" () (library) "generic-syntax-expanders")))
(define deps
'("base"
"rackunit-lib"
@ -13,18 +12,13 @@
"predicates"
"scribble-lib"
"scribble-text-lib"))
(define build-deps
'("cover"
"cover-coveralls"
"scribble-lib"
'("scribble-lib"
"rackunit-lib"
"racket-doc"
"git://github.com/jackfirth/package-scribblings-tools"))
"racket-doc"))
(define compile-omit-paths
'("private"))
(define test-omit-paths
'("info.rkt"
"generic-syntax-expanders/info.rkt"
"generic-syntax-expanders/scribblings"))
'(#rx"\\.scrbl$"
#rx"info\\.rkt$"
#rx"doc-util\\.rkt$"))

6
main.rkt Normal file
View File

@ -0,0 +1,6 @@
#lang reprovide
"private/expander-types.rkt"
"private/expanders.rkt"
"private/define-expanders.rkt"
"private/scoped-transformers.rkt"
"private/define-scoped-transformers.rkt"

View File

@ -1,11 +1,9 @@
#lang scribble/manual
@(require package-scribblings-tools
(for-label racket/base
racket/match
generic-syntax-expanders))
@(require "private/doc-util.rkt")
@module-title[generic-syntax-expanders]{Generic Syntax Expanders}
@title{Generic Syntax Expanders}
@defmodule[generic-syntax-expanders]
@author[@author+email["Jack Firth" "jackhfirth@gmail.com"]]
This library provides forms to define @italic{generic syntax
@ -22,8 +20,8 @@ extensible.
@source-code{https://github.com/jackfirth/generic-syntax-expanders}
@include-section{expanders.scrbl}
@include-section{expander-types.scrbl}
@include-section{define-expanders.scrbl}
@include-section{scoped-transformers.scrbl}
@include-section{define-scoped-transformers.scrbl}
@include-section["private/expanders.scrbl"]
@include-section["private/expander-types.scrbl"]
@include-section["private/define-expanders.scrbl"]
@include-section["private/scoped-transformers.scrbl"]
@include-section["private/define-scoped-transformers.scrbl"]

View File

@ -0,0 +1,27 @@
#lang scribble/manual
@(require "doc-util.rkt")
@title{Defining Generic Syntax Expanders}
This module provides a high-level API for creating generic
expanders for use with other macros.
@defform[(define-expander-type id)]{
Creates an expander type and binds several derived values
for working with the expander type:
@itemlist[
@item{@code{id-expander-type} - a new unique @racket[expander-type?]
bound at phase level 1}
@item{@code{make-id-expander} - a procedure bound at phase level 1
that accepts a transformer procedure and returns an @racket[expander?]
with @code{id-expander-type}}
@item{@code{id-expander?} - a predicate bound at phase level 1
recognizing expanders produced by @code{make-id-expander}}
@item{@code{define-id-expander?} - a syntactic form at phase level
0 that takes an identifier and a transformer procedure and binds the
identifier as a @code{id-expander?} for use in a transformer
environment}
@item{@code{expand-all-id-expanders} - a procedure bound at phase
level 1 that's equivalent to @racket[expand-all-expanders-of-type] with
the @code{id-expander-type} as the type argument}
]}

View File

@ -0,0 +1,14 @@
#lang scribble/manual
@(require "doc-util.rkt")
@title{Lens Scoped Syntax Transformers - Definition Form}
Syntax definition forms built on @racket[with-scoped-pre-transformer]
and friends.
@defform[(define-syntax-with-scoped-pre-transformers id
([stx-lens pre-transformer] ...)
transformer-expr)]{
Binds @racket[id] as a syntax transformer equivalent to
@racket[with-scoped-pre-transformers transformer-expr ([stx-lens pre-transformer] ...)].
}

32
private/doc-util.rkt Normal file
View File

@ -0,0 +1,32 @@
#lang at-exp racket/base
(provide (for-label (all-from-out generic-syntax-expanders
racket/base
racket/contract))
defpredicate
generic-syntax-examples
source-code)
(require (for-label generic-syntax-expanders
racket/base
racket/contract)
scribble/examples
scribble/manual
scribble/text)
(define requirements
'(generic-syntax-expanders))
(define (make-eval)
(make-base-eval #:lang 'racket/base
(cons 'require requirements)))
(define-syntax-rule (generic-syntax-examples example ...)
(examples #:eval (make-eval) example ...))
(define-syntax-rule (defpredicate id pre-flow ...)
(defthing #:kind "procedure" id predicate/c pre-flow ...))
(define (source-code dest-url)
@begin/text{Source code is available at @url[dest-url]})

View File

@ -0,0 +1,46 @@
#lang scribble/manual
@(require "doc-util.rkt")
@title{Expander Types}
Under the hood, each generic expander defined with this library has
an associated @italic{expander type}. Syntax transformers built
with this library examine this type to determine whether or not
they should expand them.
@defpredicate[expander-type?]{
A predicate for values produced by @racket[make-expander-type] and
variants.
@generic-syntax-examples[
(expander-type? (make-expander-type))
(expander-type? 'foo)]}
@defproc[(make-expander-type) expander-type?]{
Creates a unique @racket[expander-type?] for use in defining a new
kind of generic expander.
@generic-syntax-examples[
(make-expander-type)]}
@defproc[(make-union-expander-type [type expander-type?] ...+) expander-type?]{
Creates a union @racket[expander-type?]. This union type includes
all of the given types, as well as any union type of a subset of
the given types.
@generic-syntax-examples[
(make-union-expander-type (make-expander-type) (make-expander-type))]}
@defproc[(expander-type-includes? [type-1 expander-type?] [type-2 expander-type?]) boolean?]{
Returns @racket[#t] if the two types are either identical, or if either
type is a union type that contains the other, or if both types are
union types and contain a nonempty intersection. Returns @racket[#f]
otherwise.
@generic-syntax-examples[
(define A (make-expander-type))
(define B (make-expander-type))
(define C (make-expander-type))
(expander-type-includes? A A)
(expander-type-includes? B C)
(define AB (make-union-expander-type A B))
(define BC (make-union-expander-type B C))
(expander-type-includes? AB A)
(expander-type-includes? AB C)
(expander-type-includes? AB BC)]}

36
private/expanders.scrbl Normal file
View File

@ -0,0 +1,36 @@
#lang scribble/manual
@(require "doc-util.rkt")
@title{Expanders And Transformers}
Generic expanders are implemented as values of the @racket[expander?] struct
bound with @racket[define-syntax], that store both a type and a transformer
procedure. Future versions of this library may support storing an additional
transformer for use outside expander-contexts in normal syntax parsing. This
could be used for better error messages, or for an expander meant to have
meaning in both a particularly typed expansion context and a normal expression
expansion context.
@defstruct*[expander ([type expander-type?] [transformer (-> syntax? syntax?)])]{
A structure type for generic syntax expanders. A generic syntax expander
has an associated @italic{type} and @italic{transformer}. The transformer
can be any arbitrary function that accepts a syntax object in the same
manner a transformer given to @racket[define-syntax] would behave.}
@defproc[(expander-of-type? [type expander-type?] [expander expander?]) boolean?]{
Returns @racket[#t] if the @racket[expander] has type @racket[type],
according to the semantics of @racket[expander-type-includes?], and
returns @racket[#f] otherwise.
@generic-syntax-examples[
(define A (make-expander-type))
(define exp (expander A (λ (stx) stx)))
(expander-of-type? A exp)]}
@defproc[(expand-stx-tree-with-expanders-of-type [type expander-type?] [syntax syntax?]) syntax?]{
Recursively searches through @racket[syntax] for identifiers bound to
generic syntax expanders of the given type. When an expander is found,
its transformer is called with the given syntax value of its location
in the tree. The returned syntax object with have all expanders of the
given type fully expanded, but nothing else will be expanded. Due to
how expanders are bound to identifiers, this procedure can only be
called in a transformer environment.}

View File

@ -1,13 +1,7 @@
#lang scribble/manual
@(require "doc-util.rkt")
@(require "example-evaluator.rkt"
package-scribblings-tools
(for-label racket/base
lens
generic-syntax-expanders/define-expanders
generic-syntax-expanders/scoped-transformers))
@module-title[generic-syntax-expanders/scoped-transformers]{Lens Scoped Syntax Transformers}
@title{Lens Scoped Syntax Transformers}
This module uses the @racket[lens] package to create syntax transformers
that affect only some small subpiece of a syntax object and compose them
@ -24,10 +18,9 @@ extensible macro.
[pre-transformer (-> syntax? syntax?)])
[stx syntax?])
syntax?]{
Transformers @racket[stx] in two passes. First, the piece of @racket[stx]
that @racket[stx-lens] views is transformed with @racket[pre-transformer].
Then, the entire resulting syntax object is transformed with @racket[transformer].
}
Transformers @racket[stx] in two passes. First, the piece of @racket[stx]
that @racket[stx-lens] views is transformed with @racket[pre-transformer].
Then, the entire resulting syntax object is transformed with @racket[transformer].}
@defproc[((with-scoped-pre-transformers
[transformer (-> syntax? syntax?)]
@ -36,9 +29,8 @@ extensible macro.
(-> syntax? syntax?)))])
[stx syntax?])
syntax?]{
Similar to @racket[with-scoped-pre-transformer]. Given @racket[pre-transformer-lens-pairs],
a list of pairs of lenses and transformers, @racket[transformer] is wrapped
with @racket[with-scoped-pre-transformer] with the pair's pre-transformer
and lens. The last pair in @racket[pre-transformer-lens-pairs] is applied
to @racket[stx] first.
}
Similar to @racket[with-scoped-pre-transformer]. Given @racket[pre-transformer-lens-pairs],
a list of pairs of lenses and transformers, @racket[transformer] is wrapped
with @racket[with-scoped-pre-transformer] with the pair's pre-transformer
and lens. The last pair in @racket[pre-transformer-lens-pairs] is applied
to @racket[stx] first.}