Merge branch 'master' of github.com:racket/racket

This commit is contained in:
Georges Dupéron 2015-10-30 13:52:53 +01:00
commit cd3e069d37
505 changed files with 25586 additions and 11761 deletions

View File

@ -25,9 +25,13 @@ matrix:
compiler: gcc
env: PATH=./racket/bin:$PATH RACKET_CONFIGURE_ARGS="--disable-jit --disable-places
--disable-futures --disable-extflonum"
before_script:
- git config --global user.email "travis-test@racket-lang.org"
- git config --global user.name "Travis Tester"
script:
- make CPUS="2" PKGS="racket-test db-test unstable-flonum-lib net-test" CONFIGURE_ARGS_qq="$RACKET_CONFIGURE_ARGS"
- raco test -l tests/racket/test
- racket -l tests/pkg/test -- -q
- racket -l tests/racket/contract/all
- raco test -l tests/json/json
- raco test -l tests/file/main

View File

@ -1,8 +1,8 @@
Build Options
=============
For Unix platforms, instead of using this source repository, consider
getting source for the current Racket release from
Instead of using this source repository, consider getting source for
the current Racket release from
http://download.racket-lang.org/
@ -16,7 +16,9 @@ documentation are pre-built.
In contrast to this repository, release and snapshot source
distributions will work in the
configure --prefix=... && make && make install
way that you probably expect.
@ -31,7 +33,7 @@ If you stick with this repository, then you have several options:
Instructions: In-place Build" below.
* Unix-style install --- installs to a given destination directory
(Unix and Mac OS X, only), leaving no reference to the source
(on platforms other Windows), leaving no reference to the source
directory. This is the most natural mode for installing once from
the source repository. See "Quick Instructions: Unix-style Install"
below.
@ -51,11 +53,11 @@ If you stick with this repository, then you have several options:
Quick Instructions: In-place Build
==================================
On Unix, `make' (or `make in-place') creates a build in the "racket"
directory.
On Unix (including Linux) and Mac OS X, `make' (or `make in-place')
creates a build in the "racket" directory.
On Windows with Microsoft Visual Studio (any version between 2008/9.0
and 2013/12.0), `nmake win32-in-place' creates a build in the "racket"
and 2015/14.0), `nmake win32-in-place' creates a build in the "racket"
directory. For information on configuring your command-line
environment for Visual Studio, see "racket/src/worksp/README".
@ -74,10 +76,10 @@ See "More Instructions: Building Racket" below for more information.
Quick Instructions: Unix-style Install
======================================
On Unix, `make unix-style PREFIX=<dir>' builds and installs into
"<dir>" (which must be an absolute path) with binaries in "<dir>/bin",
packages in "<dir>/share/racket/pkgs", documentation in
"<dir>/share/racket/doc", etc.
On Unix (including Linux), `make unix-style PREFIX=<dir>' builds and
installs into "<dir>" (which must be an absolute path) with binaries
in "<dir>/bin", packages in "<dir>/share/racket/pkgs", documentation
in "<dir>/share/racket/doc", etc.
On Mac OS X, `make unix-style PREFIX=<dir>' builds and installs into
"<dir>" (whichmust be an absolute path) with binaries in "<dir>/bin",
@ -128,6 +130,12 @@ previously installed packages remain installed and are updated, while
new packages are added. To uninstall previously selected package, use
`raco pkg remove'.
To build anything other than the latest sources in the repository
(e.g., when building from the "v6.2.1" tag), you need a catalog
that's compatible with those sources. Note that a release distribution
is configured to use a catalog specific to that release, so you can
extract the catalog's URL from there.
Using `make' (or `make in-place') sets the installation's name to
"development", unless the installation has been previously configured
(i.e., unless the "racket/etc/config.rktd" file exists). The
@ -181,10 +189,17 @@ but under Windows, encoding-conversion, extflonum, and SSL
functionality is hobbled until native libraries from the
`racket-win32-i386' or `racket-win32-x86_64' package are installed.
On all platforms, `JOB_OPTIONS' as a makefile variable and
`PLT_SETUP_OPTIONS' as an environment variable are passed on to the
`raco setup' that is used to build minimal-Racket libraries. See the
documentation for `raco setup' for information on the options.
On all platforms, fom the top-level makefile, `JOB_OPTIONS' as a
makefile variable and `PLT_SETUP_OPTIONS' as an environment variable
are passed on to the `raco setup' that is used to build minimal-Racket
libraries. See the documentation for `raco setup' for information on
the options.
For cross compilation, add configuration options to
`CONFIGURE_ARGS_qq="..."' as descibed in the "README" of "racket/src",
but also add a `PLAIN_RACKET=...' argument for the top-level makefile
to specify the same executable as in an `--enable-racket=...' for
`configure'.
Installing Packages
-------------------
@ -305,8 +320,8 @@ where <dist-base> defaults to "racket" (but can be set via
normalizing the Windows results to "i386-win32" and "x86_63-win32",
-<dist-suffix> is omitted unless a `#:dist-suffix' string is specified
for the client in the site configuration, and <ext> is
platform-specific: ".sh" for Unix, ".dmg" or ".pkg" for Mac OS X, and
".exe" for Windows.
platform-specific: ".sh" for Unix (including Linux), ".dmg" or ".pkg"
for Mac OS X, and ".exe" for Windows.
Generating Installer Web Sites
------------------------------
@ -475,8 +490,8 @@ In more detail:
To change the base name of the installer file, provide `DIST_BASE'
to `make'. The default is "racket".
To change the directory name for Unix installation, provide
`DIST_DIR' to `make'. The default is "racket".
To change the directory name for installation on Unix (including
Linux), provide `DIST_DIR' to `make'. The default is "racket".
To add an extra piece to the installer's name, such as an
identifier for a variant of Linux, provide `DIST_SUFFIX' to

View File

@ -29,14 +29,15 @@ PKGS = main-distribution main-distribution-test
PLAIN_RACKET = racket/bin/racket
WIN32_PLAIN_RACKET = racket\racket
PLAIN_RACO = racket/bin/racket -N raco -l- raco
WIN32_PLAIN_RACO = racket\racket -N raco -l- raco
# In case of cross-installation, point explicitly to local content:
RUN_RACKET = $(PLAIN_RACKET) -G racket/etc -X racket/collects
WIN32_RUN_RACKET = $(WIN32_PLAIN_RACKET) -G racket/etc -X racket/collects
RUN_RACO = $(RUN_RACKET) -N raco -l- raco
WIN32_RUN_RACO = $(WIN32_RUN_RACKET) -N raco -l- raco
DEFAULT_SRC_CATALOG = http://pkgs.racket-lang.org
MACOSX_CHECK_ARGS = -I racket/base -e '(case (system-type) [(macosx) (exit 0)] [else (exit 1)])'
MACOSX_CHECK = $(PLAIN_RACKET) -G build/config $(MACOSX_CHECK_ARGS)
CPUS =
in-place:
@ -61,18 +62,18 @@ ALL_PLT_SETUP_OPTIONS = $(JOB_OPTIONS) $(PLT_SETUP_OPTIONS)
plain-in-place:
$(MAKE) base
$(MAKE) pkgs-catalog
$(PLAIN_RACO) pkg update $(UPDATE_PKGS_ARGS)
$(PLAIN_RACO) pkg install $(INSTALL_PKGS_ARGS)
$(PLAIN_RACO) setup --only-foreign-libs $(ALL_PLT_SETUP_OPTIONS)
$(PLAIN_RACO) setup $(ALL_PLT_SETUP_OPTIONS)
$(RUN_RACO) pkg update $(UPDATE_PKGS_ARGS)
$(RUN_RACO) pkg install $(INSTALL_PKGS_ARGS)
$(RUN_RACO) setup --only-foreign-libs $(ALL_PLT_SETUP_OPTIONS)
$(RUN_RACO) setup $(ALL_PLT_SETUP_OPTIONS)
win32-in-place:
$(MAKE) win32-base
$(MAKE) win32-pkgs-catalog
$(WIN32_PLAIN_RACO) pkg update $(UPDATE_PKGS_ARGS)
$(WIN32_PLAIN_RACO) pkg install $(INSTALL_PKGS_ARGS)
$(WIN32_PLAIN_RACO) setup --only-foreign-libs $(ALL_PLT_SETUP_OPTIONS)
$(WIN32_PLAIN_RACO) setup $(ALL_PLT_SETUP_OPTIONS)
$(WIN32_RUN_RACO) pkg update $(UPDATE_PKGS_ARGS)
$(WIN32_RUN_RACO) pkg install $(INSTALL_PKGS_ARGS)
$(WIN32_RUN_RACO) setup --only-foreign-libs $(ALL_PLT_SETUP_OPTIONS)
$(WIN32_RUN_RACO) setup $(ALL_PLT_SETUP_OPTIONS)
# Rebuild without consulting catalogs or package sources:
@ -86,11 +87,11 @@ cpus-as-is:
plain-as-is:
$(MAKE) base
$(PLAIN_RACO) setup $(ALL_PLT_SETUP_OPTIONS)
$(RUN_RACO) setup $(ALL_PLT_SETUP_OPTIONS)
win32-as-is:
$(MAKE) win32-base
$(WIN32_PLAIN_RACO) setup $(ALL_PLT_SETUP_OPTIONS)
$(WIN32_RUN_RACO) setup $(ALL_PLT_SETUP_OPTIONS)
# ------------------------------------------------------------
# Unix-style build (Unix and Mac OS X, only)
@ -171,6 +172,17 @@ win32-remove-setup-dlls:
racket/src/build/Makefile: racket/src/configure racket/src/Makefile.in
cd racket/src/build; ../configure $(CONFIGURE_ARGS_qq)
# For cross-compilation, build a native executable with no configure options:
native-for-cross:
mkdir -p racket/src/build/cross
$(MAKE) racket/src/build/cross/Makefile
cd racket/src/build/cross; $(MAKE) reconfigure
cd racket/src/build/cross/racket; $(MAKE)
racket/src/build/cross/Makefile: racket/src/configure racket/src/Makefile.in
cd racket/src/build/cross; ../../configure
# ------------------------------------------------------------
# Configuration options for building installers
@ -299,11 +311,11 @@ SVR_PRT = $(SERVER):$(SERVER_PORT)
SVR_CAT = http://$(SVR_PRT)/$(SERVER_CATALOG_PATH)
# Helper macros:
USER_CONFIG = -G build/user/config -A build/user
RACKET = racket/bin/racket $(USER_CONFIG)
RACO = racket/bin/racket $(USER_CONFIG) -N raco -l- raco
WIN32_RACKET = racket\racket $(USER_CONFIG)
WIN32_RACO = racket\racket $(USER_CONFIG) -N raco -l- raco
USER_CONFIG = -G build/user/config -X racket/collects -A build/user
RACKET = $(PLAIN_RACKET) $(USER_CONFIG)
RACO = $(PLAIN_RACKET) $(USER_CONFIG) -N raco -l- raco
WIN32_RACKET = $(WIN32_PLAIN_RACKET) $(USER_CONFIG)
WIN32_RACO = $(WIN32_PLAIN_RACKET) $(USER_CONFIG) -N raco -l- raco
X_AUTO_OPTIONS = --skip-installed --deps search-auto --pkgs $(JOB_OPTIONS)
USER_AUTO_OPTIONS = --scope user $(X_AUTO_OPTIONS)
LOCAL_USER_AUTO = --catalog build/local/catalog $(USER_AUTO_OPTIONS)
@ -312,9 +324,9 @@ REMOTE_USER_AUTO = --catalog $(SVR_CAT) $(USER_AUTO_OPTIONS)
REMOTE_INST_AUTO = --catalog $(SVR_CAT) --scope installation $(X_AUTO_OPTIONS)
CONFIG_MODE_q = "$(CONFIG)" "$(CONFIG_MODE)"
BUNDLE_CONFIG = bundle/racket/etc/config.rktd
BUNDLE_RACO_FLAGS = -A bundle/user -l raco
BUNDLE_RACO = bundle/racket/bin/racket $(BUNDLE_RACO_FLAGS)
WIN32_BUNDLE_RACO = bundle\racket\racket $(BUNDLE_RACO_FLAGS)
BUNDLE_RACO_FLAGS = -G bundle/racket/config -X bundle/racket/collects -A bundle/user -l raco
BUNDLE_RACO = $(PLAIN_RACKET) $(BUNDLE_RACO_FLAGS)
WIN32_BUNDLE_RACO = $(WIN32_PLAIN_RACKET) $(BUNDLE_RACO_FLAGS)
# ------------------------------------------------------------
# Linking all packages (development mode; not an installer build)
@ -323,9 +335,9 @@ PKGS_CATALOG = -U -G build/config -l- pkg/dirs-catalog --link --check-metadata
PKGS_CONFIG = -U -G build/config racket/src/pkgs-config.rkt
pkgs-catalog:
$(PLAIN_RACKET) $(PKGS_CATALOG) racket/share/pkgs-catalog pkgs
$(PLAIN_RACKET) $(PKGS_CONFIG) "$(DEFAULT_SRC_CATALOG)" "$(SRC_CATALOG)"
$(PLAIN_RACKET) racket/src/pkgs-check.rkt racket/share/pkgs-catalog
$(RUN_RACKET) $(PKGS_CATALOG) racket/share/pkgs-catalog pkgs
$(RUN_RACKET) $(PKGS_CONFIG) "$(DEFAULT_SRC_CATALOG)" "$(SRC_CATALOG)"
$(RUN_RACKET) racket/src/pkgs-check.rkt racket/share/pkgs-catalog
win32-pkgs-catalog:
$(MAKE) pkgs-catalog PLAIN_RACKET="$(WIN32_PLAIN_RACKET)"
@ -428,7 +440,7 @@ binary-catalog-server:
# client is the same as the server.
PROP_ARGS = SERVER=$(SERVER) SERVER_PORT=$(SERVER_PORT) SERVER_HOSTS="$(SERVER_HOSTS)" \
PKGS="$(PKGS)" BUILD_STAMP="$(BUILD_STAMP)" \
PKGS="$(PKGS)" PLAIN_RACKET="$(PLAIN_RACKET)" BUILD_STAMP="$(BUILD_STAMP)" \
RELEASE_MODE=$(RELEASE_MODE) SOURCE_MODE=$(SOURCE_MODE) \
VERSIONLESS_MODE=$(VERSIONLESS_MODE) MAC_PKG_MODE=$(MAC_PKG_MODE) \
PKG_SOURCE_MODE="$(PKG_SOURCE_MODE)" INSTALL_NAME="$(INSTALL_NAME)"\
@ -476,6 +488,8 @@ bundle-from-server:
rm -rf bundle
mkdir -p bundle/racket
$(RACKET) -l setup/unixstyle-install bundle racket bundle/racket
$(RACKET) -l setup/winstrip bundle/racket
$(RACKET) -l setup/winvers-change bundle/racket
$(RACKET) -l distro-build/unpack-collects http://$(SVR_PRT)/$(SERVER_COLLECTS_PATH)
$(BUNDLE_RACO) pkg install $(REMOTE_INST_AUTO) $(PKG_SOURCE_MODE) $(REQUIRED_PKGS)
$(BUNDLE_RACO) pkg install $(REMOTE_INST_AUTO) $(PKG_SOURCE_MODE) $(PKGS)

View File

@ -5,7 +5,7 @@ License
-------
Racket
Copyright (c) 2010-2014 PLT Design Inc.
Copyright (c) 2010-2015 PLT Design Inc.
Racket is distributed under the GNU Lesser General Public License
(LGPL). This implies that you may link Racket into proprietary

View File

@ -1,5 +1,5 @@
at-exp-lib
Copyright (c) 2010-2014 PLT Design Inc.
Copyright (c) 2010-2015 PLT Design Inc.
This package is distributed under the GNU Lesser General Public
License (LGPL). This means that you can link this package into proprietary

View File

@ -1,5 +1,5 @@
base
Copyright (c) 2010-2014 PLT Design Inc.
Copyright (c) 2010-2015 PLT Design Inc.
This package is distributed under the GNU Lesser General Public
License (LGPL). This means that you can link this package into proprietary

View File

@ -12,7 +12,7 @@
(define collection 'multi)
(define version "6.2.900.6")
(define version "6.3.0.2")
(define deps `("racket-lib"
["racket" #:version ,version]))

View File

@ -6,7 +6,6 @@
"compatibility-lib"
"r5rs-lib"
"scheme-lib"
"srfi-lite-lib"
"racket-test"
"typed-racket-lib"
"gui-lib"))

View File

@ -10,7 +10,7 @@
(module pct1 racket/base
(require racket/place
racket/match
"place-utils.rkt")
tests/racket/place-utils)
(provide place-main)
(define (place-main ch)
@ -48,7 +48,7 @@ END
#<<END
(module pct1 racket/base
(require racket/place
"place-utils.rkt")
tests/racket/place-utils)
(provide place-main)
(require algol60/parse
(for-syntax racket/base

View File

@ -7,9 +7,6 @@
#lang racket/base
(require (only-in srfi/13 string-index string-pad-right)
(only-in mzlib/string real->decimal-string))
(define IM 139968)
(define IA 3877)
(define IC 29573)

View File

@ -5,9 +5,6 @@
;;
;; Updated by Brent Fulgham to provide proper output formatting
(require (only-in srfi/13 string-index string-pad-right)
(only-in mzlib/string real->decimal-string))
(define IM 139968)
(define IA 3877)
(define IC 29573)

View File

@ -1,5 +1,5 @@
racket-doc
Copyright (c) 2010-2014 PLT Design Inc.
Copyright (c) 2010-2015 PLT Design Inc.
This package is distributed under the GNU Lesser General Public
License (LGPL). This means that you can link this package into proprietary

View File

@ -9,7 +9,8 @@
dynext/link-unit
dynext/link-sig
dynext/file-unit
dynext/file-sig))
dynext/file-sig
compiler/module-suffix))
@title{Dynext: Running a C Compiler/Linker}
@ -359,7 +360,11 @@ Appends the platform-standard dynamic-extension file suffix to
(or/c path? false/c)]{
Strips the Racket file suffix from @racket[s] and returns a stripped
path. Unlike the other functions below, when @racket[program] is not
path. The recognized suffixes are the ones reported by
@racket[(get-module-suffixes #:group 'libs)] when
@racket[extract-base-filename/ss] is first called.
Unlike the other functions below, when @racket[program] is not
@racket[#f], then any suffix (including no suffix) is allowed. If
@racket[s] is not a Racket file and @racket[program] is @racket[#f],
@racket[#f] is returned.}

View File

@ -31,7 +31,7 @@ should be considered standard:
and eight numbers; like @racket['png-bytes+bounds], but where
the image encoded that is in the byte string can be padded in
each direction (to allow the drawn region to extend beyond
it's ``bounding box''), where the extra four numbers in the
its ``bounding box''), where the extra four numbers in the
list specify the amount of padding that was added to the
image: left, right, top, and bottom}
@item{@racket['png@2x-bytes] --- like @racket['png-bytes], but for an

View File

@ -10,7 +10,8 @@ and writing @filepath{.ico} files, which contain one or more icons.
Each icon is up to 256 by 256 pixels, has a particular depth (i.e.,
bits per pixel used to represent a color), and mask (i.e., whether a
pixel is shown, except that the mask may be ignored for 32-bit icons
that have an alpha value per pixel).
that have an alpha value per pixel). The library also provides support
for reading and writing icons in Windows executables.
@defproc[(ico? [v any/c]) boolean?]{
@ -18,25 +19,40 @@ Returns @racket[#t] if @racket[v] represents an icon, @racket[#f]
otherwise.}
@deftogether[(
@defproc[(ico-width [ico ico?]) (integer-in 1 256)]
@defproc[(ico-height [ico ico?]) (integer-in 1 256)]
@defproc[(ico-width [ico ico?]) exact-positive-integer?]
@defproc[(ico-height [ico ico?]) exact-positive-integer?]
@defproc[(ico-depth [ico ico?]) (one-of/c 1 2 4 8 16 24 32)]
)]{
Returns the width or height of an icon in pixels, or the depth in bits per
pixel.}
pixel.
@history[#:changed "6.3" @elem{A PNG-format icon can have a
width or height greater than 256.}]}
@deftogether[(
@defproc[(ico-format [ico ico?]) (or/c 'bmp 'png)]
)]{
Reports the format of the icon.
@history[#:added "6.3"]}
@defproc[(read-icos [src (or/c path-string? input-port?)])
(listof ico?)]{
Parses @racket[src] as an @filepath{.ico} to extract a list of icons.}
@defproc[(read-icos-from-exe [src (or/c path-string? input-port?)])
(listof ico?)]{
Parses @racket[src] as an @filepath{.exe} to extract the list of
icons that represent the Windows executable.}
@defproc[(write-icos [icos (listof ico?)]
[dest (or/c path-string? output-port?)]
[#:exists exists (or/c 'error 'append 'update 'can-update
@ -50,22 +66,46 @@ Writes each icon in @racket[icos] to @racket[dest] as an
@racket[exists] is passed on to @racket[open-output-file] to open
@racket[dest] for writing.}
@defproc[(replace-icos [icos (listof ico?)]
[dest (or/c path-string? output-port?)])
[dest path-string?])
void?]{
Writes icons in @racket[icos] to replace icons in @racket[dest] as an
Windows executable. Only existing icon sizes and depths in the
executable are replaced, and best matches for the existing sizes and
depth are drawn from @racket[icos] (adjusting the scale and depth f a
best match as necessary).}
executable are replaced, and only when the encoding sizes match.
Best matches for the existing sizes and
depth are drawn from @racket[icos] (adjusting the scale and depth of a
best match as necessary).
Use @racket[replace-all-icos], instead, to replace a set of icons
wholesale, especially when the set include PNG-format icons.}
@defproc[(replace-all-icos [icos (listof ico?)]
[dest (or/c path-string? output-port?)])
void?]{
Replaces the icon set in the executable @racket[dest] with the given
set of icons.}
@defproc[(ico->argb [ico ico?]) bytes?]{
Converts an icon to an ARGB byte string, which has the icon's pixels
Converts an icon in BMP format (see @racket[ico-format])
to an ARGB byte string, which has the icon's pixels
in left-to-right, top-to-bottom order, with four bytes (alpha, red,
green, and blue channels) for each pixel.}
@defproc[(ico->png-bytes [ico ico?]) bytes?]{
Returns the bytes of a PNG encoding for an icon in PNG format (see
@racket[ico-format]).
@history[#:added "6.3"]}
@defproc[(argb->ico [width (integer-in 1 256)]
[height (integer-in 1 256)]
[bstr bytes?]
@ -73,7 +113,16 @@ green, and blue channels) for each pixel.}
ico?]{
Converts an ARGB byte string (in the same format as from
@racket[ico->argb]) to an icon of the given width, height, and depth.
@racket[ico->argb]) to an icon of the given width, height, and depth
in BMP format.
The @racket[bstr] argument must have a length @racket[(* 4 width height)],
and @racket[(* width depth)] must be a multiple of 8.}
@defproc[(png-bytes->ico [bstr bytes?])
ico?]{
Wraps the given PNG encoding as a PNG-encoded icon.
@history[#:added "6.3"]}

View File

@ -9,6 +9,7 @@ a function to extract items from a TAR/USTAR archive.}
@defproc[(untar [in (or/c path-string? input-port?)]
[#:dest dest-path (or/c path-string? #f) #f]
[#:strip-count strip-count exact-nonnegative-integer? 0]
[#:permissive? permissive? any/c #f]
[#:filter filter-proc
(path? (or/c path? #f)
symbol? exact-integer? (or/c path? #f)
@ -28,6 +29,12 @@ elements are removed from the item path from the archive (before
prefixing the path with @racket[dest-path]); if the item's path
contains @racket[strip-count] elements, then it is not extracted.
Unless @racket[permissive?] is true, then archive items with paths containing
an up-directory indicator are disallowed, and a link item whose target
is an absolute path or contains an up-directory indicator is also
disallowed. Absolute paths are always disallowed. A disallowed
path triggers an exception.
For each item in the archive, @racket[filter-proc] is applied to
@itemlist[
@ -60,4 +67,6 @@ For each item in the archive, @racket[filter-proc] is applied to
]
If the result of @racket[filter-proc] is @racket[#f], then the item is
not unpacked.}
not unpacked.
@history[#:changed "6.3" @elem{Added the @racket[#:permissive?] argument.}]}

View File

@ -11,6 +11,7 @@ a function to extract items from a possible @exec{gzip}ped TAR/USTAR archive.}
@defproc[(untgz [in (or/c path-string? input-port?)]
[#:dest dest-path (or/c path-string? #f) #f]
[#:strip-count strip-count exact-nonnegative-integer? 0]
[#:permissive? permissive? any/c #f]
[#:filter filter-proc
(path? (or/c path? #f)
symbol? exact-integer? (or/c path? #f)
@ -21,4 +22,6 @@ a function to extract items from a possible @exec{gzip}ped TAR/USTAR archive.}
void?]{
The same as @racket[untar], but if @racket[in] is in @exec{gzip} form,
it is @racket[gunzip]ped as it is unpacked.}
it is @racket[gunzip]ped as it is unpacked.
@history[#:changed "6.3" @elem{Added the @racket[#:permissive?] argument.}]}

View File

@ -50,6 +50,7 @@ directory while returning the result of @racket[proc].
@defproc[(make-filesystem-entry-reader
[#:dest dest-path (or/c path-string? #f) #f]
[#:strip-count strip-count exact-nonnegative-integer? 0]
[#:permissive? permissive? any/c #f]
[#:exists exists (or/c 'skip 'error 'replace 'truncate
'truncate/replace 'append 'update
'can-update 'must-truncate)
@ -72,13 +73,21 @@ elements are removed from the entry path from the archive (before
prefixing the path with @racket[dest-path]); if the item's path
contains @racket[strip-count] elements, then it is not extracted.
Unless @racket[permissive?] is true, then entries with paths containing
an up-directory indicator are disallowed, and a link entry whose target
is an absolute path or contains an up-directory indicator is also
disallowed. Absolute paths are always disallowed. A disallowed
path triggers an exception.
If @racket[exists] is @racket['skip] and the file for an entry already
exists, then the entry is skipped. Otherwise, @racket[exists] is
passed on to @racket[open-output-file] for writing the entry's
inflated content.
@history[#:changed "6.0.0.3"
@elem{Added support for the optional timestamp argument in the result function.}]}
@elem{Added support for the optional timestamp argument in the result function.}
#:changed "6.3"
@elem{Added the @racket[#:permissive?] argument.}]}
@defproc[(read-zip-directory [in (or/c path-string? input-port?)]) zip-directory?]{

View File

@ -4,7 +4,10 @@
(for-label openssl
racket
openssl/sha1
openssl/md5))
openssl/md5
openssl/libcrypto
openssl/libssl
(only-in ffi/unsafe ffi-lib ffi-lib?)))
@title{OpenSSL: Secure Communication}
@ -820,3 +823,58 @@ The @racket[md5] function composes @racket[bytes->hex-string] with
Returns a 16-byte byte string that represents the MD5 hash of the
content from @racket[in], consuming all of the input from @racket[in]
until an end-of-file.}
@; ----------------------------------------------------------------------
@(define foreign-doc '(lib "scribblings/foreign/foreign.scrbl"))
@section[#:tag "libcrypto"]{The @filepath{libcrypto} Shared Library}
@defmodule[openssl/libcrypto]{The @racketmodname[openssl/libcrypto]
library provides a @tech[#:doc foreign-doc]{foreign-library value} for
the @filepath{libcrypto} shared library.}
@defthing[libcrypto (or/c #f ffi-lib?)]{
Returns a @tech[#:doc foreign-doc]{foreign-library value} for
@filepath{libcrypto}, or @racket[#f] if the library could not be found
or loaded. The load attempt uses the versions specified by
@racket[openssl-lib-versions].}
@defthing[libcrypto-load-fail-reason (or/c #f string?)]{
Either @racket[#f] when @racket[libcrypto] is non-@racket[#f], or a
string when @racket[libcrypto] is @racket[#f]. In the latter case, the
string provides an error message for the attempt to load
@filepath{libcrypto}.}
@defthing[openssl-lib-versions (listof string?)]{
A list of versions that are tried for loading @filepath{libcrypto}.
The list of version strings is suitable as a second argument to
@racket[ffi-lib].}
@; ----------------------------------------------------------------------
@section[#:tag "libssl"]{The @filepath{libssl} Shared Library}
@defmodule[openssl/libssl]{The @racketmodname[openssl/libssl]
library provides a @tech[#:doc foreign-doc]{foreign-library value} for
the @filepath{libssl} shared library.}
@defthing[libssl (or/c #f ffi-lib?)]{
Returns a @tech[#:doc foreign-doc]{foreign-library value} for
@filepath{libssl}, or @racket[#f] if the library could not be found
or loaded. The load attempt uses the versions specified by
@racket[openssl-lib-versions].}
@defthing[libssl-load-fail-reason (or/c #f string?)]{
Either @racket[#f] when @racket[libssl] is non-@racket[#f], or a
string when @racket[libssl] is @racket[#f]. In the latter case, the
string provides an error message for the attempt to load
@filepath{libssl}.}

View File

@ -103,6 +103,18 @@ used.
@history[#:added "6.1.1.6"]}
@deftogether[(
@defparam[current-pkg-network-retries max-retries (or/c #f real?)]
)]{
A parameter that determines the number of times to retry a network communication
that fails due to a connection error. If
a parameter's value is @racket[#f], then the user's configuration is
used.
@history[#:added "6.3"]}
@defproc[(pkg-directory [name string?]
[#:cache cache (or/c #f (and/c hash? (not/c immutable?))) #f])
(or/c path-string? #f)]{
@ -678,7 +690,7 @@ represented by @racket[dir] and named @racket[pkg-name].}
[pkg-name string]
[#:namespace namespace namespace? (make-base-namespace)]
[#:system-type sys-type (or/c #f symbol?) (system-type)]
[#:system-library-subpath sys-lib-subpath (or/c #f path?)
[#:system-library-subpath sys-lib-subpath (or/c #f path-for-some-system?)
(system-library-subpath #f)])
(listof (cons/c symbol? string?))]{

View File

@ -285,8 +285,8 @@ is a GitHub package source.
@margin-note{A Github repository source that starts with
@litchar{git://} obtains the same content that would be accessed if
@litchar{github.com} were not treated specially. The special treatment
is preserved for historical reasons and because GitHub provides an
interface that is always efficient.}
is preserved for historical reasons, especially in combination
with @envvar{PLT_USE_GITHUB_API}.}
For backward compatibility, an older format is also supported:
@ -304,7 +304,15 @@ with @litchar{git://github.com/} or @litchar{github://}; a package
source that is otherwise specified as a GitHub reference is
automatically prefixed with @litchar{git://github.com/}. The inferred
package name is the last element of @nonterm{path} if it is non-empty,
otherwise the inferred name is @nonterm{repo}.}
otherwise the inferred name is @nonterm{repo}.
If the @indexed-envvar{PLT_USE_GITHUB_API} environment variable is
set, GitHub packages are obtained using the GitHub API protocol
instead of using the Git protocol.
@history[#:changed "6.3" @elem{Changed handling of
GitHub sources to use the Git
protocol by default.}]}
@; ----------------------------------------
@item{a @tech{package name} --- A @tech{package catalog} is
@ -932,9 +940,12 @@ for @nonterm{key}.
updated that its implementation is kept in the trash folder. Package implementations are
removed from a trash folder only when another package is potentially added
to the trash folder or @command-ref{empty-trash} is used.}
@item{@exec{network-retries} --- The number of times to retry a network communication that
fails due to a connection error.}
]
@history[#:changed "6.1.1.6" @elem{Added @exec{trash-max-packages} and @exec{trash-max-seconds}.}]}
@history[#:changed "6.1.1.6" @elem{Added @exec{trash-max-packages} and @exec{trash-max-seconds}.}
#:changed "6.3" @elem{Added @exec{network-retries}.}]}
@subcommand{@command/toc{catalog-show} @nonterm{option} ... @nonterm{package-name} ...
@ -1015,6 +1026,15 @@ for @nonterm{key}.
@item{@DFlag{version} @nonterm{version} or @Flag{v} @nonterm{version} --- Copies catalog
results specific to @nonterm{version}
(for catalogs that make a distinction), instead of the installation's Racket version.}
@item{@DFlag{pkg-fail} @nonterm{mode} --- Determines handling of failure for an individual
package, such as when a @nonterm{src-catalog} contains a bad package source. The
following @nonterm{mode}s are available:
@itemlist[
@item{@exec{fail} (the default) --- archiving stops and fails;}
@item{@exec{skip} --- the package is skipped and omitted from the archive catalog; or}
@item{@exec{continue} --- like @exec{skip}, but @exec{raco pkg catalog-archive}
exits with a status code of @exec{5} if any package was skipped.}
]}
]
@history[#:added "6.0.17"]

View File

@ -74,7 +74,7 @@ the following files and directories:
Any of the above can be suppressed, however, by a
@racket[source-keep-files] (for @tech{source package} and @tech{built
package} bundling), @racket[binary-keep-files] (for @tech{binary
package}, @tech{binary library package} @tech{built package} bundling),
package}, @tech{binary library package} and @tech{built package} bundling),
or @racket[binary-lib-keep-files] (for @tech{binary library package} bundling) definition in an
@filepath{info.rkt} in the package or any subdirectory. A
@racket[source-keep-files], @racket[binary-keep-files], or @racket[binary-lib-keep-files] definition

View File

@ -23,8 +23,8 @@ the library produced by @racket[ffi-lib-expr]. The syntax of
(code:line #:fail fail-expr)])]
A @racket[define-id] form binds @racket[id] by extracting a binding
with the name @racket[c-id] from the library produced by
@racket[ffi-lib-expr], where @racket[c-id] defaults to @racket[id].
with the name @racket[_c-id] from the library produced by
@racket[ffi-lib-expr], where @racket[_c-id] defaults to @racket[_id].
The other options support further wrapping and configuration:
@itemize[

View File

@ -269,6 +269,56 @@ Check whether @racket[subcls] is @racket[cls] or a subclass.
@history[#:added "6.1.0.5"]}
@defproc[(objc-get-class [obj _id]) _Class]{
Extract the class of @racket[obj].
@history[#:added "6.3"]}
@defproc[(objc-set-class! [obj _id] [cls _Class]) void?]{
Changes the class of @racket[obj] to @racket[cls]. The object's
existing representation must be compatible with the new class.
@history[#:added "6.3"]}
@defproc[(objc-get-superclass [cls _Class]) _Class]{
Returns the superclass of @racket[cls].
@history[#:added "6.3"]}
@defproc[(objc-dispose-class [cls _Class]) void?]{
Destroys @racket[cls], which must have no existing instances or
subclasses.
@history[#:added "6.3"]}
@defproc[(objc-block [function-type? ctype]
[proc procedure?]
[#:keep keep (box/c list?)])
cpointer?]{
Wraps a Racket function @racket[proc] as an Objective-C block. The
procedure must accept an initial pointer argument that is the ``self''
argument for the block, and that extra argument must be included in
the given @racket[function-type].
Extra records that are allocated to implement the block are added to
the list in @racket[keep], which might also be included in
@racket[function-type] through a @racket[#:keep] option to
@racket[_fun]. The pointers registered in @racket[keep] must be
retained as long as the block remains in use.
@history[#:added "6.3"]}
@; ----------------------------------------------------------------------
@section{Raw Runtime Functions}

View File

@ -446,5 +446,5 @@ In general, each contract error message consists of six sections:
@item{a description of the precise aspect of the contract that was violated, @lines[1 2]}
@item{the complete contract plus a path into it showing which aspect was violated, @lines[3 2]}
@item{the module where the contract was put (or, more generally, the boundary that the contract mediates), @lines[5 1]}
@item{who was blamed, @lines[6 1]}
@item{and the source location where the contract appears. @lines[7 1]}]
@item{who was blamed, @lines[6 2]}
@item{and the source location where the contract appears. @lines[8 1]}]

View File

@ -34,7 +34,7 @@ modular reasoning about programs. For example, in the module,
(provide rx:fish fishy-string?)
(define rx:fish #rx"fish")
(define (fishy-string? s)
(regexp-match? s rx:fish)))
(regexp-match? rx:fish s)))
]
the function @racket[fishy-string?] will always match strings that

View File

@ -28,5 +28,10 @@ many other installed libraries. Run @exec{raco docs} to find
documentation for libraries that are installed on your system and
specific to your user account.
@link["http://planet.plt-racket.org/"]{@|PLaneT|} offers even more
downloadable packages contributed by Racketeers.
@link["http://pkgs.racket-lang.org/"]{The Racket package repository}
offer even more downloadable packages that are contributed by
Racketeers.
The legacy @link["http://planet.racket-lang.org/"]{@|PLaneT|} site
offers additional packages, although maintained packages have
generally migrated to the newer package repository.

View File

@ -603,7 +603,7 @@ As a form for modularity, @racket[unit] complements @racket[module]:
]
The @racket[lambda] and @racket[class] forms, among others, also allow
paremetrization of code with respect to values that are chosen
parameterization of code with respect to values that are chosen
later. In principle, any of those could be implemented in terms of any
of the others. In practice, each form offers certain
conveniences---such as allowing overriding of methods or especially

View File

@ -204,7 +204,7 @@ To package the program as an executable, you have a few options:
@; ----------------------------------------------------------------------
@section[#:tag "use-module"]{A Note to Readers with Lisp/Scheme Experience}
If you already know something about Racket or Lisp, you might be
If you already know something about Scheme or Lisp, you might be
tempted to put just
@racketblock[

View File

@ -87,7 +87,7 @@ To embed Racket CGC in a program, follow these steps:
@cpp{scheme_main_stack_setup} trampoline registers the C stack with
the memory manager without creating a namespace.)
On 32-bit Windows, when support for parallelism is enabled in the Racket
On Windows, when support for parallelism is enabled in the Racket
build (as is the default), then before calling
@cpp{scheme_main_setup}, your embedding application must first call
@cppi{scheme_register_tls_space}:
@ -101,7 +101,12 @@ To embed Racket CGC in a program, follow these steps:
@verbatim[#:indent 2]{
static __declspec(thread) void *tls_space;
}}
}
@history[#:changed "6.3" @elem{Calling @cpp{scheme_register_tls_space} is
required on all Windows variants, although the call
may be a no-op, depending on how Racket is
built.}]}
@item{Configure the namespace by adding module declarations. The
initial namespace contains declarations only for a few primitive
@ -200,6 +205,16 @@ int main(int argc, char *argv[])
}
}
If modules embedded in the executable need to access runtime files
(via @racketmodname[racket/runtime-path] forms), supply the
@DFlag{runtime} flag to @exec{raco ctool}, specifying a directory
where the runtime files are to be gathered. The modules in the
generated @filepath{.c} file will then refer to the files in that
directory; the directory is normally specified relative to the
executable, but the embedding application must call
@cppi{scheme_set_exec_cmd} to set the executable path (typically
@cpp{argv[0]}) before declaring modules.
On Mac OS X, or on Windows when Racket is compiled to a DLL
using Cygwin, the garbage collector cannot find static variables
automatically. In that case, @cppi{scheme_main_setup} must be called with a

View File

@ -64,6 +64,13 @@ Sets the path to be returned by @racket[(find-system-path
'addon-dir)].}
@function[(void scheme_set_exec_cmd
[const-char* path])]{
Sets the path to be returned by @racket[(find-system-path
'exec-file)].}
@function[(void scheme_init_collection_paths_post
[Scheme_Env* env]
[Scheme_Object* pre_extra_paths]

View File

@ -196,28 +196,28 @@ A size procedure simply takes a pointer to an object with the tag and
returns its size in words (not bytes). The @cppi{gcBYTES_TO_WORDS}
macro converts a byte count to a word count.
A mark procedure is used to trace references among objects without
moving any objects. The procedure takes a pointer to an object, and it
should apply the @cppi{gcMARK} macro to every pointer within the
object. The mark procedure should return the same result as the size
procedure.
A mark procedure is used to trace references among objects. The
procedure takes a pointer to an object, and it should apply the
@cppi{gcMARK} macro to every pointer within the object. The mark
procedure should return the same result as the size procedure.
A fixup procedure is used to update references to objects after or
while they are moved. The procedure takes a pointer to an object, and
it should apply the @cppi{gcFIXUP} macro to every pointer within the
object; the expansion of this macro takes the address of its
argument. The fixup procedure should return the same result as the
size procedure.
A fixup procedure is potentially used to update references to objects
that have moved, although the mark procedure may have moved objects
and updated references already. The fixup procedure takes a pointer to
an object, and it should apply the @cppi{gcFIXUP} macro to every
pointer within the object. The fixup procedure should return the same
result as the size procedure.
Depending on the collector's implementation, the mark or fixup
procedure might not be used. For example, the collector may only use
the mark procedure and not actually move the object. Or it may use the
fixup procedure to mark and move objects at the same time. To
dereference an object pointer during a fixup procedure, use
Depending on the collector's implementation, the @cpp{gcMARK} and/or
@cpp{gcFIXUP} macros may take take the address of their arguments, and
the fixup procedure might not be used. For example, the collector may
only use the mark procedure and not actually move the object. Or it
may use mark to move objects at the same time. To dereference an
object pointer during a mark or fixup procedure, use @cppi{GC_resolve}
to convert a potentially old address to the location where the object
has been moved. To dereference an object pointer during a fixup procedure, use
@cppi{GC_fixup_self} to convert the address passed to the procedure to
refer to the potentially moved object, and use @cppi{GC_resolve} to
convert an address that is not yet fixed up to determine the object's
current location.
refer to the potentially moved object.
When allocating a tagged object in 3m, the tag must be installed
immediately after the object is allocated---or, at least, before the
@ -899,7 +899,7 @@ overflow.}
[void* ptr]
[int tls_index])]{
Only available on 32-bit Windows; registers @var{ptr} as the address of a
For Windows, registers @var{ptr} as the address of a
thread-local pointer variable that is declared in the main
executable. The variable's storage will be used to implement
thread-local storage within the Racket run-time. See
@ -908,7 +908,10 @@ Only available on 32-bit Windows; registers @var{ptr} as the address of a
The @var{tls_index} argument must be @cpp{0}. It is currently
ignored, but a future version may use the argument to allow
declaration of the thread-local variable in a dynamically linked
DLL.}
DLL.
@history[#:changed "6.3" @elem{Changed from available only on 32-bit Windows
to available on all Windows variants.}]}
@function[(void scheme_register_static
[void* ptr]
@ -1106,9 +1109,7 @@ If the result of the size procedure is a constant, then pass a
3m only. Can be called by a size, mark, or fixup procedure that is registered
with @cpp{GC_register_traversers}. It returns the current address of
an object @var{p} that might have been moved already, where @var{p}
corresponds to an object that is referenced directly by the object
being sized, marked, or fixed. This translation is necessary, for
an object @var{p} that might have been moved already. This translation is necessary, for
example, if the size or structure of an object depends on the content
of an object it references. For example, the size of a class instance
usually depends on a field count that is stored in the class. A fixup
@ -1120,7 +1121,9 @@ fixing it.}
3m only. Can be called by a fixup procedure that is registered with
@cpp{GC_register_traversers}. It returns the final address of @var{p},
which must be the pointer passed to the fixup procedure. For some
which must be the pointer passed to the fixup procedure. The
@cpp{GC_resolve} function would produce the same result, but
@cpp{GC_fixup_self} may be more efficient. For some
implementations of the memory manager, the result is the same as
@var{p}, either because objects are not moved or because the object is
moved before it is fixed. With other implementations, an object might

View File

@ -2,6 +2,7 @@
@(require scribble/manual
scribble/bnf
"common.rkt"
(for-label scheme/gui
compiler/compiler
compiler/sig
@ -12,7 +13,9 @@
dynext/compile-sig
dynext/link-sig
dynext/file-sig
launcher/launcher))
launcher/launcher
compiler/module-suffix
setup/getinfo))
@title{API for Raw Compilation}
@ -70,6 +73,7 @@ file is reported through the current output port.}
@defproc[(compile-collection-zos [collection string?] ...+
[#:skip-path skip-path (or/c path-string? #f) #f]
[#:skip-paths skip-paths (listof path-string?) null]
[#:skip-doc-sources? skip-docs? any/c #f]
[#:managed-compile-zo managed-compile-zo
(path-string? . -> . void?)
@ -83,8 +87,10 @@ The @filepath{.zo} files are placed into the collection's
By default, all files with the
extension @filepath{.rkt}, @filepath{.ss}, or @filepath{.scm} in a collection are
compiled, as are all such files within subdirectories, execept that
any file or directory whose path starts with @racket[skip-path] is
compiled, as are all such files within subdirectories; the set of such suffixes
is extensible globally as described in @racket[get-module-suffixes], and
@racket[compile-collection-zos] recognizes suffixes from the @racket['libs] group. However,
any file or directory whose path starts with @racket[skip-path] or an element of @racket[skip-paths] is
skipped. (``Starts with'' means that the simplified path @racket[_p]'s
byte-string form after @racket[(simplify-path _p #f)]starts with the
byte-string form of @racket[(simplify-path skip-path #f)].)
@ -113,24 +119,33 @@ collection. The following fields are used:
field's value is @racket['all].}
@item{@indexed-racket[compile-omit-files] : A list of filenames (without
directory paths); that are not compiled, in addition to the
directory paths) that are not compiled, in addition to the
contents of @racket[compile-omit-paths]. Do not use this
field; it is for backward compatibility.}
@item{@indexed-racket[scribblings] : A list of pairs, each of which
starts with a path for documentation source. The sources (and
the files that they require) are compiled in the same way as
@filepath{.rkt}, @filepath{.ss}, and @filepath{.scm} files,
unless the provided @racket[skip-docs?] argument is a true
value.}
other module files, unless @racket[skip-docs?] is a true value.}
]}
@item{@indexed-racket[compile-include-files] : A list of filenames (without
directory paths) to be compiled, in addition to files that
are compiled based on the file's extension, being in @racket[scribblings],
or being @racket[require]d by other compiled files.}
@item{@racket[module-suffixes] and @racket[doc-module-suffixes] ---
Used indirectly via @racket[get-module-suffixes].}
]
@history[#:changed "6.3" @elem{Added support for @racket[compile-include-files].}]}
@defproc[(compile-directory-zos [path path-string?]
[info ()]
[#:verbose verbose? any/c #f]
[#:skip-path skip-path (or/c path-string? #f) #f]
[#:skip-paths skip-paths (listof path-string?) null]
[#:skip-doc-sources? skip-docs? any/c #f]
[#:managed-compile-zo managed-compile-zo
(path-string? . -> . void?)
@ -142,6 +157,69 @@ rather than a collection. The @racket[info] function behaves like the
result of @racket[get-info] to supply @filepath{info.rkt} fields,
instead of using an @filepath{info.rkt} file (if any) in the directory.}
@; ----------------------------------------------------------------------
@section[#:tag "module-suffix"]{Recognizing Module Suffixes}
@defmodule[compiler/module-suffix]{The
@racketmodname[compiler/module-suffix] library provides functions for
recognizing file suffixes that correspond to Racket modules for the
purposes of compiling files in a directory, running tests for files in
a directory, and so on. The set of suffixes always includes
@filepath{.rkt}, @filepath{.ss}, and @filepath{.scm}, but it can be
extended globally by @filepath{info.rkt} configuration in collections.}
@history[#:added "6.3"]
@defproc[(get-module-suffixes [#:group group (or/c 'all 'libs 'docs) 'all]
[#:mode mode (or/c 'preferred 'all-available 'no-planet 'no-user) 'preferred]
[#:namespace namespace (or/c #f namespace?) #f])
(listof bytes?)]{
Inspects @filepath{info.rkt} files (see @secref["info.rkt"]) of
installed collections to produce a list of file suffixes that should
be recognized as Racket modules. Each suffix is reported as a byte
string that does not include the @litchar{.} that precedes a suffix.
The @racket[mode] and @racket[namespace] arguments are propagated to
@racket[find-relevant-directories] to determine which collection
directories might configure the set of suffixes. Consequently, suffix
registrations are found reliably only if @exec{raco setup} (or package
installations or updates that trigger @exec{raco setup}) is run.
The @racket[group] argument determines whether the result includes all
registered suffixes, only those that are registered as general library
suffixes, or only those that are registered as documentation suffixes.
The set of general-library suffixes always includes @filepath{.rkt},
@filepath{.ss}, and @filepath{.scm}. The set of documentation suffixes
always includes @filepath{.scrbl}.
The following fields in an @filepath{info.rkt} file extend the set of
suffixes:
@itemize[
@item{@indexed-racket[module-suffixes] : A list of byte strings that
correspond to general-library module suffixes (without the
@litchar{.} that must appear before the suffix). Non-lists or
non-byte-string elements of the list are ignored.}
@item{@indexed-racket[doc-module-suffixes] : A list of byte strings
as for @racket[module-suffixes], but for documentation
modules.}
]}
@defproc[(get-module-suffix-regexp [#:group group (or/c 'all 'libs 'docs) 'all]
[#:mode mode (or/c 'preferred 'all-available 'no-planet 'no-user) 'preferred]
[#:namespace namespace (or/c #f namespace?) #f])
byte-regexp?]{
Returns a @tech[#:doc reference-doc]{regexp value} that matches paths ending
with a suffix as reported by @racket[get-module-suffixes]. The pattern
includes a subpatterns for the suffix without its leading @litchar{.}}
@; ----------------------------------------------------------------------
@section[#:tag "api:loading"]{Loading Compiler Support}

View File

@ -1,5 +1,7 @@
#lang scribble/doc
@(require scribble/manual "common.rkt")
@(require scribble/manual
"common.rkt"
scribble/bnf)
@title[#:tag "c-mods"]{Embedding Modules via C}
@ -14,3 +16,11 @@ a @tt{declare_modules} function that puts the module declarations into
a namespace. Thus, using the output of @exec{raco ctool --c-mods}, a
program can embed Racket with a set of modules so that it does not
need a @filepath{collects} directory to load modules at run time.
If the embedded modules refer to runtime files, the files can be
gathers by supplying the @DFlag{runtime} argument to @exec{raco ctool
--cmods}, specifying a directory @nonterm{dir} to hold the files.
Normally, @nonterm{dir} is a relative path, and files are found at run
time in @nonterm{dir} relative to the executable, but a separate path
(usually relative) for run time can be specified with
@DFlag{runtime-access}.

View File

@ -7,5 +7,8 @@
(define inside-doc
'(lib "scribblings/inside/inside.scrbl"))
(define guide-doc
'(lib "scribblings/guide/guide.scrbl"))
(define reference-doc
'(lib "scribblings/reference/reference.scrbl"))

View File

@ -104,7 +104,10 @@ Many forms in the decompiled code, such as @racket[module],
@item{A form @racket[(#%apply-values _proc _expr)] is equivalent to
@racket[(call-with-values (lambda () _expr) _proc)], but the run-time
system avoids allocating a closure for @racket[_expr].}
system avoids allocating a closure for @racket[_expr]. Similarly,
a @racket[#%call-with-immediate-continuation-mark] call is equivalent to
a @racket[call-with-immediate-continuation-mark] call, but avoiding
a closure allocation.}
@item{A @racket[define-values] form may have @racket[(begin
'%%inline-variant%% _expr1 _expr2)] for its expression, in which case

View File

@ -16,17 +16,26 @@ perform the same work as @exec{raco distribute}.}
@defproc[(assemble-distribution [dest-dir path-string?]
[exec-files (listof path-string?)]
[#:executables? executables? any/c #t]
[#:relative-base relative-base (or/c path-string? #f) #f]
[#:collects-path path (or/c false/c (and/c path-string? relative-path?)) #f]
[#:copy-collects dirs (listof path-string?) null])
void?]{
Copies the executables in @racket[exec-files] to the directory
@racket[dest-dir], along with DLLs, frameworks, and/or shared
libraries that the executables need to run a different machine.
@racket[dest-dir], along with DLLs, frameworks, shared libraries,
and/or runtime files that the executables need to run a different
machine. If @racket[executables?] is @racket[#f], then the
@racket[exec-files] are treated as plain data files, instead of
executables, and they are modified in-place.
The arrangement of the executables and support files in
@racket[dest-dir] depends on the platform. In general
@racket[assemble-distribution] tries to do the Right Thing.
@racket[dest-dir] depends on the platform. In general,
@racket[assemble-distribution] tries to do the Right Thing, but a
non-@racket[#f] value for @racket[relative-base] specifies a
path for reaching the assembled content relative to the executable at
run time. When @racket[executables?] is @racket[#f], then the default
access path is @racket[dest-dir], with its relativeness preserved.
If a @racket[#:collects-path] argument is given, it overrides the
default location of the main @filepath{collects} directory for the
@ -35,4 +44,7 @@ directory (typically inside it).
The content of each directory in the @racket[#:copy-collects] argument
is copied into the main @filepath{collects} directory for the packaged
executables.}
executables.
@history[#:changed "6.3" @elem{Added the @racket[#:executables?]
and @racket[#:relative-base] arguments.}]}

View File

@ -187,11 +187,11 @@ currently supported keys are as follows:
@filepath{.icns}) to use for the executable's desktop icon.}
@item{@racket['ico] (Windows) : An icon file path (suffix
@filepath{.ico}) to use for the executable's desktop icon;
the executable will have 16x16, 32x32, and 48x48 icons at
4-bit, 8-bit, and 32-bit (RGBA) depths; the icons are copied
and generated from any 16x16, 32x32, and 48x48 icons in the
@filepath{.ico} file.}
@filepath{.ico}) to use for the executable's desktop icon.
@history[#:changed "6.3" @elem{All icons in the
executable are replaced with icons from the file,
instead of setting only certain sizes and depths.}]}
@item{@racket['creator] (Mac OS X) : Provides a 4-character string
to use as the application signature.}
@ -473,9 +473,17 @@ A unit that imports nothing and exports @racket[compiler:embed^].}
@defmodule[compiler/find-exe]
@defproc[(find-exe [gracket? any/c #f]
[variant (or/c 'cgc '3m) (system-type 'gc)])
@defproc[(find-exe [#:cross? cross? any/c #f]
[gracket? any/c #f]
[variant (or/c 'cgc '3m) (if cross?
(cross-system-type 'gc)
(system-type 'gc))])
path?]{
Finds the path to the @exec{racket} or @exec{gracket} (when
@racket[gracket?] is true) executable.}
@racket[gracket?] is true) executable.
If @racket[cross?] is true, the executable is found for the target
platform in @seclink["cross-system"]{cross-installation mode}.
@history[#:changed "6.3" @elem{Added the @racket[#:cross?] argument.}]}

View File

@ -0,0 +1,36 @@
#lang scribble/manual
@(require "common.rkt"
(for-label racket/base
racket/contract
compiler/exe-dylib-path))
@title[#:tag "exe-dylib-path"]{Mac OS X Dynamic Library Paths}
@defmodule[compiler/exe-dylib-path]{The
@racketmodname[compiler/exe-dylib-path] library provides functions for
reading and adjusting dynamic-library references in a Mac OS X
executable.}
@history[#:added "6.3"]
@defproc[(find-matching-library-path [exe-path path-string?]
[library-str string?])
(or/c #f string?)]{
Searches dynamic-linking information in @racket[exe-path] for a
library reference whose name includes @racket[library-str] and returns
the executable's path to the library for the first match. If no match is
found, the result is @racket[#f].}
@defproc[(update-matching-library-path [exe-path path-string?]
[library-str string?]
[library-path-str string?])
void?]{
Searches dynamic-linking information in @racket[exe-path] for each
library reference whose name includes @racket[library-str] and replaces
the executable's path to that library with @racket[library-path-str].
A single match is expected, and the update assumes enough space for
the new path, perhaps because the executable is linked with
@Flag{headerpad_max_install_names}.}

View File

@ -176,3 +176,5 @@ The @exec{raco exe} command accepts the following command-line flags:
@include-section["exe-api.scrbl"]
@include-section["launcher.scrbl"]
@include-section["exe-dylib-path.scrbl"]

View File

@ -497,6 +497,18 @@ result will not call @racket[proc] with @racket['unlock].)
compilations of the same racket source files in multiple places.
}
@defproc[(install-module-hashes! [bstr btyes?]
[start exact-nonnegatve-integer? 0]
[end exact-nonnegatve-integer? (bytes-length bstr)])
void?]{
Adjusts the bytecode representation in @racket[bstr] (from bytes
@racket[start] to @racket[end]) to install a hash code, including any
submodules within the region. The existing representation should have
zero bytes in place of each hash string, which is what @racket[write]
produces for a compiled form.
@history[#:added "6.3"]}
@; ----------------------------------------------------------------------

View File

@ -14,6 +14,7 @@
setup/collection-name
setup/collection-search
setup/matching-platform
setup/cross-system
setup/path-to-relative
setup/xref scribble/xref
;; info -- no bindings from this are used
@ -22,6 +23,7 @@
setup/unpack
setup/link
compiler/compiler
compiler/module-suffix
launcher/launcher
compiler/sig
launcher/launcher-sig
@ -759,6 +761,13 @@ Optional @filepath{info.rkt} fields trigger additional actions by
file, etc. Supplying a specific list of collections to @exec{raco
setup} disables this dependency-based deletion of compiled files.}
@item{@racket[compile-omit-paths], @racket[compile-omit-files], and
@racket[compile-include-files] --- Used indirectly via
@racket[compile-collection-zos].}
@item{@racket[module-suffixes] and @racket[doc-module-suffixes] ---
Used indirectly via @racket[get-module-suffixes].}
]
@; ------------------------------------------------------------------------
@ -1721,7 +1730,7 @@ or @litchar{_}.}
@defmodule[setup/collection-search]
@history[#:added "6.2.900.6"]
@history[#:added "6.3"]
@defproc[(collection-search [mod-path normalized-lib-module-path?]
[#:init result any/c #f]
@ -1774,9 +1783,14 @@ Returns @racket[#t] if @racket[v] is a symbol, string, or regexp value
(in the sense of @racket[regexp?]), @racket[#f] otherwise.}
@defproc[(matching-platform? [spec platform-spec?]
[#:system-type sys-type (or/c #f symbol?) (system-type)]
[#:system-library-subpath sys-lib-subpath (or/c #f path?)
(system-library-subpath #f)])
[#:cross? cross? any/c #f]
[#:system-type sys-type (or/c #f symbol?) (if cross?
(cross-system-type)
(system-type))]
[#:system-library-subpath sys-lib-subpath (or/c #f path-for-some-system?)
(if cross?
(cross-system-library-subpath #f)
(system-library-subpath #f))])
boolean?]{
Reports whether @racket[spec] matches @racket[sys-type] or
@ -1792,8 +1806,74 @@ If @racket[spec] is a string, then the result is @racket[#t] if
If @racket[spec] is a regexp value, then the result is @racket[#t] if
the regexp matches @racket[(path->string sys-lib-subpath)],
@racket[#f] otherwise.
@history[#:changed "6.3" @elem{Added @racket[#:cross?] argument and
changed the contract on @racket[sys-lib-subpath]
to accept @racket[path-for-some-system?]
instead of just @racket[path?].}]}
@; ------------------------------------------------------------------------
@section[#:tag "cross-system"]{API for Cross-Platform Configuration}
@defmodule[setup/cross-system]{The @racketmodname[setup/cross-system]
library provides functions for querying the system properties of a
destination platform, which can be different than the current platform
in cross-installation modes.}
A Racket installation includes a @filepath{system.rktd} file in the
directory reported by @racket[(find-lib-dir)]. When the information in that file
does not match the running Racket's information, then the
@racketmodname[setup/cross-system] module infers that Racket is being
run in cross-installation mode.
For example, if an in-place Racket installation for a different
platform resides at @nonterm{cross-dir}, then
@commandline{racket -G @nonterm{cross-dir}/etc -X @nonterm{cross-dir}/collects -l- raco pkg}
runs @exec{raco pkg} using the current platform's @exec{racket}
executable, but using the collections and other configuration
information of @nonterm{cross-dir}, as well as modifying the packages
of @nonterm{cross-dir}. That can work as long as no platform-specific
libraries need to run to perform the requested @exec{raco pkg} action
(e.g., when installing built packages).
@history[#:added "6.3"]
@defproc[(cross-system-type [mode (or/c 'os 'word 'gc 'link 'machine
'so-suffix 'so-mode 'fs-change)
'os])
(or/c symbol? string? bytes? exact-positive-integer? vector?)]{
Like @racket[system-type], but for the target platform instead of the
current platform in cross-installation mode. When not in
cross-installation mode, the results are the same as for
@racket[system-type].}
@defproc[(cross-system-library-subpath [mode (or/c 'cgc '3m #f)
(system-type 'gc)])
path-for-some-system?]{
Like @racket[system-library-subpath], but for the target platform
instead of the current platform in cross-installation mode. When not
in cross-installation mode, the results are the same as for
@racket[system-library-subpath].
In cross-installation mode, the target platform may have a different
path convention than the current platform, so the result is
@racket[path-for-some-system?] instead of @racket[path?].}
@defproc[(cross-installation?) boolean?]{
Returns @racket[#t] if cross-installation mode has been detected,
@racket[#f] otherwise.}
@; ------------------------------------------------------------------------
@section[#:tag "xref"]{API for Cross-References for Installed Manuals}

View File

@ -5,7 +5,8 @@
(for-label racket/runtime-path
racket/base
launcher/launcher
rackunit/log))
rackunit/log
compiler/module-suffix))
@title[#:tag "test"]{@exec{raco test}: Run tests}
@ -19,8 +20,9 @@ the file.
When an argument path refers to a directory, @exec{raco test}
recursively discovers and runs all files within the directory that end
in @filepath{.rkt}, end in @filepath{.scrbl}, or have a (possibly
empty) list of command-line arguments provided by
in a module suffix (see @racket[get-module-suffixes], but the suffixes
always include @filepath{.rkt}, @filepath{.scrbl}, @filepath{.ss}, and
@filepath{.scm}) or have a (possibly empty) list of command-line arguments provided by
@racket[test-command-line-arguments] in an @filepath{info.rkt} file,
or as directed by @racket[test-include-paths] in an
@filepath{info.rkt} file. At the same time, @exec{raco test} omits
@ -53,8 +55,7 @@ The @exec{raco test} command accepts several flags:
--- Not only interprets the arguments as paths (which is the
default mode), but treats them the same as paths found in a
directory, which means ignoring a file argument that does not
have the extension @filepath{.rkt}, does not have the extension
@filepath{.scrbl}, or is not enabled explicitly via
have a module extension or is not enabled explicitly via
@racket[test-command-line-arguments] or @racket[test-include-paths]
in an @filepath{info.rkt} file; meanwhile, paths that are otherwise
enabled can be disabled via @racket[test-omit-paths] in an
@ -88,6 +89,14 @@ The @exec{raco test} command accepts several flags:
--- When multiple submodule names are provided with @Flag{s} or
@DFlag{submodule}, runs only the first available submodule.}
@item{@DFlag{configure-runtime}
--- Run a @racketidfont{configure-runtime} submodule (if any) of
each specified module before the module or a
submodule is run. This mode is the default when only a single
module is provided or when @DFlag{process} or @DFlag{place}
mode is specified, unless a submodule name is provided
via @Flag{s} or @DFlag{submodule}.}
@item{@DFlag{direct}
--- Runs each test in a thread. This mode is the default if
a single file is specified. Multiple tests can interfere with
@ -153,7 +162,9 @@ The @exec{raco test} command accepts several flags:
]
@history[#:changed "1.1" @elem{Added @DFlag{heartbeat}.}]
@history[#:changed "1.1" @elem{Added @DFlag{heartbeat}.}
#:changed "1.4" @elem{Changed recognition of module suffixes to use @racket[get-module-suffixes],
which implies recognizing @filepath{.ss} and @filepath{.rkt}.}]
@section[#:tag "test-config"]{Test Configuration by Submodule}
@ -265,6 +276,9 @@ The following @filepath{info.rkt} fields are recognized:
the enclosing directory) for modules whose output varies.
See @secref["test-responsible"].}
@item{@racket[module-suffixes] and @racket[doc-module-suffixes] ---
Used indirectly via @racket[get-module-suffixes].}
]
@section[#:tag "test-responsible"]{Responsible-Party and Varying-Output Logging}

View File

@ -36,15 +36,28 @@ structures that are produced by @racket[zo-parse] and consumed by
@defstruct+[(compilation-top zo)
([max-let-depth exact-nonnegative-integer?]
[binding-namess (hash/c exact-nonnegative-integer?
(hash/c symbol? stx?))]
[prefix prefix?]
[code (or/c form? any/c)])]{
Wraps compiled code. The @racket[max-let-depth] field indicates the
Wraps compiled code.
The @racket[max-let-depth] field indicates the
maximum stack depth that @racket[code] creates (not counting the
@racket[prefix] array). The @racket[prefix] field describes top-level
variables, module-level variables, and quoted syntax-objects accessed
by @racket[code]. The @racket[code] field contains executable code;
it is normally a @racket[form], but a literal value is represented as
itself.}
@racket[prefix] array).
The @racket[binding-namess] field provides a per-phase mapping from
symbols that appear in @racket[prefix] for top-level
@racket[def-values] forms and in top-level @racket[def-syntaxes]
forms. Each symbol is mapped to an identifier that will be bound
(after introduction into the namespace) by the definition.
The @racket[prefix] field describes top-level variables,
module-level variables, and quoted syntax-objects accessed by
@racket[code].
The @racket[code] field contains executable code; it is normally a
@racket[form], but a literal value is represented as itself.}
@defstruct+[(prefix zo)
([num-lifts exact-nonnegative-integer?]
@ -335,7 +348,7 @@ binding, constructor, etc.}
values; also, this information is redundant, since it can be inferred
by the bindings referenced though @racket[closure-map].
Which a closure captures top-level or module-level variables or
When a closure captures top-level or module-level variables or
refers to a syntax-object constant, the variables and constants are
represented in the closure by capturing a prefix (in the sense
of @racket[prefix]). The @racket[toplevel-map] field indicates
@ -567,6 +580,22 @@ binding, constructor, etc.}
which is handled specially by the run-time system.}
@defstruct+[(with-immed-mark expr)
([key (or/c expr? seq? any/c)]
[val (or/c expr? seq? any/c)]
[body (or/c expr? seq? any/c)])]{
Represents a @racket[(call-with-immediate-continuation-mark key
(lambda (_arg) _body) val)] expression that is handled specially by
the run-time system to avoid a closure allocation. One initialized
slot is pushed onto the stack after @racket[expr] and @racket[val]
are evaluated and before @racket[body] is evaluated.
After each of @racket[key] and @racket[val] is evaluated, the stack is
restored to its depth from before evaluating @racket[key] or
@racket[val].}
@defstruct+[(primval expr)
([id exact-nonnegative-integer?])]{
Represents a direct reference to a variable imported from the run-time
@ -578,9 +607,13 @@ binding, constructor, etc.}
@defstruct+[(stx-obj zo)
([datum any/c]
[wrap wrap?]
[srcloc (or/c #f srcloc?)]
[props (hash/c symbol? any/c)]
[tamper-status (or/c 'clean 'armed 'tainted)])]{
Represents a syntax object, where @racket[wrap] contains lexical
information and @racket[tamper-status] is taint information. When the
information, @racket[srcloc] is the source location,
@racket[props] contains preserved properties,
and @racket[tamper-status] is taint information. When the
@racket[datum] part is itself compound, its pieces are wrapped
as @racket[stx-obj]s, too.

View File

@ -221,9 +221,11 @@ If any @racket[prop] is @racket[impersonator-prop:application-mark] and if the
associated @racket[prop-val] is a pair, then the call to @racket[proc]
is wrapped with @racket[with-continuation-mark] using @racket[(car
prop-val)] as the mark key and @racket[(cdr prop-val)] as the mark
value. In addition, if @racket[continuation-mark-set-first] with
@racket[(car prop-val)] produces a value for the immediate
continuation frame of the call to the impersonated procedure, the value is
value. In addition, if the immediate
continuation frame of the call to the impersonated procedure
includes a value for @racket[(car prop-val)]---that is, if
@racket[call-with-immediate-continuation-mark] would produce a value
for @racket[(car prop-val)] in the call's continuation---then the value is
also installed as an immediate value for @racket[(car prop-val)] as a
mark during the call to @racket[wrapper-proc] (which allows tail-calls
of impersonators with respect to wrapping impersonators to be detected within

View File

@ -182,21 +182,25 @@ If there are multiple higher-order contracts, @racket[or/c] uses
them. More precisely, when an @racket[or/c] is checked, it first
checks all of the @tech{flat contracts}. If none of them pass, it
calls @racket[contract-first-order-passes?] with each of the
higher-order contracts. If only one returns true, @racket[or/c] uses
that contract. If none of them return true, it signals a contract
violation. If more than one returns true, it also signals a contract
violation.
higher-order contracts, taking the first one that returns
true as the contract for the value.
For example, this contract
@racketblock[
(or/c (-> number? number?)
(-> string? string? string?))
]
does not accept a function like this one: @racket[(lambda args ...)]
since it cannot tell which of the two arrow contracts should be used
with the function.
accepts a function like this one: @racket[(lambda args ...)],
using the @racket[(-> number? number?)] contract on it, ignoring
the @racket[(-> string? string? string?)] contract since it came
second.
If all of its arguments are @racket[list-contract?]s, then @racket[or/c]
returns a @racket[list-contract?].
@history[#:changed "6.3" @list{Adjusted @racket[or/c] so that it
takes the first higher-order contract instead of insisting that
there be exactly one higher-order contract for a given value.}]
}
@defproc[(and/c [contract contract?] ...) contract?]{
@ -359,14 +363,16 @@ Returns the same contract as @racket[(vector/c c ... #:immutable #t)]. This form
reasons of backwards compatibility.}
@defproc[(box/c [c contract?]
@defproc[(box/c [in-c contract?]
[c contract? in-c]
[#:immutable immutable (or/c #t #f 'dont-care) 'dont-care]
[#:flat? flat? boolean? #f])
contract?]{
Returns a contract that recognizes boxes. The content of the box must match @racket[c].
Returns a contract that recognizes boxes. The content of the box must match @racket[c],
and mutations on mutable boxes must match @racket[in-c].
If the @racket[flat?] argument is @racket[#t], then the resulting contract is
a flat contract, and the @racket[c] argument must also be a flat contract. Such
a flat contract, and the @racket[out] argument must also be a flat contract. Such
flat contracts will be unsound if applied to mutable boxes, as they will not check
future operations on the box.
@ -1356,7 +1362,7 @@ if they do not, a contract violation is signaled.
Then, when the function returns, it is checked to determine whether the result is wrapped, since
the second @racket[a] appears in a positive position.
The @racket[new-∀/c] construct constructor is dual to @racket[new-∃/c].
The @racket[new-∀/c] contract constructor is dual to @racket[new-∃/c].
}
@defproc[(new-∃/c [name (or/c symbol? #f) #f]) contract?]{
@ -1831,7 +1837,11 @@ accepted by the third argument to @racket[datum->syntax].
@defproc[(make-contract
[#:name name any/c 'anonymous-contract]
[#:first-order test (-> any/c any/c) (λ (x) #t)]
[#:val-first-projection
[#:late-neg-projection
late-neg-proj
(or/c #f (-> blame? (-> any/c any/c any/c)))
#f]
[#:val-first-projection
val-first-proj
(or/c #f (-> blame? (-> any/c (-> any/c any/c))))
#f]
@ -1852,6 +1862,10 @@ accepted by the third argument to @racket[datum->syntax].
@defproc[(make-chaperone-contract
[#:name name any/c 'anonymous-chaperone-contract]
[#:first-order test (-> any/c any/c) (λ (x) #t)]
[#:late-neg-projection
late-neg-proj
(or/c #f (-> blame? (-> any/c any/c any/c)))
#f]
[#:val-first-projection
val-first-proj
(or/c #f (-> blame? (-> any/c (-> any/c any/c))))
@ -1873,6 +1887,10 @@ accepted by the third argument to @racket[datum->syntax].
@defproc[(make-flat-contract
[#:name name any/c 'anonymous-flat-contract]
[#:first-order test (-> any/c any/c) (λ (x) #t)]
[#:late-neg-projection
late-neg-proj
(or/c #f (-> blame? (-> any/c any/c any/c)))
#f]
[#:val-first-projection
val-first-proj
(or/c #f (-> blame? (-> any/c (-> any/c any/c))))
@ -1893,12 +1911,6 @@ accepted by the third argument to @racket[datum->syntax].
flat-contract?]
)]{
@italic{The precise details of the
@racket[val-first-projection] argument
are subject to change. (Probably
also the default values of the @racket[project]
arguments will change.}
These functions build simple higher-order contracts, chaperone contracts, and flat contracts,
respectively. They both take the same set of three optional arguments: a name,
a first-order predicate, and a blame-tracking projection.
@ -1916,13 +1928,25 @@ by @racket[contract-first-order-passes?], and indirectly by @racket[or/c] to
determine which of multiple higher-order contracts to wrap a value with. The
default test accepts any value.
The projection @racket[proj] defines the behavior of applying the contract. It
The @racket[late-neg-proj] defines the behavior of applying the contract. If it is
supplied, it accepts a blame object that does not have a value for
the @racket[blame-negative] field. Then it must return a function that accepts
both the value that is getting the contract and the name of the blame party, in
that order. The result must either be the value (perhaps suitably wrapped
with a @tech{chaperone} or @tech{impersonator} to enforce the contract), or
signal a contract violation using @racket[raise-blame-error]. The default is
@racket[#f].
The projection @racket[proj] and @racket[val-first-proj] are older mechanisms for
defining the behavior of applying the contract. The @racket[proj] argument
is a curried function of two arguments: the first application accepts a blame
object, and the second accepts a value to protect with the contract. The
projection must either produce the value, suitably wrapped to enforce any
higher-order aspects of the contract, or signal a contract violation using
@racket[raise-blame-error]. The default projection produces an error when the
first-order test fails, and produces the value unchanged otherwise.
The @racket[val-first-proj] is like @racket[late-neg-proj], except with
an extra layer of currying.
Projections for chaperone contracts must produce a value that passes
@racket[chaperone-of?] when compared with the original, uncontracted value.
@ -1961,7 +1985,7 @@ to determine if this is a contract that accepts only @racket[list?] values.
(λ (x) (range (f (domain x))))
(raise-blame-error
b f
'(expected "a function of one argument" 'given: "~e")
'(expected "a function of one argument" given: "~e")
f)))))))
(contract int->int/c "not fun" 'positive 'negative)
(define halve
@ -2274,6 +2298,10 @@ is expected to be the blame record for the contract on the value).
get-first-order
(-> contract? (-> any/c boolean?))
(λ (c) (λ (x) #t))]
[#:late-neg-projection
late-neg-proj
(or/c #f (-> contract? (-> blame? (-> any/c any/c any/c))))
#f]
[#:val-first-projection
val-first-proj
(or/c #f (-> contract? blame? (-> any/c (-> any/c any/c))))
@ -2323,6 +2351,10 @@ is expected to be the blame record for the contract on the value).
get-first-order
(-> contract? (-> any/c boolean?))
(λ (c) (λ (x) #t))]
[#:late-neg-projection
late-neg-proj
(or/c #f (-> contract? blame? (-> any/c any/c any/c)))
#f]
[#:val-first-projection
val-first-proj
(or/c #f (-> contract? blame? (-> any/c (-> any/c any/c))))
@ -2372,6 +2404,10 @@ is expected to be the blame record for the contract on the value).
get-first-order
(-> contract? (-> any/c boolean?))
(λ (c) (λ (x) #t))]
[#:late-neg-projection
late-neg-proj
(or/c #f (-> contract? blame? (-> any/c any/c any/c)))
#f]
[#:val-first-projection
val-first-proj
(or/c #f (-> contract? blame? (-> any/c (-> any/c any/c))))
@ -2789,6 +2825,53 @@ currently being checked.
@history[#:added "6.1.1.5"]
}
@defproc[(rename-contract [contract contract?]
[name any/c])
contract?]{
Produces a contract that acts like @racket[contract] but with the name
@racket[name].
The resulting contract is a flat contract if @racket[contract] is a
flat contract.
@history[#:added "6.3"]
}
@defproc[(if/c [predicate (-> any/c any/c)]
[then-contract contract?]
[else-contract contract?])
contract?]{
Produces a contract that, when applied to a value, first tests the
value with @racket[predicate]; if @racket[predicate] returns true, the
@racket[then-contract] is applied; otherwise, the
@racket[else-contract] is applied. The resulting contract is a flat
contract if both @racket[then-contract] and @racket[else-contract] are
flat contracts.
For example, the following contract enforces that if a value is a
procedure, it is a thunk; otherwise it can be any (non-procedure)
value:
@racketblock[(if/c procedure? (-> any) any/c)]
Note that the following contract is @bold{not} equivalent:
@racketblock[(or/c (-> any) any/c) (code:comment "wrong!")]
The last contract is the same as @racket[any/c] because
@racket[or/c] tries flat contracts before higher-order contracts.
@history[#:added "6.3"]
}
@defthing[failure-result/c contract?]{
A contract that describes the failure result arguments of procedures
such as @racket[hash-ref].
Equivalent to @racket[(if/c procedure? (-> any) any/c)].
@history[#:added "6.3"]
}
@section{@racketmodname[racket/contract/base]}
@defmodule[racket/contract/base]

View File

@ -180,7 +180,8 @@ only supported for dictionary types that directly implement them.
@defproc[(dict-ref [dict dict?]
[key any/c]
[failure-result any/c (lambda () (raise (make-exn:fail ....)))])
[failure-result (failure-result/c any/c)
(lambda () (raise (make-exn:fail ....)))])
any]{
Returns the value for @racket[key] in @racket[dict]. If no value
@ -471,7 +472,8 @@ Supported for any @racket[dict] that implements @racket[dict-ref] and
@defproc[(dict-update! [dict (and/c dict? (not/c immutable?))]
[key any/c]
[updater (any/c . -> . any/c)]
[failure-result any/c (lambda () (raise (make-exn:fail ....)))]) void?]{
[failure-result (failure-result/c any/c)
(lambda () (raise (make-exn:fail ....)))]) void?]{
Composes @racket[dict-ref] and @racket[dict-set!] to update an
existing mapping in @racket[dict], where the optional @racket[failure-result]
@ -496,7 +498,8 @@ v
@defproc[(dict-update [dict dict?]
[key any/c]
[updater (any/c . -> . any/c)]
[failure-result any/c (lambda () (raise (make-exn:fail ....)))])
[failure-result (failure-result/c any/c)
(lambda () (raise (make-exn:fail ....)))])
(and/c dict? immutable?)]{
Composes @racket[dict-ref] and @racket[dict-set] to functionally
@ -622,7 +625,7 @@ Supported for any @racket[dict] that supports @racket[dict-remove],
}
@defproc[(dict-clear! [dict dict?]) dict?]{
@defproc[(dict-clear! [dict dict?]) void?]{
Removes all of the key/value associations in @racket[dict].

View File

@ -484,6 +484,18 @@ Like @racket[eval-syntax], but calls the current @tech{compilation
handler} in tail position with @racket[stx].}
@defproc[(compiled-expression-recompile [ce compiled-expression?]) compiled-expression?]{
Recompiles @racket[ce], effectively re-running optimization passes to
produce an equivalent compiled form with potentially different
performance characteristics.
If @racket[ce] includes module forms, then only phase-0 code in the
immediate module (not in submodules) is recompiled.
@history[#:added "6.3"]}
@defproc[(compiled-expression? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a compiled form, @racket[#f]

View File

@ -966,6 +966,8 @@ Returns the @tech{module path}-getting procedure associated with @racket[v].}
@note-lib-only[racket/exn]
@history[#:added "6.3"]
@defproc[(exn->string [exn (or/c exn? any/c)]) string?]{
Formats @racket[exn] as a string. If @racket[exn] is an @racket[exn?],

View File

@ -3,7 +3,8 @@
(for-label framework/preferences
racket/runtime-path
launcher/launcher
setup/dirs))
setup/dirs
setup/cross-system))
@(define file-eval (make-base-eval))
@(interaction-eval #:eval file-eval (begin (require racket/file) (define filename (make-temporary-file))))
@ -936,20 +937,24 @@ Displays each element of @racket[lst] to @racket[path], adding
@racket[open-output-file].}
@defproc[(copy-directory/files [src path-string?] [dest path-string?]
[#:keep-modify-seconds? keep-modify-seconds? #f])
[#:keep-modify-seconds? keep-modify-seconds? #f]
[#:preserve-links? preserve-links? #f])
void?]{
Copies the file or directory @racket[src] to @racket[dest], raising
@racket[exn:fail:filesystem] if the file or directory cannot be
copied, possibly because @racket[dest] exists already. If @racket[src]
is a directory, the copy applies recursively to the directory's
content. If a source is a link, the target of the link is copied
rather than the link itself.
content. If a source is a link and @racket[preserve-links?] is @racket[#f],
the target of the link is copied rather than the link itself; if
@racket[preserve-links?] is @racket[#t], the link is copied.
If @racket[keep-modify-seconds?] is @racket[#f], then file copies
keep only the properties kept by @racket[copy-file], If
keep only the properties kept by @racket[copy-file]. If
@racket[keep-modify-seconds?] is true, then each file copy also keeps
the modification date of the original.}
the modification date of the original.
@history[#:changed "6.3" @elem{Added the @racket[#:preserve-links?] argument.}]}
@defproc[(delete-directory/files [path path-string?]
@ -1398,7 +1403,8 @@ in the sense of @racket[port-try-file-lock?].
[name path-element?])
path?])]{
Creates a lock filename by prepending @racket["_LOCK"] on Windows or
Creates a lock filename by prepending @racket["_LOCK"] on Windows
(i.e., when @racket[cross-system-type] reports @racket['windows]) or
@racket[".LOCK"] on other platforms to the file portion of the path.
@examples[

View File

@ -5,7 +5,8 @@
"mz.rkt"
(for-label racket/contract
racket/math
racket/format))
racket/format
racket/string))
@(begin
(define the-eval (make-base-eval))

View File

@ -170,7 +170,14 @@ See also @racket[make-custom-hash].}
Like @racket[make-hash], @racket[make-hasheq], and
@racket[make-hasheqv], but creates a mutable hash table that holds
keys weakly.}
keys weakly.
Beware that values in the table are retained normally. If a value in
the table refers back to its key, then the table will retain the value
and therefore the key; the mapping will never be removed from the
table even if the key becomes otherwise inaccessible. To avoid that
problem, instead of mapping the key to the value, map the key to an
@tech{ephemeron} that pairs the key and value.}
@deftogether[(
@defproc[(make-immutable-hash [assocs (listof pair?) null])
@ -235,8 +242,9 @@ later mappings overwrite earlier mappings.
@defproc[(hash-ref [hash hash?]
[key any/c]
[failure-result any/c (lambda ()
(raise (make-exn:fail:contract ....)))])
[failure-result (failure-result/c any/c)
(lambda ()
(raise (make-exn:fail:contract ....)))])
any]{
Returns the value for @racket[key] in @racket[hash]. If no value
@ -277,8 +285,9 @@ Returns @racket[#t] if @racket[hash] contains a value for the given
@defproc[(hash-update! [hash (and/c hash? (not/c immutable?))]
[key any/c]
[updater (any/c . -> . any/c)]
[failure-result any/c (lambda ()
(raise (make-exn:fail:contract ....)))])
[failure-result (failure-result/c any/c)
(lambda ()
(raise (make-exn:fail:contract ....)))])
void?]{
Composes @racket[hash-ref] and @racket[hash-set!] to update an
@ -293,8 +302,9 @@ concurrent updates.
@defproc[(hash-update [hash (and/c hash? immutable?)]
[key any/c]
[updater (any/c . -> . any/c)]
[failure-result any/c (lambda ()
(raise (make-exn:fail:contract ....)))])
[failure-result (failure-result/c any/c)
(lambda ()
(raise (make-exn:fail:contract ....)))])
(and/c hash? immutable?)]{
Composes @racket[hash-ref] and @racket[hash-set] to functionally
@ -355,13 +365,15 @@ procedure and mutability of @racket[hash].}
@defproc[(hash-map [hash hash?]
[proc (any/c any/c . -> . any/c)])
[proc (any/c any/c . -> . any/c)]
[try-order? any/c #f])
(listof any/c)]{
Applies the procedure @racket[proc] to each element in
@racket[hash] in an unspecified order, accumulating the results
into a list. The procedure @racket[proc] is called each time with a
key and its value.
key and its value, and the procedure's individual results appear in
order in the result list.
If a hash table is extended with new keys (either through
@racket[proc] or by another thread) while a @racket[hash-map] or
@ -372,7 +384,14 @@ change does not affect a traversal if the key has been seen already,
otherwise the traversal skips a deleted key or uses the remapped key's
new value.
@see-also-concurrency-caveat[]}
If @racket[try-order?] is true, then the order of keys and values
passed to @racket[proc] is normalized under certain circumstances,
such as when the keys are all symbols and @racket[hash] is not an
@tech{impersonator}.
@see-also-concurrency-caveat[]
@history[#:changed "6.3" @elem{Added the @racket[try-order?] argument.}]}
@defproc[(hash-keys [hash hash?])
(listof any/c)]{
@ -396,15 +415,19 @@ See @racket[hash-map] for information about modifying @racket[hash]
during @racket[hash->list]. @see-also-concurrency-caveat[]}
@defproc[(hash-for-each [hash hash?]
[proc (any/c any/c . -> . any)])
[proc (any/c any/c . -> . any)]
[try-order? any/c #f])
void?]{
Applies @racket[proc] to each element in @racket[hash] (for the
side-effects of @racket[proc]) in an unspecified order. The procedure
@racket[proc] is called each time with a key and its value.
See @racket[hash-map] for information about modifying @racket[hash]
within @racket[proc]. @see-also-concurrency-caveat[]}
See @racket[hash-map] for information about @racket[try-order?] and
about modifying @racket[hash] within @racket[proc].
@see-also-concurrency-caveat[]
@history[#:changed "6.3" @elem{Added the @racket[try-order?] argument.}]}
@defproc[(hash-count [hash hash?])

View File

@ -333,7 +333,7 @@ Returns @racket[#t] if @racket[v] is a valid logging level (@racket['none],
@racket['fatal], @racket['error], @racket['warning], @racket['info], or
@racket['debug]), @racket[#f] otherwise.
@history[#:added "6.2.900.5"]{}
@history[#:added "6.3"]{}
}
@defproc[(with-intercepted-logging
@ -368,7 +368,7 @@ Returns whatever @racket[proc] returns.
'warning)
warning-counter)]
@history[#:added "6.2.900.5"]{}}
@history[#:added "6.3"]{}}
@defproc[(with-logging-to-port
[port output-port?] [proc (-> any)]
@ -391,4 +391,4 @@ Returns whatever @racket[proc] returns.
'warning)
(get-output-string my-log))]
@history[#:added "6.2.900.5"]{}}
@history[#:added "6.3"]{}}

View File

@ -50,6 +50,7 @@ qp ::= literal @match literal
| (qp ooo . qp) @match qps beginning with repeated qp
| #(qp ...) @match vector of qps
| #&qp @match boxed qp
| #s(prefab-key qp ...) @match prefab struct with qp fields
| ,pat @match pat
| ,@(LIST lvp ...) @match lvps, spliced
| ,@(LIST-REST lvp ... pat) @match lvps plus pat, spliced

View File

@ -58,6 +58,10 @@
(list->vector (map fixup-sexp (vector->list s)))]
[(box? s)
(box (fixup-sexp (unbox s)))]
[(struct? s)
(apply make-prefab-struct
(prefab-struct-key s)
(cdr (map fixup-sexp (vector->list (struct->vector s)))))]
[(symbol? s)
(case s
[(lvp pat qp literal ooo datum struct-id

View File

@ -224,7 +224,8 @@ with additional fields:
@item{The @racket[pre-amount] field reports place-local memory use
(i.e., not counting the memory use of child places) in bytes at
the time that the @tech{garbage collection} started.}
the time that the @tech{garbage collection} started. Additional
bytes registered via @racket[make-phantom-bytes] are included.}
@item{The @racket[pre-admin-amount] is a larger number that includes
memory use for the garbage collector's overhead, such as space
@ -286,24 +287,46 @@ collection mode, the text has the format
]}
@defproc[(collect-garbage [minor? any/c #f]) void?]{
@defproc[(collect-garbage [request (or/c 'major 'minor 'incremental) 'major]) void?]{
Forces an immediate @tech{garbage collection} (unless garbage
collection is disabled by setting @envvar{PLTDISABLEGC}). Some
effectively unreachable data may remain uncollected, because the
collector cannot prove that it is unreachable.
Requests an immediate @tech{garbage collection} or requests a
garbage-collection mode, depending on @racket[request]:
If @racket[minor?] is false, then a major collection is
run. Otherwise, a minor collection is run or no collection is run. (No
collection occurs when @racket[(system-type 'gc)] returns
@racket['cgc] or when a normally scheduled minor collection would
cause a major collection.) Minor collections run by
@racket[collect-garbage] do not cause major collections to run any
sooner than they would have otherwise.
@itemlist[
@item{@racket['major] --- Forces a ``major'' collection, which
inspects all memory. Some effectively unreachable data may
remain uncollected, because the collector cannot prove that it
is unreachable.
This mode of @racket[collect-garbage] procedure provides some
control over the timing of collections, but garbage will
obviously be collected even if this procedure is never
called---unless garbage collection is disabled by setting
@envvar{PLTDISABLEGC}.}
@item{@racket['minor] --- Requests a ``minor'' collection, which
mostly inspects only recent allocations. If minor collection is
not supported (e.g., when @racket[(system-type 'gc)] returns
@racket['cgc]) or if the next collection must be a major
collection, no collection is performed. More generally, minor collections
triggered by @racket[(collect-garbage 'minor)] do not cause
major collections any sooner than they would occur otherwise.}
@item{@racket['incremental] --- Requests that each minor
collection performs incremental work toward a major collection.
This incremental-mode request expires at the next major
collection.
The intent of incremental mode is to significantly reduce pause
times due to major collections, but incremental mode typically
implies longer minor-collection times and higher memory use.}
]
@history[#:changed "6.3" @elem{Added the @racket[request] argument.}
#:changed "6.3.0.2" @elem{Added @racket['incremental] mode.}]}
The @racket[collect-garbage] procedure provides some control over the
timing of collections, but garbage will obviously be collected even if
this procedure is never called (unless garbage collection is disabled).}
@defproc[(current-memory-use [cust custodian? #f]) exact-nonnegative-integer?]{

View File

@ -21,16 +21,22 @@ otherwise.}
@defproc[(make-empty-namespace) namespace?]{
Creates a new namespace that is empty, and whose @tech{module
Creates a new @tech{namespace} that is empty, and whose @tech{module
registry} contains no mappings. The namespace's @tech{base phase} is
the same as the @tech{base phase} of the @tech{current
namespace}. Attach modules from an existing namespace to the new one
with @racket[namespace-attach-module].}
with @racket[namespace-attach-module].
The new namespace is associated with a new @deftech{root namespace},
which has the same @tech{module registry} as the returned namespace
and has a @tech{base phase} of 0. The new @tech{root namespace} is
the same as the returned namespace if both have @tech{base phase} 0.}
@defproc[(make-base-empty-namespace) namespace?]{
Creates a new empty namespace, but with @racketmodname[racket/base]
Creates a new empty @tech{namespace} like @racket[make-empty-namespace],
but with @racketmodname[racket/base]
attached. The namespace's @tech{base phase} is the same as the
@tech{phase} in which the @racket[make-base-empty-namespace]
function was created.}
@ -38,7 +44,8 @@ function was created.}
@defproc[(make-base-namespace) namespace?]{
Creates a new namespace with @racketmodname[racket/base] attached and
Creates a new @tech{namespace} like @racket[make-empty-namespace], but
with @racketmodname[racket/base] attached and
@racket[require]d into the top-level environment. The namespace's
@tech{base phase} is the same as the @tech{phase} in which the
@racket[make-base-namespace] function was created.}
@ -62,7 +69,8 @@ Returns @racket[#t] if @racket[v] is a namespace-anchor value,
@defproc[(namespace-anchor->empty-namespace [a namespace-anchor?]) namespace?]{
Returns an empty namespace that shares a @tech{module registry} with
Returns an empty namespace that shares a @tech{module registry}
and @tech{root namespace} with
the source of the anchor, and whose @tech{base phase} is the
@tech{phase} in which the anchor was created.

View File

@ -13,7 +13,7 @@
For information about TCP in general, see @italic{TCP/IP Illustrated,
Volume 1} by W. Richard Stevens.
@defproc[(tcp-listen [port-no (integer-in 0 65535)]
@defproc[(tcp-listen [port-no listen-port-number?]
[max-allow-wait exact-nonnegative-integer? 4]
[reuse? any/c #f]
[hostname (or/c string? #f) #f])
@ -67,9 +67,9 @@ A TCP listener is @tech{ready for synchronization} when
@defproc[(tcp-connect [hostname string?]
[port-no (integer-in 1 65535)]
[port-no port-number?]
[local-hostname (or/c string? #f) #f]
[local-port-no (or/c (integer-in 1 65535) #f)
[local-port-no (or/c port-number? #f)
#f])
(values input-port? output-port?)]{
@ -121,9 +121,9 @@ If a connection cannot be established by @racket[tcp-connect], the
@exnraise[exn:fail:network].}
@defproc[(tcp-connect/enable-break [hostname string?]
[port-no (integer-in 1 65535)]
[port-no port-number?]
[local-hostname (or/c string? #f) #f]
[local-port-no (or/c (integer-in 1 65535) #f)])
[local-port-no (or/c port-number? #f)])
(values input-port? output-port?)]{
Like @racket[tcp-connect], but breaking is enabled (see
@ -224,8 +224,8 @@ connections, so @racket[tcp-abandon-port] is equivalent to
@defproc[(tcp-addresses [tcp-port (or/c tcp-port? tcp-listener?)]
[port-numbers? any/c #f])
(or/c (values string? string?)
(values string? (integer-in 1 65535)
string? (integer-in 0 65535)))]{
(values string? port-number?
string? listen-port-number?))]{
Returns two strings when @racket[port-numbers?] is @racket[#f] (the
default). The first string is the Internet address for the local
@ -255,6 +255,18 @@ port returned by @racket[tcp-accept], @racket[tcp-connect],
@racket[tcp-accept/enable-break], or
@racket[tcp-connect/enable-break]---@racket[#f] otherwise.}
@defthing[port-number? contract?]{
Equivalent to @racket[(between/c 1 65535)].
@history[#:added "6.3"]{}
}
@defthing[listen-port-number? contract?]{
Equivalent to @racket[(between/c 0 65535)].
@history[#:added "6.3"]{}
}
@;------------------------------------------------------------------------
@section[#:tag "udp"]{UDP}
@ -264,7 +276,7 @@ For information about UDP in general, see @italic{TCP/IP Illustrated,
Volume 1} by W. Richard Stevens.
@defproc[(udp-open-socket [family-hostname (or/c string? #f) #f]
[family-port-no (or/c (integer-in 1 65535) #f) #f])
[family-port-no (or/c port-number? #f) #f])
udp?]{
Creates and returns a @deftech{UDP socket} to send and receive
@ -285,7 +297,7 @@ non-@racket[#f], then the socket's protocol family is IPv4.}
@defproc[(udp-bind! [udp-socket udp?]
[hostname-string (or/c string? #f)]
[port-no (integer-in 0 65535)]
[port-no listen-port-number?]
[reuse? any/c #f])
void?]{
@ -327,8 +339,7 @@ machine when using UDP multicast.}
@defproc[(udp-connect! [udp-socket udp?]
[hostname-string (or/c string? #f)]
[port-no (or/c (integer-in 1 65535)
#f)])
[port-no (or/c port-number? #f)])
void?]{
Connects the socket to the indicated remote address and port if
@ -351,7 +362,7 @@ If @racket[udp-socket] is closed, the @exnraise[exn:fail:network].}
@defproc[(udp-send-to [udp-socket udp?]
[hostname string?]
[port-no (integer-in 1 65535)]
[port-no port-number?]
[bstr bytes?]
[start-pos exact-nonnegative-integer? 0]
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
@ -385,7 +396,7 @@ connected, and the datagram goes to the connection target. If
@defproc[(udp-send-to* [udp-socket udp?]
[hostname string?]
[port-no (integer-in 1 65535)]
[port-no port-number?]
[bstr bytes?]
[start-pos exact-nonnegative-integer? 0]
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
@ -406,7 +417,7 @@ never blocks and returns @racket[#f] or @racket[#t].}
@defproc[(udp-send-to/enable-break [udp-socket udp?]
[hostname string?]
[port-no (integer-in 1 65535)]
[port-no port-number?]
[bstr bytes?]
[start-pos exact-nonnegative-integer? 0]
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
@ -435,7 +446,7 @@ Like @racket[udp-send], except that breaks are enabled like
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
(values exact-nonnegative-integer?
string?
(integer-in 1 65535))]{
port-number?)]{
Accepts up to @math{@racket[end-pos]-@racket[start-pos]} bytes of
@racket[udp-socket]'s next incoming datagram into @racket[bstr],
@ -462,7 +473,7 @@ the length of @racket[bstr], the @exnraise[exn:fail:contract].}
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
(values (or/c exact-nonnegative-integer? #f)
(or/c string? #f)
(or/c (integer-in 1 65535) #f))]{
(or/c port-number? #f))]{
Like @racket[udp-receive!], except that it never blocks. If no
datagram is available, the three result values are all @racket[#f].}
@ -473,7 +484,7 @@ datagram is available, the three result values are all @racket[#f].}
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
(values exact-nonnegative-integer?
string?
(integer-in 1 65535))]{
port-number?)]{
Like @racket[udp-receive!], but breaking is enabled (see
@secref["breakhandler"]) while trying to receive the datagram. If
@ -523,7 +534,7 @@ would block. The @tech{synchronization result} is the event itself.
@defproc[(udp-send-to-evt [udp-socket udp?]
[hostname string?]
[port-no (integer-in 1 65535)]
[port-no port-number?]
[bstr bytes?]
[start-pos exact-nonnegative-integer? 0]
[end-pos exact-nonnegative-integer? (bytes-length bstr)])
@ -570,8 +581,8 @@ content is not modified if the event is not chosen.)}
@defproc[(udp-addresses [udp-port udp?]
[port-numbers? any/c #f])
(or/c (values string? string?)
(values string? (integer-in 0 65535)
string? (integer-in 0 65535)))]{
(values string? listen-port-number?
string? listen-port-number?))]{
Returns two strings when @racket[port-numbers?] is @racket[#f] (the
default). The first string is the Internet address for the local

View File

@ -4,7 +4,8 @@
racket/flonum
racket/fixnum
racket/unsafe/ops
racket/require))
racket/require
racket/random))
@(define math-eval (make-base-eval))
@(interaction-eval #:eval math-eval (require racket/math))
@ -835,6 +836,8 @@ both in binary and as integers.
@; ------------------------------------------------------------------------
@subsection{Random Numbers}
@margin-note{When security is a concern, use @racket[crypto-random-bytes] instead of @racket[random].}
@defproc*[([(random [k (integer-in 1 4294967087)]
[rand-gen pseudo-random-generator?
(current-pseudo-random-generator)])
@ -855,7 +858,6 @@ internal state for generating numbers. The random number generator
uses a 54-bit version of L'Ecuyer's MRG32k3a algorithm
@cite["L'Ecuyer02"].}
@defproc[(random-seed [k (integer-in 1 (sub1 (expt 2 31)))])
void?]{
@ -923,6 +925,28 @@ range @racket[0] to @racket[4294944442], inclusive; at least one of
the first three integers is non-zero; and at least one of the last
three integers is non-zero. Otherwise, the result is @racket[#f].}
@; ------------------------------------------------------------------------
@subsection{System-Provided Randomness}
@defmodule[racket/random]{The @racketmodname[racket/random] module
provides an interface to randomness from the underlying operating
system. Use @racket[crypto-random-bytes]
instead of @racket[random] wherever security is a concern.}
@defproc[(crypto-random-bytes [n exact-positive-integer?])
bytes?]{
Returns @racket[n] random bytes. On Unix systems, the bytes are
obtained from @filepath{/dev/urandom}, while Windows uses
the @tt{RtlGenRand} system function.
@examples[
(eval:alts (crypto-random-bytes 14) #"\0\1\1\2\3\5\b\r\25\"7Y\220\351")
]
@history[#:added "6.3"]}
@; ------------------------------------------------------------------------
@subsection{Number--String Conversions}

View File

@ -0,0 +1,18 @@
#lang scribble/doc
@(require "mz.rkt"
(for-label racket/os))
@title[#:tag "os-lib"]{Additional Operating System Functions}
@defmodule[racket/os]{The @racketmodname[racket/os] library
additional functions for querying the operating system.}
@history[#:added "6.3"]
@defproc[(gethostname) string?]{
Returns a string for the current machine's hostname (including its domain).
}
@defproc[(getpid) exact-integer?]{
Returns an integer identifying the current process within the operating system.
}

View File

@ -14,3 +14,4 @@
@include-section["envvars.scrbl"]
@include-section["runtime.scrbl"]
@include-section["cmdline.scrbl"]
@include-section["os-lib.scrbl"]

View File

@ -875,7 +875,9 @@ Returns a list that is the same as @racket[lst] except at the specified index.
The element at the specified index is @racket[(updater (list-ref lst pos))].
@examples[#:eval list-eval
(list-update '(zero one two) 1 symbol->string)]}
(list-update '(zero one two) 1 symbol->string)]
@history[#:added "6.3"]{}
}
@defproc[(list-set [lst list?]
[pos (and/c (>=/c 0) (</c (length lst)))]
@ -886,7 +888,9 @@ Returns a list that is the same as @racket[lst] except at the specified index.
The element at the specified index is @racket[value].
@examples[#:eval list-eval
(list-set '(zero one two) 2 "two")]}
(list-set '(zero one two) 2 "two")]
@history[#:added "6.3"]{}
}
@defproc[(take [lst any/c] [pos exact-nonnegative-integer?])
list?]{
@ -1019,6 +1023,7 @@ combined with the from-right functionality of @racket[take-right],
@examples[#:eval list-eval
(list-prefix? '(1 2) '(1 2 3 4 5))
]
@history[#:added "6.3"]{}
}
@defproc[(take-common-prefix [l list?] [r list?]
@ -1030,6 +1035,7 @@ combined with the from-right functionality of @racket[take-right],
@examples[#:eval list-eval
(take-common-prefix '(a b c d) '(a b x y z))
]
@history[#:added "6.3"]{}
}
@defproc[(drop-common-prefix [l list?] [r list?]
@ -1042,6 +1048,7 @@ combined with the from-right functionality of @racket[take-right],
@examples[#:eval list-eval
(drop-common-prefix '(a b c d) '(a b x y z))
]
@history[#:added "6.3"]{}
}
@defproc[(split-common-prefix [l list?] [r list?]
@ -1054,6 +1061,7 @@ combined with the from-right functionality of @racket[take-right],
@examples[#:eval list-eval
(split-common-prefix '(a b c d) '(a b x y z))
]
@history[#:added "6.3"]{}
}
@ -1135,6 +1143,7 @@ use a dictionary for speed.
(check-duplicates '(1 2 3 4 5 6)
(lambda (x y) (equal? (modulo x 3) (modulo y 3))))
]
@history[#:added "6.3"]{}
}
@defproc[(remove-duplicates [lst list?]
@ -1299,6 +1308,7 @@ in order of first appearance in the input.
@examples[#:eval list-eval
(group-by (lambda (x) (modulo x 3)) '(1 2 1 2 54 2 5 43 7 2 643 1 2 0))
]
@history[#:added "6.3"]{}
}
@defproc[(cartesian-product [lst list?] ...)
@ -1310,6 +1320,7 @@ Computes the n-ary cartesian product of the given lists.
(cartesian-product '(1 2 3) '(a b c))
(cartesian-product '(4 5 6) '(d e f) '(#t #f))
]
@history[#:added "6.3"]{}
}
@defproc[(remf [pred procedure?]
@ -1322,7 +1333,7 @@ for which @racket[pred] produces a true value.
#:eval list-eval
(remf negative? '(1 -2 3 4 -5))
]
@history[#:added "6.3"]{}
}
@defproc[(remf* [pred procedure?]
@ -1335,7 +1346,7 @@ produces a true value.
#:eval list-eval
(remf* negative? '(1 -2 3 4 -5))
]
@history[#:added "6.3"]{}
}

View File

@ -240,10 +240,16 @@ The @racket[dynamic-place*] binding is protected in the same way as
expressions with @racket[id] bound to a place channel. The
@racket[body]s close only over @racket[id] plus the top-level
bindings of the enclosing module, because the
@racket[body]s are lifted to a function that is exported by
the module. The result of @racket[place] is a place descriptor,
@racket[body]s are lifted to a submodule.
The result of @racket[place] is a place descriptor,
like the result of @racket[dynamic-place].
The generated submodule has the name @racketidfont{place-body-@racket[_n]}
for an integer @racket[_n], and the submodule exports a @racket[main]
function that takes a place channel for the new place. The submodule
is not intended for use, however, except by the expansion of the
@racket[place] form.
The @racket[place] binding is protected in the same way as
@racket[dynamic-place].}

View File

@ -54,14 +54,21 @@ Same as @racket[pretty-print], but @racket[v] is printed like
@racket[display] instead of like @racket[print].}
@defproc[(pretty-format [v any/c] [columns exact-nonnegative-integer? (pretty-print-columns)])
@defproc[(pretty-format [v any/c] [columns exact-nonnegative-integer? (pretty-print-columns)]
[#:mode mode (or/c 'print 'write 'display) 'print])
string?]{
Like @racket[pretty-print], except that it returns a string containing
the pretty-printed value, rather than sending the output to a port.
The optional argument @racket[columns] argument is used to
parameterize @racket[pretty-print-columns].}
parameterize @racket[pretty-print-columns].
The keyword argument @racket[mode] controls whether printing is done like
either @racket[pretty-print] (the default), @racket[pretty-write] or
@racket[pretty-display].
@history[#:changed "6.3" @elem{Added a @racket[mode] argument.}]}
@defproc[(pretty-print-handler [v any/c]) void?]{

View File

@ -83,7 +83,7 @@ the sense of @racket[promise-running?] and @racket[promise-forced?].}
@defproc[(promise/name? [promise any/c]) boolean?]{
Returns @racket[#t] if @racket[promise] is a promise created with @racket[delay/name].
@history[#:added "6.2.900.5"]
@history[#:added "6.3"]
}
@defform[(delay/strict body ...+)]{

View File

@ -121,7 +121,9 @@ See @secref["readtables"] for an extended example that uses
(or/c (any/c any/c . -> . any) #f)]{
Reads from @racket[in] in the same way as @racket[read], but stopping as
soon as a @tech{reader language} (or its absence) is determined.
soon as a @tech{reader language} (or its absence) is determined, and
using the @tech{current namespace} to load a reader module instead
of its @tech{root namespace} (if those are different).
A @deftech{reader language} is specified by @litchar{#lang} or
@litchar{#!} (see @secref["parse-reader"]) at the beginning of the

View File

@ -866,7 +866,8 @@ and passes it to the procedure that is the value of the
module path. The module path is passed to @racket[dynamic-require]
with either @racket['read] or @racket['read-syntax] (depending on
whether the reader is in @racket[read] or @racket[read-syntax]
mode).
mode). The module is loaded in a @tech{root namespace} of the
@tech{current namespace}.
The arity of the resulting procedure determines whether it accepts
extra source-location information: a @racketidfont{read} procedure

View File

@ -1,5 +1,6 @@
#lang scribble/doc
@(require "mz.rkt")
@(require "mz.rkt"
(for-label setup/cross-system))
@title[#:tag "runtime"]{Environment and Runtime Information}
@ -9,7 +10,8 @@
(or/c symbol? string? bytes? exact-positive-integer? vector?)]{
Returns information about the operating system, build mode, or machine
for a running Racket.
for a running Racket. (Installation tools should use @racket[cross-system-type],
instead, to support cross-installation.)
In @indexed-racket['os] mode,
the possible symbol results are:
@ -117,7 +119,10 @@ The optional @racket[mode] argument specifies the relevant
garbage-collection variant, which one of the possible results of
@racket[(system-type 'gc)]: @racket['cgc] or @racket['3m]. It can also
be @racket[#f], in which case the result is independent of the
garbage-collection variant.}
garbage-collection variant.
Installation tools should use @racket[cross-system-library-subpath],
instead, to support cross-installation.}
@defproc[(version) (and/c string? immutable?)]{

View File

@ -47,7 +47,8 @@ function for further evaluation.
The returned evaluator operates in an isolated and limited
environment. In particular, filesystem access is restricted, which may
interfere with using modules from the filesystem. See below for
interfere with using modules from the filesystem that are not
in a @tech{collection}. See below for
information on the @racket[allow-for-require],
@racket[allow-for-load], and @racket[allow-read] arguments. When
@racket[language] is a module path or when @racket[requires] is
@ -210,15 +211,17 @@ create the sandbox is higher than the limit, then
The @racket[allow-for-require] and @racket[allow-for-load] arguments
adjust filesystem permissions to extend the set of files that
are usable by the evaluator. The @racket[allow-for-require] argument lists
modules that can be @racket[require]d along with their imports
(transitively). The @racket[allow-for-load] argument lists files that can
are usable by the evaluator. Modules that are in a collection
are automatically accessible, but the @racket[allow-for-require] argument lists
additional modules that can be @racket[require]d along with their imports
(transitively) through a filesystem path. The @racket[allow-for-load] argument
similarly lists files that can
be @racket[load]ed. (The precise permissions needed for
@racket[require] versus @racket[load] can differ.) The
@racket[allow-read] argument is for backward compatibility, only; each
@racket[module-path?] element of @racket[allow-read] is effectively
moved to @racket[allow-for-require], while other elements are moved to
@racket[all-for-load].
@racket[allow-for-load].
The sandboxed environment is well isolated, and the evaluator function
essentially sends it an expression and waits for a result. This form

View File

@ -614,7 +614,7 @@ each element in the sequence.
values in the sequence), the @exnraise[exn:fail:contract].}
@; ----------------------------------------------------------------------
@subsection[#:tag "more-sequences"]{Sequence Combinations & Contract}
@subsection[#:tag "more-sequences"]{Additional Sequence Operations}
@note-lib[racket/sequence]
@ -780,6 +780,32 @@ If @racket[min-count] is a number, the stream is required to have at least that
}
@subsubsection{Additional Sequence Constructors}
@defproc[(in-syntax [stx syntax?]) sequence?]{
Produces a sequence whose elements are the successive subparts of
@racket[stx].
Equivalent to @racket[(syntax->list lst)].
@speed[in-syntax "syntax"]
@examples[#:eval sequence-evaluator
(for/list ([x (in-syntax #'(1 2 3))])
x)]
@history[#:added "6.3"]}
@defproc[(in-slice [length exact-positive-integer?] [seq sequence?])
sequence?]{
Returns a sequence whose elements are lists with the first @racket[length]
elements of @racket[seq], then the next @racket[length] and so on.
@examples[#:eval sequence-evaluator
(for/list ([e (in-slice 3 (in-range 8))]) e)
]
@history[#:added "6.3"]
}
@; ======================================================================
@section[#:tag "streams"]{Streams}

View File

@ -449,7 +449,7 @@ Supported for any @racket[st] that @impl{implements} @racket[set-add] and @supp
(set-union (set 1 2) (seteq 2 3)) (code:comment "Sets of different types cannot be unioned.")
]}
@defproc[(set-union! [st0 generic-set?] [st generic-set?] ...) generic-set?]{
@defproc[(set-union! [st0 generic-set?] [st generic-set?] ...) void?]{
Adds the elements from all of the @racket[st]s to @racket[st0].
@ -483,7 +483,7 @@ both @racket[set-clear] and @racket[set-add], and @supp{supports} @racket[set->s
}
@defproc[(set-intersect! [st0 generic-set?] [st generic-set?] ...) generic-set?]{
@defproc[(set-intersect! [st0 generic-set?] [st generic-set?] ...) void?]{
Removes every element from @racket[st0] that is not contained by all of the
@racket[st]s.

View File

@ -177,7 +177,8 @@ flags:
embedded in the executable from file position @nonterm{n} to
@nonterm{m} and from @nonterm{m} to @nonterm{p}. (On Mac OS X,
@nonterm{n}, @nonterm{m}, and @nonterm{p} are relative to a
@tt{__PLTSCHEME} segment in the executable.) The first range
@tt{__PLTSCHEME} segment in the executable. On Windows,
they are relative to a resource of type 257 and ID 1.) The first range
is loaded in every new @tech{place}, and any modules declared
in that range are considered predefined in the sense of
@racket[module-predefined?]. This option is normally embedded

View File

@ -91,7 +91,7 @@ Returns an immutable string with the same content as
characters long, and that contains the same characters as
@racket[str] from @racket[start] inclusive to @racket[end] exclusive.
The first position in a string corresponds to @racket[0], so
the @racket[start] and @racket[end] arguments so they must be less than or
the @racket[start] and @racket[end] arguments must be less than or
equal to the length of @racket[str], and @racket[end] must be greater
than or equal to @racket[start], otherwise the
@exnraise[exn:fail:contract].
@ -507,6 +507,30 @@ trimmed (which is an alternative to using a @tech{regular expression}
(string-trim "aaaxaayaa" "aa")
]}
@defproc[(non-empty-string? [x any/c]) boolean?]{
Returns @racket[#t] if @racket[x] is a string and is not empty;
returns @racket[#f] otherwise.
@history[#:added "6.3"]{}
}
@deftogether[(
@defproc[(string-contains? [s string?] [contained string?]) boolean?]
@defproc[(string-prefix? [s string?] [prefix string?]) boolean?]
@defproc[(string-suffix? [s string?] [suffix string?]) boolean?])]{
Checks whether @racket[s] includes at any location, start with, or ends with
the second argument, respectively.
@mz-examples[#:eval string-eval
(string-prefix? "Racket" "R")
(string-prefix? "Jacket" "R")
(string-suffix? "Racket" "et")
(string-contains? "Racket" "ack")
]
@history[#:added "6.3"]{}
}
@; ----------------------------------------
@include-section["format.scrbl"]

View File

@ -135,7 +135,8 @@ The @racket[inspector] argument normally controls access to reflective
information about the structure type and its instances; see
@secref["inspectors"] for more information. If @racket[inspector] is
@racket['prefab], then the resulting @tech{prefab} structure type and
its instances are always transparent.
its instances are always transparent. If @racket[inspector] is
@racket[#f], then the structure type's instances are transparent.
If @racket[proc-spec] is an integer or procedure, instances of the
structure type act as procedures. See @racket[prop:procedure] for
@ -606,6 +607,76 @@ key, @racket[#f] otherwise.
See @racket[make-prefab-struct] for a description of valid key shapes.}
@subsection{Additional Structure Utilities}
@note-lib-only[racket/struct]
@defproc[(make-constructor-style-printer
[get-constructor (-> any/c (or/c symbol? string?))]
[get-contents (-> any/c sequence?)])
(-> any/c output-port? (or/c #t #f 0 1) void?)]{
Produces a function suitable as a value for @racket[prop:custom-write]. The
function prints values in ``constructor style.'' When the value is
@racket[print]ed as an expression, it is shown as an application of the
constructor (as returned by @racket[get-constructor]) to the contents (as
returned by @racket[get-contents]). When given to @racket[write], it is shown as
an unreadable value with the constructor separated from the contents by a colon.
@(struct-eval '(require racket/struct racket/pretty))
@examples[#:eval struct-eval
(struct point (x y)
#:property prop:custom-write
(make-constructor-style-printer
(lambda (obj) 'point)
(lambda (obj) (list (point-x obj) (point-y obj)))))
(print (point 1 2))
(write (point 1 2))
]
The function also cooperates with @racket[pretty-print]:
@examples[#:eval struct-eval
(parameterize ((pretty-print-columns 10))
(pretty-print (point #e3e6 #e4e6)))
(parameterize ((pretty-print-columns 10))
(pretty-write (point #e3e6 #e4e6)))
]
@history[#:added "6.3"]{}
}
@defproc[(struct->list [v any/c]
[#:on-opaque on-opaque (or/c 'error 'return-false 'skip) 'error])
(or/c list? #f)]{
Returns a list containing the struct instance @racket[v]'s
fields. Unlike @racket[struct->vector], the struct name itself is not
included.
If any fields of @racket[v] are inaccessible via the current inspector
the behavior of @racket[struct->list] is determined by
@racket[on-opaque]. If @racket[on-opaque] is @racket['error] (the
default), an error is raised. If it is @racket['return-false],
@racket[struct->list] returns @racket[#f]. If it is @racket['skip],
the inaccessible fields are omitted from the list.
@examples[#:eval struct-eval
(define-struct open (u v) #:transparent)
(struct->list (make-open 'a 'b))
(struct->list #s(pre 1 2 3))
(define-struct (secret open) (x y))
(struct->list (make-secret 0 1 17 22))
(struct->list (make-secret 0 1 17 22) #:on-opaque 'return-false)
(struct->list (make-secret 0 1 17 22) #:on-opaque 'skip)
(struct->list 'not-a-struct #:on-opaque 'return-false)
(struct->list 'not-a-struct #:on-opaque 'skip)
]
@history[#:added "6.3"]{}
}
@;------------------------------------------------------------------------
@section[#:tag "structinfo"]{Structure Type Transformer Binding}

View File

@ -38,9 +38,7 @@ Returns @racket[#t] if @racket[v] is a @tech{syntax object} and
Returns the source for the @tech{syntax object} @racket[stx], or @racket[#f]
if none is known. The source is represented by an arbitrary value
(e.g., one passed to @racket[read-syntax]), but it is typically a file
path string. Source-location information is dropped for a syntax
object that is marshaled as part of compiled code; see also
@racket[current-compile].}
path string.}
@defproc[(syntax-line [stx syntax?])
@ -50,8 +48,7 @@ Returns the line number (positive exact integer) for the start of the
@tech{syntax object} in its source, or @racket[#f] if the line number or
source is unknown. The result is @racket[#f] if and only if
@racket[(syntax-column stx)] produces @racket[#f]. See also
@secref["linecol"], and see @racket[syntax-source] for information
about marshaling compiled @tech{syntax object}s.}
@secref["linecol"].}
@defproc[(syntax-column [stx syntax?])
@ -61,8 +58,7 @@ Returns the column number (non-negative exact integer) for the start
of the @tech{syntax object} in its source, or @racket[#f] if the source
column is unknown. The result is @racket[#f] if and only if
@racket[(syntax-line stx)] produces @racket[#f]. See also
@secref["linecol"], and see @racket[syntax-source] for information
about marshaling compiled @tech{syntax object}s.}
@secref["linecol"].}
@defproc[(syntax-position [stx syntax?])
@ -70,9 +66,7 @@ about marshaling compiled @tech{syntax object}s.}
Returns the character position (positive exact integer) for the start
of the @tech{syntax object} in its source, or @racket[#f] if the source
position is unknown. See also @secref["linecol"], and see
@racket[syntax-source] for information about marshaling compiled
@tech{syntax object}s.}
position is unknown. See also @secref["linecol"].}
@defproc[(syntax-span [stx syntax?])
@ -80,8 +74,7 @@ position is unknown. See also @secref["linecol"], and see
Returns the span (non-negative exact integer) in characters of the
@tech{syntax object} in its source, or @racket[#f] if the span is
unknown. See also @racket[syntax-source] for information about
marshaling compiled @tech{syntax object}s.}
unknown.}
@defproc[(syntax-original? [stx syntax?]) boolean?]{
@ -95,14 +88,19 @@ object was introduced by a syntax transformer; see
This predicate can be used to distinguish @tech{syntax object}s in an expanded
expression that were directly present in the original expression, as
opposed to @tech{syntax object}s inserted by macros.}
opposed to @tech{syntax object}s inserted by macros.
The (hidden) property to represent original syntax is dropped for a
syntax object that is marshaled as part of compiled code; see also
@racket[current-compile].}
@defproc[(syntax-source-module [stx syntax?] [source? any/c #f])
(or/c module-path-index? symbol? path? resolved-module-path? #f)]{
Returns an indication of the module whose source contains
@racket[stx], or @racket[#f] if @racket[stx] has no source module. If
@racket[stx], or @racket[#f] if no source module for @racket[stx]
can be inferred from its lexical context. If
@racket[source?] is @racket[#f], then result is a module path index or
symbol (see @secref["modpathidx"]) or a @tech{resolved module path}; if @racket[source?] is true, the
result is a path or symbol corresponding to the loaded module's

View File

@ -6,8 +6,9 @@
Every syntax object has an associated @deftech{syntax property} list,
which can be queried or extended with
@racket[syntax-property]. Properties are not preserved for a
@racket[syntax-quoted] syntax object in a compiled form that is
marshaled to a byte string.
syntax object in a compiled form that is
marshaled to a byte string or @filepath{.zo} file, except for a @racket['paren-shape]
property value of @racket[#\[] or @racket[#\{].
In @racket[read-syntax], the reader attaches a @racket['paren-shape]
property to any pair or vector syntax object generated from parsing a
@ -123,7 +124,7 @@ in @racket[stx]. @tech{Uninterned} symbols (see @secref["symbols"])
are not included in the result list.}
@defproc[(syntax-track-origin [new-stx syntax?] [orig-stx syntax?] [id-stx syntax?])
@defproc[(syntax-track-origin [new-stx syntax?] [orig-stx syntax?] [id-stx identifier?])
any]{
Adds properties to @racket[new-stx] in the same way that macro

View File

@ -181,8 +181,9 @@ A @tech{structure type property} to identify structure types that act
as @tech{rename transformers} like the ones created by
@racket[make-rename-transformer].
The property value must be an exact integer or an identifier
@tech{syntax object}. In the former case, the integer designates a
The property value must be an exact integer, an identifier
@tech{syntax object}, or a procedure that takes one argument.
In the former case, the integer designates a
field within the structure that should contain an identifier; the
integer must be between @racket[0] (inclusive) and the number of
non-automatic fields in the structure type (exclusive, not counting
@ -194,10 +195,38 @@ target for renaming, just like the first argument to
@racket[make-rename-transformer]. If the property value is an integer,
the target identifier is extracted from the structure instance; if the
field value is not an identifier, then an identifier @racketidfont{?}
with an empty context is used, instead.}
with an empty context is used, instead.
If the property value is a procedure that takes one argument, then the procedure
is called to obtain the identifier that the rename transformer will use
as a target identifier. If the procedure returns any value that is not
an identifier, the @racket[exn:fail:contract] exception is raised.
@examples[#:eval stx-eval #:escape UNSYNTAX
(code:comment "Example of a procedure argument for prop:rename-transformer")
(define-syntax slv-1 'first-transformer-binding)
(define-syntax slv-2 'second-transformer-binding)
(begin-for-syntax
(struct slv-cooperator (redirect-to-first?)
#:property prop:rename-transformer
(λ (inst)
(if (slv-cooperator-redirect-to-first? inst)
#'slv-1
#'slv-2))))
(define-syntax (slv-lookup stx)
(syntax-case stx ()
[(_ id)
#`(quote #,(syntax-local-value #'id))]))
(define-syntax slv-inst-1 (slv-cooperator #t))
(define-syntax slv-inst-2 (slv-cooperator #f))
(slv-lookup slv-inst-1)
(slv-lookup slv-inst-2)
]
@history[#:changed "6.3" "the property now accepts a procedure of one argument."]}
@defproc[(local-expand [stx syntax?]
@defproc[(local-expand [stx any/c]
[context-v (or/c 'expression 'top-level 'module 'module-begin list?)]
[stop-ids (or/c (listof identifier?) #f)]
[intdef-ctx (or/c internal-definition-context?
@ -211,7 +240,9 @@ Expands @racket[stx] in the lexical context of the expression
currently being expanded. The @racket[context-v] argument is used as
the result of @racket[syntax-local-context] for immediate expansions;
a list indicates an @tech{internal-definition context}, and more
information on the form of the list is below.
information on the form of the list is below. If @racket[stx] is not
already a @tech{syntax object}, it is coerced with
@racket[(datum->syntax #f stx)] before expansion.
When an identifier in @racket[stop-ids] is encountered by the expander
in a sub-expression, expansions stops for the sub-expression. If
@ -297,7 +328,7 @@ generated value onto that list.
an explicit wrapper.}]}
@defproc[(syntax-local-expand-expression [stx syntax?])
@defproc[(syntax-local-expand-expression [stx any/c])
(values syntax? syntax?)]{
Like @racket[local-expand] given @racket['expression] and an empty
@ -316,7 +347,7 @@ avoids quadratic expansion times when local expansions are nested.
@transform-time[]}
@defproc[(local-transformer-expand [stx syntax?]
@defproc[(local-transformer-expand [stx any/c]
[context-v (or/c 'expression 'top-level list?)]
[stop-ids (or/c (listof identifier?) #f)]
[intdef-ctx (or/c internal-definition-context? #f) #f])
@ -331,7 +362,7 @@ lifted expressions---from calls to
result.}
@defproc[(local-expand/capture-lifts [stx syntax?]
@defproc[(local-expand/capture-lifts [stx any/c]
[context-v (or/c 'expression 'top-level 'module 'module-begin list?)]
[stop-ids (or/c (listof identifier?) #f)]
[intdef-ctx (or/c internal-definition-context? #f) #f]
@ -346,10 +377,15 @@ forms, and the expansion of @racket[stx] is the last expression in the
@racket[begin]. The @racket[lift-ctx] value is reported by
@racket[syntax-local-lift-context] during local expansion. The lifted
expressions are not expanded, but instead left as provided in the
@racket[begin] form.}
@racket[begin] form.
If @racket[context-v] is @racket['top-level] or @racket['module], then
@racket[module] forms can appear in the result as added via
@racket[syntax-local-lift-module]. If @racket[context-v] is
@racket['module], then @racket[module*] forms can appear, too.}
@defproc[(local-transformer-expand/capture-lifts [stx syntax?]
@defproc[(local-transformer-expand/capture-lifts [stx any/c]
[context-v (or/c 'expression 'top-level list?)]
[stop-ids (or/c (listof identifier?) #f)]
[intdef-ctx (or/c internal-definition-context? #f) #f]
@ -453,6 +489,48 @@ provided for backward compatibility; the more general
@history[#:changed "6.3" @elem{Simplified the operation to @tech{scope} removal.}]}
@defthing[prop:expansion-contexts struct-type-property?]{
A @tech{structure type property} to constrain the use of macro
@tech{transformers} and @tech{rename transformers}. The property's
value must be a list of symbols, where the allowed symbols are
@racket['expression], @racket['top-level], @racket['module],
@racket['module-begin], and @racket['definition-context]. Each symbol
corresponds to an expansion context in the same way as for
@racket[local-expand] or as reported by @racket[syntax-local-context],
except that @racket['definition-context] is used (instead of a list)
to represent an @tech{internal-definition context}.
If an identifier is bound to a transformer whose list does not include
a symbol for a particular use of the identifier, then the use is
adjusted as follows:
@;
@itemlist[
@item{In a @racket['module-begin] context, then the use is wrapped in
a @racket[begin] form.}
@item{In a @racket['module], @racket['top-level],
@racket['internal-definition] or context, if
@racket['expression] is present in the list, then the use is
wrapped in an @racket[#%expression] form.}
@item{Otherwise, a syntax error is reported.}
]
The @racket[prop:expansion-contexts] property is most useful in
combination with @racket[prop:rename-transformer], since a general
@tech{transformer} procedure can use @racket[syntax-local-context].
Furthermore, a @racket[prop:expansion-contexts] property makes the
most sense when a @tech{rename transformer}'s identifier has the
@racket['not-free-identifier=?] property, otherwise a definition of
the binding creates a binding alias that effectively routes around the
@racket[prop:expansion-contexts] property.
@history[#:added "6.3"]}
@defproc[(syntax-local-value [id-stx syntax?]
[failure-thunk (or/c (-> any) #f)
#f]
@ -576,6 +654,28 @@ for caching lift information to avoid redundant lifts.
@transform-time[]}
@defproc[(syntax-local-lift-module [stx syntax?])
void?]{
Cooperates with the @racket[module] form or top-level expansion to add
@racket[stx] as a module declaration in the enclosing module or top-level.
The @racket[stx] form must start with @racket[module] or @racket[module*],
where the latter is only allowed within the expansion of a module.
The module is not immediately declared when
@racket[syntax-local-lift-module] returns. Instead, the module
declaration is recorded for processing when expansion returns to the
enclosing module body or top-level sequence.
@transform-time[] If the current expression being transformed is not
within a @racket[module] form or within a top-level expansion, then
the @exnraise[exn:fail:contract]. If @racket[stx] form does start with
@racket[module] or @racket[module*], or if it starts with @racket[module*]
in a top-level context, the @exnraise[exn:fail:contract].
@history[#:added "6.3"]}
@defproc[(syntax-local-lift-module-end-declaration [stx syntax?])
void?]{
@ -601,7 +701,7 @@ then the @exnraise[exn:fail:contract].}
Lifts a @racket[#%require] form corresponding to
@racket[raw-require-spec] (either as a @tech{syntax object} or datum)
to the top-level or to the top of the module currently being expanded
or to an enclosing @racket[begin-for-syntax]..
or to an enclosing @racket[begin-for-syntax].
The resulting syntax object is the same as @racket[stx], except that a
fresh @tech{scope} is added. The same @tech{scope} is
@ -876,7 +976,7 @@ identifiers. Each list of identifiers includes all bindings imported
(into the module being expanded) using the module path
@racket[mod-path], or all modules if @racket[mod-path] is
@racket[#f]. The association list includes all identifiers imported
with a @racket[phase-level] shift, of all shifts if
with a @racket[phase-level] shift, or all shifts if
@racket[phase-level] is @racket[#t].
When an identifier is renamed on import, the result association list

View File

@ -74,7 +74,7 @@ corresponds to the @racket[let] form.
When a @tech{form} parses as the binding of a particular identifier,
parsing updates a global table that maps a combination of an
identifier's @tech{symbol} and @tech{scope set} to it's meaning: a
identifier's @tech{symbol} and @tech{scope set} to its meaning: a
@tech{variable}, a @tech{syntactic form}, or a @tech{transformer}. An
identifier refers to a particular binding when the reference's symbol
and the identifier's symbol are the same, and when the reference's
@ -1101,6 +1101,13 @@ property value of @|void-const| hides a name that would otherwise be
inferred from context (perhaps because a binding identifier's was
automatically generated and should not be exposed).
To support the propagation and merging of consistent properties during
expansions, the value of the @racket['inferred-name] property can be a
tree formed with @racket[cons] where all of the leaves are the same.
For example, @racket[(cons 'name 'name)] is equivalent to
@racket['name], and @racket[(cons (void) (void))] is equivalent to
@|void-const|.
When an inferred name is not available, but a source location is
available, a name is constructed using the source location
information. Inferred and property-assigned names are also available

View File

@ -315,7 +315,7 @@ the submodule. In that case, @racket[begin-for-syntax] forms that wrap
the @racket[module*] form shift the @tech{phase level} of the
enclosing module's bindings relative to the submodule. The macro
expander handles such nesting by shifting the @tech{phase level} of
the @racket[module*] form so that it's body starts at @tech{phase
the @racket[module*] form so that its body starts at @tech{phase
level} 0, expanding, and then reverting the @tech{phase level} shift;
beware that this process can leave @tech{syntax objects} as
@racket['origin] @tech{syntax property} values out-of-sync with the

View File

@ -700,10 +700,21 @@ Expands to a @racket[provide] of all identifiers implied by the
@section[#:tag "unitcontracts"]{Unit Contracts}
@defform/subs[#:literals (import export)
(unit/c (import sig-block ...) (export sig-block ...))
@defform/subs[#:literals (import export values init-depend)
(unit/c
(import sig-block ...)
(export sig-block ...)
init-depends-decl
optional-body-ctc)
([sig-block (tagged-sig-id [id contract] ...)
tagged-sig-id])]{
tagged-sig-id]
[init-depends-decl
code:blank
(init-depend tagged-sig-id ...)]
[optional-body-ctc
code:blank
contract
(values contract ...)])]{
A @deftech{unit contract} wraps a unit and checks both its imported and
exported identifiers to ensure that they match the appropriate contracts.
@ -711,21 +722,30 @@ This allows the programmer to add contract checks to a single unit value
without adding contracts to the imported and exported signatures.
The unit value must import a subset of the import signatures and export a
superset of the export signatures listed in the unit contract. Any
identifier which is not listed for a given signature is left alone.
Variables used in a given @racket[contract] expression first refer to other
variables in the same signature, and then to the context of the
@racket[unit/c] expression.}
superset of the export signatures listed in the unit contract. Additionally,
the unit value must declare initialization dependencies that are a subset of
those specified in the unit contract. Any identifier which is not listed
for a given signature is left alone. Variables used in a given
@racket[contract] expression first refer to other variables in the same
signature, and then to the context of the @racket[unit/c] expression.
If a body contract is specified then the result of invoking the unit value
is wrapped with the given contract, if no body contract is supplied then
no wrapping occurs when the unit value is invoked.}
@defform/subs[#:literals (import export)
@defform/subs[#:literals (import export values)
(define-unit/contract unit-id
(import sig-spec-block ...)
(export sig-spec-block ...)
init-depends-decl
optional-body-ctc
unit-body-expr-or-defn
...)
([sig-spec-block (tagged-sig-spec [id contract] ...)
tagged-sig-spec])]{
tagged-sig-spec]
[optional-body-ctc
code:blank
(code:line #:invoke/contract contract)
(code:line #:invoke/contract (values contract ...))])]{
The @racket[define-unit/contract] form defines a unit compatible with
link inference whose imports and exports are contracted with a unit
contract. The unit name is used for the positive blame of the contract.}
@ -856,6 +876,10 @@ values:
]
Each of the result identifiers is given a lexical context that is
based on @racket[sig-identifier], so the names are suitable for
reference or binding in the context of @racket[sign-identifier].
If @racket[sig-identifier] is not bound to a signature, then the
@exnraise[exn:fail:syntax]. In that case, the given
@racket[err-syntax] argument is used as the source of the error, where

View File

@ -14,6 +14,4 @@
@item{Find and link to good/bad examples in the code base.}
@item{Do we need a discussion of life cycles that start in @tt{unstable}?}
]

View File

@ -482,7 +482,7 @@ mutually recursive functions with modules. This capability is unique to
@image["mut-rec-contracts.png" #:scale .8]{Mutually recursive functions with contracts}
In contrast, submodules act exactly like plain modules when it comes to
contract boundaries. Like @racket[define/contract], a submodue establishes
contract boundaries. Like @racket[define/contract], a submodule establishes
a contract boundary between itself and the rest of the module. Any value
flow between a client module and the submodule is governed by
contracts. Any value flow within the submodule is free of any constraints.

View File

@ -68,7 +68,7 @@ The other arguments have the same meaning as for @racket[expr/c].
(app (lambda (x) 'pear) 5)
]
@history[#:added "6.2.900.6"]{}
@history[#:added "6.3"]{}
}
@close-eval[the-eval]

View File

@ -27,7 +27,7 @@ If the definition is ill-formed, a syntax error is raised. If
an expression context. The default value of @racket[check-context?] is
@racket[#t].
If @racket[opt-kws?] is @racket[#t], then arguments of the form
If @racket[opt+kws?] is @racket[#t], then arguments of the form
@racket[[id expr]], @racket[keyword id], and @racket[keyword [id
expr]] are allowed, and they are preserved in the expansion.}
@ -49,4 +49,4 @@ expr]] are allowed, and they are preserved in the expansion.}
is true for uses of @racket[normalize-definition].
@history[#:added "6.1.1.8"]
}
}

View File

@ -1,5 +1,10 @@
#lang scribble/doc
@(require "common.rkt" (for-label syntax/id-table racket/dict))
@(require "common.rkt"
scribble/eval
(for-label syntax/id-table racket/dict))
@(define id-table-eval (make-base-eval))
@(id-table-eval '(require (for-syntax racket/base syntax/id-table)))
@title[#:tag "idtable"]{Dictionaries with Identifier Keys}
@ -19,6 +24,41 @@ dictionary interface of @racketmodname[racket/dict], so all of the
appropriate generic functions (@racket[dict-ref], @racket[dict-map],
etc) can be used on free-identifier tables.
A caveat for using these tables is that a lookup can fail with
unexpected results if the binding of an identifier changes between
key-value insertion and the lookup.
For example, consider the following use:
@interaction[#:eval id-table-eval
(define-syntax-rule (m)
(begin
(begin-for-syntax
(define table (make-free-id-table))
(code:comment "set table entry to #t")
(free-id-table-set! table #'x #t)
(code:comment "sanity check, it's set to #t")
(displayln (free-id-table-ref table #'x #f)))
(define x 'defined-now)
(begin-for-syntax
(code:comment "might expect to get #t, but prints #f")
(displayln (free-id-table-ref table #'x #f)))))
(m)]
The macro @racket[m] expands to code that initializes an identifier table
at compile-time and inserts a key-value pair for @racket[#'x] and
@racket[#t]. The @racket[#'x] identifier has no binding, however, until
the definition @racket[(define x 'defined-now)] is evaluated.
As a result, the lookup at the end of @racket[m] will return @racket[#f]
instead of @racket[#t] because the binding symbol for @racket[#'x] changes
after the initial key-value pair is put into the table. If the definition
is evaluated @emph{before} the initial insertion, both expressions will
print @racket[#t].
@deftogether[[
@defproc[(make-free-id-table
[init-dict dict? null]
@ -234,3 +274,5 @@ Like the procedures for free-identifier tables
for bound-identifier tables, which use @racket[bound-identifier=?] to
compare keys.
}
@close-eval[id-table-eval]

View File

@ -33,6 +33,8 @@ converted to a run-time exception.
(phase1-eval (extract-struct-info (syntax-local-value #'point))
#:quote quote-syntax)
]
@history[#:added "6.3"]{}
}
@defform[(convert-compile-time-error expr)]{
@ -54,6 +56,8 @@ compile-time error checking like syntax errors:
Without the use of @racket[convert-compile-time-error], the checks
above would not be executed because the test program would not compile.
@history[#:added "6.3"]{}
}
@defform[(convert-syntax-error expr)]{
@ -69,7 +73,7 @@ exactly.
(lambda () (convert-syntax-error (lambda))))
]
@history[#:added "6.2.900.6"]{}
@history[#:added "6.3"]{}
}
@(close-eval the-eval)

View File

@ -364,7 +364,7 @@ For such cases, however, the alternative reader constructor
@racket[make-meta-reader] implements a might tightly controlled
reading of the module language.
@history[#:changed "6.2.900.6" @elem{Added the @racket[#:module-reader] option.}]}
@history[#:changed "6.3" @elem{Added the @racket[#:module-reader] option.}]}
@defproc[(make-meta-reader [self-sym symbol?]

View File

@ -8,13 +8,21 @@
@defproc[(syntax-local-infer-name [stx syntax?] [use-local? any/c #t]) any/c]{
Similar to @racket[syntax-local-name], except that @racket[stx] is
checked for an @racket['inferred-name] property (which overrides any
inferred name). If neither @racket[syntax-local-name] nor
checked for an @racket['inferred-name] property that is a symbol
(which overrides any inferred name) or @|void-const|.
If neither @racket[syntax-local-name] nor
@racket['inferred-name] produce a name, or if the
@racket['inferred-name] property value is @|void-const|, then a name
is constructed from the source-location information in @racket[stx],
if any. If no name can be constructed, the result is @racket[#f].
To support the propagation and merging of consistent properties during
expansions, the value of the @racket['inferred-name] property can be a
tree formed with @racket[cons] where all of the leaves are the same.
For example, @racket[(cons 'name 'name)] is equivalent to
@racket['name], and @racket[(cons (void) (void))] is equivalent to
@|void-const|.
If @racket[use-local?] is @racket[#f], then @racket[syntax-local-name] is
not used. Provide @racket[use-local?] as @racket[#f] to construct a name
for a syntax object that is not an expression currently being expanded.}

View File

@ -6,6 +6,8 @@
"parse-common.rkt"
(for-label syntax/parse/define))
@(define the-eval (make-sp-eval))
@title{Defining Simple Macros}
@defmodule[syntax/parse/define]
@ -22,7 +24,7 @@ Defines a macro named @racket[macro-id]; equivalent to the following:
]
@(the-eval '(require syntax/parse/define))
@myexamples[
@examples[#:eval the-eval
(define-simple-macro (fn x:id rhs:expr) (lambda (x) rhs))
((fn x x) 17)
(fn 1 2)
@ -47,7 +49,7 @@ Defines a macro named @racket[macro-id]; equivalent to:
(syntax-parser parse-option ... clause ...))
]
@myexamples[
@examples[#:eval the-eval
(define-syntax-parser fn3
[(fn3 x:id rhs:expr)
#'(lambda (x) rhs)]
@ -59,3 +61,4 @@ Defines a macro named @racket[macro-id]; equivalent to:
(fn3 a #:b 'c)
]}
@(close-eval the-eval)

View File

@ -6,6 +6,8 @@
"parse-common.rkt"
(for-label racket/class))
@(define the-eval (make-sp-eval))
@title[#:tag "exprc"]{Contracts on Macro Sub-expressions}
Just as procedures often expect certain kinds of values as arguments,
@ -17,7 +19,7 @@ For example, here is a macro @racket[myparameterize] that behaves like
@racket[parameterize] but enforces the @racket[parameter?] contract on
the parameter expressions.
@myinteraction[
@interaction[#:eval the-eval
(define-syntax (myparameterize stx)
(syntax-parse stx
[(_ ((p v:expr) ...) body:expr)
@ -37,3 +39,5 @@ template, the expansion would have used the raw, unchecked
expressions. The @racket[expr/c] syntax class does not change how
pattern variables are bound; it only computes an attribute that
represents the checked expression.
@(close-eval the-eval)

View File

@ -6,6 +6,8 @@
"parse-common.rkt"
(for-label racket/class))
@(define the-eval (make-sp-eval))
@title{Optional Keyword Arguments}
This section explains how to write a macro that accepts (simple)
@ -22,7 +24,7 @@ head-pattern forms are @racket[~seq], @racket[~or], and
Here's one way to do it:
@myinteraction[
@interaction[#:eval the-eval
(define-syntax (mycond stx)
(syntax-parse stx
[(mycond (~or (~seq #:error-on-fallthrough who:expr) (~seq))
@ -47,7 +49,7 @@ argument is omitted. Instead we must write @racket[(attribute who)],
which produces @racket[#f] if matching did not assign a value to the
attribute.
@myinteraction[
@interaction[#:eval the-eval
(mycond [(even? 13) 'blue]
[(odd? 4) 'red])
(mycond #:error-on-fallthrough 'myfun
@ -62,7 +64,7 @@ There's a simpler way of writing the @racket[~or] pattern above:
Yet another way is to introduce a @tech{splicing syntax class}, which
is like an ordinary syntax class but for head patterns.
@myinteraction[
@interaction[#:eval the-eval
(define-syntax (mycond stx)
(define-splicing-syntax-class maybe-fallthrough-option
@ -84,3 +86,5 @@ syntax class's variants. (This is possible to do in the inline pattern
version too, using @racket[~and] and @racket[~parse], just less
convenient.) Splicing syntax classes also closely parallel the style
of grammars in macro documentation.
@(close-eval the-eval)

View File

@ -6,6 +6,8 @@
"parse-common.rkt"
(for-label racket/class))
@(define the-eval (make-sp-eval))
@title{More Keyword Arguments}
This section shows how to express the syntax of @racket[struct]'s
@ -15,7 +17,7 @@ The part of @racket[struct]'s syntax that is difficult to specify is
the sequence of struct options. Let's get the easy part out of the way
first.
@myinteraction[
@interaction[#:eval the-eval
(define-splicing-syntax-class maybe-super
(pattern (~seq super:id))
(pattern (~seq)))
@ -135,3 +137,5 @@ both @racket[#:guard] and @racket[#:property]. Repetition constraints
cannot express arbitrary incompatibility relations. The best way to
handle such constraints is with a side condition using
@racket[#:fail-when].
@(close-eval the-eval)

View File

@ -6,6 +6,8 @@
"parse-common.rkt"
(for-label racket/class))
@(define the-eval (make-sp-eval))
@title{Phases and Reusable Syntax Classes}
As demonstrated in the @secref{stxparse-intro}, the simplest place to
@ -17,7 +19,7 @@ classes requires some awareness of the Racket @tech[#:doc '(lib
syntax class defined immediately within a module cannot be used by
macros in the same module; it is defined at the wrong phase.
@myinteraction[
@interaction[#:eval the-eval
(module phase-mismatch-mod racket
(require syntax/parse (for-syntax syntax/parse))
(define-syntax-class foo
@ -37,7 +39,7 @@ phase level incompatibility.)
The phase level mismatch is easily remedied by putting the syntax
class definition within a @racket[begin-for-syntax] block:
@myinteraction[
@interaction[#:eval the-eval
(module phase-ok-mod racket
(require (for-syntax syntax/parse))
(begin-for-syntax
@ -55,7 +57,7 @@ An alternative to @racket[begin-for-syntax] is to define the syntax
class in a separate module and require that module
@racket[for-syntax].
@myinteraction[
@interaction[#:eval the-eval
(module stxclass-mod racket
(require syntax/parse)
(define-syntax-class foo
@ -77,7 +79,7 @@ expressions via syntax templates, then the module containing the
syntax class must generally require @racket[for-template] the bindings
referred to in the patterns and templates.
@myinteraction[
@interaction[#:eval the-eval
(module arith-keywords-mod racket
(define-syntax plus (syntax-rules ()))
(define-syntax times (syntax-rules ()))
@ -124,3 +126,5 @@ implicit syntax @racket[#%app]) must be bound at ``absolute'' phase
level 0. Since the module @racket['arith-stxclass-mod] is required
with a phase level offset of 1 (that is, @racket[for-syntax]), it must
compensate with a phase level offset of -1, or @racket[for-template].
@(close-eval the-eval)

View File

@ -5,6 +5,8 @@
scribble/eval
"parse-common.rkt")
@(define the-eval (make-sp-eval))
@title{Experimental}
The following facilities are experimental.
@ -118,7 +120,7 @@ must be specified explicitly.
Like @racket[~reflect] but for reified splicing syntax classes.
}
@myexamples[
@examples[#:eval the-eval
(define-syntax-class (nat> x)
#:description (format "natural number greater than ~s" x)
#:attributes (diff)
@ -216,7 +218,7 @@ Includes the alternatives of @racket[eh-alternative-set-id], prefixing
their attributes with @racket[name].
}
@myexamples[
@examples[#:eval the-eval
(define-eh-alternative-set options
(pattern (~once (~seq #:a a:expr) #:name "#:a option"))
(pattern (~seq #:b b:expr)))
@ -443,3 +445,5 @@ If @racket[join] were defined as a macro, it would not be usable in
the context above; instead, @racket[let-values] would report an
invalid binding list.
}
@(close-eval the-eval)

View File

@ -6,6 +6,8 @@
"parse-common.rkt"
(for-label (only-in syntax/parse ...+)))
@(define the-eval (make-sp-eval #f))
@(define-syntax-rule (defdummy id)
(defidentifier (quote-syntax id)
#:form? #t #:index? #f #:show-libs? #f))
@ -36,7 +38,7 @@ the second case later in the introduction.
The macro can be implemented very simply using
@racket[define-syntax-rule]:
@myinteraction[
@interaction[#:eval the-eval
(define-syntax-rule (mylet ([var rhs] ...) body ...)
((lambda (var ...) body ...) rhs ...))
]
@ -47,7 +49,7 @@ uninformative error message; in others, it blithely accepts illegal
syntax and passes it along to @racket[lambda], with strange
consequences:
@myinteraction[
@interaction[#:eval the-eval
(mylet ([a 1] [b 2]) (+ a b))
(mylet (b 2) (sub1 b))
(mylet ([1 a]) (add1 a))
@ -70,13 +72,15 @@ We can improve the error behavior of the macro by using
"scribblings/reference/reference.scrbl")]{transformer environment},
since we will use it to implement a macro transformer.
@myinteraction[(require (for-syntax syntax/parse))]
@interaction[#:eval the-eval
(require (for-syntax syntax/parse))
]
The following is the syntax specification above transliterated into a
@racket[syntax-parse] macro definition. It behaves no better than the
version using @racket[define-syntax-rule] above.
@myinteraction[
@interaction[#:eval the-eval
(define-syntax (mylet stx)
(syntax-parse stx
[(_ ([var-id rhs-expr] ...) body ...+)
@ -98,7 +102,7 @@ pattern variable name, a colon character, and the syntax class
name.@margin-note*{For an alternative to the ``colon'' syntax, see the
@racket[~var] pattern form.}
@myinteraction[
@interaction[#:eval the-eval
(define-syntax (mylet stx)
(syntax-parse stx
[(_ ((var:id rhs:expr) ...) body ...+)
@ -108,24 +112,24 @@ Note that the syntax class annotations do not appear in the template
(i.e., @racket[var], not @racket[var:id]).
The syntax class annotations are checked when we use the macro.
@myinteraction[
@interaction[#:eval the-eval
(mylet ([a 1] [b 2]) (+ a b))
(mylet (["a" 1]) (add1 a))
]
The @racket[expr] syntax class does not actually check that the term
it matches is a valid expression---that would require calling that
macro expander. Instead, @racket[expr] just means not a keyword.
@myinteraction[
@interaction[#:eval the-eval
(mylet ([a #:whoops]) 1)
]
Also, @racket[syntax-parse] knows how to report a few kinds of errors
without any help:
@myinteraction[
@interaction[#:eval the-eval
(mylet ([a 1 2]) (* a a))
]
There are other kinds of errors, however, that this macro does not
handle gracefully:
@myinteraction[
@interaction[#:eval the-eval
(mylet (a 1) (+ a 2))
]
It's too much to ask for the macro to respond, ``This expression is
@ -140,7 +144,7 @@ syntactic categories. One way of doing that is by defining new syntax
classes:@margin-note*{Another way is the @racket[~describe] pattern
form.}
@myinteraction[
@interaction[#:eval the-eval
(define-syntax (mylet stx)
(define-syntax-class binding
@ -158,11 +162,11 @@ Note that we write @racket[b.var] and @racket[b.rhs] now. They are the
syntax class @racket[binding].
Now the error messages can talk about ``binding pairs.''
@myinteraction[
@interaction[#:eval the-eval
(mylet (a 1) (+ a 2))
]
Errors are still reported in more specific terms when possible:
@myinteraction[
@interaction[#:eval the-eval
(mylet (["a" 1]) (+ a 2))
]
@ -170,13 +174,13 @@ There is one other constraint on the legal syntax of
@racket[mylet]. The variables bound by the different binding pairs
must be distinct. Otherwise the macro creates an illegal
@racket[lambda] form:
@myinteraction[
@interaction[#:eval the-eval
(mylet ([a 1] [a 2]) (+ a a))
]
Constraints such as the distinctness requirement are expressed as side
conditions, thus:
@myinteraction[
@interaction[#:eval the-eval
(define-syntax (mylet stx)
(define-syntax-class binding
@ -190,7 +194,7 @@ conditions, thus:
"duplicate variable name"
#'((lambda (b.var ...) body ...) b.rhs ...)]))
]
@myinteraction[
@interaction[#:eval the-eval
(mylet ([a 1] [a 2]) (+ a a))
]
The @racket[#:fail-when] keyword is followed by two expressions: the
@ -202,7 +206,7 @@ pinpoint the cause of the failure.
Syntax classes can have side conditions, too. Here is the macro
rewritten to include another syntax class representing a ``sequence of
distinct binding pairs.''
@myinteraction[
@interaction[#:eval the-eval
(define-syntax (mylet stx)
(define-syntax-class binding
@ -238,7 +242,7 @@ offered by Racket's @racket[let]. We must add the
``named-@racket[let]'' form. That turns out to be as simple as adding
a new clause:
@myinteraction[
@interaction[#:eval the-eval
(define-syntax (mylet stx)
(define-syntax-class binding
@ -267,7 +271,7 @@ lines.
But does adding this new case affect @racket[syntax-parse]'s ability
to pinpoint and report errors?
@myinteraction[
@interaction[#:eval the-eval
(mylet ([a 1] [b 2]) (+ a b))
(mylet (["a" 1]) (add1 a))
(mylet ([a #:whoops]) 1)
@ -278,7 +282,7 @@ to pinpoint and report errors?
The error reporting for the original syntax seems intact. We should
verify that the named-@racket[let] syntax is working, that
@racket[syntax-parse] is not simply ignoring that clause.
@myinteraction[
@interaction[#:eval the-eval
(mylet loop ([a 1] [b 2]) (+ a b))
(mylet loop (["a" 1]) (add1 a))
(mylet loop ([a #:whoops]) 1)
@ -300,7 +304,7 @@ potential errors (including ones like @racket[loop] not matching
each error. Only the error with the most progress is reported.
For example, in this bad use of the macro,
@myinteraction[
@interaction[#:eval the-eval
(mylet loop (["a" 1]) (add1 a))
]
there are two potential errors: expected @racket[distinct-bindings] at
@ -309,7 +313,7 @@ second error occurs further in the term than the first, so it is
reported.
For another example, consider this term:
@myinteraction[
@interaction[#:eval the-eval
(mylet (["a" 1]) (add1 a))
]
Again, there are two potential errors: expected @racket[identifier] at
@ -319,7 +323,7 @@ if you prefer), but the second error occurs deeper in the
term. Progress is based on a left-to-right traversal of the syntax.
A final example: consider the following:
@myinteraction[
@interaction[#:eval the-eval
(mylet ([a 1] [a 2]) (+ a a))
]
There are two errors again: duplicate variable name at @racket[([a 1]
@ -339,7 +343,7 @@ the term.
It is, however, possible for multiple potential errors to occur with
the same progress. Here's one example:
@myinteraction[
@interaction[#:eval the-eval
(mylet "not-even-close")
]
In this case @racket[syntax-parse] reports both errors.
@ -347,7 +351,7 @@ In this case @racket[syntax-parse] reports both errors.
Even with all of the annotations we have added to our macro, there are
still some misuses that defy @racket[syntax-parse]'s error reporting
capabilities, such as this example:
@myinteraction[
@interaction[#:eval the-eval
(mylet)
]
The philosophy behind @racket[syntax-parse] is that in these
@ -363,3 +367,5 @@ conditions, and progress-ordered error reporting. But
@secref{stxparse-examples} section for samples of other features in
working code, or skip to the subsequent sections for the complete
reference documentation.
@(close-eval the-eval)

View File

@ -5,6 +5,8 @@
scribble/eval
"parse-common.rkt")
@(define the-eval (make-sp-eval))
@title{Literal Sets and Conventions}
Sometimes the same literals are recognized in a number of different
@ -38,7 +40,7 @@ identifiers the literal matches. If the @racket[#:literal-sets] option
is present, the contents of the given @racket[imported-litset-id]s are
included.
@myexamples[
@examples[#:eval the-eval
(define-literal-set def-litset
(define-values define-syntaxes))
(syntax-parse #'(define-syntaxes (x) 12)
@ -56,7 +58,7 @@ given, then @racket[phase-level] is @racket[0].
For example:
@myexamples[
@interaction[#:eval the-eval
(module common racket/base
(define x 'something)
(provide x))
@ -74,7 +76,7 @@ module @racketmodname['common].
The following module defines an equivalent literal set, but imports
the @racket['common] module for-template instead:
@myexamples[
@interaction[#:eval the-eval
(module lits racket/base
(require syntax/parse (for-template 'common))
(define-literal-set common-lits #:for-template (x))
@ -85,7 +87,7 @@ When a literal set is @emph{used} with the @racket[#:phase phase-expr]
option, the literals' fixed bindings are compared against the binding of
the input literal at the specified phase. Continuing the example:
@myexamples[
@interaction[#:eval the-eval
(require syntax/parse 'lits (for-syntax 'common))
(syntax-parse #'x #:literal-sets ([common-lits #:phase 1])
[x 'yes]
@ -106,7 +108,7 @@ phase @racket[_phase] at which to examine the binding of @racket[_id];
the @racket[_phase] argument defaults to
@racket[(syntax-local-phase-level)].
@myexamples[
@examples[#:eval the-eval
(define kernel? (literal-set->predicate kernel-literals))
(kernel? #'lambda)
(kernel? #'#%plain-lambda)
@ -130,7 +132,7 @@ that matches determines the syntax class for the pattern. If no
@racket[name-pattern] matches, then the pattern variable has no syntax
class.
@myexamples[
@examples[#:eval the-eval
(define-conventions xyz-as-ids
[x id] [y id] [z id])
(syntax-parse #'(a b c 1 2 3)
@ -149,7 +151,7 @@ Local conventions, introduced with the @racket[#:local-conventions]
keyword argument of @racket[syntax-parse] and syntax class
definitions, may refer to local bindings:
@myexamples[
@examples[#:eval the-eval
(define-syntax-class (nat> bound)
(pattern n:nat
#:fail-unless (> (syntax-e #'n) bound)
@ -168,3 +170,5 @@ definitions, may refer to local bindings:
]
}
@(close-eval the-eval)

View File

@ -1,54 +1,64 @@
#lang racket/base
(require scribble/manual
scribble/eval
racket/string
racket/sandbox)
(provide ellipses
the-eval
myexamples
myinteraction)
make-sp-eval)
(define ellipses (racket ...))
(define (fixup exn)
(define (fixup/short exn)
(let ([src (ormap values (exn:fail:syntax-exprs exn))])
(if src
(make-exn:fail:syntax
(format "~a at: ~s" (exn-message exn) (syntax->datum src))
(let* ([msg (exn-message exn)]
[oneline? (not (regexp-match? #rx"\n" msg))])
(format "~a~a at: ~s"
msg (if oneline? "" "\n ") (syntax->datum src)))
(exn-continuation-marks exn)
(exn:fail:syntax-exprs exn))
exn)))
(define the-eval
(call-with-trusted-sandbox-configuration
(lambda ()
(parameterize ([sandbox-output 'string]
[sandbox-error-output 'string]
[sandbox-propagate-breaks #f]
[sandbox-eval-handlers
(list #f
(lambda (thunk)
(with-handlers ([exn:fail:syntax?
(lambda (e) (raise (fixup e)))])
(thunk))))])
(make-evaluator 'racket/base
#:requires (let ([mods '(racket/promise
syntax/parse
syntax/parse/debug
syntax/parse/experimental/splicing
syntax/parse/experimental/contract
syntax/parse/experimental/reflect
syntax/parse/experimental/specialize
syntax/parse/experimental/template
syntax/parse/experimental/eh)])
`((for-syntax racket/base ,@mods)
,@mods)))))))
(the-eval '(error-print-source-location #f))
(define-syntax-rule (myexamples e ...)
(examples #:eval the-eval e ...))
(define (fixup/long exn)
(let ([src (ormap values (exn:fail:syntax-exprs exn))])
(if src
(make-exn:fail:syntax
(string-trim (exn-message exn)
#rx"[^ ]*[ ]"
#:left? #t #:right? #f)
(exn-continuation-marks exn)
(exn:fail:syntax-exprs exn))
exn)))
(define-syntax-rule (myinteraction e ...)
(interaction #:eval the-eval e ...))
(define (make-sp-eval [short? #f])
(define fixup (if short? fixup/short fixup/long))
(define the-eval
(call-with-trusted-sandbox-configuration
(lambda ()
(parameterize ([sandbox-output 'string]
[sandbox-error-output 'string]
[sandbox-propagate-breaks #f]
[sandbox-eval-handlers
(list #f
(lambda (thunk)
(with-handlers ([exn:fail:syntax?
(lambda (e) (raise (fixup e)))])
(thunk))))])
(make-evaluator 'racket/base
#:requires (let ([mods '(racket/promise
syntax/parse
syntax/parse/debug
syntax/parse/experimental/splicing
syntax/parse/experimental/contract
syntax/parse/experimental/reflect
syntax/parse/experimental/specialize
syntax/parse/experimental/template
syntax/parse/experimental/eh)])
`((for-syntax racket/base ,@mods)
,@mods)))))))
(when short? (the-eval '(error-print-source-location #f)))
the-eval)
;; ----

View File

@ -6,6 +6,8 @@
"parse-common.rkt"
(for-label racket/syntax))
@(define the-eval (make-sp-eval))
@title{Parsing Syntax}
This section describes @racket[syntax-parse], the
@ -40,7 +42,8 @@ Two parsing forms are provided: @racket[syntax-parse] and
(code:line #:phase phase-expr)]
[clause (syntax-pattern pattern-directive ... body ...+)])
#:contracts ([stx-expr syntax?]
[context-expr syntax?]
[context-expr (or/c syntax? symbol? #f
(list/c symbol? syntax?))]
[phase-expr (or/c exact-integer? #f)])]{
Evaluates @racket[stx-expr], which should produce a syntax object, and
@ -60,19 +63,34 @@ error is raised.
The following options are supported:
@specsubform[(code:line #:context context-expr)
#:contracts ([context-expr syntax?])]{
#:contracts
([context-expr (or/c syntax? symbol? #f
(list/c symbol? syntax?))])]{
When present, @racket[context-expr] is used in reporting parse
failures; otherwise @racket[stx-expr] is used. The
@racket[current-syntax-context] parameter is also set to the value of
@racket[context-expr].
failures; otherwise @racket[stx-expr] is used. If
@racket[context-expr] evaluates to @racket[(list _who _context-stx)],
then @racket[_who] appears in the error message as the form raising
the error, and @racket[_context-stx] is used as the term. If
@racket[context-expr] evaluates to a symbol, it is used as
@racket[_who] and @racket[stx-expr] (the syntax to be destructured) is
used as @racket[_context-stx]. If @racket[context-expr] evaluates to a
syntax object, it is used as @racket[_context-stx] and @racket[_who]
is inferred as with @racket[raise-syntax-error].
@(myexamples
(syntax-parse #'(a b 3)
[(x:id ...) 'ok])
(syntax-parse #'(a b 3)
#:context #'(lambda (a b 3) (+ a b))
[(x:id ...) 'ok]))
The @racket[current-syntax-context] parameter is also set to the
syntax object @racket[_context-stx].
@examples[#:eval the-eval
(syntax-parse #'(a b 3)
[(x:id ...) 'ok])
(syntax-parse #'(a b 3)
#:context #'(lambda (a b 3) (+ a b))
[(x:id ...) 'ok])
(syntax-parse #'(a b 3)
#:context 'check-id-list
[(x:id ...) 'ok])
]
}
@specsubform[(code:line #:literals (literal ...))
@ -157,7 +175,7 @@ bindings. See the section on @tech{conventions} for examples.
Suppresses the ``colon notation'' for annotated pattern variables.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(a b c)
[(x:y ...) 'ok])
(syntax-parse #'(a b c) #:disable-colon-notation
@ -180,7 +198,7 @@ syntax object result of @racket[stx-expr] against
@racket[syntax-pattern] and creates pattern variable definitions for
the attributes of @racket[syntax-pattern].
@myexamples[
@examples[#:eval the-eval
(define/syntax-parse ((~seq kw:keyword arg:expr) ...)
#'(#:a 1 #:b 2 #:c 3))
#'(kw ...)
@ -189,3 +207,5 @@ the attributes of @racket[syntax-pattern].
Compare with @racket[define/with-syntax], a similar definition form
that uses the simpler @racket[syntax-case] patterns.
}
@(close-eval the-eval)

View File

@ -5,6 +5,8 @@
scribble/eval
"parse-common.rkt")
@(define the-eval (make-sp-eval))
@(define-syntax-rule (define-dotsplus-names dotsplus def-dotsplus)
(begin (require (for-label (only-in syntax/parse ...+)))
(define dotsplus (racket ...+))
@ -200,7 +202,7 @@ An identifier can be either a @tech{pattern variable}, an
literals list, it is a @tech{literal} pattern that behaves
like @racket[(~literal id)].
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(define x 12)
#:literals (define)
[(define var:id body:expr) 'ok])
@ -221,7 +223,7 @@ An identifier can be either a @tech{pattern variable}, an
@tech{annotated pattern variable}, and the pattern is equivalent to
@racket[(~var _pvar-id _syntax-class-id)].
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'a
[var:id (syntax-e #'var)])
(syntax-parse #'12
@ -246,7 +248,7 @@ An identifier can be either a @tech{pattern variable}, an
where @racket[_literal-id] is in the literals list, then it is
equivalent to @racket[(~and (~var _pvar-id) literal-id)].
@myexamples[
@examples[#:eval the-eval
(require (only-in racket/base [define def]))
(syntax-parse #'(def x 7)
#:literals (define)
@ -299,7 +301,7 @@ If @svar[pvar-id] is @racket[_], no attributes are bound. If
If @racket[role-expr] is given and evaluates to a string, it is
combined with the syntax class's description in error messages.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'a
[(~var var id) (syntax-e #'var)])
(syntax-parse #'12
@ -327,7 +329,7 @@ combined with the syntax class's description in error messages.
A @deftech{literal} identifier pattern. Matches any identifier
@racket[free-identifier=?] to @racket[literal-id].
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(define x 12)
[((~literal define) var:id body:expr) 'ok])
(syntax-parse #'(lambda x 12)
@ -344,7 +346,7 @@ The identifiers are compared at the phase given by
Numbers, strings, booleans, keywords, and the empty list match as
literals.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(a #:foo bar)
[(x #:foo y) (syntax->datum #'y)])
(syntax-parse #'(a foo bar)
@ -358,7 +360,7 @@ Matches syntax whose S-expression contents (obtained by
@racket[syntax->datum]) is @racket[equal?] to the given
@racket[datum].
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(a #:foo bar)
[(x (~datum #:foo) y) (syntax->datum #'y)])
(syntax-parse #'(a foo bar)
@ -369,7 +371,7 @@ The @racket[~datum] form is useful for recognizing identifiers
symbolically, in contrast to the @racket[~literal] form, which
recognizes them by binding.
@myexamples[
@examples[#:eval the-eval
(syntax-parse (let ([define 'something-else]) #'(define x y))
[((~datum define) var:id e:expr) 'yes]
[_ 'no])
@ -435,7 +437,7 @@ That is, the following patterns are equivalent:
@item[@racket[((~between H 1 +inf.0) ... . S)]]
]
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(1 2 3)
[(n:nat ...+) 'ok])
(syntax-parse #'()
@ -461,7 +463,7 @@ term (including its lexical context, source location, etc) while also
examining its structure. Syntax classes are useful for the same
purpose, but @racket[~and] can be lighter weight.
@myexamples[
@examples[#:eval the-eval
(define-syntax (import stx)
(raise-syntax-error #f "illegal use of import" stx))
(eval:alts
@ -490,7 +492,7 @@ of @racket[#f]. The same attribute may be bound by multiple
subpatterns, and if it is bound by all of the subpatterns, it is sure
to have a value if the whole pattern matches.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'a
[(~or x:id y:nat) (values (attribute x) (attribute y))])
(syntax-parse #'(a 1)
@ -506,7 +508,7 @@ Matches any term that does not match the subpattern. None of the
subpattern's attributes are bound outside of the
@racket[~not]-pattern.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(x y z => u v)
#:literals (=>)
[((~and before (~not =>)) ... => after ...)
@ -520,7 +522,7 @@ Matches a term that is a vector whose elements, when considered as a
list, match the @tech{@Spattern} corresponding to
@racket[(pattern-part ...)].
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'#(1 2 3)
[#(x y z) (syntax->datum #'z)])
(syntax-parse #'#(1 2 3)
@ -536,7 +538,7 @@ Matches a term that is a prefab struct whose key is exactly the given
key and whose sequence of fields, when considered as a list, match the
@tech{@Spattern} corresponding to @racket[(pattern-part ...)].
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'#s(point 1 2 3)
[#s(point x y z) 'ok])
(syntax-parse #'#s(point 1 2 3)
@ -551,7 +553,7 @@ key and whose sequence of fields, when considered as a list, match the
Matches a term that is a box whose contents matches the inner
@tech{@Spattern}.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'#&5
[#&n:nat 'ok])
]
@ -564,7 +566,7 @@ is useful in positions where improper (``dotted'') lists are not
allowed by the reader, such as vector and structure patterns (see
above).
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(1 2 3)
[(x ~rest y) (syntax->datum #'y)])
(syntax-parse #'#(1 2 3)
@ -572,7 +574,7 @@ above).
]
}
@specsubform[(@#,def[~describe s] maybe-opaque expr S-pattern)
@specsubform[(@#,def[~describe s] maybe-role maybe-opaque expr S-pattern)
#:grammar
([maybe-opaque (code:line)
(code:line #:opaque)]
@ -594,7 +596,7 @@ terms of the description given.
If @racket[role-expr] is given and produces a string, its value is
combined with the description in error messages.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(m 1)
[(_ (~describe "id pair" (x:id y:id))) 'ok])
(syntax-parse #'(m (a 2))
@ -681,7 +683,7 @@ matches a head pattern.
Matches a sequence of terms whose elements, if put in a list, would
match @racket[L-pattern].
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(1 2 3 4)
[((~seq 1 2 3) 4) 'ok])
]
@ -695,7 +697,7 @@ examples of @racket[~seq].
Like the @Spattern version, @ref[~and s], but matches a sequence of
terms instead.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(#:a 1 #:b 2 3 4 5)
[((~and (~seq (~seq k:keyword e:expr) ...)
(~seq keyword-stuff ...))
@ -708,7 +710,7 @@ subpatterns be @tech{proper @Hpatterns} (not @tech{@Spatterns}). This
is to prevent typos like the following, a variant of the previous
example with the second @racket[~seq] omitted:
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(#:a 1 #:b 2 3 4 5)
[((~and (~seq (~seq k:keyword e:expr) ...)
(keyword-stuff ...))
@ -728,7 +730,7 @@ example with the second @racket[~seq] omitted:
Like the @Spattern version, @ref[~or s], but matches a sequence of
terms instead.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(m #:foo 2 a b c)
[(_ (~or (~seq #:foo x) (~seq)) y:id ...)
(attribute x)])
@ -752,7 +754,7 @@ terms. If the @racket[#:defaults] option is given, the subsequent
attribute bindings are used if the subpattern does not match. The
default attributes must be a subset of the subpattern's attributes.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(m #:foo 2 a b c)
[(_ (~optional (~seq #:foo x) #:defaults ([x #'#f])) y:id ...)
(attribute x)])
@ -812,7 +814,7 @@ matching position, so the pattern consumes no input. Used to look
ahead in a sequence. None of the subpattern's attributes are bound
outside of the @racket[~peek-not]-pattern.
@myexamples[
@examples[#:eval the-eval
(define-splicing-syntax-class final (code:comment "final term")
(pattern (~seq x (~peek-not _))))
@ -841,7 +843,7 @@ repetition. They are useful for matching, for example, keyword
arguments where the keywords may come in any order. Multiple
alternatives are grouped together via @ref[~or eh].
@myexamples[
@examples[#:eval the-eval
(define parser1
(syntax-parser
[((~or (~once (~seq #:a x) #:name "#:a keyword")
@ -1043,7 +1045,7 @@ There is currently no way to bind attributes using a @racket[~do]
pattern. It is an error to shadow an attribute binding with a
definition in a @racket[~do] block.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(1 2 3)
[(a b (~do (printf "a was ~s\n" #'a)) c:id) 'ok])
]
@ -1059,15 +1061,14 @@ The grammar of @tech{syntax patterns} is extensible through the use of
@deftech{pattern expanders}, which allow the definition of new pattern
forms by rewriting them into existing pattern forms.
@margin-note{A @tech{pattern expander}'s name must begin with a @code{~}
character. Otherwise, @racket[syntax-parse] and other
@racketmodname[syntax/parse] forms will not recognize it.}
@margin-note{As a convention to avoid ambiguity, @tech{pattern expander}
names normally begin with a @code{~} character.}
@defproc[(pattern-expander [proc (-> syntax? syntax?)]) pattern-expander?]{
Returns a @tech{pattern expander} that uses @racket[proc] to transform the pattern.
@myexamples[
@examples[#:eval the-eval
(define-syntax ~maybe
(pattern-expander
(syntax-rules ()
@ -1102,3 +1103,5 @@ Returns @racket[#t] if @racket[v] is a @tech{pattern expander},
Like @racket[syntax-local-introduce], but for @tech{pattern expanders}.
}
@(close-eval the-eval)

View File

@ -5,6 +5,8 @@
scribble/eval
"parse-common.rkt")
@(define the-eval (make-sp-eval))
@title[#:tag "stxparse-specifying"]{Specifying Syntax with Syntax Classes}
@declare-exporting[syntax/parse]
@ -132,7 +134,7 @@ pattern}.
@defform*[#:literals (pattern)
[(define-splicing-syntax-class name-id stxclass-option ...
stxclass-variant ...+)
(define-splicing-syntax-class (name-id kw-formals) stxclass-option ...
(define-splicing-syntax-class (name-id . kw-formals) stxclass-option ...
stxclass-variant ...+)]]{
Defines @racket[name-id] as a @deftech{splicing syntax class},
@ -204,7 +206,7 @@ If a @racket[#:with] directive appears between the main pattern (e.g., in a
@racket[#:declare], then only pattern variables from the @racket[#:with]
pattern may be declared.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'P
[x
#:declare x id
@ -322,7 +324,7 @@ subterm. A non-syntax-valued attribute should be bound using the
and @racket[~parse] will convert the right-hand side to a (possibly
3D) syntax object.
@myexamples[
@examples[#:eval the-eval
(define-syntax-class table
(pattern ((key value) ...)
#:attr hashtable
@ -347,7 +349,7 @@ used in a syntax template.
Syntax-valued attributes can be used in syntax templates:
@myinteraction[
@interaction[#:eval the-eval
(syntax-parse #'((a 3) (b 2) (c 1))
[t:table
#'(t.key ...)])
@ -357,7 +359,7 @@ Syntax-valued attributes can be used in syntax templates:
But non-syntax-valued attributes cannot:
@myinteraction[
@interaction[#:eval the-eval
(syntax-parse #'((a 3) (b 2) (c 1))
[t:table
#'t.hashtable])
@ -366,7 +368,7 @@ But non-syntax-valued attributes cannot:
Use the @racket[attribute] form to get the value of an attribute
(syntax-valued or not).
@myinteraction[
@interaction[#:eval the-eval
(syntax-parse #'((a 1) (b 2) (c 3))
[t:table
(attribute t.hashtable)])
@ -409,7 +411,7 @@ it is syntax-valued. In particular, @racket[~or] and
expected levels of list nesting, and @racket[#:attr] and
@racket[~bind] can be used to bind attributes to arbitrary values.
@myexamples[
@examples[#:eval the-eval
(syntax-parse #'(a b 3)
[(~or (x:id ...) _)
(attribute x)])
@ -421,3 +423,5 @@ Returns the value associated with the @tech{attribute} named
@racket[attr-id]. If @racket[attr-id] is not bound as an attribute, an
error is raised.
}
@(close-eval the-eval)

Some files were not shown because too many files have changed in this diff Show More