fix bug in tracking nominal imporst (which is why the version changed), add EoPL scribblings and fix browser scribblings

svn: r8633
This commit is contained in:
Matthew Flatt 2008-02-12 14:59:05 +00:00
parent 13e4753cd2
commit 86b0c9909a
10 changed files with 684 additions and 976 deletions

View File

@ -1,10 +1,23 @@
#lang scribble/doc #lang scribble/doc
@(require scribble/manual @(require scribble/manual
(for-label browser/browser (for-label browser/browser
browser/browser-unit
browser/browser-sig
browser/htmltext browser/htmltext
browser/external
browser/tool
scheme/gui/base
net/url
framework/framework)) framework/framework))
@(define-syntax-rule (def-ext id)
(begin
(require (for-label net/sendurl))
(define id (scheme send-url))))
@(def-ext net-send-url)
@title{@bold{Browser}: Simple HTML Rendering} @title{@bold{Browser}: Simple HTML Rendering}
The @schememodname[browser/browser] library provides the following The @schememodname[browser/browser] library provides the following
@ -67,464 +80,510 @@ examples). The Scheme code is executed through @scheme[eval].
The @(litchar "MZSCHEME") forms are disabled unless the web page is a The @(litchar "MZSCHEME") forms are disabled unless the web page is a
@(litchar "file:") url that points into the @scheme[doc] collection. @(litchar "file:") url that points into the @scheme[doc] collection.
@defproc[(open-url [url null]) null]{ @defproc[(open-url [url (or/c url? string? input-port?)]) void?]{
Opens the given url Opens the given url
(either a string, url record, or port) in a vanilla browser frame and returns
in a vanilla browser frame and returns the frame. The frame is an instance of
the frame. The frame is an instance of @scheme[hyper-frame%].
@scheme[hyper-frame%].
} }
@defproc[(html-img-ok [on? null undefined]) null]{ @defboolparam[html-img-ok ok?]{
@scheme[html-img-ok] controls image rendering for the browser. A parameter that determines whether the browser attempts to
download and render images.
If @scheme[on?] is provided, sets the value of the parameter to
@scheme[on?], otherwise returns the current value of the parameter
} }
@defproc[(html-eval-ok [on? null undefined]) null]{ @defboolparam[html-eval-ok ok?]{
@scheme[html-eval-ok] controls the evaluation of @(litchar "MZSCHEME=") A parameter that determines whether @(litchar "MZSCHEME=")
tags. tags are evaluated.
If @scheme[on?] is provided, sets the value of the parameter to
@scheme[on?], otherwise returns the current value of the parameter
} }
@defmixin[hyper-frame-mixin () ()]{ @; ----------------------------------------------------------------------
The result of this mixin takes one argument, a url
string. During the initialization of objects created from
this mixin, the code shows the frame and visits the url.
@defconstructor[([frame% null])]{ @defmixin[hyper-frame-mixin (frame%) ()]{
Extends the given @scheme[frame%] class.
}
@defmethod[(get-hyper-panel%) null]{ @defconstructor/auto-super[([url (or/c url? string? input-port?)])]{
Returns the class that is instantiated when the frame is created. Shows the frame and visits @scheme[url].
Must be a panel with hyper-panel-mixin mixed in. Defaults to }
just returning @scheme[hyper-panel%].
}
@defmethod[(get-hyper-panel) null]{ @defmethod[(get-hyper-panel%) (subclass?/c panel%)]{
Returns the hyper panel in this frame. Returns the class that is instantiated when the frame is created.
} Must be a panel with hyper-panel-mixin mixed in. Defaults to
just returning @scheme[hyper-panel%].
}
@defmethod[(get-hyper-panel) (is-a?/c panel%)]{
Returns the hyper panel in this frame.
}
} }
@defmixin[hyper-no-show-frame-mixin () ()]{ @; ----------------------------------------------------------------------
This is the same as the @scheme[hyper-frame-mixin], except that it
doesn't show the frame and the initialization arguments
are unchanged.
@defconstructor[([frame% null])]{ @defmixin[hyper-no-show-frame-mixin (frame%) ()]{
Extends the given @scheme[frame%] class. The same as the @scheme[hyper-frame-mixin], except that it
} doesn't show the frame and the initialization arguments
are unchanged.
} }
@defmixin[hyper-text-mixin () ()]{ @; ----------------------------------------------------------------------
The initialization arguments are extended with
four new first arguments: a url or a port to be loaded
into the @scheme[text%] object (using the @scheme[reload] method,
described below), a top-level-window or @scheme[#f] to use as a
parent for status dialogs, a progress procedure used as
for @scheme[get-url], and either @scheme[#f] or a post string to be sent
to a web server (technically changing the GET to a POST).
Sets the autowrap-bitmap to @scheme[#f]. @defmixin[hyper-text-mixin (text%) ()]{
An instance of a @scheme[(hyper-text-mixin text%)] class should be displayed
only in an instance of a class created with @scheme[hyper-canvas-mixin]
(described below).
@defconstructor[([text% null])]{ An instance of a @scheme[hyper-text-mixin]-extended class
Extends the given @scheme[text%] class. should be displayed only in an instance of a class created
} with @scheme[hyper-canvas-mixin].
The mixin adds the following methods: @defconstructor/auto-super[([url (or/c url? string? input-port?)]
[status-frame (or/c (is-a?/c top-level-window<%>) false/c)]
[post-data (or/c false/c bytes?)])]{
The @scheme[url] is loaded into the @scheme[text%] object
(using the @method[hyper-text-mixin reload] method), a
top-level window for status messages and dialogs, a progress
procedure used as for @scheme[get-url], and either @scheme[#f]
or a post string to be sent to a web server (technically
changing the GET to a POST).
@defmethod[(map-shift-style [start null] [end null] [shift-style null]) null]{ Sets the autowrap-bitmap to @scheme[#f].
Maps the given style over the given range. }
}
@defmethod[(make-link-style [start null] [end null]) null]{ @defmethod[(map-shift-style [start exact-nonnegative-integer?]
Changes the style for the given range to the link style. [end exact-nonnegative-integer?]
} [shift-style style<%>])
void?]{
Maps the given style over the given range.
}
@defmethod[(get-url) null]{ @defmethod[(make-link-style [start exact-nonnegative-integer?]
Returns the URL displayed by the editor, or @scheme[#f] if there [end exact-nonnegative-integer?])
is none. void?]{
} Changes the style for the given range to the link style.
}
@defmethod[(get-title) null]{ @defmethod[(get-url) (or/c url? string? input-port? false/c)]{
Gets the page's title. Returns the URL displayed by the editor, or @scheme[#f] if there
} is none.
}
@defmethod[(set-title [string null]) null]{ @defmethod[(get-title) string?]{
Sets the page's title. Gets the page's title.
} }
@defmethod[(hyper-delta) null]{ @defmethod[(set-title [str string?]) void?]{
A @scheme[style-delta%] object; override it to set the link style. Sets the page's title.
} }
@defmethod[(add-tag [name-string null] [pos null]) null]{ @defmethod[(hyper-delta) style-delta%]{
Installs a tag. Override this method to set the link style.
} }
@defmethod[(find-tag [name-string/number null]) null]{ @defmethod[(add-tag [name string?] [pos exact-nonnegative-integer?]) void?]{
Finds the location of a tag in the buffer (where tags are Installs a tag.
installed in HTML with @(litchar "<A NAME=\"name\">")) and returns its }
position. If @scheme[name] is a number, the number is returned
(assumed to be an offset rather than a tag). Otherwise,
if the tag is not found, @scheme[#f] is returned.
}
@defmethod[(remove-tag [name null]) null]{ @defmethod[(find-tag [name/number (or/c string? exact-nonnegative-integer?)])
Removes a tag. (or/c exact-nonnegative-integer? false/c)]{
} Finds the location of a tag in the buffer (where tags
are installed in HTML with @(litchar "<A
NAME=\"name\">")) and returns its position. If
@scheme[name] is a number, the number is returned
(assumed to be an offset rather than a
tag). Otherwise, if the tag is not found, @scheme[#f]
is returned.
}
@defmethod[(post-url [url string?] [post-data-bytes null #f]) null]{ @defmethod[(remove-tag [name string?]) void?]{
Follows the link in the string. Removes a tag.
@scheme[post-data-bytes] defaults to @scheme[#f] }
}
@defmethod[(add-link [start null] [end null] [url-string null]) null]{ @defmethod[(post-url [url (or/c string? url?)]
Installs a hyperlink. [post-data-bytes (or/c bytes? false/c) #f]) void?]{
} Follows the link, optionally with the given post data.
}
@defmethod[(add-scheme-callback [start null] [end null] [scheme-string null]) null]{ @defmethod[(add-link [start exact-nonnegative-integer?]
Installs a Scheme evaluation hyperlink. [end exact-nonnegative-integer?]
} [url (or/c url? string?)])
void?]{
Installs a hyperlink.
}
@defmethod[(add-thunk-callback [start null] [end null] [thunk null]) null]{ @defmethod[(add-scheme-callback [start exact-nonnegative-integer?]
Installs a thunk-based hyperlink. [end exact-nonnegative-integer?]
} [scheme-expr string?])
void?]{
Installs a Scheme evaluation hyperlink.
}
@defmethod[(eval-scheme-string [string null]) null]{ @defmethod[(add-thunk-callback [start exact-nonnegative-integer?]
Called to handle the @(litchar "<A MZSCHEME=\"expr\">...</A>") [end exact-nonnegative-integer?]
tag and @(litchar "<! MZSCHEME=\"expr\">") comments (see above). [thunk (-> any)])
Evaluates the string; if the result is a string, void?]{
it is opened as an HTML page. Installs a thunk-based hyperlink.
} }
@defmethod[(reload) null]{ @defmethod[(eval-scheme-string [str string?]) any]{
Reloads the current page. Called to handle the @(litchar "<A MZSCHEME=\"expr\">...</A>")
tag and @(litchar "<! MZSCHEME=\"expr\">") comments (see above).
The text defaultly uses the basic style named "Html Evaluates the string; if the result is a string,
Standard" in the editor (if it exists). } it is opened as an HTML page.
}
@defmethod[(remap-url [url null]) null]{ @defmethod[(reload) void?]{
When visiting a new page, this method is called to remap Reloads the current page.
the url. The remapped url is used in place of the
original url. If this method returns @scheme[#f], the page doesn't
go anywhere.
This method may be killed (if the user clicks the The text defaultly uses the basic style named
``stop'' button) @scheme["Html Standard"] in the editor (if it exists).
} }
@defmethod[(get-hyper-keymap) null]{ @defmethod[(remap-url [url (or/c url? string?)]) (or/c url? string?)]{
Returns a keymap suitable for frame-level handling of events to When visiting a new page, this method is called to remap
redirect page-up, etc. to the browser canvas. the url. The remapped url is used in place of the
} original url. If this method returns @scheme[#f], the page doesn't
go anywhere.
This method may be killed (if the user clicks the
``stop'' button).
}
@defmethod[(get-hyper-keymap) (is-a?/c keymap%)]{
Returns a keymap suitable for frame-level handling of events to
redirect page-up, @|etc| to the browser canvas.
}
} }
@defclass[hyper-text% hyper-text-mixin #;(hyper-text-mixin text:keymap%) ()]{ @; ----------------------------------------------------------------------
Extends the @scheme[text:keymap%] class to support standard @defclass[hyper-text% (hyper-text-mixin text:keymap%) ()]{
key bindings in the browser window.
Extends the @scheme[text:keymap%] class to support standard
key bindings in the browser window.
} }
@defmixin[hyper-canvas-mixin () ()]{ @; ----------------------------------------------------------------------
@defconstructor[([editor-canvas% null])]{
Extends the given
@scheme[editor-canvas%] class.
The initialization arguments are unchanged.
}
The canvas's parent should be an instance of a class derived with @defmixin[hyper-canvas-mixin (editor-canvas%) ()]{
@scheme[hyper-panel-mixin] (described below).
@defmethod[(get-editor%) null]{ A @scheme[hyper-can-mixin]-extended canvas's parent should be
Returns the class used to implement the editor in the browser an instance of a class derived with
window. It should be derived from @scheme[hyper-text%] @scheme[hyper-panel-mixin].
and should pass on the
initialization arguments to @scheme[hyper-text%].
The dynamic extent of the initialization of this @defconstructor/auto-super[()]{
editor is called on a thread that may be killed (via a }
custodian shutdown)
In that case, the editor in the browser's @defmethod[(get-editor%) (subclass?/c text%)]{
editor-canvas may not be an instance of this class.
}
@defmethod[(current-page) null]{ Returns the class used to implement the editor in the browser
Returns a representation of the currently displayed page, which window. It should be derived from @scheme[hyper-text%] and
includes a particular editor and a visible range within the should pass on the initialization arguments to
editor. @scheme[hyper-text%].
}
@defmethod[(goto-url [url null] [relative-to-url null] [progress-proc null undefined] [post-data-bytes null @scheme[#f]]) null]{ The dynamic extent of the initialization of this
Changes to the given url, loading it by calling the @scheme[make-editor] editor is called on a thread that may be killed (via a
method. If @scheme[relative-to-url] is not @scheme[#f], it must be custodian shutdown). In that case, the editor in the browser's
a URL for resolving @scheme[url] as a relative URL. editor-canvas may not be an instance of this class.
@scheme[url] may also be a port, in which case, }
@scheme[relative-to-url] must be @scheme[#f].
The @scheme[progress-proc] procedure is called with a boolean at the @defmethod[(current-page) any/c]{
point where the URL has been resolved and enough progress has Returns a representation of the currently displayed page, which
been made to dismiss any message that the URL is being includes a particular editor and a visible range within the
resolved. The procedure is called with @scheme[#t] if the URL will be editor.
loaded into a browser window, @scheme[#f] otherwise (e.g., the user will }
save the URL content to a file).
If @scheme[post-data-bytes] is a byte string instead of false, the URL @defmethod[(goto-url [url (or/c url? string?)]
GET is changed to a POST with the given data. [relative-to-url (or/c url? string? false/c)]
} [progress-proc (boolean? . -> . any) void]
[post-data (or/c bytes? false/c) #f])
void?]{
Changes to the given url, loading it by calling the @scheme[make-editor]
method. If @scheme[relative-to-url] is not @scheme[#f], it must be
a URL for resolving @scheme[url] as a relative URL.
@scheme[url] may also be a port, in which case,
@scheme[relative-to-url] must be @scheme[#f].
@defmethod[(set-page [page null] [notify? null]) null]{ The @scheme[progress-proc] procedure is called with a boolean at the
Changes to the given page. If @scheme[notify?] is not @scheme[#f], point where the URL has been resolved and enough progress has
the canvas's parent is notified about the change by calling its been made to dismiss any message that the URL is being
@scheme[leaving-page] method. resolved. The procedure is called with @scheme[#t] if the URL will be
} loaded into a browser window, @scheme[#f] otherwise (e.g., the user will
save the URL content to a file).
@defmethod[(after-set-page) null]{ If @scheme[post-data-bytes] is a byte string instead of false, the URL
Called during @scheme[set-page]. Defaultly does nothing. GET is changed to a POST with the given data.
} }
@defmethod[(set-page [page any/c] [notify? any/c]) void?]{
Changes to the given page. If @scheme[notify?] is not @scheme[#f],
the canvas's parent is notified about the change by calling its
@scheme[leaving-page] method.
}
@defmethod[(after-set-page) void?]{
Called during @scheme[set-page]. Defaultly does nothing.
}
} }
@defmixin[hyper-panel-mixin () ()]{ @; ----------------------------------------------------------------------
@defconstructor[([area-container% null])]{
Extends the given area
container class. The initialization arguments are unchanged, but
initialization creates controls and a hyper text canvas. The
controls permit a user to move back and forth in the hypertext
history.
}
The mixin adds a initialization argument, @scheme[info-line?],
which is a boolean indicating whether the browser should contain a
line to display special @(litchar "DOCNOTE") tags in a page.
Such tags are used primarily by the PLT documentation.
The mixin adds the following instance variables: @defmixin[hyper-panel-mixin (area-container<%>) ()]{
@defmethod[(make-canvas [container null]) null]{
Creates the panel's hypertext canvas, an instance of a class
derived using @scheme[hyper-canvas-mixin] (described above). This
method is called during initialization.
}
@defmethod[(get-canvas%) null]{ @defconstructor/auto-super[([info-line? any/c])]{
Returns the class instantiated by make-canvas. It must be derived from Creates controls and a hyper text canvas. The
@scheme[hyper-canvas%]. controls permit a user to move back and forth in the hypertext
} history.
The @scheme[info-line?] argument indicates whether the browser
should contain a line to display special @(litchar "DOCNOTE")
tags in a page. Such tags are used primarily by the PLT
documentation.}
@defmethod[(make-canvas [container (is-a?/c area-container<%>)]) void?]{
Creates the panel's hypertext canvas, an instance of a class
derived using @scheme[hyper-canvas-mixin]. This
method is called during initialization.
}
@defmethod[(make-control-bar-panel [container null]) null]{ @defmethod[(get-canvas%) (subclass?/c editor-canvas%)]{
Creates the panel's sub-container for the control bar containing Returns the class instantiated by make-canvas. It must be derived from
the navigation buttons. If @scheme[#f] is returned, the panel will @scheme[hyper-canvas-mixin].
have no control bar. The default method instantiates }
@scheme[horizontal-panel%].
}
@defmethod[(rewind) null]{ @defmethod[(make-control-bar-panel [container (is-a?/c area-container<%>)])
Goes back one page, if possible. any/c]{
} Creates the panel's sub-container for the control bar containing
the navigation buttons. If @scheme[#f] is returned, the panel will
have no control bar. The default method instantiates
@scheme[horizontal-panel%].
}
@defmethod[(forward) null]{ @defmethod[(rewind) void?]{
Goes forward one page, if possible. Goes back one page, if possible.
} }
@defmethod[(get-canvas) null]{ @defmethod[(forward) void?]{
Gets the hypertext canvas. Goes forward one page, if possible.
} }
@defmethod[(on-navigate) null]{ @defmethod[(get-canvas) (is-a?/c editor-canvas%)]{
Callback that is invoked any time the displayed hypertext page Gets the hypertext canvas.
changes (either by clicking on a link in the canvas or by }
@scheme[rewind] or @scheme[forward] calls).
}
@defmethod[(leaving-page [page null] [new-page null]) null]{ @defmethod[(on-navigate) void?]{
This method is called by the hypertext canvas to notify the Callback that is invoked any time the displayed hypertext page
panel that the hypertext page changed. The @scheme[page] is @scheme[#f] changes (either by clicking on a link in the canvas or by
if @scheme[new-page] is the first page for the canvas. See also @scheme[rewind] or @scheme[forward] calls).
@scheme[page->editor] (described below). }
}
@defmethod[(filter-notes [list-of-strings null]) null]{ @defmethod[(leaving-page [page any/c] [new-page any/c])
Given the notes from a page as a list of strings (where any]{
each string is a note), returns a single string to print This method is called by the hypertext canvas to notify the
above the page. panel that the hypertext page changed. The @scheme[page] is @scheme[#f]
} if @scheme[new-page] is the first page for the canvas. See also
@method[hyper-panel-mixin page->editor].
}
@defmethod[(reload) null]{ @defmethod[(filter-notes [notes (listof string?)])
Reloads the currently visible page by calling the @scheme[reload] (listof string?)]{
method of the currently displayed hyper-text. Given the notes from a page as a list of strings (where
} each string is a note), returns a single string to print
above the page.
}
@defmethod[(reload) void?]{
Reloads the currently visible page by calling the @scheme[reload]
method of the currently displayed hyper-text.
}
} }
@defproc[(editor->page [editor null]) null]{ @; ----------------------------------------------------------------------
Creates a page record for the given editor,
suitable for use with the @scheme[set-page] method of @defproc[(editor->page [editor (is-a?/c text%)]) any/c]{
@scheme[hyper-canvas-mixin]. Creates a page record for the given editor,
suitable for use with the @scheme[set-page] method of
@scheme[hyper-canvas-mixin].
} }
@defproc[(page->editor [page null]) null]{ @defproc[(page->editor [page any/c]) (is-a?/c text%)]{
Extracts the editor from a page record. Extracts the editor from a page record.
} }
@defproc[(on-installer-run [proc null undefined]) null]{ @defparam[bullet-size n exact-nonnegative-integer?]{
Parameter for a procedure to be invoked Parameter controlling the point size of a
after the installer is run on a .plt file. bullet.
} }
@defproc[(bullet-size [n null undefined]) null]{ @defclass[image-map-snip% snip% ()]{
Parameter controlling the point size of a Instances of this class behave like @scheme[image-snip%] objects,
bullet. except they have a @(litchar "<map> ... </map>") associated with them and
when clicking on them (in the map) they will cause their
init arg text to follow the corresponding link.
@defconstructor[([html-text (is-a?/c html-text<%>)])]{
}
@defmethod[(set-key [key string?]) void?]{
Sets the key for the image map (eg, "#key").
}
@defmethod[(get-key) string?]{
Returns the current key.
}
@defmethod[(add-area [shape string?]
[region (listof number?)]
[href string?])
void?]{
Registers the shape named by @scheme[shape] whose
coordinates are specified by @scheme[region] to go to
@scheme[href] when that region of the image
is clicked on.
}
} }
@defmixin[image-map-snip% () ()]{ @; ----------------------------------------------------------------------
Instances of this class behave like @scheme[image-snip%] objects,
except they have a @(litchar "<map> ... </map>") associated with them and
when clicking on them (in the map) they will cause their
init arg text to follow the corresponding link.
@defconstructor[([html-text (is-a?/c html-text<%>)])]{
}
@defmethod[(set-key [key-string null]) null]{
Sets the key for the image map (eg, "#key").
}
@defmethod[(get-key) null]{
Returns the current key.
}
@defmethod[(add-area [shape-string null] [list-of-numbers null] [href-string null]) null]{
Registers the shape named by the shape-string whose
coordinates are specified by the list-of-numbers to go to
the href named href-string when that region of the image
is clicked on.
}
}
@section[#:tag "browser-unit"]{Browser Unit} @section[#:tag "browser-unit"]{Browser Unit}
@defmodule[browser/browser-unit] @defmodule[browser/browser-unit]
The _browser-unit.ss_ library in the "browser" collection is a @defthing[browser@ unit?]{
unitized version of the code documented above. It imports unit
matching the following signatures:
@(itemize
(item @scheme[setup:plt-installer^])
(item @scheme[mred^])
(item @scheme[tcp^] " (see \"tcp-sig.ss\" in the \"net\" collection)")
(item @scheme[url^] " (see \"url-sig.ss\" in the \"url\" collection)"))
It exports the @scheme[browser^] signature. Imports @scheme[mred^], @scheme[tcp^], and @scheme[url^], and exports
@scheme[browser^].}
The _browser-sig.ss_ library in the ``browser'' collection defines @; ----------------------------------------------------------------------
the @scheme[browser^] signature with all of the names listed above.
@section[#:tag "browser-sig"]{Browser Signature}
@section[#:tag "html-text"]{HTML As Text} @defmodule[browser/browser-sig]
@defsignature[browser^ ()]{
Includes all of the bindings of the @schememodname[browser/browser]
library.}
@; ----------------------------------------------------------------------
@section[#:tag "html-text"]{HTML As Text Editor}
@defmodule[browser/htmltext] @defmodule[browser/htmltext]
@definterface[html-text<%> ()]{ @definterface[html-text<%> (text%)]{
An interface that extends @scheme[text%] with the following methods:
@defmethod[(get-url) null]{ @defmethod[(get-url) (or/c url? string? false/c)]{
Returns a base URL used for building Returns a base URL used for building
relative URLs, or @scheme[#f] if no base is available. relative URLs, or @scheme[#f] if no base is available.
} }
@defmethod[(set-title [str null]) null]{ @defmethod[(set-title [str string?]) void?]{
Registers the title @scheme[str] Registers the title @scheme[str]
for the rendered page. for the rendered page.
} }
@defmethod[(add-link [start-pos null] [end-pos null] [url-string null]) null]{ @defmethod[(add-link [start exact-nonnegative-integer?]
Registers a hyperlink for the given region in rendered page. [end exact-nonnegative-integer?]
} [url (or/c url? string?)])
void?]{
Registers a hyperlink for the given region in rendered page.
}
@defmethod[(label [pos null]) null]{ @defmethod[(add-tag [name string?] [pos exact-nonnegative-integer?]) void?]{
Registers a tag at the given position in the rendered page. Installs a tag.
} }
@defmethod[(make-link-style [start-pos null] [end-pos null]) null]{ @defmethod[(make-link-style [start exact-nonnegative-integer?]
Modifies the style of the rendered page from @scheme[start-pos] to [end exact-nonnegative-integer?])
@scheme[end-pos] to look like a hyperlink. void?]{
} Changes the style for the given range to the link style.
}
@defmethod*[([(add-scheme-callback [pos null] [endpos null] [code-string null]) null] @defmethod[(add-scheme-callback [start exact-nonnegative-integer?]
[(add-scheme-callback [pos null] [endpos null] [thunk null]) null])]{ [end exact-nonnegative-integer?]
Registers a code-evaluating or thunk-invoking hyperlink for the given region. [scheme-expr string?])
} void?]{
Installs a Scheme evaluation hyperlink.
}
@defmethod[(post-url [url null] [post-data-bytes null]) null]{ @defmethod[(add-thunk-callback [start exact-nonnegative-integer?]
Performs a post to the given @scheme[url] with the given post data. [end exact-nonnegative-integer?]
} [thunk (-> any)])
void?]{
Installs a thunk-based hyperlink.
}
@defmethod[(post-url [url (or/c string? url?)]
[post-data-bytes (or/c bytes? false/c) #f]) void?]{
Follows the link, optionally with the given post data.
}
} }
@defmixin[html-text-mixin () ()]{
@defconstructor[([text%-subclassr% null])]{ @defmixin[html-text-mixin (text%) ()]{
Extends the given @scheme[text%] class with implementations of the Extends the given @scheme[text%] class with implementations of the
@scheme[html-text<%>] methods. Hyperlinks are attached to clickbacks @scheme[html-text<%>] methods. Hyperlinks are attached to clickbacks
that use @scheme[send-url] that use @net-send-url from @schememodname[net/sendurl].
(from the ``sendurl.ss'' library of the ``net'' collection). }
}
} }
@defproc[(render-html-to-text [input-port null] [html-text<%>-obj null] [load-img? null] [eval-mz? null]) null]{ @defproc[(render-html-to-text [in input-port?]
Reads HTML from @scheme[input-port] and renders it to [dest (is-a? html-text<%>)]
@scheme[html-text<%>-obj]. If @scheme[load-img?] is false, then images [load-img? any/c]
are rendered as Xed-out boxes. If @scheme[eval-mz?] is false, then [eval-mz? any/c])
MZSCHEME hyperlink expressions and comments are not evaluated. void?]{
Uses the style named ``Html Standard'' in the editor's Reads HTML from @scheme[in] and renders it to @scheme[dest].
style-list (if it exists) for all of the inserted text's If @scheme[load-img?] is @scheme[#f], then images are rendered
default style. as Xed-out boxes. If @scheme[eval-mz?] is @scheme[#f], then
} @litchar{MZSCHEME} hyperlink expressions and comments are not
evaluated.
Uses the style named @scheme["Html Standard"] in the editor's
style-list (if it exists) for all of the inserted text's
default style.}
@; ----------------------------------------------------------------------
@section[#:tag "external"]{Launching an External Browser} @section[#:tag "external"]{Launching an External Browser}
@defmodule[browser/external] @defmodule[browser/external]
@defproc[(send-url [str null] [separate-window? void #t]) null]{ @defproc[(send-url [str null] [separate-window? void #t]) null]{
Like @scheme[send-url] in @scheme[(lib "sendurl.ss" "net")], but under Unix, Like @net-send-url from @scheme[net/sendurl] , but under Unix,
the user is prompted for a browser to use if none is recorded the user is prompted for a browser to use if none is recorded
in the preferences file. in the preferences file.
} }
@defproc[(browser-preference? [v null]) null]{ @defproc[(browser-preference? [v any/c]) boolean?]{
Returns @scheme[#t] if @scheme[v] is a valid browser preference. Returns @scheme[#t] if @scheme[v] is a valid browser preference.
} }
@defproc[(update-browser-preference [url-or-#f null]) null]{ @defproc[(update-browser-preference [url (or/c string? false/c)]) void?]{
Under Unix, prompts the user for a browser preference and records Under Unix, prompts the user for a browser preference and records
the user choice as a framework preference (even if one is already the user choice as a framework preference (even if one is already
recorded). If @scheme[url-or-#f] is not @scheme[#f], it is used in the recorded). If @scheme[url] is not @scheme[#f], it is used in the
dialog to explain which URL is to be opened; if it is @scheme[#f], dialog to explain which URL is to be opened; if it is @scheme[#f],
the @scheme['internal] will be one of the options for the user. the @scheme['internal] will be one of the options for the user.
} }
@defproc[(install-help-browser-preference-panel) null]{ @defproc[(install-help-browser-preference-panel) void?]{
Installs a framework preference panel for ``Browser'' options. Installs a framework preference panel for ``Browser'' options.
} }
@defproc[(add-to-browser-prefs-panel [proc null]) null]{ @defproc[(add-to-browser-prefs-panel [proc ((is-a?/c panel%) . -> . any)]) void?]{
The @scheme[proc] must be a procedure that takes a @scheme[panel%] argument. The @scheme[proc] is called when the ``Browser'' panel is constructed for
It will be called when the ``Browser'' panel is constructed for preferences. The supplied argument is the panel, so @scheme[proc] can add
preferences. The supplied argument is the panel, so @scheme[proc] can add additional option controls. If the panel is already created, @scheme[proc]
additional option controls. If the panel is already created, @scheme[proc] is called immediately.
is called immediately.
} }
@scheme[tool@] @; ----------------------------------------------------------------------
@section[#:tag "tool"]{DrScheme Browser Preference Panel}
@defmodule[browser/tool]
@defthing[tool@ unit?]{
A unit that implements a DrScheme tool to add the ``Browser'' A unit that implements a DrScheme tool to add the ``Browser''
preference panel. preference panel.
}

View File

@ -1,457 +0,0 @@
The _browser.ss_ library in the "browser" collection provides the
following procedures and classes for parsing and viewing _HTML_ files.
The "htmltext.ss" library (described further below) provides a
simplified interface for rendering to a subclass of the MrEd text%
class. The "external.ss" library (described even further below)
provides utilities for launching an external browser (such as
Mozilla).
The browser (and htmltext) supports basic HTML commands, plus special
Scheme hyperlinks of the form <A MZSCHEME=sexpr>...</A>. When the user
clicks on such a link, the string `sexpr' is parsed as a Scheme
program and evaluated. Since `sexpr' is likely to contain Scheme
strings, and since escape characters are difficult for people to read,
a vertical bar (|) character in sexpr is converted to a double-quote
(") character before it is parsed. Thus,
<A MZSCHEME="|This goes nowhere.|">Nowhere</A>
creates a "Nowhere" hyperlink, which executes the Scheme program
"This goes nowhere."
The value of that program is a string. When a Scheme hyperlink returns
a string, it is parsed as a new HTML document. Thus, where the use
clicks on "Nowhere", the result is a new page that says "This goes
nowhere."
The browser also treats comment forms containing MZSCHEME=sexpr
specially. Whereas the <A MZSCHEME=sexpr>...</A> form executes the
expression when the user clicks, the MZSCHEME expression in a comment
is executed immediately during HTML rendering. If the result is a
string, the comment is replaced in the input HTML stream with the
content of the string. Thus,
<!-- MZSCHEME="(format |<B>Here</B>: ~a| (current-directory))" -->
inserts the path of the current working directory into the containing
document (and "Here" is boldfaced). If the result is a snip instead of
a string, it replaces the comment in the document. Other types of
return values are ignored.
If the html file is being accessed as a "file:" url, the
current-load-relative-directory parameter is set to the directory
during the evaluation of the mzscheme code (in both examples). The
Scheme code is executed through `eval'.
The MZSCHEME forms are disabled unless the web page is a
file: url that points into the `doc' collection.
----------------------------------------
> (open-url url) - Opens the given url
(either a string, url record, or port)
in a vanilla browser frame and returns
the frame. The frame is an instance of
hyper-frame%.
-----------------------------------------
The html-img-ok parameter controls image rendering for the browser.
> (html-img-ok on?) - Sets the value of the parameter to on?
> (html-img-ok) - Returns the current value of the parameter
The html-eval-ok parameter controls the evaluation of
`MZSCHEME=' tags. If the parameter is #f, they are disabled.
> (html-eval-ok on?) - Sets the value of the parameter to on?
> (html-eval-ok) - Returns the current value of the parameter
------------------------------------------------------------
> (hyper-frame-mixin frame%) - Extends the given frame% class.
The result of this mixin takes one argument, a url
string. During the initialization of objects created from
this mixin, the code shows the frame and visits the url.
> get-hyper-panel% :: (send hyper-frame get-hyper-panel%)
returns the class that is instantiated with the frame is created.
Must be a panel with hyper-panel-mixin mixed in. Defaults to
just returning hyper-panel%.
> get-hyper-panel :: (send hyper-frame get-hyper-panel) - returns the hyper panel
in this frame
----------------------------------------
> hyper-frame% = (hyper-frame-mixin frame%)
------------------------------------------------------------
> (hyper-no-show-frame-mixin frame%) - Extends the given frame% class.
This is the same as the hyper-frame-mixin, except that it
doesn't show the frame and the initialization arguments
are unchanged.
----------------------------------------
> hyper-no-show-frame% = (hyper-frame-no-show-mixin frame%)
----------------------------------------
> (hyper-text-mixin text%) - Extends the given text%
class. The initialization arguments are extended with a
four new first arguments: a url or a port to be loaded
into the text% object (using the `reload' method,
described below), a top-level-window or #f to use as a
parent for status dialogs, a progress procedure used as
for `get-url', and either #f or a post string to be sent
to a web server (technically changing the GET to a POST).
Sets the autowrap-bitmap to #f.
An instance of a (hyper-text-mixin text%) class should be displayed
only in an instance of a class created with `hyper-canvas-mixin'
(described below).
The mixin adds the following methods:
> map-shift-style :: (send o map-shift-style start end shift-style)
Maps the given style over the given range
> make-link-style :: (send o make-link-style start end)
Changes the style for the given range to the link style
> get-url :: (send o get-url)
Returns the URL displayed by the editor, or #f if there
is none.
> get-title :: (send o get-title)
> set-title :: (send o set-title string)
Gets or sets the page's title
> hyper-delta
A style-delta% object; override it to set the link style
> add-tag ::(send o add-tag name-string pos)
Installs a tag.
> find-tag :: (send o find-tag name-string/number)
Finds the location of a tag in the buffer (where tags are
installed in HTML with <A NAME="name">) and returns its
position. If `name' is a number, the number is returned (assumed
to be an offset rather than a tag). Otherwise, if the tag is not
found, #f is returned.
> remove-tag :: (send o remove-tag name)
Removes a tag.
> post-url :: (send o post-url string[url] post-data-bytes)
Follows the link in the string. post-data-bytes defaults to #f
> add-link :: (send o add-link start end url-string)
Installs a hyperlink.
> add-scheme-callback :: (send o add-scheme-callback start end scheme-string)
Installs a Scheme evaluation hyperlink.
> add-scheme-callback :: (send o add-thunk-callback start end thunk)
Installs a thunk-based hyperlink.
> eval-scheme-string :: (send o eval-scheme-string string)
Called to handle the <A MZSCHEME="expr">...</A> tag and <!
MZSCHEME="expr"> comments (see above). Evaluates the string; if
the result is a string, it is opened as an HTML page.
> reload :: (send o reload)
Reloads the current page.
The text defaultly uses the basic style named "Html
Standard" in the editor (if it exists).
> remap-url :: (send o remap-url url) -> url or string or #f
When visiting a new page, this method is called to remap
the url. The remapped url is used in place of the
original url. If this method returns #f, the page doesn't
go anywhere.
This method may be killed (if the user clicks the
``stop'' button)
----------------------------------------
> hyper-text% = (hyper-text-mixin text:keymap%)
This is an extension of the keymap class, to support standard key bindings
in the browser window. It adds the following method:
> get-hyper-keymap :: (send o get-hyper-keymap) -> keymap% object
Returns a keymap suitable for frame-level handling of events to
redirect page-up, etc. to the browser canvas.
----------------------------------------
> (hyper-canvas-mixin editor-canvas%) - Extends the given
editor-canvas% class. The initialization arguments are unchanged.
The canvas's parent should be an instance of a class derived with
`hyper-panel-mixin' (described below).
The mixin adds the following methods:
> get-editor% :: (send o get-editor%)
Returns the class used to implement the editor in the browser
window. It should be derived from hyper-text% and should pass on the
initialization arguments to hyper-text%
The dynamic extent of the initialization of this
editor is called on a thread that may be killed (via a
custodian shutdown)
In that case, the editor in the browser's
editor-canvas may not be an instance of this class.
> current-page :: (send o current-page)
Returns a representation of the currently displayed page, which
includes a particular editor and a visible range within the
editor.
> goto-url :: (send o goto-url url relative-to-url [progress-proc] [post-data-bytes #f])
Changes to the given url, loading it by calling the `make-editor'
method. If `relative-to-url' is not #f, it must be a URL for
resolving `url' as a relative URL. `url' may also be a port, in
which case, `relative-to-url' must be #f.
The `progress-proc' procedure is called with a boolean at the
point where the URL has been resolved and enough progress has
been made to dismiss any message that the URL is being
resolved. The procedure is called with #t if the URL will be
loaded into a browser window, #f otherwise (e.g., the user will
save the URL content to a file).
If `post-data-bytes' is a byte string instead of false, the URL
GET is changed to a POST with the given data.
> set-page :: (send o set-page page notify?)
Changes to the given page. If `notify?' is not #f, the canvas's
parent is notified about the change by calling its `leaving-page'
method.
> after-set-page :: (send o after-set-page)
Called during `set-page'. Defaultly does nothing.
----------------------------------------
> hyper-canvas% = (hyper-canvas-mixin editor-canvas%)
----------------------------------------
> (hyper-panel-mixin area-container%) - Extends the given area
container class. The initialization arguments are unchanged, but
initialization creates controls and a hyper text canvas. The
controls permit a user to move back and forth in the hypertext
history.
The mixin adds a initialization argument, info-line?, which is a
boolean indicating whether the browser should contain a line to
display special "DOCNOTE" tags in a page. Such tags are used
primarily by the PLT documentation.
The mixin adds the following instance variables:
> make-canvas :: (send o make-canvas container)
Creates the panel's hypertext canvas, an instance of a class
derived using `hyper-canvas-mixin' (described above). This
method is called during initialization.
> get-canvas% :: (send o get-canvas%)
Returns the class instantiated by make-canvas. It must be derived from
hyper-canvas%
> make-control-bar-panel :: (send o make-control-bar-panel container)
Creates the panel's sub-container for the control bar containing
the navigation buttons. If #f is returned, the panel will have no
control bar. The default method instantiates horizontal-panel%.
> rewind :: (send o rewind)
Goes back one page, if possible.
> forward :: (send o forward)
Goes forward one page, if possible.
> get-canvas :: (send o get-canvas)
Gets the hypertext canvas.
> on-navigate :: (send o on-navigate)
Callback that is invoked any time the displayed hypertext page
changes (either by clicking on a link in the canvas or by
`rewind' or `forward' calls).
> leaving-page :: (send o leaving-page page new-page)
This method is called by the hypertext canvas to notify the
panel that the hypertext page changed. The `page' is #f
if `new-page' is the first page for the canvas. See also
`page->editor' (described below).
> filter-notes :: (send o filter-notes list-of-strings)
Given the notes from a page as a list of strings (where
each string is a note), returns a single string to print
above the page.
> reload :: (send o reload)
Reloads the currently visible page by calling the reload method of
the currently displayed hyper-text.
----------------------------------------
> hyper-panel% = (hyper-panel-mixin vertical-panel%)
----------------------------------------
> (editor->page editor) - Creates a page record for the given editor,
suitable for use with the `set-page' method of hyper-canvas-mixin.
> (page->editor page) - Extracts the editor from a page record.
> (on-installer-run [proc]) - Parameter for a procedure to be invoked
after the installer is run on a .plt file
> (bullet-size [n]) - Parameter controlling the point size of a
bullet
-----------------------------------------
> image-map-snip% extends image-snip%
init: html-text : (is-a?/c html-text<%>)
Instances of this class behave like image-snip% objects,
except they have a <map> ... </map> associated with them and
when clicking on them (in the map) they will cause their
init arg text to follow the corresponding link.
> (send an-image-map-snip set-key key-string)
Sets the key for the image map (eg, "#key").
> (send an-image-map-snip get-key)
Returns the current key.
> (send an-image-map-snip add-area shape-string list-of-numbers href-string)
Registers the shape named by the shape-string whose
coordinates are specified by the list-of-numbers to go to
the href named href-string when that region of the image
is clicked on.
-----------------------------------------
The _browser-unit.ss_ library in the "browser" collection is a
unitized version of the code documented above. It imports unit
matching the following signatures:
setup:plt-installer^
mred^
tcp^ (see "tcp-sig.ss" in the "net" collection)
url^ (see "url-sig.ss" in the "url" collection)
It exports the browser^ signature.
-----------------------------------------
The _browser-sig.ss_ library in the "browser" collection defines
the browser^ signature with all of the names listed above.
========================================
_htmltext.ss_
========================================
> html-text<%>
An interface that extends text% with the following methods:
> get-url :: (send t get-url) --- returns a base URL used for building
relative URLs, or #f if no base is available
> set-title :: (send t set-title str) --- registers the title `str'
for the rendered page
> add-link :: (send t add-link start-pos end-pos url-string) ---
registers a hyperlink for the given region in rendered page
> add-tag :: (send t label pos) --- registers a tag at the given
position in the rendered page
> make-link-style :: (send t make-link-style start-pos end-pos) ---
modifies the style of the rendered page from start-pos to end-pos to
look like a hyperlink
> add-scheme-callback :: (send t add-scheme-callback pos endpos code-string)
--- registers a code-evaluating hyperlink for the given region
> add-thunk-callback :: (send t add-scheme-callback pos endpos thunk)
--- registers a thunk-invoking hyperlink for the given region
> post-url :: (send t post-url url post-data-bytes)
--- performs a post to the given `url' with the given post data
----------------------------------------
> (html-text-mixin text%-subclass) -> html-text<%> implementation
Extends the given text% class with implementations of the html-text<%>
methods. Hyperlinks are attached to clickbacks that use `send-url'
(from the "sendurl.ss" library of the "net" collection).
> (render-html-to-text input-port html-text<%>-obj load-img? eval-mz?)
Reads HTML from `input-port' and renders it to `html-text<%>-obj'. If
`load-img?' is false, then images are rendered as Xed-out boxes. If
`eval-mz?' is false, then MZSCHEME hyperlink expressions and comments
are not evaluated.
Uses the style named "Html Standard" in the editor's
style-list (if it exists) for all of the inserted text's
default style.
========================================
_external.ss_
========================================
> (send-url str [separate-window? #t])
Like 'send-url' in (lib "sendurl.ss" "net"), but under Unix,
the user is prompted for a browser to use if none is recorded
in the preferences file.
> (browser-preference? v)
Returns #t if v is a valid browser preference
> (update-browser-preference url-or-#f)
Under Unix, prompts the user for a browser preference and records
the user choice as a framework preference (even if one is already
recorded). If `url-or-#f' is not #f, it is used in the dialog to
explain which URL is to be opened; if it is #f, the 'internal will
be one of the options for the user.
> (install-help-browser-preference-panel)
Installs a framework preference panel for "Browser" options.
> (add-to-browser-prefs-panel proc)
The `proc' must be a procedure that takes a panel% argument. It
will be called when the "Browser" panel is constructed for
preferences. The supplied argument is the panel, so `proc' can add
additional option controls. If the panel is already created, `proc'
is called immediately.
> tool@
A unit that implements a DrScheme tool to add the "Browser"
preference panel.

View File

@ -1,123 +0,0 @@
The _Essentials of Programming Languages_ (a.k.a _EoPL_) language in
DrScheme provides all of the functions of R5RS, plus the forms and
procedures described below. It is intended for use with the textbook
Essentials of Programming Languages, Second Edition
Friedman, Wand, and Haynes
MIT Press, 2001
Differences from the book:
* Datatypes must be defined before they are used in `cases'
expressions. This constraint enables better and earlier error
reporting.
Some examples in the book's code (or at least the code distributed
for the book) must be changed by moving datatype definitions
earlier.
* The sllgen: functions have been changed to syntactic forms. This
change is also related to better error reporting.
All examples in the book work work with the sllgen: forms.
----------------------------------------
> (define-datatype id predicate-id (variant-id (field-id predicate-expr) ...) ...)
Defines the datatype `id' and a function `predicate-id' that returns
#t for instances of the datatype, and #f for any other value.
Each `variant-id' is defined as a constructor function that creates
an instance of the datatype; the constructor takes as many arguments
as the variant's `field-id's, and each argument is checked by
applying the function produced by the variant's `predicate-expr'.
In DrScheme v209 and older, when constructor-based printing was
used, variant instances were printed with a `make-' prefix before
the variant name. Thus, for compatibility, in addition to
`variant-id', `make-variant-id' is also defined for each
`variant-id' (to the same constructor as `variant-id').
> (cases datatype-id expr (variant-id (field-id ...) result-expr ...) ...)
> (cases datatype-id expr (variant-id (field-id ...) result-expr ...) ... (else result-expr ...))
Branches on the datatype instance produced by `expr', which must be
an instance of the specified `datatype-id' (previously defined with
`define-datatype').
> sllgen:make-string-scanner
> sllgen:make-string-parser
> sllgen:make-stream-parser
> sllgen:make-define-datatypes
> sllgen:show-define-datatypes
> sllgen:list-define-datatypes
Defined in the EoPL textbook's Appendix A. However, the DrScheme
versions are syntactic forms, instead of procedures, and the
arguments must be either quoted literal tables or identifiers that
are defined (at the top level) to quoted literal tables.
> sllgen:make-rep-loop
Defined in the EoPL textbook's Appendix A (and still a function).
> eopl:error
As in the book.
> eopl:printf
> eopl:pretty-print
Same as MzScheme's `printf' and `pretty-print'.
> list-of
> always?
As in the book.
> empty
The empty list.
> (time expr)
Evaluates `expr', and prints timing information before returning the
result.
> (collect-garbage)
Performs a garbage collection (useful for repeatable timings).
> (trace id ...)
> (untrace id ...)
For debugging: `trace' redefines each `id' at the top level (bound
to a procedure) so that it prints arguments on entry and results on
exit. `untrace' reverses the action of `trace' for the given `id's.
Tracing a function causes tail-calls in the original function to
become non-tail calls.
> (provide provide-spec ...)
Useful only with a module that uses _(lib "eopl.ss" "eopl")_ as a
language: exports identifiers from the module. See the MzScheme
manual for information on `provided-spec'.
> eopl:error-stop
Defined only in the top-level namespace (i.e., not in a module);
mutate this variable to install an exception-handling
thunk. Typically, the handler thunk escapes through a continuation.
The "eopl.ss" module sets this variable to #f in the current
namespace when it executes.
> (install-eopl-exception-handler)
Sets MzScheme's exception handler to one that checks
`eopl:error-stop'.
The "eopl.ss" module calls this function when it executes.

164
collects/eopl/eopl.scrbl Normal file
View File

@ -0,0 +1,164 @@
#lang scribble/doc
@(require scribble/manual
(for-label eopl/eopl
scheme/contract
(only-in scheme printf pretty-print)))
@(define-syntax-rule (def-mz id)
(begin
(require (for-label mzscheme))
(define id (scheme provide))))
@(def-mz mzscheme-provide)
@title{@italic{Essentials of Programming Languages} Language}
The @italic{Essentials of Programming Languages} language in DrScheme
provides all of the functions of R5RS (see @schememodname[r5rs]), plus
the forms and procedures described below. It is intended for use with
the textbook @cite["EoPL"].
Differences from the book:
@itemize{
@item{Datatypes must be defined before they are used in
@scheme[cases] expressions. This constraint enables better and
earlier error reporting.
Some examples in the book's code (or at least the code distributed
for the book) must be changed by moving datatype definitions
earlier.}
@item{The @scheme[sllgen:] functions have been changed to syntactic
forms. This change is also related to better error reporting.
All examples in the book work with the @scheme[sllgen:] forms.}
}
@defmodule[eopl/eopl]
@defform[(define-datatype id predicate-id
(variant-id (field-id predicate-expr) ...)
...)]{
Defines the datatype @scheme[id] and a function
@scheme[predicate-id] that returns @scheme[#t] for instances of the
datatype, and @scheme[#f] for any other value.
Each @scheme[variant-id] is defined as a constructor function that
creates an instance of the datatype; the constructor takes as many
arguments as the variant's @scheme[field-id]s, and each argument is
checked by applying the function produced by the variant's
@scheme[predicate-expr].
In DrScheme v209 and older, when constructor-based printing was
used, variant instances were printed with a @scheme[make-] prefix
before the variant name. Thus, for compatibility, in addition to
@scheme[variant-id], @scheme[make-variant-id] is also defined for
each @scheme[variant-id] (to the same constructor as
@scheme[variant-id]).}
@defform*[#:literals (else)
[(cases datatype-id expr
(variant-id (field-id ...) result-expr ...)
...)
(cases datatype-id expr
(variant-id (field-id ...) result-expr ...)
...
(else result-expr ...))]]{
Branches on the datatype instance produced by @scheme[expr], which
must be an instance of the specified @scheme[datatype-id]
(previously defined with @scheme[define-datatype]).}
@deftogether[(
@defidform[sllgen:make-string-scanner]
@defidform[sllgen:make-string-parser]
@defidform[sllgen:make-stream-parser]
@defidform[sllgen:make-define-datatypes]
@defidform[sllgen:show-define-datatypes]
@defidform[sllgen:list-define-datatypes])]{
Defined in the textbook's Appendix A @cite["EoPL"]. However, the
DrScheme versions are syntactic forms, instead of procedures, and
the arguments must be either quoted literal tables or identifiers
that are defined (at the top level) to quoted literal tables.}
@defthing[sllgen:make-rep-loop procedure?]{
Defined in the @italic{EoPL} textbook's Appendix A @cite["EoPL"]
(and still a function).}
@defthing[eopl:error procedure?]{
As in the book.}
@deftogether[(
@defproc[(eopl:printf (form string?) (v any/c) ...) void?]
@defproc[(eopl:pretty-print (v any/c) (port output-port? (current-output-port))) void?])]{
Same as PLT Scheme's @scheme[printf] and @scheme[pretty-print].}
@deftogether[(
@defproc[((list-of (pred (any/c . -> . any)) ...+) (x any/c)) boolean?]
@defproc[(always? (x any/c)) boolean?])]{
As in the book @cite["EoPL"].}
@defthing[empty empty?]{
The empty list.}
@defform[(time expr)]{
Evaluates @scheme[expr], and prints timing information before returning the
result.}
@defproc[(collect-garbage) void?]{
Performs a garbage collection (useful for repeatable timings).}
@deftogether[(
@defform[(trace id ...)]
@defform[(untrace id ...)])]{
For debugging: @scheme[trace] redefines each @scheme[id] at the top
level (bound to a procedure) so that it prints arguments on entry
and results on exit. The @scheme[untrace] form reverses the action
of @scheme[trace] for the given @scheme[id]s.
Tracing a function causes tail-calls in the original function to
become non-tail calls.}
@defform[(provide provide-spec ...)]{
Useful only with a module that uses @schememodname[eopl/eopl] as a
language: exports identifiers from the module. See @mzscheme-provide
from @schememodname[mzscheme] for more information.}
@defthing[eopl:error-stop (-> any/c)]{
Defined only in the top-level namespace (i.e., not in a module);
mutate this variable to install an exception-handling
thunk. Typically, the handler thunk escapes through a continuation.
The @schememodname[eopl/eopl] library sets this variable to
@scheme[#f] in the current namespace when it executes.}
@defproc[(install-eopl-exception-handler) void?]{
Sets an exception handler to one that checks
@scheme[eopl:error-stop].
The @schememodname[eopl/eopl] library calls this function when it
executes.}
@(bibliography
(bib-entry #:key "EoPL"
#:title @elem{@italic{Essentials of Programming Languages}, Second Edition}
#:location "MIT Press"
#:date "2001")
)

View File

@ -8,6 +8,9 @@
(define tool-names (list "Essentials of Programming Languages")) (define tool-names (list "Essentials of Programming Languages"))
(define tool-urls (list "http://www.cs.indiana.edu/eopl/")) (define tool-urls (list "http://www.cs.indiana.edu/eopl/"))
(define scribblings '(("eopl.scrbl")))
(define doc-categories '((language -10)))
(define textbook-pls (define textbook-pls
(list (list '("eopl-small.gif" "eopl") (list (list '("eopl-small.gif" "eopl")
"Essentials of Programming Languages" "Essentials of Programming Languages"

View File

@ -584,20 +584,25 @@
(define-syntax (quote-syntax/loc stx) (define-syntax (quote-syntax/loc stx)
(syntax-case stx () (syntax-case stx ()
[(_ id) [(_ id)
(with-syntax ([loc (with-syntax ([loc
(let ([s #'id]) (let ([s #'id])
(list (syntax-source s) (vector (syntax-source s)
(syntax-line s) (syntax-line s)
(syntax-column s) (syntax-column s)
(syntax-position s) (syntax-position s)
(syntax-span s)))]) (syntax-span s)))])
#'(let ([s (quote-syntax id)]) #'(let ([s (*quote-syntax/loc id)])
(datum->syntax s (datum->syntax s
(syntax-e s) (syntax-e s)
'loc 'loc
s)))])) s)))]))
(define-syntax *quote-syntax/loc
(syntax-rules ()
[(_ (sub ...)) (datum->syntax #f (list (quote-syntax/loc sub) ...))]
[(_ id) (quote-syntax id)]))
(define void-const (define void-const
(schemeresultfont "#<void>")) (schemeresultfont "#<void>"))
(define undefined-const (define undefined-const
@ -1981,7 +1986,7 @@
(define-syntax-parameter current-class #f) (define-syntax-parameter current-class #f)
(define-struct decl (name super intfs ranges mk-head body)) (define-struct decl (name super app-mixins intfs ranges mk-head body))
(define-struct constructor (def)) (define-struct constructor (def))
(define-struct meth (name mode desc def)) (define-struct meth (name mode desc def))
(define-struct spec (def)) (define-struct spec (def))
@ -1989,14 +1994,17 @@
(define (id-info id) (define (id-info id)
(let ([b (identifier-label-binding id)]) (let ([b (identifier-label-binding id)])
(list (let ([p (resolved-module-path-name (module-path-index-resolve (caddr b)))]) (if b
(if (path? p) (list (let ([p (resolved-module-path-name (module-path-index-resolve (caddr b)))])
(intern-taglet (path->main-collects-relative p)) (if (path? p)
p)) (intern-taglet (path->main-collects-relative p))
(cadddr b) p))
(list-ref b 5)))) (cadddr b)
(list-ref b 5))
(error 'scribble "no class/interface/mixin information for identifier: ~e"
id))))
(define-serializable-struct cls/intf (name-element super intfs methods)) (define-serializable-struct cls/intf (name-element app-mixins super intfs methods))
(define (make-inherited-table r d ri decl) (define (make-inherited-table r d ri decl)
(let* ([start (let ([key (find-scheme-tag d ri (decl-name decl) 'for-label)]) (let* ([start (let ([key (find-scheme-tag d ri (decl-name decl) 'for-label)])
@ -2018,12 +2026,12 @@
(let ([key (find-scheme-tag d ri i 'for-label)]) (let ([key (find-scheme-tag d ri i 'for-label)])
(and key (and key
(cons key (lookup-cls/intf d ri key))))) (cons key (lookup-cls/intf d ri key)))))
(reverse (cls/intf-intfs (cdr super))))) (append
(let ([s (and (cls/intf-super (cdr super)) (reverse (cls/intf-intfs (cdr super)))
(find-scheme-tag d ri (cls/intf-super (cdr super)) 'for-label))]) (if (cls/intf-super (cdr super))
(if s (list (cls/intf-super (cdr super)))
(list (cons s (lookup-cls/intf d ri s))) null)
null)) (reverse (cls/intf-app-mixins (cdr super))))))
(cdr supers)) (cdr supers))
(cons super accum)))]))))] (cons super accum)))]))))]
[ht (let ([ht (make-hash-table)]) [ht (let ([ht (make-hash-table)])
@ -2080,6 +2088,7 @@
"schemevaluelink" "schemevaluelink"
(list (symbol->string (syntax-e (decl-name decl)))) (list (symbol->string (syntax-e (decl-name decl))))
tag))) tag)))
(map id-info (decl-app-mixins decl))
(and (decl-super decl) (and (decl-super decl)
(not (free-label-identifier=? (quote-syntax object%) (not (free-label-identifier=? (quote-syntax object%)
(decl-super decl))) (decl-super decl)))
@ -2194,20 +2203,36 @@
(show-intfs intfs #f) (show-intfs intfs #f)
(show-intfs ranges #t))))))) (show-intfs ranges #t)))))))
(define-syntax extract-super
(syntax-rules ()
[(_ (mixin base))
(extract-super base)]
[(_ super)
(quote-syntax/loc super)]))
(define-syntax extract-app-mixins
(syntax-rules ()
[(_ (mixin base))
(cons (quote-syntax/loc mixin)
(extract-app-mixins base))]
[(_ super)
null]))
(define-syntax *defclass (define-syntax *defclass
(syntax-rules () (syntax-rules ()
[(_ *include-class name super (intf ...) body ...) [(_ *include-class name super (intf ...) body ...)
(*include-class (*include-class
(syntax-parameterize ([current-class (quote-syntax name)]) (syntax-parameterize ([current-class (quote-syntax name)])
(make-decl (quote-syntax/loc name) (make-decl (quote-syntax/loc name)
(quote-syntax/loc super) (extract-super super)
(extract-app-mixins super)
(list (quote-syntax/loc intf) ...) (list (quote-syntax/loc intf) ...)
null null
(lambda (whole-page?) (lambda (whole-page?)
(list (list
(*class-doc 'class (*class-doc 'class
(quote-syntax/loc name) (quote-syntax/loc name)
(quote-syntax super) (quote-syntax/loc super)
(list (quote-syntax intf) ...) (list (quote-syntax intf) ...)
null null
whole-page? whole-page?
@ -2231,6 +2256,7 @@
(syntax-parameterize ([current-class (quote-syntax name)]) (syntax-parameterize ([current-class (quote-syntax name)])
(make-decl (quote-syntax/loc name) (make-decl (quote-syntax/loc name)
#f #f
null
(list (quote-syntax/loc intf) ...) (list (quote-syntax/loc intf) ...)
null null
(lambda (whole-page?) (lambda (whole-page?)
@ -2261,6 +2287,7 @@
(syntax-parameterize ([current-class (quote-syntax name)]) (syntax-parameterize ([current-class (quote-syntax name)])
(make-decl (quote-syntax/loc name) (make-decl (quote-syntax/loc name)
#f #f
null
(list (quote-syntax/loc domain) ...) (list (quote-syntax/loc domain) ...)
(list (quote-syntax/loc range) ...) (list (quote-syntax/loc range) ...)
(lambda (whole-page?) (lambda (whole-page?)
@ -2394,8 +2421,9 @@
(if key (if key
(let ([v (lookup-cls/intf d ri key)]) (let ([v (lookup-cls/intf d ri key)])
(if v (if v
(cons (cls/intf-super v) (append (cls/intf-app-mixins v)
(cls/intf-intfs v)) (cons (cls/intf-super v)
(cls/intf-intfs v)))
null)) null))
null))]) null))])
(make-delayed-element (make-delayed-element
@ -2425,6 +2453,7 @@
(let ([v (resolve-get d ri `(cls/intf ,(cadr tag)))]) (let ([v (resolve-get d ri `(cls/intf ,(cadr tag)))])
(or v (or v
(make-cls/intf "unknown" (make-cls/intf "unknown"
null
#f #f
null null
null)))) null))))

View File

@ -505,7 +505,9 @@ the @scheme[read-accept-quasiquote] @tech{parameter} is set to
A @as-index{@litchar{;}} starts a line comment. When the reader A @as-index{@litchar{;}} starts a line comment. When the reader
encounters @litchar{;}, then it skips past all characters until the encounters @litchar{;}, then it skips past all characters until the
next linefeed or carriage return. next linefeed (ASCII 10), carriage return (ASCII 13), next-line
(Unicode @scheme[#x0085]), line-separator (Unicode @scheme[#x2028]),
or line-separator (Uunicode @scheme[#x2028]) character.
A @as-index{@litchar["#|"]} starts a nestable block comment. When the A @as-index{@litchar["#|"]} starts a nestable block comment. When the
reader encounters @litchar["#|"], then it skips past all characters reader encounters @litchar["#|"], then it skips past all characters

View File

@ -6279,7 +6279,7 @@ int compute_reprovides(Scheme_Hash_Table *_provided, Scheme_Hash_Table *_et_prov
Scheme_Object *nominal_modidx, *name, *modidx, *srcname, *outname, *nml, *orig_nml, *mark_src; Scheme_Object *nominal_modidx, *name, *modidx, *srcname, *outname, *nml, *orig_nml, *mark_src;
int break_outer = 0; int break_outer = 0;
name = required->keys[i]; name = required->keys[i]; /* internal symbolic name */
orig_nml = SCHEME_VEC_ELS(required->vals[i])[0]; orig_nml = SCHEME_VEC_ELS(required->vals[i])[0];
modidx = SCHEME_VEC_ELS(required->vals[i])[1]; modidx = SCHEME_VEC_ELS(required->vals[i])[1];
srcname = SCHEME_VEC_ELS(required->vals[i])[2]; srcname = SCHEME_VEC_ELS(required->vals[i])[2];
@ -6532,6 +6532,9 @@ static Scheme_Object *adjust_for_rename(Scheme_Object *out_name, Scheme_Object *
{ {
Scheme_Object *first = scheme_null, *last = NULL, *p, *a; Scheme_Object *first = scheme_null, *last = NULL, *p, *a;
if (SCHEME_STXP(in_name))
in_name = SCHEME_STX_VAL(in_name);
if (SAME_OBJ(in_name, out_name)) if (SAME_OBJ(in_name, out_name))
return noms; return noms;
@ -6595,8 +6598,8 @@ char *compute_provide_arrays(Scheme_Hash_Table *provided, Scheme_Hash_Table *req
Scheme_Object *name, *prnt_name, *v; Scheme_Object *name, *prnt_name, *v;
int protected; int protected;
v = provided->vals[i]; v = provided->vals[i]; /* external name */
name = SCHEME_CAR(v); name = SCHEME_CAR(v); /* internal name (maybe already a symbol) */
protected = SCHEME_TRUEP(SCHEME_CDR(v)); protected = SCHEME_TRUEP(SCHEME_CDR(v));
prnt_name = name; prnt_name = name;
@ -6636,7 +6639,7 @@ char *compute_provide_arrays(Scheme_Hash_Table *provided, Scheme_Hash_Table *req
exs[count] = provided->keys[i]; exs[count] = provided->keys[i];
exsns[count] = SCHEME_VEC_ELS(v)[2]; exsns[count] = SCHEME_VEC_ELS(v)[2];
exss[count] = SCHEME_VEC_ELS(v)[1]; exss[count] = SCHEME_VEC_ELS(v)[1];
noms = adjust_for_rename(exs[count], name, SCHEME_VEC_ELS(v)[0]); noms = adjust_for_rename(exs[count], SCHEME_VEC_ELS(v)[4], SCHEME_VEC_ELS(v)[0]);
exsnoms[count] = noms; exsnoms[count] = noms;
exps[count] = protected; exps[count] = protected;
count++; count++;
@ -6657,7 +6660,7 @@ char *compute_provide_arrays(Scheme_Hash_Table *provided, Scheme_Hash_Table *req
int protected; int protected;
v = provided->vals[i]; v = provided->vals[i];
name = SCHEME_CAR(v); name = SCHEME_CAR(v); /* internal name (maybe already a symbol) */
protected = SCHEME_TRUEP(SCHEME_CDR(v)); protected = SCHEME_TRUEP(SCHEME_CDR(v));
if (SCHEME_STXP(name)) { if (SCHEME_STXP(name)) {
@ -6691,7 +6694,7 @@ char *compute_provide_arrays(Scheme_Hash_Table *provided, Scheme_Hash_Table *req
exs[count] = provided->keys[i]; exs[count] = provided->keys[i];
exsns[count] = SCHEME_VEC_ELS(v)[2]; exsns[count] = SCHEME_VEC_ELS(v)[2];
exss[count] = SCHEME_VEC_ELS(v)[1]; exss[count] = SCHEME_VEC_ELS(v)[1];
noms = adjust_for_rename(exs[count], name, SCHEME_VEC_ELS(v)[0]); noms = adjust_for_rename(exs[count], SCHEME_VEC_ELS(v)[4], SCHEME_VEC_ELS(v)[0]);
exsnoms[count] = noms; exsnoms[count] = noms;
exps[count] = protected; exps[count] = protected;
count++; count++;

View File

@ -221,7 +221,8 @@ static Scheme_Object *read_lang(Scheme_Object *port, Scheme_Object *stxsrc,
long line, long col, long pos, long line, long col, long pos,
Scheme_Hash_Table **ht, Scheme_Hash_Table **ht,
Scheme_Object *indentation, Scheme_Object *indentation,
ReadParams *params); ReadParams *params,
int init_ch);
static Scheme_Object *read_compiled(Scheme_Object *port, Scheme_Object *stxsrc, static Scheme_Object *read_compiled(Scheme_Object *port, Scheme_Object *stxsrc,
long line, long col, long pos, long line, long col, long pos,
Scheme_Hash_Table **ht, Scheme_Hash_Table **ht,
@ -321,6 +322,20 @@ static unsigned char delim[128];
#define HONU_INUM_OK 0x10 #define HONU_INUM_OK 0x10
#define HONU_INUM_SIGN_OK 0x20 #define HONU_INUM_SIGN_OK 0x20
#define is_lang_nonsep_char(ch) (scheme_isalpha(ch) \
|| scheme_isdigit(ch) \
|| ((ch) == '-') \
|| ((ch) == '+') \
|| ((ch) == '_'))
#define NEXT_LINE_CHAR 0x85
#define LINE_SEPARATOR_CHAR 0x2028
#define PARAGRAPH_SEPARATOR_CHAR 0x2029
#define is_line_comment_end(ch) ((ch == '\n') || (ch == '\r') \
|| (ch == NEXT_LINE_CHAR) \
|| (ch == LINE_SEPARATOR_CHAR) \
|| (ch == PARAGRAPH_SEPARATOR_CHAR))
/*========================================================================*/ /*========================================================================*/
/* initialization */ /* initialization */
/*========================================================================*/ /*========================================================================*/
@ -1019,7 +1034,8 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table *
else else
return honu_semicolon; return honu_semicolon;
} else { } else {
while (((ch = scheme_getc_special_ok(port)) != '\n') && (ch != '\r')) { while (((ch = scheme_getc_special_ok(port)) != '\n')
&& !is_line_comment_end(ch)) {
if (ch == EOF) { if (ch == EOF) {
if (comment_mode & RETURN_FOR_COMMENT) if (comment_mode & RETURN_FOR_COMMENT)
return NULL; return NULL;
@ -1358,7 +1374,7 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table *
"read: #lang expressions not currently enabled"); "read: #lang expressions not currently enabled");
return NULL; return NULL;
} }
v = read_lang(port, stxsrc, line, col, pos, ht, indentation, params); v = read_lang(port, stxsrc, line, col, pos, ht, indentation, params, 0);
if (!v) { if (!v) {
if (comment_mode & RETURN_FOR_SPECIAL_COMMENT) if (comment_mode & RETURN_FOR_SPECIAL_COMMENT)
return NULL; return NULL;
@ -1622,6 +1638,15 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table *
if (comment_mode & RETURN_FOR_COMMENT) if (comment_mode & RETURN_FOR_COMMENT)
return NULL; return NULL;
goto start_over; goto start_over;
} else if ((ch < 128) && is_lang_nonsep_char(ch)) {
Scheme_Object *v;
v = read_lang(port, stxsrc, line, col, pos, ht, indentation, params, ch);
if (!v) {
if (comment_mode & RETURN_FOR_SPECIAL_COMMENT)
return NULL;
goto start_over;
}
return v;
} else { } else {
if (NOT_EOF_OR_SPECIAL(ch)) if (NOT_EOF_OR_SPECIAL(ch))
scheme_read_err(port, stxsrc, line, col, pos, 3, scheme_read_err(port, stxsrc, line, col, pos, 3,
@ -3973,7 +3998,7 @@ skip_whitespace_comments(Scheme_Object *port, Scheme_Object *stxsrc,
ch = scheme_getc_special_ok(port); ch = scheme_getc_special_ok(port);
if (ch == SCHEME_SPECIAL) if (ch == SCHEME_SPECIAL)
scheme_get_ready_read_special(port, stxsrc, ht); scheme_get_ready_read_special(port, stxsrc, ht);
} while (ch != '\n' && ch != '\r' && ch != EOF); } while (!is_line_comment_end(ch) && ch != EOF);
goto start_over; goto start_over;
} }
@ -5919,11 +5944,12 @@ static Scheme_Object *read_reader(Scheme_Object *port,
return do_reader(modpath, port, stxsrc, line, col, pos, ht, indentation, params); return do_reader(modpath, port, stxsrc, line, col, pos, ht, indentation, params);
} }
/* "#lang" has been read */ /* "#lang " has been read */
static Scheme_Object *read_lang(Scheme_Object *port, static Scheme_Object *read_lang(Scheme_Object *port,
Scheme_Object *stxsrc, long line, long col, long pos, Scheme_Object *stxsrc, long line, long col, long pos,
Scheme_Hash_Table **ht, Scheme_Hash_Table **ht,
Scheme_Object *indentation, ReadParams *params) Scheme_Object *indentation, ReadParams *params,
int init_ch)
{ {
int size, len; int size, len;
GC_CAN_IGNORE char *sfx; GC_CAN_IGNORE char *sfx;
@ -5936,7 +5962,10 @@ static Scheme_Object *read_lang(Scheme_Object *port,
len = 0; len = 0;
while (1) { while (1) {
ch = scheme_getc_special_ok(port); if (!len && init_ch) {
ch = init_ch;
} else
ch = scheme_getc_special_ok(port);
if (ch == EOF) { if (ch == EOF) {
break; break;
} else if (ch == SCHEME_SPECIAL) { } else if (ch == SCHEME_SPECIAL) {
@ -5946,11 +5975,7 @@ static Scheme_Object *read_lang(Scheme_Object *port,
break; break;
} else { } else {
if ((ch < 128) if ((ch < 128)
&& (scheme_isalpha(ch) && (is_lang_nonsep_char(ch)
|| scheme_isdigit(ch)
|| (ch == '-')
|| (ch == '+')
|| (ch == '_')
|| (ch == '/'))) { || (ch == '/'))) {
if (len + 1 >= size) { if (len + 1 >= size) {
size *= 2; size *= 2;
@ -5962,7 +5987,8 @@ static Scheme_Object *read_lang(Scheme_Object *port,
} else { } else {
scheme_read_err(port, stxsrc, line, col, pos, SPAN(port, pos), ch, indentation, scheme_read_err(port, stxsrc, line, col, pos, SPAN(port, pos), ch, indentation,
"read: expected only alphanumberic, `-', `+', `_', or `/'" "read: expected only alphanumberic, `-', `+', `_', or `/'"
" characters for `#lang', found %c", " characters for `#%s', found %c",
init_ch ? "!" : "lang",
ch); ch);
return NULL; return NULL;
} }
@ -5971,9 +5997,10 @@ static Scheme_Object *read_lang(Scheme_Object *port,
if (!len) { if (!len) {
scheme_read_err(port, stxsrc, line, col, pos, SPAN(port, pos), ch, indentation, scheme_read_err(port, stxsrc, line, col, pos, SPAN(port, pos), ch, indentation,
((ch == ' ') (((ch == ' ') && !init_ch)
? "read: expected a single space after `#lang'" ? "read: expected a single space after `#lang'"
: "read: expected a non-empty sequence of alphanumberic, `-', `+', `_', or `/' after `#lang '")); : "read: expected a non-empty sequence of alphanumberic, `-', `+', `_', or `/' after `#%s'"),
init_ch ? "!" : "lang ");
return NULL; return NULL;
} }
if (buf[0] == '/') { if (buf[0] == '/') {
@ -5983,7 +6010,8 @@ static Scheme_Object *read_lang(Scheme_Object *port,
} }
if (buf[len - 1] == '/') { if (buf[len - 1] == '/') {
scheme_read_err(port, stxsrc, line, col, pos, SPAN(port, pos), ch, indentation, scheme_read_err(port, stxsrc, line, col, pos, SPAN(port, pos), ch, indentation,
"read: expected a name that does not end `/' after `#lang'"); "read: expected a name that does not end `/' after `#%s'",
init_ch ? "!" : "lang");
return NULL; return NULL;
} }

View File

@ -10,12 +10,12 @@
The string and the separate X/Y/Z/W numbers must The string and the separate X/Y/Z/W numbers must
be updated consistently. */ be updated consistently. */
#define MZSCHEME_VERSION "3.99.0.11" #define MZSCHEME_VERSION "3.99.0.12"
#define MZSCHEME_VERSION_X 3 #define MZSCHEME_VERSION_X 3
#define MZSCHEME_VERSION_Y 99 #define MZSCHEME_VERSION_Y 99
#define MZSCHEME_VERSION_Z 0 #define MZSCHEME_VERSION_Z 0
#define MZSCHEME_VERSION_W 11 #define MZSCHEME_VERSION_W 12
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)