mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 03:30:27 +02:00
Merge remote-tracking branch 'local-2.0/stable-2.0'
Conflicts: libguile/deprecated.c module/ice-9/psyntax-pp.scm
This commit is contained in:
commit
8a562c697b
16 changed files with 2944 additions and 2704 deletions
32
acinclude.m4
32
acinclude.m4
|
@ -499,11 +499,41 @@ AC_DEFUN([GUILE_LIBUNISTRING_WITH_ICONV_SUPPORT], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl GUILE_UNISTRING_CONSTANT NAME
|
||||
dnl
|
||||
dnl Determine the compile-time value of NAME and define/substitute
|
||||
dnl `SCM_I_GSC_NAME'.
|
||||
AC_DEFUN([GUILE_UNISTRING_CONSTANT], [
|
||||
m4_pushdef([UPPER_CASE_NAME],
|
||||
[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz],
|
||||
[ABCDEFGHIJKLMNOPQRSTUVWXYZ])])
|
||||
|
||||
AC_CACHE_CHECK([the value of `$1'], [ac_cv_]$1, [
|
||||
AC_COMPUTE_INT([ac_cv_]$1, [$1],
|
||||
[AC_INCLUDES_DEFAULT
|
||||
#include <uniconv.h>
|
||||
],
|
||||
[AC_MSG_ERROR([failed to determine the value of `$1'])])
|
||||
])
|
||||
|
||||
[SCM_I_GSC_]UPPER_CASE_NAME="$ac_cv_[]$1"
|
||||
AC_SUBST([SCM_I_GSC_]UPPER_CASE_NAME)
|
||||
m4_popdef([UPPER_CASE_NAME])])
|
||||
|
||||
dnl GUILE_UNISTRING_ICONVEH_VALUES
|
||||
dnl
|
||||
dnl Determine the values of the `iconveh_' libunistring constants.
|
||||
AC_DEFUN([GUILE_UNISTRING_ICONVEH_VALUES], [
|
||||
GUILE_UNISTRING_CONSTANT([iconveh_error])
|
||||
GUILE_UNISTRING_CONSTANT([iconveh_question_mark])
|
||||
GUILE_UNISTRING_CONSTANT([iconveh_escape_sequence])
|
||||
])
|
||||
|
||||
dnl Declare file $1 to be a script that needs configuring,
|
||||
dnl and arrange to make it executable in the process.
|
||||
AC_DEFUN([GUILE_CONFIG_SCRIPT],[AC_CONFIG_FILES([$1],[chmod +x $1])])
|
||||
|
||||
# clock_time.m4 serial 10
|
||||
|
||||
dnl Copyright (C) 2002-2006, 2009-2011 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
|
|
85
configure.ac
85
configure.ac
|
@ -68,7 +68,9 @@ dnl Gnulib.
|
|||
gl_INIT
|
||||
dnl FIXME: remove me and the acinclude.m4 code when clock-gettime is
|
||||
dnl fixed for clock_getcpuclockid and can be imported normally from
|
||||
dnl gnulib.
|
||||
dnl gnulib. See
|
||||
dnl <http://lists.gnu.org/archive/html/bug-gnulib/2011-06/msg00227.html>
|
||||
dnl for details.
|
||||
gl_CLOCK_TIME
|
||||
|
||||
AC_PROG_CC_C89
|
||||
|
@ -232,6 +234,8 @@ dnl files which are destined for separate modules.
|
|||
|
||||
if test "$use_modules" != no; then
|
||||
AC_LIBOBJ([dynl])
|
||||
AC_DEFINE([HAVE_MODULES], 1,
|
||||
[Define this if you want support for dynamically loaded modules in Guile.])
|
||||
fi
|
||||
|
||||
if test "$enable_posix" = yes; then
|
||||
|
@ -1203,67 +1207,13 @@ GUILE_STRUCT_UTIMBUF
|
|||
# the error handlers, which are just ints. So we weaken our
|
||||
# dependency by looking up those values at configure-time.
|
||||
#--------------------------------------------------------------------
|
||||
SCM_I_GSC_ICONVEH_ERROR=0
|
||||
SCM_I_GSC_ICONVEH_QUESTION_MARK=1
|
||||
SCM_I_GSC_ICONVEH_ESCAPE_SEQUENCE=2
|
||||
AC_MSG_CHECKING([for iconveh_error])
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE(
|
||||
[AC_INCLUDES_DEFAULT
|
||||
#include <uniconv.h>
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
if (argc > 1)
|
||||
printf ("%d\n", (int)iconveh_error);
|
||||
return 0;
|
||||
}])],
|
||||
[SCM_I_GSC_ICONVEH_ERROR=`./conftest$EXEEXT pretty-please`
|
||||
AC_MSG_RESULT([$SCM_I_GSC_ICONVEH_ERROR])],
|
||||
[AC_MSG_FAILURE([failed to get iconveh_error])],
|
||||
[AC_MSG_WARN([assuming $SCM_I_GSC_ICONVEH_ERROR for cross-compilation])])
|
||||
|
||||
AC_MSG_CHECKING([for iconveh_question_mark])
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE(
|
||||
[AC_INCLUDES_DEFAULT
|
||||
#include <uniconv.h>
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
if (argc > 1)
|
||||
printf ("%d\n", (int)iconveh_question_mark);
|
||||
return 0;
|
||||
}])],
|
||||
[SCM_I_GSC_ICONVEH_QUESTION_MARK=`./conftest$EXEEXT pretty-please`
|
||||
AC_MSG_RESULT([$SCM_I_GSC_ICONVEH_QUESTION_MARK])],
|
||||
[AC_MSG_FAILURE([failed to get iconveh_question_mark])],
|
||||
[AC_MSG_WARN([assuming $SCM_I_GSC_ICONVEH_QUESTION_MARK for cross-compilation])])
|
||||
|
||||
AC_MSG_CHECKING([for iconveh_escape_sequence])
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE(
|
||||
[AC_INCLUDES_DEFAULT
|
||||
#include <uniconv.h>
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
if (argc > 1)
|
||||
printf ("%d\n", (int)iconveh_escape_sequence);
|
||||
return 0;
|
||||
}])],
|
||||
[SCM_I_GSC_ICONVEH_ESCAPE_SEQUENCE=`./conftest$EXEEXT pretty-please`
|
||||
AC_MSG_RESULT([$SCM_I_GSC_ICONVEH_ESCAPE_SEQUENCE])],
|
||||
[AC_MSG_FAILURE([failed to get iconveh_escape_sequence])],
|
||||
[AC_MSG_WARN([assuming $SCM_I_GSC_ICONVEH_ESCAPE_SEQUENCE for cross-compilation])])
|
||||
|
||||
AC_SUBST([SCM_I_GSC_ICONVEH_ERROR])
|
||||
AC_SUBST([SCM_I_GSC_ICONVEH_QUESTION_MARK])
|
||||
AC_SUBST([SCM_I_GSC_ICONVEH_ESCAPE_SEQUENCE])
|
||||
|
||||
GUILE_UNISTRING_ICONVEH_VALUES
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
#
|
||||
# Which way does the stack grow?
|
||||
#
|
||||
# Following code comes from Autoconf 2.61's internal _AC_LIBOBJ_ALLOCA
|
||||
# Following code comes from Autoconf 2.69's internal _AC_LIBOBJ_ALLOCA
|
||||
# macro (/usr/share/autoconf/autoconf/functions.m4). Gnulib has
|
||||
# very similar code, so in future we could look at using that.
|
||||
#
|
||||
|
@ -1278,23 +1228,20 @@ SCM_I_GSC_STACK_GROWS_UP=0
|
|||
AC_RUN_IFELSE([AC_LANG_SOURCE(
|
||||
[AC_INCLUDES_DEFAULT
|
||||
int
|
||||
find_stack_direction ()
|
||||
find_stack_direction (int *addr, int depth)
|
||||
{
|
||||
static char *addr = 0;
|
||||
auto char dummy;
|
||||
if (addr == 0)
|
||||
{
|
||||
addr = &dummy;
|
||||
return find_stack_direction ();
|
||||
}
|
||||
else
|
||||
return (&dummy > addr) ? 1 : -1;
|
||||
int dir, dummy = 0;
|
||||
if (! addr)
|
||||
addr = &dummy;
|
||||
*addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
|
||||
dir = depth ? find_stack_direction (addr, depth - 1) : 0;
|
||||
return dir + dummy;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
return find_stack_direction () < 0;
|
||||
return find_stack_direction (0, argc + !argv + 20) < 0;
|
||||
}])],
|
||||
[SCM_I_GSC_STACK_GROWS_UP=1],
|
||||
[],
|
||||
|
|
355
doc/ref/guile-invoke.texi
Normal file
355
doc/ref/guile-invoke.texi
Normal file
|
@ -0,0 +1,355 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
@node Invoking Guile
|
||||
@section Invoking Guile
|
||||
@cindex invocation
|
||||
|
||||
Many features of Guile depend on and can be changed by information that
|
||||
the user provides either before or when Guile is started. Below is a
|
||||
description of what information to provide and how to provide it.
|
||||
|
||||
@menu
|
||||
* Command-line Options:: Command-line options understood by Guile.
|
||||
* Environment Variables:: Variables that affect Guile's behavior.
|
||||
@end menu
|
||||
|
||||
@node Command-line Options
|
||||
@subsection Command-line Options
|
||||
@cindex Command-line Options
|
||||
@cindex command-line arguments
|
||||
@cindex arguments (command line)
|
||||
@cindex options (command line)
|
||||
@cindex switches (command line)
|
||||
@cindex startup (command-line arguments)
|
||||
@cindex invocation (command-line arguments)
|
||||
|
||||
Here we describe Guile's command-line processing in detail. Guile
|
||||
processes its arguments from left to right, recognizing the switches
|
||||
described below. For examples, see @ref{Scripting Examples}.
|
||||
|
||||
@table @code
|
||||
|
||||
@item @var{script} @var{arg...}
|
||||
@itemx -s @var{script} @var{arg...}
|
||||
@cindex script mode
|
||||
By default, Guile will read a file named on the command line as a
|
||||
script. Any command-line arguments @var{arg...} following @var{script}
|
||||
become the script's arguments; the @code{command-line} function returns
|
||||
a list of strings of the form @code{(@var{script} @var{arg...})}.
|
||||
|
||||
It is possible to name a file using a leading hyphen, for example,
|
||||
@file{-myfile.scm}. In this case, the file name must be preceded by
|
||||
@option{-s} to tell Guile that a (script) file is being named.
|
||||
|
||||
Scripts are read and evaluated as Scheme source code just as the
|
||||
@code{load} function would. After loading @var{script}, Guile exits.
|
||||
|
||||
@item -c @var{expr} @var{arg...}
|
||||
@cindex evaluate expression, command-line argument
|
||||
Evaluate @var{expr} as Scheme code, and then exit. Any command-line
|
||||
arguments @var{arg...} following @var{expr} become command-line
|
||||
arguments; the @code{command-line} function returns a list of strings of
|
||||
the form @code{(@var{guile} @var{arg...})}, where @var{guile} is the
|
||||
path of the Guile executable.
|
||||
|
||||
@item -- @var{arg...}
|
||||
Run interactively, prompting the user for expressions and evaluating
|
||||
them. Any command-line arguments @var{arg...} following the @option{--}
|
||||
become command-line arguments for the interactive session; the
|
||||
@code{command-line} function returns a list of strings of the form
|
||||
@code{(@var{guile} @var{arg...})}, where @var{guile} is the path of the
|
||||
Guile executable.
|
||||
|
||||
@item -L @var{directory}
|
||||
Add @var{directory} to the front of Guile's module load path. The given
|
||||
directories are searched in the order given on the command line and
|
||||
before any directories in the @env{GUILE_LOAD_PATH} environment
|
||||
variable. Paths added here are @emph{not} in effect during execution of
|
||||
the user's @file{.guile} file.
|
||||
|
||||
@item -x @var{extension}
|
||||
Add @var{extension} to the front of Guile's load extension list
|
||||
(@pxref{Loading, @code{%load-extensions}}). The specified extensions
|
||||
are tried in the order given on the command line, and before the default
|
||||
load extensions. Extensions added here are @emph{not} in effect during
|
||||
execution of the user's @file{.guile} file.
|
||||
|
||||
@item -l @var{file}
|
||||
Load Scheme source code from @var{file}, and continue processing the
|
||||
command line.
|
||||
|
||||
@item -e @var{function}
|
||||
Make @var{function} the @dfn{entry point} of the script. After loading
|
||||
the script file (with @option{-s}) or evaluating the expression (with
|
||||
@option{-c}), apply @var{function} to a list containing the program name
|
||||
and the command-line arguments---the list provided by the
|
||||
@code{command-line} function.
|
||||
|
||||
A @option{-e} switch can appear anywhere in the argument list, but Guile
|
||||
always invokes the @var{function} as the @emph{last} action it performs.
|
||||
This is weird, but because of the way script invocation works under
|
||||
POSIX, the @option{-s} option must always come last in the list.
|
||||
|
||||
The @var{function} is most often a simple symbol that names a function
|
||||
that is defined in the script. It can also be of the form @code{(@@
|
||||
@var{module-name} @var{symbol})}, and in that case, the symbol is
|
||||
looked up in the module named @var{module-name}.
|
||||
|
||||
For compatibility with some versions of Guile 1.4, you can also use the
|
||||
form @code{(symbol ...)} (that is, a list of only symbols that doesn't
|
||||
start with @code{@@}), which is equivalent to @code{(@@ (symbol ...)
|
||||
main)}, or @code{(symbol ...) symbol} (that is, a list of only symbols
|
||||
followed by a symbol), which is equivalent to @code{(@@ (symbol ...)
|
||||
symbol)}. We recommend to use the equivalent forms directly since they
|
||||
correspond to the @code{(@@ ...)} read syntax that can be used in
|
||||
normal code. See @ref{Using Guile Modules} and @ref{Scripting
|
||||
Examples}.
|
||||
|
||||
@item -ds
|
||||
Treat a final @option{-s} option as if it occurred at this point in the
|
||||
command line; load the script here.
|
||||
|
||||
This switch is necessary because, although the POSIX script invocation
|
||||
mechanism effectively requires the @option{-s} option to appear last, the
|
||||
programmer may well want to run the script before other actions
|
||||
requested on the command line. For examples, see @ref{Scripting
|
||||
Examples}.
|
||||
|
||||
@item \
|
||||
Read more command-line arguments, starting from the second line of the
|
||||
script file. @xref{The Meta Switch}.
|
||||
|
||||
@item --use-srfi=@var{list}
|
||||
@cindex loading srfi modules (command line)
|
||||
The option @option{--use-srfi} expects a comma-separated list of numbers,
|
||||
each representing a SRFI module to be loaded into the interpreter
|
||||
before evaluating a script file or starting the REPL. Additionally,
|
||||
the feature identifier for the loaded SRFIs is recognized by
|
||||
the procedure @code{cond-expand} when this option is used.
|
||||
|
||||
Here is an example that loads the modules SRFI-8 ('receive') and SRFI-13
|
||||
('string library') before the GUILE interpreter is started:
|
||||
|
||||
@example
|
||||
guile --use-srfi=8,13
|
||||
@end example
|
||||
|
||||
@item --debug
|
||||
@cindex debugging virtual machine (command line)
|
||||
Start with the debugging virtual machine (VM) engine. Using the
|
||||
debugging VM will enable support for VM hooks, which are needed for
|
||||
tracing, breakpoints, and accurate call counts when profiling. The
|
||||
debugging VM is slower than the regular VM, though, by about ten
|
||||
percent. @xref{VM Hooks}, for more information.
|
||||
|
||||
By default, the debugging VM engine is only used when entering an
|
||||
interactive session. When executing a script with @option{-s} or
|
||||
@option{-c}, the normal, faster VM is used by default.
|
||||
|
||||
@vnew{1.8}
|
||||
@item --no-debug
|
||||
@cindex debugging virtual machine (command line)
|
||||
Do not use the debugging VM engine, even when entering an interactive
|
||||
session.
|
||||
|
||||
@item -q
|
||||
@cindex init file, not loading
|
||||
@cindex @file{.guile} file, not loading
|
||||
Do not load the initialization file, @file{.guile}. This option only
|
||||
has an effect when running interactively; running scripts does not load
|
||||
the @file{.guile} file. @xref{Init File}.
|
||||
|
||||
@item --listen[=@var{p}]
|
||||
While this program runs, listen on a local port or a path for REPL
|
||||
clients. If @var{p} starts with a number, it is assumed to be a local
|
||||
port on which to listen. If it starts with a forward slash, it is
|
||||
assumed to be a path to a UNIX domain socket on which to listen.
|
||||
|
||||
If @var{p} is not given, the default is local port 37146. If you look
|
||||
at it upside down, it almost spells ``Guile''. If you have netcat
|
||||
installed, you should be able to @kbd{nc localhost 37146} and get a
|
||||
Guile prompt. Alternately you can fire up Emacs and connect to the
|
||||
process; see @ref{Using Guile in Emacs} for more details.
|
||||
|
||||
Note that opening a port allows anyone who can connect to that port---in
|
||||
the TCP case, any local user---to do anything Guile can do, as the user
|
||||
that the Guile process is running as. Do not use @option{--listen} on
|
||||
multi-user machines. Of course, if you do not pass @option{--listen} to
|
||||
Guile, no port will be opened.
|
||||
|
||||
That said, @option{--listen} is great for interactive debugging and
|
||||
development.
|
||||
|
||||
@vnew{2.0}
|
||||
|
||||
@item --auto-compile
|
||||
Compile source files automatically (default behavior).
|
||||
|
||||
@vnew{2.0.1}
|
||||
|
||||
@item --fresh-auto-compile
|
||||
Treat the auto-compilation cache as invalid, forcing recompilation.
|
||||
|
||||
@vnew{2.0}
|
||||
|
||||
@item --no-auto-compile
|
||||
Disable automatic source file compilation.
|
||||
|
||||
@vnew{2.0}
|
||||
|
||||
@item -h@r{, }--help
|
||||
Display help on invoking Guile, and then exit.
|
||||
|
||||
@item -v@r{, }--version
|
||||
Display the current version of Guile, and then exit.
|
||||
|
||||
@end table
|
||||
|
||||
@node Environment Variables
|
||||
@subsection Environment Variables
|
||||
@cindex environment variables
|
||||
@cindex shell
|
||||
@cindex initialization
|
||||
The @dfn{environment} is a feature of the operating system; it consists
|
||||
of a collection of variables with names and values. Each variable is
|
||||
called an @dfn{environment variable} (or, sometimes, a ``shell
|
||||
variable''); environment variable names are case-sensitive, and it is
|
||||
conventional to use upper-case letters only. The values are all text
|
||||
strings, even those that are written as numerals. (Note that here we
|
||||
are referring to names and values that are defined in the operating
|
||||
system shell from which Guile is invoked. This is not the same as a
|
||||
Scheme environment that is defined within a running instance of Guile.
|
||||
For a description of Scheme environments, @pxref{About Environments}.)
|
||||
|
||||
How to set environment variables before starting Guile depends on the
|
||||
operating system and, especially, the shell that you are using. For
|
||||
example, here is how to tell Guile to provide detailed warning messages
|
||||
about deprecated features by setting @env{GUILE_WARN_DEPRECATED} using
|
||||
Bash:
|
||||
|
||||
@example
|
||||
$ export GUILE_WARN_DEPRECATED="detailed"
|
||||
$ guile
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
Or, detailed warnings can be turned on for a single invocation using:
|
||||
|
||||
@example
|
||||
$ env GUILE_WARN_DEPRECATED="detailed" guile
|
||||
@end example
|
||||
|
||||
If you wish to retrieve or change the value of the shell environment
|
||||
variables that affect the run-time behavior of Guile from within a
|
||||
running instance of Guile, see @ref{Runtime Environment}.
|
||||
|
||||
Here are the environment variables that affect the run-time behavior of
|
||||
Guile:
|
||||
|
||||
@table @env
|
||||
@item GUILE_AUTO_COMPILE
|
||||
@vindex GUILE_AUTO_COMPILE
|
||||
This is a flag that can be used to tell Guile whether or not to compile
|
||||
Scheme source files automatically. Starting with Guile 2.0, Scheme
|
||||
source files will be compiled automatically, by default.
|
||||
|
||||
If a compiled (@file{.go}) file corresponding to a @file{.scm} file is
|
||||
not found or is not newer than the @file{.scm} file, the @file{.scm}
|
||||
file will be compiled on the fly, and the resulting @file{.go} file
|
||||
stored away. An advisory note will be printed on the console.
|
||||
|
||||
Compiled files will be stored in the directory
|
||||
@file{$XDG_CACHE_HOME/@/guile/@/ccache}, where @env{XDG_CACHE_HOME}
|
||||
defaults to the directory @file{$HOME/.cache}. This directory will be
|
||||
created if it does not already exist.
|
||||
|
||||
Note that this mechanism depends on the timestamp of the @file{.go} file
|
||||
being newer than that of the @file{.scm} file; if the @file{.scm} or
|
||||
@file{.go} files are moved after installation, care should be taken to
|
||||
preserve their original timestamps.
|
||||
|
||||
Set @env{GUILE_AUTO_COMPILE} to zero (0), to prevent Scheme files from
|
||||
being compiled automatically. Set this variable to ``fresh'' to tell
|
||||
Guile to compile Scheme files whether they are newer than the compiled
|
||||
files or not.
|
||||
|
||||
@xref{Compilation}.
|
||||
|
||||
@item GUILE_HISTORY
|
||||
@vindex GUILE_HISTORY
|
||||
This variable names the file that holds the Guile REPL command history.
|
||||
You can specify a different history file by setting this environment
|
||||
variable. By default, the history file is @file{$HOME/.guile_history}.
|
||||
|
||||
@item GUILE_LOAD_COMPILED_PATH
|
||||
@vindex GUILE_LOAD_COMPILED_PATH
|
||||
This variable may be used to augment the path that is searched for
|
||||
compiled Scheme files (@file{.go} files) when loading. Its value should
|
||||
be a colon-separated list of directories, which will be prefixed to the
|
||||
value of the default search path stored in @code{%load-compiled-path}.
|
||||
|
||||
Here is an example using the Bash shell that adds the current directory,
|
||||
@file{.}, and the relative directory @file{../my-library} to
|
||||
@code{%load-compiled-path}:
|
||||
|
||||
@example
|
||||
$ export GUILE_LOAD_COMPILED_PATH=".:../my-library"
|
||||
$ guile -c '(display %load-compiled-path) (newline)'
|
||||
(. ../my-library /usr/local/lib/guile/2.0/ccache)
|
||||
@end example
|
||||
|
||||
@item GUILE_LOAD_PATH
|
||||
@vindex GUILE_LOAD_PATH
|
||||
This variable may be used to augment the path that is searched for
|
||||
Scheme files when loading. Its value should be a colon-separated list
|
||||
of directories, which will be prefixed to the value of the default
|
||||
search path stored in @code{%load-path}.
|
||||
|
||||
Here is an example using the Bash shell that adds the current directory
|
||||
and the parent of the current directory to @code{%load-path}:
|
||||
|
||||
@example
|
||||
$ env GUILE_LOAD_PATH=".:.." \
|
||||
guile -c '(display %load-path) (newline)'
|
||||
(. .. /usr/local/share/guile/2.0 \
|
||||
/usr/local/share/guile/site/2.0 \
|
||||
/usr/local/share/guile/site /usr/local/share/guile)
|
||||
@end example
|
||||
|
||||
(Note: The line breaks, above, are for documentation purposes only, and
|
||||
not required in the actual example.)
|
||||
|
||||
@item GUILE_WARN_DEPRECATED
|
||||
@vindex GUILE_WARN_DEPRECATED
|
||||
As Guile evolves, some features will be eliminated or replaced by newer
|
||||
features. To help users migrate their code as this evolution occurs,
|
||||
Guile will issue warning messages about code that uses features that
|
||||
have been marked for eventual elimination. @env{GUILE_WARN_DEPRECATED}
|
||||
can be set to ``no'' to tell Guile not to display these warning
|
||||
messages, or set to ``detailed'' to tell Guile to display more lengthy
|
||||
messages describing the warning. @xref{Deprecation}.
|
||||
|
||||
@item HOME
|
||||
@vindex HOME
|
||||
Guile uses the environment variable @env{HOME}, the name of your home
|
||||
directory, to locate various files, such as @file{.guile} or
|
||||
@file{.guile_history}.
|
||||
|
||||
@item LTDL_LIBRARY_PATH
|
||||
@vindex LTDL_LIBRARY_PATH
|
||||
Guile now adds its install prefix to the @env{LTDL_LIBRARY_PATH}.
|
||||
|
||||
Users may now install Guile in non-standard directories and run
|
||||
`/path/to/bin/guile', without having also to set @env{LTDL_LIBRARY_PATH}
|
||||
to include `/path/to/lib'.
|
||||
|
||||
@end table
|
||||
|
||||
@c Local Variables:
|
||||
@c mode: texinfo
|
||||
@c TeX-master: "guile"
|
||||
@c End:
|
|
@ -217,14 +217,15 @@ Guile's core language is Scheme, and a lot can be achieved simply by using Guile
|
|||
to write and run Scheme programs --- as opposed to having to dive into C code.
|
||||
In this part of the manual, we explain how to use Guile in this mode, and
|
||||
describe the tools that Guile provides to help you with script writing,
|
||||
debugging and packaging your programs for distribution.
|
||||
debugging, and packaging your programs for distribution.
|
||||
|
||||
For detailed reference information on the variables, functions
|
||||
etc. that make up Guile's application programming interface (API),
|
||||
@xref{API Reference}.
|
||||
For detailed reference information on the variables, functions, and so
|
||||
on that make up Guile's application programming interface (API), see
|
||||
@ref{API Reference}.
|
||||
|
||||
@menu
|
||||
* Guile Scheme:: Guile's implementation of Scheme.
|
||||
* Invoking Guile:: Selecting optional features when starting Guile.
|
||||
* Guile Scripting:: How to write Guile scripts.
|
||||
* Using Guile Interactively:: Guile's REPL features.
|
||||
* Using Guile in Emacs:: Guile and Emacs.
|
||||
|
@ -232,6 +233,7 @@ etc. that make up Guile's application programming interface (API),
|
|||
@end menu
|
||||
|
||||
@include scheme-intro.texi
|
||||
@include guile-invoke.texi
|
||||
@include scheme-scripts.texi
|
||||
@include scheme-using.texi
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ then tells Guile how to handle the Scheme code.
|
|||
|
||||
@menu
|
||||
* The Top of a Script File:: How to start a Guile script.
|
||||
* Invoking Guile:: Command line options understood by Guile.
|
||||
* The Meta Switch:: Passing complex argument lists to Guile
|
||||
from shell scripts.
|
||||
* Command Line Handling:: Accessing the command line from a script.
|
||||
|
@ -76,178 +75,6 @@ The rest of the file should be a Scheme program.
|
|||
Guile reads the program, evaluating expressions in the order that they
|
||||
appear. Upon reaching the end of the file, Guile exits.
|
||||
|
||||
|
||||
@node Invoking Guile
|
||||
@subsection Invoking Guile
|
||||
@cindex invocation
|
||||
|
||||
Here we describe Guile's command-line processing in detail. Guile
|
||||
processes its arguments from left to right, recognizing the switches
|
||||
described below. For examples, see @ref{Scripting Examples}.
|
||||
|
||||
@table @code
|
||||
|
||||
@item -s @var{script} @var{arg...}
|
||||
Read and evaluate Scheme source code from the file @var{script}, as the
|
||||
@code{load} function would. After loading @var{script}, exit. Any
|
||||
command-line arguments @var{arg...} following @var{script} become the
|
||||
script's arguments; the @code{command-line} function returns a list of
|
||||
strings of the form @code{(@var{script} @var{arg...})}.
|
||||
|
||||
@item -c @var{expr} @var{arg...}
|
||||
Evaluate @var{expr} as Scheme code, and then exit. Any command-line
|
||||
arguments @var{arg...} following @var{expr} become command-line arguments; the
|
||||
@code{command-line} function returns a list of strings of the form
|
||||
@code{(@var{guile} @var{arg...})}, where @var{guile} is the path of the
|
||||
Guile executable.
|
||||
|
||||
@item -- @var{arg...}
|
||||
Run interactively, prompting the user for expressions and evaluating
|
||||
them. Any command-line arguments @var{arg...} following the @code{--}
|
||||
become command-line arguments for the interactive session; the
|
||||
@code{command-line} function returns a list of strings of the form
|
||||
@code{(@var{guile} @var{arg...})}, where @var{guile} is the path of the
|
||||
Guile executable.
|
||||
|
||||
@item -L @var{directory}
|
||||
Add @var{directory} to the front of Guile's module load path. The
|
||||
given directories are searched in the order given on the command line
|
||||
and before any directories in the GUILE_LOAD_PATH environment
|
||||
variable. Paths added here are @emph{not} in effect during execution
|
||||
of the user's @file{.guile} file.
|
||||
|
||||
@item -x @var{extension}
|
||||
Add @var{extension} to the front of Guile's load extension list
|
||||
(@pxref{Loading, @code{%load-extensions}}). The specified extensions
|
||||
are tried in the order given on the command line, and before the default
|
||||
load extensions. Extensions added here are @emph{not} in effect during
|
||||
execution of the user's @file{.guile} file.
|
||||
|
||||
@item -l @var{file}
|
||||
Load Scheme source code from @var{file}, and continue processing the
|
||||
command line.
|
||||
|
||||
@item -e @var{function}
|
||||
Make @var{function} the @dfn{entry point} of the script. After loading
|
||||
the script file (with @code{-s}) or evaluating the expression (with
|
||||
@code{-c}), apply @var{function} to a list containing the program name
|
||||
and the command-line arguments --- the list provided by the
|
||||
@code{command-line} function.
|
||||
|
||||
A @code{-e} switch can appear anywhere in the argument list, but Guile
|
||||
always invokes the @var{function} as the @emph{last} action it performs.
|
||||
This is weird, but because of the way script invocation works under
|
||||
POSIX, the @code{-s} option must always come last in the list.
|
||||
|
||||
The @var{function} is most often a simple symbol that names a function
|
||||
that is defined in the script. It can also be of the form @code{(@@
|
||||
@var{module-name} @var{symbol})} and in that case, the symbol is
|
||||
looked up in the module named @var{module-name}.
|
||||
|
||||
For compatibility with some versions of Guile 1.4, you can also use the
|
||||
form @code{(symbol ...)} (that is, a list of only symbols that doesn't
|
||||
start with @code{@@}), which is equivalent to @code{(@@ (symbol ...)
|
||||
main)}, or @code{(symbol ...) symbol} (that is, a list of only symbols
|
||||
followed by a symbol), which is equivalent to @code{(@@ (symbol ...)
|
||||
symbol)}. We recommend to use the equivalent forms directly since they
|
||||
correspond to the @code{(@@ ...)} read syntax that can be used in
|
||||
normal code, @xref{Using Guile Modules}.
|
||||
|
||||
@xref{Scripting Examples}.
|
||||
|
||||
@item -ds
|
||||
Treat a final @code{-s} option as if it occurred at this point in the
|
||||
command line; load the script here.
|
||||
|
||||
This switch is necessary because, although the POSIX script invocation
|
||||
mechanism effectively requires the @code{-s} option to appear last, the
|
||||
programmer may well want to run the script before other actions
|
||||
requested on the command line. For examples, see @ref{Scripting
|
||||
Examples}.
|
||||
|
||||
@item \
|
||||
Read more command-line arguments, starting from the second line of the
|
||||
script file. @xref{The Meta Switch}.
|
||||
|
||||
@item --use-srfi=@var{list}
|
||||
The option @code{--use-srfi} expects a comma-separated list of numbers,
|
||||
each representing a SRFI number to be loaded into the interpreter
|
||||
before starting evaluating a script file or the REPL. Additionally,
|
||||
the feature identifier for the loaded SRFIs is recognized by
|
||||
`cond-expand' when using this option.
|
||||
|
||||
@example
|
||||
guile --use-srfi=8,13
|
||||
@end example
|
||||
|
||||
@item --debug
|
||||
Start with the debugging virtual machine engine. Using the debugging VM
|
||||
will enable support for VM hooks, which are needed for tracing,
|
||||
breakpoints, and accurate call counts when profiling. The debugging VM
|
||||
is slower than the regular VM, though, by about 10 percent. @xref{VM
|
||||
Hooks}, for more information.
|
||||
|
||||
By default, the debugging VM engine is only used when entering an
|
||||
interactive session. When executing a script with @code{-s} or
|
||||
@code{-c}, the normal, faster VM is used by default.
|
||||
|
||||
@vnew{1.8}
|
||||
@item --no-debug
|
||||
Do not use the debugging VM engine, even when entering an interactive
|
||||
session.
|
||||
|
||||
@item -q
|
||||
Do not the local initialization file, @code{.guile}. This option only
|
||||
has an effect when running interactively; running scripts does not load
|
||||
the @code{.guile} file. @xref{Init File}.
|
||||
|
||||
@item --listen[=@var{p}]
|
||||
While this program runs, listen on a local port or a path for REPL
|
||||
clients. If @var{p} starts with a number, it is assumed to be a local
|
||||
port on which to listen. If it starts with a forward slash, it is
|
||||
assumed to be a path to a UNIX domain socket on which to listen.
|
||||
|
||||
If @var{p} is not given, the default is local port 37146. If you look
|
||||
at it upside down, it almost spells ``Guile''. If you have netcat
|
||||
installed, you should be able to @kbd{nc localhost 37146} and get a
|
||||
Guile prompt. Alternately you can fire up Emacs and connect to the
|
||||
process; see @ref{Using Guile in Emacs} for more details.
|
||||
|
||||
Note that opening a port allows anyone who can connect to that port---in
|
||||
the TCP case, any local user---to do anything Guile can do, as the user
|
||||
that the Guile process is running as. Don't use @option{--listen} on
|
||||
multi-user machines. Of course, if you don't pass @option{--listen} to
|
||||
Guile, no port will be opened.
|
||||
|
||||
That said, @code{--listen} is great for interactive debugging and
|
||||
development.
|
||||
|
||||
@vnew{2.0}
|
||||
|
||||
@item --auto-compile
|
||||
Compile source files automatically (default behavior).
|
||||
|
||||
@vnew{2.0.1}
|
||||
|
||||
@item --fresh-auto-compile
|
||||
Treat the auto-compilation cache as invalid, forcing recompilation.
|
||||
|
||||
@vnew{2.0}
|
||||
|
||||
@item --no-auto-compile
|
||||
Disable automatic source file compilation.
|
||||
|
||||
@vnew{2.0}
|
||||
|
||||
@item -h@r{, }--help
|
||||
Display help on invoking Guile, and then exit.
|
||||
|
||||
@item -v@r{, }--version
|
||||
Display the current version of Guile, and then exit.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
@node The Meta Switch
|
||||
@subsection The Meta Switch
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* extensions.c - registering and loading extensions.
|
||||
*
|
||||
* Copyright (C) 2001, 2006, 2009, 2010 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
|
@ -111,7 +111,13 @@ load_extension (SCM lib, SCM init)
|
|||
}
|
||||
|
||||
/* Dynamically link the library. */
|
||||
#if HAVE_MODULES
|
||||
scm_dynamic_call (init, scm_dynamic_link (lib));
|
||||
#else
|
||||
scm_misc_error ("load-extension",
|
||||
"extension ~S:~S not registered and dynamic-link disabled",
|
||||
scm_list_2 (init, lib));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1788,6 +1788,7 @@ SCM_DEFINE (scm_closedir, "closedir", 1, 0, 0,
|
|||
#undef FUNC_NAME
|
||||
|
||||
|
||||
#ifdef HAVE_POSIX
|
||||
static int
|
||||
scm_dir_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
|
||||
{
|
||||
|
@ -1808,6 +1809,7 @@ scm_dir_free (SCM p)
|
|||
closedir ((DIR *) SCM_SMOB_DATA_1 (p));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -501,7 +501,9 @@ scm_i_init_guile (void *base)
|
|||
scm_init_debug (); /* Requires macro smobs */
|
||||
scm_init_random (); /* Requires smob_prehistory */
|
||||
scm_init_simpos ();
|
||||
#if HAVE_MODULES
|
||||
scm_init_dynamic_linking (); /* Requires smob_prehistory */
|
||||
#endif
|
||||
scm_bootstrap_i18n ();
|
||||
scm_init_script ();
|
||||
|
||||
|
|
|
@ -806,6 +806,11 @@ SCM_DEFINE (scm_primitive_load_path, "primitive-load-path", 0, 0, 1,
|
|||
SCM filename, exception_on_not_found;
|
||||
SCM full_filename, compiled_filename;
|
||||
int compiled_is_fallback = 0;
|
||||
SCM hook = *scm_loc_load_hook;
|
||||
|
||||
if (scm_is_true (hook) && scm_is_false (scm_procedure_p (hook)))
|
||||
SCM_MISC_ERROR ("value of %load-hook is neither a procedure nor #f",
|
||||
SCM_EOL);
|
||||
|
||||
if (scm_is_string (args))
|
||||
{
|
||||
|
@ -870,6 +875,10 @@ SCM_DEFINE (scm_primitive_load_path, "primitive-load-path", 0, 0, 1,
|
|||
return SCM_BOOL_F;
|
||||
}
|
||||
|
||||
if (!scm_is_false (hook))
|
||||
scm_call_1 (hook, (scm_is_true (full_filename)
|
||||
? full_filename : compiled_filename));
|
||||
|
||||
if (scm_is_false (full_filename)
|
||||
|| (scm_is_true (compiled_filename)
|
||||
&& compiled_is_fresh (full_filename, compiled_filename)))
|
||||
|
|
|
@ -1367,6 +1367,8 @@ fat_mutex_lock (SCM mutex, scm_t_timespec *timeout, SCM owner, int *ret)
|
|||
if (SCM_I_IS_THREAD (new_owner))
|
||||
{
|
||||
scm_i_thread *t = SCM_I_THREAD_DATA (new_owner);
|
||||
|
||||
scm_i_pthread_mutex_unlock (&m->lock);
|
||||
scm_i_pthread_mutex_lock (&t->admin_mutex);
|
||||
|
||||
/* Only keep a weak reference to MUTEX so that it's not
|
||||
|
@ -1377,6 +1379,7 @@ fat_mutex_lock (SCM mutex, scm_t_timespec *timeout, SCM owner, int *ret)
|
|||
t->mutexes = scm_weak_car_pair (mutex, t->mutexes);
|
||||
|
||||
scm_i_pthread_mutex_unlock (&t->admin_mutex);
|
||||
scm_i_pthread_mutex_lock (&m->lock);
|
||||
}
|
||||
*ret = 1;
|
||||
break;
|
||||
|
|
|
@ -3490,7 +3490,10 @@ module '(ice-9 q) '(make-q q-length))}."
|
|||
(and go-path
|
||||
(fresh-compiled-file-name abs-path go-path)))))))
|
||||
(if cfn
|
||||
(load-compiled cfn)
|
||||
(begin
|
||||
(if %load-hook
|
||||
(%load-hook abs-path))
|
||||
(load-compiled cfn))
|
||||
(start-stack 'load-stack
|
||||
(primitive-load abs-path)))))
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2232,8 +2232,8 @@
|
|||
(lambda (pattern keys)
|
||||
(define cvt*
|
||||
(lambda (p* n ids)
|
||||
(if (null? p*)
|
||||
(values '() ids)
|
||||
(if (not (pair? p*))
|
||||
(cvt p* n ids)
|
||||
(call-with-values
|
||||
(lambda () (cvt* (cdr p*) n ids))
|
||||
(lambda (y ids)
|
||||
|
@ -2241,6 +2241,13 @@
|
|||
(lambda () (cvt (car p*) n ids))
|
||||
(lambda (x ids)
|
||||
(values (cons x y) ids))))))))
|
||||
|
||||
(define (v-reverse x)
|
||||
(let loop ((r '()) (x x))
|
||||
(if (not (pair? x))
|
||||
(values r x)
|
||||
(loop (cons (car x) r) (cdr x)))))
|
||||
|
||||
(define cvt
|
||||
(lambda (p n ids)
|
||||
(if (id? p)
|
||||
|
@ -2259,15 +2266,19 @@
|
|||
(lambda (p ids)
|
||||
(values (if (eq? p 'any) 'each-any (vector 'each p))
|
||||
ids))))
|
||||
((x dots ys ...)
|
||||
((x dots . ys)
|
||||
(ellipsis? (syntax dots))
|
||||
(call-with-values
|
||||
(lambda () (cvt* (syntax (ys ...)) n ids))
|
||||
(lambda () (cvt* (syntax ys) n ids))
|
||||
(lambda (ys ids)
|
||||
(call-with-values
|
||||
(lambda () (cvt (syntax x) (+ n 1) ids))
|
||||
(lambda (x ids)
|
||||
(values `#(each+ ,x ,(reverse ys) ()) ids))))))
|
||||
(call-with-values
|
||||
(lambda () (v-reverse ys))
|
||||
(lambda (ys e)
|
||||
(values `#(each+ ,x ,ys ,e)
|
||||
ids))))))))
|
||||
((x . y)
|
||||
(call-with-values
|
||||
(lambda () (cvt (syntax y) n ids))
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
(export define-record-type
|
||||
record-type-descriptor
|
||||
record-constructor-descriptor)
|
||||
(import (only (guile) *unspecified* and=> gensym unspecified?)
|
||||
(import (only (guile) and=> gensym)
|
||||
(rnrs base (6))
|
||||
(rnrs conditions (6))
|
||||
(rnrs exceptions (6))
|
||||
|
@ -75,172 +75,162 @@
|
|||
(number-fields-inner fields 0))
|
||||
|
||||
(define (process-fields record-name fields)
|
||||
(define record-name-str (symbol->string record-name))
|
||||
(define (wrap x) (datum->syntax record-name x))
|
||||
(define (id->string x)
|
||||
(symbol->string (syntax->datum x)))
|
||||
(define record-name-str (id->string record-name))
|
||||
(define (guess-accessor-name field-name)
|
||||
(string->symbol (string-append
|
||||
record-name-str "-" (symbol->string field-name))))
|
||||
(wrap
|
||||
(string->symbol (string-append
|
||||
record-name-str "-" (id->string field-name)))))
|
||||
(define (guess-mutator-name field-name)
|
||||
(string->symbol
|
||||
(string-append
|
||||
record-name-str "-" (symbol->string field-name) "-set!")))
|
||||
|
||||
(wrap
|
||||
(string->symbol
|
||||
(string-append
|
||||
record-name-str "-" (id->string field-name) "-set!"))))
|
||||
(define (f x)
|
||||
(define (lose)
|
||||
(syntax-violation 'define-record-type "invalid field specifier" x))
|
||||
(cond ((symbol? x) (list 'immutable x (guess-accessor-name x) #f))
|
||||
((not (list? x)) (lose))
|
||||
((eq? (car x) 'immutable)
|
||||
(cons 'immutable
|
||||
(case (length x)
|
||||
((2) (list (cadr x) (guess-accessor-name (cadr x)) #f))
|
||||
((3) (list (cadr x) (caddr x) #f))
|
||||
(else (lose)))))
|
||||
((eq? (car x) 'mutable)
|
||||
(cons 'mutable
|
||||
(case (length x)
|
||||
((2) (list (cadr x)
|
||||
(guess-accessor-name (cadr x))
|
||||
(guess-mutator-name (cadr x))))
|
||||
((4) (cdr x))
|
||||
(else (lose)))))
|
||||
(else (lose))))
|
||||
(syntax-case x (immutable mutable)
|
||||
[(immutable name)
|
||||
(list (wrap `(immutable ,(syntax->datum #'name)))
|
||||
(guess-accessor-name #'name)
|
||||
#f)]
|
||||
[(immutable name accessor)
|
||||
(list (wrap `(immutable ,(syntax->datum #'name))) #'accessor #f)]
|
||||
[(mutable name)
|
||||
(list (wrap `(mutable ,(syntax->datum #'name)))
|
||||
(guess-accessor-name #'name)
|
||||
(guess-mutator-name #'name))]
|
||||
[(mutable name accessor mutator)
|
||||
(list (wrap `(mutable ,(syntax->datum #'name))) #'accessor #'mutator)]
|
||||
[name
|
||||
(identifier? #'name)
|
||||
(list (wrap `(immutable ,(syntax->datum #'name)))
|
||||
(guess-accessor-name #'name)
|
||||
#f)]
|
||||
[else
|
||||
(syntax-violation 'define-record-type "invalid field specifier" x)]))
|
||||
(map f fields))
|
||||
|
||||
(define-syntax define-record-type0
|
||||
(lambda (stx)
|
||||
(define *unspecified* (cons #f #f))
|
||||
(define (unspecified? obj)
|
||||
(eq? *unspecified* obj))
|
||||
(syntax-case stx ()
|
||||
((_ (record-name constructor-name predicate-name) record-clause ...)
|
||||
(let loop ((fields *unspecified*)
|
||||
(parent *unspecified*)
|
||||
(protocol *unspecified*)
|
||||
(sealed *unspecified*)
|
||||
(opaque *unspecified*)
|
||||
(nongenerative *unspecified*)
|
||||
(constructor *unspecified*)
|
||||
(parent-rtd *unspecified*)
|
||||
(record-clauses (syntax->datum #'(record-clause ...))))
|
||||
(if (null? record-clauses)
|
||||
(let*
|
||||
((fields (if (unspecified? fields) '() fields))
|
||||
(field-names
|
||||
(datum->syntax
|
||||
#'record-name
|
||||
(list->vector (map (lambda (x) (take x 2)) fields))))
|
||||
(field-accessors
|
||||
(fold-left (lambda (x c lst)
|
||||
(cons #`(define #,(datum->syntax
|
||||
#'record-name (caddr x))
|
||||
(record-accessor record-name #,c))
|
||||
lst))
|
||||
'() fields (sequence (length fields))))
|
||||
(field-mutators
|
||||
(fold-left (lambda (x c lst)
|
||||
(if (cadddr x)
|
||||
(cons #`(define #,(datum->syntax
|
||||
#'record-name (cadddr x))
|
||||
(record-mutator record-name #,c))
|
||||
lst)
|
||||
lst))
|
||||
'() fields (sequence (length fields))))
|
||||
|
||||
(parent-cd
|
||||
(datum->syntax
|
||||
stx (cond ((not (unspecified? parent))
|
||||
`(record-constructor-descriptor ,parent))
|
||||
((not (unspecified? parent-rtd)) (cadr parent-rtd))
|
||||
(else #f))))
|
||||
(parent-rtd
|
||||
(datum->syntax
|
||||
stx (cond ((not (unspecified? parent))
|
||||
`(record-type-descriptor ,parent))
|
||||
((not (unspecified? parent-rtd)) (car parent-rtd))
|
||||
(else #f))))
|
||||
|
||||
(protocol (datum->syntax
|
||||
#'record-name (if (unspecified? protocol)
|
||||
#f protocol)))
|
||||
(uid (datum->syntax
|
||||
#'record-name (if (unspecified? nongenerative)
|
||||
#f nongenerative)))
|
||||
(sealed? (if (unspecified? sealed) #f sealed))
|
||||
(opaque? (if (unspecified? opaque) #f opaque))
|
||||
|
||||
(record-name-sym (datum->syntax
|
||||
stx (list 'quote
|
||||
(syntax->datum #'record-name)))))
|
||||
|
||||
#`(begin
|
||||
(define record-name
|
||||
(make-record-type-descriptor
|
||||
#,record-name-sym
|
||||
#,parent-rtd #,uid #,sealed? #,opaque?
|
||||
#,field-names))
|
||||
(define constructor-name
|
||||
(record-constructor
|
||||
(make-record-constructor-descriptor
|
||||
record-name #,parent-cd #,protocol)))
|
||||
((_ (record-name constructor-name predicate-name) record-clause ...)
|
||||
(let loop ((_fields *unspecified*)
|
||||
(_parent *unspecified*)
|
||||
(_protocol *unspecified*)
|
||||
(_sealed *unspecified*)
|
||||
(_opaque *unspecified*)
|
||||
(_nongenerative *unspecified*)
|
||||
(_constructor *unspecified*)
|
||||
(_parent-rtd *unspecified*)
|
||||
(record-clauses #'(record-clause ...)))
|
||||
(syntax-case record-clauses
|
||||
(fields parent protocol sealed opaque nongenerative
|
||||
constructor parent-rtd)
|
||||
[()
|
||||
(let* ((fields (if (unspecified? _fields) '() _fields))
|
||||
(field-names (list->vector (map car fields)))
|
||||
(field-accessors
|
||||
(fold-left (lambda (x c lst)
|
||||
(cons #`(define #,(cadr x)
|
||||
(record-accessor record-name #,c))
|
||||
lst))
|
||||
'() fields (sequence (length fields))))
|
||||
(field-mutators
|
||||
(fold-left (lambda (x c lst)
|
||||
(if (caddr x)
|
||||
(cons #`(define #,(caddr x)
|
||||
(record-mutator record-name
|
||||
#,c))
|
||||
lst)
|
||||
lst))
|
||||
'() fields (sequence (length fields))))
|
||||
(parent-cd (cond ((not (unspecified? _parent))
|
||||
#`(record-constructor-descriptor
|
||||
#,_parent))
|
||||
((not (unspecified? _parent-rtd))
|
||||
(cadr _parent-rtd))
|
||||
(else #f)))
|
||||
(parent-rtd (cond ((not (unspecified? _parent))
|
||||
#`(record-type-descriptor #,_parent))
|
||||
((not (unspecified? _parent-rtd))
|
||||
(car _parent-rtd))
|
||||
(else #f)))
|
||||
(protocol (if (unspecified? _protocol) #f _protocol))
|
||||
(uid (if (unspecified? _nongenerative) #f _nongenerative))
|
||||
(sealed? (if (unspecified? _sealed) #f _sealed))
|
||||
(opaque? (if (unspecified? _opaque) #f _opaque)))
|
||||
#`(begin
|
||||
(define record-name
|
||||
(make-record-type-descriptor
|
||||
(quote record-name)
|
||||
#,parent-rtd #,uid #,sealed? #,opaque?
|
||||
#,field-names))
|
||||
(define constructor-name
|
||||
(record-constructor
|
||||
(make-record-constructor-descriptor
|
||||
record-name #,parent-cd #,protocol)))
|
||||
(define dummy
|
||||
(let ()
|
||||
(register-record-type
|
||||
#,record-name-sym
|
||||
(quote record-name)
|
||||
record-name (make-record-constructor-descriptor
|
||||
record-name #,parent-cd #,protocol))
|
||||
'dummy))
|
||||
(define predicate-name (record-predicate record-name))
|
||||
#,@field-accessors
|
||||
#,@field-mutators))
|
||||
(let ((cr (car record-clauses)))
|
||||
(case (car cr)
|
||||
((fields)
|
||||
(if (unspecified? fields)
|
||||
(loop (process-fields (syntax->datum #'record-name)
|
||||
(cdr cr))
|
||||
parent protocol sealed opaque nongenerative
|
||||
constructor parent-rtd (cdr record-clauses))
|
||||
(raise (make-assertion-violation))))
|
||||
((parent)
|
||||
(if (not (unspecified? parent-rtd))
|
||||
(raise (make-assertion-violation)))
|
||||
(if (unspecified? parent)
|
||||
(loop fields (cadr cr) protocol sealed opaque
|
||||
nongenerative constructor parent-rtd
|
||||
(cdr record-clauses))
|
||||
(raise (make-assertion-violation))))
|
||||
((protocol)
|
||||
(if (unspecified? protocol)
|
||||
(loop fields parent (cadr cr) sealed opaque
|
||||
nongenerative constructor parent-rtd
|
||||
(cdr record-clauses))
|
||||
(raise (make-assertion-violation))))
|
||||
((sealed)
|
||||
(if (unspecified? sealed)
|
||||
(loop fields parent protocol (cadr cr) opaque
|
||||
nongenerative constructor parent-rtd
|
||||
(cdr record-clauses))
|
||||
(raise (make-assertion-violation))))
|
||||
((opaque) (if (unspecified? opaque)
|
||||
(loop fields parent protocol sealed (cadr cr)
|
||||
nongenerative constructor parent-rtd
|
||||
(cdr record-clauses))
|
||||
(raise (make-assertion-violation))))
|
||||
((nongenerative)
|
||||
(if (unspecified? nongenerative)
|
||||
(let ((uid (list 'quote
|
||||
(or (and (> (length cr) 1) (cadr cr))
|
||||
(gensym)))))
|
||||
(loop fields parent protocol sealed
|
||||
opaque uid constructor
|
||||
parent-rtd (cdr record-clauses)))
|
||||
(raise (make-assertion-violation))))
|
||||
((parent-rtd)
|
||||
(if (not (unspecified? parent))
|
||||
(raise (make-assertion-violation)))
|
||||
(if (unspecified? parent-rtd)
|
||||
(loop fields parent protocol sealed opaque
|
||||
nongenerative constructor (cdr cr)
|
||||
(cdr record-clauses))
|
||||
(raise (make-assertion-violation))))
|
||||
(else (raise (make-assertion-violation)))))))))))
|
||||
(define predicate-name (record-predicate record-name))
|
||||
#,@field-accessors
|
||||
#,@field-mutators))]
|
||||
[((fields record-fields ...) . rest)
|
||||
(if (unspecified? _fields)
|
||||
(loop (process-fields #'record-name #'(record-fields ...))
|
||||
_parent _protocol _sealed _opaque _nongenerative
|
||||
_constructor _parent-rtd #'rest)
|
||||
(raise (make-assertion-violation)))]
|
||||
[((parent parent-name) . rest)
|
||||
(if (not (unspecified? _parent-rtd))
|
||||
(raise (make-assertion-violation))
|
||||
(if (unspecified? _parent)
|
||||
(loop _fields #'parent-name _protocol _sealed _opaque
|
||||
_nongenerative _constructor _parent-rtd #'rest)
|
||||
(raise (make-assertion-violation))))]
|
||||
[((protocol expression) . rest)
|
||||
(if (unspecified? _protocol)
|
||||
(loop _fields _parent #'expression _sealed _opaque
|
||||
_nongenerative _constructor _parent-rtd #'rest)
|
||||
(raise (make-assertion-violation)))]
|
||||
[((sealed sealed?) . rest)
|
||||
(if (unspecified? _sealed)
|
||||
(loop _fields _parent _protocol #'sealed? _opaque
|
||||
_nongenerative _constructor _parent-rtd #'rest)
|
||||
(raise (make-assertion-violation)))]
|
||||
[((opaque opaque?) . rest)
|
||||
(if (unspecified? _opaque)
|
||||
(loop _fields _parent _protocol _sealed #'opaque?
|
||||
_nongenerative _constructor _parent-rtd #'rest)
|
||||
(raise (make-assertion-violation)))]
|
||||
[((nongenerative) . rest)
|
||||
(if (unspecified? _nongenerative)
|
||||
(loop _fields _parent _protocol _sealed _opaque
|
||||
#`(quote #,(datum->syntax #'record-name (gensym)))
|
||||
_constructor _parent-rtd #'rest)
|
||||
(raise (make-assertion-violation)))]
|
||||
[((nongenerative uid) . rest)
|
||||
(if (unspecified? _nongenerative)
|
||||
(loop _fields _parent _protocol _sealed
|
||||
_opaque #''uid _constructor
|
||||
_parent-rtd #'rest)
|
||||
(raise (make-assertion-violation)))]
|
||||
[((parent-rtd rtd cd) . rest)
|
||||
(if (not (unspecified? _parent))
|
||||
(raise (make-assertion-violation))
|
||||
(if (unspecified? _parent-rtd)
|
||||
(loop _fields _parent _protocol _sealed _opaque
|
||||
_nongenerative _constructor #'(rtd cd)
|
||||
#'rest)
|
||||
(raise (make-assertion-violation))))]))))))
|
||||
|
||||
(define-syntax record-type-descriptor
|
||||
(lambda (stx)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
|
@ -132,19 +132,19 @@ scm_t_int32 test_ffi_s32_s64 (scm_t_int64 a)
|
|||
scm_t_uint32 test_ffi_u32_ (void);
|
||||
scm_t_uint32 test_ffi_u32_ (void)
|
||||
{
|
||||
return 4000000000;
|
||||
return 4000000000U;
|
||||
}
|
||||
|
||||
scm_t_uint32 test_ffi_u32_u8 (scm_t_uint8 a);
|
||||
scm_t_uint32 test_ffi_u32_u8 (scm_t_uint8 a)
|
||||
{
|
||||
return 4000000000 + a;
|
||||
return 4000000000U + a;
|
||||
}
|
||||
|
||||
scm_t_uint32 test_ffi_u32_s64 (scm_t_int64 a);
|
||||
scm_t_uint32 test_ffi_u32_s64 (scm_t_int64 a)
|
||||
{
|
||||
return 4000000000 + a;
|
||||
return 4000000000U + a;
|
||||
}
|
||||
|
||||
/* FIXME: use 64-bit literals */
|
||||
|
@ -169,19 +169,19 @@ scm_t_int64 test_ffi_s64_s64 (scm_t_int64 a)
|
|||
scm_t_uint64 test_ffi_u64_ (void);
|
||||
scm_t_uint64 test_ffi_u64_ (void)
|
||||
{
|
||||
return 4000000000;
|
||||
return 4000000000UL;
|
||||
}
|
||||
|
||||
scm_t_uint64 test_ffi_u64_u8 (scm_t_uint8 a);
|
||||
scm_t_uint64 test_ffi_u64_u8 (scm_t_uint8 a)
|
||||
{
|
||||
return 4000000000 + a;
|
||||
return 4000000000UL + a;
|
||||
}
|
||||
|
||||
scm_t_uint64 test_ffi_u64_s64 (scm_t_int64 a);
|
||||
scm_t_uint64 test_ffi_u64_s64 (scm_t_int64 a)
|
||||
{
|
||||
return 4000000000 + a;
|
||||
return 4000000000UL + a;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,10 +19,13 @@
|
|||
|
||||
|
||||
(define-module (test-suite test-rnrs-records-syntactic)
|
||||
:use-module ((rnrs records syntactic) :version (6))
|
||||
:use-module ((rnrs records procedural) :version (6))
|
||||
:use-module ((rnrs records inspection) :version (6))
|
||||
:use-module (test-suite lib))
|
||||
#:use-module ((rnrs records syntactic) #:version (6))
|
||||
#:use-module ((rnrs records procedural) #:version (6))
|
||||
#:use-module ((rnrs records inspection) #:version (6))
|
||||
#:use-module ((rnrs conditions) #:version (6))
|
||||
#:use-module ((rnrs exceptions) #:version (6))
|
||||
#:use-module ((system base compile) #:select (compile))
|
||||
#:use-module (test-suite lib))
|
||||
|
||||
(define-record-type simple-rtd)
|
||||
(define-record-type
|
||||
|
@ -115,3 +118,34 @@
|
|||
|
||||
(pass-if "record-constructor-descriptor returns rcd"
|
||||
(procedure? (record-constructor (record-constructor-descriptor simple-rtd))))
|
||||
|
||||
(with-test-prefix "record hygiene"
|
||||
(pass-if-exception "using shadowed record keywords fails" exception:syntax-pattern-unmatched
|
||||
(compile '(let ((fields #f))
|
||||
(define-record-type foo (fields bar))
|
||||
#t)
|
||||
#:env (current-module)))
|
||||
(pass-if "using shadowed record keywords fails 2"
|
||||
(guard (condition ((syntax-violation? condition) #t))
|
||||
(compile '(let ((immutable #f))
|
||||
(define-record-type foo (fields (immutable bar)))
|
||||
#t)
|
||||
#:env (current-module))
|
||||
#f))
|
||||
(pass-if "hygiene preserved when using macros"
|
||||
(compile '(begin
|
||||
(define pass #t)
|
||||
(define-syntax define-record
|
||||
(syntax-rules ()
|
||||
((define-record name field)
|
||||
(define-record-type name
|
||||
(protocol
|
||||
(lambda (x)
|
||||
(lambda ()
|
||||
;; pass refers to pass in scope of macro not use
|
||||
(x pass))))
|
||||
(fields field)))))
|
||||
(let ((pass #f))
|
||||
(define-record foo bar)
|
||||
(foo-bar (make-foo))))
|
||||
#:env (current-module))))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue