Merge branch 'master' of github.com:racket/racket
This commit is contained in:
commit
cd3e069d37
|
@ -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
|
||||
|
|
51
INSTALL.txt
51
INSTALL.txt
|
@ -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
|
||||
|
|
68
Makefile
68
Makefile
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]))
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
"compatibility-lib"
|
||||
"r5rs-lib"
|
||||
"scheme-lib"
|
||||
"srfi-lite-lib"
|
||||
"racket-test"
|
||||
"typed-racket-lib"
|
||||
"gui-lib"))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"]}
|
||||
|
|
|
@ -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.}]}
|
||||
|
|
|
@ -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.}]}
|
||||
|
|
|
@ -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?]{
|
||||
|
|
|
@ -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}.}
|
||||
|
|
|
@ -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?))]{
|
||||
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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[
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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]}]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
|
@ -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
|
||||
|
|
|
@ -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[
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}.
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.}]}
|
||||
|
|
|
@ -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.}]}
|
||||
|
|
36
pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl
Normal file
36
pkgs/racket-doc/scribblings/raco/exe-dylib-path.scrbl
Normal 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}.}
|
|
@ -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"]
|
||||
|
||||
|
|
|
@ -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"]}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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].
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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?],
|
||||
|
|
|
@ -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[
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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?])
|
||||
|
|
|
@ -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"]{}}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?]{
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
18
pkgs/racket-doc/scribblings/reference/os-lib.scrbl
Normal file
18
pkgs/racket-doc/scribblings/reference/os-lib.scrbl
Normal 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.
|
||||
}
|
|
@ -14,3 +14,4 @@
|
|||
@include-section["envvars.scrbl"]
|
||||
@include-section["runtime.scrbl"]
|
||||
@include-section["cmdline.scrbl"]
|
||||
@include-section["os-lib.scrbl"]
|
||||
|
|
|
@ -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"]{}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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].}
|
||||
|
||||
|
|
|
@ -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?]{
|
||||
|
|
|
@ -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 ...+)]{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?)]{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"]
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}?}
|
||||
|
||||
]
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]
|
|
@ -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)
|
||||
|
|
|
@ -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?]
|
||||
|
|
|
@ -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.}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
;; ----
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue
Block a user