From 6fa6ea3bb327755509b3d9de8f3e219c28f323d0 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 5 Feb 2008 17:38:58 +0000 Subject: [PATCH] scribbled macro-debugger docs svn: r8542 --- collects/macro-debugger/doc.txt | 312 ------------------- collects/macro-debugger/info.ss | 1 + collects/macro-debugger/macro-debugger.scrbl | 307 ++++++++++++++++++ 3 files changed, 308 insertions(+), 312 deletions(-) delete mode 100644 collects/macro-debugger/doc.txt create mode 100644 collects/macro-debugger/macro-debugger.scrbl diff --git a/collects/macro-debugger/doc.txt b/collects/macro-debugger/doc.txt deleted file mode 100644 index fbce16d04a..0000000000 --- a/collects/macro-debugger/doc.txt +++ /dev/null @@ -1,312 +0,0 @@ -_Macro Debugger_ -================ - -Keywords: _syntax_, _syntax-browser_, _hygiene_, - _referential transparency_, _lexical context_, - _macro_, _expansion_, _macro-debugger_, _macro-stepper_ - -OUTLINE -======= - -* Introduction -* APIs - - expand.ss - - syntax-browser.ss -* Using the macro stepper -* Using the syntax browser -* Enabling the macro stepper in other languages -* Notes for DrScheme language implementors - -Introduction -============ - -The macro-debugger collection contains two tools: a stepper for macro -expansion and a standalone syntax browser. The macro stepper shows the -programmer the expansion of a program as a sequence of rewriting -steps, using the syntax browser to display the individual terms. The -syntax browser uses colors and a properties panel to show the term's -syntax properties, such as lexical binding information and source -location. - -_stepper.ss_ -============ - -> (require (lib "stepper.ss" "macro-debugger")) - -This module provides a single procedure: - -> (expand/step syntax-or-sexpr) - -Expands the syntax (or S-expression) and opens a macro stepper frame -for stepping through the expansion. Returns an object of -macro-stepper<%> with the following methods: - -> (send a-macro-stepper at-start?) -> boolean -> (send a-macro-stepper at-end?) -> boolean -> (send a-macro-stepper navigate-to-start) -> void -> (send a-macro-stepper navigate-to-end) -> void -> (send a-macro-stepper navigate-previous) -> void -> (send a-macro-stepper navigate-next) -> void -> (send a-macro-stepper navigate-forward/count n) -> void -> (send a-macro-stepper navigate-forward/pred pred) -> void - pred : syntax -> boolean - Navigate forward to an expansion with redex (focus) matching pred. - -> (send a-macro-stepper at-top?) -> boolean -> (send a-macro-stepper at-bottom?) -> boolean -> (send a-macro-stepper navigate-up) -> void -> (send a-macro-stepper navigate-down) -> void -> (send a-macro-stepper navigate-down/pred pred) -> void - pred : syntax -> boolean - Navigate down to an expansion with initial syntax satisfying pred. - -_expand.ss_ -=========== - -> (require (lib "expand.ss" "macro-debugger")) - -This module provides the following procedures: - -> (expand-only syntax list-of-identifiers) - -Expands the given syntax, but only shows the expansion of macros in -the given identifier list. - -Warning: because of limitations in syntax, expansion, and hiding, the -resulting syntax may not evaluate to the same thing as the original -syntax. - -> (expand/hide syntax list-of-identifier) - -Expands the given syntax, but hides the expansion of macros in the -given identifier list (conceptually, the complement of expand-only). - -Warning: because of limitations in syntax, expansion, and hiding, the -resulting syntax may not evaluate to the same thing as the original -syntax. - -_stepper-text.ss_ -================= - -> (require (lib "stepper-text.ss" "macro-debugger")) - -This module provides two procedures for stepping through macro -expansion in text-only environments. - -> (expand/step-text syntax [identifier-predicate]) - -Expands the syntax and prints the macro expansion steps. If the -identifier predicate is given, it determines which macros are shown -(if absent, no macros are hidden). A list of identifiers is also -accepted. - -> (stepper-text syntax [identifier-predicate]) - -Returns a procedure P that: - - when called with no arguments (or on the symbol 'next), - prints out individual steps until macro expansion finishes - - when called on the symbol 'all, - prints out all of the remaining steps - -_syntax-browser.ss_ -=================== - -> (require (lib "syntax-browser.ss" "macro-debugger")) - -This module provides the following procedures: - -> (browse-syntax syntax) -> void - -Creates a frame with the given syntax object shown. More information -on using the GUI is available below. - -> (browse-syntaxes list-of-syntax) -> void - -Like browse-syntax, but shows multiple syntax objects in the same -frame. The coloring partitions are shared between the two, -showing the relationships between subterms in different syntax -objects. - -> (syntax-snip syntax) -> (is-a?/c snip%) - -Like 'browse-syntax', but creates a snip that can be displayed in an -editor. In particular, evaluating - (syntax-snip ) -in DrScheme's interactions window will insert a syntax browser into -the interactions window. - -Using the Macro Stepper -======================= - -Navigation ----------- - -The stepper presents expansion as a linear sequence of rewriting -process, and it gives the user controls to step forward or backwards -as well as to jump to the beginning or end of the expansion process. - -If the macro stepper is showing multiple expansions, then it also -provides "Previous term" and "Next term" buttons to go up and down in -the list of expansions. Horizontal lines delimit the current expansion -from the others. - -Macro hiding ------------- - -Macro hiding lets one see how expansion would look if certain macros -were actually primitive syntactic forms. The macro stepper skips over -the expansion of the macros you designate as opaque, but it still -shows the expansion of their subterms. - -The bottom panel of the macro stepper controls the macro hiding -policy. The user changes the policy by selecting an identifier in the -syntax browser pane and then clicking one of "Hide module", "Hide -macro", or "Show macro". The new rule appears in the policy display, -and the user may later remove it using the "Delete" button. - -The stepper also offers coarser-grained options that can hide -collections of modules at once. These options have lower precedence -than the rules above. - -Macro hiding, even with no macros marked opaque, also hides certain -other kinds of steps: internal defines are not rewritten to letrecs, -begin forms are not spliced into module or block bodies, etc. - -Using the Syntax Browser -======================== - -Selection (bold) ----------------- - -The user can click on any part of a subterm to *select* it. To select -a parenthesized subterm, click on either of the parentheses. The -selected syntax is bolded. Since one syntax object may occur -inside of multiple other syntax objects, clicking on one occurrence -will cause all occurrences to be bolded. - -The syntax browser displays information about the selected syntax -object in the properties panel on the right, when that panel is -shown. The selected syntax also determines the highlighting done by -the secondary partitioning (see below). - -Primary partition (foreground color) ------------------------------------- - -The *primary partitioning* always assigns two syntax subterms the same -color if they have the same marks. In the absence of unhygienic -macros, this means that subterms with the same foreground color were -either present in the original pre-expansion syntax or generated by -the same macro transformation step. - -Syntax colored in black always corresponds to unmarked syntax. Such -syntax may be original, or it may be produced by the expansion of a -nonhygienic macro. - -Secondary partitioning (highlight) ----------------------------------- - -The user may select a *secondary partitioning* from a drop-down box -(or in the macro stepper, through the Syntax menu). This partitioning -applies only to identifiers. When the user selects an identifier, all -terms in the same equivalence class as the selected term are -highlighted in yellow. - -The available secondary partitionings are: - -* bound-identifier=? -* module-identifier=? -* module-or-top-identifier=? - - See the documentation for these predicates in the MzScheme manual. - -* symbolic-identifer=? - - Two identifiers are symbolic-identifier=? if discarding all lexical - context information yields the same symbol. - -* same marks - - Two identifiers have the same marks if (barring nonhygienic macros) - they were produced by the same macro transformation step. - -* same source module - - The bindings of the two identifiers come from definitions in the - same module. - -* same nominal module - - The bindings of the two identifiers were imported into the current - context by requiring the same module. - -Properties ----------- - -When the properties pane is shown, it displays properties of the -selected syntax object. The properties pane has three tabbed pages: - - - Binding - - If the selection is an identifier, shows the binding information - associated with the syntax object. - - *Note: See the warning in the section below. - - For more information, look up 'identifier-binding', - 'identifier-transformer-binding', and - 'identifier-template-binding' in the Help Desk. - - - Source - - Displays source location information about the syntax object. - - - Properties - - Displays properties (see 'syntax-property') of the selection - when it has properties it knows the keys for. - -Warnings about interpreting syntax ----------------------------------- - -The binding information of a *syntax object* may not be the same as -the binding structure of the *program* it represents. The binding -structure of a *program* is only determined after macro expansion is -complete. - - Example: (browse-syntax #'(lambda (foo) foo)) - The syntax browser will report that the inner 'foo' is unbound, even - though in the *program* that this syntax represents, the inner 'foo' - is bound to the outer 'foo'. - -Notes and Limitations ---------------------- - -The syntax browser does not have a way of extending the set of -available secondary partitions. - -The syntax browser does not have a way of extending the set of known -properties. - -The syntax browser does not preserve the distinction between -parentheses and square brackets. - - -Notes for DrScheme language implementors -======================================== - -The macro stepper works "out of the box" only with certain languages -out of all the languages available from the DrScheme languages -menu. For example, the macro stepper is disabled for the teaching -languages. - -An implementor of a new DrScheme language can designate their language -"macro-steppable" by overriding the 'enable-macro-stepper?' method of -their implementation of 'drscheme:language:language<%>'. The default -implementation in the mixin provided by -'drscheme:language:get-default-mixin' returns false; override this -method to return true if the macro stepper button should be shown for -this language. - -Note: There is currently no way to customize the behavior of the macro -stepper for different languages. When enabled, the macro stepper sees -exactly those terms that pass through the 'current-eval' handler. diff --git a/collects/macro-debugger/info.ss b/collects/macro-debugger/info.ss index daf5f050b8..cd94c97b39 100644 --- a/collects/macro-debugger/info.ss +++ b/collects/macro-debugger/info.ss @@ -3,3 +3,4 @@ (define name "Macro Debugger") (define tools '(["tool.ss"])) (define tool-names '("Macro Stepper")) +(define scribblings '(("macro-debugger.scrbl"))) diff --git a/collects/macro-debugger/macro-debugger.scrbl b/collects/macro-debugger/macro-debugger.scrbl new file mode 100644 index 0000000000..0a409c0989 --- /dev/null +++ b/collects/macro-debugger/macro-debugger.scrbl @@ -0,0 +1,307 @@ +#lang scribble/doc +@(require scribble/manual + scribble/struct + scribble/eval + (for-label scheme/base + macro-debugger/expand + macro-debugger/stepper + macro-debugger/stepper-text + macro-debugger/syntax-browser + (rename-in scheme (free-identifier=? module-identifier=?)))) + +@(define the-eval + (let ([the-eval (make-base-eval)]) + (the-eval '(require macro-debugger/expand + macro-debugger/stepper-text)) + the-eval)) + +@title{Macro debugger} + +The macro-debugger collection contains two tools: a stepper for macro +expansion and a standalone syntax browser. The macro stepper shows the +programmer the expansion of a program as a sequence of rewriting +steps, using the syntax browser to display the individual terms. The +syntax browser uses colors and a properties panel to show the term's +syntax properties, such as lexical binding information and source +location. + +@section{Macro stepper} + +@defmodule[macro-debugger/stepper] + +@defproc[(expand/step [stx any/c]) + (is-a/c macro-stepper<%>)]{ + + Expands the syntax (or S-expression) and opens a macro stepper frame + for stepping through the expansion. +} + +@definterface[macro-stepper<%> ()]{ + +@defmethod[(at-start?) boolean?] +@defmethod[(at-end?) boolean?] +@defmethod[(navigate-to-start) void?] +@defmethod[(navigate-to-end) void?] +@defmethod[(navigate-previous) void?] +@defmethod[(navigate-next) void?] +@defmethod[(at-top?) boolean?] +@defmethod[(at-bottom?) boolean?] +@defmethod[(navigate-up) void?] +@defmethod[(navigate-down) void?] +} + +@section{Macro expansion tools} + +@defmodule[macro-debugger/expand] + +@defproc[(expand-only [stx any/c] [transparent-macros (listof identifier?)]) + syntax?]{ + + Expands the given syntax @scheme[stx], but only shows the expansion + of macros whose names occur in @scheme[transparent-macros]. + + @(examples #:eval the-eval + (syntax->datum + (expand-only #'(let ([x 1] [y 2]) (or (even? x) (even? y))) + (list #'or)))) + + Warning: because of limitations in syntax, expansion, and hiding, + the resulting syntax may not evaluate to the same thing as the + original syntax. +} + +@defproc[(expand/hide [stx any/c] [hidden-macros (listof identifier?)]) + syntax?]{ + + Expands the given syntax @scheme[stx], but hides the expansion of macros in the + given identifier list (conceptually, the complement of expand-only). + + @(examples #:eval the-eval + (syntax->datum + (expand/hide #'(let ([x 1] [y 2]) (or (even? x) (even? y))) + (list #'or)))) + + Warning: because of limitations in syntax, expansion, and hiding, + the resulting syntax may not evaluate to the same thing as the + original syntax. +} + +@section{Macro stepper text interface} + +@defmodule[macro-debugger/stepper-text] + +@defproc[(expand/step-text [stx any/c] + [macro-policy (or/c (-> identifier? boolean?) + (listof identifier?)) + null]) + void?]{ + + Expands the syntax and prints the macro expansion steps. If the + identifier predicate is given, it determines which macros are shown + (if absent, no macros are hidden). A list of identifiers is also + accepted. + + @(examples #:eval the-eval + (expand/step-text #'(let ([x 1]) (even? x))) + #;(expand/step-text #'(let ([x 1] [y 2]) (or (even? x) (even? y))) + (lambda (id) (eq? (syntax-e id) 'or)))) +} + +@defproc[(stepper-text [stx any/c] + [macro-policy (or/c (-> identifier? boolean?) + (listof identifier?))]) + (symbol? -> void?)]{ + + Returns a procedure that can be called on the symbol + @scheme['next] to print the next step or on the symbol + @scheme['all] to print out all remaining steps. +} + +@section{Syntax browser} + +@defmodule[macro-debugger/syntax-browser] + +@defproc[(browse-syntax [stx syntax?]) + void?]{ + + Creates a frame with the given syntax object shown. More information + on using the GUI is available below. +} + +@defproc[(browse-syntaxes [stxs (listof syntax?)]) + void?]{ + + Like @scheme[browse-syntax], but shows multiple syntax objects in + the same frame. The coloring partitions are shared between the two, + showing the relationships between subterms in different syntax + objects. +} + +@;{ +@defproc[(syntax-snip [stx syntax?]) + (is-a/c snip%)]{ + + Like @scheme[browse-syntax], but creates a snip that can be + displayed in an editor. +} +} + +@section{Using the macro stepper} + +@subsection{Navigation} + +The stepper presents expansion as a linear sequence of rewriting +process, and it gives the user controls to step forward or backwards +as well as to jump to the beginning or end of the expansion process. + +If the macro stepper is showing multiple expansions, then it also +provides "Previous term" and "Next term" buttons to go up and down in +the list of expansions. Horizontal lines delimit the current expansion +from the others. + +@subsection{Macro hiding} + +Macro hiding lets one see how expansion would look if certain macros +were actually primitive syntactic forms. The macro stepper skips over +the expansion of the macros you designate as opaque, but it still +shows the expansion of their subterms. + +The bottom panel of the macro stepper controls the macro hiding +policy. The user changes the policy by selecting an identifier in the +syntax browser pane and then clicking one of "Hide module", "Hide +macro", or "Show macro". The new rule appears in the policy display, +and the user may later remove it using the "Delete" button. + +The stepper also offers coarser-grained options that can hide +collections of modules at once. These options have lower precedence +than the rules above. + +Macro hiding, even with no macros marked opaque, also hides certain +other kinds of steps: internal defines are not rewritten to letrecs, +begin forms are not spliced into module or block bodies, etc. + +@section{Using the syntax browser} + +@subsection{Selection (bold)} + +The user can click on any part of a subterm to select it. To select a +parenthesized subterm, click on either of the parentheses. The +selected syntax is bolded. Since one syntax object may occur inside of +multiple other syntax objects, clicking on one occurrence will cause +all occurrences to be bolded. + +The syntax browser displays information about the selected syntax +object in the properties panel on the right, when that panel is +shown. The selected syntax also determines the highlighting done by +the secondary partitioning (see below). + +@subsection{Primary partition (foreground color)} + +The primary partitioning always assigns two syntax subterms the same +color if they have the same marks. In the absence of unhygienic +macros, this means that subterms with the same foreground color were +either present in the original pre-expansion syntax or generated by +the same macro transformation step. + +Syntax colored in black always corresponds to unmarked syntax. Such +syntax may be original, or it may be produced by the expansion of a +nonhygienic macro. + +@subsection{Secondary partitioning (highlight)} + +The user may select a *secondary partitioning* from a drop-down box +(or in the macro stepper, through the Syntax menu). This partitioning +applies only to identifiers. When the user selects an identifier, all +terms in the same equivalence class as the selected term are +highlighted in yellow. + +The available secondary partitionings are: +@itemize{ +@item{@scheme[bound-identifier=?]} +@item{@scheme[module-identifier=?]} +@item{@scheme[module-or-top-identifier=?]} +@item{@bold{symbolic-identifier=?}: + Two identifiers are symbolic-identifier=? if discarding all lexical + context information yields the same symbol. +} +@item{@bold{same marks}: + Two identifiers have the same marks if (barring nonhygienic macros) + they were produced by the same macro transformation step. +} +@item{@bold{same source module}: + The bindings of the two identifiers come from definitions in the + same module. +} +@item{@bold{same nominal module}: + The bindings of the two identifiers were imported into the current + context by requiring the same module. +} +} + +@subsection{Properties} + +When the properties pane is shown, it displays properties of the +selected syntax object. The properties pane has three tabbed pages: + + - Binding + + If the selection is an identifier, shows the binding information + associated with the syntax object. + + *Note: See the warning in the section below. + + For more information, look up 'identifier-binding', + 'identifier-transformer-binding', and + 'identifier-template-binding' in the Help Desk. + + - Source + + Displays source location information about the syntax object. + + - Properties + + Displays properties (see 'syntax-property') of the selection + when it has properties it knows the keys for. + +@subsection{Warnings about interpreting syntax} + +The binding information of a *syntax object* may not be the same as +the binding structure of the *program* it represents. The binding +structure of a *program* is only determined after macro expansion is +complete. + +For example, in @schemeblock[(browse-syntax #'(lambda (foo) foo))] +the syntax browser will report that the inner 'foo' is unbound, even +though in the *program* that this syntax represents, the inner 'foo' +is bound to the outer 'foo'. + +@subsection{Notes and Limitations} + +The syntax browser does not have a way of extending the set of +available secondary partitions. + +The syntax browser does not have a way of extending the set of known +properties. + +The syntax browser does not preserve the distinction between +parentheses and square brackets. + + +@section{Notes for DrScheme language implementors} + +The macro stepper works "out of the box" only with certain languages +out of all the languages available from the DrScheme languages +menu. For example, the macro stepper is disabled for the teaching +languages. + +An implementor of a new DrScheme language can designate their language +"macro-steppable" by overriding the 'enable-macro-stepper?' method of +their implementation of 'drscheme:language:language<%>'. The default +implementation in the mixin provided by +'drscheme:language:get-default-mixin' returns false; override this +method to return true if the macro stepper button should be shown for +this language. + +Note: There is currently no way to customize the behavior of the macro +stepper for different languages. When enabled, the macro stepper sees +exactly those terms that pass through the 'current-eval' handler.