Split almost everything else from the main repository.
The source to the split packages is in repositories under the `racket` organization on GitHub. The repositories are all named according to the pkg name, except for multiple-package repositories such as `racket/compiler` which is named based on the old directory name without the `-pkgs` suffix. Thus `pkgs/compiler-pkgs` -> https://github.com/racket/compiler The Makefile has also been adjusted to pull packages from the catalog when you type `make`. This currently relies on some tricks that will break if you try to specify a particular set of `PKGS` on the command line. We plan to improve this soon. The packages in `pkgs/racket-pkgs` and `pkgs/base` are staying in the repository, since they logically belong with the core code. The `plt-services` package is still in the repository, but will move out soon.
This commit is contained in:
parent
f3dba3eb6b
commit
2987338218
18
Makefile
18
Makefile
|
@ -21,7 +21,9 @@
|
||||||
|
|
||||||
# Packages (separated by spaces) to link in development mode or
|
# Packages (separated by spaces) to link in development mode or
|
||||||
# to include in a distribution:
|
# to include in a distribution:
|
||||||
PKGS = main-distribution plt-services
|
PKGS = base racket-lib # plt-services
|
||||||
|
LINK_PKGS = $(PKGS) racket-doc at-exp-lib racket-test racket-benchmarks racket-index
|
||||||
|
INSTALL_PKGS = main-distribution main-distribution-test
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# In-place build
|
# In-place build
|
||||||
|
@ -29,6 +31,10 @@ PKGS = main-distribution plt-services
|
||||||
PLAIN_RACKET = racket/bin/racket
|
PLAIN_RACKET = racket/bin/racket
|
||||||
WIN32_PLAIN_RACKET = racket\racket
|
WIN32_PLAIN_RACKET = racket\racket
|
||||||
|
|
||||||
|
PLAIN_RACO = racket/bin/racket -N raco -l- raco
|
||||||
|
WIN32_PLAIN_RACO = racket\racket -N raco -l- raco
|
||||||
|
|
||||||
|
|
||||||
MACOSX_CHECK_ARGS = -I racket/base -e '(case (system-type) [(macosx) (exit 0)] [else (exit 1)])'
|
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)
|
MACOSX_CHECK = $(PLAIN_RACKET) -G build/config $(MACOSX_CHECK_ARGS)
|
||||||
|
|
||||||
|
@ -46,6 +52,7 @@ cpus-in-place:
|
||||||
|
|
||||||
# Explicitly propagate variables for non-GNU `make's:
|
# Explicitly propagate variables for non-GNU `make's:
|
||||||
PKG_LINK_COPY_ARGS = PKGS="$(PKGS)" LINK_MODE="$(LINK_MODE)"
|
PKG_LINK_COPY_ARGS = PKGS="$(PKGS)" LINK_MODE="$(LINK_MODE)"
|
||||||
|
PKG_LINK_COPY_EXTRA_ARGS = PKGS="$(LINK_PKGS)" LINK_MODE="$(LINK_MODE)"
|
||||||
LIBSETUP = -N raco -l- raco setup
|
LIBSETUP = -N raco -l- raco setup
|
||||||
|
|
||||||
plain-in-place:
|
plain-in-place:
|
||||||
|
@ -53,6 +60,9 @@ plain-in-place:
|
||||||
if $(MACOSX_CHECK) ; then $(MAKE) native-from-git ; fi
|
if $(MACOSX_CHECK) ; then $(MAKE) native-from-git ; fi
|
||||||
$(MAKE) pkg-links $(PKG_LINK_COPY_ARGS)
|
$(MAKE) pkg-links $(PKG_LINK_COPY_ARGS)
|
||||||
$(PLAIN_RACKET) $(LIBSETUP) $(JOB_OPTIONS) $(PLT_SETUP_OPTIONS)
|
$(PLAIN_RACKET) $(LIBSETUP) $(JOB_OPTIONS) $(PLT_SETUP_OPTIONS)
|
||||||
|
$(MAKE) pkg-extra-links $(PKG_LINK_COPY_EXTRA_ARGS) # NOTE: no setup after this step
|
||||||
|
$(PLAIN_RACO) pkg install $(JOB_OPTIONS) --scope installation \
|
||||||
|
--deps search-auto $(INSTALL_PKGS)
|
||||||
|
|
||||||
# For Windows: set up the following collections first, so that native
|
# For Windows: set up the following collections first, so that native
|
||||||
# libraries are in place for use by a full setup:
|
# libraries are in place for use by a full setup:
|
||||||
|
@ -63,6 +73,8 @@ win32-in-place:
|
||||||
$(MAKE) win32-pkg-links $(PKG_LINK_COPY_ARGS)
|
$(MAKE) win32-pkg-links $(PKG_LINK_COPY_ARGS)
|
||||||
$(WIN32_PLAIN_RACKET) $(LIBSETUP) -nxiID $(JOB_OPTIONS) $(PLT_SETUP_OPTIONS) $(LIB_PRE_COLLECTS)
|
$(WIN32_PLAIN_RACKET) $(LIBSETUP) -nxiID $(JOB_OPTIONS) $(PLT_SETUP_OPTIONS) $(LIB_PRE_COLLECTS)
|
||||||
$(WIN32_PLAIN_RACKET) $(LIBSETUP) $(JOB_OPTIONS) $(PLT_SETUP_OPTIONS)
|
$(WIN32_PLAIN_RACKET) $(LIBSETUP) $(JOB_OPTIONS) $(PLT_SETUP_OPTIONS)
|
||||||
|
$(WIN32_PLAIN_RACO) pkg install $(JOB_OPTIONS) --scope installation \
|
||||||
|
--deps search-auto $(INSTALL_PKGS)
|
||||||
|
|
||||||
again:
|
again:
|
||||||
$(MAKE) LINK_MODE="--restore"
|
$(MAKE) LINK_MODE="--restore"
|
||||||
|
@ -96,6 +108,7 @@ plain-unix-style:
|
||||||
$(MAKE) local-catalog-maybe-native RACKET="$(DESTDIR)$(PREFIX)/bin/racket"
|
$(MAKE) local-catalog-maybe-native RACKET="$(DESTDIR)$(PREFIX)/bin/racket"
|
||||||
"$(DESTDIR)$(PREFIX)/bin/raco" pkg install $(UNIX_RACO_ARGS) $(REQUIRED_PKGS) $(PKGS)
|
"$(DESTDIR)$(PREFIX)/bin/raco" pkg install $(UNIX_RACO_ARGS) $(REQUIRED_PKGS) $(PKGS)
|
||||||
cd racket/src/build; $(MAKE) fix-paths
|
cd racket/src/build; $(MAKE) fix-paths
|
||||||
|
"$(DESTDIR)$(PREFIX)/bin/raco" pkg install $(JOB_OPTIONS) -i --dep search-auto $(INSTALL_PKGS)
|
||||||
|
|
||||||
error-need-prefix:
|
error-need-prefix:
|
||||||
: ================================================================
|
: ================================================================
|
||||||
|
@ -302,6 +315,9 @@ LINK_ALL = -U -G build/config racket/src/link-all.rkt ++dir pkgs ++dir native-pk
|
||||||
pkg-links:
|
pkg-links:
|
||||||
$(PLAIN_RACKET) $(LINK_ALL) $(LINK_MODE) $(PKGS) $(REQUIRED_PKGS)
|
$(PLAIN_RACKET) $(LINK_ALL) $(LINK_MODE) $(PKGS) $(REQUIRED_PKGS)
|
||||||
|
|
||||||
|
pkg-extra-links:
|
||||||
|
$(PLAIN_RACKET) $(LINK_ALL) $(LINK_MODE) $(LINK_PKGS) $(REQUIRED_PKGS)
|
||||||
|
|
||||||
win32-pkg-links:
|
win32-pkg-links:
|
||||||
IF NOT EXIST native-pkgs\racket-win32-i386 $(MAKE) complain-no-submodule
|
IF NOT EXIST native-pkgs\racket-win32-i386 $(MAKE) complain-no-submodule
|
||||||
$(MAKE) pkg-links PLAIN_RACKET="$(WIN32_PLAIN_RACKET)" LINK_MODE="$(LINK_MODE)" PKGS="$(PKGS)"
|
$(MAKE) pkg-links PLAIN_RACKET="$(WIN32_PLAIN_RACKET)" LINK_MODE="$(LINK_MODE)" PKGS="$(PKGS)"
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
algol60
|
|
||||||
Copyright (c) 2010-2014 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
|
|
||||||
applications, provided you follow the rules stated in the LGPL. You
|
|
||||||
can also modify this package; if you distribute a modified version,
|
|
||||||
you must distribute it under the terms of the LGPL, which in
|
|
||||||
particular means that you must release the source code for the
|
|
||||||
modified software. See http://www.gnu.org/copyleft/lesser.html
|
|
||||||
for more information.
|
|
|
@ -1,55 +0,0 @@
|
||||||
#cs(module algol60 mzscheme
|
|
||||||
(require-for-syntax "parse.rkt"
|
|
||||||
;; Parses to generate an AST. Identifiers in the AST
|
|
||||||
;; are represented as syntax objects with source location.
|
|
||||||
|
|
||||||
"simplify.rkt"
|
|
||||||
;; Desugars the AST, transforming `for' to `if'+`goto',
|
|
||||||
;; and flattening `if' statements so they are always
|
|
||||||
;; of the for `if <exp> then goto <label> else goto <label>'
|
|
||||||
|
|
||||||
"compile.rkt"
|
|
||||||
;; Compiles a simplified AST to Scheme.
|
|
||||||
|
|
||||||
mzlib/file)
|
|
||||||
|
|
||||||
;; By using #'here for the context of identifiers
|
|
||||||
;; introduced by compilation, the identifiers can
|
|
||||||
;; refer to runtime functions and primitives, as
|
|
||||||
;; well as mzscheme:
|
|
||||||
(require "runtime.rkt" "prims.rkt")
|
|
||||||
|
|
||||||
|
|
||||||
(provide include-algol literal-algol)
|
|
||||||
|
|
||||||
(define-syntax (include-algol stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ str)
|
|
||||||
(string? (syntax-e (syntax str)))
|
|
||||||
|
|
||||||
(compile-simplified
|
|
||||||
(simplify
|
|
||||||
(parse-a60-file
|
|
||||||
(normalize-path (syntax-e (syntax str))
|
|
||||||
(or
|
|
||||||
(current-load-relative-directory)
|
|
||||||
(current-directory))))
|
|
||||||
#'here)
|
|
||||||
#'here)]))
|
|
||||||
|
|
||||||
(define-syntax (literal-algol stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ strs ...)
|
|
||||||
(andmap (λ (x) (string? (syntax-e x)))
|
|
||||||
(syntax->list (syntax (strs ...))))
|
|
||||||
|
|
||||||
(compile-simplified
|
|
||||||
(simplify
|
|
||||||
(parse-a60-port
|
|
||||||
(open-input-string
|
|
||||||
(apply
|
|
||||||
string-append
|
|
||||||
(map syntax-e (syntax->list #'(strs ...)))))
|
|
||||||
(syntax-source stx))
|
|
||||||
#'here)
|
|
||||||
#'here)])))
|
|
|
@ -1,90 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require scribble/manual
|
|
||||||
(for-label algol60/algol60))
|
|
||||||
|
|
||||||
@title{Algol 60}
|
|
||||||
|
|
||||||
@section{Implementation}
|
|
||||||
|
|
||||||
The ``Algol 60'' language for DrRacket implements the language defined
|
|
||||||
by the ``Revised Report on the Algorithmic Language Algol 60,'' edited
|
|
||||||
by Peter Naur.
|
|
||||||
|
|
||||||
@section{Including Algol 60 Programs}
|
|
||||||
|
|
||||||
Although Algol 60 is mainly provided as a DrRacket language,
|
|
||||||
@racket[include-algol] supports limited use of Algol 60 programs in
|
|
||||||
larger programs.
|
|
||||||
|
|
||||||
@defmodule[algol60/algol60]
|
|
||||||
|
|
||||||
@defform[(include-algol path-string)]{
|
|
||||||
|
|
||||||
Includes the Algol 60 program indicated by @racket[path-string] as an
|
|
||||||
expression in a Racket program. The included Algol 60 program is
|
|
||||||
closed (i.e., it doesn't see any bindings in the included context),
|
|
||||||
and the result is always @|void-const|.}
|
|
||||||
|
|
||||||
|
|
||||||
@defform[(literal-algol string ...)]{
|
|
||||||
|
|
||||||
Evaluates the Algol 60 program indicated by the literal @racket[string]s
|
|
||||||
as an expression in a Racket program. The Algol 60 program is
|
|
||||||
closed (i.e., it doesn't see any bindings in the included context),
|
|
||||||
and the result is always @|void-const|.
|
|
||||||
|
|
||||||
This is generally useful when combined with the @racketmodname[at-exp] reader,
|
|
||||||
e.g.,
|
|
||||||
@codeblock|{
|
|
||||||
#lang at-exp racket
|
|
||||||
@literal-algol{
|
|
||||||
begin
|
|
||||||
printsln (`hello world')
|
|
||||||
end
|
|
||||||
}
|
|
||||||
}|
|
|
||||||
}
|
|
||||||
|
|
||||||
@section{Language}
|
|
||||||
|
|
||||||
The DrRacket and @racket[include-algol] implementation departs from
|
|
||||||
the Algol 60 specification in the following minor ways:
|
|
||||||
|
|
||||||
@(itemize (item "Strings are not permitted to contain nested quotes.")
|
|
||||||
(item "Identifiers cannot contain whitespace.")
|
|
||||||
(item "Argument separators are constrained to be identifiers (i.e., they
|
|
||||||
cannot be keywords, and they cannot consist of multiple
|
|
||||||
identifiers separated by whitespace.)")
|
|
||||||
(item "Numbers containing exponents (using the ``10'' subscript) are not
|
|
||||||
supported."))
|
|
||||||
|
|
||||||
Identifiers and keywords are case-sensitive. The boldface/underlined
|
|
||||||
keywords of the report are represented by the obvious character
|
|
||||||
sequence, as are most operators. A few operators do not fit into
|
|
||||||
ASCII, and they are mapped as follows:
|
|
||||||
|
|
||||||
@(verbatim
|
|
||||||
" times *
|
|
||||||
quotient div
|
|
||||||
exponential ^
|
|
||||||
less or equal <=
|
|
||||||
greater or equal >=
|
|
||||||
not equal !=
|
|
||||||
equivalence ==
|
|
||||||
implication =>
|
|
||||||
and &
|
|
||||||
or |
|
|
||||||
negation !")
|
|
||||||
|
|
||||||
In addition to the standard functions, the following output functions
|
|
||||||
are supported:
|
|
||||||
|
|
||||||
@(verbatim
|
|
||||||
" prints(E) prints the string E
|
|
||||||
printsln(E) prints the string E followed by a newline
|
|
||||||
printn(E) prints the number E
|
|
||||||
printnln(E) prints the number E followed by a newline")
|
|
||||||
|
|
||||||
A prompt in DrRacket's interactions area accepts whole programs only
|
|
||||||
for the Algol 60 language.
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
(module base mzscheme
|
|
||||||
(require "prims.rkt"
|
|
||||||
"runtime.rkt")
|
|
||||||
|
|
||||||
(define base-importing-stx #'here)
|
|
||||||
|
|
||||||
(provide (all-from mzscheme)
|
|
||||||
(all-from "prims.rkt")
|
|
||||||
(all-from "runtime.rkt")
|
|
||||||
base-importing-stx))
|
|
|
@ -1,35 +0,0 @@
|
||||||
#lang s-exp framework/private/decode
|
|
||||||
|
|
||||||
jVTJbtswEL3rK6YujJBFmbhGFyBAF/TUc69BAlDiWGJCkSpJ2/HfdyhKka04TXmwoZk3bxa+Y
|
|
||||||
c E 8 / t l q j
|
|
||||||
9 \ B \ \ \ \ \6V\ \ \ \ \OB\ \l9\ \ \ \ \YD\xq\jI\yh\ P
|
|
||||||
F j a 3 U E 5 Y e v 6 J z h R c
|
|
||||||
EUb\rRF \8K\4s\ \ D6J\U8v \C9\AG\ \AGI 7AbB \ \ \ \ S xg5\awK
|
|
||||||
4 p u S E Y F V W + / R R j
|
|
||||||
G \YO\b/\ lBK\cA\ \ \ \aQ\ \ \n8\ \ \ FVi\Ci\db\Z2\ \ID\i8\ I
|
|
||||||
V P R q J O p j W n M +
|
|
||||||
Utd\S3\ \ \ \ \ \ \Kt\hg\YTqvo\D2\vl\Aw\pX\ 3mM\VC\ \R1\b2\ S 1
|
|
||||||
H H 3 n L r T Z K d J
|
|
||||||
L \yscoZ\Qyjtb\DY\sp\Km\d+\ \ \ \bxacF\iU\ \ \ 6 \vK\+q\ \ \ x
|
|
||||||
e n y Y 2 O 0 e A r + W k U
|
|
||||||
7 \ \ 2 \ \gW\Zf\tK\KU\eH\ \ \ \Xa\ \ X \ BEV\/u\ \ \ \ D
|
|
||||||
m q M Y q 9 V b D h 8 5 P 8 d 0
|
|
||||||
aCum5h\ \C+O0s\ 6EZ\V5\6o\Rq\lp\ \ \ \C2Y \ \6Xk \ \ p \ l 7
|
|
||||||
W s I H o g y V N A i r y / W
|
|
||||||
n /uc\cT\ \ H \ \m5F5lu \ LGY\ \Fq\5c\IB\+Db \ \ \ \ z \ R
|
|
||||||
G A C u i H 3 H m 3 0 w
|
|
||||||
ohK\e3\HNHWR\ \ dFh\ka\ \ \wF\ \Mt\53\ z \ \ \ \SZ\eh\arDF6\ 2
|
|
||||||
S / I z a G j 8 8 d
|
|
||||||
I \ht\DDxgusWt\kw\A+\ w \c1\rN\re\ u \5N\c/\M4r4v\Qm\y8\ \ \bH\EJY
|
|
||||||
d u h X / Y d s
|
|
||||||
L \wx\2Z\Jb\Yto26\Gl\10\p2U2x\ \ \h7\ \ \eV\k0Q8u\sB\ w ttQ5Q2\ 6
|
|
||||||
n 5 N + O j L e Y f Z 5
|
|
||||||
ODhg \ \ \ \x0HZM\8kJnas \zN\H2\ \Qv6 \ \ \ \ \ \ Mly\2p\Nq1
|
|
||||||
D 8 g P u 4 o n O p n 0 +
|
|
||||||
F \o3S \0rh6C\ Ytf\su\ \ s \ \O8\ \FP\72J D03\8P\vt\AZ\vFula\ b
|
|
||||||
2 d 6 P S F o M Q R Z 0 w Q H
|
|
||||||
o \ \ah\ \ \ \ \/g\Yc\ \ e \ \59\ \ \ \ mekqmzi \ zHvD 5
|
|
||||||
C P C o T Q u H 2 q 8 f x K
|
|
||||||
5 \XP\BSucV\ \ \+j\no\lC\P2\ \ \78\Lk\iw\da\kw\u6\ \ \PZ\ob\ q s
|
|
||||||
m Z o 5 7
|
|
||||||
fBFSNtDWKqqHXiB7IqWDy0btkw9A+GJ7Z2L4h2Oy9YU9ipwxX+Bgp23X+OxIsnBVxmgMv/gI=
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB |
|
@ -1,7 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
;; Legacy module. cfg-parser used to live in the algol60 collection.
|
|
||||||
;; This module re-exports its contents for backwards compatibility.
|
|
||||||
|
|
||||||
(require parser-tools/cfg-parser)
|
|
||||||
(provide (all-from-out parser-tools/cfg-parser))
|
|
|
@ -1,536 +0,0 @@
|
||||||
#cs(module compile mzscheme
|
|
||||||
(require "parse.rkt"
|
|
||||||
mzlib/match
|
|
||||||
mzlib/list)
|
|
||||||
|
|
||||||
(provide compile-simplified)
|
|
||||||
|
|
||||||
;; The compiler generates references to "prims.rkt" and
|
|
||||||
;; "runtime.rkt" exports, as well as Racket forms
|
|
||||||
;; and functions. The `ctx' argument provides
|
|
||||||
;; an appropriate context for those bindings (in
|
|
||||||
;; the form of a syntax object to use with d->s-o).
|
|
||||||
(define (compile-simplified stmt ctx)
|
|
||||||
(datum->syntax-object
|
|
||||||
ctx
|
|
||||||
(parameterize ([current-compile-context ctx])
|
|
||||||
(compile-a60 stmt 'void (empty-context) #t))))
|
|
||||||
|
|
||||||
(define current-compile-context (make-parameter #f))
|
|
||||||
|
|
||||||
(define (compile-a60 stmt next-label context add-to-top-level?)
|
|
||||||
(match stmt
|
|
||||||
[($ a60:block decls statements)
|
|
||||||
(compile-block decls statements next-label context add-to-top-level?)]
|
|
||||||
[else
|
|
||||||
(compile-statement stmt next-label context)]))
|
|
||||||
|
|
||||||
(define (compile-block decls statements next-label context add-to-top-level?)
|
|
||||||
(let* ([labels-with-numbers (map car statements)]
|
|
||||||
[labels (map (lambda (l)
|
|
||||||
(if (stx-number? l)
|
|
||||||
(datum->syntax-object
|
|
||||||
l
|
|
||||||
(string->symbol (format "~a" (syntax-e l)))
|
|
||||||
l
|
|
||||||
l)
|
|
||||||
l))
|
|
||||||
labels-with-numbers)]
|
|
||||||
;; Build environment by adding labels, then decls:
|
|
||||||
[context (foldl (lambda (decl context)
|
|
||||||
(match decl
|
|
||||||
[($ a60:proc-decl result-type var arg-vars by-value-vars arg-specs body)
|
|
||||||
(add-procedure context var result-type arg-vars by-value-vars arg-specs)]
|
|
||||||
[($ a60:type-decl type ids)
|
|
||||||
(add-atoms context ids type)]
|
|
||||||
[($ a60:array-decl type arrays)
|
|
||||||
(add-arrays context
|
|
||||||
(map car arrays) ; names
|
|
||||||
(map cdr arrays) ; dimensions
|
|
||||||
type)]
|
|
||||||
[($ a60:switch-decl name exprs)
|
|
||||||
(add-switch context name)]))
|
|
||||||
(add-labels
|
|
||||||
context
|
|
||||||
labels)
|
|
||||||
decls)])
|
|
||||||
;; Generate bindings and initialization for all decls,
|
|
||||||
;; plus all statements (thunked):
|
|
||||||
(let ([bindings
|
|
||||||
(append
|
|
||||||
(apply
|
|
||||||
append
|
|
||||||
;; Decls:
|
|
||||||
(map (lambda (decl)
|
|
||||||
(match decl
|
|
||||||
[($ a60:proc-decl result-type var arg-vars by-value-vars arg-specs body)
|
|
||||||
(let ([code
|
|
||||||
`(lambda (kont . ,arg-vars)
|
|
||||||
;; Extract by-value variables
|
|
||||||
(let ,(map (lambda (var)
|
|
||||||
`[,var (get-value ,var)])
|
|
||||||
by-value-vars)
|
|
||||||
;; Set up the result variable and done continuation:
|
|
||||||
,(let ([result-var (gensym 'prec-result)]
|
|
||||||
[done (gensym 'done)])
|
|
||||||
`(let* ([,result-var undefined]
|
|
||||||
[,done (lambda () (kont ,result-var))])
|
|
||||||
;; Include the compiled body:
|
|
||||||
,(compile-a60 body done
|
|
||||||
(add-settable-procedure
|
|
||||||
(add-bindings
|
|
||||||
context
|
|
||||||
arg-vars
|
|
||||||
by-value-vars
|
|
||||||
arg-specs)
|
|
||||||
var
|
|
||||||
result-type
|
|
||||||
result-var)
|
|
||||||
#f)))))])
|
|
||||||
(if add-to-top-level?
|
|
||||||
`([,var
|
|
||||||
(let ([tmp ,code])
|
|
||||||
(namespace-set-variable-value! ',var tmp)
|
|
||||||
tmp)])
|
|
||||||
`([,var
|
|
||||||
,code])))]
|
|
||||||
[($ a60:type-decl type ids)
|
|
||||||
(map (lambda (id) `[,id undefined]) ids)]
|
|
||||||
[($ a60:array-decl type arrays)
|
|
||||||
(map (lambda (array)
|
|
||||||
`[,(car array) (make-array
|
|
||||||
,@(apply
|
|
||||||
append
|
|
||||||
(map
|
|
||||||
(lambda (bp)
|
|
||||||
(list
|
|
||||||
(compile-expression (car bp) context 'num)
|
|
||||||
(compile-expression (cdr bp) context 'num)))
|
|
||||||
(cdr array))))])
|
|
||||||
arrays)]
|
|
||||||
[($ a60:switch-decl name exprs)
|
|
||||||
`([,name (make-switch ,@(map (lambda (e) `(lambda () ,(compile-expression e context 'des)))
|
|
||||||
exprs))])]
|
|
||||||
[else (error "can't compile decl")]))
|
|
||||||
decls))
|
|
||||||
;; Statements: most of the work is in `compile-statement', but
|
|
||||||
;; we provide the continuation label:
|
|
||||||
(cdr
|
|
||||||
(foldr (lambda (stmt label next-label+compiled)
|
|
||||||
(cons label
|
|
||||||
(cons
|
|
||||||
`[,label
|
|
||||||
(lambda ()
|
|
||||||
,(compile-statement (cdr stmt)
|
|
||||||
(car next-label+compiled)
|
|
||||||
context))]
|
|
||||||
(cdr next-label+compiled))))
|
|
||||||
(cons next-label null)
|
|
||||||
statements
|
|
||||||
labels)))])
|
|
||||||
;; Check for duplicate bindings:
|
|
||||||
(let ([dup (check-duplicate-identifier (filter identifier? (map car bindings)))])
|
|
||||||
(when dup
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"name defined twice"
|
|
||||||
dup)))
|
|
||||||
;; Generate code; body of leterec jumps to the first statement label.
|
|
||||||
`(letrec ,bindings
|
|
||||||
(,(caar statements))))))
|
|
||||||
|
|
||||||
(define (compile-statement statement next-label context)
|
|
||||||
(match statement
|
|
||||||
[($ a60:block decls statements)
|
|
||||||
(compile-block decls statements next-label context #f)]
|
|
||||||
[($ a60:branch test ($ a60:goto then) ($ a60:goto else))
|
|
||||||
`(if (check-boolean ,(compile-expression test context 'bool))
|
|
||||||
(goto ,(check-label then context))
|
|
||||||
(goto ,(check-label else context)))]
|
|
||||||
[($ a60:goto label)
|
|
||||||
(at (expression-location label)
|
|
||||||
`(goto ,(compile-expression label context 'des)))]
|
|
||||||
[($ a60:dummy)
|
|
||||||
`(,next-label)]
|
|
||||||
[($ a60:call proc args)
|
|
||||||
(at (expression-location proc)
|
|
||||||
`(,(compile-expression proc context 'func)
|
|
||||||
(lambda (val)
|
|
||||||
(,next-label))
|
|
||||||
,@(map (lambda (arg) (compile-argument arg context))
|
|
||||||
args)))]
|
|
||||||
[($ a60:assign vars val)
|
|
||||||
;; >>>>>>>>>>>>>>> Start clean-up here <<<<<<<<<<<<<<<<<
|
|
||||||
;; Lift out the spec-finding part, and use it to generate
|
|
||||||
;; an expected type that is passed to `compile-expression':
|
|
||||||
`(begin
|
|
||||||
(let ([val ,(compile-expression val context 'numbool)])
|
|
||||||
,@(map (lambda (avar)
|
|
||||||
(let ([var (a60:variable-name avar)])
|
|
||||||
(at var
|
|
||||||
(cond
|
|
||||||
[(null? (a60:variable-indices avar))
|
|
||||||
(cond
|
|
||||||
[(call-by-name-variable? var context)
|
|
||||||
=> (lambda (spec)
|
|
||||||
`(set-target! ,var ',var (coerce ',(spec-coerce-target spec null) val)))]
|
|
||||||
[(procedure-result-variable? var context)
|
|
||||||
`(set! ,(procedure-result-variable-name var context)
|
|
||||||
(coerce ',(spec-coerce-target (procedure-result-spec var context) null) val))]
|
|
||||||
[(or (settable-variable? var context)
|
|
||||||
(array-element? var context))
|
|
||||||
=> (lambda (spec)
|
|
||||||
`(,(if (own-variable? var context) 'set-box! 'set!)
|
|
||||||
,var
|
|
||||||
(coerce ',(spec-coerce-target spec null) val)))]
|
|
||||||
[else (raise-syntax-error #f "confused by assignment" (expression-location var))])]
|
|
||||||
[else
|
|
||||||
(let ([spec (or (array-element? var context)
|
|
||||||
(call-by-name-variable? var context))])
|
|
||||||
`(array-set! ,(compile-expression (make-a60:variable var null) context 'numbool)
|
|
||||||
(coerce ',(spec-coerce-target spec null) val)
|
|
||||||
,@(map (lambda (e) (compile-expression e context 'num))
|
|
||||||
(a60:variable-indices avar))))]))))
|
|
||||||
vars))
|
|
||||||
(,next-label))]
|
|
||||||
[else (error "can't compile statement")]))
|
|
||||||
|
|
||||||
(define (compile-expression expr context type)
|
|
||||||
(match expr
|
|
||||||
[(? (lambda (x) (and (syntax? x) (number? (syntax-e x)))) n)
|
|
||||||
(if (eq? type 'des)
|
|
||||||
;; Need a label:
|
|
||||||
(check-label (datum->syntax-object expr
|
|
||||||
(string->symbol (number->string (syntax-e expr)))
|
|
||||||
expr
|
|
||||||
expr)
|
|
||||||
context)
|
|
||||||
;; Normal use of a number:
|
|
||||||
(begin
|
|
||||||
(check-type 'num type expr)
|
|
||||||
(as-builtin n)))]
|
|
||||||
[(? (lambda (x) (and (syntax? x) (boolean? (syntax-e x)))) n) (check-type 'bool type expr) (as-builtin n)]
|
|
||||||
[(? (lambda (x) (and (syntax? x) (string? (syntax-e x)))) n) (check-type 'string type expr) (as-builtin n)]
|
|
||||||
[(? identifier? i) (compile-expression (make-a60:variable i null) context type)]
|
|
||||||
[(? symbol? i) ; either a generated label or 'val:
|
|
||||||
(unless (eq? expr 'val)
|
|
||||||
(check-type 'des type expr))
|
|
||||||
(datum->syntax-object #f i)]
|
|
||||||
[($ a60:subscript array index)
|
|
||||||
;; Maybe a switch index, or maybe an array reference
|
|
||||||
(at array
|
|
||||||
(cond
|
|
||||||
[(array-element? array context)
|
|
||||||
`(array-ref ,array ,(compile-expression index context 'num))]
|
|
||||||
[(switch-variable? array context)
|
|
||||||
`(switch-ref ,array ,(compile-expression index context 'num))]
|
|
||||||
[else (raise-syntax-error
|
|
||||||
#f
|
|
||||||
"confused by variable"
|
|
||||||
array)]))]
|
|
||||||
[($ a60:binary t argt op e1 e2)
|
|
||||||
(check-type t type expr)
|
|
||||||
(at op
|
|
||||||
`(,(as-builtin op) ,(compile-expression e1 context argt) ,(compile-expression e2 context argt)))]
|
|
||||||
[($ a60:unary t argt op e1)
|
|
||||||
(check-type t type expr)
|
|
||||||
(at op
|
|
||||||
`(,(as-builtin op) ,(compile-expression e1 context argt)))]
|
|
||||||
[($ a60:variable var subscripts)
|
|
||||||
(let ([sub (lambda (wrap v)
|
|
||||||
(wrap
|
|
||||||
(if (null? subscripts)
|
|
||||||
v
|
|
||||||
`(array-ref ,v ,@(map (lambda (e) (compile-expression e context 'num)) subscripts)))))])
|
|
||||||
(cond
|
|
||||||
[(call-by-name-variable? var context)
|
|
||||||
=> (lambda (spec)
|
|
||||||
(check-spec-type spec type var subscripts)
|
|
||||||
(sub (lambda (val) `(coerce ',(spec-coerce-target spec subscripts) ,val)) `(get-value ,var)))]
|
|
||||||
[(primitive-variable? var context)
|
|
||||||
=> (lambda (name)
|
|
||||||
(sub values
|
|
||||||
(datum->syntax-object
|
|
||||||
(current-compile-context)
|
|
||||||
name
|
|
||||||
var
|
|
||||||
var)))]
|
|
||||||
[(and (procedure-result-variable? var context)
|
|
||||||
(not (eq? type 'func)))
|
|
||||||
(unless (null? subscripts)
|
|
||||||
(raise-syntax-error "confused by subscripts" var))
|
|
||||||
(let ([spec (procedure-result-spec var context)])
|
|
||||||
(check-spec-type spec type var null)
|
|
||||||
(at var
|
|
||||||
`(coerce
|
|
||||||
',(spec-coerce-target spec null)
|
|
||||||
,(procedure-result-variable-name var context))))]
|
|
||||||
[(or (procedure-result-variable? var context)
|
|
||||||
(procedure-variable? var context)
|
|
||||||
(label-variable? var context)
|
|
||||||
(settable-variable? var context)
|
|
||||||
(array-element? var context))
|
|
||||||
=> (lambda (spec)
|
|
||||||
(let ([spec (if (or (procedure-result-variable? var context)
|
|
||||||
(procedure-variable? var context)
|
|
||||||
(and (array-element? var context)
|
|
||||||
(null? subscripts)))
|
|
||||||
#f ;; need just the proc or array...
|
|
||||||
spec)])
|
|
||||||
(check-spec-type spec type var subscripts)
|
|
||||||
(let ([target (spec-coerce-target spec subscripts)])
|
|
||||||
(sub (if target
|
|
||||||
(lambda (v) `(coerce ',target ,v))
|
|
||||||
values)
|
|
||||||
(if (own-variable? var context)
|
|
||||||
`(unbox ,var)
|
|
||||||
var)))))]
|
|
||||||
[else (raise-syntax-error
|
|
||||||
#f
|
|
||||||
"confused by expression"
|
|
||||||
(expression-location var))]))]
|
|
||||||
|
|
||||||
[($ a60:app func args)
|
|
||||||
(at (expression-location func)
|
|
||||||
`(,(compile-expression func context 'func)
|
|
||||||
values
|
|
||||||
,@(map (lambda (e) (compile-argument e context))
|
|
||||||
args)))]
|
|
||||||
[($ a60:if test then else)
|
|
||||||
`(if (check-boolean ,(compile-expression test context 'bool))
|
|
||||||
,(compile-expression then context type)
|
|
||||||
,(compile-expression else context type))]
|
|
||||||
[else (error 'compile-expression "can't compile expression ~a" expr)]))
|
|
||||||
|
|
||||||
(define (expression-location expr)
|
|
||||||
(if (syntax? expr)
|
|
||||||
expr
|
|
||||||
(match expr
|
|
||||||
[($ a60:subscript array index) (expression-location array)]
|
|
||||||
[($ a60:binary type argtype op e1 e2) op]
|
|
||||||
[($ a60:unary type argtype op e1) op]
|
|
||||||
[($ a60:variable var subscripts) (expression-location var)]
|
|
||||||
[($ a60:app func args)
|
|
||||||
(expression-location func)]
|
|
||||||
[else #f])))
|
|
||||||
|
|
||||||
(define (compile-argument arg context)
|
|
||||||
(cond
|
|
||||||
[(or (and (a60:variable? arg)
|
|
||||||
(not (let ([v (a60:variable-name arg)])
|
|
||||||
(or (procedure-variable? v context)
|
|
||||||
(label-variable? v context)
|
|
||||||
(primitive-variable? v context)))))
|
|
||||||
(a60:subscript? arg))
|
|
||||||
(let ([arg (if (a60:subscript? arg)
|
|
||||||
(make-a60:variable (a60:subscript-array arg)
|
|
||||||
(list (a60:subscript-index arg)))
|
|
||||||
arg)])
|
|
||||||
`(case-lambda
|
|
||||||
[() ,(compile-expression arg context 'any)]
|
|
||||||
[(val) ,(compile-statement (make-a60:assign (list arg) 'val) 'void context)]))]
|
|
||||||
[(identifier? arg)
|
|
||||||
(compile-argument (make-a60:variable arg null) context)]
|
|
||||||
[else `(lambda () ,(compile-expression arg context 'any))]))
|
|
||||||
|
|
||||||
(define (check-type got expected expr)
|
|
||||||
(or (eq? expected 'any)
|
|
||||||
(case got
|
|
||||||
[(num) (memq expected '(num numbool))]
|
|
||||||
[(bool) (memq expected '(bool numbool))]
|
|
||||||
[(des) (memq expected '(des))]
|
|
||||||
[(func) (memq expected '(func))]
|
|
||||||
[else #f])
|
|
||||||
(raise-syntax-error #f
|
|
||||||
(format "type mismatch (~a != ~a)" got expected)
|
|
||||||
expr)))
|
|
||||||
|
|
||||||
(define (check-spec-type spec type expr subscripts)
|
|
||||||
(let ([target (spec-coerce-target spec subscripts)])
|
|
||||||
(when target
|
|
||||||
(case (syntax-e target)
|
|
||||||
[(integer real) (check-type 'num type expr)]
|
|
||||||
[(boolean) (check-type 'bool type expr)]
|
|
||||||
[(procedure) (check-type 'func type expr)]))))
|
|
||||||
|
|
||||||
|
|
||||||
(define (check-label l context)
|
|
||||||
(if (or (symbol? l)
|
|
||||||
(label-variable? l context))
|
|
||||||
l
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"undefined label"
|
|
||||||
l)))
|
|
||||||
|
|
||||||
(define (at stx expr)
|
|
||||||
(if (syntax? stx)
|
|
||||||
(datum->syntax-object (current-compile-context) expr stx)
|
|
||||||
expr))
|
|
||||||
|
|
||||||
(define (as-builtin stx)
|
|
||||||
;; Preserve source loc, but change to reference to
|
|
||||||
;; a builtin operation by changing the context:
|
|
||||||
(datum->syntax-object
|
|
||||||
(current-compile-context)
|
|
||||||
(syntax-e stx)
|
|
||||||
stx
|
|
||||||
stx))
|
|
||||||
|
|
||||||
;; --------------------
|
|
||||||
|
|
||||||
(define (empty-context)
|
|
||||||
`(((sign prim sign)
|
|
||||||
(entier prim entier)
|
|
||||||
|
|
||||||
(sin prim a60:sin)
|
|
||||||
(cos prim a60:cos)
|
|
||||||
(acrtan prim a60:arctan)
|
|
||||||
(sqrt prim a60:sqrt)
|
|
||||||
(abs prim a60:abs)
|
|
||||||
(ln prim a60:ln)
|
|
||||||
(exp prim a60:exp)
|
|
||||||
|
|
||||||
(prints prim prints)
|
|
||||||
(printn prim printn)
|
|
||||||
(printsln prim printsln)
|
|
||||||
(printnln prim printnln))))
|
|
||||||
|
|
||||||
(define (add-labels context l)
|
|
||||||
(cons (map (lambda (lbl) (cons (if (symbol? lbl)
|
|
||||||
(datum->syntax-object #f lbl)
|
|
||||||
lbl)
|
|
||||||
'label)) l)
|
|
||||||
context))
|
|
||||||
|
|
||||||
(define (add-procedure context var result-type arg-vars by-value-vars arg-specs)
|
|
||||||
(cons (list (cons var 'procedure))
|
|
||||||
context))
|
|
||||||
|
|
||||||
(define (add-settable-procedure context var result-type result-var)
|
|
||||||
(cons (list (cons var `(settable-procedure ,result-var ,result-type)))
|
|
||||||
context))
|
|
||||||
|
|
||||||
(define (add-atoms context ids type)
|
|
||||||
(cons (map (lambda (id) (cons id type)) ids)
|
|
||||||
context))
|
|
||||||
|
|
||||||
(define (add-arrays context names dimensionses type)
|
|
||||||
(cons (map (lambda (name dimensions)
|
|
||||||
(cons name `(array ,type ,(length dimensions))))
|
|
||||||
names dimensionses)
|
|
||||||
context))
|
|
||||||
|
|
||||||
(define (add-switch context name)
|
|
||||||
(cons (list (cons name 'switch))
|
|
||||||
context))
|
|
||||||
|
|
||||||
(define (add-bindings context arg-vars by-value-vars arg-specs)
|
|
||||||
(cons (map (lambda (var)
|
|
||||||
(let ([spec (or (ormap (lambda (spec)
|
|
||||||
(and (ormap (lambda (x) (bound-identifier=? var x))
|
|
||||||
(cdr spec))
|
|
||||||
(car spec)))
|
|
||||||
arg-specs)
|
|
||||||
#'unknown)])
|
|
||||||
(cons var
|
|
||||||
(if (ormap (lambda (x) (bound-identifier=? var x)) by-value-vars)
|
|
||||||
spec
|
|
||||||
(list 'by-name spec)))))
|
|
||||||
arg-vars)
|
|
||||||
context))
|
|
||||||
|
|
||||||
;; var-binding : syntax context -> symbol
|
|
||||||
;; returns an identifier indicating where the var is
|
|
||||||
;; bound, or 'free if it isn't. The compiler inserts
|
|
||||||
;; top-level procedure definitions into the namespace; if
|
|
||||||
;; the variable is bound there, it is a procedure.
|
|
||||||
(define (var-binding var context)
|
|
||||||
(cond
|
|
||||||
[(null? context)
|
|
||||||
(let/ec k
|
|
||||||
(namespace-variable-value (syntax-e var)
|
|
||||||
#t
|
|
||||||
(lambda () (k 'free)))
|
|
||||||
'procedure)]
|
|
||||||
[else
|
|
||||||
(let ([m (var-in-rib var (car context))])
|
|
||||||
(or m (var-binding var (cdr context))))]))
|
|
||||||
|
|
||||||
(define (var-in-rib var rib)
|
|
||||||
(ormap (lambda (b)
|
|
||||||
(if (symbol? (car b))
|
|
||||||
;; primitives:
|
|
||||||
(and (eq? (syntax-e var) (car b))
|
|
||||||
(cdr b))
|
|
||||||
;; everything else:
|
|
||||||
(and (bound-identifier=? var (car b))
|
|
||||||
(cdr b))))
|
|
||||||
rib))
|
|
||||||
|
|
||||||
(define (primitive-variable? var context)
|
|
||||||
(let ([v (var-binding var context)])
|
|
||||||
(and (pair? v)
|
|
||||||
(eq? (car v) 'prim)
|
|
||||||
(cadr v))))
|
|
||||||
|
|
||||||
(define (call-by-name-variable? var context)
|
|
||||||
(let ([v (var-binding var context)])
|
|
||||||
(and (pair? v)
|
|
||||||
(eq? (car v) 'by-name)
|
|
||||||
(cadr v))))
|
|
||||||
|
|
||||||
(define (procedure-variable? var context)
|
|
||||||
(let ([v (var-binding var context)])
|
|
||||||
(eq? v 'procedure)))
|
|
||||||
|
|
||||||
(define (procedure-result-variable? var context)
|
|
||||||
(let ([v (var-binding var context)])
|
|
||||||
(and (pair? v)
|
|
||||||
(eq? (car v) 'settable-procedure)
|
|
||||||
(cdr v))))
|
|
||||||
|
|
||||||
(define (procedure-result-variable-name var context)
|
|
||||||
(let ([v (procedure-result-variable? var context)])
|
|
||||||
(car v)))
|
|
||||||
|
|
||||||
(define (procedure-result-spec var context)
|
|
||||||
(let ([v (procedure-result-variable? var context)])
|
|
||||||
(cadr v)))
|
|
||||||
|
|
||||||
(define (label-variable? var context)
|
|
||||||
(let ([v (var-binding var context)])
|
|
||||||
(eq? v 'label)))
|
|
||||||
|
|
||||||
(define (switch-variable? var context)
|
|
||||||
(let ([v (var-binding var context)])
|
|
||||||
(eq? v 'switch)))
|
|
||||||
|
|
||||||
(define (settable-variable? var context)
|
|
||||||
(let ([v (var-binding var context)])
|
|
||||||
(or (box? v)
|
|
||||||
(and (syntax? v)
|
|
||||||
(memq (syntax-e v) '(integer real boolean))
|
|
||||||
v))))
|
|
||||||
|
|
||||||
(define (own-variable? var context)
|
|
||||||
(let ([v (var-binding var context)])
|
|
||||||
(box? v)))
|
|
||||||
|
|
||||||
(define (array-element? var context)
|
|
||||||
(let ([v (var-binding var context)])
|
|
||||||
(and (pair? v)
|
|
||||||
(eq? (car v) 'array)
|
|
||||||
(or (cadr v)
|
|
||||||
#'unknown))))
|
|
||||||
|
|
||||||
(define (spec-coerce-target spec subscripts)
|
|
||||||
(cond
|
|
||||||
[(and (syntax? spec) (memq (syntax-e spec) '(string label switch real integer boolean unknown))) spec]
|
|
||||||
[(and (syntax? spec) (memq (syntax-e spec) '(unknown))) #f]
|
|
||||||
[(or (not spec) (not (pair? spec))) #f]
|
|
||||||
[(eq? (car spec) 'array) (if (null? subscripts) #'array (cadr spec))]
|
|
||||||
[(eq? (car spec) 'procedure) #'procedure]
|
|
||||||
[else #f]))
|
|
||||||
|
|
||||||
(define (stx-number? a) (and (syntax? a) (number? (syntax-e a)))))
|
|
|
@ -1,35 +0,0 @@
|
||||||
#lang algol60
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
procedure euler (fct,sum,eps,tim); value eps,tim; integer tim;
|
|
||||||
real procedure fct; real sum,eps;
|
|
||||||
comment euler computes the sum of fct(i) for i from zero up to
|
|
||||||
infinity by means of a suitably refined euler transformation. The
|
|
||||||
summation is stopped as soon as tim times in succession the absolute
|
|
||||||
value of the terms of the transformed series are found to be less than
|
|
||||||
eps. Hence, one should provide a function fct with one integer argument,
|
|
||||||
an upper bound eps, and an integer tim. The output is the sum sum. euler
|
|
||||||
is particularly efficient in the case of a slowly convergent or
|
|
||||||
divergent alternating series;
|
|
||||||
begin integer i,k,n,t; array m[0:15]; real mn,mp,ds;
|
|
||||||
i:=n:=t:=0; m[0]:=fct(0); sum:=m[0]/2;
|
|
||||||
nextterm: i:=i+1; mn:=fct(i);
|
|
||||||
for k:=0 step 1 until n do
|
|
||||||
begin mp:=(mn+m[k])/2; m[k]:=mn;
|
|
||||||
mn:=mp end;
|
|
||||||
if (abs(mn)<abs(m[n])) & (n<15) then
|
|
||||||
begin ds:=mn/2; n:=n+1; m[n]:=mn end
|
|
||||||
else ds:=mn;
|
|
||||||
sum:=sum+ds;
|
|
||||||
if abs(ds)<eps then t:=t+1 else t:=0;
|
|
||||||
if t<tim then goto nextterm
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure inv(v) ; inv := 1.0/((v+1)^2);
|
|
||||||
|
|
||||||
real result;
|
|
||||||
euler(inv, result, 0.00005, 10);
|
|
||||||
printnln(result);
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,16 +0,0 @@
|
||||||
#lang algol60
|
|
||||||
|
|
||||||
begin
|
|
||||||
integer procedure SIGMA(x, i, n);
|
|
||||||
value n;
|
|
||||||
integer x, i, n;
|
|
||||||
begin
|
|
||||||
integer sum;
|
|
||||||
sum:=0;
|
|
||||||
for i:=1 step 1 until n do
|
|
||||||
sum:=sum+x;
|
|
||||||
SIGMA:=sum;
|
|
||||||
end;
|
|
||||||
integer q;
|
|
||||||
printnln(SIGMA(q*2-1, q, 7));
|
|
||||||
end
|
|
|
@ -1,124 +0,0 @@
|
||||||
#lang algol60
|
|
||||||
|
|
||||||
begin
|
|
||||||
comment
|
|
||||||
-- From the NASE A60 distribution --
|
|
||||||
Find a solution for the `N queen problem.
|
|
||||||
(got the algorithm from a Modula program from
|
|
||||||
Martin Neitzel).
|
|
||||||
;
|
|
||||||
|
|
||||||
integer N, MAXN;
|
|
||||||
|
|
||||||
MAXN := 9; comment maximum size;
|
|
||||||
N := 2; comment current size;
|
|
||||||
|
|
||||||
tryNextN:
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
integer array column [1 : N];
|
|
||||||
Boolean array empcol [1 : N];
|
|
||||||
Boolean array empup [-N+1 : N-1];
|
|
||||||
Boolean array empdo [2 : 2*N];
|
|
||||||
integer i;
|
|
||||||
|
|
||||||
procedure print;
|
|
||||||
comment
|
|
||||||
print the current solution in a chessboard alike
|
|
||||||
picture ;
|
|
||||||
begin
|
|
||||||
integer i, j;
|
|
||||||
|
|
||||||
procedure outframe;
|
|
||||||
begin
|
|
||||||
integer i;
|
|
||||||
|
|
||||||
for i := 1 step 1 until N do
|
|
||||||
prints (`+---');
|
|
||||||
printsln (`+')
|
|
||||||
end;
|
|
||||||
|
|
||||||
for j := 1 step 1 until N do begin
|
|
||||||
outframe;
|
|
||||||
prints (`|');
|
|
||||||
for i := 1 step 1 until N do begin
|
|
||||||
if N + 1 - j = column [i] then
|
|
||||||
prints (` Q |')
|
|
||||||
else
|
|
||||||
prints (` |')
|
|
||||||
end;
|
|
||||||
printsln (`')
|
|
||||||
end;
|
|
||||||
outframe;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure set (x);
|
|
||||||
value x;
|
|
||||||
integer x;
|
|
||||||
begin
|
|
||||||
integer y;
|
|
||||||
|
|
||||||
for y := 1 step 1 until N do
|
|
||||||
begin
|
|
||||||
if empcol [ y ] & empup [ x-y ]
|
|
||||||
& empdo [ x+y ] then
|
|
||||||
begin
|
|
||||||
column [ y ] := x ;
|
|
||||||
empcol [ y ] := false ;
|
|
||||||
empup [ x-y ] := false ;
|
|
||||||
empdo [ x+y ] := false ;
|
|
||||||
if x = N then
|
|
||||||
goto gotone
|
|
||||||
else
|
|
||||||
set ( x + 1 ) ;
|
|
||||||
empdo [ x+y ] := true ;
|
|
||||||
empup [ x-y ] := true ;
|
|
||||||
empcol [ y ] := true ;
|
|
||||||
column [ y ] := 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
comment
|
|
||||||
main program start
|
|
||||||
;
|
|
||||||
|
|
||||||
prints (`looking onto a ');
|
|
||||||
printn (N);
|
|
||||||
prints (` x ');
|
|
||||||
printn (N);
|
|
||||||
printsln (` chessboard...');
|
|
||||||
|
|
||||||
for i := 1 step 1 until N do
|
|
||||||
begin
|
|
||||||
column [ i ] := 0 ;
|
|
||||||
empcol [ i ] := true
|
|
||||||
end;
|
|
||||||
|
|
||||||
for i := -N+1 step 1 until N-1 do
|
|
||||||
empup [ i ] := true ;
|
|
||||||
|
|
||||||
for i := 2 step 1 until 2*N do
|
|
||||||
empdo [ i ] := true ;
|
|
||||||
|
|
||||||
set ( 1 ) ;
|
|
||||||
|
|
||||||
printsln (`NO SOLUTION.');
|
|
||||||
goto contN;
|
|
||||||
|
|
||||||
gotone:
|
|
||||||
printsln(`SOLVED');
|
|
||||||
print;
|
|
||||||
|
|
||||||
contN:
|
|
||||||
if N < MAXN then begin
|
|
||||||
N := N + 1;
|
|
||||||
goto tryNextN
|
|
||||||
end;
|
|
||||||
|
|
||||||
printsln (`done.')
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,69 +0,0 @@
|
||||||
#lang algol60
|
|
||||||
|
|
||||||
begin
|
|
||||||
comment
|
|
||||||
-- From the NASE A60 distribution --
|
|
||||||
calculation of the prime numbers between 2 and 200
|
|
||||||
;
|
|
||||||
|
|
||||||
integer NN;
|
|
||||||
|
|
||||||
NN := 200;
|
|
||||||
|
|
||||||
begin
|
|
||||||
comment first algorithm (check division in a loop) ;
|
|
||||||
|
|
||||||
Boolean procedure isprime (n);
|
|
||||||
value n;
|
|
||||||
integer n;
|
|
||||||
begin
|
|
||||||
Boolean procedure even (n);
|
|
||||||
value n; integer n;
|
|
||||||
even := entier (n / 2) * 2 = n;
|
|
||||||
integer i;
|
|
||||||
|
|
||||||
isprime := false;
|
|
||||||
if even (n) & n != 2 then
|
|
||||||
goto ret;
|
|
||||||
|
|
||||||
for i := 3 step 2 until n div 2 do
|
|
||||||
if entier (n / i) * i = n then
|
|
||||||
goto ret;
|
|
||||||
isprime := true;
|
|
||||||
ret:
|
|
||||||
|
|
||||||
end;
|
|
||||||
|
|
||||||
integer i;
|
|
||||||
|
|
||||||
printsln (`first:');
|
|
||||||
|
|
||||||
for i := 2 step 1 until NN do
|
|
||||||
if isprime (i) then
|
|
||||||
printnln (i);
|
|
||||||
printsln (`done.')
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
|
||||||
comment second algorithm (sieve) ;
|
|
||||||
|
|
||||||
|
|
||||||
Boolean array arr [2 : NN];
|
|
||||||
integer i, j;
|
|
||||||
|
|
||||||
printsln (`second:');
|
|
||||||
|
|
||||||
for i := 2 step 1 until NN do
|
|
||||||
arr [i] := true;
|
|
||||||
|
|
||||||
for i := 2 step 1 until NN div 2 do
|
|
||||||
for j := 2 * i step i until NN do
|
|
||||||
arr [j] := false;
|
|
||||||
|
|
||||||
for i := 2 step 1 until NN do
|
|
||||||
if arr [i] then
|
|
||||||
printnln (i);
|
|
||||||
printsln (`done.')
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,24 +0,0 @@
|
||||||
#lang info
|
|
||||||
|
|
||||||
(define collection "algol60")
|
|
||||||
(define build-deps '("at-exp-lib"
|
|
||||||
"rackunit-lib"
|
|
||||||
"racket-doc"
|
|
||||||
"scribble-doc"
|
|
||||||
"scribble-lib"
|
|
||||||
"drracket-plugin-lib"))
|
|
||||||
|
|
||||||
(define tools '(("tool.rkt")))
|
|
||||||
(define tool-names '("Algol 60"))
|
|
||||||
(define scribblings '(("algol60.scrbl" () (experimental 40))))
|
|
||||||
(define deps '("base"
|
|
||||||
"compatibility-lib"
|
|
||||||
"drracket-plugin-lib"
|
|
||||||
"errortrace-lib"
|
|
||||||
"gui-lib"
|
|
||||||
"parser-tools-lib"
|
|
||||||
"string-constants-lib"))
|
|
||||||
|
|
||||||
(define pkg-desc "An implementation of the Algol60 language")
|
|
||||||
|
|
||||||
(define pkg-authors '(mflatt robby))
|
|
|
@ -1,8 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
(require "../runtime.rkt"
|
|
||||||
"../prims.rkt")
|
|
||||||
|
|
||||||
(provide (all-from-out racket/base)
|
|
||||||
(all-from-out "../prims.rkt")
|
|
||||||
(all-from-out "../runtime.rkt"))
|
|
|
@ -1,48 +0,0 @@
|
||||||
#lang s-exp syntax/module-reader
|
|
||||||
algol60/lang/algol60
|
|
||||||
|
|
||||||
#:read algol60-read
|
|
||||||
#:read-syntax algol60-read-syntax
|
|
||||||
#:info algol60-get-info
|
|
||||||
#:whole-body-readers? #t
|
|
||||||
|
|
||||||
|
|
||||||
(require "../parse.rkt"
|
|
||||||
;; Parses to generate an AST. Identifiers in the AST
|
|
||||||
;; are represented as syntax objects with source location.
|
|
||||||
|
|
||||||
"../simplify.rkt"
|
|
||||||
;; Desugars the AST, transforming `for' to `if'+`goto',
|
|
||||||
;; and flattening `if' statements so they are always
|
|
||||||
;; of the for `if <exp> then goto <label> else goto <label>'
|
|
||||||
|
|
||||||
"../compile.rkt"
|
|
||||||
;; Compiles a simplified AST to Scheme.
|
|
||||||
|
|
||||||
mzlib/file
|
|
||||||
syntax/strip-context)
|
|
||||||
|
|
||||||
|
|
||||||
(define (algol60-read in)
|
|
||||||
(map syntax->datum (algol60-read-syntax #f in)))
|
|
||||||
|
|
||||||
|
|
||||||
(define (algol60-read-syntax src in)
|
|
||||||
(define parsed (parse-a60-port in src))
|
|
||||||
(define simplified (simplify parsed #'here))
|
|
||||||
(define compiled (compile-simplified simplified #'here))
|
|
||||||
(define stripped (strip-context compiled))
|
|
||||||
|
|
||||||
(list stripped))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; Extension: cooperate with DrRacket and tell it to use the default,
|
|
||||||
;; textual lexer and color scheme when editing algol programs.
|
|
||||||
(define (algol60-get-info key default default-filter)
|
|
||||||
(case key
|
|
||||||
[(color-lexer)
|
|
||||||
(dynamic-require 'syntax-color/default-lexer
|
|
||||||
'default-lexer)]
|
|
||||||
[else
|
|
||||||
(default-filter key default)]))
|
|
|
@ -1,413 +0,0 @@
|
||||||
#cs(module parse mzscheme
|
|
||||||
(require parser-tools/lex
|
|
||||||
(prefix : parser-tools/lex-sre)
|
|
||||||
"cfg-parser.rkt"
|
|
||||||
parser-tools/yacc
|
|
||||||
syntax/readerr
|
|
||||||
"prims.rkt")
|
|
||||||
|
|
||||||
(define-lex-abbrevs [lex:letter (:or (:/ #\a #\z) (:/ #\A #\Z))]
|
|
||||||
[lex:digit (:/ #\0 #\9)]
|
|
||||||
[lex:whitespace (:or #\newline #\return #\tab #\space #\vtab)]
|
|
||||||
[lex:comment (:: (:* lex:whitespace) "comment" (:* (:~ #\;)) #\;)])
|
|
||||||
|
|
||||||
(define-tokens non-terminals (<logical-value>
|
|
||||||
<type> <identifier>
|
|
||||||
<unsigned-integer> <unsigned-float> <string>
|
|
||||||
|
|
||||||
GOTO IF THEN ELSE FOR DO STEP UNTIL WHILE
|
|
||||||
OWN ARRAY STRING PROCEDURE SWITCH LABEL VALUE
|
|
||||||
BEGIN END
|
|
||||||
POWER PLUS MINUS TIMES SLASH DIVIDE
|
|
||||||
LESS LESS-OR-EQUAL EQUAL GREATER-OR-EQUAL GREATER NOT-EQUAL ASSIGN
|
|
||||||
NEGATE AND OR IMPLIES EQUIV
|
|
||||||
COMMA COLON SEMICOLON
|
|
||||||
OPEN CLOSE OPENSQ CLOSESQ
|
|
||||||
EOF
|
|
||||||
UNPARSEABLE))
|
|
||||||
|
|
||||||
(define stx-for-original-property (read-syntax #f (open-input-string "original")))
|
|
||||||
|
|
||||||
(define-syntax (token stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ name val)
|
|
||||||
(identifier? (syntax name))
|
|
||||||
(let ([name (syntax name)])
|
|
||||||
(with-syntax ([token-name (datum->syntax-object
|
|
||||||
name
|
|
||||||
(string->symbol
|
|
||||||
(format "token-~a" (syntax-e name))))]
|
|
||||||
[source-name (datum->syntax-object name 'source-name)]
|
|
||||||
[start-pos (datum->syntax-object name 'start-pos)]
|
|
||||||
[end-pos (datum->syntax-object name 'end-pos)])
|
|
||||||
(syntax
|
|
||||||
(token-name
|
|
||||||
(datum->syntax-object #f val
|
|
||||||
(list
|
|
||||||
source-name
|
|
||||||
(position-line start-pos)
|
|
||||||
(position-col start-pos)
|
|
||||||
(position-offset start-pos)
|
|
||||||
(- (position-offset end-pos)
|
|
||||||
(position-offset start-pos)))
|
|
||||||
stx-for-original-property)))))]))
|
|
||||||
(define-syntax (ttoken stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ name)
|
|
||||||
(identifier? (syntax name))
|
|
||||||
(syntax (token name 'name))]))
|
|
||||||
|
|
||||||
(define (lex source-name)
|
|
||||||
(lexer
|
|
||||||
[(:+ lex:whitespace) (void)]
|
|
||||||
["true" (token <logical-value> #t)]
|
|
||||||
["false" (token <logical-value> #f)]
|
|
||||||
["real" (token <type> 'real)]
|
|
||||||
["integer" (token <type> 'integer)]
|
|
||||||
["Boolean" (token <type> 'boolean)]
|
|
||||||
["goto" (ttoken GOTO)]
|
|
||||||
["if" (ttoken IF)]
|
|
||||||
["then" (ttoken THEN)]
|
|
||||||
["else" (ttoken ELSE)]
|
|
||||||
["for" (ttoken FOR)]
|
|
||||||
["do" (ttoken DO)]
|
|
||||||
["step" (ttoken STEP)]
|
|
||||||
["until" (ttoken UNTIL)]
|
|
||||||
["while" (ttoken WHILE)]
|
|
||||||
["own" (ttoken OWN)]
|
|
||||||
["array" (ttoken ARRAY)]
|
|
||||||
["string" (ttoken STRING)]
|
|
||||||
["procedure" (ttoken PROCEDURE)]
|
|
||||||
["switch" (ttoken SWITCH)]
|
|
||||||
["label" (ttoken LABEL)]
|
|
||||||
["value" (ttoken VALUE)]
|
|
||||||
[(:: "begin" lex:comment) (ttoken BEGIN)]
|
|
||||||
["begin" (ttoken BEGIN)]
|
|
||||||
[(:: "end" lex:comment) (ttoken BEGIN)]
|
|
||||||
["end" (ttoken END)]
|
|
||||||
["^" (token POWER 'expt)]
|
|
||||||
["+" (token PLUS '+)]
|
|
||||||
["-" (token MINUS '-)]
|
|
||||||
["*" (token TIMES '*)]
|
|
||||||
["/" (token SLASH '/)]
|
|
||||||
["div" (token DIVIDE 'quotient)]
|
|
||||||
["<" (token LESS '<)]
|
|
||||||
["<=" (token LESS-OR-EQUAL '<=)]
|
|
||||||
["=" (token EQUAL '=)]
|
|
||||||
[">" (token GREATER '>)]
|
|
||||||
[">=" (token GREATER-OR-EQUAL '>=)]
|
|
||||||
["!=" (token NOT-EQUAL '!=)]
|
|
||||||
["!" (token NEGATE '!)]
|
|
||||||
["&" (token AND '&)]
|
|
||||||
["|" (token OR '\|)]
|
|
||||||
["=>" (token IMPLIES '==>)]
|
|
||||||
["==" (token EQUIV '==)]
|
|
||||||
[":=" (ttoken ASSIGN)]
|
|
||||||
["," (ttoken COMMA)]
|
|
||||||
[":" (ttoken COLON)]
|
|
||||||
[(:: ";" lex:comment) (ttoken SEMICOLON)]
|
|
||||||
[";" (ttoken SEMICOLON)]
|
|
||||||
["(" (ttoken OPEN)]
|
|
||||||
[")" (ttoken CLOSE)]
|
|
||||||
["[" (ttoken OPENSQ)]
|
|
||||||
["]" (ttoken CLOSESQ)]
|
|
||||||
[(:: lex:letter (:* (:or lex:letter lex:digit))) (token <identifier> (string->symbol lexeme))]
|
|
||||||
[(:+ lex:digit) (token <unsigned-integer> (string->number lexeme))]
|
|
||||||
[(:or (:: (:+ lex:digit) #\. (:* lex:digit))
|
|
||||||
(:: (:* lex:digit) #\. (:+ lex:digit))) (token <unsigned-float> (string->number lexeme))]
|
|
||||||
[(:: #\` (:* (:~ #\' #\`)) #\') (let ([s lexeme])
|
|
||||||
(token <string> (substring s 1 (sub1 (string-length s)))))]
|
|
||||||
[(eof) (ttoken EOF)]
|
|
||||||
[any-char (token UNPARSEABLE (string->symbol lexeme))]))
|
|
||||||
|
|
||||||
(define parse
|
|
||||||
(cfg-parser
|
|
||||||
(tokens non-terminals)
|
|
||||||
(start <program>)
|
|
||||||
(end EOF)
|
|
||||||
(error (lambda (_ name stx start end)
|
|
||||||
(raise-read-error (format "parse error near ~a" name)
|
|
||||||
(syntax-source stx)
|
|
||||||
(syntax-line stx)
|
|
||||||
(syntax-column stx)
|
|
||||||
(syntax-position stx)
|
|
||||||
(syntax-span stx))))
|
|
||||||
(suppress)
|
|
||||||
(grammar
|
|
||||||
;; ==================== Expressions ====================
|
|
||||||
(<expression> [(<arithmetic-expression>) $1]
|
|
||||||
[(<Boolean-expression>) $1]
|
|
||||||
[(<designational-expression>) $1])
|
|
||||||
;; -------------------- Numbers --------------------
|
|
||||||
(<arithmetic-expression> [(<simple-arithmetic-expression>) $1]
|
|
||||||
[(IF <Boolean-expression>
|
|
||||||
THEN <simple-arithmetic-expression>
|
|
||||||
ELSE <arithmetic-expression>)
|
|
||||||
(make-a60:if $2 $4 $6)])
|
|
||||||
(<simple-arithmetic-expression> [(<term>) $1]
|
|
||||||
[(<adding-operator> <term>) (make-a60:unary 'num 'num $1 $2)]
|
|
||||||
[(<simple-arithmetic-expression> <adding-operator> <term>)
|
|
||||||
(make-a60:binary 'num 'num $2 $1 $3)])
|
|
||||||
(<term> [(<factor>) $1]
|
|
||||||
[(<term> <multiplying-operator> <factor>) (make-a60:binary 'num 'num $2 $1 $3)])
|
|
||||||
(<factor> [(<primary>) $1]
|
|
||||||
[(<factor> POWER <primary>) (make-a60:binary 'num 'num $2 $1 $3)])
|
|
||||||
(<adding-operator> [(PLUS) $1]
|
|
||||||
[(MINUS) $1])
|
|
||||||
(<multiplying-operator> [(TIMES) $1]
|
|
||||||
[(SLASH) $1]
|
|
||||||
[(DIVIDE) $1])
|
|
||||||
(<primary> [(<unsigned-integer>) $1]
|
|
||||||
[(<unsigned-float>) $1]
|
|
||||||
[(<variable>) $1]
|
|
||||||
[(<function-designator>) $1]
|
|
||||||
[(OPEN <arithmetic-expression> CLOSE) $2])
|
|
||||||
;; -------------------- Booleans --------------------
|
|
||||||
(<relational-operator> [(LESS) $1]
|
|
||||||
[(LESS-OR-EQUAL) $1]
|
|
||||||
[(EQUAL) $1]
|
|
||||||
[(GREATER-OR-EQUAL) $1]
|
|
||||||
[(GREATER) $1]
|
|
||||||
[(NOT-EQUAL) $1])
|
|
||||||
(<relation> [(<simple-arithmetic-expression> <relational-operator> <simple-arithmetic-expression>)
|
|
||||||
(make-a60:binary 'bool 'num $2 $1 $3)])
|
|
||||||
(<Boolean-primary> [(<logical-value>) $1]
|
|
||||||
[(<variable>) $1]
|
|
||||||
[(<function-designator>) $1]
|
|
||||||
[(<relation>) $1]
|
|
||||||
[(OPEN <Boolean-expression> CLOSE) $2])
|
|
||||||
(<Boolean-secondary> [(<Boolean-primary>) $1]
|
|
||||||
[(NEGATE <Boolean-primary>) (make-a60:unary 'bool 'bool $1 $2)])
|
|
||||||
(<Boolean-factor> [(<Boolean-secondary>) $1]
|
|
||||||
[(<Boolean-factor> AND <Boolean-secondary>) (make-a60:binary 'bool 'bool $2 $1 $3)])
|
|
||||||
(<Boolean-term> [(<Boolean-factor>) $1]
|
|
||||||
[(<Boolean-term> OR <Boolean-factor>) (make-a60:binary 'bool 'bool $2 $1 $3)])
|
|
||||||
|
|
||||||
(<implication> [(<Boolean-term>) $1]
|
|
||||||
[(<implication> IMPLIES <Boolean-term>) (make-a60:binary 'bool 'bool $2 $1 $3)])
|
|
||||||
(<simple-Boolean> [(<implication>) $1]
|
|
||||||
[(<simple-Boolean> EQUIV <implication>) (make-a60:binary 'bool 'bool $2 $1 $3)])
|
|
||||||
(<Boolean-expression> [(<simple-Boolean>) $1]
|
|
||||||
[(IF <Boolean-expression>
|
|
||||||
THEN <simple-Boolean>
|
|
||||||
ELSE <Boolean-expression>)
|
|
||||||
(make-a60:if $2 $4 $6)])
|
|
||||||
;; -------------------- Designationals --------------------
|
|
||||||
(<label> [(<identifier>) $1]
|
|
||||||
[(<unsigned-integer>) $1])
|
|
||||||
(<switch-identifier> [(<identifier>) $1])
|
|
||||||
(<switch-designator> [(<switch-identifier> OPENSQ <arithmetic-expression> CLOSESQ)
|
|
||||||
(make-a60:subscript $1 $3)])
|
|
||||||
(<simple-designational-expression> [(<label>) $1]
|
|
||||||
[(<switch-designator>) $1]
|
|
||||||
[(OPEN <designational-expression> CLOSE) $2])
|
|
||||||
(<designational-expression> [(<simple-designational-expression>) $1]
|
|
||||||
[(IF <Boolean-expression>
|
|
||||||
THEN <simple-designational-expression>
|
|
||||||
ELSE <designational-expression>)
|
|
||||||
(make-a60:if $2 $4 $6)])
|
|
||||||
;; -------------------- Variables --------------------
|
|
||||||
(<subscript-list> [(<arithmetic-expression>) (list $1)]
|
|
||||||
[(<subscript-list> COMMA <arithmetic-expression>) (append $1 (list $3))])
|
|
||||||
(<subscripted-variable> [(<identifier> OPENSQ <subscript-list> CLOSESQ) (make-a60:variable $1 $3)])
|
|
||||||
(<variable> [(<identifier>) (make-a60:variable $1 null)]
|
|
||||||
[(<subscripted-variable>) $1])
|
|
||||||
;; -------------------- Function calls --------------------
|
|
||||||
(<function-designator> [(<identifier> <actual-parameter-part>) (make-a60:app $1 $2)])
|
|
||||||
;; ==================== Statements ====================
|
|
||||||
;; - - - - - - - - - - non-empty - - - - - - - - - -
|
|
||||||
(<unlabelled-basic-nonempty-statement> [(<assignment-statement>) $1]
|
|
||||||
[(<go-to-statement>) $1]
|
|
||||||
[(<procedure-statement>) $1])
|
|
||||||
(<basic-nonempty-statement> [(<unlabelled-basic-nonempty-statement>) $1]
|
|
||||||
[(<label> COLON <basic-statement>) (make-a60:label $1 $3)])
|
|
||||||
(<unconditional-nonempty-statement> [(<basic-nonempty-statement>) $1]
|
|
||||||
[(<compound-statement>) $1]
|
|
||||||
[(<block>) $1])
|
|
||||||
(<nonempty-statement> [(<unconditional-nonempty-statement>) $1]
|
|
||||||
[(<conditional-statement>) $1]
|
|
||||||
[(<for-statement>) $1])
|
|
||||||
;; - - - - - - - - - - possibly empty - - - - - - - - - -
|
|
||||||
(<unlabelled-basic-statement> [(<unlabelled-basic-nonempty-statement>) $1]
|
|
||||||
[(<dummy-statement>) $1])
|
|
||||||
(<basic-statement> [(<unlabelled-basic-statement>) $1]
|
|
||||||
[(<label> COLON <basic-statement>) (make-a60:label $1 $3)])
|
|
||||||
(<unconditional-statement> [(<basic-statement>) $1]
|
|
||||||
[(<unconditional-nonempty-statement>) $1])
|
|
||||||
(<statement> [(<unconditional-statement>) $1]
|
|
||||||
[(<nonempty-statement>) $1])
|
|
||||||
;; -------------------- block and compound --------------------
|
|
||||||
(<compound-tail> [(<statement> END) (list $1)]
|
|
||||||
[(<statement> SEMICOLON <compound-tail>) (cons $1 $3)])
|
|
||||||
(<block-head> [(BEGIN <declaration>) (list $2)]
|
|
||||||
[(<block-head> SEMICOLON <declaration>) (append $1 (list $3))])
|
|
||||||
(<unlabelled-block> [(<block-head> SEMICOLON <compound-tail>) (make-a60:block $1 $3)])
|
|
||||||
(<unlabelled-compound> [(BEGIN <compound-tail>) (make-a60:compound $2)])
|
|
||||||
|
|
||||||
(<compound-statement> [(<unlabelled-compound>) $1]
|
|
||||||
[(<label> COLON <compound-statement>) (make-a60:label $1 $3)])
|
|
||||||
(<block> [(<unlabelled-block>) $1]
|
|
||||||
[(<label> COLON <block>) (make-a60:label $1 $3)])
|
|
||||||
;; -------------------- assignment --------------------
|
|
||||||
(<left-part> [(<variable> ASSIGN) $1])
|
|
||||||
(<left-part-list> [(<left-part>) (list $1)]
|
|
||||||
[(<left-part-list> <left-part>) (append $1 (list $2))])
|
|
||||||
(<assignment-statement> [(<left-part-list> <arithmetic-expression>) (make-a60:assign $1 $2)]
|
|
||||||
[(<left-part-list> <Boolean-expression>) (make-a60:assign $1 $2)])
|
|
||||||
;; -------------------- goto --------------------
|
|
||||||
(<go-to-statement> [(GOTO <designational-expression>) (make-a60:goto $2)])
|
|
||||||
;; -------------------- dummy --------------------
|
|
||||||
(<dummy-statement> [() (make-a60:compound null)])
|
|
||||||
;; -------------------- conditional --------------------
|
|
||||||
(<conditional-statement> [(IF <Boolean-expression> THEN <unconditional-statement>)
|
|
||||||
(make-a60:branch $2 $4 (make-a60:compound null))]
|
|
||||||
[(IF <Boolean-expression> THEN <unconditional-statement> ELSE <statement>)
|
|
||||||
(make-a60:branch $2 $4 $6)]
|
|
||||||
[(IF <Boolean-expression> THEN <for-statement>)
|
|
||||||
(make-a60:branch $2 $4 (make-a60:compound null))]
|
|
||||||
[(<label> COLON <conditional-statement>) (make-a60:label $1 $3)])
|
|
||||||
;; -------------------- for --------------------
|
|
||||||
(<for-list-element> [(<arithmetic-expression>) (make-a60:for-number $1)]
|
|
||||||
[(<arithmetic-expression> STEP <arithmetic-expression> UNTIL <arithmetic-expression>)
|
|
||||||
(make-a60:for-step $1 $3 $5)]
|
|
||||||
[(<arithmetic-expression> WHILE <Boolean-expression>) (make-a60:for-while $1 $3)])
|
|
||||||
(<for-list> [(<for-list-element>) (list $1)]
|
|
||||||
[(<for-list> COMMA <for-list-element>) (append $1 (list $3))])
|
|
||||||
(<for-statement> [(FOR <variable> ASSIGN <for-list> DO <statement>)
|
|
||||||
(make-a60:for $2 $4 $6)]
|
|
||||||
[(<label> COLON <for-statement>) (make-a60:label $1 $3)])
|
|
||||||
;; -------------------- procedure statement --------------------
|
|
||||||
(<actual-parameter> [(<string>) $1]
|
|
||||||
[(<expression>) $1]
|
|
||||||
; [(<identifier>) $1] ; switch, array, or procedure
|
|
||||||
)
|
|
||||||
(<parameter-delimiter> [(COMMA) (void)]
|
|
||||||
[(CLOSE <identifier> COLON OPEN) (void)]) ;; <identifier> was <letter-string>!
|
|
||||||
(<actual-parameter-list> [(<actual-parameter>) (list $1)]
|
|
||||||
[(<actual-parameter-list> <parameter-delimiter> <actual-parameter>)
|
|
||||||
(append $1 (list $3))])
|
|
||||||
(<actual-parameter-part> [() null]
|
|
||||||
[(OPEN <actual-parameter-list> CLOSE) $2])
|
|
||||||
(<procedure-statement> [(<identifier> <actual-parameter-part>) (make-a60:call $1 $2)])
|
|
||||||
;; ==================== Declarations ====================
|
|
||||||
(<declaration> [(<type-declaration>) $1]
|
|
||||||
[(<array-declaration>) $1]
|
|
||||||
[(<switch-declaration>) $1]
|
|
||||||
[(<procedure-declaration>) $1])
|
|
||||||
;; -------------------- Simple --------------------
|
|
||||||
(<type-list> [(<identifier>) (list $1)]
|
|
||||||
[(<identifier> COMMA <type-list>) (cons $1 $3)])
|
|
||||||
(<local-or-own-type> [(<type>) $1]
|
|
||||||
[(OWN <type>) (box $2)]) ; box => own
|
|
||||||
(<type-declaration> [(<local-or-own-type> <type-list>) (make-a60:type-decl $1 $2)])
|
|
||||||
;; -------------------- Arrays --------------------
|
|
||||||
(<bound-pair> [(<arithmetic-expression> COLON <arithmetic-expression>) (cons $1 $3)])
|
|
||||||
(<bound-pair-list> [(<bound-pair>) (list $1)]
|
|
||||||
[(<bound-pair-list> COMMA <bound-pair>) (append $1 (list $3))])
|
|
||||||
(<array-segment> [(<identifier> OPENSQ <bound-pair-list> CLOSESQ) (list (cons $1 $3))]
|
|
||||||
[(<identifier> COMMA <array-segment>) (cons (cons $1 (cdar $3)) $3)])
|
|
||||||
(<array-list> [(<array-segment>) $1]
|
|
||||||
[(<array-list> COMMA <array-segment>) (append $1 $3)])
|
|
||||||
(<array-declaration> [(ARRAY <array-list>) (make-a60:array-decl #'unknown $2)]
|
|
||||||
[(<local-or-own-type> ARRAY <array-list>) (make-a60:array-decl $1 $3)])
|
|
||||||
;; -------------------- Switches --------------------
|
|
||||||
(<switch-list> [(<designational-expression>) (list $1)]
|
|
||||||
[(<switch-list> COMMA <designational-expression>) (append $1 (list $3))])
|
|
||||||
(<switch-declaration> [(SWITCH <switch-identifier> ASSIGN <switch-list>) (make-a60:switch-decl $2 $4)])
|
|
||||||
;; -------------------- Procedures --------------------
|
|
||||||
(<formal-parameter> [(<identifier>) $1])
|
|
||||||
(<formal-parameter-list> [(<formal-parameter>) (list $1)]
|
|
||||||
[(<formal-parameter-list> <parameter-delimiter> <formal-parameter>)
|
|
||||||
(append $1 (list $3))])
|
|
||||||
(<formal-parameter-part> [() null]
|
|
||||||
[(OPEN <formal-parameter-list> CLOSE) $2])
|
|
||||||
(<identifier-list> [(<identifier>) (list $1)]
|
|
||||||
[(<identifier-list> COMMA <identifier>) (append $1 (list $3))])
|
|
||||||
(<value-part> [(VALUE <identifier-list> SEMICOLON) $2]
|
|
||||||
[() null])
|
|
||||||
(<specifier> [(STRING) 'string]
|
|
||||||
[(<type>) $1]
|
|
||||||
[(ARRAY) '(array #'unknown)]
|
|
||||||
[(<type> ARRAY) `(array ,$1)]
|
|
||||||
[(LABEL) 'label]
|
|
||||||
[(SWITCH) 'switch]
|
|
||||||
[(PROCEDURE) '(procedure #'unknown)]
|
|
||||||
[(<type> PROCEDURE) `(procedure ,$1)])
|
|
||||||
(<nonempty-specification-part> [(<specifier> <identifier-list> SEMICOLON) (list (cons $1 $2))]
|
|
||||||
[(<nonempty-specification-part> <specifier> <identifier-list> SEMICOLON)
|
|
||||||
(append $1 (list (cons $2 $3)))])
|
|
||||||
(<specification-part> [() null]
|
|
||||||
[(<nonempty-specification-part>) $1])
|
|
||||||
(<procedure-heading> [(<identifier> <formal-parameter-part> SEMICOLON <value-part> <specification-part>)
|
|
||||||
(list $1 $2 $4 $5)])
|
|
||||||
(<procedure-body> [(<nonempty-statement>) $1])
|
|
||||||
(<procedure-declaration> [(PROCEDURE <procedure-heading> <procedure-body>)
|
|
||||||
(make-a60:proc-decl #'unknown (car $2) (cadr $2) (caddr $2) (cadddr $2) $3)]
|
|
||||||
[(<type> PROCEDURE <procedure-heading> <procedure-body>)
|
|
||||||
(make-a60:proc-decl $1 (car $3) (cadr $3) (caddr $3) (cadddr $3) $4)])
|
|
||||||
;; ==================== Program ====================
|
|
||||||
(<program> [(<block>) $1]
|
|
||||||
[(<compound-statement>) $1]))))
|
|
||||||
|
|
||||||
(define-syntax (define-a60-structs stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ (struct-name (field ...)) ...)
|
|
||||||
(with-syntax ([(a60:struct ...) (map (lambda (id)
|
|
||||||
(datum->syntax-object
|
|
||||||
id
|
|
||||||
(string->symbol
|
|
||||||
(format "a60:~a" (syntax-e id)))))
|
|
||||||
(syntax->list (syntax (struct-name ...))))])
|
|
||||||
(syntax (begin (define-struct a60:struct (field ...)) ...
|
|
||||||
(provide (struct a60:struct (field ...)) ...))))]))
|
|
||||||
|
|
||||||
(define-a60-structs
|
|
||||||
;; Expressions
|
|
||||||
(if (test then else))
|
|
||||||
(unary (type argtype op arg))
|
|
||||||
(binary (type argtype op arg1 arg2))
|
|
||||||
(subscript (array index))
|
|
||||||
(variable (name indices))
|
|
||||||
(app (func args))
|
|
||||||
;; plus numbers, strings, and booleans
|
|
||||||
|
|
||||||
;; Statements
|
|
||||||
(block (decls statements))
|
|
||||||
(compound (statements))
|
|
||||||
(assign (variables rhs))
|
|
||||||
(goto (target))
|
|
||||||
(branch (test then else))
|
|
||||||
(call (proc args))
|
|
||||||
(for (variable values body))
|
|
||||||
(dummy ())
|
|
||||||
(label (name statement))
|
|
||||||
|
|
||||||
;; for values
|
|
||||||
(for-number (value))
|
|
||||||
(for-step (start step end))
|
|
||||||
(for-while (value test))
|
|
||||||
|
|
||||||
;; declarations
|
|
||||||
(type-decl (type vars))
|
|
||||||
(array-decl (type vars))
|
|
||||||
(switch-decl (var cases))
|
|
||||||
(proc-decl (result-type var arg-vars by-value-vars arg-specs body)))
|
|
||||||
|
|
||||||
(define (parse-a60-port port file)
|
|
||||||
(let ([lexer (lex file)])
|
|
||||||
(port-count-lines! port)
|
|
||||||
(parse
|
|
||||||
(lambda ()
|
|
||||||
(let loop ()
|
|
||||||
(let ([v (lexer port)])
|
|
||||||
(if (void? v)
|
|
||||||
(loop)
|
|
||||||
v)))))))
|
|
||||||
|
|
||||||
(define (parse-a60-file file)
|
|
||||||
(with-input-from-file file
|
|
||||||
(lambda ()
|
|
||||||
(parse-a60-port (current-input-port)
|
|
||||||
(path->complete-path file)))))
|
|
||||||
|
|
||||||
(provide parse-a60-file parse-a60-port))
|
|
|
@ -1,106 +0,0 @@
|
||||||
(module prims mzscheme
|
|
||||||
(provide != ! & \|
|
|
||||||
==> ==
|
|
||||||
sign entier
|
|
||||||
|
|
||||||
a60:sin
|
|
||||||
a60:cos
|
|
||||||
a60:arctan
|
|
||||||
a60:sqrt
|
|
||||||
a60:abs
|
|
||||||
a60:ln
|
|
||||||
a60:exp
|
|
||||||
|
|
||||||
prints printn
|
|
||||||
printsln printnln)
|
|
||||||
|
|
||||||
(define (!= a b)
|
|
||||||
(not (= a b)))
|
|
||||||
|
|
||||||
(define (! a)
|
|
||||||
(unless (boolean? a)
|
|
||||||
(raise-type-error '! "boolean" a))
|
|
||||||
(not a))
|
|
||||||
|
|
||||||
(define (& a b)
|
|
||||||
(unless (boolean? a)
|
|
||||||
(raise-type-error '& "boolean" 0 a b))
|
|
||||||
(unless (boolean? b)
|
|
||||||
(raise-type-error '& "boolean" 1 a b))
|
|
||||||
(and a b))
|
|
||||||
|
|
||||||
(define (\| a b)
|
|
||||||
(unless (boolean? a)
|
|
||||||
(raise-type-error '\| "boolean" 0 a b))
|
|
||||||
(unless (boolean? b)
|
|
||||||
(raise-type-error '\| "boolean" 1 a b))
|
|
||||||
(or a b))
|
|
||||||
|
|
||||||
(define (==> a b)
|
|
||||||
(unless (boolean? a)
|
|
||||||
(raise-type-error '=> "boolean" 0 a b))
|
|
||||||
(unless (boolean? b)
|
|
||||||
(raise-type-error '=> "boolean" 1 a b))
|
|
||||||
(or (not a) b))
|
|
||||||
|
|
||||||
(define (== a b)
|
|
||||||
(unless (boolean? a)
|
|
||||||
(raise-type-error '== "boolean" 0 a b))
|
|
||||||
(unless (boolean? b)
|
|
||||||
(raise-type-error '== "boolean" 1 a b))
|
|
||||||
(eq? a b))
|
|
||||||
|
|
||||||
(define (get-number who v)
|
|
||||||
(let ([v (v)])
|
|
||||||
(unless (number? v)
|
|
||||||
(raise-type-error who "number" v))
|
|
||||||
v))
|
|
||||||
|
|
||||||
(define (get-string who v)
|
|
||||||
(let ([v (v)])
|
|
||||||
(unless (string? v)
|
|
||||||
(raise-type-error who "string" v))
|
|
||||||
v))
|
|
||||||
|
|
||||||
(define (sign k v)
|
|
||||||
(k (let ([v (get-number 'sign v)])
|
|
||||||
(cond
|
|
||||||
[(< v 0) -1]
|
|
||||||
[(> v 0) 1]
|
|
||||||
[else 0]))))
|
|
||||||
|
|
||||||
(define (entier k v)
|
|
||||||
(k (inexact->exact (floor (get-number 'entier v)))))
|
|
||||||
|
|
||||||
(define (a60:abs k v)
|
|
||||||
(k (abs (get-number 'abs v))))
|
|
||||||
|
|
||||||
(define (a60:sqrt k v)
|
|
||||||
(k (sqrt (get-number 'sqrt v))))
|
|
||||||
|
|
||||||
(define (a60:sin k v)
|
|
||||||
(k (sin (get-number 'sin v))))
|
|
||||||
|
|
||||||
(define (a60:cos k v)
|
|
||||||
(k (cos (get-number 'cos v))))
|
|
||||||
|
|
||||||
(define (a60:exp k v)
|
|
||||||
(k (exp (get-number 'exp v))))
|
|
||||||
|
|
||||||
(define (a60:arctan k v)
|
|
||||||
(k (atan (get-number 'arctan v))))
|
|
||||||
|
|
||||||
(define (a60:ln k v)
|
|
||||||
(k (log (get-number 'ln v))))
|
|
||||||
|
|
||||||
(define (printsln k v)
|
|
||||||
(k (printf "~a\n" (get-string 'printsln v))))
|
|
||||||
|
|
||||||
(define (printnln k v)
|
|
||||||
(k (printf "~a\n" (get-number 'printnln v))))
|
|
||||||
|
|
||||||
(define (prints k v)
|
|
||||||
(k (printf "~a" (get-string 'prints v))))
|
|
||||||
|
|
||||||
(define (printn k v)
|
|
||||||
(k (printf "~a" (get-number 'printn v)))))
|
|
|
@ -1,108 +0,0 @@
|
||||||
(module runtime mzscheme
|
|
||||||
(require racket/undefined)
|
|
||||||
|
|
||||||
(provide (struct a60:array (vec dimens))
|
|
||||||
(struct a60:switch (choices))
|
|
||||||
undefined
|
|
||||||
check-boolean
|
|
||||||
goto
|
|
||||||
get-value
|
|
||||||
set-target!
|
|
||||||
make-array
|
|
||||||
array-ref
|
|
||||||
array-set!
|
|
||||||
make-switch
|
|
||||||
switch-ref
|
|
||||||
coerce)
|
|
||||||
|
|
||||||
(define-struct a60:array (vec dimens))
|
|
||||||
(define-struct a60:switch (choices))
|
|
||||||
|
|
||||||
(define (check-boolean b) b)
|
|
||||||
(define (goto f) (f))
|
|
||||||
(define (get-value v) (v))
|
|
||||||
(define (set-target! t name v)
|
|
||||||
(unless (procedure-arity-includes? t 1)
|
|
||||||
(error 'assignment "formal-argument variable ~a is assigned, but actual argument was not assignable"
|
|
||||||
name))
|
|
||||||
(t v))
|
|
||||||
|
|
||||||
(define (bad what v)
|
|
||||||
(error '|bad value| "expected a ~a, got ~e" what v))
|
|
||||||
(define (coerce type v)
|
|
||||||
(cond
|
|
||||||
[(eq? type 'integer)
|
|
||||||
(if (number? v)
|
|
||||||
(inexact->exact (floor v))
|
|
||||||
(bad 'number v))]
|
|
||||||
[(eq? type 'real)
|
|
||||||
(if (number? v)
|
|
||||||
(exact->inexact v)
|
|
||||||
(bad 'number v))]
|
|
||||||
[(eq? type 'boolean)
|
|
||||||
(if (boolean? v)
|
|
||||||
v
|
|
||||||
(bad 'boolean v))]
|
|
||||||
[else v]))
|
|
||||||
|
|
||||||
(define (make-array . dimens)
|
|
||||||
(make-a60:array
|
|
||||||
((let loop ([dimens dimens])
|
|
||||||
(if (null? dimens)
|
|
||||||
(lambda () undefined)
|
|
||||||
(let ([start (car dimens)]
|
|
||||||
[end (cadr dimens)])
|
|
||||||
(let ([build (loop (cddr dimens))])
|
|
||||||
(lambda ()
|
|
||||||
(let ([len (add1 (- end start))])
|
|
||||||
(let ([v (make-vector len)])
|
|
||||||
(let loop ([len len])
|
|
||||||
(unless (zero? len)
|
|
||||||
(vector-set! v (sub1 len) (build))
|
|
||||||
(loop (sub1 len))))
|
|
||||||
v))))))))
|
|
||||||
dimens))
|
|
||||||
|
|
||||||
(define (check-array a is who)
|
|
||||||
(unless (a60:array? a)
|
|
||||||
(error who "not an array: ~e" a))
|
|
||||||
(unless (= (length is) (/ (length (a60:array-dimens a)) 2))
|
|
||||||
(error who "array dimension ~a doesn't match the number of provided indices ~a"
|
|
||||||
(length is) (/ (length (a60:array-dimens a)) 2))))
|
|
||||||
|
|
||||||
(define (check-index who dimens indices)
|
|
||||||
(unless (and (number? (car indices))
|
|
||||||
(exact? (car indices))
|
|
||||||
(integer? (car indices)))
|
|
||||||
(error who "index is not an integer: ~e"
|
|
||||||
(car indices)))
|
|
||||||
(unless (<= (car dimens) (car indices) (cadr dimens))
|
|
||||||
(error who "index ~a out of range ~a:~a"
|
|
||||||
(car indices) (car dimens) (cadr dimens))))
|
|
||||||
|
|
||||||
(define (array-ref a . indices)
|
|
||||||
(check-array a indices 'array-reference)
|
|
||||||
(let loop ([v (a60:array-vec a)][indices indices][dimens (a60:array-dimens a)])
|
|
||||||
(check-index 'array-reference dimens indices)
|
|
||||||
(let ([i (vector-ref v (- (car indices) (car dimens)))])
|
|
||||||
(if (null? (cdr indices))
|
|
||||||
i
|
|
||||||
(loop i (cdr indices) (cddr dimens))))))
|
|
||||||
|
|
||||||
(define (array-set! a val . indices)
|
|
||||||
(check-array a indices 'array-assignment)
|
|
||||||
(let loop ([v (a60:array-vec a)][indices indices][dimens (a60:array-dimens a)])
|
|
||||||
(check-index 'array-assignment dimens indices)
|
|
||||||
(if (null? (cdr indices))
|
|
||||||
(vector-set! v (- (car indices) (car dimens)) val)
|
|
||||||
(loop (vector-ref v (- (car indices) (car dimens))) (cdr indices) (cddr dimens)))))
|
|
||||||
|
|
||||||
(define (make-switch . choices)
|
|
||||||
(make-a60:switch (list->vector choices)))
|
|
||||||
(define (switch-ref sw index)
|
|
||||||
(unless (and (number? index)
|
|
||||||
(integer? index)
|
|
||||||
(exact? index)
|
|
||||||
(<= 1 index (vector-length (a60:switch-choices sw))))
|
|
||||||
(error "bad switch index: " index))
|
|
||||||
((vector-ref (a60:switch-choices sw) (sub1 index)))))
|
|
|
@ -1,169 +0,0 @@
|
||||||
#cs(module simplify mzscheme
|
|
||||||
(require "parse.rkt"
|
|
||||||
"prims.rkt"
|
|
||||||
mzlib/match)
|
|
||||||
|
|
||||||
(provide simplify)
|
|
||||||
|
|
||||||
;; flatten/label-block : list-of-decl list-of-stmt -> block-stmt
|
|
||||||
;; Desugars `for', converts `if' so that it's always of the form
|
|
||||||
;; `if <test> then goto <label> else goto <label>', flattens
|
|
||||||
;; compound statements into the enclosing block, and gives every
|
|
||||||
;; statement exactly one label. The result usually has lots of
|
|
||||||
;; "dummy" statements that could easily be eliminated by merging
|
|
||||||
;; labels.
|
|
||||||
(define (flatten/label-block decls statements ->stx)
|
|
||||||
(define extra-decls null)
|
|
||||||
(define new-statements
|
|
||||||
(let loop ([l statements])
|
|
||||||
(if (null? l)
|
|
||||||
null
|
|
||||||
(match (car l)
|
|
||||||
[($ a60:block decls statements)
|
|
||||||
(cons (cons (gensym 'block) (flatten/label-block decls statements ->stx))
|
|
||||||
(loop (cdr l)))]
|
|
||||||
[($ a60:compound statements)
|
|
||||||
(loop (append statements (cdr l)))]
|
|
||||||
[($ a60:branch test then else)
|
|
||||||
(if (and (a60:goto? then) (a60:goto? else))
|
|
||||||
(cons (cons (gensym 'branch) (car l))
|
|
||||||
(loop (cdr l)))
|
|
||||||
(let ([then-label (gensym 'then)]
|
|
||||||
[else-label (gensym 'else)]
|
|
||||||
[cont-label (gensym 'if-cont)])
|
|
||||||
(loop
|
|
||||||
(list*
|
|
||||||
(make-a60:branch test (make-a60:goto then-label) (make-a60:goto else-label))
|
|
||||||
(make-a60:label then-label then)
|
|
||||||
(make-a60:goto cont-label)
|
|
||||||
(make-a60:label else-label else)
|
|
||||||
(make-a60:label cont-label (make-a60:dummy))
|
|
||||||
(cdr l)))))]
|
|
||||||
[($ a60:for variable val-exprs body)
|
|
||||||
(let ([body-label (gensym 'for-body)]
|
|
||||||
[cont-label (gensym 'for-cont)])
|
|
||||||
(letrec ([make-init+test+increment+loop
|
|
||||||
(lambda (value)
|
|
||||||
(match value
|
|
||||||
[($ a60:for-number value)
|
|
||||||
(values (make-a60:assign (list variable) (make-a60:binary 'num 'num
|
|
||||||
(->stx '+)
|
|
||||||
(->stx '0)
|
|
||||||
value)) ; +0 => number
|
|
||||||
(->stx #t)
|
|
||||||
(make-a60:dummy)
|
|
||||||
#f)]
|
|
||||||
[($ a60:for-step start step end)
|
|
||||||
(values (make-a60:assign (list variable) start)
|
|
||||||
(make-a60:binary 'bool 'num
|
|
||||||
(->stx '<=)
|
|
||||||
(make-a60:binary 'num 'num
|
|
||||||
(->stx '*)
|
|
||||||
(make-a60:binary 'num 'num (->stx '-) variable end)
|
|
||||||
(make-a60:app (->stx 'sign) (list step)))
|
|
||||||
(->stx '0))
|
|
||||||
(make-a60:assign (list variable) (make-a60:binary 'num 'num (->stx '+) variable step))
|
|
||||||
#t)]
|
|
||||||
[($ a60:for-while value test)
|
|
||||||
(values (make-a60:assign (list variable) value)
|
|
||||||
test
|
|
||||||
(make-a60:assign (list variable) value)
|
|
||||||
#t)]))])
|
|
||||||
(if (= 1 (length val-exprs))
|
|
||||||
(let-values ([(init test inc loop?) (make-init+test+increment+loop (car val-exprs))])
|
|
||||||
(loop (list*
|
|
||||||
init
|
|
||||||
(make-a60:label body-label (make-a60:dummy))
|
|
||||||
(make-a60:branch test
|
|
||||||
(make-a60:compound
|
|
||||||
(list
|
|
||||||
body
|
|
||||||
inc
|
|
||||||
(if loop?
|
|
||||||
(make-a60:goto body-label)
|
|
||||||
(make-a60:dummy))))
|
|
||||||
(make-a60:dummy))
|
|
||||||
(cdr l))))
|
|
||||||
(let* ([stage-name (datum->syntax-object #f (gensym 'stage-number))]
|
|
||||||
[switch-name (datum->syntax-object #f (gensym 'stage-switch))]
|
|
||||||
[end-switch-name (datum->syntax-object #f (gensym 'stage-switch))]
|
|
||||||
[stage-var (make-a60:variable stage-name null)]
|
|
||||||
[start-labels (map (lambda (x) (gensym 'stage)) (append val-exprs (list 'extra)))]
|
|
||||||
[end-labels (map (lambda (x) (gensym 'stage)) val-exprs)])
|
|
||||||
(set! extra-decls (list* stage-name
|
|
||||||
(cons switch-name start-labels)
|
|
||||||
(cons end-switch-name end-labels)
|
|
||||||
extra-decls))
|
|
||||||
(loop
|
|
||||||
(append
|
|
||||||
(list (make-a60:assign (list stage-var) (->stx '0)))
|
|
||||||
(let loop ([start-labels start-labels][end-labels end-labels][val-exprs val-exprs])
|
|
||||||
(if (null? val-exprs)
|
|
||||||
(list (make-a60:label (car start-labels) (make-a60:dummy)))
|
|
||||||
(let-values ([(init test inc loop?) (make-init+test+increment+loop (car val-exprs))])
|
|
||||||
(list*
|
|
||||||
(make-a60:label (car start-labels) (make-a60:dummy))
|
|
||||||
init
|
|
||||||
(make-a60:branch test
|
|
||||||
(make-a60:goto body-label)
|
|
||||||
(make-a60:compound
|
|
||||||
(list
|
|
||||||
(make-a60:assign (list stage-var) (make-a60:binary 'num 'num
|
|
||||||
(->stx '+)
|
|
||||||
(->stx '1)
|
|
||||||
stage-var))
|
|
||||||
(make-a60:goto (make-a60:subscript switch-name stage-var)))))
|
|
||||||
(make-a60:label (car end-labels) (make-a60:dummy))
|
|
||||||
inc
|
|
||||||
(if loop?
|
|
||||||
(make-a60:goto (car start-labels))
|
|
||||||
(make-a60:goto (cadr start-labels)))
|
|
||||||
(loop (cdr start-labels)
|
|
||||||
(cdr end-labels)
|
|
||||||
(cdr val-exprs))))))
|
|
||||||
(list
|
|
||||||
(make-a60:goto cont-label)
|
|
||||||
(make-a60:label body-label (make-a60:dummy))
|
|
||||||
body
|
|
||||||
(make-a60:goto (make-a60:subscript end-switch-name stage-var))
|
|
||||||
(make-a60:label cont-label (make-a60:dummy)))
|
|
||||||
(cdr l)))))))]
|
|
||||||
[($ a60:label name statement)
|
|
||||||
(cons (cons name (make-a60:dummy))
|
|
||||||
(loop (cons statement (cdr l))))]
|
|
||||||
[else
|
|
||||||
(cons (cons (gensym 'other) (car l))
|
|
||||||
(loop (cdr l)))]))))
|
|
||||||
(make-a60:block
|
|
||||||
(append
|
|
||||||
(map (lambda (decl)
|
|
||||||
(match decl
|
|
||||||
[($ a60:proc-decl result-type var arg-vars by-value-vars arg-specs body)
|
|
||||||
(make-a60:proc-decl result-type var arg-vars by-value-vars arg-specs
|
|
||||||
(simplify-statement body ->stx))]
|
|
||||||
[else decl]))
|
|
||||||
decls)
|
|
||||||
(map (lambda (extra)
|
|
||||||
(if (identifier? extra)
|
|
||||||
(make-a60:type-decl (->stx 'integer) (list extra))
|
|
||||||
(make-a60:switch-decl
|
|
||||||
(car extra)
|
|
||||||
(map (lambda (x)
|
|
||||||
(make-a60:variable (datum->syntax-object #f x)
|
|
||||||
null))
|
|
||||||
(cdr extra)))))
|
|
||||||
extra-decls))
|
|
||||||
(if (null? new-statements)
|
|
||||||
(list (cons (gensym 'other) (make-a60:dummy)))
|
|
||||||
new-statements)))
|
|
||||||
|
|
||||||
(define (simplify stmt ctx)
|
|
||||||
(simplify-statement stmt (lambda (x) (datum->syntax-object ctx x))))
|
|
||||||
|
|
||||||
(define (simplify-statement stmt ->stx)
|
|
||||||
(match stmt
|
|
||||||
[($ a60:block decls statements)
|
|
||||||
(flatten/label-block decls statements ->stx)]
|
|
||||||
[($ a60:compound statements)
|
|
||||||
(flatten/label-block null statements ->stx)]
|
|
||||||
[else stmt])))
|
|
|
@ -1,61 +0,0 @@
|
||||||
#lang at-exp racket/base
|
|
||||||
(require algol60/algol60
|
|
||||||
rackunit
|
|
||||||
(for-syntax racket/base))
|
|
||||||
|
|
||||||
(define-syntax (capture-output stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ exp)
|
|
||||||
(with-handlers ((exn:fail?
|
|
||||||
(λ (exn)
|
|
||||||
#`(list 'expand
|
|
||||||
#,(exn-message exn)))))
|
|
||||||
(define expanded (local-expand #'exp 'expression #f))
|
|
||||||
#`(let ([op (open-output-string)]
|
|
||||||
[ep (open-output-string)])
|
|
||||||
(let/ec k
|
|
||||||
(parameterize ([current-output-port op]
|
|
||||||
[current-error-port ep]
|
|
||||||
[error-escape-handler (λ () (k (void)))])
|
|
||||||
#,expanded))
|
|
||||||
(list 'run
|
|
||||||
(get-output-string op)
|
|
||||||
(get-output-string ep))))]))
|
|
||||||
|
|
||||||
(check-equal?
|
|
||||||
(capture-output
|
|
||||||
@literal-algol{
|
|
||||||
begin
|
|
||||||
printsln (`hello world')
|
|
||||||
end
|
|
||||||
})
|
|
||||||
'(run "hello world\n" ""))
|
|
||||||
|
|
||||||
(check-pred
|
|
||||||
(λ (x) (and (eq? (list-ref x 0) 'expand)
|
|
||||||
(regexp-match #rx"parse error near BEGIN"
|
|
||||||
(list-ref x 1))))
|
|
||||||
(capture-output
|
|
||||||
@literal-algol{
|
|
||||||
begin
|
|
||||||
}))
|
|
||||||
|
|
||||||
|
|
||||||
(check-pred
|
|
||||||
(λ (x) (and (eq? (list-ref x 0) 'expand)
|
|
||||||
(regexp-match #rx"parse error near PROCEDURE"
|
|
||||||
(list-ref x 1))))
|
|
||||||
(capture-output
|
|
||||||
@literal-algol{
|
|
||||||
procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);
|
|
||||||
value n, m; array a; integer n, m, i, k; real y;
|
|
||||||
begin integer p, q;
|
|
||||||
y := 0; i := k := 1;
|
|
||||||
for p:=1 step 1 until n do
|
|
||||||
for q:=1 step 1 until m do
|
|
||||||
if abs(a[p, q]) > y then
|
|
||||||
begin y := abs(a[p, q]);
|
|
||||||
i := p; k := q
|
|
||||||
end
|
|
||||||
end Absmax
|
|
||||||
}))
|
|
|
@ -1,123 +0,0 @@
|
||||||
(module tool mzscheme
|
|
||||||
(require drscheme/tool
|
|
||||||
mred
|
|
||||||
mzlib/unit
|
|
||||||
mzlib/class
|
|
||||||
"parse.rkt"
|
|
||||||
"simplify.rkt"
|
|
||||||
"compile.rkt"
|
|
||||||
compiler/embed
|
|
||||||
string-constants
|
|
||||||
errortrace/errortrace-lib
|
|
||||||
(prefix bd: "bd-tool.rkt"))
|
|
||||||
|
|
||||||
(provide tool@)
|
|
||||||
|
|
||||||
(define base-importing-stx (dynamic-require 'algol60/base
|
|
||||||
'base-importing-stx))
|
|
||||||
|
|
||||||
(define tool@
|
|
||||||
(unit
|
|
||||||
(import drscheme:tool^)
|
|
||||||
(export drscheme:tool-exports^)
|
|
||||||
|
|
||||||
(define-values/invoke-unit bd:tool@
|
|
||||||
(import drscheme:tool^)
|
|
||||||
(export (prefix bd: drscheme:tool-exports^)))
|
|
||||||
|
|
||||||
(define (phase1) (bd:phase1))
|
|
||||||
(define (phase2)
|
|
||||||
(bd:phase2)
|
|
||||||
(drscheme:language-configuration:add-language
|
|
||||||
(make-object (override-mrflow-methods
|
|
||||||
((drscheme:language:get-default-mixin)
|
|
||||||
lang%)))))
|
|
||||||
|
|
||||||
(define (override-mrflow-methods %)
|
|
||||||
(if (method-in-interface? 'render-value-set (class->interface %))
|
|
||||||
(class %
|
|
||||||
(inherit [super-render-value-set render-value-set]
|
|
||||||
[super-get-mrflow-primitives-filename get-mrflow-primitives-filename])
|
|
||||||
(define/override (render-value-set . x)
|
|
||||||
;; needs to be filled in!
|
|
||||||
(super-render-value-set . x))
|
|
||||||
(define/override (get-mrflow-primitives-filename)
|
|
||||||
(build-path (collection-path "mrflow")
|
|
||||||
"primitives"
|
|
||||||
"algol60.rkt"))
|
|
||||||
(super-instantiate ()))
|
|
||||||
%))
|
|
||||||
|
|
||||||
(define lang%
|
|
||||||
(class* object% (drscheme:language:language<%>)
|
|
||||||
(define/public (front-end/finished-complete-program settings) (void))
|
|
||||||
(define/public (extra-repl-information settings port) (void))
|
|
||||||
(define/public (get-reader-module) #f)
|
|
||||||
(define/public (get-metadata a b) #f)
|
|
||||||
(define/public (metadata->settings m) #f)
|
|
||||||
(define/public (get-metadata-lines) #f)
|
|
||||||
|
|
||||||
(define/public (capability-value s) (drscheme:language:get-capability-default s))
|
|
||||||
(define/public (first-opened) (void))
|
|
||||||
(define/public (config-panel parent)
|
|
||||||
(case-lambda
|
|
||||||
[() null]
|
|
||||||
[(x) (void)]))
|
|
||||||
(define/public (get-comment-character) (values "'COMMENT'" #\*))
|
|
||||||
(define/public (default-settings) null)
|
|
||||||
(define/public (default-settings? x) #t)
|
|
||||||
(define/private (front-end port settings)
|
|
||||||
(let ([name (object-name port)])
|
|
||||||
(lambda ()
|
|
||||||
(if (eof-object? (peek-char port))
|
|
||||||
eof
|
|
||||||
(compile-simplified
|
|
||||||
(simplify (parse-a60-port port name) base-importing-stx)
|
|
||||||
base-importing-stx)))))
|
|
||||||
(define/public (front-end/complete-program port settings) (front-end port settings))
|
|
||||||
(define/public (front-end/interaction port settings) (front-end port settings))
|
|
||||||
(define/public (get-style-delta) #f)
|
|
||||||
(define/public (get-language-position)
|
|
||||||
(list (string-constant experimental-languages)
|
|
||||||
"Algol 60"))
|
|
||||||
(define/public (get-language-name) "Algol 60")
|
|
||||||
(define/public (get-language-url) #f)
|
|
||||||
(define/public (get-language-numbers) (list 1000 10))
|
|
||||||
(define/public (get-teachpack-names) null)
|
|
||||||
(define/public (marshall-settings x) x)
|
|
||||||
(define/public (on-execute settings run-in-user-thread)
|
|
||||||
(dynamic-require 'algol60/base #f)
|
|
||||||
(let ([path ((current-module-name-resolver) 'algol60/base #f #f #t)]
|
|
||||||
[n (current-namespace)])
|
|
||||||
(run-in-user-thread
|
|
||||||
(lambda ()
|
|
||||||
(error-display-handler
|
|
||||||
(drscheme:debug:make-debug-error-display-handler (error-display-handler)))
|
|
||||||
(current-compile (make-errortrace-compile-handler))
|
|
||||||
(with-handlers ([void (lambda (x)
|
|
||||||
(printf "~a\n"
|
|
||||||
(exn-message x)))])
|
|
||||||
(namespace-attach-module n path)
|
|
||||||
(namespace-require path))))))
|
|
||||||
(define/public (render-value value settings port) (write value port))
|
|
||||||
(define/public (render-value/format value settings port width) (write value port))
|
|
||||||
(define/public (unmarshall-settings x) x)
|
|
||||||
(define/public (create-executable settings parent src-file)
|
|
||||||
(let ([dst-file (drscheme:language:put-executable
|
|
||||||
parent src-file #f #f
|
|
||||||
(string-constant save-a-mzscheme-stand-alone-executable))])
|
|
||||||
(when dst-file
|
|
||||||
(let ([code (compile-simplified (simplify (parse-a60-file src-file)
|
|
||||||
base-importing-stx)
|
|
||||||
base-importing-stx)])
|
|
||||||
(make-embedding-executable dst-file
|
|
||||||
#f #f
|
|
||||||
'((#f algol60/base))
|
|
||||||
null
|
|
||||||
(compile
|
|
||||||
`(module m algol60/base
|
|
||||||
,code))
|
|
||||||
(list "-mvqe" "(require m)"))))))
|
|
||||||
(define/public (get-one-line-summary) "Of historic interest")
|
|
||||||
|
|
||||||
(super-instantiate ()))))))
|
|
|
@ -1,306 +0,0 @@
|
||||||
#lang scheme/base
|
|
||||||
|
|
||||||
(module test racket/base)
|
|
||||||
|
|
||||||
;; On error, exit with 1 status code
|
|
||||||
(error-escape-handler (lambda () (exit 1)))
|
|
||||||
|
|
||||||
(error-print-width 512)
|
|
||||||
|
|
||||||
(require (prefix-in compiler:option: compiler/option)
|
|
||||||
compiler/compiler
|
|
||||||
raco/command-name
|
|
||||||
racket/cmdline
|
|
||||||
dynext/file
|
|
||||||
dynext/compile
|
|
||||||
dynext/link
|
|
||||||
scheme/pretty
|
|
||||||
setup/pack
|
|
||||||
setup/getinfo
|
|
||||||
setup/dirs)
|
|
||||||
|
|
||||||
(define dest-dir (make-parameter #f))
|
|
||||||
|
|
||||||
(define ld-output (make-parameter #f))
|
|
||||||
|
|
||||||
(define exe-output (make-parameter #f))
|
|
||||||
(define exe-embedded-flags (make-parameter '("-U" "--")))
|
|
||||||
(define exe-embedded-libraries (make-parameter null))
|
|
||||||
(define exe-aux (make-parameter null))
|
|
||||||
(define exe-embedded-collects-path (make-parameter #f))
|
|
||||||
(define exe-embedded-collects-dest (make-parameter #f))
|
|
||||||
(define exe-dir-add-collects-dirs (make-parameter null))
|
|
||||||
|
|
||||||
(define exe-dir-output (make-parameter #f))
|
|
||||||
|
|
||||||
(define mods-output (make-parameter #f))
|
|
||||||
|
|
||||||
(define default-plt-name "archive")
|
|
||||||
|
|
||||||
(define disable-inlining (make-parameter #f))
|
|
||||||
|
|
||||||
(define plt-output (make-parameter #f))
|
|
||||||
(define plt-name (make-parameter default-plt-name))
|
|
||||||
(define plt-files-replace (make-parameter #f))
|
|
||||||
(define plt-files-plt-relative? (make-parameter #f))
|
|
||||||
(define plt-files-plt-home-relative? (make-parameter #f))
|
|
||||||
(define plt-force-install-dir? (make-parameter #f))
|
|
||||||
(define plt-setup-collections (make-parameter null))
|
|
||||||
(define plt-include-compiled (make-parameter #f))
|
|
||||||
|
|
||||||
(define stop-at-source (make-parameter #f))
|
|
||||||
|
|
||||||
(define (extract-suffix appender)
|
|
||||||
(bytes->string/latin-1
|
|
||||||
(subbytes (path->bytes (appender (bytes->path #"x"))) 1)))
|
|
||||||
|
|
||||||
(define ((add-to-param param) f v) (param (append (param) (list v))))
|
|
||||||
|
|
||||||
(define mzc-symbol (string->symbol (short-program+command-name)))
|
|
||||||
|
|
||||||
;; Returns (values mode files prefixes)
|
|
||||||
;; where mode is 'compile, 'make-zo, etc.
|
|
||||||
(define-values (mode source-files prefix)
|
|
||||||
(parse-command-line
|
|
||||||
(short-program+command-name)
|
|
||||||
(current-command-line-arguments)
|
|
||||||
`([help-labels
|
|
||||||
"-------------------------------- mode flags ---------------------------------"]
|
|
||||||
[once-any
|
|
||||||
[("--cc")
|
|
||||||
,(lambda (f) 'cc)
|
|
||||||
(,(format "Compile arbitrary file(s) for an extension: ~a -> ~a"
|
|
||||||
(extract-suffix append-c-suffix)
|
|
||||||
(extract-suffix append-object-suffix)))]
|
|
||||||
[("--ld")
|
|
||||||
,(lambda (f name) (ld-output name) 'ld)
|
|
||||||
(,(format "Link arbitrary file(s) to create <extension>: ~a -> ~a"
|
|
||||||
(extract-suffix append-object-suffix)
|
|
||||||
(extract-suffix append-extension-suffix))
|
|
||||||
"extension")]
|
|
||||||
[("-x" "--xform")
|
|
||||||
,(lambda (f) 'xform)
|
|
||||||
((,(format "Convert for 3m compilation: ~a -> ~a"
|
|
||||||
(extract-suffix append-c-suffix)
|
|
||||||
(extract-suffix append-c-suffix))
|
|
||||||
""))]
|
|
||||||
[("--c-mods")
|
|
||||||
,(lambda (f name) (mods-output name) 'c-mods)
|
|
||||||
((,(format "Write C-embeddable module bytecode to <file>") "")
|
|
||||||
"file")]]
|
|
||||||
[help-labels ""]
|
|
||||||
[once-any
|
|
||||||
[("--3m")
|
|
||||||
,(lambda (f) (compiler:option:3m #t))
|
|
||||||
(,(format "Compile/link for 3m~a"
|
|
||||||
(if (eq? '3m (system-type 'gc)) " [current default]" "")))]
|
|
||||||
[("--cgc")
|
|
||||||
,(lambda (f) (compiler:option:3m #f))
|
|
||||||
(,(format "Compile/link for CGC~a"
|
|
||||||
(if (eq? 'cgc (system-type 'gc)) " [current default]" "")))]]
|
|
||||||
[once-each
|
|
||||||
[("-n" "--name")
|
|
||||||
,(lambda (f name) (compiler:option:setup-prefix name))
|
|
||||||
("Use <name> as extra part of public low-level names" "name")]]
|
|
||||||
[once-any
|
|
||||||
[("-d" "--destination")
|
|
||||||
,(lambda (f d)
|
|
||||||
(unless (directory-exists? d)
|
|
||||||
(error mzc-symbol "the destination directory does not exist: ~s" d))
|
|
||||||
(dest-dir d))
|
|
||||||
("Output --cc/--ld/-x file(s) to <dir>" "dir")]]
|
|
||||||
[help-labels
|
|
||||||
"------------------- compiler/linker configuration flags ---------------------"]
|
|
||||||
[once-each
|
|
||||||
[("--tool")
|
|
||||||
,(lambda (f v)
|
|
||||||
(let ([v (string->symbol v)])
|
|
||||||
(use-standard-compiler v)
|
|
||||||
(use-standard-linker v)))
|
|
||||||
(,(format "Use pre-defined <tool> as C compiler/linker:~a"
|
|
||||||
(apply string-append
|
|
||||||
(apply append (map (lambda (t)
|
|
||||||
(list " " (symbol->string t)))
|
|
||||||
(get-standard-compilers)))))
|
|
||||||
"tool")]
|
|
||||||
[("--compiler")
|
|
||||||
,(lambda (f v) (current-extension-compiler v))
|
|
||||||
("Use <compiler-path> as C compiler" "compiler-path")]]
|
|
||||||
[multi
|
|
||||||
[("++ccf")
|
|
||||||
,(add-to-param current-extension-compiler-flags)
|
|
||||||
("Add C compiler flag" "flag")]
|
|
||||||
[("--ccf")
|
|
||||||
,(lambda (f v)
|
|
||||||
(current-extension-compiler-flags
|
|
||||||
(remove v (current-extension-compiler-flags))))
|
|
||||||
("Remove C compiler flag" "flag")]
|
|
||||||
[("--ccf-clear")
|
|
||||||
,(lambda (f) (current-extension-compiler-flags null))
|
|
||||||
("Clear C compiler flags")]
|
|
||||||
[("--ccf-show")
|
|
||||||
,(lambda (f)
|
|
||||||
(printf "C compiler flags: ~s\n"
|
|
||||||
(expand-for-link-variant (current-extension-compiler-flags))))
|
|
||||||
("Show C compiler flags")]]
|
|
||||||
[once-each
|
|
||||||
[("--linker")
|
|
||||||
,(lambda (f v) (current-extension-linker v))
|
|
||||||
("Use <linker-path> as C linker" "linker-path")]]
|
|
||||||
[multi
|
|
||||||
[("++ldf")
|
|
||||||
,(add-to-param current-extension-linker-flags)
|
|
||||||
("Add C linker flag" "flag")]
|
|
||||||
[("--ldf")
|
|
||||||
,(lambda (f v)
|
|
||||||
(current-extension-linker-flags
|
|
||||||
(remove v (current-extension-linker-flags))))
|
|
||||||
("Remove C linker flag" "flag")]
|
|
||||||
[("--ldf-clear")
|
|
||||||
,(lambda (f) (current-extension-linker-flags null))
|
|
||||||
("Clear C linker flags")]
|
|
||||||
[("--ldf-show")
|
|
||||||
,(lambda (f)
|
|
||||||
(printf "C linker flags: ~s\n"
|
|
||||||
(expand-for-link-variant (current-extension-linker-flags))))
|
|
||||||
("Show C linker flags")]
|
|
||||||
[("++ldl")
|
|
||||||
,(add-to-param current-standard-link-libraries)
|
|
||||||
("Add C linker library" "lib")]
|
|
||||||
[("--ldl-show")
|
|
||||||
,(lambda (f)
|
|
||||||
(printf "C linker libraries: ~s\n"
|
|
||||||
(expand-for-link-variant (current-standard-link-libraries))))
|
|
||||||
("Show C linker libraries")]]
|
|
||||||
[multi
|
|
||||||
[("++cppf")
|
|
||||||
,(add-to-param current-extension-preprocess-flags)
|
|
||||||
("Add C preprocess (xform) flag" "flag")]
|
|
||||||
[("--cppf")
|
|
||||||
,(lambda (f v)
|
|
||||||
(current-extension-preprocess-flags
|
|
||||||
(remove v (current-extension-preprocess-flags))))
|
|
||||||
("Remove C preprocess (xform) flag" "flag")]
|
|
||||||
[("--cppf-clear")
|
|
||||||
,(lambda (f) (current-extension-preprocess-flags null))
|
|
||||||
("Clear C preprocess (xform) flags")]
|
|
||||||
[("--cppf-show")
|
|
||||||
,(lambda (f)
|
|
||||||
(printf "C compiler flags: ~s\n"
|
|
||||||
(expand-for-link-variant (current-extension-preprocess-flags))))
|
|
||||||
("Show C preprocess (xform) flags")]]
|
|
||||||
[help-labels
|
|
||||||
"----------------------- C-embeddable module flags ---------------------------"]
|
|
||||||
[multi
|
|
||||||
[("++lib")
|
|
||||||
,(lambda (f l)
|
|
||||||
(exe-embedded-libraries (append (exe-embedded-libraries) (list l))))
|
|
||||||
("Embed <lib> in --c-mods output" "lib")]]
|
|
||||||
[help-labels
|
|
||||||
"-------------------------- miscellaneous flags ------------------------------"]
|
|
||||||
[once-each
|
|
||||||
[("-v")
|
|
||||||
,(lambda (f) (compiler:option:somewhat-verbose #t))
|
|
||||||
("Slightly verbose mode, including version banner and output files")]
|
|
||||||
[("--vv")
|
|
||||||
,(lambda (f) (compiler:option:somewhat-verbose #t) (compiler:option:verbose #t))
|
|
||||||
("Very verbose mode")]])
|
|
||||||
(lambda (accum . files)
|
|
||||||
(let ([mode (let ([l (filter symbol? accum)])
|
|
||||||
(if (null? l)
|
|
||||||
(error mzc-symbol "no mode flag specified")
|
|
||||||
(car l)))])
|
|
||||||
(values
|
|
||||||
mode
|
|
||||||
files
|
|
||||||
#f)))
|
|
||||||
(list "file")))
|
|
||||||
|
|
||||||
(when (compiler:option:somewhat-verbose)
|
|
||||||
(printf "~a v~a [~a], Copyright (c) 2004-2014 PLT Design Inc.\n"
|
|
||||||
(short-program+command-name)
|
|
||||||
(version)
|
|
||||||
(system-type 'gc)))
|
|
||||||
|
|
||||||
(if (compiler:option:3m)
|
|
||||||
(begin (link-variant '3m) (compile-variant '3m))
|
|
||||||
(begin (link-variant 'cgc) (compile-variant 'cgc)))
|
|
||||||
|
|
||||||
(define (compiler-warning)
|
|
||||||
(eprintf "Warning: ~a\n ~a\n"
|
|
||||||
"compilation to C is usually less effective for performance"
|
|
||||||
"than relying on the bytecode just-in-time compiler."))
|
|
||||||
|
|
||||||
(case mode
|
|
||||||
[(cc)
|
|
||||||
(for ([file source-files])
|
|
||||||
(let* ([base (extract-base-filename/c file mzc-symbol)]
|
|
||||||
[dest (append-object-suffix
|
|
||||||
(let-values ([(base name dir?) (split-path base)])
|
|
||||||
(build-path (or (dest-dir) 'same) name)))])
|
|
||||||
(when (compiler:option:somewhat-verbose)
|
|
||||||
(printf "\"~a\":\n" file))
|
|
||||||
(compile-extension (not (compiler:option:verbose)) file dest null)
|
|
||||||
(when (compiler:option:somewhat-verbose)
|
|
||||||
(printf " [output to \"~a\"]\n" dest))))]
|
|
||||||
[(ld)
|
|
||||||
(extract-base-filename/ext (ld-output) mzc-symbol)
|
|
||||||
;; (for ([file source-files]) (extract-base-filename/o file mzc-symbol))
|
|
||||||
(let ([dest (if (dest-dir)
|
|
||||||
(build-path (dest-dir) (ld-output))
|
|
||||||
(ld-output))])
|
|
||||||
(when (compiler:option:somewhat-verbose)
|
|
||||||
(printf "~a:\n" (let ([s (apply string-append
|
|
||||||
(map (lambda (n) (format " \"~a\"" n))
|
|
||||||
source-files))])
|
|
||||||
(substring s 1 (string-length s)))))
|
|
||||||
(link-extension (not (compiler:option:verbose))
|
|
||||||
source-files
|
|
||||||
dest)
|
|
||||||
(when (compiler:option:somewhat-verbose)
|
|
||||||
(printf " [output to \"~a\"]\n" dest)))]
|
|
||||||
[(xform)
|
|
||||||
(for ([file source-files])
|
|
||||||
(let* ([out-file (path-replace-suffix file ".3m.c")]
|
|
||||||
[out-file (if (dest-dir)
|
|
||||||
(build-path (dest-dir) out-file)
|
|
||||||
out-file)])
|
|
||||||
((dynamic-require 'compiler/xform 'xform)
|
|
||||||
(not (compiler:option:verbose))
|
|
||||||
file
|
|
||||||
out-file
|
|
||||||
(list (find-include-dir)))
|
|
||||||
(when (compiler:option:somewhat-verbose)
|
|
||||||
(printf " [output to \"~a\"]\n" out-file))))]
|
|
||||||
[(c-mods)
|
|
||||||
(let ([dest (mods-output)])
|
|
||||||
(let-values ([(in out) (make-pipe)])
|
|
||||||
(parameterize ([current-output-port out])
|
|
||||||
((dynamic-require 'compiler/embed 'write-module-bundle)
|
|
||||||
#:modules
|
|
||||||
(append (map (lambda (l) `(#f (file ,l))) source-files)
|
|
||||||
(map (lambda (l) `(#t (lib ,l))) (exe-embedded-libraries)))))
|
|
||||||
(close-output-port out)
|
|
||||||
(let ([out (open-output-file dest #:exists 'truncate/replace)])
|
|
||||||
(fprintf out "#ifdef MZ_XFORM\n")
|
|
||||||
(fprintf out "XFORM_START_SKIP;\n")
|
|
||||||
(fprintf out "#endif\n")
|
|
||||||
(fprintf out "static void declare_modules(Scheme_Env *env) {\n")
|
|
||||||
(fprintf out " static unsigned char data[] = {")
|
|
||||||
(let loop ([pos 0])
|
|
||||||
(let ([b (read-byte in)])
|
|
||||||
(when (zero? (modulo pos 20)) (fprintf out "\n "))
|
|
||||||
(unless (eof-object? b) (fprintf out "~a," b) (loop (add1 pos)))))
|
|
||||||
(fprintf out "0\n };\n")
|
|
||||||
(fprintf out " scheme_register_embedded_load(~a, (const char *)data);\n"
|
|
||||||
(file-position in))
|
|
||||||
(fprintf out " scheme_embedded_load(~a, (const char *)data, 1);\n"
|
|
||||||
(file-position in))
|
|
||||||
(fprintf out "}\n")
|
|
||||||
(fprintf out "#ifdef MZ_XFORM\n")
|
|
||||||
(fprintf out "XFORM_END_SKIP;\n")
|
|
||||||
(fprintf out "#endif\n")
|
|
||||||
(close-output-port out)))
|
|
||||||
(when (compiler:option:somewhat-verbose)
|
|
||||||
(printf " [output to \"~a\"]\n" dest)))]
|
|
||||||
[else (printf "bad mode: ~a\n" mode)])
|
|
|
@ -1,4 +0,0 @@
|
||||||
#lang info
|
|
||||||
|
|
||||||
(define raco-commands
|
|
||||||
'(("ctool" compiler/commands/ctool "compile and link C-based extensions" #f)))
|
|
|
@ -1,28 +0,0 @@
|
||||||
#lang scheme/base
|
|
||||||
|
|
||||||
(require dynext/compile
|
|
||||||
setup/dirs
|
|
||||||
(prefix-in xform: compiler/private/xform))
|
|
||||||
|
|
||||||
(provide xform)
|
|
||||||
|
|
||||||
(define (xform quiet? src dest header-dirs #:keep-lines? [keep-lines? #f])
|
|
||||||
(let ([exe (current-extension-compiler)]
|
|
||||||
[flags (expand-for-compile-variant
|
|
||||||
(current-extension-preprocess-flags))]
|
|
||||||
[headers (apply append
|
|
||||||
(map (current-make-compile-include-strings)
|
|
||||||
(append
|
|
||||||
header-dirs
|
|
||||||
(list (find-include-dir)))))])
|
|
||||||
(xform:xform quiet?
|
|
||||||
(cons exe
|
|
||||||
(append flags headers))
|
|
||||||
src
|
|
||||||
dest
|
|
||||||
keep-lines?
|
|
||||||
#f #t #t
|
|
||||||
#f #f
|
|
||||||
#f #f
|
|
||||||
#f)))
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require racket/unit)
|
|
||||||
|
|
||||||
(provide dynext:compile^)
|
|
||||||
|
|
||||||
(define-signature dynext:compile^
|
|
||||||
(compile-extension
|
|
||||||
preprocess-extension
|
|
||||||
current-extension-compiler
|
|
||||||
current-extension-compiler-flags
|
|
||||||
current-extension-preprocess-flags
|
|
||||||
current-make-compile-include-strings
|
|
||||||
current-make-compile-input-strings
|
|
||||||
current-make-compile-output-strings
|
|
||||||
use-standard-compiler
|
|
||||||
get-standard-compilers
|
|
||||||
compile-variant
|
|
||||||
expand-for-compile-variant))
|
|
||||||
|
|
|
@ -1,300 +0,0 @@
|
||||||
(module compile-unit racket/base
|
|
||||||
(require racket/unit
|
|
||||||
racket/system
|
|
||||||
"private/dirs.rkt"
|
|
||||||
"private/stdio.rkt"
|
|
||||||
"private/cmdargs.rkt")
|
|
||||||
|
|
||||||
(require "compile-sig.rkt")
|
|
||||||
|
|
||||||
(provide dynext:compile@)
|
|
||||||
|
|
||||||
(define-unit dynext:compile@
|
|
||||||
(import)
|
|
||||||
(export dynext:compile^)
|
|
||||||
|
|
||||||
(define (get-unix-compile)
|
|
||||||
(or (find-executable-path "gcc" #f)
|
|
||||||
(find-executable-path "cc" #f)))
|
|
||||||
|
|
||||||
(define (get-windows-compile)
|
|
||||||
(or (find-executable-path "cl.exe" #f)
|
|
||||||
(find-executable-path "gcc.exe" #f)
|
|
||||||
(find-executable-path "bcc32.exe" #f)))
|
|
||||||
|
|
||||||
(define current-extension-compiler
|
|
||||||
(make-parameter
|
|
||||||
(or (let ([p (or (getenv "MZSCHEME_DYNEXT_COMPILER")
|
|
||||||
(getenv "CC"))])
|
|
||||||
(and p
|
|
||||||
(if (absolute-path? p)
|
|
||||||
(string->path p)
|
|
||||||
(find-executable-path p #f))))
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx) (get-unix-compile)]
|
|
||||||
[(windows) (get-windows-compile)]
|
|
||||||
[else #f]))
|
|
||||||
(lambda (v)
|
|
||||||
(when v
|
|
||||||
(if (path-string? v)
|
|
||||||
(unless (and (file-exists? v)
|
|
||||||
(memq 'execute (file-or-directory-permissions v)))
|
|
||||||
(error 'current-extension-compiler
|
|
||||||
"compiler not found or not executable: ~s" v))
|
|
||||||
(raise-type-error 'current-extension-compiler "path, valid-path string, or #f" v)))
|
|
||||||
v)))
|
|
||||||
|
|
||||||
(define win-gcc?
|
|
||||||
(let ([c (current-extension-compiler)])
|
|
||||||
(and c (regexp-match #"gcc.exe$" (path->bytes c)))))
|
|
||||||
(define win-borland?
|
|
||||||
(let ([c (current-extension-compiler)])
|
|
||||||
(and c (regexp-match #"bcc32.exe$" (path->bytes c)))))
|
|
||||||
(define unix-cc?
|
|
||||||
(let ([c (current-extension-compiler)])
|
|
||||||
(and c (regexp-match #"[^g]cc$" (path->bytes c)))))
|
|
||||||
|
|
||||||
(define (add-variant-flags l)
|
|
||||||
(append l (list (lambda ()
|
|
||||||
(if (eq? '3m (specific-compile-variant))
|
|
||||||
'("-DMZ_PRECISE_GC")
|
|
||||||
null)))))
|
|
||||||
|
|
||||||
(define gcc-cpp-flags
|
|
||||||
(add-variant-flags (case (string->symbol (path->string (system-library-subpath #f)))
|
|
||||||
[(parisc-hpux) '("-D_HPUX_SOURCE")]
|
|
||||||
[(ppc-macosx x86_64-macosx) '("-DOS_X")]
|
|
||||||
[(i386-macosx) '("-DOS_X" "-m32")]
|
|
||||||
[(ppc-darwin x86_64-darwin) '("-DOS_X" "-DXONX")]
|
|
||||||
[(i386-darwin) '("-DOS_X" "-DXONX" "-m32")]
|
|
||||||
[else null])))
|
|
||||||
|
|
||||||
(define gcc-compile-flags (append '("-c" "-O2" "-fPIC")
|
|
||||||
(case (string->symbol (path->string (system-library-subpath #f)))
|
|
||||||
[(i386-macosx i386-darwin) '("-m32" "-fno-common")]
|
|
||||||
[(ppc-macosx ppc-darwin x86_64-macosx x86_64-darwin) '("-fno-common")]
|
|
||||||
[(win32\\i386) '("-DAS_MSVC_EXTENSION")]
|
|
||||||
[else null])
|
|
||||||
gcc-cpp-flags))
|
|
||||||
|
|
||||||
(define unix-cpp-flags
|
|
||||||
(add-variant-flags (case (string->symbol (path->string (system-library-subpath #f)))
|
|
||||||
[(parisc-hpux) '("-D_HPUX_SOURCE")]
|
|
||||||
[else gcc-cpp-flags])))
|
|
||||||
|
|
||||||
(define unix-compile-flags (case (string->symbol (path->string (system-library-subpath #f)))
|
|
||||||
[(parisc-hpux) (append '("-c" "-O2" "-Aa" "+z" "+e")
|
|
||||||
unix-cpp-flags)]
|
|
||||||
[else gcc-compile-flags]))
|
|
||||||
|
|
||||||
(define msvc-compile-flags
|
|
||||||
(add-variant-flags '("/c" "/MT" "/O2")))
|
|
||||||
|
|
||||||
(define (make-flags-guard who)
|
|
||||||
(lambda (l)
|
|
||||||
(unless (and (list? l) (andmap (lambda (s) (or (path-string? s)
|
|
||||||
(and (procedure? s) (procedure-arity-includes? s 0))))
|
|
||||||
l))
|
|
||||||
(raise-type-error who "list of paths/strings and thunks" l))
|
|
||||||
l))
|
|
||||||
|
|
||||||
(define (get-env-compile-flags)
|
|
||||||
(let ([v (or (getenv "MZSCHEME_DYNEXT_COMPILER_FLAGS")
|
|
||||||
(getenv "CFLAGS"))])
|
|
||||||
(if v
|
|
||||||
(split-command-line-args v)
|
|
||||||
null)))
|
|
||||||
|
|
||||||
(define current-extension-compiler-flags
|
|
||||||
(make-parameter
|
|
||||||
(append
|
|
||||||
(get-env-compile-flags)
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx) (if unix-cc?
|
|
||||||
unix-compile-flags
|
|
||||||
gcc-compile-flags)]
|
|
||||||
[(windows) (if (or win-gcc? win-borland?)
|
|
||||||
gcc-compile-flags
|
|
||||||
msvc-compile-flags)]
|
|
||||||
[(macos) '()]))
|
|
||||||
(make-flags-guard 'current-extension-compiler-flags)))
|
|
||||||
|
|
||||||
(define current-extension-preprocess-flags
|
|
||||||
(make-parameter
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx) (cons "-E" (if unix-cc?
|
|
||||||
unix-cpp-flags
|
|
||||||
gcc-cpp-flags))]
|
|
||||||
[(windows) (if (or win-gcc? win-borland?)
|
|
||||||
(cons "-E" gcc-cpp-flags)
|
|
||||||
'("/E"))]
|
|
||||||
[(macos) '()])
|
|
||||||
(make-flags-guard 'current-extension-preprocess-flags)))
|
|
||||||
|
|
||||||
(define compile-variant (make-parameter
|
|
||||||
'normal
|
|
||||||
(lambda (s)
|
|
||||||
(unless (memq s '(normal cgc 3m))
|
|
||||||
(raise-type-error 'compile-variant "'normal, 'cgc, or '3m" s))
|
|
||||||
s)))
|
|
||||||
|
|
||||||
(define (specific-compile-variant)
|
|
||||||
(let ([v (compile-variant)])
|
|
||||||
(if (eq? v 'normal)
|
|
||||||
(system-type 'gc)
|
|
||||||
v)))
|
|
||||||
|
|
||||||
(define (expand-for-compile-variant l)
|
|
||||||
(apply append (map (lambda (s) (if (path-string? s) (list s) (s))) l)))
|
|
||||||
|
|
||||||
(define current-make-extra-extension-compiler-flags
|
|
||||||
(make-parameter
|
|
||||||
(lambda () (case (specific-compile-variant)
|
|
||||||
[(3m) '("-DMZ_PRECISE_GC")]
|
|
||||||
[else null]))
|
|
||||||
(lambda (p)
|
|
||||||
(unless (and (procedure? p) (procedure-arity-includes? p 0))
|
|
||||||
(raise-type-error 'current-make-extra-extension-compiler-flags "procedure (arity 0)" p))
|
|
||||||
p)))
|
|
||||||
|
|
||||||
(define (path-string->string s)
|
|
||||||
(if (string? s) s (path->string s)))
|
|
||||||
|
|
||||||
(define unix-compile-include-strings (lambda (s)
|
|
||||||
(list (string-append "-I" (path-string->string s)))))
|
|
||||||
(define msvc-compile-include-strings (lambda (s)
|
|
||||||
(list (string-append "/I" (path-string->string s)))))
|
|
||||||
|
|
||||||
(define current-make-compile-include-strings
|
|
||||||
(make-parameter
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx) unix-compile-include-strings]
|
|
||||||
[(windows) (if (or win-gcc? win-borland?)
|
|
||||||
unix-compile-include-strings
|
|
||||||
msvc-compile-include-strings)]
|
|
||||||
[(macos) unix-compile-include-strings])
|
|
||||||
(lambda (p)
|
|
||||||
(unless (procedure-arity-includes? p 1)
|
|
||||||
(raise-type-error 'current-make-compile-include-strings "procedure of arity 1" p))
|
|
||||||
p)))
|
|
||||||
|
|
||||||
(define current-make-compile-input-strings
|
|
||||||
(make-parameter
|
|
||||||
(lambda (s) (list (path-string->string s)))
|
|
||||||
(lambda (p)
|
|
||||||
(unless (procedure-arity-includes? p 1)
|
|
||||||
(raise-type-error 'current-make-compile-input-strings "procedure of arity 1" p))
|
|
||||||
p)))
|
|
||||||
|
|
||||||
(define unix-compile-output-strings (lambda (s) (list "-o" (path-string->string s))))
|
|
||||||
(define msvc-compile-output-strings (lambda (s) (list (string-append "/Fo" (path-string->string s)))))
|
|
||||||
|
|
||||||
(define current-make-compile-output-strings
|
|
||||||
(make-parameter
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx) unix-compile-output-strings]
|
|
||||||
[(windows) (if (or win-gcc? win-borland?)
|
|
||||||
unix-compile-output-strings
|
|
||||||
msvc-compile-output-strings)]
|
|
||||||
[(macos) unix-compile-output-strings])
|
|
||||||
(lambda (p)
|
|
||||||
(unless (procedure-arity-includes? p 1)
|
|
||||||
(raise-type-error 'current-make-compile-output-strings "procedure of arity 1" p))
|
|
||||||
p)))
|
|
||||||
|
|
||||||
(define (get-standard-compilers)
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx) '(gcc cc)]
|
|
||||||
[(windows) '(gcc msvc borland)]
|
|
||||||
[(macos) '(cw)]))
|
|
||||||
|
|
||||||
(define (use-standard-compiler name)
|
|
||||||
(define (bad-name name)
|
|
||||||
(error 'use-standard-compiler "unknown compiler: ~a" name))
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx)
|
|
||||||
(case name
|
|
||||||
[(cc gcc) (let* ([n (if (eq? name 'gcc) "gcc" "cc")]
|
|
||||||
[f (find-executable-path n n)])
|
|
||||||
(unless f
|
|
||||||
(error 'use-standard-compiler "cannot find ~a" n))
|
|
||||||
(current-extension-compiler f))
|
|
||||||
(current-extension-compiler-flags (add-variant-flags
|
|
||||||
(if (eq? name 'gcc)
|
|
||||||
gcc-compile-flags
|
|
||||||
unix-compile-flags)))
|
|
||||||
(current-make-compile-include-strings unix-compile-include-strings)
|
|
||||||
(current-make-compile-input-strings (lambda (s) (list (path-string->string s))))
|
|
||||||
(current-make-compile-output-strings unix-compile-output-strings)]
|
|
||||||
[else (bad-name name)])]
|
|
||||||
[(windows)
|
|
||||||
(case name
|
|
||||||
[(gcc) (let ([f (find-executable-path "gcc.exe" #f)])
|
|
||||||
(unless f
|
|
||||||
(error 'use-standard-compiler "cannot find gcc.exe"))
|
|
||||||
(current-extension-compiler f))
|
|
||||||
(current-extension-compiler-flags (add-variant-flags gcc-compile-flags))
|
|
||||||
(current-make-compile-include-strings unix-compile-include-strings)
|
|
||||||
(current-make-compile-input-strings (lambda (s) (list (path-string->string s))))
|
|
||||||
(current-make-compile-output-strings unix-compile-output-strings)]
|
|
||||||
[(borland) (let ([f (find-executable-path "bcc32.exe" #f)])
|
|
||||||
(unless f
|
|
||||||
(error 'use-standard-compiler "cannot find bcc32.exe"))
|
|
||||||
(current-extension-compiler f))
|
|
||||||
(current-extension-compiler-flags (add-variant-flags gcc-compile-flags))
|
|
||||||
(current-make-compile-include-strings unix-compile-include-strings)
|
|
||||||
(current-make-compile-input-strings (lambda (s) (list (path-string->string s))))
|
|
||||||
(current-make-compile-output-strings unix-compile-output-strings)]
|
|
||||||
[(msvc) (let ([f (find-executable-path "cl.exe" #f)])
|
|
||||||
(unless f
|
|
||||||
(error 'use-standard-compiler "cannot find MSVC's cl.exe"))
|
|
||||||
(current-extension-compiler f))
|
|
||||||
(current-extension-compiler-flags (add-variant-flags msvc-compile-flags))
|
|
||||||
(current-make-compile-include-strings msvc-compile-include-strings)
|
|
||||||
(current-make-compile-input-strings (lambda (s) (list (path-string->string s))))
|
|
||||||
(current-make-compile-output-strings msvc-compile-output-strings)]
|
|
||||||
[else (bad-name name)])]
|
|
||||||
[(macos)
|
|
||||||
(case name
|
|
||||||
[(cw) (current-extension-compiler #f)
|
|
||||||
(current-extension-compiler-flags (add-variant-flags unix-compile-flags))
|
|
||||||
(current-make-compile-include-strings unix-compile-include-strings)
|
|
||||||
(current-make-compile-input-strings (lambda (s) (list (path-string->string s))))
|
|
||||||
(current-make-compile-output-strings unix-compile-output-strings)]
|
|
||||||
[else (bad-name name)])]))
|
|
||||||
|
|
||||||
(define-values (my-process* stdio-compile)
|
|
||||||
(let-values ([(p* do-stdio) (get-stdio)])
|
|
||||||
(values
|
|
||||||
p*
|
|
||||||
(lambda (start-process quiet?)
|
|
||||||
(do-stdio start-process quiet? (lambda (s) (error 'compile-extension "~a" s)))))))
|
|
||||||
|
|
||||||
(define (make-compile-extension current-extension-compiler-flags)
|
|
||||||
(lambda (quiet? in out includes)
|
|
||||||
(let ([c (current-extension-compiler)])
|
|
||||||
(if c
|
|
||||||
(stdio-compile (lambda (quiet?)
|
|
||||||
(let ([command (append
|
|
||||||
(list c)
|
|
||||||
(expand-for-compile-variant
|
|
||||||
(current-extension-compiler-flags))
|
|
||||||
(apply append
|
|
||||||
(map
|
|
||||||
(lambda (s)
|
|
||||||
((current-make-compile-include-strings) s))
|
|
||||||
includes))
|
|
||||||
((current-make-compile-include-strings) (include-dir))
|
|
||||||
((current-make-compile-input-strings) in)
|
|
||||||
((current-make-compile-output-strings) out))])
|
|
||||||
(unless quiet?
|
|
||||||
(printf "compile-extension: ~a\n" command))
|
|
||||||
(apply my-process* command)))
|
|
||||||
quiet?)
|
|
||||||
(error 'compile-extension "can't find an installed C compiler")))))
|
|
||||||
|
|
||||||
(define compile-extension (make-compile-extension
|
|
||||||
current-extension-compiler-flags))
|
|
||||||
(define preprocess-extension (make-compile-extension
|
|
||||||
current-extension-compiler-flags))))
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require racket/unit)
|
|
||||||
|
|
||||||
(require "compile-sig.rkt"
|
|
||||||
"compile-unit.rkt")
|
|
||||||
|
|
||||||
(define-values/invoke-unit/infer dynext:compile@)
|
|
||||||
|
|
||||||
(provide-signature-elements dynext:compile^)
|
|
|
@ -1,6 +0,0 @@
|
||||||
(module dynext-sig racket/base
|
|
||||||
|
|
||||||
(require "compile-sig.rkt" "link-sig.rkt")
|
|
||||||
|
|
||||||
(provide (all-from-out "compile-sig.rkt")
|
|
||||||
(all-from-out "link-sig.rkt")))
|
|
|
@ -1,6 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
(require "compile-unit.rkt" "link-unit.rkt")
|
|
||||||
|
|
||||||
(provide (all-from-out "compile-unit.rkt")
|
|
||||||
(all-from-out "link-unit.rkt"))
|
|
|
@ -1,7 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
(require "compile.rkt" "link.rkt" dynext/file)
|
|
||||||
|
|
||||||
(provide (all-from-out "compile.rkt")
|
|
||||||
(all-from-out "link.rkt")
|
|
||||||
(all-from-out dynext/file))
|
|
|
@ -1,17 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require racket/unit)
|
|
||||||
|
|
||||||
(provide dynext:file^)
|
|
||||||
|
|
||||||
(define-signature dynext:file^
|
|
||||||
(append-zo-suffix
|
|
||||||
append-c-suffix
|
|
||||||
append-constant-pool-suffix
|
|
||||||
append-object-suffix
|
|
||||||
append-extension-suffix
|
|
||||||
|
|
||||||
extract-base-filename/ss
|
|
||||||
extract-base-filename/c
|
|
||||||
extract-base-filename/kp
|
|
||||||
extract-base-filename/o
|
|
||||||
extract-base-filename/ext))
|
|
|
@ -1,7 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
(require racket/unit "file-sig.rkt" dynext/file)
|
|
||||||
|
|
||||||
(provide dynext:file@)
|
|
||||||
|
|
||||||
(define-unit-from-context dynext:file@ dynext:file^)
|
|
|
@ -1,16 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require racket/unit)
|
|
||||||
|
|
||||||
(provide dynext:link^)
|
|
||||||
|
|
||||||
(define-signature dynext:link^
|
|
||||||
(link-extension
|
|
||||||
current-extension-linker
|
|
||||||
current-extension-linker-flags
|
|
||||||
current-make-link-input-strings
|
|
||||||
current-make-link-output-strings
|
|
||||||
current-standard-link-libraries
|
|
||||||
current-use-mzdyn
|
|
||||||
use-standard-linker
|
|
||||||
link-variant
|
|
||||||
expand-for-link-variant))
|
|
|
@ -1,440 +0,0 @@
|
||||||
(module link-unit racket/base
|
|
||||||
(require racket/unit
|
|
||||||
racket/system
|
|
||||||
"private/dirs.rkt"
|
|
||||||
"private/stdio.rkt"
|
|
||||||
"private/cmdargs.rkt"
|
|
||||||
dynext/filename-version)
|
|
||||||
|
|
||||||
(require "link-sig.rkt")
|
|
||||||
|
|
||||||
(provide dynext:link@)
|
|
||||||
|
|
||||||
(define-unit dynext:link@
|
|
||||||
(import)
|
|
||||||
(export dynext:link^)
|
|
||||||
|
|
||||||
(define (path-string->string s)
|
|
||||||
(if (string? s) s (path->string s)))
|
|
||||||
|
|
||||||
;; ---- Find a linker for this platform --------------------
|
|
||||||
|
|
||||||
(define (get-windows-linker)
|
|
||||||
(or (find-executable-path "cl.exe" #f)
|
|
||||||
(find-executable-path "ld.exe" #f)
|
|
||||||
(find-executable-path "ilink32.exe" #f)))
|
|
||||||
|
|
||||||
(define (get-unix-linker)
|
|
||||||
(let ([l (case (string->symbol (path->string (system-library-subpath #f)))
|
|
||||||
[(sparc-solaris i386-solaris
|
|
||||||
sparc-sunos4
|
|
||||||
i386-freebsd-2.x
|
|
||||||
parisc-hpux
|
|
||||||
i386-cygwin)
|
|
||||||
'("ld")]
|
|
||||||
[else '("gcc" "cc")])])
|
|
||||||
(ormap (lambda (s)
|
|
||||||
(find-executable-path s #f))
|
|
||||||
l)))
|
|
||||||
|
|
||||||
(define (check-valid-linker-path v)
|
|
||||||
(unless (and (file-exists? v)
|
|
||||||
(memq 'execute (file-or-directory-permissions v)))
|
|
||||||
(error 'current-extension-linker
|
|
||||||
"linker not found or not executable: ~s" v)))
|
|
||||||
|
|
||||||
;; See manual:
|
|
||||||
(define current-extension-linker
|
|
||||||
(make-parameter
|
|
||||||
(or (let ([p (getenv "MZSCHEME_DYNEXT_LINKER")])
|
|
||||||
(and p
|
|
||||||
(if (absolute-path? p)
|
|
||||||
(string->path p)
|
|
||||||
(find-executable-path p #f))))
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx) (get-unix-linker)]
|
|
||||||
[(windows) (get-windows-linker)]
|
|
||||||
[else #f]))
|
|
||||||
(lambda (v)
|
|
||||||
(when v
|
|
||||||
(if (path-string? v)
|
|
||||||
(check-valid-linker-path v)
|
|
||||||
(raise-type-error 'current-extension-linker "path, valid-path string, or #f" v)))
|
|
||||||
v)))
|
|
||||||
|
|
||||||
;; Helpers to tell us about the selected linker in Windows:
|
|
||||||
|
|
||||||
(define (still-win-gcc?)
|
|
||||||
(or (and (eq? 'windows (system-type))
|
|
||||||
(let ([c (current-extension-linker)])
|
|
||||||
(and c (regexp-match #"ld.exe$" (path-string->string c)))))
|
|
||||||
(and (eq? 'unix (system-type))
|
|
||||||
(string=? "i386-cygwin"
|
|
||||||
(path->string (system-library-subpath #f))))))
|
|
||||||
(define (still-win-borland?)
|
|
||||||
(and (eq? 'windows (system-type))
|
|
||||||
(let ([c (current-extension-linker)])
|
|
||||||
(and c (regexp-match #"ilink32.exe$" (path-string->string c))))))
|
|
||||||
|
|
||||||
(define win-gcc? (still-win-gcc?))
|
|
||||||
(define win-borland? (still-win-borland?))
|
|
||||||
|
|
||||||
;; ---- The right flags for this platform+linker --------------------
|
|
||||||
|
|
||||||
;; We need
|
|
||||||
;; 1) the basic flags
|
|
||||||
;; 2) a way to wrap inputs on the command line
|
|
||||||
;; 3) a way to wrap the output on the command line
|
|
||||||
;; 4) needed base libraries and objects
|
|
||||||
|
|
||||||
(define link-variant (make-parameter
|
|
||||||
'normal
|
|
||||||
(lambda (s)
|
|
||||||
(unless (memq s '(normal cgc 3m))
|
|
||||||
(raise-type-error 'link-variant "'normal, 'cgc, or '3m" s))
|
|
||||||
s)))
|
|
||||||
|
|
||||||
(define (specific-link-variant)
|
|
||||||
(let ([v (link-variant)])
|
|
||||||
(if (eq? v 'normal)
|
|
||||||
(system-type 'gc)
|
|
||||||
v)))
|
|
||||||
|
|
||||||
(define (wrap-3m s)
|
|
||||||
(lambda ()
|
|
||||||
(list (format s (if (eq? '3m (specific-link-variant)) "3m" "")))))
|
|
||||||
|
|
||||||
(define (drop-3m s)
|
|
||||||
(lambda ()
|
|
||||||
(if (eq? '3m (specific-link-variant))
|
|
||||||
null
|
|
||||||
(list s))))
|
|
||||||
|
|
||||||
(define (expand-for-link-variant l)
|
|
||||||
(apply append (map (lambda (s) (if (path-string? s) (list (path-string->string s)) (s))) l)))
|
|
||||||
|
|
||||||
(define current-use-mzdyn (make-parameter #t))
|
|
||||||
(define (mzdyn-maybe s)
|
|
||||||
(lambda ()
|
|
||||||
(if (current-use-mzdyn) (s) null)))
|
|
||||||
|
|
||||||
(define msvc-linker-flags (list "/LD"))
|
|
||||||
(define win-gcc-linker-flags (list "--dll"))
|
|
||||||
(define borland-linker-flags (list "/Tpd" "/c"))
|
|
||||||
|
|
||||||
(define mac-link-flags (list "-bundle" "-flat_namespace" "-undefined" "suppress"))
|
|
||||||
|
|
||||||
(define (get-unix-link-flags)
|
|
||||||
(case (string->symbol (path->string (system-library-subpath #f)))
|
|
||||||
[(sparc-solaris i386-solaris) (list "-G")]
|
|
||||||
[(sparc-sunos4) (list "-Bdynamic")]
|
|
||||||
[(i386-freebsd-2.x) (list "-Bshareable")]
|
|
||||||
[(rs6k-aix) (list "-bM:SRE"
|
|
||||||
"-brtl"
|
|
||||||
(lambda ()
|
|
||||||
(map (lambda (mz-exp)
|
|
||||||
(format "-bI:~a/~a" (include-dir) mz-exp))
|
|
||||||
((wrap-3m "mzscheme~a.exp"))))
|
|
||||||
(format "-bE:~a/ext.exp" (include-dir))
|
|
||||||
"-bnoentry")]
|
|
||||||
[(parisc-hpux) (list "-b")]
|
|
||||||
[(ppc-macosx ppc-darwin x86_64-macosx x86_64-darwin) mac-link-flags]
|
|
||||||
[(i386-macosx i386-darwin) (append mac-link-flags '("-m32"))]
|
|
||||||
[(i386-cygwin) win-gcc-linker-flags]
|
|
||||||
[else (list "-fPIC" "-shared")]))
|
|
||||||
|
|
||||||
(define (get-env-link-flags)
|
|
||||||
(let ([v (or (getenv "MZSCHEME_DYNEXT_LINKER_FLAGS")
|
|
||||||
(getenv "LDFLAGS"))])
|
|
||||||
(if v
|
|
||||||
(split-command-line-args v)
|
|
||||||
null)))
|
|
||||||
|
|
||||||
;; See manual:
|
|
||||||
(define current-extension-linker-flags
|
|
||||||
(make-parameter
|
|
||||||
(append (get-env-link-flags)
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx) (get-unix-link-flags)]
|
|
||||||
[(windows) (cond
|
|
||||||
[win-gcc? win-gcc-linker-flags]
|
|
||||||
[win-borland? borland-linker-flags]
|
|
||||||
[else msvc-linker-flags])]
|
|
||||||
[(macos) null]))
|
|
||||||
(lambda (l)
|
|
||||||
(unless (and (list? l) (andmap string? l))
|
|
||||||
(raise-type-error 'current-extension-linker-flags "list of strings" l))
|
|
||||||
l)))
|
|
||||||
|
|
||||||
;; See manual:
|
|
||||||
(define current-make-link-input-strings
|
|
||||||
(make-parameter
|
|
||||||
(lambda (s) (list (path-string->string s)))
|
|
||||||
(lambda (p)
|
|
||||||
(unless (procedure-arity-includes? p 1)
|
|
||||||
(raise-type-error 'current-make-link-input-strings "procedure of arity 1" p))
|
|
||||||
p)))
|
|
||||||
|
|
||||||
(define win-gcc-link-output-strings (lambda (s) (list "--base-file"
|
|
||||||
(path->string (make-win-gcc-temp "base"))
|
|
||||||
"-e" "_dll_entry@12"
|
|
||||||
"-o" (path-string->string s))))
|
|
||||||
(define msvc-link-output-strings (lambda (s) (list (string-append "/Fe" (path-string->string s)))))
|
|
||||||
(define borland-link-output-strings (lambda (s) (list* "," (path-string->string s)
|
|
||||||
"," "," "c0d32.obj" "cw32.lib" "import32.lib"
|
|
||||||
(if (current-use-mzdyn)
|
|
||||||
(list "," (path->string
|
|
||||||
(build-path (std-library-dir)
|
|
||||||
"bcc"
|
|
||||||
"mzdynb.def")))
|
|
||||||
null))))
|
|
||||||
|
|
||||||
;; See manual:
|
|
||||||
(define current-make-link-output-strings
|
|
||||||
(make-parameter
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx)
|
|
||||||
(case (string->symbol (path->string (system-library-subpath #f)))
|
|
||||||
[(i386-cygwin) win-gcc-link-output-strings]
|
|
||||||
[else (lambda (s) (list "-o" (path-string->string s)))])]
|
|
||||||
[(windows) (cond
|
|
||||||
[win-gcc? win-gcc-link-output-strings]
|
|
||||||
[win-borland? borland-link-output-strings]
|
|
||||||
[else msvc-link-output-strings])]
|
|
||||||
[(macos) (lambda (s) (list "-o" (path-string->string s)))])
|
|
||||||
(lambda (p)
|
|
||||||
(unless (procedure-arity-includes? p 1)
|
|
||||||
(raise-type-error 'current-make-link-output-strings "procedure of arity 1" p))
|
|
||||||
p)))
|
|
||||||
|
|
||||||
(define (make-win-link-libraries win-gcc? win-borland? unix?)
|
|
||||||
(let* ([file (lambda (f)
|
|
||||||
(path->string
|
|
||||||
(build-path (std-library-dir)
|
|
||||||
(cond
|
|
||||||
[win-gcc? "gcc"]
|
|
||||||
[win-borland? "bcc"]
|
|
||||||
[else "msvc"])
|
|
||||||
f)))]
|
|
||||||
[dllfile (lambda (f)
|
|
||||||
(path->string
|
|
||||||
(build-path (std-library-dir) f)))]
|
|
||||||
[filethunk (lambda (f)
|
|
||||||
(lambda ()
|
|
||||||
(map file (f))))]
|
|
||||||
[wrap-xxxxxxx
|
|
||||||
(lambda (file f)
|
|
||||||
(lambda ()
|
|
||||||
(map (lambda (s)
|
|
||||||
(if (file-exists?
|
|
||||||
(file (format s filename-version-part)))
|
|
||||||
(file (format s filename-version-part))
|
|
||||||
(file (format s "xxxxxxx"))))
|
|
||||||
(f))))])
|
|
||||||
(cond
|
|
||||||
[win-gcc? (append
|
|
||||||
(if unix?
|
|
||||||
null
|
|
||||||
(list (wrap-xxxxxxx dllfile (wrap-3m "libracket~a~~a.dll"))
|
|
||||||
(wrap-xxxxxxx dllfile (drop-3m "libmzgc~a.dll"))))
|
|
||||||
(list
|
|
||||||
(mzdyn-maybe (filethunk (wrap-3m "mzdyn~a.exp")))
|
|
||||||
(mzdyn-maybe (filethunk (wrap-3m
|
|
||||||
;; mzdyn.o is for Unix build, mzdynw.o for Windows
|
|
||||||
(format "mzdyn~a~~a.o"
|
|
||||||
(if unix? "" "w")))))
|
|
||||||
(file "init.o")
|
|
||||||
(file "fixup.o")))]
|
|
||||||
[win-borland? (map file (if (current-use-mzdyn)
|
|
||||||
(list "mzdynb.obj")
|
|
||||||
null))]
|
|
||||||
[else (list (wrap-xxxxxxx file (wrap-3m "libracket~a~~a.lib"))
|
|
||||||
(wrap-xxxxxxx file (drop-3m "libmzgc~a.lib"))
|
|
||||||
(mzdyn-maybe (filethunk (wrap-3m "mzdyn~a.exp")))
|
|
||||||
(mzdyn-maybe (filethunk (wrap-3m "mzdyn~a.obj"))))])))
|
|
||||||
|
|
||||||
(define (get-unix/macos-link-libraries)
|
|
||||||
(case (string->symbol (path->string (system-library-subpath #f)))
|
|
||||||
[(i386-cygwin)
|
|
||||||
(make-win-link-libraries #t #f #t)]
|
|
||||||
[else
|
|
||||||
(list (lambda ()
|
|
||||||
(if (current-use-mzdyn)
|
|
||||||
(map (lambda (mz.o)
|
|
||||||
(path->string (build-path (std-library-dir) mz.o)))
|
|
||||||
((wrap-3m "mzdyn~a.o")))
|
|
||||||
null)))]))
|
|
||||||
|
|
||||||
;; See manual:
|
|
||||||
(define current-standard-link-libraries
|
|
||||||
(make-parameter
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macos macosx) (get-unix/macos-link-libraries)]
|
|
||||||
[(windows) (make-win-link-libraries win-gcc? win-borland? #f)])
|
|
||||||
(lambda (l)
|
|
||||||
(unless (and (list? l)
|
|
||||||
(andmap (lambda (s) (or (path-string? s)
|
|
||||||
(and (procedure? s) (procedure-arity-includes? s 0))))
|
|
||||||
l))
|
|
||||||
(raise-type-error 'current-stand-link-libraries "list of paths/strings and thunks" l))
|
|
||||||
l)))
|
|
||||||
|
|
||||||
;; ---- Function to install standard linker parameters --------------------
|
|
||||||
|
|
||||||
;; see manual
|
|
||||||
(define (use-standard-linker name)
|
|
||||||
(define (bad-name name)
|
|
||||||
(error 'use-standard-linker "unknown linker: ~a" name))
|
|
||||||
(case (system-type)
|
|
||||||
[(unix macosx)
|
|
||||||
(case name
|
|
||||||
[(cc gcc) (current-extension-linker (get-unix-linker))
|
|
||||||
(current-extension-linker-flags (get-unix-link-flags))
|
|
||||||
(current-make-link-input-strings (lambda (s) (list (path-string->string s))))
|
|
||||||
(current-make-link-output-strings (lambda (s) (list "-o" (path-string->string s))))
|
|
||||||
(current-standard-link-libraries (get-unix/macos-link-libraries))]
|
|
||||||
[else (bad-name name)])]
|
|
||||||
[(windows)
|
|
||||||
(case name
|
|
||||||
[(gcc) (let ([f (find-executable-path "ld.exe" #f)])
|
|
||||||
(unless f
|
|
||||||
(error 'use-standard-linker "cannot find gcc's ld.exe"))
|
|
||||||
(current-extension-linker f)
|
|
||||||
(current-extension-linker-flags win-gcc-linker-flags)
|
|
||||||
(current-make-link-input-strings (lambda (s) (list (path-string->string s))))
|
|
||||||
(current-make-link-output-strings win-gcc-link-output-strings)
|
|
||||||
(current-standard-link-libraries (make-win-link-libraries #t #f #f)))]
|
|
||||||
[(borland) (let ([f (find-executable-path "ilink32.exe" #f)])
|
|
||||||
(unless f
|
|
||||||
(error 'use-standard-linker "cannot find ilink32.exe"))
|
|
||||||
(current-extension-linker f)
|
|
||||||
(current-extension-linker-flags borland-linker-flags)
|
|
||||||
(current-make-link-input-strings (lambda (s) (list (path-string->string s))))
|
|
||||||
(current-make-link-output-strings borland-link-output-strings)
|
|
||||||
(current-standard-link-libraries (make-win-link-libraries #f #t #f)))]
|
|
||||||
[(msvc) (let ([f (find-executable-path "cl.exe" #f)])
|
|
||||||
(unless f
|
|
||||||
(error 'use-standard-linker "cannot find MSVC's cl.exe"))
|
|
||||||
(current-extension-linker f)
|
|
||||||
(current-extension-linker-flags msvc-linker-flags)
|
|
||||||
(current-make-link-input-strings (lambda (s) (list (path-string->string s))))
|
|
||||||
(current-make-link-output-strings msvc-link-output-strings)
|
|
||||||
(current-standard-link-libraries (make-win-link-libraries #f #f #f)))]
|
|
||||||
[else (bad-name name)])]
|
|
||||||
[(macos)
|
|
||||||
(case name
|
|
||||||
[(cw) (current-extension-linker #f)
|
|
||||||
(current-extension-linker-flags null)
|
|
||||||
(current-make-link-input-strings (lambda (s) (list (path-string->string s))))
|
|
||||||
(current-make-link-output-strings (lambda (s) (list "-o" (path-string->string s))))
|
|
||||||
(current-standard-link-libraries (get-unix/macos-link-libraries))]
|
|
||||||
[else (bad-name name)])]))
|
|
||||||
|
|
||||||
;; ---- The link driver for each platform --------------------
|
|
||||||
|
|
||||||
(define unix/windows-link
|
|
||||||
(lambda (quiet? in out)
|
|
||||||
(let ([c (current-extension-linker)])
|
|
||||||
(if c
|
|
||||||
(let* ([output-strings
|
|
||||||
((current-make-link-output-strings) out)]
|
|
||||||
[libs (expand-for-link-variant (current-standard-link-libraries))]
|
|
||||||
[command
|
|
||||||
(append
|
|
||||||
(list c)
|
|
||||||
(expand-for-link-variant (current-extension-linker-flags))
|
|
||||||
(apply append (map (lambda (s) ((current-make-link-input-strings) s))
|
|
||||||
in))
|
|
||||||
libs
|
|
||||||
output-strings)])
|
|
||||||
(unless quiet?
|
|
||||||
(printf "link-extension: ~a\n" command))
|
|
||||||
(stdio-link (lambda (quiet?)
|
|
||||||
(apply my-process* command))
|
|
||||||
quiet?)
|
|
||||||
|
|
||||||
;; Stange Cygwin system for relocatable DLLs: we run dlltool twice and
|
|
||||||
;; ld three times total
|
|
||||||
(when (still-win-gcc?)
|
|
||||||
(let ([dlltool (find-executable-path "dlltool.exe" "dlltool.exe")]
|
|
||||||
;; Find base-file name we already made up:
|
|
||||||
[basefile (let ([m (member "--base-file" output-strings)])
|
|
||||||
(and m (cadr m)))]
|
|
||||||
;; Make new exp file name:
|
|
||||||
[expfile (make-win-gcc-temp "exp")])
|
|
||||||
(when (and dlltool basefile)
|
|
||||||
(let* ([dll-command
|
|
||||||
;; Generate DLL link information
|
|
||||||
`("--dllname" ,(if (path? out) (path->string out) out)
|
|
||||||
,@(if (current-use-mzdyn)
|
|
||||||
`("--def" ,(path->string (build-path (std-library-dir) "gcc" "mzdyn.def")))
|
|
||||||
`())
|
|
||||||
"--base-file" ,basefile
|
|
||||||
"--output-exp" ,(path->string expfile))]
|
|
||||||
;; Command to link with new .exp, re-create .base:
|
|
||||||
[command1
|
|
||||||
(map (lambda (s)
|
|
||||||
(let ([s (if (path? s)
|
|
||||||
(path->string s)
|
|
||||||
s)])
|
|
||||||
(if (regexp-match "[.]exp$" s)
|
|
||||||
(path->string expfile)
|
|
||||||
s)))
|
|
||||||
command)]
|
|
||||||
;; Command to link with new .exp file, no .base needed:
|
|
||||||
[command2
|
|
||||||
(let loop ([l command1])
|
|
||||||
(cond
|
|
||||||
[(null? l) null]
|
|
||||||
[(and (string? (car l))
|
|
||||||
(string=? (car l) "--base-file"))
|
|
||||||
(cddr l)]
|
|
||||||
[else (cons (car l) (loop (cdr l)))]))])
|
|
||||||
(unless quiet?
|
|
||||||
(printf "link-extension, dlltool phase: ~a\n"
|
|
||||||
(cons dlltool dll-command)))
|
|
||||||
(stdio-link (lambda (quiet?)
|
|
||||||
(apply my-process* dlltool dll-command))
|
|
||||||
quiet?)
|
|
||||||
(unless quiet?
|
|
||||||
(printf "link-extension, re-link phase: ~a\n"
|
|
||||||
command1))
|
|
||||||
(stdio-link (lambda (quiet?)
|
|
||||||
(apply my-process* command1))
|
|
||||||
quiet?)
|
|
||||||
(unless quiet?
|
|
||||||
(printf "link-extension, re-dlltool phase: ~a\n"
|
|
||||||
(cons dlltool dll-command)))
|
|
||||||
(stdio-link (lambda (quiet?)
|
|
||||||
(apply my-process* dlltool dll-command))
|
|
||||||
quiet?)
|
|
||||||
(unless quiet?
|
|
||||||
(printf "link-extension, last re-link phase: ~a\n"
|
|
||||||
command2))
|
|
||||||
(stdio-link (lambda (quiet?)
|
|
||||||
(apply my-process* command2))
|
|
||||||
quiet?)
|
|
||||||
(delete-file basefile)
|
|
||||||
(delete-file expfile))))))
|
|
||||||
(error 'link-extension "can't find an installed linker")))))
|
|
||||||
|
|
||||||
(define link-extension
|
|
||||||
(case (system-type)
|
|
||||||
[(unix windows macosx) unix/windows-link]))
|
|
||||||
|
|
||||||
;; ---- some helpers:
|
|
||||||
|
|
||||||
(define-values (my-process* stdio-link)
|
|
||||||
(let-values ([(p* do-stdio) (get-stdio)])
|
|
||||||
(values
|
|
||||||
p*
|
|
||||||
(lambda (start-process quiet?)
|
|
||||||
(do-stdio start-process quiet? (lambda (s) (error 'link-extension "~a" s)))))))
|
|
||||||
|
|
||||||
(define (make-win-gcc-temp suffix)
|
|
||||||
(let ([d (find-system-path 'temp-dir)])
|
|
||||||
(let loop ([n 1])
|
|
||||||
(let ([f (build-path d (format "tmp~a.~a" n suffix))])
|
|
||||||
(if (file-exists? f)
|
|
||||||
(loop (add1 n))
|
|
||||||
f)))))))
|
|
|
@ -1,9 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require racket/unit)
|
|
||||||
|
|
||||||
(require "link-sig.rkt"
|
|
||||||
"link-unit.rkt")
|
|
||||||
|
|
||||||
(define-values/invoke-unit/infer dynext:link@)
|
|
||||||
|
|
||||||
(provide-signature-elements dynext:link^)
|
|
|
@ -1,4 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
(require "dynext.rkt")
|
|
||||||
(provide (all-from-out "dynext.rkt"))
|
|
|
@ -1,32 +0,0 @@
|
||||||
(module cmdargs racket/base
|
|
||||||
|
|
||||||
(provide split-command-line-args)
|
|
||||||
|
|
||||||
(define (split-command-line-args v)
|
|
||||||
(let loop ([v (strip-leading-spaces (strip-trailing-spaces v))])
|
|
||||||
(if (string=? v "")
|
|
||||||
null
|
|
||||||
(let-values ([(s v) (let loop ([v v])
|
|
||||||
(cond
|
|
||||||
[(string=? v "") (values "" "")]
|
|
||||||
[(regexp-match #rx"^[ \t\r\n]" v) (values "" v)]
|
|
||||||
[(regexp-match-positions #rx"^\"[^\"]*\"" v)
|
|
||||||
=> (combine v loop 1)]
|
|
||||||
[(regexp-match-positions #rx"^'[^']*'" v)
|
|
||||||
=> (combine v loop 1)]
|
|
||||||
[(regexp-match-positions #rx"^[^ \t\r\n]+" v)
|
|
||||||
=> (combine v loop 0)]))])
|
|
||||||
(cons s (loop (strip-leading-spaces v)))))))
|
|
||||||
|
|
||||||
(define (combine v loop inset)
|
|
||||||
(lambda (m)
|
|
||||||
(let-values ([(rest leftover) (loop (substring v (cdar m)))])
|
|
||||||
(values (string-append
|
|
||||||
(substring v (+ (caar m) inset) (- (cdar m) inset)))
|
|
||||||
leftover))))
|
|
||||||
|
|
||||||
(define (strip-leading-spaces v)
|
|
||||||
(regexp-replace #rx"^[\t \r\n]+" v ""))
|
|
||||||
|
|
||||||
(define (strip-trailing-spaces v)
|
|
||||||
(regexp-replace #rx"[\t \r\n]+$" v "")))
|
|
|
@ -1,7 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require setup/dirs)
|
|
||||||
|
|
||||||
(define include-dir find-include-dir)
|
|
||||||
(define std-library-dir find-lib-dir)
|
|
||||||
|
|
||||||
(provide include-dir std-library-dir)
|
|
|
@ -1,56 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require racket/system)
|
|
||||||
|
|
||||||
(provide get-stdio)
|
|
||||||
|
|
||||||
(define (get-stdio)
|
|
||||||
(values
|
|
||||||
(if (member (system-library-subpath) '("rs6k-aix" "parisc-hpux"))
|
|
||||||
(letrec ([pseudo-process*
|
|
||||||
(lambda (c . args)
|
|
||||||
(if (null? args)
|
|
||||||
(let ([r (process* "/usr/bin/csh" "-t")])
|
|
||||||
(display c (cadr r))
|
|
||||||
(newline (cadr r))
|
|
||||||
r)
|
|
||||||
(apply pseudo-process* (string-append c " " (car args)) (cdr args))))])
|
|
||||||
pseudo-process*)
|
|
||||||
process*)
|
|
||||||
|
|
||||||
(lambda (start-process quiet? error)
|
|
||||||
(let* ([l (start-process quiet?)]
|
|
||||||
[in (car l)]
|
|
||||||
[out (cadr l)]
|
|
||||||
[in-error (cadddr l)]
|
|
||||||
[control (cadddr (cdr l))]
|
|
||||||
|
|
||||||
[collect-output (box "")]
|
|
||||||
|
|
||||||
[make-collector
|
|
||||||
(lambda (in dest box)
|
|
||||||
(thread (lambda ()
|
|
||||||
(let loop ()
|
|
||||||
(let ([t (read-line in 'any)])
|
|
||||||
(unless (eof-object? t)
|
|
||||||
(unless quiet? (fprintf (dest) "~a\n" t))
|
|
||||||
(set-box! box (string-append (unbox box)
|
|
||||||
(string #\newline) t))
|
|
||||||
(loop)))))))]
|
|
||||||
[in-thread (make-collector in current-output-port collect-output)]
|
|
||||||
[in-error-thread (make-collector in-error current-error-port collect-output)])
|
|
||||||
|
|
||||||
(close-output-port out)
|
|
||||||
|
|
||||||
(control 'wait)
|
|
||||||
|
|
||||||
(thread-wait in-thread)
|
|
||||||
(thread-wait in-error-thread)
|
|
||||||
|
|
||||||
(close-input-port in)
|
|
||||||
(close-input-port in-error)
|
|
||||||
|
|
||||||
(unless (eq? (control 'status) 'done-ok)
|
|
||||||
(error (if quiet?
|
|
||||||
(unbox collect-output)
|
|
||||||
"command failed")))))))
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#lang info
|
|
||||||
(define collection 'multi)
|
|
||||||
(define deps '("base"
|
|
||||||
"compiler-lib"
|
|
||||||
"scheme-lib"
|
|
||||||
"rackunit-lib"))
|
|
||||||
|
|
||||||
(define pkg-desc "Tools for managing C extensions, such as `raco ctool`")
|
|
||||||
|
|
||||||
(define pkg-authors '(mflatt))
|
|
|
@ -1,11 +0,0 @@
|
||||||
compatibility-doc
|
|
||||||
Copyright (c) 2010-2014 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
|
|
||||||
applications, provided you follow the rules stated in the LGPL. You
|
|
||||||
can also modify this package; if you distribute a modified version,
|
|
||||||
you must distribute it under the terms of the LGPL, which in
|
|
||||||
particular means that you must release the source code for the
|
|
||||||
modified software. See http://www.gnu.org/copyleft/lesser.html
|
|
||||||
for more information.
|
|
|
@ -1,18 +0,0 @@
|
||||||
#lang info
|
|
||||||
(define collection 'multi)
|
|
||||||
(define deps '("base"
|
|
||||||
"scribble-lib"
|
|
||||||
"compatibility-lib"
|
|
||||||
"pconvert-lib"
|
|
||||||
"sandbox-lib"
|
|
||||||
"compiler-lib"
|
|
||||||
"gui-lib"
|
|
||||||
"racket-doc"))
|
|
||||||
|
|
||||||
(define pkg-desc "documentation part of \"compatibility\"")
|
|
||||||
|
|
||||||
(define pkg-authors '(eli mflatt robby samth))
|
|
||||||
(define build-deps '("data-doc"
|
|
||||||
"mzscheme-doc"
|
|
||||||
"scheme-lib"))
|
|
||||||
(define update-implies '("compatibility-lib"))
|
|
|
@ -1,3 +0,0 @@
|
||||||
#lang info
|
|
||||||
|
|
||||||
(define test-responsibles '((all mflatt)))
|
|
|
@ -1,69 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/awk
|
|
||||||
scheme/contract))
|
|
||||||
|
|
||||||
@mzlib[#:mode title awk]
|
|
||||||
|
|
||||||
@defform/subs[
|
|
||||||
#:literals (after range / => :range range: :range: else)
|
|
||||||
(awk next-record-expr
|
|
||||||
(record field-id ...)
|
|
||||||
maybe-counter
|
|
||||||
((state-variable init-expr) ...)
|
|
||||||
maybe-continue
|
|
||||||
clause ...)
|
|
||||||
([maybe-counter code:blank
|
|
||||||
id]
|
|
||||||
[maybe-continue code:blank
|
|
||||||
id]
|
|
||||||
[clause (test body ...+)
|
|
||||||
(test => procedure-expr)
|
|
||||||
(/ regexp-str / (id-or-false ...+) body ...+)
|
|
||||||
(range excl-start-test excl-stop-test body ...+)
|
|
||||||
(:range incl-start-test excl-stop-test body ...+)
|
|
||||||
(range: excl-start-test incl-stop-test body ...+)
|
|
||||||
(:range: incl-start-test incl-stop-test body ...+)
|
|
||||||
(else body ...+)
|
|
||||||
(after body ...+)]
|
|
||||||
[test integer
|
|
||||||
regexp-string
|
|
||||||
expr]
|
|
||||||
[excl-start-test test]
|
|
||||||
[excl-stop-test test]
|
|
||||||
[incl-start-test test]
|
|
||||||
[incl-stop-test test]
|
|
||||||
[id-or-false id
|
|
||||||
#f])]{
|
|
||||||
|
|
||||||
The @racket[awk] macro from Scsh @cite["Shivers06"]. In addition to
|
|
||||||
@racket[awk], the Scsh-compatible procedures @racket[match:start],
|
|
||||||
@racket[match:end], @racket[match:substring], and @racket[regexp-exec]
|
|
||||||
are defined. These @racketidfont{match:} procedures must be used to
|
|
||||||
extract match information in a regular expression clause when using
|
|
||||||
the @racket[=>] form. }
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defproc[(match:start [rec ....]
|
|
||||||
[which exact-nonnegative-integer? 0])
|
|
||||||
exact-nonnegative-integer?]
|
|
||||||
@defproc[(match:end [rec ....]
|
|
||||||
[which exact-nonnegative-integer? 0])
|
|
||||||
exact-nonnegative-integer?]
|
|
||||||
@defproc[(match:substring
|
|
||||||
[rec ....]
|
|
||||||
[which exact-nonnegative-integer? 0])
|
|
||||||
string?]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Extracts a start position, end position, or substring corresponding to
|
|
||||||
a match. The first argument is the value supplied to the procedure
|
|
||||||
after @racket[=>] in a @racket[awk] clause or the result of
|
|
||||||
@racket[regexp-exec].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(regexp-exec [re (or/c string? regexp?)] [s string?])
|
|
||||||
(or/c .... false/c)]{
|
|
||||||
|
|
||||||
Matches a regexp to a string, returning a record compatible with
|
|
||||||
@racket[match:start], etc.}
|
|
|
@ -1,40 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/cmdline))
|
|
||||||
|
|
||||||
@(define-syntax-rule (intro id)
|
|
||||||
(begin
|
|
||||||
(require (for-label racket/cmdline))
|
|
||||||
(define id (racket command-line))))
|
|
||||||
@(intro racket-command-line)
|
|
||||||
|
|
||||||
@mzlib[#:mode title cmdline]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/cmdline]]{}
|
|
||||||
|
|
||||||
Provides a @racket[command-line] from that is similar to the one in
|
|
||||||
@racketmodname[racket/cmdline], but without using keywords. The
|
|
||||||
@racket[parse-command-line] procedure from
|
|
||||||
@racketmodname[racket/cmdline] is re-exported directly.
|
|
||||||
|
|
||||||
@defform/subs[
|
|
||||||
#:literals (multi once-each once-any final help-labels args =>)
|
|
||||||
(command-line program-name-expr argv-expr clause ...)
|
|
||||||
([clause (multi flag-spec ...)
|
|
||||||
(once-each flag-spec ...)
|
|
||||||
(once-any flag-spec ...)
|
|
||||||
(final flag-spec ...)
|
|
||||||
(help-labels string ...)
|
|
||||||
(args arg-formals body-expr ...+)
|
|
||||||
(=> finish-proc-expr arg-help-expr help-proc-expr
|
|
||||||
unknown-proc-expr)]
|
|
||||||
[flag-spec (flags id ... help-str ...+ body-expr ...+)
|
|
||||||
(flags => handler-expr help-expr)]
|
|
||||||
[flags flag-string
|
|
||||||
(flag-string ...+)]
|
|
||||||
[arg-formals id
|
|
||||||
(id ...)
|
|
||||||
(id ...+ . id)])]{
|
|
||||||
|
|
||||||
Like @racket-command-line from @racket[racket/cmdline], but without
|
|
||||||
keywords in the syntax.}
|
|
|
@ -1,45 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/cml))
|
|
||||||
|
|
||||||
@mzlib[#:mode title cml]
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/cml] library defines a number of procedures
|
|
||||||
that wrap Racket concurrency procedures. The wrapper procedures
|
|
||||||
have names and interfaces that more closely match those of Concurrent
|
|
||||||
ML @cite["Reppy99"].
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(spawn [thunk (-> any)]) thread?]{
|
|
||||||
|
|
||||||
Equivalent to @racket[(thread/suspend-to-kill thunk)].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(channel) channel?]{
|
|
||||||
|
|
||||||
Equivalent to @racket[(make-channel)].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(channel-recv-evt [ch channel?]) evt?]{
|
|
||||||
|
|
||||||
Equivalent to @racket[ch].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(channel-send-evt [ch channel?][v any/c]) evt?]{
|
|
||||||
|
|
||||||
Equivalent to @racket[(channel-put-evt ch v)].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(thread-done-evt [thd thread?]) any]{
|
|
||||||
|
|
||||||
Equivalent to @racket[(thread-dead-evt thread)].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(current-time) real?]{
|
|
||||||
|
|
||||||
Equivalent to @racket[(current-inexact-milliseconds)].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(time-evt [tm real?]) evt?]{
|
|
||||||
|
|
||||||
Equivalent to @racket[(alarm-evt tm)].}
|
|
|
@ -1,24 +0,0 @@
|
||||||
#lang scheme/base
|
|
||||||
|
|
||||||
(require (for-syntax scheme/base)
|
|
||||||
scribble/manual
|
|
||||||
(for-label mzscheme
|
|
||||||
(only-in scheme/base exn:fail exn:fail:unsupported exn:fail:contract)))
|
|
||||||
|
|
||||||
(provide mzlib
|
|
||||||
(all-from-out scribble/manual)
|
|
||||||
(for-label (all-from-out mzscheme)
|
|
||||||
(all-from-out scheme/base)))
|
|
||||||
|
|
||||||
(define-syntax (mzlib stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ #:mode section name #:use-sources (src ...))
|
|
||||||
(with-syntax ([lib (string->symbol
|
|
||||||
(format "mzlib/~a" (syntax-e #'name)))])
|
|
||||||
#'(begin
|
|
||||||
(section #:style 'hidden (racket lib))
|
|
||||||
(defmodule lib #:use-sources (src ...))))]
|
|
||||||
[(_ #:mode section name)
|
|
||||||
#'(mzlib #:mode section name #:use-sources ())]
|
|
||||||
[(_ name)
|
|
||||||
#'(mzlib #:mode section name #:use-sources ())]))
|
|
|
@ -1,98 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
scribble/eval
|
|
||||||
(for-label mzlib/compat))
|
|
||||||
|
|
||||||
@(define compat-eval (make-base-eval))
|
|
||||||
|
|
||||||
@interaction-eval[#:eval compat-eval (require mzlib/compat)]
|
|
||||||
|
|
||||||
@mzlib[#:mode title compat]
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/compat] library defines a number of
|
|
||||||
procedures and syntactic forms that are commonly provided by other
|
|
||||||
Scheme implementations. Most of the procedures are aliases for
|
|
||||||
@racketmodname[mzscheme] procedures.
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defproc[(=? [n number?] ...+) boolean?]
|
|
||||||
@defproc[(<? [n real?] ...+) boolean?]
|
|
||||||
@defproc[(>? [n real?] ...+) boolean?]
|
|
||||||
@defproc[(<=? [n real?] ...+) boolean?]
|
|
||||||
@defproc[(>=? [n real?] ...+) boolean?]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Same as @racket[=], @racket[<], etc.}
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defproc[(1+ [n number?]) number?]
|
|
||||||
@defproc[(1- [n number?]) number?]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Same as @racket[add1] and @racket[sub1].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(gentmp [base (or/c string? symbol?) "g"]) symbol?]{
|
|
||||||
|
|
||||||
Same as @racket[gensym].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(flush-output-port [o output-port? (current-output-port)]) void?]{
|
|
||||||
|
|
||||||
Same as @racket[flush-output].}
|
|
||||||
|
|
||||||
@defproc[(real-time) exact-integer?]{
|
|
||||||
|
|
||||||
Same as @racket[current-milliseconds].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(atom? [v any/c]) any]{
|
|
||||||
|
|
||||||
Same as @racket[(not (pair? v))] (which does not actually imply an
|
|
||||||
atomic value).}
|
|
||||||
|
|
||||||
|
|
||||||
@defform*[[(define-structure (name-id field-id ...))
|
|
||||||
(define-structure (name-id field-id ...)
|
|
||||||
((init-field-id init-expr) ...))]]{
|
|
||||||
|
|
||||||
Like @racket[define-struct], except that the @racket[name-id] is moved
|
|
||||||
inside the parenthesis for fields. In addition,
|
|
||||||
@racket[init-field-id]s can be specified with automatic initial-value
|
|
||||||
expression.
|
|
||||||
|
|
||||||
The @racket[init-field-id]s do not have corresponding arguments for
|
|
||||||
the @racketidfont{make-}@racket[name-id] constructor. Instead, each
|
|
||||||
@racket[init-field-id]'s @racket[init-expr] is evaluated to obtain the
|
|
||||||
field's value when the constructor is called. The @racket[field-id]s
|
|
||||||
are bound in @racket[init-expr]s, but not other
|
|
||||||
@racket[init-field-id]s.
|
|
||||||
|
|
||||||
@examples[
|
|
||||||
#:eval compat-eval
|
|
||||||
(define-structure (add left right) ([sum (+ left right)]))
|
|
||||||
(add-sum (make-add 3 6))
|
|
||||||
]}
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defproc[(getprop [sym symbol?][property symbol?][default any/c #f]) any/c]
|
|
||||||
@defproc[(putprop [sym symbol?][property symbol?][value any/c]) void?]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
The @racket[getprop] function gets a property value associated with
|
|
||||||
@racket[sym]. The @racket[property] argument names the property to be
|
|
||||||
found. If the property is not found, @racket[default] is returned.
|
|
||||||
|
|
||||||
The properties obtained with @racket[getprop] are the ones installed
|
|
||||||
with @racket[putprop].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(new-cafe [eval-handler (any/c . -> . any) #f]) any]{
|
|
||||||
|
|
||||||
Emulates Chez Scheme's @racket[new-cafe] by installing
|
|
||||||
@racket[eval-handler] into the @racket[current-eval] parameter while
|
|
||||||
running @racket[read-eval-print]. In addition, @racket[current-exit]
|
|
||||||
is set to escape from the call to @racket[new-cafe].}
|
|
||||||
|
|
||||||
|
|
||||||
@close-eval[compat-eval]
|
|
|
@ -1,7 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label compiler/compile-file))
|
|
||||||
|
|
||||||
@mzlib[#:mode title compile]
|
|
||||||
|
|
||||||
Re-exports @racket[compile-file] from @racketmodname[compiler/compile-file].
|
|
|
@ -1,13 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require (for-label racket/contract)
|
|
||||||
scribble/manual)
|
|
||||||
(provide (all-defined-out))
|
|
||||||
|
|
||||||
;; this file establishes the right for-label
|
|
||||||
;; bindings so that I can link to racket/contract
|
|
||||||
;; combinators in the mzlib/contract docs
|
|
||||||
|
|
||||||
(define r:-> (racket ->))
|
|
||||||
(define r:->* (racket ->*))
|
|
||||||
(define r:->i (racket ->i))
|
|
||||||
(define r:->d (racket ->d))
|
|
|
@ -1,294 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
scribble/struct
|
|
||||||
"contract-label.rkt"
|
|
||||||
(for-label mzlib/contract)
|
|
||||||
(for-label (prefix-in r: racket/contract)))
|
|
||||||
|
|
||||||
@(define-syntax-rule (twocolumns id ...)
|
|
||||||
(*twocolumns (list (racket id) ...)))
|
|
||||||
@(define (*twocolumns uneven-l)
|
|
||||||
(let* ([l (if (zero? (modulo (length uneven-l) 2)) uneven-l (append uneven-l (list #f)))]
|
|
||||||
[len (length l)]
|
|
||||||
[half (quotient len 2)]
|
|
||||||
[a (for/list ([i (in-range half)]
|
|
||||||
[e l])
|
|
||||||
e)]
|
|
||||||
[b (list-tail l half)]
|
|
||||||
[spacer (hspace 2)]
|
|
||||||
[to-flow (compose make-flow list make-paragraph list)])
|
|
||||||
(make-table #f
|
|
||||||
(map (lambda (a b)
|
|
||||||
(list (to-flow spacer)
|
|
||||||
(to-flow a)
|
|
||||||
(to-flow spacer)
|
|
||||||
(to-flow (or b ""))))
|
|
||||||
a b))))
|
|
||||||
|
|
||||||
@mzlib[#:mode title contract]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/contract]]{
|
|
||||||
This library is designed as a backwards compatible library
|
|
||||||
for old uses of contracts. It should not be used for new
|
|
||||||
libraries.
|
|
||||||
}
|
|
||||||
|
|
||||||
The main differences: the function contract syntax is more
|
|
||||||
regular and function contracts now support keywords, and
|
|
||||||
@tt{union} is now @racket[or/c].
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/contract] library re-exports many bindings
|
|
||||||
from @racketmodname[racket/contract]:
|
|
||||||
|
|
||||||
@twocolumns[
|
|
||||||
</c
|
|
||||||
<=/c
|
|
||||||
=/c
|
|
||||||
>/c
|
|
||||||
>=/c
|
|
||||||
and/c
|
|
||||||
any
|
|
||||||
any/c
|
|
||||||
between/c
|
|
||||||
box-immutable/c
|
|
||||||
build-compound-type-name
|
|
||||||
coerce-contract
|
|
||||||
cons/c
|
|
||||||
contract
|
|
||||||
contract-first-order-passes?
|
|
||||||
contract-violation->string
|
|
||||||
contract?
|
|
||||||
define-contract-struct
|
|
||||||
false/c
|
|
||||||
flat-contract
|
|
||||||
flat-contract-predicate
|
|
||||||
flat-contract?
|
|
||||||
flat-murec-contract
|
|
||||||
flat-named-contract
|
|
||||||
flat-rec-contract
|
|
||||||
guilty-party
|
|
||||||
integer-in
|
|
||||||
list/c
|
|
||||||
listof
|
|
||||||
make-none/c
|
|
||||||
make-proj-contract
|
|
||||||
natural-number/c
|
|
||||||
none/c
|
|
||||||
not/c
|
|
||||||
one-of/c
|
|
||||||
or/c
|
|
||||||
parameter/c
|
|
||||||
printable/c
|
|
||||||
promise/c
|
|
||||||
provide/contract
|
|
||||||
raise-contract-error
|
|
||||||
real-in
|
|
||||||
recursive-contract
|
|
||||||
string/len
|
|
||||||
symbols
|
|
||||||
syntax/c
|
|
||||||
vector-immutable/c
|
|
||||||
vector-immutableof]
|
|
||||||
|
|
||||||
It also provides the old version of the following contracts:
|
|
||||||
|
|
||||||
@defform[(define/contract id contract-expr init-value-expr)]{
|
|
||||||
|
|
||||||
Attaches the contract @racket[contract-expr] to
|
|
||||||
@racket[init-value-expr] and binds that to @racket[id].
|
|
||||||
|
|
||||||
The @racket[define/contract] form treats individual definitions as
|
|
||||||
units of blame. The definition itself is responsible for positive
|
|
||||||
(co-variant) positions of the contract and each reference to
|
|
||||||
@racket[id] (including those in the initial value expression) must
|
|
||||||
meet the negative positions of the contract.
|
|
||||||
|
|
||||||
Error messages with @racket[define/contract] are not as clear as those
|
|
||||||
provided by @racket[provide/contract], because
|
|
||||||
@racket[define/contract] cannot detect the name of the definition
|
|
||||||
where the reference to the defined variable occurs. Instead, it uses
|
|
||||||
the source location of the reference to the variable as the name of
|
|
||||||
that definition.}
|
|
||||||
|
|
||||||
@defproc[(box/c [c flat-contract?]) flat-contract?]{
|
|
||||||
|
|
||||||
Returns a flat contract that recognizes boxes. The content of the box
|
|
||||||
must match @racket[c].}
|
|
||||||
|
|
||||||
@defproc[(vectorof [c flat-contract?]) flat-contract?]{
|
|
||||||
|
|
||||||
Accepts a flat contract and returns a flat contract
|
|
||||||
that checks for vectors whose elements match the original contract.}
|
|
||||||
|
|
||||||
@defproc[(vector/c [c flat-contract?] ...) flat-contract?]{
|
|
||||||
|
|
||||||
Accepts any number of flat contracts and returns a
|
|
||||||
flat contract that recognizes vectors. The number of elements in the
|
|
||||||
vector must match the number of arguments supplied to
|
|
||||||
@racket[vector/c], and each element of the vector must match the
|
|
||||||
corresponding flat contract.}
|
|
||||||
|
|
||||||
@defform[(struct/c struct-id flat-contract-expr ...)]{
|
|
||||||
|
|
||||||
Produces a flat contract that recognizes instances of the structure
|
|
||||||
type named by @racket[struct-id], and whose field values match the
|
|
||||||
flat contracts produced by the @racket[flat-contract-expr]s.}
|
|
||||||
|
|
||||||
@defproc[(build-flat-contract [name symbol?] [predicate (-> any/c any)]) flat-contract?]{
|
|
||||||
Builds a flat contract out of @racket[predicate], giving it the name
|
|
||||||
@racket[name]. Nowadays, just using @racket[predicate] directly is preferred.
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform*[((-> contract-dom-expr ... any)
|
|
||||||
(-> contract-dom-expr ... contract-rng-expr))]{
|
|
||||||
This is a restricted form of @racketmodname[racket/contract]'s
|
|
||||||
@r:-> contract that does not
|
|
||||||
handle keyword arguments or multiple
|
|
||||||
value results.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform*/subs[((->* (contract-dom-expr ...) ->*rng)
|
|
||||||
(->* (contract-dom-expr ...) contract-rest-expr ->*rng))
|
|
||||||
([->*rng (contract-rng-expr ...)
|
|
||||||
any])]{
|
|
||||||
The @racket[->*] form matches up to
|
|
||||||
@racketmodname[racket/contract]'s @r:-> and @r:->*, according
|
|
||||||
to the following rules; each equation on the
|
|
||||||
left refers to a @racketmodname[mzlib/contract] combinator;
|
|
||||||
on the right are the @racketmodname[racket/contract] equivalents.
|
|
||||||
@racketblock[(->* (contract-dom-expr ...) any) =
|
|
||||||
(#,r:-> contract-dom-expr ... any)]
|
|
||||||
@racketblock[(->* (contract-dom-expr ...) (contract-rng-expr ...)) =
|
|
||||||
(#,r:-> contract-dom-expr ... (values contract-rng-expr))]
|
|
||||||
@racketblock[(->* (contract-expr ...) contract-rest-expr any) =
|
|
||||||
(#,r:->* (contract-expr ...) #:rest contract-rest-expr any)]
|
|
||||||
@racketblock[(->* (contract-expr ...) contract-rest-expr (contract-rng-expr ...)) =
|
|
||||||
(#,r:->* (contract-expr ...)
|
|
||||||
#:rest contract-rest-expr
|
|
||||||
(values contract-rng-expr ...))]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform*[((opt-> (contract-req-expr ...) (contact-opt-expr ...) any)
|
|
||||||
(opt-> (contract-req-expr ...) (contact-opt-expr ...) contract-rng-expr))]{
|
|
||||||
|
|
||||||
The @racket[opt->] form is a simplified verison of @racketmodname[racket/contract]'s
|
|
||||||
@|r:->*| and appearances of @racket[opt->] can be simply replaced with @|r:->*|.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform*[((opt->* (contract-req-expr ...) (contact-opt-expr ...) any)
|
|
||||||
(opt->* (contract-req-expr ...) (contact-opt-expr ...) (contract-rng-expr ...)))]{
|
|
||||||
|
|
||||||
The @racket[opt->*] form matches up to
|
|
||||||
@racketmodname[racket/contract]'s @r:->*, according
|
|
||||||
to the following rules; each equation on the
|
|
||||||
left refers to a @racketmodname[mzlib/contract] combinator;
|
|
||||||
on the right are the @racketmodname[racket/contract] equivalents.
|
|
||||||
|
|
||||||
@racketblock[(opt->* (contract-req-expr ...) (contract-opt-expr ...) any) =
|
|
||||||
(#,r:->* (contract-req-expr ...) (contract-opt-expr ...) any)]
|
|
||||||
|
|
||||||
@racketblock[(opt->* (contract-req-expr ...)
|
|
||||||
(contract-opt-expr ...)
|
|
||||||
(contract-rng-expr ...)) =
|
|
||||||
(#,r:->* (contract-req-expr ...)
|
|
||||||
(contract-opt-expr ...)
|
|
||||||
(values contract-rng-expr ...))]
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform[(->d contract-dom-expr ... contract-rng-fun-expr)]{
|
|
||||||
The @racket[->d] contract constructor is just like @racket[->],
|
|
||||||
except that the range position is expected to be a function
|
|
||||||
that accepts the actual arguments passed to the function,
|
|
||||||
and returns a contract for the range. For example, this
|
|
||||||
is one contract for @racket[sqrt]:
|
|
||||||
@racketblock[(->d real?
|
|
||||||
(λ (in)
|
|
||||||
(and/c real?
|
|
||||||
(λ (out)
|
|
||||||
(< (abs (- (sqr out) in))
|
|
||||||
0.01)))))]
|
|
||||||
It says that the input must be a real number, and so must the
|
|
||||||
result, and that the square of the result is within
|
|
||||||
@racket[0.01] of input.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform*[((->d* (contract-dom-expr ...) contract-rng-fun-expr)
|
|
||||||
(->d* (contract-dom-expr ...) contract-rest-expr contract-rng-fun-expr))]{
|
|
||||||
The @racket[->d*] contract constructor is a generalization of
|
|
||||||
@racket[->d] to support multiple values and rest arguments.
|
|
||||||
|
|
||||||
In the two sub-expression case, the first sequence of contracts
|
|
||||||
are contracts on the domain of the function and the second
|
|
||||||
subexpression is expected to evaluate to a function that accepts
|
|
||||||
as many arguments as there are expressions in the first position.
|
|
||||||
It should return multiple values: one contract for each result
|
|
||||||
of the function.
|
|
||||||
|
|
||||||
In the three sub-expression case, the first and last subexpressions
|
|
||||||
are just like the sub-expressions in the two sub-expression case;
|
|
||||||
the middle sub-expression si expected to evaluate to a contract on
|
|
||||||
the rest argument.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform*/subs[((->r ([dom-x contract-dom-expr] ...) rng)
|
|
||||||
(->r ([dom-x contract-dom-expr] ...) rest-x contract-rest-expr rng))
|
|
||||||
((rng any
|
|
||||||
(values contract-expr ...)
|
|
||||||
contract-expr))]{
|
|
||||||
|
|
||||||
The @racket[->r] form is a simplified version of @racketmodname[racket/contract]'s @|r:->i|, where
|
|
||||||
each @racket[contract-dom-expr] is parameterized over all of the @racket[dom-x] variables
|
|
||||||
(and does lax checking; see @r:->d for details).
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform*[((->pp ([dom-x contract-dom-expr] ...) pre-cond-expr any)
|
|
||||||
(->pp ([dom-x contract-dom-expr] ...)
|
|
||||||
pre-cond-expr
|
|
||||||
(values [rng-x contract-rng-expr] ...)
|
|
||||||
post-cond-expr)
|
|
||||||
(->pp ([dom-x contract-dom-expr] ...)
|
|
||||||
pre-cond-expr
|
|
||||||
contract-rng-expr
|
|
||||||
rng-x
|
|
||||||
post-cond-expr))]{
|
|
||||||
|
|
||||||
The @racket[->pp] form, like @racket[->r] is a simplified version of @racketmodname[racket/contract]'s @|r:->i|, where
|
|
||||||
each @racket[contract-dom-expr] is parameterized over all of the @racket[dom-x] variables
|
|
||||||
(and does lax checking; see @racketmodname[racket/contract]'s @r:->d for details). Unlike @racket[->r], it also has pre- and post-condition
|
|
||||||
expressions; these expressions are also implicitly parameterized over all of the @racket[dom-x]
|
|
||||||
variables and the post-condition is also paramterized over @racket[rng-x], which is bound to the result
|
|
||||||
of the function.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform*[((->pp-rest ([dom-x contract-dom-expr] ...) rest-x rest-contract-expr pre-cond-expr any)
|
|
||||||
(->pp-rest ([dom-x contract-dom-expr] ...)
|
|
||||||
rest-x rest-contract-expr
|
|
||||||
pre-cond-expr
|
|
||||||
(values [rng-x contract-rng-expr] ...)
|
|
||||||
post-cond-expr)
|
|
||||||
(->pp-rest ([dom-x contract-dom-expr] ...)
|
|
||||||
rest-x rest-contract-expr
|
|
||||||
pre-cond-expr
|
|
||||||
contract-rng-expr
|
|
||||||
rng-x
|
|
||||||
post-cond-expr))]{
|
|
||||||
Like @racket[->pp], but with an additional contract for the rest arguments of the function.
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform[(case-> mzlib/contract-arrow-contract-expr ...)]{
|
|
||||||
Builds a contract analogous to @racket[case-lambda],
|
|
||||||
where each case comes from one of the contract expression arguments
|
|
||||||
(tried in order).
|
|
||||||
}
|
|
||||||
|
|
||||||
@defform[(object-contract [id mzlib/contract-arrow-contract-expr] ...)]{
|
|
||||||
Builds a contract for objects where each @racket[id] is expected to be
|
|
||||||
a method on the object living up to the corresponding contract
|
|
||||||
}
|
|
|
@ -1,274 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
scribble/eval
|
|
||||||
(for-label mzlib/etc
|
|
||||||
scheme/bool
|
|
||||||
scheme/local
|
|
||||||
setup/dirs
|
|
||||||
racket/block
|
|
||||||
(only-in scheme build-list build-string build-vector
|
|
||||||
symbol=?)))
|
|
||||||
|
|
||||||
@(define etc-eval (make-base-eval))
|
|
||||||
@interaction-eval[#:eval etc-eval (require mzlib/etc)]
|
|
||||||
|
|
||||||
@(begin
|
|
||||||
(define-syntax-rule (bind id else-id)
|
|
||||||
(begin
|
|
||||||
(require (for-label scheme/base))
|
|
||||||
(define id (racket lambda))
|
|
||||||
(define else-id (racket else))))
|
|
||||||
(bind base-lambda base-else))
|
|
||||||
|
|
||||||
@mzlib[#:mode title etc]
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/etc] library re-exports the following from
|
|
||||||
@racketmodname[scheme/base] and other libraries:
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
boolean=?
|
|
||||||
true
|
|
||||||
false
|
|
||||||
build-list
|
|
||||||
build-string
|
|
||||||
build-vector
|
|
||||||
compose
|
|
||||||
local
|
|
||||||
symbol=?
|
|
||||||
nand
|
|
||||||
nor
|
|
||||||
]
|
|
||||||
|
|
||||||
@defform[(begin-lifted expr ...+)]
|
|
||||||
|
|
||||||
Lifts the @racket[expr]s so that they are evaluated once at the ``top
|
|
||||||
level'' of the current context, and the result of the last
|
|
||||||
@racket[expr] is used for every evaluation of the
|
|
||||||
@racket[begin-lifted] form.
|
|
||||||
|
|
||||||
When this form is used as a run-time expression within a module, the
|
|
||||||
``top level'' corresponds to the module's top level, so that each
|
|
||||||
@racket[expr] is evaluated once for each invocation of the
|
|
||||||
module. When it is used as a run-time expression outside of a module,
|
|
||||||
the ``top level'' corresponds to the true top level. When this form is
|
|
||||||
used in a @racket[define-syntax], @racket[letrec-syntax],
|
|
||||||
etc. binding, the ``top level'' corresponds to the beginning of the
|
|
||||||
binding's right-hand side. Other forms may redefine ``top level''
|
|
||||||
(using @racket[local-expand/capture-lifts]) for the expressions that
|
|
||||||
they enclose.
|
|
||||||
|
|
||||||
@defform[(begin-with-definitions defn-or-expr ...)]{
|
|
||||||
|
|
||||||
The same as @racket[(block defn-or-expr ...)].}
|
|
||||||
|
|
||||||
@defform[(define-syntax-set (id ...) defn ...)]{
|
|
||||||
|
|
||||||
Similar to @racket[define-syntaxes], but instead of a single body
|
|
||||||
expression, a sequence of definitions follows the sequence of defined
|
|
||||||
identifiers. For each @racket[identifier], the @racket[defn]s should
|
|
||||||
include a definition for @racket[id]@racketidfont{/proc}. The value
|
|
||||||
for @racket[id]@racketidfont{/proc} is used as the (expansion-time)
|
|
||||||
value for @racket[id].
|
|
||||||
|
|
||||||
The @racket[define-syntax-set] form is useful for defining a set of
|
|
||||||
syntax transformers that share helper functions, though
|
|
||||||
@racket[begin-for-syntax] now serves essentially the same purposes.
|
|
||||||
|
|
||||||
@as-examples[
|
|
||||||
@racketblock[
|
|
||||||
(define-syntax-set (let-current-continuation
|
|
||||||
let-current-escape-continuation)
|
|
||||||
(define (mk call-id)
|
|
||||||
(lambda (stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ id body1 body ...)
|
|
||||||
(with-syntax ([call call-id])
|
|
||||||
(syntax (call (lambda (id) body1 body ...))))])))
|
|
||||||
(define let-current-continuation/proc
|
|
||||||
(mk (quote-syntax call/cc)))
|
|
||||||
(define let-current-escape-continuation/proc
|
|
||||||
(mk (quote-syntax call/ec))))
|
|
||||||
]]}
|
|
||||||
|
|
||||||
|
|
||||||
@defform*[#:literals (else)
|
|
||||||
[(evcase key-expr (value-expr body-expr ...) ...+)
|
|
||||||
(evcase key-expr (value-expr body-expr ...) ... [else body-expr ...])]]{
|
|
||||||
|
|
||||||
The @racket[evcase] form is similar to @racket[case], except that
|
|
||||||
expressions are provided in each clause instead of a sequence of
|
|
||||||
data. After @racket[key-expr] is evaluated, each @racket[value-expr]
|
|
||||||
is evaluated until a value is found that is @racket[eqv?] to the key
|
|
||||||
value; when a matching value is found, the corresponding
|
|
||||||
@racket[body-expr]s are evaluated and the value(s) for the last is the
|
|
||||||
result of the entire @racket[evcase] expression.
|
|
||||||
|
|
||||||
The @racket[else] literal is recognized either as unbound (like in the
|
|
||||||
@racketmodname[mzscheme] language) or bound as @|base-else| from
|
|
||||||
@racketmodname[scheme/base].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(identity [v any/c]) any/c]{
|
|
||||||
|
|
||||||
Returns @racket[v].}
|
|
||||||
|
|
||||||
|
|
||||||
@defform/subs[#:literals (val rec vals recs _ values)
|
|
||||||
(let+ clause body-expr ...+)
|
|
||||||
([clause (val target expr)
|
|
||||||
(rec target expr)
|
|
||||||
(vals (target ...) expr)
|
|
||||||
(recs (target expr) ...)
|
|
||||||
(_ expr ...)]
|
|
||||||
[target id
|
|
||||||
(values id ...)])]{
|
|
||||||
|
|
||||||
A binding construct that specifies scoping on a per-binding basis
|
|
||||||
instead of a per-expression basis. It helps eliminate rightward-drift
|
|
||||||
in programs. It looks similar to @racket[let], except each clause has
|
|
||||||
an additional keyword tag before the binding variables.
|
|
||||||
|
|
||||||
Each @racket[clause] has one of the following forms:
|
|
||||||
|
|
||||||
@itemize[
|
|
||||||
|
|
||||||
@item{@racket[(val target expr)] : Binds @racket[target]
|
|
||||||
non-recursively to @racket[expr].}
|
|
||||||
|
|
||||||
@item{@racket[(rec target expr)] : Binds @racket[target] recursively to
|
|
||||||
@racket[expr].}
|
|
||||||
|
|
||||||
@item{@racket[(vals (target expr) ...)] : The @racket[target]s are
|
|
||||||
bound to the @racket[expr]s. The environment of the @racket[expr]s is
|
|
||||||
the environment active before this clause.}
|
|
||||||
|
|
||||||
@item{@racket[(recs (target expr) ...)] : The @racket[targets]s are
|
|
||||||
bound to the @racket[expr]s. The environment of the @racket[expr]s
|
|
||||||
includes all of the @racket[targets]s.}
|
|
||||||
|
|
||||||
@item{@racket[(_ expr ...)] : Evaluates the @racket[expr]s without
|
|
||||||
binding any variables.}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
The clauses bind left-to-right. When a @racket[target] is
|
|
||||||
@racket[(values id ...)], multiple values returned by the
|
|
||||||
corresponding expression are bound to the multiple variables.
|
|
||||||
|
|
||||||
@examples[
|
|
||||||
#:eval etc-eval
|
|
||||||
(let+ ([val (values x y) (values 1 2)])
|
|
||||||
(list x y))
|
|
||||||
|
|
||||||
(let ([x 1])
|
|
||||||
(let+ ([val x 3]
|
|
||||||
[val y x])
|
|
||||||
y))
|
|
||||||
]}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(loop-until [start any/c] [done? (any/c . -> . any)]
|
|
||||||
[next (any/c . -> . any/c)]
|
|
||||||
[f (any/c . -> . any)])
|
|
||||||
void?]{
|
|
||||||
|
|
||||||
Repeatedly invokes the @racket[f] procedure until the @racket[done?]
|
|
||||||
procedure returns @racket[#t]:
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
(define (loop-until start done? next f)
|
|
||||||
(let loop ([i start])
|
|
||||||
(unless (done? i)
|
|
||||||
(f i)
|
|
||||||
(loop (next i)))))
|
|
||||||
]}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(namespace-defined? [sym symbol?]) boolean?]{
|
|
||||||
|
|
||||||
Returns @racket[#t] if @racket[namespace-variable-value] would return
|
|
||||||
a value for @racket[sym], @racket[#f] otherwise.}
|
|
||||||
|
|
||||||
|
|
||||||
@defform[(nand expr ...)]{
|
|
||||||
|
|
||||||
Same as @racket[(not (and expr ...))].}
|
|
||||||
|
|
||||||
|
|
||||||
@defform[(nor expr ...)]{
|
|
||||||
|
|
||||||
Same as @racket[(not (or expr ...))].}
|
|
||||||
|
|
||||||
|
|
||||||
@defform[(opt-lambda formals body ...+)]{
|
|
||||||
|
|
||||||
Supports optional (but not keyword) arguments like @base-lambda from
|
|
||||||
@racket[scheme/base].}
|
|
||||||
|
|
||||||
|
|
||||||
@defform[(recur id bindings body ...+)]{
|
|
||||||
|
|
||||||
Equivalent to @racket[(let id bindings body ...+)].}
|
|
||||||
|
|
||||||
|
|
||||||
@defform*[[(rec id value-expr)
|
|
||||||
(rec (id arg-id ...) expr)
|
|
||||||
(rec (id arg-id ... . rest-id) expr)]]{
|
|
||||||
|
|
||||||
Equivalent, respectively, to
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
(letrec ([id value-expr]) id)
|
|
||||||
(letrec ([id (lambda (arg-id ...) value-expr)]) id)
|
|
||||||
(letrec ([id (lambda (arg-id ... . rest-id) value-expr)]) id)
|
|
||||||
]}
|
|
||||||
|
|
||||||
|
|
||||||
@defform*[[(this-expression-source-directory)
|
|
||||||
(this-expression-source-directory datum)]]{
|
|
||||||
|
|
||||||
@margin-note{See @racketmodname[scheme/runtime-path] for a definition form
|
|
||||||
that works better when creating executables.}
|
|
||||||
|
|
||||||
Expands to an expression that evaluates to the directory of the file
|
|
||||||
containing the source @racket[datum]. If @racket[datum] is not
|
|
||||||
supplied, then the entire @racket[(this-expression-source-directory)]
|
|
||||||
expression is used as @racket[datum].
|
|
||||||
|
|
||||||
If @racket[datum] has a source module, then the expansion attempts to
|
|
||||||
determine the module's run-time location. This location is determined
|
|
||||||
by preserving the lexical context of @racket[datum] in a syntax
|
|
||||||
object, extracting its source module path at run time, and then
|
|
||||||
resolving the module path.
|
|
||||||
|
|
||||||
Otherwise, @racket[datum]'s source file is determined through source
|
|
||||||
location information associated with @racket[datum], if it is
|
|
||||||
present. As a last resort, @racket[current-load-relative-directory] is
|
|
||||||
used if it is not @racket[#f], and @racket[current-directory] is used
|
|
||||||
if all else fails.
|
|
||||||
|
|
||||||
A directory path derived from source location is always stored in
|
|
||||||
bytes in the expanded code, unless the file is within the result of
|
|
||||||
@racket[find-collects-dir], in which case the expansion records the
|
|
||||||
path relative to @racket[(find-collects-dir)] and then reconstructs it
|
|
||||||
using @racket[(find-collects-dir)] at run time.}
|
|
||||||
|
|
||||||
|
|
||||||
@defform*[[(this-expression-file-name)
|
|
||||||
(this-expression-file-name datum)]]{
|
|
||||||
|
|
||||||
Similar to @racket[this-expression-source-directory], except that only
|
|
||||||
source information associated with @racket[datum] or
|
|
||||||
@racket[(this-expression-file-name)] is used to extract a filename. If
|
|
||||||
no filename is available, the result is @racket[#f].}
|
|
||||||
|
|
||||||
|
|
||||||
@defform[#:literals (quote unsyntax scheme)
|
|
||||||
(hash-table (#,(racket quote) flag) ... (key-expr val-expr) ...)]{
|
|
||||||
|
|
||||||
Creates a new hash-table providing the quoted flags (if any) to
|
|
||||||
@racket[make-hash-table], and then mapping each key to the
|
|
||||||
corresponding values.}
|
|
||||||
|
|
||||||
|
|
||||||
@close-eval[etc-eval]
|
|
|
@ -1,66 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/file
|
|
||||||
scheme/contract))
|
|
||||||
|
|
||||||
|
|
||||||
@mzlib[#:mode title file]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/file]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/file] library mostly re-exports from
|
|
||||||
@racketmodname[scheme/file]:
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
find-relative-path
|
|
||||||
explode-path
|
|
||||||
normalize-path
|
|
||||||
filename-extension
|
|
||||||
file-name-from-path
|
|
||||||
path-only
|
|
||||||
delete-directory/files
|
|
||||||
copy-directory/files
|
|
||||||
make-directory*
|
|
||||||
make-temporary-file
|
|
||||||
get-preference
|
|
||||||
put-preferences
|
|
||||||
fold-files
|
|
||||||
find-files
|
|
||||||
pathlist-closure
|
|
||||||
]
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defproc[(call-with-input-file* [file path-string?]
|
|
||||||
[proc (input-port? -> any)]
|
|
||||||
[mode (one-of/c 'text 'binary) 'binary])
|
|
||||||
any]
|
|
||||||
@defproc[(call-with-output-file* [file path-string?]
|
|
||||||
[proc (output-port? -> any)]
|
|
||||||
[mode (one-of/c 'text 'binary) 'binary]
|
|
||||||
[exists (one-of/c 'error 'append 'update
|
|
||||||
'replace 'truncate 'truncate/replace) 'error])
|
|
||||||
any]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Like @racket[call-with-input-file]and @racket[call-with-output-file],
|
|
||||||
except that the opened port is closed if control escapes from the body
|
|
||||||
of @racket[proc].}
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defproc[(build-relative-path [base (or/c path-string?
|
|
||||||
(one-of/c 'up 'same))]
|
|
||||||
[sub (or/c (and/c path-string?
|
|
||||||
relative-path?)
|
|
||||||
(one-of/c 'up 'same))] ...)
|
|
||||||
(and/c path? relative-path?)]
|
|
||||||
@defproc[(build-absolute-path [base (or/c (and/c path-string?
|
|
||||||
(not/c relative-path?))
|
|
||||||
(one-of/c 'up 'same))]
|
|
||||||
[sub (or/c (and/c path-string?
|
|
||||||
(not/c complete-path?))
|
|
||||||
(one-of/c 'up 'same))] ...)
|
|
||||||
(and/c path? absolute-path?)]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Like @racket[build-path], but with extra constraints to ensure a
|
|
||||||
relative or absolute result.}
|
|
|
@ -1,47 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/for))
|
|
||||||
|
|
||||||
@mzlib[#:mode title for]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/base]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/for] library re-exports from
|
|
||||||
@racketmodname[scheme/base]:
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
for/fold for*/fold
|
|
||||||
for for*
|
|
||||||
for/list for*/list
|
|
||||||
for/lists for*/lists
|
|
||||||
for/and for*/and
|
|
||||||
for/or for*/or
|
|
||||||
for/first for*/first
|
|
||||||
for/last for*/last
|
|
||||||
|
|
||||||
for/fold/derived for*/fold/derived
|
|
||||||
|
|
||||||
in-range
|
|
||||||
in-naturals
|
|
||||||
in-list
|
|
||||||
in-vector
|
|
||||||
in-string
|
|
||||||
in-bytes
|
|
||||||
in-input-port-bytes
|
|
||||||
in-input-port-chars
|
|
||||||
in-hash-table
|
|
||||||
in-hash-table-keys
|
|
||||||
in-hash-table-values
|
|
||||||
in-hash-table-pairs
|
|
||||||
|
|
||||||
in-parallel
|
|
||||||
stop-before
|
|
||||||
stop-after
|
|
||||||
in-indexed
|
|
||||||
|
|
||||||
sequence?
|
|
||||||
sequence-generate
|
|
||||||
|
|
||||||
define-sequence-syntax
|
|
||||||
make-do-sequence
|
|
||||||
:do-in]
|
|
|
@ -1,70 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/include))
|
|
||||||
|
|
||||||
@mzlib[#:mode title include]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/include]]{}
|
|
||||||
|
|
||||||
Similar to @racketmodname[scheme/include], but with a different syntax
|
|
||||||
for paths.
|
|
||||||
|
|
||||||
@defform/subs[#:literals (build-path lib up same)
|
|
||||||
(include path-spec)
|
|
||||||
([path-spec string
|
|
||||||
(build-path elem ...+)
|
|
||||||
(lib file-string collection-string ...)]
|
|
||||||
[elem string
|
|
||||||
up
|
|
||||||
same])]{
|
|
||||||
|
|
||||||
Inlines the syntax in the designated file in place of the
|
|
||||||
@racket[include] expression. The @racket[path-spec] can be any of the
|
|
||||||
following:
|
|
||||||
|
|
||||||
@itemize[
|
|
||||||
|
|
||||||
@item{A literal string that specifies a path to include, parsed
|
|
||||||
according to the platform's conventions (which means that it is
|
|
||||||
not portable).}
|
|
||||||
|
|
||||||
@item{A path construction of the form @racket[(build-path elem
|
|
||||||
...+)], where @racket[build-path] is
|
|
||||||
@racket[module-identifier=?] either to the @racket[build-path]
|
|
||||||
export from @racket[mzscheme] or to the top-level
|
|
||||||
@racket[build-path], and where each @racket[elem] is a path
|
|
||||||
string, @racket[up] (unquoted), or @racket[same] (unquoted).
|
|
||||||
The @racket[elem]s are combined in the same way as for the
|
|
||||||
@racket[build-path] function to obtain the path to include.}
|
|
||||||
|
|
||||||
@item{A path construction of the form @racket[(lib file-string
|
|
||||||
collection-string ...)], where @racket[lib] is free or refers
|
|
||||||
to a top-level @racket[lib] variable. The
|
|
||||||
@racket[collection-string]s are passed to
|
|
||||||
@racket[collection-path] to obtain a directory; if no
|
|
||||||
@racket[collection-strings]s are supplied, @racket["mzlib"] is
|
|
||||||
used. The @racket[file-string] is then appended to the
|
|
||||||
directory using @racket[build-path] to obtain the path to
|
|
||||||
include.}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
If @racket[path-spec] specifies a relative path to include, the path
|
|
||||||
is resolved relative to the source for the @racket[include]
|
|
||||||
expression, if that source is a complete path string. If the source is
|
|
||||||
not a complete path string, then @racket[path-spec] is resolved
|
|
||||||
relative to the current load relative directory if one is available,
|
|
||||||
or to the current directory otherwise.
|
|
||||||
|
|
||||||
The included syntax is given the lexical context of the
|
|
||||||
@racket[include] expression.}
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defform[(include-at/relative-to context source path-spec)]
|
|
||||||
@defform[(include-at/relative-to/reader context source path-spec reader-expr)]
|
|
||||||
@defform[(include/reader path-spec reader-expr)]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Variants of @racket[include] analogous to the variants of
|
|
||||||
@racketmodname[scheme/include].}
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
#lang info
|
|
||||||
|
|
||||||
(define scribblings '(("mzlib.scrbl" (multi-page) (legacy))))
|
|
|
@ -1,13 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label data/integer-set
|
|
||||||
mzlib/integer-set))
|
|
||||||
|
|
||||||
@mzlib[#:mode title integer-set]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[data/integer-set]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/integer-set] library re-exports bindings
|
|
||||||
from @racketmodname[data/integer-set] except that it renames
|
|
||||||
@racket[symmetric-difference] to @racket[xor], @racket[subtract]
|
|
||||||
to @racket[difference], and @racket[count] to @racket[card].
|
|
|
@ -1,452 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
scribble/eval
|
|
||||||
(for-label mzlib/kw
|
|
||||||
mzlib/etc))
|
|
||||||
|
|
||||||
@(define kw-eval (make-base-eval))
|
|
||||||
|
|
||||||
@interaction-eval[#:eval kw-eval (require mzscheme)]
|
|
||||||
@interaction-eval[#:eval kw-eval (require mzlib/kw)]
|
|
||||||
|
|
||||||
@(begin
|
|
||||||
(define-syntax-rule (bind id)
|
|
||||||
(begin
|
|
||||||
(require (for-label scheme/base))
|
|
||||||
(define id (racket lambda))))
|
|
||||||
(bind base-lambda))
|
|
||||||
|
|
||||||
@mzlib[#:mode title kw]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/base]]{The Racket base language
|
|
||||||
supports keyword arguments. Using the built-in keyword arguments
|
|
||||||
in Racket is highly recommended.}
|
|
||||||
|
|
||||||
@margin-note{The @base-lambda and procedure-application forms of
|
|
||||||
@racket[scheme/base] support keyword arguments, and it is
|
|
||||||
@emph{not} compatible with the @racket[mzlib/kw]
|
|
||||||
library.}
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defform[(lambda/kw kw-formals body ...+)]
|
|
||||||
@defform/subs[
|
|
||||||
(define/kw (head args) body ...+)
|
|
||||||
([kw-formals id
|
|
||||||
(id ... [#:optional optional-spec ...]
|
|
||||||
[#:key key-spec ...]
|
|
||||||
[rest/mode-spec ...])
|
|
||||||
(id ... . id)]
|
|
||||||
[optional-spec id
|
|
||||||
(id default-expr)]
|
|
||||||
[key-spec id
|
|
||||||
(id default-expr)
|
|
||||||
(id keyword default-expr)]
|
|
||||||
[rest/mode-spec (code:line #:rest id)
|
|
||||||
(code:line #:other-keys id)
|
|
||||||
(code:line #:other-keys+body id)
|
|
||||||
(code:line #:all-keys id)
|
|
||||||
(code:line #:body kw-formals)
|
|
||||||
(code:line #:allow-other-keys)
|
|
||||||
(code:line #:forbid-other-keys)
|
|
||||||
(code:line #:allow-duplicate-keys)
|
|
||||||
(code:line #:forbid-duplicate-keys)
|
|
||||||
(code:line #:allow-body)
|
|
||||||
(code:line #:forbid-body)
|
|
||||||
(code:line #:allow-anything)
|
|
||||||
(code:line #:forbid-anything)]
|
|
||||||
[head id
|
|
||||||
(head . kw-formals)])
|
|
||||||
])]{
|
|
||||||
|
|
||||||
Like @racket[lambda], but with optional and keyword-based argument
|
|
||||||
processing. This form is similar to an extended version of Common
|
|
||||||
Lisp procedure arguments (but note the differences below). When used
|
|
||||||
with plain variable names, @racket[lambda/kw] expands to a plain
|
|
||||||
@racket[lambda], so @racket[lambda/kw] is suitable for a language
|
|
||||||
module that will use it to replace @racket[lambda]. Also, when used
|
|
||||||
with only optionals, the resulting procedure is similar to
|
|
||||||
@racket[opt-lambda] (but a bit faster).
|
|
||||||
|
|
||||||
In addition to @racket[lambda/kw], @racket[define/kw] is similar to
|
|
||||||
@racket[define], except that the @racket[formals] are as in
|
|
||||||
@racket[lambda/kw]. Like @racket[define], this form can be used with
|
|
||||||
nested parenthesis for curried functions (the MIT-style generalization
|
|
||||||
of @racket[define]).
|
|
||||||
|
|
||||||
The syntax of @racket[lambda/kw] is the same as @racket[lambda],
|
|
||||||
except for the list of formal argument specifications. These
|
|
||||||
specifications can hold (zero or more) plain argument names, then an
|
|
||||||
optionals (and defaults) section that begins after an
|
|
||||||
@racket[#:optional] marker, then a keyword section that is marked by
|
|
||||||
@racket[#:keyword], and finally a section holding rest and
|
|
||||||
``rest''-like arguments which are described below, together with
|
|
||||||
argument processing flag directives. Each section is optional, but
|
|
||||||
the order of the sections must be as listed. Of course, all binding
|
|
||||||
@racket[id]s must be unique.
|
|
||||||
|
|
||||||
The following sections describe each part of the @racket[kw-formals].}
|
|
||||||
|
|
||||||
@; ----------------------------------------
|
|
||||||
|
|
||||||
@section{Required Arguments}
|
|
||||||
|
|
||||||
Required arguments correspond to @racket[id]s that appear before any
|
|
||||||
keyword marker in the argument list. They determine the minimum arity
|
|
||||||
of the resulting procedure.
|
|
||||||
|
|
||||||
@; ----------------------------------------
|
|
||||||
|
|
||||||
@section{Optional Arguments}
|
|
||||||
|
|
||||||
The optional-arguments section follows an
|
|
||||||
@as-index{@racket[#:optional]} marker in the @racket[_kw-formals].
|
|
||||||
Each optional argument can take the form of a parenthesized variable
|
|
||||||
and a default expression; the latter is used if a value is not given
|
|
||||||
at the call site. The default expression can be omitted (along with
|
|
||||||
the parentheses), in which case @racket[#f] is the default.
|
|
||||||
|
|
||||||
The default expression's environment includes all previous arguments,
|
|
||||||
both required and optional names. With @math{k} optionals after
|
|
||||||
@math{n} required arguments, and with no keyword arguments or
|
|
||||||
rest-like arguments, the resulting procedure accept between @math{n}
|
|
||||||
and @math{n+k} arguments, inclusive.
|
|
||||||
|
|
||||||
The treatment of optionals is efficient, with an important caveat:
|
|
||||||
default expressions appear multiple times in the resulting
|
|
||||||
@racket[case-lambda]. For example, the default expression for the last
|
|
||||||
optional argument appears @math{k-1} times (but no expression is ever
|
|
||||||
evaluated more than once in a procedure call). This expansion risks
|
|
||||||
exponential blow-up is if @racket[lambda/kw] is used in a default
|
|
||||||
expression of a @racket[lambda/kw], etc. The bottom line, however, is
|
|
||||||
that @racket[lambda/kw] is a sensible choice, due to its enhanced
|
|
||||||
efficiency, even when you need only optional arguments.
|
|
||||||
|
|
||||||
Using both optional and keyword arguments is possible, but note that
|
|
||||||
the resulting behavior differs from traditional keyword facilities
|
|
||||||
(including the one in Common Lisp). See the following section for
|
|
||||||
details.
|
|
||||||
|
|
||||||
@; ----------------------------------------
|
|
||||||
|
|
||||||
@section{Keyword Arguments}
|
|
||||||
|
|
||||||
A keyword argument section is marked by a @as-index{@racket[#:key]}.
|
|
||||||
If it is used with optional arguments, then the keyword specifications
|
|
||||||
must follow the optional arguments (which mirrors the use in call
|
|
||||||
sites; where optionals are given before keywords).
|
|
||||||
|
|
||||||
When a procedure accepts both optional and keyword arguments, the
|
|
||||||
argument-handling convention is slightly different than in traditional
|
|
||||||
keyword-argument facilities: a keyword after required arguments marks
|
|
||||||
the beginning of keyword arguments, no matter how many optional
|
|
||||||
arguments have been provided before the keyword. This convention
|
|
||||||
restricts the procedure's non-keyword optional arguments to
|
|
||||||
non-keyword values, but it also avoids confusion when mixing optional
|
|
||||||
arguments and keywords. For example, when a procedure that takes two
|
|
||||||
optional arguments and a keyword argument @racket[#:x] is called with
|
|
||||||
@racket[#:x 1], then the optional arguments get their default values
|
|
||||||
and the keyword argument is bound to @racket[1]. (The traditional
|
|
||||||
behavior would bind @racket[#:x] and @racket[1] to the two optional
|
|
||||||
arguments.) When the same procedure is called with @racket[1 #:x 2],
|
|
||||||
the first optional argument is bound to @racket[1], the second
|
|
||||||
optional argument is bound to its default, and the keyword argument is
|
|
||||||
bound to @racket[2]. (The traditional behavior would report an error,
|
|
||||||
because @racket[2] is provided where @racket[#:x] is expected.)
|
|
||||||
|
|
||||||
Like optional arguments, each keyword argument is specified as a
|
|
||||||
parenthesized variable name and a default expression. The default
|
|
||||||
expression can be omitted (with the parentheses), in which case
|
|
||||||
@racket[#f] is the default value. The keyword used at a call site for
|
|
||||||
the corresponding variable has the same name as the variable; a third
|
|
||||||
form of keyword arguments has three parts---a variable name, a
|
|
||||||
keyword, and a default expression---to allow the name of the locally
|
|
||||||
bound variable to differ from the keyword used at call sites.
|
|
||||||
|
|
||||||
When calling a procedure with keyword arguments, the required argument
|
|
||||||
(and all optional arguments, if specified) must be followed by an even
|
|
||||||
number of arguments, where the first argument is a keyword that
|
|
||||||
determines which variable should get the following value, etc. If the
|
|
||||||
same keyword appears multiple times (and if multiple instances of the
|
|
||||||
keyword are allowed; see @secref["mode-keywords"]), the value after
|
|
||||||
the first occurrence is used for the variable:
|
|
||||||
|
|
||||||
@examples[
|
|
||||||
#:eval kw-eval
|
|
||||||
((lambda/kw (#:key x [y 2] [z #:zz 3] #:allow-duplicate-keys)
|
|
||||||
(list x y z))
|
|
||||||
#:x 'x #:zz 'z #:x "foo")
|
|
||||||
]
|
|
||||||
|
|
||||||
Default expressions are evaluated only for keyword arguments that do
|
|
||||||
not receive a value for a particular call. Like optional arguments,
|
|
||||||
each default expression is evaluated in an environment that includes
|
|
||||||
all previous bindings (required, optional, and keywords that were
|
|
||||||
specified on its left).
|
|
||||||
|
|
||||||
See @secref["mode-keywords"] for information on when duplicate or
|
|
||||||
unknown keywords are allowed at a call site.
|
|
||||||
|
|
||||||
@; ----------------------------------------
|
|
||||||
|
|
||||||
@section{Rest and Rest-like Arguments}
|
|
||||||
|
|
||||||
The last @racket[_kw-formals] section---after the required, optional,
|
|
||||||
and keyword arguments---may contain specifications for rest-like
|
|
||||||
arguments and/or mode keywords. Up to five rest-like arguments can be
|
|
||||||
declared, each with an @racket[_id] to bind:
|
|
||||||
|
|
||||||
@itemize[
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:rest]} --- The variable is bound to the
|
|
||||||
list of ``rest'' arguments, which is the list of all values after
|
|
||||||
the required and the optional values. This list includes all
|
|
||||||
keyword-value pairs, exactly as they are specified at the call site.
|
|
||||||
|
|
||||||
Scheme's usual dot-notation is accepted in @racket[_kw-formals] only
|
|
||||||
if no other meta-keywords are specified, since it is not clear
|
|
||||||
whether it should specify the same binding as a @racket[#:rest] or
|
|
||||||
as a @racket[#:body]. The dot notation is allowed without
|
|
||||||
meta-keywords to make the @racket[lambda/kw] syntax compatible with
|
|
||||||
@racket[lambda].}
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:body]} --- The variable is bound to all
|
|
||||||
arguments after keyword--value pairs. (This is different from
|
|
||||||
Common Lisp's @racket[&body], which is a synonym for
|
|
||||||
@racket[&rest].) More generally, a @racket[#:body] specification
|
|
||||||
can be followed by another @racket[_kw-formals], not just a single
|
|
||||||
@racket[_id]; see @secref["kw-body"] for more information.}
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:all-keys]} --- the variable is bound to the
|
|
||||||
list of all keyword-values from the call site, which is always a
|
|
||||||
proper prefix of a @racket[#:rest] argument. (If no @racket[#:body]
|
|
||||||
arguments are declared, then @racket[#:all-keys] binds the same as
|
|
||||||
@racket[#:rest].) See also @racket[keyword-get].}
|
|
||||||
|
|
||||||
@item{@racket[#:other-keys] --- The variable is bound like an
|
|
||||||
@racket[#:all-keys] variable, except that all keywords specified in
|
|
||||||
the @racket[kw-formals] are removed from the list. When a keyword
|
|
||||||
is used multiple times at a call cite (and this is allowed), only
|
|
||||||
the first instances is removed for the @racket[#:other-keys]
|
|
||||||
binding.}
|
|
||||||
|
|
||||||
@item{@racket[#:other-keys+body] --- the variable is bound like a
|
|
||||||
@racket[#:rest] variable, except that all keywords specified in the
|
|
||||||
@racket[_kw-formals] are removed from the list. When a keyword is
|
|
||||||
used multiple times at a call site (and this is allowed), only the
|
|
||||||
first instance us removed for the @racket[#:other-keys+body]
|
|
||||||
binding. (When no @racket[#:body] variables are specified, then
|
|
||||||
@racket[#:other-keys+body] is the same as @racket[#:other-keys].)}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
In the following example, all rest-like arguments are used and have different
|
|
||||||
bindings:
|
|
||||||
|
|
||||||
@examples[
|
|
||||||
#:eval kw-eval
|
|
||||||
((lambda/kw (#:key x y
|
|
||||||
#:rest r
|
|
||||||
#:other-keys+body rk
|
|
||||||
#:all-keys ak
|
|
||||||
#:other-keys ok
|
|
||||||
#:body b)
|
|
||||||
(list r rk b ak ok))
|
|
||||||
#:z 1 #:x 2 2 3 4)
|
|
||||||
]
|
|
||||||
|
|
||||||
Note that the following invariants always hold:
|
|
||||||
|
|
||||||
@itemize[
|
|
||||||
@item{@racket[_rest] = @racket[(append _all-keys _body)]}
|
|
||||||
@item{@racket[_other-keys+body] = @racket[(append _other-keys _body)]}
|
|
||||||
]
|
|
||||||
|
|
||||||
To write a procedure that uses a few keyword argument values, and that
|
|
||||||
also calls another procedure with the same list of arguments
|
|
||||||
(including all keywords), use @racket[#:other-keys] (or
|
|
||||||
@racket[#:other-keys+body]). The Common Lisp approach is to specify
|
|
||||||
@racket[:allow-other-keys], so that the second procedure call will not
|
|
||||||
cause an error due to unknown keywords, but the
|
|
||||||
@racket[:allow-other-keys] approach risks confusing the two layers of
|
|
||||||
keywords.
|
|
||||||
|
|
||||||
@; ----------------------------------------
|
|
||||||
|
|
||||||
@section[#:tag "kw-body"]{Body Argument}
|
|
||||||
|
|
||||||
The most notable divergence from Common Lisp in @racket[lambda/kw] is
|
|
||||||
the @racket[#:body] argument, and the fact that it is possible at a
|
|
||||||
call site to pass plain values after the keyword-value pairs. The
|
|
||||||
@racket[#:body] binding is useful for procedure calls that use
|
|
||||||
keyword-value pairs as sort of an attribute list before the actual
|
|
||||||
arguments to the procedure. For example, consider a procedure that
|
|
||||||
accepts any number of numeric arguments and will apply a procedure to
|
|
||||||
them, but the procedure can be specified as an optional keyword
|
|
||||||
argument. It is easily implemented with a @racket[#:body] argument:
|
|
||||||
|
|
||||||
@examples[
|
|
||||||
#:eval kw-eval
|
|
||||||
(define/kw (mathop #:key [op +] #:body b)
|
|
||||||
(apply op b))
|
|
||||||
(mathop 1 2 3)
|
|
||||||
(mathop #:op max 1 2 3)
|
|
||||||
]
|
|
||||||
|
|
||||||
(Note that the first body value cannot itself be a keyword.)
|
|
||||||
|
|
||||||
A @racket[#:body] declaration works as an arbitrary
|
|
||||||
@racket[kw-formals], not just a single variable like @racket[b] in the
|
|
||||||
above example. For example, to make the above @racket[mathop] work
|
|
||||||
only on three arguments that follow the keyword, use @racket[(x y z)]
|
|
||||||
instead of @racket[b]:
|
|
||||||
|
|
||||||
@examples[
|
|
||||||
#:eval kw-eval
|
|
||||||
(define/kw (mathop #:key [op +] #:body (x y z))
|
|
||||||
(op x y z))
|
|
||||||
]
|
|
||||||
|
|
||||||
In general, @racket[#:body] handling is compiled to a sub procedure
|
|
||||||
using @racket[lambda/kw], so that a procedure can use more then one
|
|
||||||
level of keyword arguments. For example:
|
|
||||||
|
|
||||||
@examples[
|
|
||||||
#:eval kw-eval
|
|
||||||
(define/kw (mathop #:key [op +]
|
|
||||||
#:body (x y z #:key [convert values]))
|
|
||||||
(op (convert x) (convert y) (convert z)))
|
|
||||||
(mathop #:op * 2 4 6 #:convert exact->inexact)
|
|
||||||
]
|
|
||||||
|
|
||||||
Obviously, nested keyword arguments works only when non-keyword
|
|
||||||
arguments separate the sets.
|
|
||||||
|
|
||||||
Run-time errors during such calls report a mismatch for a procedure
|
|
||||||
with a name that is based on the original name plus a @racketidfont{~body}
|
|
||||||
suffix:
|
|
||||||
|
|
||||||
@examples[
|
|
||||||
#:eval kw-eval
|
|
||||||
(mathop #:op * 2 4)
|
|
||||||
]
|
|
||||||
|
|
||||||
@; ----------------------------------------
|
|
||||||
|
|
||||||
@section[#:tag "mode-keywords"]{Mode Keywords}
|
|
||||||
|
|
||||||
Finally, the argument list of a @racket[lambda/kw] can contain
|
|
||||||
keywords that serve as mode flags to control error reporting.
|
|
||||||
|
|
||||||
@itemize[
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:allow-other-keys]} --- The keyword-value
|
|
||||||
sequence at the call site @italic{can} include keywords that are not
|
|
||||||
listed in the keyword part of the @racket[lambda/kw] form.}
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:forbid-other-keys]} --- The keyword-value
|
|
||||||
sequence at the call site @italic{cannot} include keywords that are
|
|
||||||
not listed in the keyword part of the @racket[lambda/kw] form,
|
|
||||||
otherwise the @racket[exn:fail:contract] exception is raised.}
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:allow-duplicate-keys]} --- The
|
|
||||||
keyword-value list at the call site @emph{can} include duplicate
|
|
||||||
values associated with same keyword, the first one is used.}
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:forbid-duplicate-keys]} --- The
|
|
||||||
keyword-value list at the call site @italic{cannot} include
|
|
||||||
duplicate values for keywords, otherwise the
|
|
||||||
@racket[exn:fail:contract] exception is raised. This restriction
|
|
||||||
applies only to keywords that are listed in the keyword part of the
|
|
||||||
@racket[lambda/kw] form --- if other keys are allowed, this
|
|
||||||
restriction does not apply to them.}
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:allow-body]} --- Body arguments
|
|
||||||
@italic{can} be specified at the call site after all keyword-value
|
|
||||||
pairs.}
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:forbid-body]} --- Body arguments
|
|
||||||
@italic{cannot} be specified at the call site after all
|
|
||||||
keyword-value pairs.}
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:allow-anything]} --- Allows all of the
|
|
||||||
above, and treat a single keyword at the end of an argument list as
|
|
||||||
a @racket[#:body], a situation that is usually an error. When this
|
|
||||||
is used and no rest-like arguments are used except @racket[#:rest],
|
|
||||||
an extra loop is saved and calling the procedures is faster (around
|
|
||||||
20%).}
|
|
||||||
|
|
||||||
@item{@as-index{@racket[#:forbid-anything]} --- Forbids all of the
|
|
||||||
above, ensuring that calls are as restricted as possible.}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
These above mode markers are rarely needed, because the default modes
|
|
||||||
are determined by the declared rest-like arguments:
|
|
||||||
|
|
||||||
@itemize[
|
|
||||||
|
|
||||||
@item{The default is to allow other keys if a @racket[#:rest],
|
|
||||||
@racket[#:other-keys+body], @racket[#:all-keys], or
|
|
||||||
@racket[#:other-keys] variable is declared (and an
|
|
||||||
@racket[#:other-keys] declaration requires allowing other keys).}
|
|
||||||
|
|
||||||
@item{The default is to allow duplicate keys if a @racket[#:rest] or
|
|
||||||
@racket[#:all-keys] variable is declared.}
|
|
||||||
|
|
||||||
@item{The default is to allow body arguments if a @racket[#:rest],
|
|
||||||
@racket[#:body], or @racket[#:other-keys+body] variable is declared
|
|
||||||
(and a @racket[#:body] argument requires allowing them).}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
Here's an alternate specification, which maps rest-like arguments to
|
|
||||||
the behavior that they imply:
|
|
||||||
|
|
||||||
@itemize[
|
|
||||||
|
|
||||||
@item{@racket[#:rest]: Everything is allowed (a body, other keys,
|
|
||||||
and duplicate keys);}
|
|
||||||
|
|
||||||
@item{@racket[#:other-keys+body]: Other keys and body are allowed,
|
|
||||||
but duplicates are not;}
|
|
||||||
|
|
||||||
@item{@racket[#:all-keys]: Other keys and duplicate keys are allowed,
|
|
||||||
but a body is not;}
|
|
||||||
|
|
||||||
@item{@racket[#:other-keys]: Other keys must be allowed (on by
|
|
||||||
default, cannot use with @racket[#:forbid-other-keys]), and
|
|
||||||
duplicate keys and body are not allowed;}
|
|
||||||
|
|
||||||
@item{@racket[#:body]: Body must be allowed (on by default, cannot use
|
|
||||||
with @racket[#:forbid-body]) and other keys and duplicate keys and
|
|
||||||
body are not allowed;}
|
|
||||||
|
|
||||||
@item{Except for the previous two ``must''s, defaults can be
|
|
||||||
overridden by an explicit @racket[#:allow-...] or a
|
|
||||||
@racket[#:forbid-...] mode.}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
@; ----------------------------------------
|
|
||||||
|
|
||||||
@section[#:tag "keyword-get"]{Property Lists}
|
|
||||||
|
|
||||||
@defproc[(keyword-get [args (listof (cons/c keyword? any/c))] [kw keyword?]
|
|
||||||
[not-found (-> any)])
|
|
||||||
any]{
|
|
||||||
|
|
||||||
Searches a list of keyword arguments (a ``property list'' or ``plist''
|
|
||||||
in Lisp jargon) for the given keyword, and returns the associated
|
|
||||||
value. It is the facility that is used by @racket[lambda/kw] to
|
|
||||||
search for keyword values.
|
|
||||||
|
|
||||||
The @racket[args] list is scanned from left to right, if the keyword
|
|
||||||
is found, then the next value is returned. If the @racket[kw] was not
|
|
||||||
found, then the @racket[not-found] thunk is used to produce a value by
|
|
||||||
applying it. If the @racket[kw] was not found, and @racket[not-found]
|
|
||||||
thunk is not given, @racket[#f] is returned. (No exception is raised
|
|
||||||
if the @racket[args] list is imbalanced, and the search stops at a
|
|
||||||
non-keyword value.)}
|
|
||||||
|
|
||||||
|
|
||||||
@close-eval[kw-eval]
|
|
|
@ -1,77 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/list))
|
|
||||||
|
|
||||||
@mzlib[#:mode title list]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/list]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/list] library re-exports several functions
|
|
||||||
from @racketmodname[scheme/base] and @racketmodname[scheme/list]:
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
cons?
|
|
||||||
empty?
|
|
||||||
empty
|
|
||||||
foldl
|
|
||||||
foldr
|
|
||||||
remv
|
|
||||||
remq
|
|
||||||
remove
|
|
||||||
remv*
|
|
||||||
remq*
|
|
||||||
remove*
|
|
||||||
findf
|
|
||||||
memf
|
|
||||||
assf
|
|
||||||
filter
|
|
||||||
sort
|
|
||||||
]
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defproc[(first [v pair?]) any/c]
|
|
||||||
@defproc[(second [v (and/c pair? ....)]) any/c]
|
|
||||||
@defproc[(third [v (and/c pair? ....)]) any/c]
|
|
||||||
@defproc[(fourth [v (and/c pair? ....)]) any/c]
|
|
||||||
@defproc[(fifth [v (and/c pair? ....)]) any/c]
|
|
||||||
@defproc[(sixth [v (and/c pair? ....)]) any/c]
|
|
||||||
@defproc[(seventh [v (and/c pair? ....)]) any/c]
|
|
||||||
@defproc[(eighth [v (and/c pair? ....)]) any/c]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Accesses the first, second, @|etc| elment of ``list'' @racket[v]. The
|
|
||||||
argument need not actually be a list; it is inspected only as far as
|
|
||||||
necessary to obtain an element (unlike the same-named functions from
|
|
||||||
@racketmodname[scheme/list], which do require the argument to be a
|
|
||||||
list).}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(rest [v pair?]) any/c]{
|
|
||||||
|
|
||||||
The same as @racket[cdr].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(last-pair [v pair?]) pair?]{
|
|
||||||
|
|
||||||
Returns the last pair in @racket[v], raising an error if @racket[v] is
|
|
||||||
not a pair (but @racket[v] does not have to be a proper list).}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(merge-sorted-lists [lst1 list?][lst2 lst?]
|
|
||||||
[less-than? (any/c any/c . -> . any/c)])
|
|
||||||
list?]{
|
|
||||||
|
|
||||||
Merges the two sorted input lists, creating a new sorted list. The
|
|
||||||
merged result is stable: equal items in both lists stay in the same
|
|
||||||
order, and these in @racket[lst1] precede @racket[lst2].}
|
|
||||||
|
|
||||||
@defproc[(mergesort [lst list?] [less-than? (any/c any/c . -> . any/c)])
|
|
||||||
list?]{
|
|
||||||
|
|
||||||
The same as @racket[sort].}
|
|
||||||
|
|
||||||
@defproc[(quicksort [lst list?] [less-than? (any/c any/c . -> . any/c)])
|
|
||||||
list?]{
|
|
||||||
|
|
||||||
The same as @racket[sort].}
|
|
|
@ -1,49 +0,0 @@
|
||||||
#lang scheme/base
|
|
||||||
(require scribblings/reference/match-parse)
|
|
||||||
|
|
||||||
(provide match-grammar)
|
|
||||||
|
|
||||||
(define grammar "
|
|
||||||
pat ::= id @match anything, bind identifier
|
|
||||||
| _ @match anything
|
|
||||||
| literal @match literal
|
|
||||||
| 'datum @match equal% datum
|
|
||||||
| (lvp ...) @match sequence of lvps
|
|
||||||
| (lvp ... . pat) @match lvps consed onto a pat
|
|
||||||
| #(lvp ...) @match vector of pats
|
|
||||||
| #&pat @match boxed pat
|
|
||||||
| ($ struct-id pat ...) @match struct-id instance
|
|
||||||
| (AND pat ...) @match when all pats match
|
|
||||||
| (OR pat ...) @match when any pat match
|
|
||||||
| (NOT pat ...) @match when no pat match
|
|
||||||
| (= expr pat) @match (expr value) to pat
|
|
||||||
| (? pred-expr pat ...) @match if (expr value) and pats
|
|
||||||
| `qp @match quasipattern
|
|
||||||
literal ::= #t @match true
|
|
||||||
| #f @match false
|
|
||||||
| string @match equal% string
|
|
||||||
| number @match equal% number
|
|
||||||
| character @match equal% character
|
|
||||||
| bytes @match equal% byte string
|
|
||||||
| keyword @match equal% keyword
|
|
||||||
| regexp literal @match equal% regexp literal
|
|
||||||
| pregexp literal @match equal% pregexp literal
|
|
||||||
lvp ::= pat ooo @greedily match pat instances
|
|
||||||
| pat @match pat
|
|
||||||
ooo ::= *** @zero or more; *** is literal
|
|
||||||
| ___ @zero or more
|
|
||||||
| ..K @K or more
|
|
||||||
| __K @K or more
|
|
||||||
qp ::= literal @match literal
|
|
||||||
| id @match equal% symbol
|
|
||||||
| (qp ...) @match sequences of qps
|
|
||||||
| (qp ... . qp) @match sequence of qps consed onto a qp
|
|
||||||
| (qp ... qp ooo) @match qps consed onto a repeated qp
|
|
||||||
| #(qp ...) @match vector of qps
|
|
||||||
| #&qp @match boxed qp
|
|
||||||
| ,pat @match pat
|
|
||||||
| ,@pat @match pat, spliced
|
|
||||||
")
|
|
||||||
|
|
||||||
(define match-grammar
|
|
||||||
(parse-match-grammar grammar))
|
|
|
@ -1,57 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
"match-grammar.rkt"
|
|
||||||
(for-label mzlib/match))
|
|
||||||
|
|
||||||
@(begin
|
|
||||||
(define-syntax-rule (bind id)
|
|
||||||
(begin
|
|
||||||
(require racket/match)
|
|
||||||
(define id (racket match))))
|
|
||||||
(bind racket-match))
|
|
||||||
|
|
||||||
@mzlib[#:mode title match]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/match]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/match] library provides a @racket[match] form
|
|
||||||
similar to that of @racketmodname[racket/match], but with an different
|
|
||||||
(older and less extensible) syntax of patterns.
|
|
||||||
|
|
||||||
@defform/subs[(match val-expr clause ...)
|
|
||||||
([clause [pat expr ...+]
|
|
||||||
[pat (=> id) expr ...+]])]{
|
|
||||||
|
|
||||||
See @racket-match from @racketmodname[racket/match] for a description
|
|
||||||
of matching. The grammar of @racket[pat] for this @racket[match] is as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
@|match-grammar|}
|
|
||||||
|
|
||||||
@; ------------------------------------------------------------
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defform[(define/match (head args) match*-clause ...)]
|
|
||||||
@defform[(match-lambda clause ...)]
|
|
||||||
@defform[(match-lambda* clause ...)]
|
|
||||||
@defform[(match-let ([pat expr] ...) body ...+)]
|
|
||||||
@defform[(match-let* ([pat expr] ...) body ...+)]
|
|
||||||
@defform[(match-letrec ([pat expr] ...) body ...+)]
|
|
||||||
@defform[(match-define pat expr)]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Analogous to the combined forms from @racket[racket/match].}
|
|
||||||
|
|
||||||
@; ------------------------------------------------------------
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defform*[((define-match-expander id proc-expr)
|
|
||||||
(define-match-expander id proc-expr proc-expr)
|
|
||||||
(define-match-expander id proc-expr proc-expr proc-expr))]
|
|
||||||
@defparam[match-equality-test comp-proc (any/c any/c . -> . any)]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Analogous to the form and parameter from @racket[racket/match]. The
|
|
||||||
@racket[define-match-expander] form, however, supports an extra
|
|
||||||
@racket[proc-expr] as the middle one: an expander for use with
|
|
||||||
@racket[match] from @racketmodname[mzlib/match].}
|
|
|
@ -1,13 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/math))
|
|
||||||
|
|
||||||
@mzlib[#:mode title math]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/math]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/math], and also exports @racket[e].
|
|
||||||
|
|
||||||
@defthing[e real?]{
|
|
||||||
|
|
||||||
An approximation to Euler's constant: @number->string[(exp 1)].}
|
|
|
@ -1,378 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt")
|
|
||||||
|
|
||||||
@title{MzLib: Legacy Libraries}
|
|
||||||
|
|
||||||
The @filepath{mzlib} collection contains wrappers and libraries for
|
|
||||||
compatibility with older versions of Racket. In many ways, the
|
|
||||||
libraries of the @filepath{mzlib} collection go with the
|
|
||||||
@racketmodname[mzscheme] legacy language. Newer variants of many
|
|
||||||
libraries reside in the @filepath{scheme} collection.
|
|
||||||
|
|
||||||
@table-of-contents[]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[a-signature]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/signature]]{}
|
|
||||||
|
|
||||||
Like @racketmodname[scheme/signature] in @hash-lang[] form for
|
|
||||||
defining a single signature within a module, but based on
|
|
||||||
@racketmodname[mzscheme] instead of @racketmodname[scheme/base].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[a-unit]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/unit]]{}
|
|
||||||
|
|
||||||
Like @racketmodname[scheme/unit] in @hash-lang[] form for defining a
|
|
||||||
single unit within a module, but based on @racketmodname[mzscheme]
|
|
||||||
instead of @racketmodname[scheme/base].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[async-channel]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/async-channel]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/async-channel].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["awk.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[class]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/class]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/class], except for the contract
|
|
||||||
constructors.
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[cm]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[compiler/cm]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[compiler/cm].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[cm-accomplice]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[compiler/cm-accomplice]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[compiler/cm-accomplice].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["cmdline.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["cml.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["compat.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["compile.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["contract.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[control]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/control]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/control].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[date]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/date]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/date].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[deflate]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[file/gzip]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[file/gzip].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[defmacro]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[compatibility/defmacro]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[compatibility/defmacro].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["etc.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["file.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["for.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[foreign]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[ffi/unsafe]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/foreign].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["include.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[inflate]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[file/gunzip]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[file/gunzip].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["integer-set.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["kw.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["list.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["match.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["math.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[md5]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[file/md5]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[file/md5].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["os.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["pconvert.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["pconvert-prop.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["plt-match.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["port.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["pregexp.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[pretty]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/pretty]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/pretty].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[process]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/system]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/system].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["restart.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[runtime-path]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/runtime-path]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/runtime-path].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["sandbox.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["sendevent.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["serialize.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[shared]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/shared]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/shared].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["string.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["struct.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[stxparam]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/stxparam]]{
|
|
||||||
Also see @racketmodname[racket/stxparam-exptime].
|
|
||||||
}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/stxparam] and
|
|
||||||
@racketmodname[scheme/stxparam-exptime] (both at phase level 0).
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[surrogate]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/surrogate]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/surrogate].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[tar]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[file/tar]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[file/tar].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["thread.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[trace]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/trace]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[racket/trace].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["traceld.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[trait]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/trait]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/trait].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["transcr.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@include-section["unit.scrbl"]
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@mzlib[unit-exptime]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/unit-exptime]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[scheme/unit-exptime].
|
|
||||||
|
|
||||||
@; ----------------------------------------
|
|
||||||
|
|
||||||
@mzlib[unit200]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/unit]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/unit200] library provides an old
|
|
||||||
implementation of units. See archived version 360 documentation on the
|
|
||||||
@filepath{unit.ss} library of the @filepath{mzlib} collection for
|
|
||||||
information about this library.
|
|
||||||
|
|
||||||
@; ----------------------------------------
|
|
||||||
|
|
||||||
@mzlib[unitsig200]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/unit]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/unit200] library provides an old
|
|
||||||
implementation of units. See archived version 360 documentation on the
|
|
||||||
@filepath{unitsig.ss} library of the @filepath{mzlib} collection for
|
|
||||||
information about this library.
|
|
||||||
|
|
||||||
@; ----------------------------------------
|
|
||||||
|
|
||||||
@mzlib[zip]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[file/zip]]{}
|
|
||||||
|
|
||||||
Re-exports @racketmodname[file/zip].
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@(bibliography
|
|
||||||
|
|
||||||
(bib-entry #:key "Shivers06"
|
|
||||||
#:title "Scsh Reference Manual"
|
|
||||||
#:author "Olin Shivers, Brian D. Carlstrom, Martin Gasbichler, and Mike Sperber"
|
|
||||||
#:date "2006")
|
|
||||||
|
|
||||||
(bib-entry #:key "Reppy99"
|
|
||||||
#:title @italic{Concurrent Programming in ML}
|
|
||||||
#:author "John H. Reppy"
|
|
||||||
#:date "1999")
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@index-section[]
|
|
|
@ -1,30 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/os))
|
|
||||||
|
|
||||||
@mzlib[#:mode title os]
|
|
||||||
|
|
||||||
@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.}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(truncate-file [file path-string?][n-bytes exact-nonnegative-integer? 0])
|
|
||||||
void?]{
|
|
||||||
|
|
||||||
Truncates or extends the given @racket[file] so that it is
|
|
||||||
@racket[n-bytes] long. If the file does not exist, or if the process
|
|
||||||
does not have sufficient privilege to truncate the file, the
|
|
||||||
@racket[exn:fail] exception is raised.
|
|
||||||
|
|
||||||
The @racket[truncate-file] function is implemented in terms of
|
|
||||||
@racketmodname[racket/base]'s @racket[file-truncate].}
|
|
||||||
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/pconvert
|
|
||||||
mzlib/pconvert-prop))
|
|
||||||
|
|
||||||
@mzlib[#:mode title pconvert-prop]
|
|
||||||
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defthing[prop:print-converter property?]
|
|
||||||
@defproc[(print-converter? [v any/c]) any]
|
|
||||||
@defproc[(print-converter-proc [v print-converter?]) (any/c (any/c . -> . any/c) . -> . any/c)]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
The @racket[prop:print-converter] property can be given a procedure
|
|
||||||
value for a structure type. In that case, for constructor-style print
|
|
||||||
conversion via @racket[print-convert], instances of the structure are
|
|
||||||
converted by calling the procedure that is the property's value. The
|
|
||||||
procedure is called with the value to convert and a procedure to
|
|
||||||
recursively convert nested values. The result should be an
|
|
||||||
S-expression for the converted value.
|
|
||||||
|
|
||||||
The @racket[print-converter?] predicate recognizes instances of
|
|
||||||
structure types that have the @racket[prop:print-converter] property,
|
|
||||||
and @racket[print-converter-proc] extracts the property value.}
|
|
||||||
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defthing[prop:print-convert-constructor-name property?]
|
|
||||||
@defproc[(print-convert-named-constructor? [v any/c]) any]
|
|
||||||
@defproc[(print-convert-constructor-name [v print-convert-named-constructor?]) any]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
The @racket[prop:print-convert-constructor-name] property can be given
|
|
||||||
a symbol value for a structure type. In that case, for
|
|
||||||
constructor-style print conversion via @racket[print-convert],
|
|
||||||
instances of the structure are shown using the symbol as the
|
|
||||||
constructor name.
|
|
||||||
|
|
||||||
The @racket[prop:print-converter] property takes precedence over
|
|
||||||
@racket[prop:print-convert-constructor-name]. If neither is attached
|
|
||||||
to a structure type, its instances are converted using a constructor
|
|
||||||
name that is @racketidfont{make-} prefixed onto the result of
|
|
||||||
@racket[object-name].
|
|
||||||
|
|
||||||
The @racket[print-convert-named-constructor?] predicate recognizes
|
|
||||||
instances of structure types that have the
|
|
||||||
@racket[prop:print-convert-constructor-name] property, and
|
|
||||||
@racket[print-convert-constructor-name] extracts the property value.}
|
|
|
@ -1,263 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/pconvert
|
|
||||||
mzlib/pconvert-prop
|
|
||||||
racket/contract
|
|
||||||
racket/pretty))
|
|
||||||
|
|
||||||
@mzlib[#:mode title pconvert]
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/pconvert] library defines routines for
|
|
||||||
printing Racket values as @racket[eval]uable S-expressions. Racket's
|
|
||||||
default printing mode also prints values as expressions (in contrast
|
|
||||||
to the Lisp and Racket tradition of printing @racket[read]able
|
|
||||||
S-expressions), but @racketmodname[mzlib/pconvert] is more
|
|
||||||
configurable and approximates expressions for a wider range of
|
|
||||||
values. For example, procedures print using @racketresultfont{lambda}
|
|
||||||
instead of @racketresultfont{#<procedure>}.
|
|
||||||
|
|
||||||
The @racket[print-convert] procedure does not print values; rather, it
|
|
||||||
converts a Racket value into another Racket value such that the new
|
|
||||||
value @racket[pretty-write]s as a Racket expression that evaluates to
|
|
||||||
the original value. For example, @racket[(pretty-write (print-convert
|
|
||||||
`(9 ,(box 5) #(6 7))))] prints the literal expression
|
|
||||||
@racketresult[(list 9 (box 5) (vector 6 7))] to the current output
|
|
||||||
port.
|
|
||||||
|
|
||||||
To install print converting into the read-eval-print loop, require
|
|
||||||
@racketmodname[mzlib/pconvert] and call the procedure
|
|
||||||
@racket[install-converting-printer].
|
|
||||||
|
|
||||||
In addition to @racket[print-convert], this library provides
|
|
||||||
@racket[print-convert], @racket[build-share], @racket[get-shared],
|
|
||||||
and @racket[print-convert-expr]. The last three are used to convert
|
|
||||||
sub-expressions of a larger expression (potentially with shared
|
|
||||||
structure).
|
|
||||||
|
|
||||||
See also @racket[prop:print-convert-constructor-name].
|
|
||||||
|
|
||||||
@defboolparam[abbreviate-cons-as-list abbreviate?]{
|
|
||||||
|
|
||||||
A parameter that controls how lists are represented with
|
|
||||||
constructor-style conversion. If the parameter's value is @racket[#t],
|
|
||||||
lists are represented using @racket[list]. Otherwise, lists are
|
|
||||||
represented using @racket[cons]. The initial value of the parameter is
|
|
||||||
@racket[#t].}
|
|
||||||
|
|
||||||
|
|
||||||
@defboolparam[booleans-as-true/false use-name?]{
|
|
||||||
|
|
||||||
A parameter that controls how @racket[#t] and @racket[#f] are
|
|
||||||
represented. If the parameter's value is @racket[#t], then @racket[#t]
|
|
||||||
is represented as @racket[true] and @racket[#f] is represented as
|
|
||||||
@racket[false]. The initial value of the parameter is @racket[#t].}
|
|
||||||
|
|
||||||
|
|
||||||
@defparam[use-named/undefined-handler use-handler (any/c . -> . any/c)]{
|
|
||||||
|
|
||||||
A parameter that controls how values that have inferred names are
|
|
||||||
represented. The procedure is passed a value. If the procedure returns
|
|
||||||
true, the procedure associated with @racket[named/undefined-handler]
|
|
||||||
is invoked to render that value. Only values that have inferred names
|
|
||||||
but are not defined at the top-level are used with this handler.
|
|
||||||
|
|
||||||
The initial value of the parameter is @racket[(lambda (x) #f)].}
|
|
||||||
|
|
||||||
|
|
||||||
@defparam[named/undefined-handler use-handler (any/c . -> . any/c)]{
|
|
||||||
|
|
||||||
Parameter for a procedure that controls how values that have inferred
|
|
||||||
names are represented. The procedure is called only if
|
|
||||||
@racket[use-named/undefined-handler] returns true for some value. In
|
|
||||||
that case, the procedure is passed that same value, and the result of
|
|
||||||
the parameter is used as the representation for the value.
|
|
||||||
|
|
||||||
The initial value of the parameter is @racket[(lambda (x) #f)].}
|
|
||||||
|
|
||||||
|
|
||||||
@defboolparam[add-make-prefix-to-constructor add-prefix?]{
|
|
||||||
|
|
||||||
A parameter that controls whether a @racketidfont{make-} prefix is
|
|
||||||
added to a constructor name for a structure instance. The initial
|
|
||||||
value of the parameter is @racket[#f].}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(build-share [v any/c]) ....]{
|
|
||||||
|
|
||||||
Takes a value and computes sharing information used for representing
|
|
||||||
the value as an expression. The return value is an opaque structure
|
|
||||||
that can be passed back into @racket[get-shared] or
|
|
||||||
@racket[print-convert-expr].}
|
|
||||||
|
|
||||||
|
|
||||||
@defboolparam[constructor-style-printing use-constructors?]{
|
|
||||||
|
|
||||||
Parameter that controls how values are represented after conversion.
|
|
||||||
If this parameter's value is @racket[#t], then constructors are used;
|
|
||||||
e.g., pair containing @racket[1] and @racket[2] is represented as
|
|
||||||
@racket[(cons 1 2)]. Otherwise, @racket[quasiquote]-style syntax is
|
|
||||||
used; e.g., the pair containing @racket[1] and @racket[2] is
|
|
||||||
represented as @racket[`(1 . 2)]. The initial value of the parameter
|
|
||||||
is @racket[#f].
|
|
||||||
|
|
||||||
The constructor used for mutable pairs is @racketidfont{mcons}, unless
|
|
||||||
@racket[print-mpair-curly-braces] is set to @racket[#f], in which case
|
|
||||||
@racketidfont{cons} and @racketidfont{list} are used. Similarly, when
|
|
||||||
using @racket[quasiquote] style and @racket[print-mpair-curly-braces]
|
|
||||||
is set to @racket[#f], mutable pair constructions are represented
|
|
||||||
using @racketidfont{quote}, @racketidfont{quasiquote}, etc.
|
|
||||||
|
|
||||||
See also @racket[quasi-read-style-printing] and
|
|
||||||
@racket[prop:print-convert-constructor-name].}
|
|
||||||
|
|
||||||
|
|
||||||
@defparam[current-build-share-hook
|
|
||||||
hook
|
|
||||||
(any/c (any/c . -> . void?)
|
|
||||||
(any/c . -> . void?) . -> . any)]{
|
|
||||||
|
|
||||||
Parameter that sets a procedure used by @racket[print-convert] and
|
|
||||||
@racket[build-share] to assemble sharing information. The procedure
|
|
||||||
@racket[hook] takes three arguments: a value @racket[_v], a procedure
|
|
||||||
@racket[_basic-share], and a procedure @racket[_sub-share]; the return
|
|
||||||
value is ignored. The @racket[basic-share] procedure takes @racket[_v]
|
|
||||||
and performs the built-in sharing analysis, while the
|
|
||||||
@racket[_sub-share] procedure takes a component of @racket[_v] ands
|
|
||||||
analyzes it. Sharing information is accumulated as values are passed
|
|
||||||
to @racket[basic-share] and @racket[sub-share].
|
|
||||||
|
|
||||||
A @racket[current-build-share-hook] procedure usually works together
|
|
||||||
with a @racket[current-print-convert-hook] procedure.}
|
|
||||||
|
|
||||||
|
|
||||||
@defparam[current-build-share-name-hook hook (any/c . -> . (or/c symbol? false/c))]{
|
|
||||||
|
|
||||||
Parameter that sets a procedure used by @racket[print-convert] and
|
|
||||||
@racket[build-share] to generate a new name for a shared value. The
|
|
||||||
@racket[hook] procedure takes a single value and returns a symbol for
|
|
||||||
the value's name. If @racket[hook] returns @racket[#f], a name is
|
|
||||||
generated using the form
|
|
||||||
``@racketidfont{-}@racket[_n]@racketidfont{-}, where @racket[n] is an
|
|
||||||
integer.}
|
|
||||||
|
|
||||||
|
|
||||||
@defparam[current-print-convert-hook
|
|
||||||
hook
|
|
||||||
(any/c (any/c . -> . any/c)
|
|
||||||
(any/c . -> . any/c)
|
|
||||||
. -> . any/c)]{
|
|
||||||
|
|
||||||
Parameter that sets a procedure used by @racket[print-convert] and
|
|
||||||
@racket[print-convert-expr] to convert values. The procedure
|
|
||||||
@racket[hook] takes three arguments---a value @racket[_v], a procedure
|
|
||||||
@racket[_basic-convert], and a procedure @racket[_sub-convert]---and
|
|
||||||
returns the converted representation of @racket[_v]. The
|
|
||||||
@racket[_basic-convert] procedure takes @racket[_v] and returns the
|
|
||||||
default conversion, while the @racket[_sub-convert] procedure takes a
|
|
||||||
component of @racket[_v] and returns its conversion.
|
|
||||||
|
|
||||||
A @racket[current-print-convert-hook] procedure usually works together
|
|
||||||
with a @racket[current-build-share-hook] procedure.}
|
|
||||||
|
|
||||||
|
|
||||||
@defparam[current-read-eval-convert-print-prompt str string?]{
|
|
||||||
|
|
||||||
Parameter that sets the prompt used by
|
|
||||||
@racket[install-converting-printer].
|
|
||||||
The initial value is @racket["|- "].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(get-shared [share-info ....]
|
|
||||||
[cycles-only? any/c #f])
|
|
||||||
(list-of (cons/c symbol? any/c))]{
|
|
||||||
|
|
||||||
The @racket[shared-info] value must be a result from @racket[build-share].
|
|
||||||
The procedure returns a list matching variables to shared values
|
|
||||||
within the value passed to @racket[build-share].
|
|
||||||
|
|
||||||
The default value for @racket[cycles-only?] is @racket[#f];
|
|
||||||
if it is not @racket[#f], @racket[get-shared] returns only information
|
|
||||||
about cycles.
|
|
||||||
|
|
||||||
For example,
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
(get-shared (build-share (shared ([a (cons 1 b)]
|
|
||||||
[b (cons 2 a)])
|
|
||||||
a)))
|
|
||||||
]
|
|
||||||
|
|
||||||
might return the list
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
'((-1- (cons 1 -2-)) (-2- (cons 2 -1-)))
|
|
||||||
]}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(install-converting-printer) void?]{
|
|
||||||
|
|
||||||
Sets the current print handler to print values using
|
|
||||||
@racket[print-convert] and sets @racket[print-as-expression] to
|
|
||||||
@racket[#f] (since the conversion of a value is meant to be printed in
|
|
||||||
@racket[read]able form rather than @racket[eval]uable form). The
|
|
||||||
current read handler is also set to use the prompt returned by
|
|
||||||
@racket[current-read-eval-convert-print-prompt].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(print-convert [v any/c][cycles-only? any/c (show-sharing)]) any/c]{
|
|
||||||
|
|
||||||
Converts the value @racket[v]. If @racket[cycles-only?] is not
|
|
||||||
@racket[#f], then only circular objects are included in the
|
|
||||||
output.}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(print-convert-expr [share-info ....]
|
|
||||||
[v any/c]
|
|
||||||
[unroll-once? any/c]) any/c]{
|
|
||||||
|
|
||||||
Converts the value @racket[v] using sharing information
|
|
||||||
@racket[share-info], which was previously returned by
|
|
||||||
@racket[build-share] for a value containing @racket[v]. If the most
|
|
||||||
recent call to @racket[get-shared] with @racket[share-info] requested
|
|
||||||
information only for cycles, then @racket[print-convert-expr] will
|
|
||||||
only display sharing among values for cycles, rather than showing all
|
|
||||||
value sharing.
|
|
||||||
|
|
||||||
The @racket[unroll-once?] argument is used if @racket[v] is a shared
|
|
||||||
value in @racket[share-info]. In this case, if @racket[unroll-once?]
|
|
||||||
is @racket[#f], then the return value will be a shared-value
|
|
||||||
identifier; otherwise, the returned value shows the internal structure
|
|
||||||
of @racket[v] (using shared value identifiers within @racket[v]'s
|
|
||||||
immediate structure as appropriate).}
|
|
||||||
|
|
||||||
|
|
||||||
@defboolparam[quasi-read-style-printing on?]{
|
|
||||||
|
|
||||||
Parameter that controls how vectors and boxes are represented after
|
|
||||||
conversion when the value of @racket[constructor-style-printing] is
|
|
||||||
@racket[#f]. If @racket[quasi-read-style-printing] is set to
|
|
||||||
@racket[#f], then boxes and vectors are unquoted and represented using
|
|
||||||
constructors. For example, the list of a box containing the number 1
|
|
||||||
and a vector containing the number 1 is represented as @racketresult[`(,(box
|
|
||||||
1) ,(vector 1))]. If the parameter's value is @racket[#t], then
|
|
||||||
@racket[#&....] and @racket[#(....)] are used, e.g., @racket[`(#&1
|
|
||||||
#(1))]. The initial value of the parameter is @racket[#t].}
|
|
||||||
|
|
||||||
|
|
||||||
@defboolparam[show-sharing show?]{
|
|
||||||
|
|
||||||
Parameter that determines whether sub-value sharing is conserved (and
|
|
||||||
shown) in the converted output by default. The initial value of the
|
|
||||||
parameter is @racket[#t].}
|
|
||||||
|
|
||||||
|
|
||||||
@defboolparam[whole/fractional-exact-numbers whole-frac?]{
|
|
||||||
|
|
||||||
Parameter that controls how exact, non-integer numbers are converted
|
|
||||||
when the numerator is greater than the denominator. If the parameter's
|
|
||||||
value is @racket[#t], the number is converted to the form @racket[(+
|
|
||||||
_integer _fraction)] (i.e., a list containing @racket['+], an exact
|
|
||||||
integer, and an exact rational less than @racket[1] and greater than
|
|
||||||
@racket[-1]). The initial value of the parameter is @racket[#f].}
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/plt-match))
|
|
||||||
|
|
||||||
@mzlib[#:mode title plt-match]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/match]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/plt-match] library mostly re-provides
|
|
||||||
@racket[scheme/match].
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defform*[((define-match-expander id proc-expr)
|
|
||||||
(define-match-expander id proc-expr proc-expr)
|
|
||||||
(define-match-expander id proc-expr proc-expr proc-expr))]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
The same as the form from @racketmodname[mzlib/match].}
|
|
|
@ -1,18 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/port))
|
|
||||||
|
|
||||||
@mzlib[#:mode title port]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/port]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/port] library mostly re-provides
|
|
||||||
@racketmodname[racket/port].
|
|
||||||
|
|
||||||
@defproc[(strip-shell-command-start [in input-port?]) void?]{
|
|
||||||
|
|
||||||
Reads and discards a leading @litchar{#!} in @racket[in] (plus
|
|
||||||
continuing lines if the line ends with a backslash). Since
|
|
||||||
@litchar{#!} followed by a forward slash or space is a comment, this
|
|
||||||
procedure is not needed before reading Scheme expressions.}
|
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/pregexp
|
|
||||||
(only-in scheme/base regexp-quote)))
|
|
||||||
|
|
||||||
@mzlib[#:mode title pregexp]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/base]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/pregexp] library provides wrappers around
|
|
||||||
@racket[regexp-match], @|etc| that coerce string and byte-string
|
|
||||||
arguments to @racket[pregexp] matchers instead of @racket[regexp]
|
|
||||||
matchers.
|
|
||||||
|
|
||||||
The library also re-exports: @racket[pregexp], and it re-exports
|
|
||||||
@racket[regexp-quote] as @racket[pregexp-quote].
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defproc[(pregexp-match [pattern (or/c string? bytes? regexp? byte-regexp?)]
|
|
||||||
[input (or/c string? bytes? input-port?)]
|
|
||||||
[start-pos exact-nonnegative-integer? 0]
|
|
||||||
[end-pos (or/c exact-nonnegative-integer? false/c) #f]
|
|
||||||
[output-port (or/c output-port? false/c) #f])
|
|
||||||
(or/c (listof (or/c (cons (or/c string? bytes?)
|
|
||||||
(or/c string? bytes?))
|
|
||||||
false/c))
|
|
||||||
false/c)]
|
|
||||||
@defproc[(pregexp-match-positions [pattern (or/c string? bytes? regexp? byte-regexp?)]
|
|
||||||
[input (or/c string? bytes? input-port?)]
|
|
||||||
[start-pos exact-nonnegative-integer? 0]
|
|
||||||
[end-pos (or/c exact-nonnegative-integer? false/c) #f]
|
|
||||||
[output-port (or/c output-port? false/c) #f])
|
|
||||||
(or/c (listof (or/c (cons exact-nonnegative-integer?
|
|
||||||
exact-nonnegative-integer?)
|
|
||||||
false/c))
|
|
||||||
false/c)]
|
|
||||||
@defproc[(pregexp-split [pattern (or/c string? bytes? regexp? byte-regexp?)]
|
|
||||||
[input (or/c string? bytes? input-port?)]
|
|
||||||
[start-pos exact-nonnegative-integer? 0]
|
|
||||||
[end-pos (or/c exact-nonnegative-integer? false/c) #f])
|
|
||||||
(listof (or/c string? bytes?))]
|
|
||||||
@defproc[(pregexp-replace [pattern (or/c string? bytes? regexp? byte-regexp?)]
|
|
||||||
[input (or/c string? bytes?)]
|
|
||||||
[insert (or/c string? bytes?
|
|
||||||
(string? . -> . string?)
|
|
||||||
(bytes? . -> . bytes?))])
|
|
||||||
(or/c string? bytes?)]
|
|
||||||
@defproc[(pregexp-replace* [pattern (or/c string? bytes? regexp? byte-regexp?)]
|
|
||||||
[input (or/c string? bytes?)]
|
|
||||||
[insert (or/c string? bytes?
|
|
||||||
(string? . -> . string?)
|
|
||||||
(bytes? . -> . bytes?))])
|
|
||||||
(or/c string? bytes?)]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Like @racket[regexp-match], @|etc|, but a string @racket[pattern]
|
|
||||||
argument is compiled via @racket[pregexp], and a byte string
|
|
||||||
@racket[pattern] argument is compiled via @racket[byte-pregexp].}
|
|
|
@ -1,69 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/restart
|
|
||||||
mzlib/cmdline))
|
|
||||||
|
|
||||||
@mzlib[#:mode title restart]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/sandbox]]{
|
|
||||||
The @racket[racket/sandbox] library provides a more general way to
|
|
||||||
simulate running a new Racket process.
|
|
||||||
}
|
|
||||||
|
|
||||||
@defproc[(restart-mzscheme [init-argv (vectorof string?)]
|
|
||||||
[adjust-flag-table (any/c . -> . any/c)]
|
|
||||||
[argv (vectorof string?)]
|
|
||||||
[init-namespace (-> any)])
|
|
||||||
boolean?]{
|
|
||||||
|
|
||||||
Simulates starting Racket with the vector of command-line strings
|
|
||||||
@racket[argv]. The @racket[init-argv], @racket[adjust-flag-table], and
|
|
||||||
@racket[init-namespace] arguments are used to modify the default
|
|
||||||
settings for command-line flags, adjust the parsing of command-line
|
|
||||||
flags, and customize the initial namespace, respectively.
|
|
||||||
|
|
||||||
The vector of strings @racket[init-argv] is read first with the
|
|
||||||
standard Racket command-line parsing. Flags that load files or
|
|
||||||
evaluate expressions (e.g., @Flag{f} and @Flag{e}) are ignored, but
|
|
||||||
flags that set Racket's modes (e.g., @Flag{c} or @Flag{j})
|
|
||||||
effectively set the default mode before @racket[argv] is parsed.
|
|
||||||
|
|
||||||
Before @racket[argv] is parsed, the procedure
|
|
||||||
@racket[adjust-flag-table] is called with a command-line flag table as
|
|
||||||
accepted by @racket[parse-command-line]. The return value must also be
|
|
||||||
a table of command-line flags, and this table is used to parse
|
|
||||||
@racket[argv]. The intent is to allow @racket[adjust-flag-table] to
|
|
||||||
add or remove flags from the standard set.
|
|
||||||
|
|
||||||
After @racket[argv] is parsed, a new thread and a namespace are
|
|
||||||
created for the ``restarted'' Racket. (The new namespace is
|
|
||||||
installed as the current namespace in the new thread.) In the new
|
|
||||||
thread, restarting performs the following actions:
|
|
||||||
|
|
||||||
@itemize[
|
|
||||||
|
|
||||||
@item{The @racket[init-namespace] procedure is called with no
|
|
||||||
arguments. The return value is ignored.}
|
|
||||||
|
|
||||||
@item{Expressions and files specified by @racket[argv] are evaluated
|
|
||||||
and loaded. If an error occurs, the remaining expressions and
|
|
||||||
files are ignored, and the return value for
|
|
||||||
@racket[restart-mzscheme] is set to @racket[#f].}
|
|
||||||
|
|
||||||
@item{The @racket[read-eval-print-loop] procedure is called, unless a
|
|
||||||
flag in @racket[init-argv] or @racket[argv] disables it. When
|
|
||||||
@racket[read-eval-print-loop] returns, the return value for
|
|
||||||
@racket[restart-mzscheme] is set to @racket[#t].}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
Before evaluating command-line arguments, an exit handler is installed
|
|
||||||
that immediately returns from @racket[restart-mzscheme] with the value
|
|
||||||
supplied to the handler. This exit handler remains in effect when
|
|
||||||
@racket[read-eval-print-loop] is called (unless a command-line
|
|
||||||
argument changes it). If @racket[restart-mzscheme] returns normally,
|
|
||||||
the return value is determined as described above.
|
|
||||||
|
|
||||||
Note that an error in a command-line expression followed by
|
|
||||||
@racket[read-eval-print-loop] produces a @racket[#t] result. This is
|
|
||||||
consistent with Racket's stand-alone behavior.}
|
|
|
@ -1,84 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/sandbox
|
|
||||||
(only-in racket/sandbox make-module-evaluator)))
|
|
||||||
|
|
||||||
@(begin
|
|
||||||
(define-syntax-rule (bind id)
|
|
||||||
(begin
|
|
||||||
(require (for-label racket/sandbox))
|
|
||||||
(define id (racket make-evaluator))))
|
|
||||||
(bind racket-make-evaluator))
|
|
||||||
|
|
||||||
@mzlib[#:mode title sandbox]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/sandbox]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/sandbox] library mostly re-exports
|
|
||||||
@racketmodname[racket/sandbox], but it provides a slightly different
|
|
||||||
@racket[make-evaluator] function.
|
|
||||||
|
|
||||||
The library re-exports the following bindings:
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
sandbox-init-hook
|
|
||||||
sandbox-reader
|
|
||||||
sandbox-input
|
|
||||||
sandbox-output
|
|
||||||
sandbox-error-output
|
|
||||||
sandbox-propagate-breaks
|
|
||||||
sandbox-coverage-enabled
|
|
||||||
sandbox-namespace-specs
|
|
||||||
sandbox-override-collection-paths
|
|
||||||
sandbox-security-guard
|
|
||||||
sandbox-path-permissions
|
|
||||||
sandbox-network-guard
|
|
||||||
sandbox-make-inspector
|
|
||||||
sandbox-eval-limits
|
|
||||||
kill-evaluator
|
|
||||||
break-evaluator
|
|
||||||
set-eval-limits
|
|
||||||
put-input
|
|
||||||
get-output
|
|
||||||
get-error-output
|
|
||||||
get-uncovered-expressions
|
|
||||||
call-with-limits
|
|
||||||
with-limits
|
|
||||||
exn:fail:resource?
|
|
||||||
exn:fail:resource-resource
|
|
||||||
]
|
|
||||||
|
|
||||||
@defproc*[([(make-evaluator [language (or/c module-path?
|
|
||||||
(one-of/c 'r5rs 'beginner 'beginner-abbr
|
|
||||||
'intermediate 'intermediate-lambda 'advanced)
|
|
||||||
(list/c (one-of/c 'special) symbol?)
|
|
||||||
(list/c (one-of/c 'special) symbol?)
|
|
||||||
(cons/c (one-of/c 'begin) list?))]
|
|
||||||
[requires (or/c (cons/c 'begin list?)
|
|
||||||
(listof (or/c module-path? path?)))]
|
|
||||||
[input-program any/c] ...)
|
|
||||||
(any/c . -> . any)]
|
|
||||||
[(make-evaluator [module-decl (or/c syntax? pair?)])
|
|
||||||
(any/c . -> . any)])]{
|
|
||||||
|
|
||||||
Like @racket-make-evaluator or @racket[make-module-evaluator], but
|
|
||||||
with several differences:
|
|
||||||
|
|
||||||
@itemize[
|
|
||||||
|
|
||||||
@item{The @racket[language] argument can be one of a fixed set of
|
|
||||||
symbols: @racket['r5rs], etc. They are converted by adding a
|
|
||||||
@racket[(list 'special ....)] wrapper.}
|
|
||||||
|
|
||||||
@item{If @racket[requires] starts with @racket['begin], then each
|
|
||||||
element in the remainder of the list is effectively evaluated
|
|
||||||
as a prefix to the program. Otherwise, it corresponds to the
|
|
||||||
@racket[#:requires] argument of @|racket-make-evaluator|.}
|
|
||||||
|
|
||||||
@item{For each of @racket[language] and @racket[requires] that starts
|
|
||||||
with @racket['begin], the expressions are inspected to find
|
|
||||||
top-level @racket[require] forms (using symbolic equality to
|
|
||||||
detect @racket[require]), and the @racket[require]d modules are
|
|
||||||
added to the @racket[#:allow] list for @|racket-make-evaluator|.}
|
|
||||||
|
|
||||||
]}
|
|
|
@ -1,29 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/sendevent))
|
|
||||||
|
|
||||||
@(begin
|
|
||||||
(define-syntax-rule (bind id)
|
|
||||||
(begin
|
|
||||||
(require (for-label scheme/gui/base))
|
|
||||||
(define id (racket send-event))))
|
|
||||||
(bind mred-send-event))
|
|
||||||
|
|
||||||
@mzlib[#:mode title sendevent]
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/sendevent] library provides a
|
|
||||||
@racket[send-event] function that works only on Mac OS X, and only
|
|
||||||
when running in GRacket (though the library can be loaded in Racket).
|
|
||||||
|
|
||||||
@defproc[(send-event [receiver-bytes (lambda (s) (and (bytes? s)
|
|
||||||
(= 4 (bytes-length s))))]
|
|
||||||
[event-class-bytes (lambda (s) (and (bytes? s)
|
|
||||||
(= 4 (bytes-length s))))]
|
|
||||||
[event-id-bytes (lambda (s) (and (bytes? s)
|
|
||||||
(= 4 (bytes-length s))))]
|
|
||||||
[direct-arg-v any/c (void)]
|
|
||||||
[argument-list list? null])
|
|
||||||
any/c]{
|
|
||||||
|
|
||||||
Calls @|mred-send-event| @racketmodname[scheme/gui/base], if
|
|
||||||
available, otherwise raises @racket[exn:fail:unsupported].}
|
|
|
@ -1,39 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/serialize))
|
|
||||||
|
|
||||||
@(begin
|
|
||||||
(define-syntax-rule (bind id id2)
|
|
||||||
(begin
|
|
||||||
(require (for-label racket/serialize))
|
|
||||||
(define id (racket define-serializable-struct))
|
|
||||||
(define id2 (racket define-serializable-struct/versions))))
|
|
||||||
(bind racket-define-serializable-struct
|
|
||||||
racket-define-serializable-struct/versions))
|
|
||||||
|
|
||||||
@mzlib[#:mode title serialize]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/serialize]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/serialize] library provides the same bindings
|
|
||||||
as @racketmodname[racket/serialize], except that
|
|
||||||
@racket[define-serializable-struct] and
|
|
||||||
@racket[define-serializable-struct/versions] are based on the syntax
|
|
||||||
of @racket[define-struct] from @racketmodname[mzscheme].
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defform[(define-serializable-struct id-maybe-super (field-id ...) maybe-inspector-expr)]
|
|
||||||
@defform/subs[(define-serializable-struct/versions id-maybe-super vers-num (field-id ...)
|
|
||||||
(other-version-clause ...)
|
|
||||||
maybe-inspector-expr)
|
|
||||||
([id-maybe-super id
|
|
||||||
(id super-id)]
|
|
||||||
[maybe-inspector-expr code:blank
|
|
||||||
inspector-expr]
|
|
||||||
[other-version-clause (other-vers make-proc-expr
|
|
||||||
cycle-make-proc-expr)])]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Like @racket-define-serializable-struct and
|
|
||||||
@racket-define-serializable-struct/versions, but with the syntax of
|
|
||||||
closer to @racket[define-struct] of @racketmodname[mzscheme].}
|
|
|
@ -1,118 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/string
|
|
||||||
scheme/contract
|
|
||||||
(only-in scheme/base
|
|
||||||
regexp-try-match)))
|
|
||||||
|
|
||||||
@mzlib[#:mode title string]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/base]]{
|
|
||||||
Also see @racketmodname[racket/string]
|
|
||||||
}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/string] library re-exports several functions
|
|
||||||
from @racketmodname[scheme/base]:
|
|
||||||
|
|
||||||
@racketblock[
|
|
||||||
real->decimal-string
|
|
||||||
regexp-quote
|
|
||||||
regexp-replace-quote
|
|
||||||
regexp-match*
|
|
||||||
regexp-match-positions*
|
|
||||||
regexp-match-peek-positions*
|
|
||||||
regexp-split
|
|
||||||
regexp-match-exact?
|
|
||||||
]
|
|
||||||
|
|
||||||
It also re-exports @racket[regexp-try-match] as
|
|
||||||
@racket[regexp-match/fail-without-reading].
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(glob->regexp [str (or/c string bytes?)?]
|
|
||||||
[hide-dots? any/c #t]
|
|
||||||
[case-sensitive? any/c (eq? (system-path-convention-type)'unix)]
|
|
||||||
[simple? any/c #f])
|
|
||||||
(or/c regexp? byte-regexp?)]{
|
|
||||||
|
|
||||||
Produces a regexp for a an input ``glob pattern'' @racket[str]. A
|
|
||||||
glob pattern is one that matches @litchar{*} with any string,
|
|
||||||
@litchar{?} with a single character, and character ranges are the same
|
|
||||||
as in regexps (unless @racket[simple?] is true). In addition, the
|
|
||||||
resulting regexp does not match strings that begin with @litchar{.},
|
|
||||||
unless @racket[str] begins with @litchar{.} or @racket[hide-dots?] is
|
|
||||||
@racket[#f]. The resulting regexp can be used with string file names
|
|
||||||
to check the glob pattern. If the glob pattern is provided as a byte
|
|
||||||
string, the result is a byte regexp.
|
|
||||||
|
|
||||||
The @racket[case-sensitive?] argument determines whether the resulting
|
|
||||||
regexp is case-sensitive.
|
|
||||||
|
|
||||||
If @racket[simple?] is true, then ranges with
|
|
||||||
@litchar{[}...@litchar{]} in @racket[str] are treated as literal
|
|
||||||
character sequences.}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(string-lowercase! [str (and/c string? (not/c immutable?))]) void?]{
|
|
||||||
|
|
||||||
Destructively changes @racket[str] to contain only lowercase
|
|
||||||
characters.}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(string-uppercase! [str (and/c string? (not/c immutable?))]) void?]{
|
|
||||||
|
|
||||||
Destructively changes @racket[str] to contain only uppercase
|
|
||||||
characters.}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(eval-string [str (or/c string? bytes?)]
|
|
||||||
[err-handler (or/c false/c
|
|
||||||
(any/c . -> . any/c)
|
|
||||||
(-> any/c))
|
|
||||||
#f])
|
|
||||||
list?]{
|
|
||||||
|
|
||||||
Reads and evaluates S-expressions from @racket[str], returning results
|
|
||||||
for all of the expressions in the string. If any expression produces
|
|
||||||
multiple results, the results are spliced into the resulting list. If
|
|
||||||
@racket[str] contains only whitespace and comments, an empty list is
|
|
||||||
returned, and if @racket[str] contains multiple expressions, the
|
|
||||||
result will be contain multiple values from all subexpressions.
|
|
||||||
|
|
||||||
The @racket[err-handler] argument can be:
|
|
||||||
@itemize[
|
|
||||||
@item{@racket[#f] (the default) which means that errors are not
|
|
||||||
caught;}
|
|
||||||
@item{a one-argument procedure, which will be used with an exception
|
|
||||||
(when an error occurs) and its result will be returned}
|
|
||||||
@item{a thunk, which will be used to produce a result.}
|
|
||||||
]}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(expr->string [expr any/c]) string?]{
|
|
||||||
|
|
||||||
Prints @racket[expr] into a string and returns the string.}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(read-from-string [str (or/c string? bytes?)]
|
|
||||||
[err-handler (or/c false/c
|
|
||||||
(any/c . -> . any/c)
|
|
||||||
(-> any/c))
|
|
||||||
#f])
|
|
||||||
any/c]{
|
|
||||||
|
|
||||||
Reads the first S-expression from @racket[str] and returns it. The
|
|
||||||
@racket[err-handler] is as in @racket[eval-string].}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(read-from-string-all [str (or/c string? bytes?)]
|
|
||||||
[err-handler (or/c false/c
|
|
||||||
(any/c . -> . any/c)
|
|
||||||
(-> any/c))
|
|
||||||
#f])
|
|
||||||
list?]{
|
|
||||||
|
|
||||||
Reads all S-expressions from the string (or byte string) @racket[str]
|
|
||||||
and returns them in a list. The @racket[err-handler] is as in
|
|
||||||
@racket[eval-string].}
|
|
|
@ -1,70 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
scribble/eval
|
|
||||||
(for-label mzlib/struct
|
|
||||||
scheme/contract
|
|
||||||
(only-in scheme/base
|
|
||||||
regexp-try-match)))
|
|
||||||
|
|
||||||
@(define struct-eval (make-base-eval))
|
|
||||||
@interaction-eval[#:eval struct-eval (require mzscheme)]
|
|
||||||
@interaction-eval[#:eval struct-eval (require mzlib/struct)]
|
|
||||||
|
|
||||||
@mzlib[#:mode title struct]
|
|
||||||
|
|
||||||
@defform[(copy-struct struct-id struct-expr
|
|
||||||
(accessor-id field-expr) ...)]{
|
|
||||||
|
|
||||||
``Functional update'' for structure instances. The result of
|
|
||||||
evaluating @racket[struct-expr] must be an instance of the structure
|
|
||||||
type named by @racket[struct-id]. The result of the
|
|
||||||
@racket[copy-struct] expression is a fresh instance of
|
|
||||||
@racket[struct-id] with the same field values as the result of
|
|
||||||
@racket[struct-expr], except that the value for the field accessed by
|
|
||||||
each @racket[accessor-id] is replaced by the result of
|
|
||||||
@racket[field-expr].
|
|
||||||
|
|
||||||
The result of @racket[struct-expr] might be an instance of a sub-type
|
|
||||||
of @racket[struct-id], but the result of the @racket[copy-struct]
|
|
||||||
expression is an immediate instance of @racket[struct-id]. If
|
|
||||||
@racket[struct-expr] does not produce an instance of
|
|
||||||
@racket[struct-id], the @racket[exn:fail:contract] exception is
|
|
||||||
raised.
|
|
||||||
|
|
||||||
If any @racket[accessor-id] is not bound to an accessor of
|
|
||||||
@racket[struct-id] (according to the expansion-time information
|
|
||||||
associated with @racket[struct-id]), or if the same
|
|
||||||
@racket[accessor-id] is used twice, then a syntax error is raised.}
|
|
||||||
|
|
||||||
|
|
||||||
@defform/subs[(define-struct/properties id (field-id ...)
|
|
||||||
((prop-expr val-expr) ...)
|
|
||||||
maybe-inspector-expr)
|
|
||||||
([maybe-inspector-expr code:blank
|
|
||||||
expr])]{
|
|
||||||
|
|
||||||
Like @racket[define-struct] from @racketmodname[mzscheme], but
|
|
||||||
properties can be attached to the structure type. Each
|
|
||||||
@racket[prop-expr] should produce a structure-type property value, and
|
|
||||||
each @racket[val-expr] produces the corresponding value for the
|
|
||||||
property.
|
|
||||||
|
|
||||||
@examples[
|
|
||||||
#:eval struct-eval
|
|
||||||
(define-struct/properties point (x y)
|
|
||||||
([prop:custom-write (lambda (p port write?)
|
|
||||||
(fprintf port "(~a, ~a)"
|
|
||||||
(point-x p)
|
|
||||||
(point-y p)))]))
|
|
||||||
(display (make-point 1 2))
|
|
||||||
]}
|
|
||||||
|
|
||||||
|
|
||||||
@defform[(make-->vector struct-id)]{
|
|
||||||
|
|
||||||
Builds a function that accepts a structure type instance (matching
|
|
||||||
@racket[struct-id]) and provides a vector of the fields of the
|
|
||||||
structure type instance.}
|
|
||||||
|
|
||||||
|
|
||||||
@close-eval[struct-eval]
|
|
|
@ -1,99 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/thread
|
|
||||||
racket/engine
|
|
||||||
scheme/contract
|
|
||||||
scheme/tcp))
|
|
||||||
|
|
||||||
@mzlib[#:mode title thread]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/engine]]{}
|
|
||||||
|
|
||||||
Re-exports the bindings from @racketmodname[racket/engine] under
|
|
||||||
different names and also provides two extra bindings. The renamings
|
|
||||||
are:
|
|
||||||
|
|
||||||
@itemlist[
|
|
||||||
@item{@racket[engine] as @racket[coroutine]}
|
|
||||||
@item{@racket[engine?] as @racket[coroutine?]}
|
|
||||||
@item{@racket[engine-run] as @racket[coroutine-run]}
|
|
||||||
@item{@racket[engine-result] as @racket[coroutine-result]}
|
|
||||||
@item{@racket[engine-kill] as @racket[coroutine-kill]}
|
|
||||||
]
|
|
||||||
|
|
||||||
@defproc[(consumer-thread [f procedure?][init (-> any) void])
|
|
||||||
(values thread? procedure?)]{
|
|
||||||
|
|
||||||
Returns two values: a thread descriptor for a new thread, and a
|
|
||||||
procedure with the same arity as @racket[f].
|
|
||||||
|
|
||||||
When the returned procedure is applied, its arguments are queued to be
|
|
||||||
passed on to @racket[f], and @|void-const| is immediately returned.
|
|
||||||
The thread created by @racket[consumer-thread] dequeues arguments and
|
|
||||||
applies @racket[f] to them, removing a new set of arguments from the
|
|
||||||
queue only when the previous application of @racket[f] has completed;
|
|
||||||
if @racket[f] escapes from a normal return (via an exception or a
|
|
||||||
continuation), the @racket[f]-applying thread terminates.
|
|
||||||
|
|
||||||
The @racket[init] argument is a procedure of no arguments; if it is
|
|
||||||
provided, @racket[init] is called in the new thread immediately after the
|
|
||||||
thread is created.}
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(run-server [port-no (integer-in 1 65535)]
|
|
||||||
[conn-proc (input-port? output-port? . -> . any)]
|
|
||||||
[conn-timeout (and/c real? (not/c negative?))]
|
|
||||||
[handler (exn? . -> . any/c) void]
|
|
||||||
[listen ((integer-in 1 65535) (one-of/c 5) (one-of/c #t)
|
|
||||||
. -> . listener?)
|
|
||||||
tcp-listen]
|
|
||||||
[close (listener? . -> . any) tcp-close]
|
|
||||||
[accept (listener? . ->* . (input-port? output-port?)) tcp-accept]
|
|
||||||
[accept/break (listener? . ->* . (input-port? output-port?)) tcp-accept/enable-break])
|
|
||||||
void?]{
|
|
||||||
|
|
||||||
Executes a TCP server on the port indicated by @racket[port-no]. When
|
|
||||||
a connection is made by a client, @racket[conn] is called with two
|
|
||||||
values: an input port to receive from the client, and an output port
|
|
||||||
to send to the client.
|
|
||||||
|
|
||||||
Each client connection is managed by a new custodian, and each call to
|
|
||||||
@racket[conn] occurs in a new thread (managed by the connection's
|
|
||||||
custodian). If the thread executing @racket[conn] terminates for any
|
|
||||||
reason (e.g., @racket[conn] returns), the connection's custodian is
|
|
||||||
shut down. Consequently, @racket[conn] need not close the ports
|
|
||||||
provided to it. Breaks are enabled in the connection thread if breaks
|
|
||||||
are enabled when @racket[run-server] is called.
|
|
||||||
|
|
||||||
To facilitate capturing a continuation in one connection thread and
|
|
||||||
invoking it in another, the parameterization of the
|
|
||||||
@racket[run-server] call is used for every call to
|
|
||||||
@racket[handler]. In this parameterization and for the connection's
|
|
||||||
thread, the @racket[current-custodian] parameter is assigned to the
|
|
||||||
connection's custodian.
|
|
||||||
|
|
||||||
If @racket[conn-timeout] is not @racket[#f], then it must be a
|
|
||||||
non-negative number specifying the time in seconds that a connection
|
|
||||||
thread is allowed to run before it is sent a break signal. Then, if
|
|
||||||
the thread runs longer than @racket[(* conn-timeout 2)] seconds, then
|
|
||||||
the connection's custodian is shut down. If @racket[conn-timeout] is
|
|
||||||
@racket[#f], a connection thread can run indefinitely.
|
|
||||||
|
|
||||||
If @racket[handler] is provided, it is passed exceptions related
|
|
||||||
to connections (i.e., exceptions not caught by @racket[conn-proc], or
|
|
||||||
exceptions that occur when trying to accept a connection). The default
|
|
||||||
handler ignores the exception and returns @|void-const|.
|
|
||||||
|
|
||||||
The @racket[run-server] function uses @racket[listen], @racket[close],
|
|
||||||
@racket[accept] and @racket[accept/break] in the same way as it might
|
|
||||||
use @racket[tcp-listen], @racket[tcp-close], @racket[tcp-accept], and
|
|
||||||
@racket[tcp-accept/enable-break] to accept connections. Provide
|
|
||||||
alternate procedures to use an alternate communication protocol (such
|
|
||||||
as SSL) or to supply optional arguments in the use of
|
|
||||||
@racket[tcp-listen]. The @racket[listener?] part of the contract
|
|
||||||
indicates that the procedures must all work on the same kind of
|
|
||||||
listener value.
|
|
||||||
|
|
||||||
The @racket[run-server] procedure loops to serve client connections,
|
|
||||||
so it never returns. If a break occurs, the loop will cleanly shut
|
|
||||||
down the server, but it will not terminate active connections.}
|
|
|
@ -1,22 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt")
|
|
||||||
|
|
||||||
@mzlib[#:mode title traceld]
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/traceld] library does not provide any
|
|
||||||
bindings. Instead, @racketmodname[mzlib/traceld] is @racket[require]d
|
|
||||||
for its side-effects.
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/traceld] library installs a new load handler
|
|
||||||
(see @racket[current-load]) and load-extension handler (see
|
|
||||||
@racket[current-load-extension]) to print information about the files
|
|
||||||
that are loaded. These handlers chain to the current handlers to
|
|
||||||
perform the actual loads. Trace output is printed to the port that is
|
|
||||||
the current error port (see @racket[current-error-port]) when the
|
|
||||||
library is instantiated.
|
|
||||||
|
|
||||||
Before a file is loaded, the tracer prints the file name and ``time''
|
|
||||||
(as reported by the procedure @racket[current-process-milliseconds])
|
|
||||||
when the load starts. Trace information for nested loads is printed
|
|
||||||
with indentation. After the file is loaded, the file name is printed
|
|
||||||
with the ``time'' that the load completed.
|
|
|
@ -1,22 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt")
|
|
||||||
|
|
||||||
@mzlib[#:mode title transcr]
|
|
||||||
|
|
||||||
The @racket[transcript-on] and @racket[transcript-off] procedures of
|
|
||||||
@racketmodname[mzscheme] always raise
|
|
||||||
@racket[exn:fail:unsupported]. The @racketmodname[mzlib/transcr]
|
|
||||||
library provides working versions of @racket[transcript-on] and
|
|
||||||
@racket[transcript-off].
|
|
||||||
|
|
||||||
@(define-syntax-rule (go)
|
|
||||||
(begin
|
|
||||||
(require (for-label mzlib/transcr))
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defproc[(transcript-on [filename any/c]) any]
|
|
||||||
@defproc[(transcript-off) any]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Starts/stops recording a transcript at @racket[filename].}))
|
|
||||||
@(go)
|
|
|
@ -1,57 +0,0 @@
|
||||||
#lang scribble/doc
|
|
||||||
@(require "common.rkt"
|
|
||||||
(for-label mzlib/unit))
|
|
||||||
|
|
||||||
@(begin
|
|
||||||
(define-syntax-rule (bind id)
|
|
||||||
(begin
|
|
||||||
(require (for-label racket/base))
|
|
||||||
(define id (racket struct))))
|
|
||||||
(bind racket-struct)
|
|
||||||
(define-syntax-rule (bindc id)
|
|
||||||
(begin
|
|
||||||
(require (for-label racket/unit))
|
|
||||||
(define id (racket struct/ctc))))
|
|
||||||
(bindc racket-struct/ctc))
|
|
||||||
|
|
||||||
@mzlib[#:mode title unit #:use-sources ((submod racket/unit compat))]
|
|
||||||
|
|
||||||
@deprecated[@racketmodname[racket/unit]]{}
|
|
||||||
|
|
||||||
The @racketmodname[mzlib/unit] library mostly re-provides
|
|
||||||
@racketmodname[racket/unit], except for @racket-struct and
|
|
||||||
@racket-struct/ctc from @racketmodname[racket/unit].
|
|
||||||
|
|
||||||
@defform/subs[(struct id (field-id ...) omit-decl ...)
|
|
||||||
([omit-decl -type
|
|
||||||
-selectors
|
|
||||||
-setters
|
|
||||||
-constructor])]{
|
|
||||||
|
|
||||||
A signature form like @racket-struct from @racketmodname[racket/base],
|
|
||||||
but with a different syntax for options that limit exports.}
|
|
||||||
|
|
||||||
@defform/subs[(struct/ctc id ([field-id contract-expr] ...) omit-decl ...)
|
|
||||||
([omit-decl -type
|
|
||||||
-selectors
|
|
||||||
-setters
|
|
||||||
-constructor])]{
|
|
||||||
|
|
||||||
A signature form like @racket-struct/ctc from @racketmodname[racket/unit],
|
|
||||||
but with a different syntax for the options that limit exports.}
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defidform[struct~r]
|
|
||||||
@defidform[struct~r/ctc]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
The same as @|racket-struct| from @racketmodname[racket/base] and @|racket-struct/ctc| from
|
|
||||||
@racketmodname[racket/unit].}
|
|
||||||
|
|
||||||
@deftogether[(
|
|
||||||
@defidform[struct~s]
|
|
||||||
@defidform[struct~s/ctc]
|
|
||||||
)]{
|
|
||||||
|
|
||||||
Like @racket[struct~r] and @racket[struct~r/ctc], but the constructor is
|
|
||||||
named the same as the type, instead of with @racketidfont{make-} prefix.}
|
|
|
@ -1,11 +0,0 @@
|
||||||
compatibility-lib
|
|
||||||
Copyright (c) 2010-2014 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
|
|
||||||
applications, provided you follow the rules stated in the LGPL. You
|
|
||||||
can also modify this package; if you distribute a modified version,
|
|
||||||
you must distribute it under the terms of the LGPL, which in
|
|
||||||
particular means that you must release the source code for the
|
|
||||||
modified software. See http://www.gnu.org/copyleft/lesser.html
|
|
||||||
for more information.
|
|
|
@ -1,136 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
;; defmacro - for legacy macros only
|
|
||||||
|
|
||||||
(require (for-syntax racket/base syntax/stx))
|
|
||||||
|
|
||||||
(provide define-macro
|
|
||||||
defmacro)
|
|
||||||
|
|
||||||
(define-syntax define-macro
|
|
||||||
(lambda (stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ (name . args) proc0 proc ...)
|
|
||||||
(begin
|
|
||||||
(unless (identifier? (syntax name))
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"expected an identifier for the macro name"
|
|
||||||
stx
|
|
||||||
(syntax name)))
|
|
||||||
(let loop ([args (syntax args)])
|
|
||||||
(cond
|
|
||||||
[(stx-null? args) 'ok]
|
|
||||||
[(identifier? args) 'ok]
|
|
||||||
[(stx-pair? args)
|
|
||||||
(unless (identifier? (stx-car args))
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"expected an identifier for a macro argument"
|
|
||||||
stx
|
|
||||||
(stx-car args)))
|
|
||||||
(loop (stx-cdr args))]
|
|
||||||
[else (raise-syntax-error
|
|
||||||
#f
|
|
||||||
"not a valid argument sequence after the macro name"
|
|
||||||
stx)]))
|
|
||||||
(syntax
|
|
||||||
(define-macro name (lambda args proc0 proc ...))))]
|
|
||||||
[(_ name proc)
|
|
||||||
(begin
|
|
||||||
(unless (identifier? (syntax name))
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"expected an identifier for the macro name"
|
|
||||||
stx
|
|
||||||
(syntax name)))
|
|
||||||
(syntax
|
|
||||||
(define-syntax name
|
|
||||||
(let ([p proc])
|
|
||||||
(unless (procedure? p)
|
|
||||||
(raise-type-error
|
|
||||||
'define-macro
|
|
||||||
"procedure (arity 1)"
|
|
||||||
p))
|
|
||||||
(lambda (stx)
|
|
||||||
(let ([l (syntax->list stx)])
|
|
||||||
(unless (and l (procedure-arity-includes? p (sub1 (length l))))
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"bad form"
|
|
||||||
stx))
|
|
||||||
(let ([ht (make-hash)])
|
|
||||||
(datum->syntax
|
|
||||||
stx
|
|
||||||
(dm-subst
|
|
||||||
ht
|
|
||||||
(apply p (cdr (dm-syntax->datum stx ht))))
|
|
||||||
stx))))))))])))
|
|
||||||
|
|
||||||
(define-syntax defmacro
|
|
||||||
(syntax-rules ()
|
|
||||||
[(_ name formals body1 body ...)
|
|
||||||
(define-macro (name . formals) body1 body ...)]))
|
|
||||||
|
|
||||||
;; helper submodule
|
|
||||||
;;
|
|
||||||
;; defined as a submodule because swindle requires it
|
|
||||||
(module dmhelp racket/base
|
|
||||||
(require syntax/stx)
|
|
||||||
|
|
||||||
(provide dm-syntax->datum
|
|
||||||
dm-subst)
|
|
||||||
|
|
||||||
;; `dm-syntax->datum' is like syntax-object->datum, but it also
|
|
||||||
;; builds a hash table that maps generated data to original syntax
|
|
||||||
;; objects. The hash table can then be used with `dm-subst' to
|
|
||||||
;; replace each re-used, unmodified datum with the original syntax
|
|
||||||
;; object.
|
|
||||||
|
|
||||||
(define (dm-syntax->datum stx ht)
|
|
||||||
;; Easiest to handle cycles by letting `syntax-object->datum'
|
|
||||||
;; do all the work.
|
|
||||||
(let ([v (syntax->datum stx)])
|
|
||||||
(let loop ([stx stx][v v])
|
|
||||||
(let ([already (hash-ref ht v (lambda () #f))])
|
|
||||||
(if already
|
|
||||||
(hash-set! ht v #t) ;; not stx => don't subst later
|
|
||||||
(hash-set! ht v stx))
|
|
||||||
(cond
|
|
||||||
[(stx-pair? stx)
|
|
||||||
(loop (stx-car stx) (car v))
|
|
||||||
(loop (stx-cdr stx) (cdr v))]
|
|
||||||
[(stx-null? stx) null]
|
|
||||||
[(vector? (syntax-e stx))
|
|
||||||
(for-each
|
|
||||||
loop
|
|
||||||
(vector->list
|
|
||||||
(syntax-e stx))
|
|
||||||
(vector->list v))]
|
|
||||||
[(box? (syntax-e stx))
|
|
||||||
(loop (unbox (syntax-e stx))
|
|
||||||
(unbox v))]
|
|
||||||
[else (void)])))
|
|
||||||
v))
|
|
||||||
|
|
||||||
(define (dm-subst ht v)
|
|
||||||
(define cycle-ht (make-hash))
|
|
||||||
(let loop ([v v])
|
|
||||||
(if (hash-ref cycle-ht v (lambda () #f))
|
|
||||||
v
|
|
||||||
(begin
|
|
||||||
(hash-set! cycle-ht v #t)
|
|
||||||
(let ([m (hash-ref ht v (lambda () #f))])
|
|
||||||
(cond
|
|
||||||
[(syntax? m) m] ;; subst back!
|
|
||||||
[(pair? v) (cons (loop (car v))
|
|
||||||
(loop (cdr v)))]
|
|
||||||
[(vector? v) (list->vector
|
|
||||||
(map
|
|
||||||
loop
|
|
||||||
(vector->list v)))]
|
|
||||||
[(box? v) (box (loop (unbox v)))]
|
|
||||||
[else v])))))))
|
|
||||||
|
|
||||||
;; this require has to be here after the submodule
|
|
||||||
(require (for-syntax 'dmhelp))
|
|
|
@ -1,210 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
(require (for-syntax racket/base)
|
|
||||||
racket/performance-hint)
|
|
||||||
|
|
||||||
(provide mmap
|
|
||||||
mfor-each
|
|
||||||
mlist
|
|
||||||
mlist?
|
|
||||||
mlength
|
|
||||||
mappend
|
|
||||||
mappend!
|
|
||||||
mreverse
|
|
||||||
mreverse!
|
|
||||||
mlist-tail
|
|
||||||
mlist-ref
|
|
||||||
mmemq
|
|
||||||
mmemv
|
|
||||||
mmember
|
|
||||||
massq
|
|
||||||
massv
|
|
||||||
massoc
|
|
||||||
mlist->list
|
|
||||||
list->mlist
|
|
||||||
mlistof)
|
|
||||||
|
|
||||||
(begin-encourage-inline
|
|
||||||
(define mmap
|
|
||||||
(case-lambda
|
|
||||||
[(f l) (let loop ([l l])
|
|
||||||
(cond
|
|
||||||
[(null? l) null]
|
|
||||||
[else (mcons (f (mcar l)) (loop (mcdr l)))]))]
|
|
||||||
[(f l1 l2) (let loop ([l1 l1][l2 l2])
|
|
||||||
(cond
|
|
||||||
[(null? l1) null]
|
|
||||||
[else (mcons (f (mcar l1) (mcar l2))
|
|
||||||
(loop (mcdr l1) (mcdr l2)))]))]
|
|
||||||
[(f l . ls) (let loop ([l l][ls ls])
|
|
||||||
(cond
|
|
||||||
[(null? l) null]
|
|
||||||
[else (mcons (apply f (mcar l) (map mcar ls))
|
|
||||||
(loop (mcdr l) (map mcdr ls)))]))]))
|
|
||||||
|
|
||||||
(define mfor-each
|
|
||||||
(case-lambda
|
|
||||||
[(f l) (let loop ([l l])
|
|
||||||
(cond
|
|
||||||
[(null? l) (void)]
|
|
||||||
[else (f (mcar l))
|
|
||||||
(loop (mcdr l))]))]
|
|
||||||
[(f l1 l2) (let loop ([l1 l1][l2 l2])
|
|
||||||
(cond
|
|
||||||
[(null? l1) (void)]
|
|
||||||
[else (f (mcar l1) (mcar l2))
|
|
||||||
(loop (mcdr l1) (mcdr l2))]))]
|
|
||||||
[(f l . ls) (let loop ([l l][ls ls])
|
|
||||||
(cond
|
|
||||||
[(null? l) (void)]
|
|
||||||
[else (apply f (mcar l) (map mcar ls))
|
|
||||||
(loop (mcdr l) (map mcdr ls))]))])))
|
|
||||||
|
|
||||||
(define (list->mlist l)
|
|
||||||
(cond
|
|
||||||
[(null? l) null]
|
|
||||||
[else (mcons (car l) (list->mlist (cdr l)))]))
|
|
||||||
|
|
||||||
(define (mlist->list l)
|
|
||||||
(cond
|
|
||||||
[(null? l) null]
|
|
||||||
[else (cons (mcar l) (mlist->list (mcdr l)))]))
|
|
||||||
|
|
||||||
(define-syntax mlist
|
|
||||||
(make-set!-transformer
|
|
||||||
(lambda (stx)
|
|
||||||
(syntax-case stx (set!)
|
|
||||||
[(set! id . _) (raise-syntax-error #f
|
|
||||||
"cannot mutate imported variable"
|
|
||||||
stx
|
|
||||||
#'id)]
|
|
||||||
[(_ a) #'(mcons a null)]
|
|
||||||
[(_ a b) #'(mcons a (mcons b null))]
|
|
||||||
[(_ a b c) #'(mcons a (mcons b (mcons c null)))]
|
|
||||||
[(_ arg ...) #'(-mlist arg ...)]
|
|
||||||
[_ #'-mlist]))))
|
|
||||||
|
|
||||||
(define -mlist
|
|
||||||
(let ([mlist
|
|
||||||
(case-lambda
|
|
||||||
[() null]
|
|
||||||
[(a) (mcons a null)]
|
|
||||||
[(a b) (mcons a (mcons b null))]
|
|
||||||
[(a b c) (mcons a (mcons b (mcons c null)))]
|
|
||||||
[(a b c d) (mcons a (mcons b (mcons c (mcons d null))))]
|
|
||||||
[l (list->mlist l)])])
|
|
||||||
mlist))
|
|
||||||
|
|
||||||
(define (mlist? l)
|
|
||||||
(cond
|
|
||||||
[(null? l) #t]
|
|
||||||
[(mpair? l)
|
|
||||||
(let loop ([turtle l][hare (mcdr l)])
|
|
||||||
(cond
|
|
||||||
[(null? hare) #t]
|
|
||||||
[(eq? hare turtle) #f]
|
|
||||||
[(mpair? hare)
|
|
||||||
(let ([hare (mcdr hare)])
|
|
||||||
(cond
|
|
||||||
[(null? hare) #t]
|
|
||||||
[(eq? hare turtle) #f]
|
|
||||||
[(mpair? hare)
|
|
||||||
(loop (mcdr turtle) (mcdr hare))]
|
|
||||||
[else #f]))]
|
|
||||||
[else #f]))]
|
|
||||||
[else #f]))
|
|
||||||
|
|
||||||
(define (mlength l)
|
|
||||||
(let loop ([l l][len 0])
|
|
||||||
(cond
|
|
||||||
[(null? l) len]
|
|
||||||
[else (loop (mcdr l) (add1 len))])))
|
|
||||||
|
|
||||||
(define mappend
|
|
||||||
(case-lambda
|
|
||||||
[() null]
|
|
||||||
[(a) a]
|
|
||||||
[(a b) (let loop ([a a])
|
|
||||||
(if (null? a)
|
|
||||||
b
|
|
||||||
(mcons (mcar a) (loop (mcdr a)))))]
|
|
||||||
[(a . l) (mappend a (apply mappend l))]))
|
|
||||||
|
|
||||||
;; mappend! : like append, but mutate each list to refer to the next.
|
|
||||||
;; modeled loosely on the v372 behavior
|
|
||||||
|
|
||||||
(define mappend!
|
|
||||||
(case-lambda
|
|
||||||
[() null]
|
|
||||||
[(a) a]
|
|
||||||
[(a b) (if (null? a)
|
|
||||||
b
|
|
||||||
(let loop ([atail a])
|
|
||||||
(cond [(null? (mcdr atail)) (set-mcdr! atail b) a]
|
|
||||||
[else (loop (mcdr atail))])))]
|
|
||||||
[(a . l) (mappend! a (apply mappend! l))]))
|
|
||||||
|
|
||||||
(define (mreverse l)
|
|
||||||
(let loop ([l l][a null])
|
|
||||||
(cond
|
|
||||||
[(null? l) a]
|
|
||||||
[else (loop (mcdr l) (mcons (mcar l) a))])))
|
|
||||||
|
|
||||||
(define (mreverse! l)
|
|
||||||
(let loop ([l l][prev null])
|
|
||||||
(cond
|
|
||||||
[(null? l) prev]
|
|
||||||
[else (let ([next (mcdr l)])
|
|
||||||
(set-mcdr! l prev)
|
|
||||||
(loop next l))])))
|
|
||||||
|
|
||||||
(define (mlist-tail l n)
|
|
||||||
(cond
|
|
||||||
[(zero? n) l]
|
|
||||||
[else (mlist-tail (mcdr l) (sub1 n))]))
|
|
||||||
|
|
||||||
(define (mlist-ref l n)
|
|
||||||
(cond
|
|
||||||
[(zero? n) (mcar l)]
|
|
||||||
[else (mlist-ref (mcdr l) (sub1 n))]))
|
|
||||||
|
|
||||||
(define (do-member =? v l)
|
|
||||||
(let loop ([l l])
|
|
||||||
(cond
|
|
||||||
[(null? l) #f]
|
|
||||||
[(=? v (mcar l)) l]
|
|
||||||
[else (loop (mcdr l))])))
|
|
||||||
|
|
||||||
(define (mmemq v l)
|
|
||||||
(do-member eq? v l))
|
|
||||||
|
|
||||||
(define (mmemv v l)
|
|
||||||
(do-member eqv? v l))
|
|
||||||
|
|
||||||
(define (mmember v l)
|
|
||||||
(do-member equal? v l))
|
|
||||||
|
|
||||||
|
|
||||||
(define (do-assoc =? v l)
|
|
||||||
(let loop ([l l])
|
|
||||||
(cond
|
|
||||||
[(null? l) #f]
|
|
||||||
[(=? v (mcar (mcar l))) (mcar l)]
|
|
||||||
[else (loop (mcdr l))])))
|
|
||||||
|
|
||||||
(define (massq v l)
|
|
||||||
(do-assoc eq? v l))
|
|
||||||
|
|
||||||
(define (massv v l)
|
|
||||||
(do-assoc eqv? v l))
|
|
||||||
|
|
||||||
(define (massoc v l)
|
|
||||||
(do-assoc equal? v l))
|
|
||||||
|
|
||||||
(define ((mlistof p?) l)
|
|
||||||
(let loop ([l l])
|
|
||||||
(cond
|
|
||||||
[(null? l) #t]
|
|
||||||
[(not (mpair? l)) #f]
|
|
||||||
[(p? (mcar l)) (loop (mcdr l))]
|
|
||||||
[else #f])))
|
|
|
@ -1,458 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require (for-syntax racket/base
|
|
||||||
racket/list
|
|
||||||
syntax/kerncase
|
|
||||||
syntax/boundmap
|
|
||||||
syntax/define
|
|
||||||
syntax/flatten-begin
|
|
||||||
syntax/context))
|
|
||||||
|
|
||||||
(provide define-package
|
|
||||||
package-begin
|
|
||||||
|
|
||||||
open-package
|
|
||||||
open*-package
|
|
||||||
|
|
||||||
define*
|
|
||||||
define*-values
|
|
||||||
define*-syntax
|
|
||||||
define*-syntaxes
|
|
||||||
|
|
||||||
(for-syntax package?
|
|
||||||
package-exported-identifiers
|
|
||||||
package-original-identifiers))
|
|
||||||
|
|
||||||
(define-for-syntax (do-define-* stx define-values-id)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ (id ...) rhs)
|
|
||||||
(let ([ids (syntax->list #'(id ...))])
|
|
||||||
(for-each (lambda (id)
|
|
||||||
(unless (identifier? id)
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"expected an identifier for definition"
|
|
||||||
stx
|
|
||||||
id)))
|
|
||||||
ids)
|
|
||||||
(with-syntax ([define-values define-values-id])
|
|
||||||
(syntax/loc stx
|
|
||||||
(define-values (id ...) rhs))))]))
|
|
||||||
(define-syntax (-define*-values stx)
|
|
||||||
(do-define-* stx #'define-values))
|
|
||||||
(define-syntax (-define*-syntaxes stx)
|
|
||||||
(do-define-* stx #'define-syntaxes))
|
|
||||||
(define-syntax (define*-values stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ (id ...) rhs)
|
|
||||||
(syntax-property
|
|
||||||
(syntax/loc stx (-define*-values (id ...) rhs))
|
|
||||||
'certify-mode
|
|
||||||
'transparent-binding)]))
|
|
||||||
(define-syntax (define*-syntaxes stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ (id ...) rhs)
|
|
||||||
(syntax-property
|
|
||||||
(syntax/loc stx (-define*-syntaxes (id ...) rhs))
|
|
||||||
'certify-mode
|
|
||||||
'transparent-binding)]))
|
|
||||||
|
|
||||||
(define-syntax (define* stx)
|
|
||||||
(let-values ([(id rhs) (normalize-definition stx #'lambda)])
|
|
||||||
(quasisyntax/loc stx
|
|
||||||
(define*-values (#,id) #,rhs))))
|
|
||||||
(define-syntax (define*-syntax stx)
|
|
||||||
(let-values ([(id rhs) (normalize-definition stx #'lambda)])
|
|
||||||
(quasisyntax/loc stx
|
|
||||||
(define*-syntaxes (#,id) #,rhs))))
|
|
||||||
|
|
||||||
(begin-for-syntax
|
|
||||||
(define-struct package (exports hidden)
|
|
||||||
#:omit-define-syntaxes
|
|
||||||
#:property prop:procedure (lambda (r stx)
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"misuse of a package name"
|
|
||||||
stx)))
|
|
||||||
|
|
||||||
(define (generate-hidden id)
|
|
||||||
;; Like `generate-temporaries', but preserve the symbolic name
|
|
||||||
((make-syntax-introducer) (datum->syntax #f (syntax-e id))))
|
|
||||||
|
|
||||||
(define (reverse-mapping who id exports hidden)
|
|
||||||
(or (ormap (lambda (m)
|
|
||||||
(and (free-identifier=? id (cdr m))
|
|
||||||
(car m)))
|
|
||||||
exports)
|
|
||||||
(ormap (lambda (h)
|
|
||||||
(and (free-identifier=? id h)
|
|
||||||
;; Not at top level, where free-id=? is unreliable,
|
|
||||||
;; and re-definition is ok:
|
|
||||||
(identifier-binding id)
|
|
||||||
;; Name is inaccessible. Generate a temporary to
|
|
||||||
;; avoid potential duplicate-definition errors
|
|
||||||
;; when the name is bound in the same context as
|
|
||||||
;; the package.
|
|
||||||
(generate-hidden id)))
|
|
||||||
hidden)
|
|
||||||
id)))
|
|
||||||
|
|
||||||
(define-for-syntax (move-props orig new)
|
|
||||||
(datum->syntax new
|
|
||||||
(syntax-e new)
|
|
||||||
orig
|
|
||||||
orig))
|
|
||||||
|
|
||||||
(define-for-syntax code-insp (variable-reference->module-declaration-inspector
|
|
||||||
(#%variable-reference)))
|
|
||||||
(define-for-syntax (disarm* stx)
|
|
||||||
(cond
|
|
||||||
[(and (syntax? stx)
|
|
||||||
(pair? (syntax-e stx)))
|
|
||||||
(let ([stx (syntax-disarm stx code-insp)])
|
|
||||||
(datum->syntax stx (disarm* (syntax-e stx)) stx stx))]
|
|
||||||
[(pair? stx) (cons (disarm* (car stx)) (disarm* (cdr stx)))]
|
|
||||||
[else stx]))
|
|
||||||
|
|
||||||
(define-for-syntax (do-define-package stx exp-stx)
|
|
||||||
(syntax-case exp-stx ()
|
|
||||||
[(_ pack-id mode exports form ...)
|
|
||||||
(let ([id #'pack-id]
|
|
||||||
[exports #'exports]
|
|
||||||
[mode (syntax-e #'mode)])
|
|
||||||
(unless (eq? mode '#:begin)
|
|
||||||
(unless (identifier? id)
|
|
||||||
(raise-syntax-error #f
|
|
||||||
"expected an identifier"
|
|
||||||
stx
|
|
||||||
id)))
|
|
||||||
(let ([exports
|
|
||||||
(cond
|
|
||||||
[(syntax->list exports)
|
|
||||||
=> (lambda (l)
|
|
||||||
(for-each (lambda (i)
|
|
||||||
(unless (identifier? i)
|
|
||||||
(raise-syntax-error #f
|
|
||||||
"expected identifier to export"
|
|
||||||
stx
|
|
||||||
i)))
|
|
||||||
l)
|
|
||||||
(let ([dup-id (check-duplicate-identifier l)])
|
|
||||||
(when dup-id
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"duplicate export"
|
|
||||||
stx
|
|
||||||
dup-id)))
|
|
||||||
l)]
|
|
||||||
[else (raise-syntax-error #f
|
|
||||||
(format "expected a parenthesized sequence of identifiers ~a"
|
|
||||||
(case mode
|
|
||||||
[(#:only) "to export"]
|
|
||||||
[(#:all-defined-except) "to exclude from export"]
|
|
||||||
[else (format "for ~a" mode)]))
|
|
||||||
stx
|
|
||||||
exports)])])
|
|
||||||
(let* ([def-ctx (syntax-local-make-definition-context)]
|
|
||||||
[ctx (generate-expand-context #t)]
|
|
||||||
[pre-package-id (lambda (id def-ctxes)
|
|
||||||
(identifier-remove-from-definition-context
|
|
||||||
id
|
|
||||||
def-ctxes))]
|
|
||||||
[kernel-forms (list*
|
|
||||||
#'-define*-values
|
|
||||||
#'-define*-syntaxes
|
|
||||||
(kernel-form-identifier-list))]
|
|
||||||
[init-exprs (syntax->list #'(form ...))]
|
|
||||||
[new-bindings (make-bound-identifier-mapping)]
|
|
||||||
[fixup-sub-package (lambda (renamed-exports renamed-defines def-ctxes)
|
|
||||||
(lambda (stx)
|
|
||||||
(syntax-case* (disarm* stx) (define-syntaxes #%plain-app make-package quote-syntax
|
|
||||||
list cons #%plain-lambda)
|
|
||||||
free-transformer-identifier=?
|
|
||||||
[(define-syntaxes (pack-id)
|
|
||||||
(#%plain-app
|
|
||||||
make-package
|
|
||||||
(#%plain-lambda ()
|
|
||||||
(#%plain-app list
|
|
||||||
(#%plain-app cons
|
|
||||||
(quote-syntax export)
|
|
||||||
(quote-syntax renamed))
|
|
||||||
...))
|
|
||||||
hidden))
|
|
||||||
(with-syntax ([(export ...)
|
|
||||||
(map (lambda (id)
|
|
||||||
(if (or (ormap (lambda (e-id)
|
|
||||||
(bound-identifier=? id e-id))
|
|
||||||
renamed-exports)
|
|
||||||
(not (ormap (lambda (e-id)
|
|
||||||
(bound-identifier=? id e-id))
|
|
||||||
renamed-defines)))
|
|
||||||
;; Need to preserve the original
|
|
||||||
(pre-package-id id def-ctxes)
|
|
||||||
;; It's not accessible, so just hide the name
|
|
||||||
;; to avoid re-binding errors. (Is this necessary,
|
|
||||||
;; or would `pre-package-id' take care of it?)
|
|
||||||
(generate-hidden id)))
|
|
||||||
(syntax->list #'(export ...)))])
|
|
||||||
(syntax/loc stx
|
|
||||||
(define-syntaxes (pack-id)
|
|
||||||
(make-package
|
|
||||||
(lambda ()
|
|
||||||
(list (cons (quote-syntax export)
|
|
||||||
(quote-syntax renamed))
|
|
||||||
...))
|
|
||||||
hidden))))]
|
|
||||||
[_ stx])))]
|
|
||||||
[complement (lambda (bindings ids)
|
|
||||||
(let ([tmp (make-bound-identifier-mapping)])
|
|
||||||
(bound-identifier-mapping-for-each bindings
|
|
||||||
(lambda (k v)
|
|
||||||
(bound-identifier-mapping-put! tmp k #t)))
|
|
||||||
(for-each (lambda (id)
|
|
||||||
(bound-identifier-mapping-put! tmp id #f))
|
|
||||||
ids)
|
|
||||||
(filter
|
|
||||||
values
|
|
||||||
(bound-identifier-mapping-map tmp (lambda (k v) (and v k))))))])
|
|
||||||
(let ([register-bindings!
|
|
||||||
(lambda (ids)
|
|
||||||
(for-each (lambda (id)
|
|
||||||
(when (bound-identifier-mapping-get new-bindings id (lambda () #f))
|
|
||||||
(raise-syntax-error #f
|
|
||||||
"duplicate binding"
|
|
||||||
stx
|
|
||||||
id))
|
|
||||||
(bound-identifier-mapping-put! new-bindings
|
|
||||||
id
|
|
||||||
#t))
|
|
||||||
ids))]
|
|
||||||
[add-package-context (lambda (def-ctxes)
|
|
||||||
(lambda (stx)
|
|
||||||
(let ([q (local-expand #`(quote #,stx)
|
|
||||||
ctx
|
|
||||||
(list #'quote)
|
|
||||||
def-ctxes)])
|
|
||||||
(syntax-case q ()
|
|
||||||
[(_ stx) #'stx]))))])
|
|
||||||
(let loop ([exprs init-exprs]
|
|
||||||
[rev-forms null]
|
|
||||||
[def-ctxes (list def-ctx)])
|
|
||||||
(cond
|
|
||||||
[(null? exprs)
|
|
||||||
(for-each (lambda (def-ctx)
|
|
||||||
(internal-definition-context-seal def-ctx))
|
|
||||||
def-ctxes)
|
|
||||||
(let ([exports-renamed (map (add-package-context def-ctxes) exports)]
|
|
||||||
[defined-renamed (bound-identifier-mapping-map new-bindings
|
|
||||||
(lambda (k v) k))])
|
|
||||||
(for-each (lambda (ex renamed)
|
|
||||||
(unless (bound-identifier-mapping-get new-bindings
|
|
||||||
renamed
|
|
||||||
(lambda () #f))
|
|
||||||
(raise-syntax-error #f
|
|
||||||
(format "no definition for ~a identifier"
|
|
||||||
(case mode
|
|
||||||
[(#:only) "exported"]
|
|
||||||
[(#:all-defined-except) "excluded"]))
|
|
||||||
stx
|
|
||||||
ex)))
|
|
||||||
exports
|
|
||||||
exports-renamed)
|
|
||||||
(let-values ([(exports exports-renamed)
|
|
||||||
(if (memq mode '(#:only #:begin))
|
|
||||||
(values exports exports-renamed)
|
|
||||||
(let ([all-exports-renamed (complement new-bindings exports-renamed)])
|
|
||||||
;; In case of define*, get only the last definition:
|
|
||||||
(let ([tmp (make-bound-identifier-mapping)])
|
|
||||||
(for-each (lambda (id)
|
|
||||||
(bound-identifier-mapping-put!
|
|
||||||
tmp
|
|
||||||
((add-package-context def-ctxes)
|
|
||||||
(pre-package-id id def-ctxes))
|
|
||||||
#t))
|
|
||||||
all-exports-renamed)
|
|
||||||
(let* ([exports-renamed (bound-identifier-mapping-map tmp (lambda (k v) k))]
|
|
||||||
[exports (map (lambda (id) (pre-package-id id def-ctxes))
|
|
||||||
exports-renamed)])
|
|
||||||
(values exports exports-renamed)))))]
|
|
||||||
[(prune)
|
|
||||||
(lambda (stx)
|
|
||||||
(identifier-prune-lexical-context stx (list (syntax-e stx) '#%top)))])
|
|
||||||
(with-syntax ([(export ...) (map prune exports)]
|
|
||||||
[(renamed ...) (map prune exports-renamed)]
|
|
||||||
[(hidden ...) (map prune (complement new-bindings exports-renamed))])
|
|
||||||
(let ([body (map (fixup-sub-package exports-renamed defined-renamed def-ctxes)
|
|
||||||
(reverse rev-forms))])
|
|
||||||
(if (eq? mode '#:begin)
|
|
||||||
(if (eq? 'expression (syntax-local-context))
|
|
||||||
(quasisyntax/loc stx (let () #,@body))
|
|
||||||
(quasisyntax/loc stx (begin #,@body)))
|
|
||||||
(quasisyntax/loc stx
|
|
||||||
(begin
|
|
||||||
#,@(if (eq? 'top-level (syntax-local-context))
|
|
||||||
;; delcare all bindings before they are used:
|
|
||||||
#`((define-syntaxes #,defined-renamed (values)))
|
|
||||||
null)
|
|
||||||
#,@body
|
|
||||||
(define-syntax pack-id
|
|
||||||
(make-package
|
|
||||||
(lambda ()
|
|
||||||
(list (cons (quote-syntax export)
|
|
||||||
(quote-syntax renamed))
|
|
||||||
...))
|
|
||||||
(lambda ()
|
|
||||||
(list (quote-syntax hidden) ...)))))))))))]
|
|
||||||
[else
|
|
||||||
(let ([expr (local-expand (car exprs)
|
|
||||||
ctx
|
|
||||||
kernel-forms
|
|
||||||
def-ctxes)])
|
|
||||||
(syntax-case expr (begin)
|
|
||||||
[(begin . rest)
|
|
||||||
(loop (append (flatten-begin expr) (cdr exprs))
|
|
||||||
rev-forms
|
|
||||||
def-ctxes)]
|
|
||||||
[(def (id ...) rhs)
|
|
||||||
(and (or (free-identifier=? #'def #'define-syntaxes)
|
|
||||||
(free-identifier=? #'def #'-define*-syntaxes))
|
|
||||||
(andmap identifier? (syntax->list #'(id ...))))
|
|
||||||
(with-syntax ([rhs (local-transformer-expand
|
|
||||||
#'rhs
|
|
||||||
'expression
|
|
||||||
null)])
|
|
||||||
(let ([star? (free-identifier=? #'def #'-define*-syntaxes)]
|
|
||||||
[ids (syntax->list #'(id ...))])
|
|
||||||
(let* ([def-ctx (if star?
|
|
||||||
(syntax-local-make-definition-context (car def-ctxes))
|
|
||||||
(last def-ctxes))]
|
|
||||||
[ids (map
|
|
||||||
(lambda (id) (syntax-property id 'unshadowable #t))
|
|
||||||
(if star?
|
|
||||||
(map (add-package-context (list def-ctx)) ids)
|
|
||||||
ids))])
|
|
||||||
(syntax-local-bind-syntaxes ids #'rhs def-ctx)
|
|
||||||
(register-bindings! ids)
|
|
||||||
(loop (cdr exprs)
|
|
||||||
(cons (move-props expr #`(define-syntaxes #,ids rhs))
|
|
||||||
rev-forms)
|
|
||||||
(if star? (cons def-ctx def-ctxes) def-ctxes)))))]
|
|
||||||
[(def (id ...) rhs)
|
|
||||||
(and (or (free-identifier=? #'def #'define-values)
|
|
||||||
(free-identifier=? #'def #'-define*-values))
|
|
||||||
(andmap identifier? (syntax->list #'(id ...))))
|
|
||||||
(let ([star? (free-identifier=? #'def #'-define*-values)]
|
|
||||||
[ids (syntax->list #'(id ...))])
|
|
||||||
(let* ([def-ctx (if star?
|
|
||||||
(syntax-local-make-definition-context (car def-ctxes))
|
|
||||||
(last def-ctxes))]
|
|
||||||
[ids (map
|
|
||||||
(lambda (id) (syntax-property id 'unshadowable #t))
|
|
||||||
(if star?
|
|
||||||
(map (add-package-context (list def-ctx)) ids)
|
|
||||||
ids))])
|
|
||||||
(syntax-local-bind-syntaxes ids #f def-ctx)
|
|
||||||
(register-bindings! ids)
|
|
||||||
(loop (cdr exprs)
|
|
||||||
(cons (move-props expr #`(define-values #,ids rhs)) rev-forms)
|
|
||||||
(if star? (cons def-ctx def-ctxes) def-ctxes))))]
|
|
||||||
[else
|
|
||||||
(loop (cdr exprs)
|
|
||||||
(cons (if (and (eq? mode '#:begin)
|
|
||||||
(null? (cdr exprs)))
|
|
||||||
expr
|
|
||||||
#`(define-values () (begin #,expr (values))))
|
|
||||||
rev-forms)
|
|
||||||
def-ctxes)]))]))))))]))
|
|
||||||
|
|
||||||
(define-syntax (define-package stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ id #:all-defined form ...)
|
|
||||||
(do-define-package stx #'(define-package id #:all-defined () form ...))]
|
|
||||||
[(_ id #:all-defined-except ids form ...)
|
|
||||||
(do-define-package stx stx)]
|
|
||||||
[(_ id #:only ids form ...)
|
|
||||||
(do-define-package stx stx)]
|
|
||||||
[(_ id ids form ...)
|
|
||||||
(do-define-package stx #'(define-package id #:only ids form ...))]))
|
|
||||||
|
|
||||||
(define-syntax (package-begin stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ form ...)
|
|
||||||
(do-define-package stx #'(define-package #f #:begin () form ...))]))
|
|
||||||
|
|
||||||
(define-for-syntax (do-open stx define-syntaxes-id)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ pack-id)
|
|
||||||
(let ([id #'pack-id])
|
|
||||||
(unless (identifier? id)
|
|
||||||
(raise-syntax-error #f
|
|
||||||
"expected an identifier for a package"
|
|
||||||
stx
|
|
||||||
id))
|
|
||||||
(let ([v (syntax-local-value id (lambda () #f))])
|
|
||||||
(unless (package? v)
|
|
||||||
(raise-syntax-error #f
|
|
||||||
"identifier is not bound to a package"
|
|
||||||
stx
|
|
||||||
id))
|
|
||||||
(let ([introduce (syntax-local-make-delta-introducer
|
|
||||||
(syntax-local-introduce id))])
|
|
||||||
(with-syntax ([(intro ...)
|
|
||||||
(map (lambda (i)
|
|
||||||
(syntax-local-introduce
|
|
||||||
(syntax-local-get-shadower
|
|
||||||
(introduce i))))
|
|
||||||
(map car ((package-exports v))))]
|
|
||||||
[(defined ...)
|
|
||||||
(map (lambda (v) (syntax-local-introduce (cdr v)))
|
|
||||||
((package-exports v)))]
|
|
||||||
[((a . b) ...) (map (lambda (p)
|
|
||||||
(cons (syntax-local-introduce (car p))
|
|
||||||
(syntax-local-introduce (cdr p))))
|
|
||||||
((package-exports v)))]
|
|
||||||
[(h ...) (map syntax-local-introduce ((package-hidden v)))])
|
|
||||||
(syntax-property
|
|
||||||
#`(#,define-syntaxes-id (intro ...)
|
|
||||||
(let ([rev-map (lambda (x)
|
|
||||||
(reverse-mapping
|
|
||||||
'pack-id
|
|
||||||
x
|
|
||||||
(list (cons (quote-syntax a)
|
|
||||||
(quote-syntax b))
|
|
||||||
...)
|
|
||||||
(list (quote-syntax h) ...)))])
|
|
||||||
(values (make-rename-transformer #'defined rev-map)
|
|
||||||
...)))
|
|
||||||
'disappeared-use
|
|
||||||
(syntax-local-introduce id))))))]))
|
|
||||||
|
|
||||||
(define-syntax (open-package stx)
|
|
||||||
(do-open stx #'define-syntaxes))
|
|
||||||
(define-syntax (open*-package stx)
|
|
||||||
(do-open stx #'define*-syntaxes))
|
|
||||||
|
|
||||||
(define-for-syntax (package-exported-identifiers id)
|
|
||||||
(let ([v (and (identifier? id)
|
|
||||||
(syntax-local-value id (lambda () #f)))])
|
|
||||||
(unless (package? v)
|
|
||||||
(if (identifier? id)
|
|
||||||
(raise-arguments-error 'package-exported-identifiers "identifier is not bound to a package"
|
|
||||||
"identifier" id)
|
|
||||||
(raise-argument-error 'package-exported-identifiers "identifier?" id)))
|
|
||||||
(let ([introduce (syntax-local-make-delta-introducer
|
|
||||||
(syntax-local-introduce id))])
|
|
||||||
(map (lambda (i)
|
|
||||||
(syntax-local-introduce
|
|
||||||
(syntax-local-get-shadower
|
|
||||||
(introduce (car i)))))
|
|
||||||
((package-exports v))))))
|
|
||||||
|
|
||||||
(define-for-syntax (package-original-identifiers id)
|
|
||||||
(let ([v (and (identifier? id)
|
|
||||||
(syntax-local-value id (lambda () #f)))])
|
|
||||||
(unless (package? v)
|
|
||||||
(if (identifier? id)
|
|
||||||
(raise-arguments-error 'package-original-identifiers "identifier is not bound to a package"
|
|
||||||
"identifier" id)
|
|
||||||
(raise-argument-error 'package-original-identifiers "identifier?" id)))
|
|
||||||
(map cdr ((package-exports v)))))
|
|
|
@ -1,10 +0,0 @@
|
||||||
#lang info
|
|
||||||
(define collection 'multi)
|
|
||||||
(define deps '("scheme-lib"
|
|
||||||
"base"
|
|
||||||
"net-lib"
|
|
||||||
"sandbox-lib"))
|
|
||||||
|
|
||||||
(define pkg-desc "implementation (no documentation) part of \"compatibility\"")
|
|
||||||
|
|
||||||
(define pkg-authors '(eli mflatt robby samth))
|
|
|
@ -1,3 +0,0 @@
|
||||||
;; A tiny language to build our promises with no built-in interference
|
|
||||||
(module mz-without-promises mzscheme
|
|
||||||
(provide (all-from-except mzscheme delay force promise?)))
|
|
|
@ -1,29 +0,0 @@
|
||||||
(module a-signature mzscheme
|
|
||||||
(require-for-syntax racket/private/unit-compiletime
|
|
||||||
racket/private/unit-syntax)
|
|
||||||
(require "unit.rkt")
|
|
||||||
|
|
||||||
(provide (rename module-begin #%module-begin)
|
|
||||||
(all-from-except mzscheme #%module-begin)
|
|
||||||
(all-from "unit.rkt"))
|
|
||||||
|
|
||||||
(define-for-syntax (make-name s)
|
|
||||||
(string->symbol
|
|
||||||
(string-append (regexp-replace "-sig$" (symbol->string s) "")
|
|
||||||
"^")))
|
|
||||||
|
|
||||||
(define-syntax (module-begin stx)
|
|
||||||
(parameterize ((error-syntax stx))
|
|
||||||
(with-syntax ((name (make-name (syntax-property stx 'enclosing-module-name))))
|
|
||||||
(syntax-case stx ()
|
|
||||||
((_ . x)
|
|
||||||
(with-syntax ((((reqs ...) . (body ...))
|
|
||||||
(split-requires (checked-syntax->list #'x))))
|
|
||||||
(datum->syntax-object
|
|
||||||
stx
|
|
||||||
(syntax-e #'(#%module-begin
|
|
||||||
reqs ...
|
|
||||||
(provide name)
|
|
||||||
(define-signature name (body ...))))
|
|
||||||
stx))))))))
|
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
(module a-unit mzscheme
|
|
||||||
(require "unit.rkt")
|
|
||||||
(require-for-syntax syntax/kerncase)
|
|
||||||
|
|
||||||
(provide (rename module-begin #%module-begin)
|
|
||||||
(all-from-except mzscheme #%module-begin)
|
|
||||||
(all-from "unit.rkt"))
|
|
||||||
|
|
||||||
(define-for-syntax (make-name s)
|
|
||||||
(string->symbol
|
|
||||||
(string-append (regexp-replace "-unit$" (symbol->string s) "")
|
|
||||||
"@")))
|
|
||||||
|
|
||||||
;; Look for `import' and `export', and start processing the body:
|
|
||||||
(define-syntax (module-begin stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ elem ...)
|
|
||||||
(with-syntax ([((elem ...) . (literal ...))
|
|
||||||
(let loop ([elems (syntax->list #'(elem ...))]
|
|
||||||
[accum null])
|
|
||||||
(syntax-case elems (import export)
|
|
||||||
[((import . _1) (export . _2) . _3)
|
|
||||||
(cons (reverse accum) elems)]
|
|
||||||
[((import . _1) . _2)
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"expected an `export' clause after `import'"
|
|
||||||
stx)]
|
|
||||||
[()
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"missing an `import' clause"
|
|
||||||
stx)]
|
|
||||||
[_else
|
|
||||||
(loop (cdr elems) (cons (car elems) accum))]))])
|
|
||||||
(with-syntax ((name (datum->syntax-object
|
|
||||||
stx
|
|
||||||
(make-name (syntax-property stx 'enclosing-module-name))
|
|
||||||
stx))
|
|
||||||
(orig-stx stx))
|
|
||||||
(datum->syntax-object
|
|
||||||
stx
|
|
||||||
(syntax-e
|
|
||||||
#'(#%module-begin (a-unit-module orig-stx finish-a-unit (import export)
|
|
||||||
"original import form"
|
|
||||||
name (elem ...) (literal ...))))
|
|
||||||
stx
|
|
||||||
stx)))]))
|
|
||||||
|
|
||||||
;; Process one `require' form (and make sure it's a require form):
|
|
||||||
(define-syntax (a-unit-module stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ orig-stx finish stops separator name (elem1 elem ...) (literal ...))
|
|
||||||
(let ([e (local-expand #'elem1
|
|
||||||
'module
|
|
||||||
(append
|
|
||||||
(syntax->list #'stops)
|
|
||||||
(list*
|
|
||||||
#'require
|
|
||||||
#'require-for-syntax
|
|
||||||
#'require-for-template
|
|
||||||
(kernel-form-identifier-list))))])
|
|
||||||
(syntax-case e (begin)
|
|
||||||
[(req r ...)
|
|
||||||
(or (module-identifier=? #'req #'require)
|
|
||||||
(module-identifier=? #'req #'require-for-syntax)
|
|
||||||
(module-identifier=? #'req #'require-for-template))
|
|
||||||
#'(begin
|
|
||||||
(req r ...)
|
|
||||||
(a-unit-module orig-stx finish stops separator name (elem ...) (literal ...)))]
|
|
||||||
[(begin b ...)
|
|
||||||
#'(a-unit-module orig-stx finish stops separator name (b ... elem ...) (literal ...))]
|
|
||||||
[_else
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
(format "non-require form before ~a" (syntax-e #'separator))
|
|
||||||
#'orig-stx
|
|
||||||
e)]))]
|
|
||||||
[(_ orig-stx finish stops separator name () (literal ...))
|
|
||||||
#'(finish orig-stx name literal ...)]))
|
|
||||||
|
|
||||||
;; All requires are done, so finish handling the unit:
|
|
||||||
(define-syntax (finish-a-unit stx)
|
|
||||||
(syntax-case stx (import export)
|
|
||||||
[(_ orig-stx name imports exports elem ...)
|
|
||||||
#'(begin
|
|
||||||
(provide name)
|
|
||||||
(define-unit name imports exports elem ...))])))
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require racket/async-channel)
|
|
||||||
(provide (all-from-out racket/async-channel))
|
|
|
@ -1,256 +0,0 @@
|
||||||
|
|
||||||
(module awk mzscheme
|
|
||||||
(require-for-syntax syntax/stx)
|
|
||||||
|
|
||||||
(provide awk match:start match:end match:substring regexp-exec)
|
|
||||||
|
|
||||||
(define-syntax awk
|
|
||||||
(lambda (stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ next-record
|
|
||||||
(record field ...)
|
|
||||||
counter
|
|
||||||
((state-variable init-expr) ...)
|
|
||||||
continue
|
|
||||||
clause ...)
|
|
||||||
(and (identifier? (syntax counter))
|
|
||||||
(identifier? (syntax continue)))
|
|
||||||
(let ([clauses (syntax->list (syntax (clause ...)))]
|
|
||||||
[initvars null])
|
|
||||||
(with-syntax ([(local-state ...) (generate-temporaries
|
|
||||||
(syntax->list (syntax (state-variable ...))))])
|
|
||||||
(letrec ([get-after-clauses
|
|
||||||
(lambda ()
|
|
||||||
(let loop ([l clauses][afters null])
|
|
||||||
(cond
|
|
||||||
[(null? l) (if (stx-null? afters)
|
|
||||||
(syntax ((values state-variable ...)))
|
|
||||||
afters)]
|
|
||||||
[(syntax-case (car l) (after)
|
|
||||||
[(after . rest) (syntax rest)]
|
|
||||||
[_else #f])
|
|
||||||
=> (lambda (rest)
|
|
||||||
(with-syntax ([(after ...) afters])
|
|
||||||
(loop (cdr l) (syntax (after ... . rest)))))]
|
|
||||||
[else
|
|
||||||
(loop (cdr l) afters)])))]
|
|
||||||
[wrap-state
|
|
||||||
(lambda (e)
|
|
||||||
(syntax-case e (=>)
|
|
||||||
[(=> f)
|
|
||||||
(with-syntax ([body (wrap-state (syntax ((f arg))))])
|
|
||||||
(syntax (=> (lambda (arg)
|
|
||||||
. body))))]
|
|
||||||
[body
|
|
||||||
(syntax
|
|
||||||
((call-with-values (lambda () . body)
|
|
||||||
(lambda (local-state ... . extras)
|
|
||||||
(set! else-ready? #f)
|
|
||||||
(set! state-variable local-state)
|
|
||||||
...))))]))]
|
|
||||||
[make-range
|
|
||||||
(lambda (include-on? include-off? body rest)
|
|
||||||
(syntax-case body ()
|
|
||||||
[(t1 t2 . body)
|
|
||||||
(with-syntax ([on? (car (generate-temporaries '(1)))]
|
|
||||||
[t1 (make-test (syntax-e (syntax t1)) (syntax t1))]
|
|
||||||
[t2 (make-test (syntax-e (syntax t2)) (syntax t2))]
|
|
||||||
[body (wrap-state (syntax body))])
|
|
||||||
(with-syntax ([check (if include-on?
|
|
||||||
(if include-off?
|
|
||||||
(syntax post-on-on?)
|
|
||||||
(syntax on?))
|
|
||||||
(if include-off?
|
|
||||||
(syntax orig-on?)
|
|
||||||
(syntax (and orig-on? on?))))])
|
|
||||||
(set! initvars (cons (syntax (on? #f)) initvars))
|
|
||||||
(syntax
|
|
||||||
((let ([orig-on? on?])
|
|
||||||
(unless on?
|
|
||||||
(set! on? t1))
|
|
||||||
(let ([post-on-on? on?])
|
|
||||||
(when on?
|
|
||||||
(set! on? (not t2))))
|
|
||||||
(when check
|
|
||||||
. body))
|
|
||||||
. rest))))]
|
|
||||||
[_else (raise-syntax-error
|
|
||||||
#f
|
|
||||||
"bad range"
|
|
||||||
stx
|
|
||||||
body)]))]
|
|
||||||
[make-test
|
|
||||||
(lambda (test expr)
|
|
||||||
(cond
|
|
||||||
[(string? test)
|
|
||||||
(with-syntax ([g (car (generate-temporaries '(1)))]
|
|
||||||
[expr expr])
|
|
||||||
(set! initvars (cons (syntax (g (regexp expr))) initvars))
|
|
||||||
(syntax (regexp-exec g record)))]
|
|
||||||
[(number? test)
|
|
||||||
(with-syntax ([expr expr])
|
|
||||||
(syntax (= expr counter)))]
|
|
||||||
[else expr]))]
|
|
||||||
[get-testing-clauses
|
|
||||||
(lambda ()
|
|
||||||
(let loop ([l clauses])
|
|
||||||
(if (null? l)
|
|
||||||
null
|
|
||||||
(syntax-case (car l) ()
|
|
||||||
[(test-expr body ...)
|
|
||||||
(with-syntax ([rest (loop (cdr l))])
|
|
||||||
(let ([test (syntax-e (syntax test-expr))]
|
|
||||||
[body (syntax (body ...))])
|
|
||||||
(cond
|
|
||||||
[(or (string? test) (number? test))
|
|
||||||
(with-syntax ([t (make-test test (syntax test-expr))]
|
|
||||||
[body (wrap-state body)])
|
|
||||||
(syntax
|
|
||||||
((cond [t . body]
|
|
||||||
[else (void)])
|
|
||||||
. rest)))]
|
|
||||||
[(eq? test 'else)
|
|
||||||
(with-syntax ([body (wrap-state body)])
|
|
||||||
(syntax
|
|
||||||
((when else-ready? . body)
|
|
||||||
(set! else-ready? #t)
|
|
||||||
. rest)))]
|
|
||||||
[(eq? test 'range)
|
|
||||||
(make-range #f #f body (syntax rest))]
|
|
||||||
[(eq? test ':range)
|
|
||||||
(make-range #t #f body (syntax rest))]
|
|
||||||
[(eq? test 'range:)
|
|
||||||
(make-range #f #t body (syntax rest))]
|
|
||||||
[(eq? test ':range:)
|
|
||||||
(make-range #t #t body (syntax rest))]
|
|
||||||
[(eq? test 'after)
|
|
||||||
(syntax rest)]
|
|
||||||
[(eq? test '/)
|
|
||||||
(with-syntax ([g (car (generate-temporaries '(1)))])
|
|
||||||
(syntax-case* body (/) (lambda (a b)
|
|
||||||
(eq? (syntax-e a)
|
|
||||||
(syntax-e b)))
|
|
||||||
[(re / (var ...) . body)
|
|
||||||
(and (string? (syntax-e (syntax re)))
|
|
||||||
(andmap (lambda (x) (or (identifier? x)
|
|
||||||
(not (syntax-e x))))
|
|
||||||
(syntax->list (syntax (var ...)))))
|
|
||||||
(with-syntax ([(var ...)
|
|
||||||
(map (lambda (x)
|
|
||||||
(if (identifier? x)
|
|
||||||
x
|
|
||||||
(car (generate-temporaries '(1)))))
|
|
||||||
(syntax->list (syntax (var ...))))]
|
|
||||||
[body (wrap-state (syntax body))])
|
|
||||||
(set! initvars (cons (syntax (g (regexp re))) initvars))
|
|
||||||
(syntax
|
|
||||||
((cond
|
|
||||||
[(regexp-match re record)
|
|
||||||
=> (lambda (arg)
|
|
||||||
(apply
|
|
||||||
(lambda (var ...) . body)
|
|
||||||
arg))]
|
|
||||||
[else (void)])
|
|
||||||
. rest)))]
|
|
||||||
[_else (raise-syntax-error
|
|
||||||
#f
|
|
||||||
"bad / ... / clause"
|
|
||||||
stx
|
|
||||||
(car l))]))]
|
|
||||||
[else
|
|
||||||
(with-syntax ([body (wrap-state body)])
|
|
||||||
(syntax
|
|
||||||
((cond [test-expr . body]
|
|
||||||
[else (void)])
|
|
||||||
. rest)))])))]
|
|
||||||
[_else (raise-syntax-error
|
|
||||||
#f
|
|
||||||
"bad clause"
|
|
||||||
stx
|
|
||||||
(car l))]))))])
|
|
||||||
(with-syntax ([testing-clauses (get-testing-clauses)]
|
|
||||||
[after-clauses (get-after-clauses)]
|
|
||||||
[initvars initvars])
|
|
||||||
(syntax
|
|
||||||
(let ((state-variable init-expr) ...
|
|
||||||
. initvars)
|
|
||||||
(let loop ([counter 1])
|
|
||||||
(call-with-values (lambda () next-record)
|
|
||||||
(lambda (record field ...)
|
|
||||||
(if (eof-object? record)
|
|
||||||
(begin
|
|
||||||
. after-clauses)
|
|
||||||
(let ([else-ready? #t])
|
|
||||||
(let/ec escape
|
|
||||||
(let ([continue
|
|
||||||
(lambda (local-state ... . extras)
|
|
||||||
(set! state-variable local-state)
|
|
||||||
...
|
|
||||||
(escape))])
|
|
||||||
. testing-clauses))
|
|
||||||
(loop (add1 counter)))))))))))))]
|
|
||||||
;; Left out continue...
|
|
||||||
[(_ next-record
|
|
||||||
(record field-variable ...)
|
|
||||||
counter-variable
|
|
||||||
((state-variable init-expr) ...)
|
|
||||||
clause ...)
|
|
||||||
(identifier? (syntax counter-variable))
|
|
||||||
(syntax
|
|
||||||
(awk next-record
|
|
||||||
(record field-variable ...)
|
|
||||||
counter-variable
|
|
||||||
((state-variable init-expr) ...)
|
|
||||||
continue
|
|
||||||
clause ...))]
|
|
||||||
;; Left out counter...
|
|
||||||
[(_ next-record
|
|
||||||
(record field-variable ...)
|
|
||||||
((state-variable init-expr) ...)
|
|
||||||
continue-variable
|
|
||||||
clause ...)
|
|
||||||
(identifier? (syntax continue-variable))
|
|
||||||
(syntax
|
|
||||||
(awk next-record
|
|
||||||
(record field-variable ...)
|
|
||||||
counter
|
|
||||||
((state-variable init-expr) ...)
|
|
||||||
continue-variable
|
|
||||||
clause ...))]
|
|
||||||
;; Left out both...
|
|
||||||
[(_ next-record
|
|
||||||
(record field-variable ...)
|
|
||||||
((state-variable init-expr) ...)
|
|
||||||
clause ...)
|
|
||||||
(syntax
|
|
||||||
(awk next-record
|
|
||||||
(record field-variable ...)
|
|
||||||
counter
|
|
||||||
((state-variable init-expr) ...)
|
|
||||||
continue
|
|
||||||
clause ...))])))
|
|
||||||
|
|
||||||
(define-struct match (s a))
|
|
||||||
|
|
||||||
(define match:start
|
|
||||||
(case-lambda
|
|
||||||
[(rec) (match:start rec 0)]
|
|
||||||
[(rec which) (car (list-ref (match-a rec) which))]))
|
|
||||||
|
|
||||||
(define match:end
|
|
||||||
(case-lambda
|
|
||||||
[(rec) (match:end rec 0)]
|
|
||||||
[(rec which) (cdr (list-ref (match-a rec) which))]))
|
|
||||||
|
|
||||||
(define match:substring
|
|
||||||
(case-lambda
|
|
||||||
[(rec) (match:substring rec 0)]
|
|
||||||
[(rec which) (let ([p (list-ref (match-a rec) which)])
|
|
||||||
(substring (match-s rec) (car p) (cdr p)))]))
|
|
||||||
|
|
||||||
(define regexp-exec
|
|
||||||
(lambda (re s)
|
|
||||||
(let ([r (regexp-match-positions re s)])
|
|
||||||
(if r
|
|
||||||
(make-match s r)
|
|
||||||
#f)))))
|
|
|
@ -1,4 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require racket/private/class-internal
|
|
||||||
racket/private/class-c-old)
|
|
||||||
(provide-public-names)
|
|
|
@ -1,4 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
(require compiler/cm-accomplice)
|
|
||||||
(provide (all-from-out compiler/cm-accomplice))
|
|
|
@ -1,4 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
(require compiler/cm)
|
|
||||||
(provide (all-from-out compiler/cm))
|
|
|
@ -1,145 +0,0 @@
|
||||||
#lang mzscheme
|
|
||||||
|
|
||||||
(require (only racket/cmdline parse-command-line))
|
|
||||||
|
|
||||||
(provide command-line
|
|
||||||
parse-command-line)
|
|
||||||
|
|
||||||
(define-syntax (command-line stx)
|
|
||||||
(define (id=? x y)
|
|
||||||
(eq? (syntax-e x) (syntax-e y)))
|
|
||||||
(define (serror msg . detail)
|
|
||||||
(apply raise-syntax-error #f msg stx detail))
|
|
||||||
(define (extract-one what args . detail)
|
|
||||||
(if (null? args)
|
|
||||||
(apply serror (format "missing ~a" what) detail)
|
|
||||||
(values (car args) (cdr args))))
|
|
||||||
(define (extract-list stx/list pred)
|
|
||||||
(let loop ([xs null]
|
|
||||||
[rest (if (syntax? stx/list) (syntax->list stx/list) stx/list)])
|
|
||||||
(if (and (pair? rest) (pred (car rest)))
|
|
||||||
(loop (cons (car rest) xs) (cdr rest))
|
|
||||||
(values (reverse xs) rest))))
|
|
||||||
(define (formal-names l)
|
|
||||||
(map (lambda (a)
|
|
||||||
(datum->syntax-object
|
|
||||||
(quote-syntax here)
|
|
||||||
(let ([s (symbol->string (syntax-e a))])
|
|
||||||
(if (char=? #\* (string-ref s (sub1 (string-length s))))
|
|
||||||
(substring s 0 (sub1 (string-length s)))
|
|
||||||
s))
|
|
||||||
#f))
|
|
||||||
l))
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ program-name argv clause ...)
|
|
||||||
(let ([clauses
|
|
||||||
(let loop ([csrcs (syntax->list #'(clause ...))][clauses null])
|
|
||||||
(with-syntax ([(clause ...) clauses])
|
|
||||||
(if (null? csrcs)
|
|
||||||
#'((list clause ...) (lambda (accum) (void)) null)
|
|
||||||
(let ([line (car csrcs)]
|
|
||||||
[arest (cdr csrcs)])
|
|
||||||
(syntax-case* line (help-labels => args) id=?
|
|
||||||
[(help-labels s ...)
|
|
||||||
(begin
|
|
||||||
(unless (andmap (lambda (x) (string? (syntax-e x)))
|
|
||||||
(syntax->list #'(s ...)))
|
|
||||||
(serror "help-labels clause must contain only strings" line))
|
|
||||||
(loop arest #'(clause ... '(help-labels s ...))))]
|
|
||||||
[(tag . rest)
|
|
||||||
(ormap (lambda (x) (id=? #'tag x))
|
|
||||||
(syntax->list #'(once-each once-any multi final)))
|
|
||||||
(with-syntax
|
|
||||||
([sublines
|
|
||||||
(let slloop ([sublines (syntax->list #'rest)])
|
|
||||||
(if (null? sublines)
|
|
||||||
#'()
|
|
||||||
(with-syntax
|
|
||||||
([looped (slloop (cdr sublines))]
|
|
||||||
[subline
|
|
||||||
(with-syntax
|
|
||||||
([flags
|
|
||||||
(syntax-case (car sublines) ()
|
|
||||||
[((flag ...) . rest)
|
|
||||||
(begin
|
|
||||||
(unless (andmap
|
|
||||||
(lambda (x) (string? (syntax-e x)))
|
|
||||||
(syntax->list #'(flag ...)))
|
|
||||||
(serror
|
|
||||||
"flag specification is not a string or sequence of strings"
|
|
||||||
#'(flag ...)))
|
|
||||||
#'(flag ...))]
|
|
||||||
[(flag . rest)
|
|
||||||
(string? (syntax-e #'flag))
|
|
||||||
#'(flag)]
|
|
||||||
[else
|
|
||||||
(serror "clause does not start with flags")])])
|
|
||||||
(syntax-case* (car sublines) (=>) id=?
|
|
||||||
[(_ => a b)
|
|
||||||
#'(list 'flags a b)]
|
|
||||||
[(_ rest ...)
|
|
||||||
(let*-values ([(formals rest)
|
|
||||||
(extract-list #'(rest ...) identifier?)]
|
|
||||||
[(helps rest)
|
|
||||||
(extract-list
|
|
||||||
rest (lambda (x) (string? (syntax-e x))))]
|
|
||||||
[(expr1 rest)
|
|
||||||
(extract-one
|
|
||||||
"handler body expressions" rest line)])
|
|
||||||
(when (null? helps)
|
|
||||||
(serror "missing help string/s"))
|
|
||||||
(with-syntax ([formals formals]
|
|
||||||
[formal-names (formal-names formals)]
|
|
||||||
[helps helps]
|
|
||||||
[expr1 expr1]
|
|
||||||
[rest rest])
|
|
||||||
#'(list 'flags
|
|
||||||
(lambda (flag . formals) expr1 . rest)
|
|
||||||
'(helps . formal-names))))]))])
|
|
||||||
#'(subline . looped))))])
|
|
||||||
(loop arest #'(clause ... (list 'tag . sublines))))]
|
|
||||||
[(=> finish-proc arg-help help-proc unknown-proc)
|
|
||||||
(begin
|
|
||||||
(unless (null? arest)
|
|
||||||
(serror "=> must be the last clause line"))
|
|
||||||
#'((list clause ...)
|
|
||||||
finish-proc arg-help help-proc unknown-proc))]
|
|
||||||
[(=> finish-proc arg-help help-proc)
|
|
||||||
(begin
|
|
||||||
(unless (null? arest)
|
|
||||||
(serror "=> must be the last clause line"))
|
|
||||||
#'((list clause ...)
|
|
||||||
finish-proc arg-help help-proc))]
|
|
||||||
[(=> finish-proc arg-help)
|
|
||||||
(begin
|
|
||||||
(unless (null? arest)
|
|
||||||
(serror "=> must be the last clause line"))
|
|
||||||
#'((list clause ...) finish-proc arg-help))]
|
|
||||||
[(=> . _)
|
|
||||||
(serror "bad => line" line)]
|
|
||||||
[(args arg-formals body1 body ...)
|
|
||||||
(begin
|
|
||||||
(unless (null? arest)
|
|
||||||
(serror "args must be the last clause" line))
|
|
||||||
(let ([formals
|
|
||||||
(let loop ([f #'arg-formals])
|
|
||||||
(syntax-case f ()
|
|
||||||
[() null]
|
|
||||||
[(arg . rest)
|
|
||||||
(identifier? #'arg)
|
|
||||||
(cons #'arg (loop #'rest))]
|
|
||||||
[arg
|
|
||||||
(identifier? #'arg)
|
|
||||||
(list #'arg)]
|
|
||||||
[else
|
|
||||||
(serror "bad argument list" line)]))])
|
|
||||||
(with-syntax ([formal-names (formal-names formals)])
|
|
||||||
#'((list clause ...)
|
|
||||||
(lambda (accume . arg-formals)
|
|
||||||
body1 body ...)
|
|
||||||
'formal-names))))]
|
|
||||||
[(args . _)
|
|
||||||
(serror "bad args line" line)]
|
|
||||||
[else (serror "not a once-each, once-any, multi, final, args, or => line" line)])))))])
|
|
||||||
(with-syntax ([clauses clauses])
|
|
||||||
#'(parse-command-line program-name argv . clauses)))]))
|
|
|
@ -1,35 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require racket/contract/base)
|
|
||||||
|
|
||||||
(define (spawn thunk)
|
|
||||||
(thread/suspend-to-kill thunk))
|
|
||||||
|
|
||||||
(define (channel)
|
|
||||||
(make-channel))
|
|
||||||
|
|
||||||
(define (channel-recv-evt ch)
|
|
||||||
ch)
|
|
||||||
|
|
||||||
(define (channel-send-evt ch v)
|
|
||||||
(wrap-evt
|
|
||||||
(channel-put-evt ch v)
|
|
||||||
void))
|
|
||||||
|
|
||||||
(define (thread-done-evt th)
|
|
||||||
(thread-dead-evt th))
|
|
||||||
|
|
||||||
(define (current-time)
|
|
||||||
(current-inexact-milliseconds))
|
|
||||||
(define (time-evt t)
|
|
||||||
(alarm-evt t))
|
|
||||||
|
|
||||||
(provide/contract
|
|
||||||
(spawn ((-> any) . -> . thread?))
|
|
||||||
(channel (-> channel?))
|
|
||||||
(channel-recv-evt (channel? . -> . evt?))
|
|
||||||
(channel-send-evt (channel? any/c . -> . evt?))
|
|
||||||
|
|
||||||
(thread-done-evt (thread? . -> . evt?))
|
|
||||||
(current-time (-> number?))
|
|
||||||
(time-evt (real? . -> . evt?)))
|
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
|
|
||||||
(module compat mzscheme
|
|
||||||
|
|
||||||
(provide real-time
|
|
||||||
1+ 1-
|
|
||||||
>=? <=? >? <? =?
|
|
||||||
flush-output-port
|
|
||||||
gentemp
|
|
||||||
atom?
|
|
||||||
putprop getprop
|
|
||||||
new-cafe
|
|
||||||
define-structure)
|
|
||||||
|
|
||||||
(define 1+ add1)
|
|
||||||
(define 1- sub1)
|
|
||||||
|
|
||||||
(define =? =)
|
|
||||||
(define <? <)
|
|
||||||
(define >? >)
|
|
||||||
(define <=? <)
|
|
||||||
(define >=? >)
|
|
||||||
|
|
||||||
(define atom? (lambda (v) (not (pair? v))))
|
|
||||||
|
|
||||||
(define gentemp gensym)
|
|
||||||
|
|
||||||
(define flush-output-port flush-output)
|
|
||||||
|
|
||||||
(define real-time current-milliseconds)
|
|
||||||
|
|
||||||
(define table (make-hash-table))
|
|
||||||
(define getprop
|
|
||||||
(case-lambda
|
|
||||||
[(k prop) (getprop k prop #f)]
|
|
||||||
[(k prop def)
|
|
||||||
(let ([al (hash-table-get table k (lambda () #f))])
|
|
||||||
(if al
|
|
||||||
(let ([v (assq prop al)])
|
|
||||||
(if v
|
|
||||||
(unbox (cdr v))
|
|
||||||
def))
|
|
||||||
def))]))
|
|
||||||
(define putprop
|
|
||||||
(lambda (k prop nv)
|
|
||||||
(let ([al (hash-table-get table k (lambda () '()))])
|
|
||||||
(let ([v (assq prop al)])
|
|
||||||
(if v
|
|
||||||
(set-box! (cdr v) nv)
|
|
||||||
(hash-table-put! table k (cons (cons prop (box nv)) al)))))))
|
|
||||||
|
|
||||||
;; Chez's new-cafe
|
|
||||||
(define new-cafe
|
|
||||||
(letrec ([nc
|
|
||||||
(case-lambda
|
|
||||||
[() (nc (current-eval))]
|
|
||||||
[(eval)
|
|
||||||
(let/ec escape
|
|
||||||
(let ([orig-exit (exit-handler)]
|
|
||||||
[orig-eval (current-eval)])
|
|
||||||
(dynamic-wind
|
|
||||||
(lambda ()
|
|
||||||
(current-eval eval)
|
|
||||||
(exit-handler
|
|
||||||
(lambda (v) (escape v))))
|
|
||||||
read-eval-print-loop
|
|
||||||
(lambda ()
|
|
||||||
(current-eval orig-eval)
|
|
||||||
(exit-handler orig-exit)))))])])
|
|
||||||
nc))
|
|
||||||
|
|
||||||
(define-syntax define-structure
|
|
||||||
(lambda (stx)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ (sname field ...))
|
|
||||||
(syntax (define-structure (sname field ...) ()))]
|
|
||||||
[(_ (sname field ...) ([init-field init] ...))
|
|
||||||
(andmap identifier? (syntax->list
|
|
||||||
(syntax (sname field ... init-field ...))))
|
|
||||||
(let ([name (symbol->string (syntax-e (syntax sname)))]
|
|
||||||
[fields (map symbol->string
|
|
||||||
(map syntax-e
|
|
||||||
(syntax->list (syntax (field ...)))))]
|
|
||||||
[init-fields (map symbol->string
|
|
||||||
(map syntax-e
|
|
||||||
(syntax->list (syntax (init-field ...)))))]
|
|
||||||
[+ (lambda args
|
|
||||||
(datum->syntax-object
|
|
||||||
(syntax sname)
|
|
||||||
(string->symbol (apply string-append args))
|
|
||||||
(syntax sname)))])
|
|
||||||
(with-syntax ([struct: (+ "struct:" name)]
|
|
||||||
[make- (+ "make-" name)]
|
|
||||||
[? (+ name "?")]
|
|
||||||
[(gs ...)
|
|
||||||
(apply
|
|
||||||
append
|
|
||||||
(map (lambda (f) (list (+ name "-" f)
|
|
||||||
(+ "set-" name "-" f "!")))
|
|
||||||
(append fields init-fields)))])
|
|
||||||
(syntax
|
|
||||||
(define-values (struct: make- ? gs ...)
|
|
||||||
(let ()
|
|
||||||
(define-struct sname (field ... init-field ...))
|
|
||||||
(values struct:
|
|
||||||
(let ([make- (lambda (field ...)
|
|
||||||
(make- field ...
|
|
||||||
init ...))])
|
|
||||||
make-)
|
|
||||||
? gs ...))))))]))))
|
|
|
@ -1,4 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require compiler/compile-file)
|
|
||||||
|
|
||||||
(provide compile-file)
|
|
|
@ -1,209 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;
|
|
||||||
;; provide arrow contracts from our local copy (mostly)
|
|
||||||
;;
|
|
||||||
|
|
||||||
(require "private/contract-arrow.rkt")
|
|
||||||
(provide (all-from-out "private/contract-arrow.rkt"))
|
|
||||||
(require (only-in racket/contract/base unconstrained-domain->))
|
|
||||||
(provide unconstrained-domain->)
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;
|
|
||||||
;; provide contracts for objects
|
|
||||||
;;
|
|
||||||
(require "private/contract-object.rkt")
|
|
||||||
(provide (all-from-out "private/contract-object.rkt"))
|
|
||||||
|
|
||||||
(require (only-in racket/class
|
|
||||||
is-a?/c
|
|
||||||
implementation?/c
|
|
||||||
subclass?/c
|
|
||||||
mixin-contract
|
|
||||||
make-mixin-contract))
|
|
||||||
(provide is-a?/c
|
|
||||||
implementation?/c
|
|
||||||
subclass?/c
|
|
||||||
mixin-contract
|
|
||||||
make-mixin-contract)
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;
|
|
||||||
;; old-style define/contract
|
|
||||||
;;
|
|
||||||
|
|
||||||
(require "private/contract-define.rkt")
|
|
||||||
(provide (all-from-out "private/contract-define.rkt"))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;
|
|
||||||
;; old-style flat mutable contracts
|
|
||||||
;;
|
|
||||||
(require "private/contract-mutable.rkt")
|
|
||||||
(provide (all-from-out "private/contract-mutable.rkt"))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;
|
|
||||||
;; old-style flat struct contracts
|
|
||||||
;;
|
|
||||||
(require "private/contract-struct.rkt")
|
|
||||||
(provide (all-from-out "private/contract-struct.rkt"))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;
|
|
||||||
;; provide everything from the racket/ implementation
|
|
||||||
;; except the arrow contracts
|
|
||||||
;;
|
|
||||||
|
|
||||||
(require (prefix-in : racket/contract))
|
|
||||||
(require (for-syntax racket/provide-transform racket/base))
|
|
||||||
(define-syntax remove-prefix
|
|
||||||
(make-provide-transformer
|
|
||||||
(λ (stx ctxt)
|
|
||||||
(syntax-case stx ()
|
|
||||||
[(_ args ...)
|
|
||||||
(for/list ([arg (in-list (syntax->list #'(args ...)))])
|
|
||||||
(export arg
|
|
||||||
(string->symbol
|
|
||||||
(regexp-replace #rx"^:" (symbol->string (syntax-e arg)) ""))
|
|
||||||
0
|
|
||||||
#f
|
|
||||||
arg))]))))
|
|
||||||
|
|
||||||
(provide (remove-prefix
|
|
||||||
:define-contract-struct
|
|
||||||
:</c
|
|
||||||
:>/c
|
|
||||||
:chaperone-contract?
|
|
||||||
:contract-name
|
|
||||||
:contract-projection
|
|
||||||
:contract?
|
|
||||||
:false/c
|
|
||||||
:flat-contract
|
|
||||||
:flat-contract-predicate
|
|
||||||
:flat-contract?
|
|
||||||
:flat-named-contract
|
|
||||||
:impersonator-contract?
|
|
||||||
:make-none/c
|
|
||||||
:n->th
|
|
||||||
:natural-number/c
|
|
||||||
:printable/c
|
|
||||||
:promise/c
|
|
||||||
:or/c
|
|
||||||
:prompt-tag/c
|
|
||||||
:>=/c
|
|
||||||
:syntax/c
|
|
||||||
:any
|
|
||||||
:non-empty-listof
|
|
||||||
:any/c
|
|
||||||
:between/c
|
|
||||||
:cons/c
|
|
||||||
:integer-in
|
|
||||||
:symbols
|
|
||||||
:real-in
|
|
||||||
:list/c
|
|
||||||
:continuation-mark-key/c
|
|
||||||
:one-of/c
|
|
||||||
:procedure-arity-includes/c
|
|
||||||
:not/c
|
|
||||||
:flat-rec-contract
|
|
||||||
:flat-murec-contract
|
|
||||||
:=/c
|
|
||||||
:and/c
|
|
||||||
:parameter/c
|
|
||||||
:none/c
|
|
||||||
:<=/c
|
|
||||||
:listof
|
|
||||||
:contract
|
|
||||||
:current-contract-region
|
|
||||||
:recursive-contract
|
|
||||||
:provide/contract
|
|
||||||
:build-compound-type-name
|
|
||||||
:coerce-chaperone-contract
|
|
||||||
:coerce-chaperone-contracts
|
|
||||||
:coerce-contract
|
|
||||||
:coerce-contract/f
|
|
||||||
:coerce-contracts
|
|
||||||
:coerce-flat-contract
|
|
||||||
:coerce-flat-contracts
|
|
||||||
:contract-first-order
|
|
||||||
:contract-first-order-passes?
|
|
||||||
:contract-stronger?
|
|
||||||
:eq-contract-val
|
|
||||||
:eq-contract?
|
|
||||||
:equal-contract-val
|
|
||||||
:equal-contract?
|
|
||||||
:has-contract?
|
|
||||||
:impersonator-prop:contracted
|
|
||||||
:prop:contracted
|
|
||||||
:value-contract
|
|
||||||
:define/subexpression-pos-prop
|
|
||||||
:define/final-prop
|
|
||||||
:blame-add-unknown-context
|
|
||||||
:blame-context
|
|
||||||
:blame-contract
|
|
||||||
:blame-fmt->-string
|
|
||||||
:blame-negative
|
|
||||||
:blame-original?
|
|
||||||
:blame-positive
|
|
||||||
:blame-replace-negative
|
|
||||||
:blame-source
|
|
||||||
:blame-swap
|
|
||||||
:blame-swapped?
|
|
||||||
:blame-value
|
|
||||||
:blame?
|
|
||||||
:current-blame-format
|
|
||||||
:exn:fail:contract:blame-object
|
|
||||||
:exn:fail:contract:blame?
|
|
||||||
:make-exn:fail:contract:blame
|
|
||||||
:raise-blame-error
|
|
||||||
:struct:exn:fail:contract:blame
|
|
||||||
:blame-add-context
|
|
||||||
:exn:fail:contract:blame
|
|
||||||
:build-chaperone-contract-property
|
|
||||||
:build-contract-property
|
|
||||||
:build-flat-contract-property
|
|
||||||
:chaperone-contract-property?
|
|
||||||
:contract-property?
|
|
||||||
:contract-struct-exercise
|
|
||||||
:contract-struct-generate
|
|
||||||
:flat-contract-property?
|
|
||||||
:make-chaperone-contract
|
|
||||||
:make-contract
|
|
||||||
:make-flat-contract
|
|
||||||
:prop:chaperone-contract
|
|
||||||
:prop:contract
|
|
||||||
:prop:flat-contract
|
|
||||||
:prop:opt-chaperone-contract
|
|
||||||
:prop:opt-chaperone-contract-get-test
|
|
||||||
:prop:opt-chaperone-contract?
|
|
||||||
:skip-projection-wrapper?
|
|
||||||
:opt/c
|
|
||||||
:define-opt/c))
|
|
||||||
(provide
|
|
||||||
(rename-out [:or/c union])
|
|
||||||
(rename-out [:string-len/c string/len]))
|
|
||||||
|
|
||||||
(define (build-flat-contract name pred)
|
|
||||||
(:flat-contract (procedure-rename pred name)))
|
|
||||||
(provide build-flat-contract)
|
|
||||||
|
|
||||||
(require racket/contract/combinator)
|
|
||||||
;; exports from racket/contract/combinator as of 5.3.5
|
|
||||||
(provide blame-add-unknown-context blame-context blame-contract blame-fmt->-string blame-negative
|
|
||||||
blame-original? blame-positive blame-replace-negative blame-source blame-swap blame-swapped?
|
|
||||||
blame-update blame-value blame? build-chaperone-contract-property build-compound-type-name
|
|
||||||
build-contract-property build-flat-contract-property chaperone-contract-property?
|
|
||||||
coerce-chaperone-contract coerce-chaperone-contracts coerce-contract coerce-contract/f
|
|
||||||
coerce-contracts coerce-flat-contract coerce-flat-contracts contract-first-order
|
|
||||||
contract-first-order-passes? contract-property? contract-stronger? contract-struct-exercise
|
|
||||||
contract-struct-generate current-blame-format eq-contract-val eq-contract? equal-contract-val
|
|
||||||
equal-contract? exn:fail:contract:blame-object exn:fail:contract:blame?
|
|
||||||
flat-contract-property? impersonator-prop:contracted make-chaperone-contract make-contract
|
|
||||||
make-exn:fail:contract:blame make-flat-contract prop:chaperone-contract prop:contract
|
|
||||||
prop:contracted prop:flat-contract prop:opt-chaperone-contract
|
|
||||||
prop:opt-chaperone-contract-get-test prop:opt-chaperone-contract? raise-blame-error
|
|
||||||
skip-projection-wrapper? struct:exn:fail:contract:blame define/final-prop
|
|
||||||
exn:fail:contract:blame blame-add-context define/subexpression-pos-prop)
|
|
|
@ -1,6 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
;; deprecated library, see `racket/control`
|
|
||||||
|
|
||||||
(require racket/control)
|
|
||||||
(provide (all-from-out racket/control))
|
|
|
@ -1,6 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
|
|
||||||
;; deprecated library, see `racket/date`
|
|
||||||
|
|
||||||
(require racket/date)
|
|
||||||
(provide (all-from-out racket/date))
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user