commit 27c0303b26fb3502a15390e00463b8fe6bc2bdb8 parent 50ec46be192584ec1247f3884cab23646ab86c29 Author: Jack Firth <jackhfirth@gmail.com> Date: Tue, 31 Mar 2015 16:55:49 -0700 Restructure to use package scribblings tools Diffstat:
18 files changed, 234 insertions(+), 272 deletions(-)
diff --git a/generic-syntax-expanders/docs/define-expanders.scrbl b/generic-syntax-expanders/docs/define-expanders.scrbl @@ -1,34 +0,0 @@ -#lang scribble/manual - -@(require "example-evaluator.rkt" - "defpredicate.rkt" - "module-title.rkt" - (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} -]} diff --git a/generic-syntax-expanders/docs/define-scoped-transformers.scrbl b/generic-syntax-expanders/docs/define-scoped-transformers.scrbl @@ -1,20 +0,0 @@ -#lang scribble/manual - -@(require "example-evaluator.rkt" - "module-title.rkt" - (for-label racket/base - lenses - 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] ...)]. -} diff --git a/generic-syntax-expanders/docs/defpredicate.rkt b/generic-syntax-expanders/docs/defpredicate.rkt @@ -1,8 +0,0 @@ -#lang racket - -(require scribble/manual) - -(provide defpredicate) - -(define-syntax-rule (defpredicate id pre-flow ...) - (defthing #:kind "predicate" id predicate/c pre-flow ...)) diff --git a/generic-syntax-expanders/docs/example-evaluator.rkt b/generic-syntax-expanders/docs/example-evaluator.rkt @@ -1,11 +0,0 @@ -#lang racket - -(require scribble/eval) - -(provide package-examples) - -(define generic-syntax-expanders-eval (make-base-eval)) -(generic-syntax-expanders-eval '(require generic-syntax-expanders)) - -(define-syntax-rule (package-examples example-body ...) - (examples #:eval generic-syntax-expanders-eval example-body ...)) -\ No newline at end of file diff --git a/generic-syntax-expanders/docs/expander-types.scrbl b/generic-syntax-expanders/docs/expander-types.scrbl @@ -1,56 +0,0 @@ -#lang scribble/manual - -@(require "example-evaluator.rkt" - "defpredicate.rkt" - "module-title.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) -]} diff --git a/generic-syntax-expanders/docs/expanders.scrbl b/generic-syntax-expanders/docs/expanders.scrbl @@ -1,45 +0,0 @@ -#lang scribble/manual - -@(require "example-evaluator.rkt" - "defpredicate.rkt" - "module-title.rkt" - (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. -} diff --git a/generic-syntax-expanders/docs/generic-syntax-expanders.scrbl b/generic-syntax-expanders/docs/generic-syntax-expanders.scrbl @@ -1,32 +0,0 @@ -#lang scribble/manual - -@(require "example-evaluator.rkt" - "defpredicate.rkt" - "module-title.rkt" - "source-code.rkt" - (for-label racket/base - racket/match - generic-syntax-expanders)) - -@module-title[generic-syntax-expanders]{Generic Syntax Expanders} -@author[@author+email["Jack Firth" "jackhfirth@gmail.com"]] - -This library provides forms to define @italic{generic syntax -expanders}. These are essentially macros that have no meaning -on their own, but other macros can be told to expand all -generic syntax expanders of some type in some portion of -their body before themselves expanding. This is similar to -how Racket's built in @racket[match] form has @italic{match -expanders}, which allows the grammar of the @racket[match] -form to be extended with custom match expanders using -@racket[define-match-expander]. This library generalizes -the concept, making complex macros more composable and -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} diff --git a/generic-syntax-expanders/docs/module-title.rkt b/generic-syntax-expanders/docs/module-title.rkt @@ -1,10 +0,0 @@ -#lang racket - -(require scribble/manual) - -(provide module-title) - -(define-syntax-rule (module-title id title-text pre-flow ...) - (begin - (title title-text) - (defmodule id pre-flow ...))) diff --git a/generic-syntax-expanders/docs/scoped-transformers.scrbl b/generic-syntax-expanders/docs/scoped-transformers.scrbl @@ -1,44 +0,0 @@ -#lang scribble/manual - -@(require "example-evaluator.rkt" - "module-title.rkt" - (for-label racket/base - lenses - generic-syntax-expanders/define-expanders - generic-syntax-expanders/scoped-transformers)) - -@module-title[generic-syntax-expanders/scoped-transformers]{Lens Scoped Syntax Transformers} - -This module uses the @racket[lenses] package to create syntax transformers -that affect only some small subpiece of a syntax object and compose them -with other transformers. This allows for the creation of a macro that cedes -control to other macros to pre-expand parts of its body before the macro -expands. Combined with the syntax transformer produced by @racket[define-expander-type], -this makes it easy to define a macro that expands all instances of a generic -expander type in a specific subpiece of its body, turning it into an -extensible macro. - -@defproc[((with-scoped-pre-transformer - [transformer (-> syntax? syntax?)] - [stx-lens (lens/c syntax? syntax?)] - [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]. -} - -@defproc[((with-scoped-pre-transformers - [transformer (-> syntax? syntax?)] - [pre-transformer-lens-pairs - (listof (list/c (lens/c syntax? syntax?) - (-> 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. -} diff --git a/generic-syntax-expanders/docs/source-code.rkt b/generic-syntax-expanders/docs/source-code.rkt @@ -1,9 +0,0 @@ -#lang racket - -(require scribble/manual - scribble/text) - -(provide source-code) - -(define (source-code link) - (list "Source code can be found at " (url link))) diff --git a/generic-syntax-expanders/info.rkt b/generic-syntax-expanders/info.rkt @@ -1,4 +1,4 @@ #lang info (define name "generic-syntax-expanders") -(define scribblings '(("docs/generic-syntax-expanders.scrbl" ()))) -\ No newline at end of file +(define scribblings '(("scribblings/main.scrbl" () (library) "generic-syntax-expanders"))) diff --git a/generic-syntax-expanders/scribblings/define-expanders.scrbl b/generic-syntax-expanders/scribblings/define-expanders.scrbl @@ -0,0 +1,33 @@ +#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} +]} diff --git a/generic-syntax-expanders/scribblings/define-scoped-transformers.scrbl b/generic-syntax-expanders/scribblings/define-scoped-transformers.scrbl @@ -0,0 +1,20 @@ +#lang scribble/manual + +@(require "example-evaluator.rkt" + package-scribblings-tools + (for-label racket/base + lenses + 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] ...)]. +} diff --git a/generic-syntax-expanders/scribblings/example-evaluator.rkt b/generic-syntax-expanders/scribblings/example-evaluator.rkt @@ -0,0 +1,8 @@ +#lang racket + +(require scribble/eval + package-scribblings-tools) + +(provide package-examples) + +(define-custom-examples package-examples generic-syntax-expanders) diff --git a/generic-syntax-expanders/scribblings/expander-types.scrbl b/generic-syntax-expanders/scribblings/expander-types.scrbl @@ -0,0 +1,55 @@ +#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) +]} diff --git a/generic-syntax-expanders/scribblings/expanders.scrbl b/generic-syntax-expanders/scribblings/expanders.scrbl @@ -0,0 +1,44 @@ +#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. +} diff --git a/generic-syntax-expanders/scribblings/main.scrbl b/generic-syntax-expanders/scribblings/main.scrbl @@ -0,0 +1,29 @@ +#lang scribble/manual + +@(require package-scribblings-tools + (for-label racket/base + racket/match + generic-syntax-expanders)) + +@module-title[generic-syntax-expanders]{Generic Syntax Expanders} +@author[@author+email["Jack Firth" "jackhfirth@gmail.com"]] + +This library provides forms to define @italic{generic syntax +expanders}. These are essentially macros that have no meaning +on their own, but other macros can be told to expand all +generic syntax expanders of some type in some portion of +their body before themselves expanding. This is similar to +how Racket's built in @racket[match] form has @italic{match +expanders}, which allows the grammar of the @racket[match] +form to be extended with custom match expanders using +@racket[define-match-expander]. This library generalizes +the concept, making complex macros more composable and +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} diff --git a/generic-syntax-expanders/scribblings/scoped-transformers.scrbl b/generic-syntax-expanders/scribblings/scoped-transformers.scrbl @@ -0,0 +1,44 @@ +#lang scribble/manual + +@(require "example-evaluator.rkt" + package-scribblings-tools + (for-label racket/base + lenses + generic-syntax-expanders/define-expanders + generic-syntax-expanders/scoped-transformers)) + +@module-title[generic-syntax-expanders/scoped-transformers]{Lens Scoped Syntax Transformers} + +This module uses the @racket[lenses] package to create syntax transformers +that affect only some small subpiece of a syntax object and compose them +with other transformers. This allows for the creation of a macro that cedes +control to other macros to pre-expand parts of its body before the macro +expands. Combined with the syntax transformer produced by @racket[define-expander-type], +this makes it easy to define a macro that expands all instances of a generic +expander type in a specific subpiece of its body, turning it into an +extensible macro. + +@defproc[((with-scoped-pre-transformer + [transformer (-> syntax? syntax?)] + [stx-lens (lens/c syntax? syntax?)] + [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]. +} + +@defproc[((with-scoped-pre-transformers + [transformer (-> syntax? syntax?)] + [pre-transformer-lens-pairs + (listof (list/c (lens/c syntax? syntax?) + (-> 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. +}