mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
Merge commit '3d51e57cfb
'
Conflicts: libguile/foreign.c libguile/hashtab.c module/ice-9/psyntax-pp.scm module/language/tree-il/compile-glil.scm
This commit is contained in:
commit
252acfe8e7
38 changed files with 560 additions and 169 deletions
|
@ -12,7 +12,7 @@ flow of Scheme affects C code.
|
|||
|
||||
@menu
|
||||
* begin:: Sequencing and splicing.
|
||||
* if cond case:: Simple conditional evaluation.
|
||||
* Conditionals:: If, when, unless, case, and cond.
|
||||
* and or:: Conditional evaluation of a sequence.
|
||||
* while do:: Iteration mechanisms.
|
||||
* Prompts:: Composable, delimited continuations.
|
||||
|
@ -103,11 +103,13 @@ good idea. But it is useful to be able to write macros that expand out
|
|||
to multiple definitions, as in @code{define-sealant} above, so Scheme
|
||||
abuses the @code{begin} form for these two tasks.
|
||||
|
||||
@node if cond case
|
||||
@node Conditionals
|
||||
@subsection Simple Conditional Evaluation
|
||||
|
||||
@cindex conditional evaluation
|
||||
@cindex if
|
||||
@cindex when
|
||||
@cindex unless
|
||||
@cindex case
|
||||
@cindex cond
|
||||
|
||||
|
@ -121,14 +123,44 @@ values.
|
|||
All arguments may be arbitrary expressions. First, @var{test} is
|
||||
evaluated. If it returns a true value, the expression @var{consequent}
|
||||
is evaluated and @var{alternate} is ignored. If @var{test} evaluates to
|
||||
@code{#f}, @var{alternate} is evaluated instead. The value of the
|
||||
evaluated branch (@var{consequent} or @var{alternate}) is returned as
|
||||
the value of the @code{if} expression.
|
||||
@code{#f}, @var{alternate} is evaluated instead. The values of the
|
||||
evaluated branch (@var{consequent} or @var{alternate}) are returned as
|
||||
the values of the @code{if} expression.
|
||||
|
||||
When @var{alternate} is omitted and the @var{test} evaluates to
|
||||
@code{#f}, the value of the expression is not specified.
|
||||
@end deffn
|
||||
|
||||
When you go to write an @code{if} without an alternate (a @dfn{one-armed
|
||||
@code{if}}), part of what you are expressing is that you don't care
|
||||
about the return value (or values) of the expression. As such, you are
|
||||
more interested in the @emph{effect} of evaluating the consequent
|
||||
expression. (By convention, we use the word @dfn{statement} to refer to
|
||||
an expression that is evaluated for effect, not for value).
|
||||
|
||||
In such a case, it is considered more clear to express these intentions
|
||||
with these special forms, @code{when} and @code{unless}. As an added
|
||||
bonus, these forms accept multiple statements to evaluate, which are
|
||||
implicitly wrapped in a @code{begin}.
|
||||
|
||||
@deffn {Scheme Syntax} when test statement1 statement2 ...
|
||||
@deffnx {Scheme Syntax} unless test statement1 statement2 ...
|
||||
The actual definitions of these forms are in many ways their most clear
|
||||
documentation:
|
||||
|
||||
@example
|
||||
(define-syntax-rule (when test stmt stmt* ...)
|
||||
(if test (begin stmt stmt* ...)))
|
||||
|
||||
(define-syntax-rule (unless condition stmt stmt* ...)
|
||||
(if (not test) (begin stmt stmt* ...)))
|
||||
@end example
|
||||
|
||||
That is to say, @code{when} evaluates its consequent statements in order
|
||||
if @var{test} is true. @code{unless} is the opposite: it evaluates the
|
||||
statements if @var{test} is false.
|
||||
@end deffn
|
||||
|
||||
@deffn syntax cond clause1 clause2 @dots{}
|
||||
Each @code{cond}-clause must look like this:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
@ -78,10 +78,10 @@ equality predicates @code{eq?}, @code{eqv?} and @code{equal?}
|
|||
#t
|
||||
@end lisp
|
||||
|
||||
In test condition contexts like @code{if} and @code{cond} (@pxref{if
|
||||
cond case}), where a group of subexpressions will be evaluated only if a
|
||||
@var{condition} expression evaluates to ``true'', ``true'' means any
|
||||
value at all except @code{#f}.
|
||||
In test condition contexts like @code{if} and @code{cond}
|
||||
(@pxref{Conditionals}), where a group of subexpressions will be
|
||||
evaluated only if a @var{condition} expression evaluates to ``true'',
|
||||
``true'' means any value at all except @code{#f}.
|
||||
|
||||
@lisp
|
||||
(if #t "yes" "no")
|
||||
|
@ -1865,6 +1865,16 @@ Return a datum representation of @var{state} that may be written out and
|
|||
read back with the Scheme reader.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} random-state-from-platform
|
||||
@deffnx {C Function} scm_random_state_from_platform ()
|
||||
Construct a new random state seeded from a platform-specific source of
|
||||
entropy, appropriate for use in non-security-critical applications.
|
||||
Currently @file{/dev/urandom} is tried first, or else the seed is based
|
||||
on the time, date, process ID, an address from a freshly allocated heap
|
||||
cell, an address from the local stack frame, and a high-resolution timer
|
||||
if available.
|
||||
@end deffn
|
||||
|
||||
@defvar *random-state*
|
||||
The global random state used by the above functions when the
|
||||
@var{state} parameter is not given.
|
||||
|
@ -1887,29 +1897,13 @@ Guile started up, will always give:
|
|||
(0 1 1 2 2 2 1 2 6 7 10 0 5 3 12 5 5 12)
|
||||
@end lisp
|
||||
|
||||
To use the time of day as the random seed, you can use code like this:
|
||||
To seed the random state in a sensible way for non-security-critical
|
||||
applications, do this during initialization of your program:
|
||||
|
||||
@lisp
|
||||
(let ((time (gettimeofday)))
|
||||
(set! *random-state*
|
||||
(seed->random-state (+ (car time)
|
||||
(cdr time)))))
|
||||
(set! *random-state* (random-state-from-platform))
|
||||
@end lisp
|
||||
|
||||
@noindent
|
||||
And then (depending on the time of day, of course):
|
||||
|
||||
@lisp
|
||||
(map random (cdr (iota 19)))
|
||||
@result{}
|
||||
(0 0 1 0 2 4 5 4 5 5 9 3 10 1 8 3 14 17)
|
||||
@end lisp
|
||||
|
||||
For security applications, such as password generation, you should use
|
||||
more bits of seed. Otherwise an open source password generator could
|
||||
be attacked by guessing the seed@dots{} but that's a subject for
|
||||
another manual.
|
||||
|
||||
|
||||
@node Characters
|
||||
@subsection Characters
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2010, 2011
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2010, 2011, 2012
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
@ -292,6 +292,25 @@ If the @code{positions} reader option is enabled, each parenthesized
|
|||
expression will have values set for the @code{filename}, @code{line} and
|
||||
@code{column} properties.
|
||||
|
||||
Source properties are also associated with syntax objects. Procedural
|
||||
macros can get at the source location of their input using the
|
||||
@code{syntax-source} accessor. @xref{Syntax Transformer Helpers}, for
|
||||
more.
|
||||
|
||||
Guile also defines a couple of convenience macros built on
|
||||
@code{syntax-source}:
|
||||
|
||||
@deffn {Scheme Syntax} current-source-location
|
||||
Expands to the source properties corresponding to the location of the
|
||||
@code{(current-source-location)} form.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Syntax} current-filename
|
||||
Expands to the current filename: the filename that the
|
||||
@code{(current-filename)} form appears in. Expands to @code{#f} if this
|
||||
information is unavailable.
|
||||
@end deffn
|
||||
|
||||
If you're stuck with defmacros (@pxref{Defmacros}), and want to preserve
|
||||
source information, the following helper function might be useful to
|
||||
you:
|
||||
|
|
|
@ -17,6 +17,7 @@ loading, evaluating, and compiling Scheme code at run time.
|
|||
* Fly Evaluation:: Procedures for on the fly evaluation.
|
||||
* Compilation:: How to compile Scheme files and procedures.
|
||||
* Loading:: Loading Scheme code from file.
|
||||
* Load Paths:: Where Guile looks for code.
|
||||
* Character Encoding of Source Files:: Loading non-ASCII Scheme code from file.
|
||||
* Delayed Evaluation:: Postponing evaluation until it is needed.
|
||||
@end menu
|
||||
|
@ -711,7 +712,7 @@ useful compilation warnings. It can be customized from @file{~/.guile}.
|
|||
@rnindex load
|
||||
@deffn {Scheme Procedure} load filename [reader]
|
||||
Load @var{filename} and evaluate its contents in the top-level
|
||||
environment. The load paths are not searched.
|
||||
environment.
|
||||
|
||||
@var{reader} if provided should be either @code{#f}, or a procedure with
|
||||
the signature @code{(lambda (port) @dots{})} which reads the next
|
||||
|
@ -730,29 +731,21 @@ documentation for @code{%load-hook} later in this section.
|
|||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} load-compiled filename
|
||||
Load the compiled file named @var{filename}. The load paths are not
|
||||
searched.
|
||||
Load the compiled file named @var{filename}.
|
||||
|
||||
Compiling a source file (@pxref{Read/Load/Eval/Compile}) and then
|
||||
calling @code{load-compiled} on the resulting file is equivalent to
|
||||
calling @code{load} on the source file.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} load-from-path filename
|
||||
Similar to @code{load}, but searches for @var{filename} in the load
|
||||
paths. Preferentially loads a compiled version of the file, if it is
|
||||
available and up-to-date.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} primitive-load filename
|
||||
@deffnx {C Function} scm_primitive_load (filename)
|
||||
Load the file named @var{filename} and evaluate its contents in
|
||||
the top-level environment. The load paths are not searched;
|
||||
@var{filename} must either be a full pathname or be a pathname
|
||||
relative to the current directory. If the variable
|
||||
@code{%load-hook} is defined, it should be bound to a procedure
|
||||
that will be called before any code is loaded. See the
|
||||
documentation for @code{%load-hook} later in this section.
|
||||
Load the file named @var{filename} and evaluate its contents in the
|
||||
top-level environment. @var{filename} must either be a full pathname or
|
||||
be a pathname relative to the current directory. If the variable
|
||||
@code{%load-hook} is defined, it should be bound to a procedure that
|
||||
will be called before any code is loaded. See the documentation for
|
||||
@code{%load-hook} later in this section.
|
||||
@end deffn
|
||||
|
||||
@deftypefn {C Function} SCM scm_c_primitive_load (const char *filename)
|
||||
|
@ -760,33 +753,6 @@ documentation for @code{%load-hook} later in this section.
|
|||
@code{SCM}.
|
||||
@end deftypefn
|
||||
|
||||
@deffn {Scheme Procedure} primitive-load-path filename [exception-on-not-found]
|
||||
@deffnx {C Function} scm_primitive_load_path (filename)
|
||||
Search @code{%load-path} for the file named @var{filename} and
|
||||
load it into the top-level environment. If @var{filename} is a
|
||||
relative pathname and is not found in the list of search paths,
|
||||
an error is signalled. Preferentially loads a compiled version of the
|
||||
file, if it is available and up-to-date.
|
||||
|
||||
By default or if @var{exception-on-not-found} is true, an exception is
|
||||
raised if @var{filename} is not found. If @var{exception-on-not-found}
|
||||
is @code{#f} and @var{filename} is not found, no exception is raised and
|
||||
@code{#f} is returned. For compatibility with Guile 1.8 and earlier,
|
||||
the C function takes only one argument, which can be either a string
|
||||
(the file name) or an argument list.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} %search-load-path filename
|
||||
@deffnx {C Function} scm_sys_search_load_path (filename)
|
||||
Search @code{%load-path} for the file named @var{filename},
|
||||
which must be readable by the current user. If @var{filename}
|
||||
is found in the list of paths to search or is an absolute
|
||||
pathname, return its full pathname. Otherwise, return
|
||||
@code{#f}. Filenames may have any of the optional extensions
|
||||
in the @code{%load-extensions} list; @code{%search-load-path}
|
||||
will try each extension automatically.
|
||||
@end deffn
|
||||
|
||||
@defvar current-reader
|
||||
@code{current-reader} holds the read procedure that is currently being
|
||||
used by the above loading procedures to read expressions (from the file
|
||||
|
@ -814,9 +780,9 @@ change occurs at the right time.
|
|||
@defvar %load-hook
|
||||
A procedure to be called @code{(%load-hook @var{filename})} whenever a
|
||||
file is loaded, or @code{#f} for no such call. @code{%load-hook} is
|
||||
used by all of the above loading functions (@code{load},
|
||||
@code{load-path}, @code{primitive-load} and
|
||||
@code{primitive-load-path}).
|
||||
used by all of the loading functions (@code{load} and
|
||||
@code{primitive-load}, and @code{load-from-path} and
|
||||
@code{primitive-load-path} documented in the next section).
|
||||
|
||||
For example an application can set this to show what's loaded,
|
||||
|
||||
|
@ -834,6 +800,65 @@ Return the current-load-port.
|
|||
The load port is used internally by @code{primitive-load}.
|
||||
@end deffn
|
||||
|
||||
@node Load Paths
|
||||
@subsection Load Paths
|
||||
|
||||
The procedure in the previous section look for Scheme code in the file
|
||||
system at specific location. Guile also has some procedures to search
|
||||
the load path for code.
|
||||
|
||||
For more on the @code{%load-path} variable, @xref{Build Config}.
|
||||
|
||||
@deffn {Scheme Procedure} load-from-path filename
|
||||
Similar to @code{load}, but searches for @var{filename} in the load
|
||||
paths. Preferentially loads a compiled version of the file, if it is
|
||||
available and up-to-date.
|
||||
@end deffn
|
||||
|
||||
A user can extend the load path by calling @code{add-to-load-path}.
|
||||
|
||||
@deffn {Scheme Syntax} add-to-load-path dir
|
||||
Add @var{dir} to the load path.
|
||||
|
||||
For example, a script might include this form to add the directory that
|
||||
it is in to the load path:
|
||||
|
||||
@example
|
||||
(add-to-load-path (dirname (current-filename)))
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
It's better to use @code{add-to-load-path} than to modify
|
||||
@code{%load-path} directly, because @code{add-to-load-path} takes care
|
||||
of modifying the path both at compile-time and at run-time.
|
||||
|
||||
@deffn {Scheme Procedure} primitive-load-path filename [exception-on-not-found]
|
||||
@deffnx {C Function} scm_primitive_load_path (filename)
|
||||
Search @code{%load-path} for the file named @var{filename} and
|
||||
load it into the top-level environment. If @var{filename} is a
|
||||
relative pathname and is not found in the list of search paths,
|
||||
an error is signalled. Preferentially loads a compiled version of the
|
||||
file, if it is available and up-to-date.
|
||||
|
||||
By default or if @var{exception-on-not-found} is true, an exception is
|
||||
raised if @var{filename} is not found. If @var{exception-on-not-found}
|
||||
is @code{#f} and @var{filename} is not found, no exception is raised and
|
||||
@code{#f} is returned. For compatibility with Guile 1.8 and earlier,
|
||||
the C function takes only one argument, which can be either a string
|
||||
(the file name) or an argument list.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} %search-load-path filename
|
||||
@deffnx {C Function} scm_sys_search_load_path (filename)
|
||||
Search @code{%load-path} for the file named @var{filename},
|
||||
which must be readable by the current user. If @var{filename}
|
||||
is found in the list of paths to search or is an absolute
|
||||
pathname, return its full pathname. Otherwise, return
|
||||
@code{#f}. Filenames may have any of the optional extensions
|
||||
in the @code{%load-extensions} list; @code{%search-load-path}
|
||||
will try each extension automatically.
|
||||
@end deffn
|
||||
|
||||
@defvar %load-extensions
|
||||
A list of default file extensions for files containing Scheme code.
|
||||
@code{%search-load-path} tries each of these extensions when looking for
|
||||
|
@ -841,6 +866,7 @@ a file to load. By default, @code{%load-extensions} is bound to the
|
|||
list @code{("" ".scm")}.
|
||||
@end defvar
|
||||
|
||||
|
||||
@node Character Encoding of Source Files
|
||||
@subsection Character Encoding of Source Files
|
||||
|
||||
|
|
|
@ -744,7 +744,7 @@ information with macros:
|
|||
(define-syntax-rule (with-aux aux value)
|
||||
(let ((trans value))
|
||||
(set! (aux-property trans) aux)
|
||||
trans)))
|
||||
trans))
|
||||
(define-syntax retrieve-aux
|
||||
(lambda (x)
|
||||
(syntax-case x ()
|
||||
|
@ -768,6 +768,41 @@ information with macros:
|
|||
a syntax transformer; to call it otherwise will signal an error.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} syntax-locally-bound-identifiers id
|
||||
Return a list of identifiers that were visible lexically when the
|
||||
identifier @var{id} was created, in order from outermost to innermost.
|
||||
|
||||
This procedure is intended to be used in specialized procedural macros,
|
||||
to provide a macro with the set of bound identifiers that the macro can
|
||||
reference.
|
||||
|
||||
As a technical implementation detail, the identifiers returned by
|
||||
@code{syntax-locally-bound-identifiers} will be anti-marked, like the
|
||||
syntax object that is given as input to a macro. This is to signal to
|
||||
the macro expander that these bindings were present in the original
|
||||
source, and do not need to be hygienically renamed, as would be the case
|
||||
with other introduced identifiers. See the discussion of hygiene in
|
||||
section 12.1 of the R6RS, for more information on marks.
|
||||
|
||||
@example
|
||||
(define (local-lexicals id)
|
||||
(filter (lambda (x)
|
||||
(eq? (syntax-local-binding x) 'lexical))
|
||||
(syntax-locally-bound-identifiers id)))
|
||||
(define-syntax lexicals
|
||||
(lambda (x)
|
||||
(syntax-case x ()
|
||||
((lexicals) #'(lexicals lexicals))
|
||||
((lexicals scope)
|
||||
(with-syntax (((id ...) (local-lexicals #'scope)))
|
||||
#'(list (cons 'id id) ...))))))
|
||||
|
||||
(let* ((x 10) (x 20)) (lexicals))
|
||||
@result{} ((x . 10) (x . 20))
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Defmacros
|
||||
@subsection Lisp-style Macro Definitions
|
||||
|
||||
|
|
|
@ -468,7 +468,7 @@ the @code{%load-path} (@pxref{Build Config}). For each directory in
|
|||
@code{%load-path}, Guile will try to find the file name, concatenated
|
||||
with the extensions from @code{%load-extensions}. By default, this will
|
||||
cause Guile to @code{stat} @file{ice-9/popen.scm}, and then
|
||||
@file{ice-9/popen}. @xref{Loading}, for more on
|
||||
@file{ice-9/popen}. @xref{Load Paths}, for more on
|
||||
@code{primitive-load-path}.
|
||||
|
||||
If a corresponding compiled @file{.go} file is found in the
|
||||
|
|
|
@ -73,7 +73,7 @@ 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
|
||||
(@pxref{Load Paths, @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.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 2010, 2011
|
||||
@c Copyright (C) 2010, 2011, 2012
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
@ -316,7 +316,7 @@ grouped below by the existing manual sections to which they correspond.
|
|||
@deffn {Scheme Syntax} if test consequence [alternate]
|
||||
@deffnx {Scheme Syntax} cond clause1 clause2 ...
|
||||
@deffnx {Scheme Syntax} case key clause1 clause2 ...
|
||||
@xref{if cond case}, for documentation.
|
||||
@xref{Conditionals}, for documentation.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Syntax} and expr ...
|
||||
|
@ -1146,7 +1146,7 @@ exception handler that binds a raised exception to @var{variable} and
|
|||
then evaluates the specified @var{clause}s as if they were part of a
|
||||
@code{cond} expression, with the value of the first matching clause
|
||||
becoming the value of the @code{guard} expression
|
||||
(@pxref{if cond case}). If none of the clause's test expressions
|
||||
(@pxref{Conditionals}). If none of the clause's test expressions
|
||||
evaluates to @code{#t}, the exception is re-raised, with the exception
|
||||
handler that was current before the evaluation of the @code{guard} form.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2012
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
@ -964,11 +964,11 @@ same as a procedure which returns its last argument, because the
|
|||
evaluation of a procedure invocation expression does not guarantee to
|
||||
evaluate the arguments in order.
|
||||
|
||||
@code{if} and @code{cond} (@pxref{if cond case}) provide conditional
|
||||
@code{if} and @code{cond} (@pxref{Conditionals}) provide conditional
|
||||
evaluation of argument expressions depending on whether one or more
|
||||
conditions evaluate to ``true'' or ``false''.
|
||||
|
||||
@code{case} (@pxref{if cond case}) provides conditional evaluation of
|
||||
@code{case} (@pxref{Conditionals}) provides conditional evaluation of
|
||||
argument expressions depending on whether a variable has one of a
|
||||
specified group of values.
|
||||
|
||||
|
|
|
@ -750,8 +750,8 @@ The first thing to do is to install your Scheme files where Guile can
|
|||
find them. When Guile goes to find a Scheme file, it will search a
|
||||
@dfn{load path} to find the file: first in Guile's own path, then in
|
||||
paths for @dfn{site packages}. A site package is any Scheme code that
|
||||
is installed and not part of Guile itself. @xref{Loading}, for more on
|
||||
load paths.
|
||||
is installed and not part of Guile itself. @xref{Load Paths}, for more
|
||||
on load paths.
|
||||
|
||||
There are several site paths, for historical reasons, but the one that
|
||||
should generally be used can be obtained by invoking the
|
||||
|
|
|
@ -4193,7 +4193,7 @@ This SRFI extends RnRS @code{cond} to support test expressions that
|
|||
return multiple values, as well as arbitrary definitions of test
|
||||
success. SRFI 61 is implemented in the Guile core; there's no module
|
||||
needed to get SRFI-61 itself. Extended @code{cond} is documented in
|
||||
@ref{if cond case,, Simple Conditional Evaluation}.
|
||||
@ref{Conditionals,, Simple Conditional Evaluation}.
|
||||
|
||||
@node SRFI-67
|
||||
@subsection SRFI-67 - Compare procedures
|
||||
|
|
|
@ -6,6 +6,10 @@ This document describes the typical release process for Guile 2.0.
|
|||
|
||||
* Preparing & uploading the tarball
|
||||
|
||||
** M-x debbugs-gnu
|
||||
|
||||
… or http://bugs.gnu.org/guile, for an idea of things to fix.
|
||||
|
||||
** Update Gnulib
|
||||
|
||||
The commit log's first line should be "Update Gnulib to X", where X is
|
||||
|
@ -49,6 +53,12 @@ If you're still in a good mood, you may also want to check on porter
|
|||
boxes for other OSes. The GNU/Hurd people have [[http://www.gnu.org/software/hurd/public_hurd_boxen.html][porter boxes]], so does
|
||||
the [[http://www.opencsw.org/standards/build_farm][OpenCSW Solaris Team]].
|
||||
|
||||
|
||||
*** Post a pre-release announcement to `platform-testers@gnu.org'
|
||||
|
||||
Send a link to [[http://hydra.nixos.org/job/gnu/guile-2-0/tarball/latest/download-by-type/file/source-dist][the latest tarball]]. This will allow readers to test on
|
||||
possibly weird platforms and report any bugs.
|
||||
|
||||
** Update `GUILE-VERSION'
|
||||
|
||||
For stable releases, make sure to update the SONAME appropriately. To
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## Process this file with Automake to create Makefile.in
|
||||
##
|
||||
## Copyright (C) 1998, 1999, 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
## Copyright (C) 1998, 1999, 2000, 2001, 2004, 2006, 2007, 2008,
|
||||
## 2009, 2010, 2012 Free Software Foundation, Inc.
|
||||
##
|
||||
## This file is part of guile-readline.
|
||||
##
|
||||
|
@ -68,7 +69,7 @@ EXTRA_DIST += LIBGUILEREADLINE-VERSION ChangeLog-2008
|
|||
ETAGS_ARGS += \
|
||||
$(libguilereadline_v_@LIBGUILEREADLINE_MAJOR@_la_SOURCES)
|
||||
|
||||
CLEANFILES += *.x
|
||||
CLEANFILES += *.x *.go
|
||||
|
||||
endif HAVE_READLINE
|
||||
|
||||
|
|
|
@ -316,8 +316,6 @@ SCM_DEFINE (scm_set_pointer_finalizer_x, "set-pointer-finalizer!", 2, 0, 0,
|
|||
|
||||
c_finalizer = SCM_POINTER_VALUE (finalizer);
|
||||
|
||||
SCM_SET_CELL_WORD_0 (pointer, SCM_CELL_WORD_0 (pointer) | (1 << 16UL));
|
||||
|
||||
GC_REGISTER_FINALIZER_NO_ORDER (SCM_HEAP_OBJECT_BASE (pointer),
|
||||
pointer_finalizer_trampoline,
|
||||
c_finalizer,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2001, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001, 2009, 2010, 2011, 2012 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
|
||||
|
@ -24,9 +24,16 @@
|
|||
#include <string.h>
|
||||
#include "_scm.h"
|
||||
#include "frames.h"
|
||||
#include <verify.h>
|
||||
|
||||
/* Make sure assumptions on the layout of `struct scm_vm_frame' hold. */
|
||||
verify (sizeof (SCM) == sizeof (SCM *));
|
||||
verify (sizeof (struct scm_vm_frame) == 5 * sizeof (SCM));
|
||||
verify (offsetof (struct scm_vm_frame, dynamic_link) == 0);
|
||||
|
||||
|
||||
#define RELOC(frame, val) (val + SCM_VM_FRAME_OFFSET (frame))
|
||||
#define RELOC(frame, val) \
|
||||
(((SCM *) (val)) + SCM_VM_FRAME_OFFSET (frame))
|
||||
|
||||
SCM
|
||||
scm_c_make_frame (SCM stack_holder, SCM *fp, SCM *sp,
|
||||
|
|
|
@ -70,9 +70,10 @@ struct scm_vm_frame
|
|||
SCM stack[1]; /* Variable-length */
|
||||
};
|
||||
|
||||
#define SCM_FRAME_STRUCT(fp) ((struct scm_vm_frame*)(((SCM*)(fp)) - 4))
|
||||
#define SCM_FRAME_STRUCT(fp) \
|
||||
((struct scm_vm_frame *) SCM_FRAME_DATA_ADDRESS (fp))
|
||||
|
||||
#define SCM_FRAME_DATA_ADDRESS(fp) (fp - 4)
|
||||
#define SCM_FRAME_DATA_ADDRESS(fp) (((SCM *) (fp)) - 4)
|
||||
#define SCM_FRAME_STACK_ADDRESS(fp) (SCM_FRAME_STRUCT (fp)->stack)
|
||||
#define SCM_FRAME_UPPER_ADDRESS(fp) ((SCM*)&SCM_FRAME_STRUCT (fp)->return_address)
|
||||
#define SCM_FRAME_LOWER_ADDRESS(fp) ((SCM*)SCM_FRAME_STRUCT (fp))
|
||||
|
@ -91,7 +92,7 @@ struct scm_vm_frame
|
|||
#define SCM_FRAME_DYNAMIC_LINK(fp) \
|
||||
(SCM_FRAME_STRUCT (fp)->dynamic_link)
|
||||
#define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) \
|
||||
SCM_FRAME_STRUCT (fp)->dynamic_link = (dl)
|
||||
SCM_FRAME_DYNAMIC_LINK (fp) = (dl)
|
||||
#define SCM_FRAME_VARIABLE(fp,i) \
|
||||
(SCM_FRAME_STRUCT (fp)->stack[i])
|
||||
#define SCM_FRAME_PROGRAM(fp) \
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Copyright (C) 1995,1996,1998,1999,2000,2001, 2003, 2004, 2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
*
|
||||
/* Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2003, 2004, 2006,
|
||||
* 2008, 2009, 2010, 2011, 2012 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
|
||||
* as published by the Free Software Foundation; either version 3 of
|
||||
|
@ -168,6 +169,8 @@ void
|
|||
scm_i_hashtable_print (SCM exp, SCM port, scm_print_state *pstate)
|
||||
{
|
||||
scm_puts_unlocked ("#<hash-table ", port);
|
||||
scm_uintprint (SCM_UNPACK (exp), 16, port);
|
||||
scm_putc (' ', port);
|
||||
scm_uintprint (SCM_HASHTABLE_N_ITEMS (exp), 10, port);
|
||||
scm_putc_unlocked ('/', port);
|
||||
scm_uintprint (SCM_SIMPLE_VECTOR_LENGTH (SCM_HASHTABLE_VECTOR (exp)),
|
||||
|
|
|
@ -653,6 +653,107 @@ SCM_DEFINE (scm_random_exp, "random:exp", 0, 1, 0,
|
|||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
/* Return a new random-state seeded from the time, date, process ID, an
|
||||
address from a freshly allocated heap cell, an address from the local
|
||||
stack frame, and a high-resolution timer if available. This is only
|
||||
to be used as a last resort, when no better source of entropy is
|
||||
available. */
|
||||
static SCM
|
||||
random_state_of_last_resort (void)
|
||||
{
|
||||
SCM state;
|
||||
SCM time_of_day = scm_gettimeofday ();
|
||||
SCM sources = scm_list_n
|
||||
(scm_from_unsigned_integer (SCM_UNPACK (time_of_day)), /* heap addr */
|
||||
scm_getpid (), /* process ID */
|
||||
scm_get_internal_real_time (), /* high-resolution process timer */
|
||||
scm_from_unsigned_integer ((scm_t_bits) &time_of_day), /* stack addr */
|
||||
scm_car (time_of_day), /* seconds since midnight 1970-01-01 UTC */
|
||||
scm_cdr (time_of_day), /* microsecond component of the above clock */
|
||||
SCM_UNDEFINED);
|
||||
|
||||
/* Concatenate the sources bitwise to form the seed */
|
||||
SCM seed = SCM_INUM0;
|
||||
while (scm_is_pair (sources))
|
||||
{
|
||||
seed = scm_logxor (seed, scm_ash (scm_car (sources),
|
||||
scm_integer_length (seed)));
|
||||
sources = scm_cdr (sources);
|
||||
}
|
||||
|
||||
/* FIXME The following code belongs in `scm_seed_to_random_state',
|
||||
and here we should simply do:
|
||||
|
||||
return scm_seed_to_random_state (seed);
|
||||
|
||||
Unfortunately, `scm_seed_to_random_state' only preserves around 32
|
||||
bits of entropy from the provided seed. I don't know if it's okay
|
||||
to fix that in 2.0, so for now we have this workaround. */
|
||||
{
|
||||
int i, len;
|
||||
unsigned char *buf;
|
||||
len = scm_to_int (scm_ceiling_quotient (scm_integer_length (seed),
|
||||
SCM_I_MAKINUM (8)));
|
||||
buf = (unsigned char *) malloc (len);
|
||||
for (i = len-1; i >= 0; --i)
|
||||
{
|
||||
buf[i] = scm_to_int (scm_logand (seed, SCM_I_MAKINUM (255)));
|
||||
seed = scm_ash (seed, SCM_I_MAKINUM (-8));
|
||||
}
|
||||
state = make_rstate (scm_c_make_rstate ((char *) buf, len));
|
||||
free (buf);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/* Attempt to fill buffer with random bytes from /dev/urandom.
|
||||
Return 1 if successful, else return 0. */
|
||||
static int
|
||||
read_dev_urandom (unsigned char *buf, size_t len)
|
||||
{
|
||||
size_t res = 0;
|
||||
FILE *f = fopen ("/dev/urandom", "r");
|
||||
if (f)
|
||||
{
|
||||
res = fread(buf, 1, len, f);
|
||||
fclose (f);
|
||||
}
|
||||
return (res == len);
|
||||
}
|
||||
|
||||
/* Fill a buffer with random bytes seeded from a platform-specific
|
||||
source of entropy. /dev/urandom is used if available. Note that
|
||||
this function provides no guarantees about the amount of entropy
|
||||
present in the returned bytes. */
|
||||
void
|
||||
scm_i_random_bytes_from_platform (unsigned char *buf, size_t len)
|
||||
{
|
||||
if (read_dev_urandom (buf, len))
|
||||
return;
|
||||
else /* FIXME: support other platform sources */
|
||||
{
|
||||
/* When all else fails, use this (rather weak) fallback */
|
||||
SCM random_state = random_state_of_last_resort ();
|
||||
int i;
|
||||
for (i = len-1; i >= 0; --i)
|
||||
buf[i] = scm_to_int (scm_random (SCM_I_MAKINUM (256), random_state));
|
||||
}
|
||||
}
|
||||
|
||||
SCM_DEFINE (scm_random_state_from_platform, "random-state-from-platform", 0, 0, 0,
|
||||
(void),
|
||||
"Construct a new random state seeded from a platform-specific\n\
|
||||
source of entropy, appropriate for use in non-security-critical applications.")
|
||||
#define FUNC_NAME s_scm_random_state_from_platform
|
||||
{
|
||||
unsigned char buf[32];
|
||||
if (read_dev_urandom (buf, sizeof(buf)))
|
||||
return make_rstate (scm_c_make_rstate ((char *) buf, sizeof(buf)));
|
||||
else
|
||||
return random_state_of_last_resort ();
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
void
|
||||
scm_init_random ()
|
||||
{
|
||||
|
|
|
@ -86,6 +86,7 @@ SCM_API SCM scm_copy_random_state (SCM state);
|
|||
SCM_API SCM scm_seed_to_random_state (SCM seed);
|
||||
SCM_API SCM scm_datum_to_random_state (SCM datum);
|
||||
SCM_API SCM scm_random_state_to_datum (SCM state);
|
||||
SCM_API SCM scm_random_state_from_platform (void);
|
||||
SCM_API SCM scm_random_uniform (SCM state);
|
||||
SCM_API SCM scm_random_solid_sphere_x (SCM v, SCM state);
|
||||
SCM_API SCM scm_random_hollow_sphere_x (SCM v, SCM state);
|
||||
|
@ -94,6 +95,8 @@ SCM_API SCM scm_random_normal_vector_x (SCM v, SCM state);
|
|||
SCM_API SCM scm_random_exp (SCM state);
|
||||
SCM_INTERNAL void scm_init_random (void);
|
||||
|
||||
SCM_INTERNAL void scm_i_random_bytes_from_platform (unsigned char *buf, size_t len);
|
||||
|
||||
#endif /* SCM_RANDOM_H */
|
||||
|
||||
/*
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "libguile/variable.h"
|
||||
#include "libguile/alist.h"
|
||||
#include "libguile/fluids.h"
|
||||
#include "libguile/threads.h"
|
||||
#include "libguile/strings.h"
|
||||
#include "libguile/vectors.h"
|
||||
#include "libguile/weak-set.h"
|
||||
|
@ -378,7 +379,9 @@ SCM_DEFINE (scm_string_ci_to_symbol, "string-ci->symbol", 1, 0, 0,
|
|||
/* The default prefix for `gensym'd symbols. */
|
||||
static SCM default_gensym_prefix;
|
||||
|
||||
#define MAX_PREFIX_LENGTH 30
|
||||
#define GENSYM_LENGTH 22 /* bytes */
|
||||
#define GENSYM_RADIX_BITS 6
|
||||
#define GENSYM_RADIX (1 << (GENSYM_RADIX_BITS))
|
||||
|
||||
SCM_DEFINE (scm_gensym, "gensym", 0, 1, 0,
|
||||
(SCM prefix),
|
||||
|
@ -389,22 +392,47 @@ SCM_DEFINE (scm_gensym, "gensym", 0, 1, 0,
|
|||
"resetting the counter.")
|
||||
#define FUNC_NAME s_scm_gensym
|
||||
{
|
||||
static int gensym_counter = 0;
|
||||
|
||||
static const char base64[GENSYM_RADIX] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$@";
|
||||
static const char base4[4] = "_.-~";
|
||||
|
||||
unsigned char *digit_buf = SCM_I_CURRENT_THREAD->gensym_counter;
|
||||
char char_buf[GENSYM_LENGTH];
|
||||
SCM suffix, name;
|
||||
int n, n_digits;
|
||||
char buf[SCM_INTBUFLEN];
|
||||
int i;
|
||||
|
||||
if (SCM_UNBNDP (prefix))
|
||||
prefix = default_gensym_prefix;
|
||||
|
||||
/* mutex in case another thread looks and incs at the exact same moment */
|
||||
scm_i_scm_pthread_mutex_lock (&scm_i_misc_mutex);
|
||||
n = gensym_counter++;
|
||||
scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
|
||||
if (SCM_UNLIKELY (digit_buf == NULL))
|
||||
{
|
||||
/* This is the first time gensym has been called in this thread.
|
||||
Allocate and randomize our new thread-local gensym counter */
|
||||
digit_buf = (unsigned char *)
|
||||
scm_gc_malloc_pointerless (GENSYM_LENGTH, "gensym-counter");
|
||||
scm_i_random_bytes_from_platform (digit_buf, GENSYM_LENGTH);
|
||||
for (i = (GENSYM_LENGTH - 1); i >= 0; --i)
|
||||
digit_buf[i] &= (GENSYM_RADIX - 1);
|
||||
SCM_I_CURRENT_THREAD->gensym_counter = digit_buf;
|
||||
}
|
||||
|
||||
n_digits = scm_iint2str (n, 10, buf);
|
||||
suffix = scm_from_latin1_stringn (buf, n_digits);
|
||||
/* Increment our thread-local gensym_counter. */
|
||||
for (i = (GENSYM_LENGTH - 1); i >= 0; --i)
|
||||
{
|
||||
if (SCM_LIKELY (++(digit_buf[i]) < GENSYM_RADIX))
|
||||
break;
|
||||
else
|
||||
digit_buf[i] = 0;
|
||||
}
|
||||
|
||||
/* Encode digit_buf as base64, except for the first character where we
|
||||
use the sparse glyphs "_.-~" (base 4) to provide some visual
|
||||
separation between the prefix and the dense base64 block. */
|
||||
for (i = (GENSYM_LENGTH - 1); i > 0; --i)
|
||||
char_buf[i] = base64[digit_buf[i]];
|
||||
char_buf[0] = base4[digit_buf[0] & 3];
|
||||
|
||||
suffix = scm_from_latin1_stringn (char_buf, GENSYM_LENGTH);
|
||||
name = scm_string_append (scm_list_2 (prefix, suffix));
|
||||
return scm_string_to_symbol (name);
|
||||
}
|
||||
|
|
|
@ -544,6 +544,7 @@ guilify_self_1 (struct GC_stack_base *base)
|
|||
t.join_queue = SCM_EOL;
|
||||
t.dynamic_state = SCM_BOOL_F;
|
||||
t.dynwinds = SCM_EOL;
|
||||
t.gensym_counter = NULL;
|
||||
t.active_asyncs = SCM_EOL;
|
||||
t.block_asyncs = 1;
|
||||
t.pending_asyncs = 1;
|
||||
|
|
|
@ -81,6 +81,10 @@ typedef struct scm_i_thread {
|
|||
SCM dynamic_state;
|
||||
SCM dynwinds;
|
||||
|
||||
/* Thread-local gensym counter.
|
||||
*/
|
||||
unsigned char *gensym_counter;
|
||||
|
||||
/* For system asyncs.
|
||||
*/
|
||||
SCM active_asyncs; /* The thunks to be run at the next
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Copyright (C) 2001,2008,2009,2010,2011 Free Software Foundation, Inc.
|
||||
*
|
||||
/* Copyright (C) 2001, 2008, 2009, 2010, 2011,
|
||||
* 2012 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
|
||||
* as published by the Free Software Foundation; either version 3 of
|
||||
|
@ -19,6 +20,17 @@
|
|||
|
||||
/* This file is included in vm_engine.c */
|
||||
|
||||
/* Compiler barrier, to prevent instruction reordering, apparently due
|
||||
to a bug in GCC 4.3.2 on sparc-linux-gnu and on hppa2.0-linux-gnu.
|
||||
See <http://bugs.gnu.org/10520>, for details. */
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define COMPILER_BARRIER __asm__ __volatile__ ("")
|
||||
#else
|
||||
# define COMPILER_BARRIER do { } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Basic operations
|
||||
|
@ -55,6 +67,7 @@ VM_DEFINE_INSTRUCTION (1, halt, "halt", 0, 0, 0)
|
|||
stack */
|
||||
ip = SCM_FRAME_RETURN_ADDRESS (fp);
|
||||
fp = SCM_FRAME_DYNAMIC_LINK (fp);
|
||||
COMPILER_BARRIER;
|
||||
NULLSTACK (old_sp - sp);
|
||||
}
|
||||
|
||||
|
@ -1267,6 +1280,7 @@ VM_DEFINE_INSTRUCTION (67, return, "return", 0, 1, 1)
|
|||
sp = SCM_FRAME_LOWER_ADDRESS (fp);
|
||||
ip = SCM_FRAME_RETURN_ADDRESS (fp);
|
||||
fp = SCM_FRAME_DYNAMIC_LINK (fp);
|
||||
COMPILER_BARRIER;
|
||||
|
||||
#ifdef VM_ENABLE_STACK_NULLING
|
||||
NULLSTACK (old_sp - sp);
|
||||
|
@ -1302,7 +1316,8 @@ VM_DEFINE_INSTRUCTION (68, return_values, "return/values", 1, -1, -1)
|
|||
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
|
||||
ip = SCM_FRAME_MV_RETURN_ADDRESS (fp);
|
||||
fp = SCM_FRAME_DYNAMIC_LINK (fp);
|
||||
|
||||
COMPILER_BARRIER;
|
||||
|
||||
/* Push return values, and the number of values */
|
||||
for (i = 0; i < nvalues; i++)
|
||||
*++sp = vals[i+1];
|
||||
|
@ -1322,7 +1337,8 @@ VM_DEFINE_INSTRUCTION (68, return_values, "return/values", 1, -1, -1)
|
|||
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
|
||||
ip = SCM_FRAME_RETURN_ADDRESS (fp);
|
||||
fp = SCM_FRAME_DYNAMIC_LINK (fp);
|
||||
|
||||
COMPILER_BARRIER;
|
||||
|
||||
/* Push first value */
|
||||
*++sp = vals[1];
|
||||
|
||||
|
@ -1713,6 +1729,7 @@ VM_DEFINE_INSTRUCTION (93, assert_nargs_ee_locals, "assert-nargs-ee/locals", 1,
|
|||
NEXT;
|
||||
}
|
||||
|
||||
#undef COMPILER_BARRIER
|
||||
|
||||
/*
|
||||
(defun renumber-ops ()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2001, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001, 2009, 2010, 2011, 2012 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
|
||||
|
@ -280,7 +280,8 @@ vm_reinstate_partial_continuation (SCM vm, SCM cont, SCM intwinds,
|
|||
cp = SCM_VM_CONT_DATA (cont);
|
||||
base = SCM_FRAME_UPPER_ADDRESS (vp->fp) + 1;
|
||||
|
||||
#define RELOC(scm_p) (scm_p + cp->reloc + (base - cp->stack_base))
|
||||
#define RELOC(scm_p) \
|
||||
(((SCM *) (scm_p)) + cp->reloc + (base - cp->stack_base))
|
||||
|
||||
if ((base - vp->stack_base) + cp->stack_size + n + 1 > vp->stack_size)
|
||||
scm_misc_error ("vm-engine",
|
||||
|
|
|
@ -390,6 +390,7 @@ If there is no handler at all, Guile prints an error and then exits."
|
|||
(define bound-identifier=? #f)
|
||||
(define free-identifier=? #f)
|
||||
(define syntax-local-binding #f)
|
||||
(define syntax-locally-bound-identifiers #f)
|
||||
|
||||
;; $sc-dispatch is an implementation detail of psyntax. It is used by
|
||||
;; expanded macros, to dispatch an input against a set of patterns.
|
||||
|
@ -412,6 +413,12 @@ If there is no handler at all, Guile prints an error and then exits."
|
|||
((_ x) x)
|
||||
((_ x y ...) (let ((t x)) (if t t (or y ...))))))
|
||||
|
||||
(define-syntax-rule (when test stmt stmt* ...)
|
||||
(if test (begin stmt stmt* ...)))
|
||||
|
||||
(define-syntax-rule (unless test stmt stmt* ...)
|
||||
(if (not test) (begin stmt stmt* ...)))
|
||||
|
||||
;; The "maybe-more" bits are something of a hack, so that we can support
|
||||
;; SRFI-61. Rewrites into a standalone syntax-case macro would be
|
||||
;; appreciated.
|
||||
|
@ -506,6 +513,18 @@ If there is no handler at all, Guile prints an error and then exits."
|
|||
(with-syntax ((s (datum->syntax x (syntax-source x))))
|
||||
#''s)))))
|
||||
|
||||
;; We provide this accessor out of convenience. current-line and
|
||||
;; current-column aren't so interesting, because they distort what they
|
||||
;; are measuring; better to use syntax-source from a macro.
|
||||
;;
|
||||
(define-syntax current-filename
|
||||
(lambda (x)
|
||||
"A macro that expands to the current filename: the filename that
|
||||
the (current-filename) form appears in. Expands to #f if this
|
||||
information is unavailable."
|
||||
(false-if-exception
|
||||
(canonicalize-path (assq-ref (syntax-source x) 'filename)))))
|
||||
|
||||
(define-syntax-rule (define-once sym val)
|
||||
(define sym
|
||||
(if (module-locally-bound? (current-module) 'sym) sym val)))
|
||||
|
@ -1377,6 +1396,11 @@ VALUE."
|
|||
(start-stack 'load-stack
|
||||
(primitive-load-path name)))
|
||||
|
||||
(define-syntax-rule (add-to-load-path elt)
|
||||
"Add ELT to Guile's load path, at compile-time and at run-time."
|
||||
(eval-when (compile load eval)
|
||||
(set! %load-path (cons elt %load-path))))
|
||||
|
||||
(define %load-verbosely #f)
|
||||
(define (assert-load-verbosity v) (set! %load-verbosely v))
|
||||
|
||||
|
|
|
@ -627,7 +627,12 @@
|
|||
;; labels must be comparable with "eq?", have read-write invariance,
|
||||
;; and distinct from symbols.
|
||||
(define gen-label
|
||||
(lambda () (symbol->string (gensym "i"))))
|
||||
(let ((i 0))
|
||||
(lambda ()
|
||||
(let ((n i))
|
||||
;; FIXME: Use atomic ops.
|
||||
(set! i (1+ n))
|
||||
(number->string n 36)))))
|
||||
|
||||
(define gen-labels
|
||||
(lambda (ls)
|
||||
|
@ -812,6 +817,55 @@
|
|||
id))))))
|
||||
(else (syntax-violation 'id-var-name "invalid id" id)))))
|
||||
|
||||
;; A helper procedure for syntax-locally-bound-identifiers, which
|
||||
;; itself is a helper for transformer procedures.
|
||||
;; `locally-bound-identifiers' returns a list of all bindings
|
||||
;; visible to a syntax object with the given wrap. They are in
|
||||
;; order from outer to inner.
|
||||
;;
|
||||
;; The purpose of this procedure is to give a transformer procedure
|
||||
;; references on bound identifiers, that the transformer can then
|
||||
;; introduce some of them in its output. As such, the identifiers
|
||||
;; are anti-marked, so that rebuild-macro-output doesn't apply new
|
||||
;; marks to them.
|
||||
;;
|
||||
(define locally-bound-identifiers
|
||||
(lambda (w mod)
|
||||
(define scan
|
||||
(lambda (subst results)
|
||||
(if (null? subst)
|
||||
results
|
||||
(let ((fst (car subst)))
|
||||
(if (eq? fst 'shift)
|
||||
(scan (cdr subst) results)
|
||||
(let ((symnames (ribcage-symnames fst))
|
||||
(marks (ribcage-marks fst)))
|
||||
(if (vector? symnames)
|
||||
(scan-vector-rib subst symnames marks results)
|
||||
(scan-list-rib subst symnames marks results))))))))
|
||||
(define scan-list-rib
|
||||
(lambda (subst symnames marks results)
|
||||
(let f ((symnames symnames) (marks marks) (results results))
|
||||
(if (null? symnames)
|
||||
(scan (cdr subst) results)
|
||||
(f (cdr symnames) (cdr marks)
|
||||
(cons (wrap (car symnames)
|
||||
(anti-mark (make-wrap (car marks) subst))
|
||||
mod)
|
||||
results))))))
|
||||
(define scan-vector-rib
|
||||
(lambda (subst symnames marks results)
|
||||
(let ((n (vector-length symnames)))
|
||||
(let f ((i 0) (results results))
|
||||
(if (fx= i n)
|
||||
(scan (cdr subst) results)
|
||||
(f (fx+ i 1)
|
||||
(cons (wrap (vector-ref symnames i)
|
||||
(anti-mark (make-wrap (vector-ref marks i) subst))
|
||||
mod)
|
||||
results)))))))
|
||||
(scan (wrap-subst w) '())))
|
||||
|
||||
;; Returns three values: binding type, binding value, the module (for
|
||||
;; resolving toplevel vars).
|
||||
(define (resolve-identifier id w r mod resolve-syntax-parameters?)
|
||||
|
@ -2553,7 +2607,7 @@
|
|||
|
||||
(set! syntax-local-binding
|
||||
(lambda (id)
|
||||
(arg-check nonsymbol-id? id 'syntax-local-value)
|
||||
(arg-check nonsymbol-id? id 'syntax-local-binding)
|
||||
(with-transformer-environment
|
||||
(lambda (e r w s rib mod)
|
||||
(define (strip-anti-mark w)
|
||||
|
@ -2578,9 +2632,15 @@
|
|||
((macro) (values 'macro value))
|
||||
((syntax) (values 'pattern-variable value))
|
||||
((displaced-lexical) (values 'displaced-lexical #f))
|
||||
((global) (values 'global (cons value mod)))
|
||||
((global) (values 'global (cons value (cdr mod))))
|
||||
(else (values 'other #f)))))))))
|
||||
|
||||
(set! syntax-locally-bound-identifiers
|
||||
(lambda (x)
|
||||
(arg-check nonsymbol-id? x 'syntax-locally-bound-identifiers)
|
||||
(locally-bound-identifiers (syntax-object-wrap x)
|
||||
(syntax-object-module x))))
|
||||
|
||||
(set! generate-temporaries
|
||||
(lambda (ls)
|
||||
(arg-check list? ls 'generate-temporaries)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; -*- mode: scheme; coding: utf-8; -*-
|
||||
;;;
|
||||
;;; Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
;;; Copyright (C) 2009, 2010, 2011, 2012 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
|
||||
|
@ -21,6 +21,7 @@
|
|||
#:use-module (srfi srfi-9)
|
||||
#:use-module (srfi srfi-9 gnu)
|
||||
#:use-module (srfi srfi-26)
|
||||
#:use-module (ice-9 format)
|
||||
|
||||
#:export (vlist? vlist-cons vlist-head vlist-tail vlist-null?
|
||||
vlist-null list->vlist vlist-ref vlist-drop vlist-take
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; Guile VM code converters
|
||||
|
||||
;; Copyright (C) 2001, 2009, 2010 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2001, 2009, 2010, 2012 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
|
||||
|
@ -141,6 +141,9 @@
|
|||
(list "`~a'~@[ (arg)~]"
|
||||
(binding:name b) (< (binding:index b) nargs))
|
||||
(lp (cdr bindings))))))))
|
||||
((assert-nargs-ee/locals assert-nargs-ge/locals)
|
||||
(list "~a arg~:p, ~a local~:p"
|
||||
(logand (car args) #x7) (ash (car args) -3)))
|
||||
((free-ref free-boxed-ref free-boxed-set)
|
||||
;; FIXME: we can do better than this
|
||||
(list "(closure variable)"))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; TREE-IL -> GLIL compiler
|
||||
|
||||
;; Copyright (C) 2001,2008,2009,2010,2011 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2001,2008,2009,2010,2011,2012 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
|
||||
|
@ -402,13 +402,12 @@
|
|||
;; values-mismatch warning pass.
|
||||
(comp-push (make-call src (make-primitive-ref #f 'values)
|
||||
'())))
|
||||
((1)
|
||||
(comp-push (car args)))
|
||||
(else
|
||||
;; Taking advantage of unspecified order of evaluation of
|
||||
;; arguments.
|
||||
(for-each comp-drop (cdr args))
|
||||
(comp-push (car args)))))
|
||||
(comp-push (car args))
|
||||
(maybe-emit-return))))
|
||||
((vals)
|
||||
(for-each comp-push args)
|
||||
(emit-code #f (make-glil-const (length args)))
|
||||
|
|
|
@ -1008,7 +1008,9 @@ top-level bindings from ENV and return the resulting expression."
|
|||
exp))
|
||||
(else
|
||||
(let ((vals (map for-value exps)))
|
||||
(if (and (memq ctx '(value test effect))
|
||||
(if (and (case ctx
|
||||
((value test effect) #t)
|
||||
(else (null? (cdr vals))))
|
||||
(every singly-valued-expression? vals))
|
||||
(for-tail (list->seq src (append (cdr vals) (list (car vals)))))
|
||||
(make-primcall src 'values vals))))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; control.scm --- The R6RS control structures library
|
||||
|
||||
;; Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2010, 2012 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
|
||||
|
@ -19,14 +19,4 @@
|
|||
|
||||
(library (rnrs control (6))
|
||||
(export when unless do case-lambda)
|
||||
(import (only (guile) if not begin define-syntax syntax-rules do case-lambda))
|
||||
|
||||
(define-syntax when
|
||||
(syntax-rules ()
|
||||
((when test result1 result2 ...)
|
||||
(if test (begin result1 result2 ...)))))
|
||||
|
||||
(define-syntax unless
|
||||
(syntax-rules ()
|
||||
((unless test result1 result2 ...)
|
||||
(if (not test) (begin result1 result2 ...))))))
|
||||
(import (only (guile) when unless do case-lambda)))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;; (sxml ssax) -- the SSAX parser
|
||||
;;;;
|
||||
;;;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
|
||||
;;;; Copyright (C) 2009, 2010,2012 Free Software Foundation, Inc.
|
||||
;;;; Modified 2004 by Andy Wingo <wingo at pobox dot com>.
|
||||
;;;; Written 2001,2002,2003,2004 by Oleg Kiselyov <oleg at pobox dot com> as SSAX.scm.
|
||||
;;;;
|
||||
|
@ -209,13 +209,6 @@ string @var{str}, which will then be parsed."
|
|||
(set! ssax:predefined-parsed-entities
|
||||
(acons entity str ssax:predefined-parsed-entities)))
|
||||
|
||||
;; if condition is true, execute stmts in turn and return the result of
|
||||
;; the last statement otherwise, return #f
|
||||
(define-syntax when
|
||||
(syntax-rules ()
|
||||
((when condition . stmts)
|
||||
(and condition (begin . stmts)))))
|
||||
|
||||
;; Execute a sequence of forms and return the result of the _first_ one.
|
||||
;; Like PROG1 in Lisp. Typically used to evaluate one or more forms with
|
||||
;; side effects and return a value that must be computed before some or
|
||||
|
|
|
@ -8,13 +8,6 @@
|
|||
|
||||
(define *error* '())
|
||||
|
||||
(define-syntax when
|
||||
(syntax-rules ()
|
||||
((_ ?expr ?body ...)
|
||||
(if ?expr
|
||||
(let () ?body ...)
|
||||
#f))))
|
||||
|
||||
(define-syntax check
|
||||
(syntax-rules (=>)
|
||||
((_ ?expr => ?expected-result)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;; Assembly to bytecode compilation -*- mode: scheme; coding: utf-8; -*-
|
||||
;;;;
|
||||
;;;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
;;;; Copyright (C) 2010, 2011, 2012 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
|
||||
|
@ -129,6 +129,12 @@
|
|||
(string=? (target-vendor) vendor)
|
||||
(string=? (target-os) os)))))))
|
||||
|
||||
(define (native-cpu)
|
||||
(with-target %host-type target-cpu))
|
||||
|
||||
(define (native-word-size)
|
||||
((@ (system foreign) sizeof) '*))
|
||||
|
||||
(define %objcode-cookie-size
|
||||
(string-length "GOOF----LE-8"))
|
||||
|
||||
|
@ -139,7 +145,17 @@
|
|||
(lambda (p get-objcode)
|
||||
(with-target triplet
|
||||
(lambda ()
|
||||
(let ((b (compile-bytecode
|
||||
(let ((word-size
|
||||
;; When the target is the native CPU, rather trust
|
||||
;; the native CPU's word size. This is because
|
||||
;; Debian's `sparc64-linux-gnu' port, for instance,
|
||||
;; actually has a 32-bit user-land, for instance (see
|
||||
;; <http://www.debian.org/ports/sparc/#sparc64bit>
|
||||
;; for details.)
|
||||
(if (string=? (native-cpu) (target-cpu))
|
||||
(native-word-size)
|
||||
word-size))
|
||||
(b (compile-bytecode
|
||||
'(load-program () 16 #f
|
||||
(assert-nargs-ee/locals 1)
|
||||
(make-int8 77)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;; foreign.test --- FFI. -*- mode: scheme; coding: utf-8; -*-
|
||||
;;;;
|
||||
;;;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
;;;; Copyright (C) 2010, 2011, 2012 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
|
||||
|
@ -71,6 +71,12 @@
|
|||
(equal? (make-pointer 123)
|
||||
(make-pointer 123 finalizer))))
|
||||
|
||||
(pass-if "equal? modulo finalizer (set-pointer-finalizer!)"
|
||||
(let ((finalizer (dynamic-func "scm_is_pair" (dynamic-link)))
|
||||
(ptr (make-pointer 123)))
|
||||
(set-pointer-finalizer! ptr finalizer)
|
||||
(equal? (make-pointer 123) ptr)))
|
||||
|
||||
(pass-if "not equal?"
|
||||
(not (equal? (make-pointer 123) (make-pointer 456)))))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;; gc.test --- test guile's garbage collection -*- scheme -*-
|
||||
;;;; Copyright (C) 2000, 2001, 2004, 2006, 2007, 2008, 2009,
|
||||
;;;; 2011 Free Software Foundation, Inc.
|
||||
;;;; 2011, 2012 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
|
||||
|
@ -87,11 +87,14 @@
|
|||
total)))
|
||||
|
||||
(pass-if "Lexical vars are collectable"
|
||||
(procedure?
|
||||
(list?
|
||||
(compile
|
||||
'(begin
|
||||
(define guardian (make-guardian))
|
||||
(let ((f (lambda () (display "test\n"))))
|
||||
(let ((f (list 'foo)))
|
||||
;; Introduce a useless second reference to f to prevent the
|
||||
;; optimizer from propagating the lexical binding.
|
||||
f
|
||||
(guardian f))
|
||||
(gc)(gc)(gc)
|
||||
(guardian))))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;; hash.test --- test guile hashing -*- scheme -*-
|
||||
;;;;
|
||||
;;;; Copyright (C) 2004, 2005, 2006, 2008, 2011 Free Software Foundation, Inc.
|
||||
;;;; Copyright (C) 2004, 2005, 2006, 2008, 2011, 2012 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
|
||||
|
@ -75,9 +75,10 @@
|
|||
(make-hash-table -1))
|
||||
(pass-if (hash-table? (make-hash-table 0))) ;; default
|
||||
(pass-if (not (hash-table? 'not-a-hash-table)))
|
||||
(pass-if (equal? "#<hash-table 0/113>"
|
||||
(with-output-to-string
|
||||
(lambda () (write (make-hash-table 100)))))))
|
||||
(pass-if (string-suffix? " 0/113>"
|
||||
(with-output-to-string
|
||||
(lambda ()
|
||||
(write (make-hash-table 100)))))))
|
||||
|
||||
;;;
|
||||
;;; usual set and reference
|
||||
|
@ -129,8 +130,9 @@
|
|||
(equal? 'thirty (hash-ref table 30))
|
||||
(equal? 'thirty-three (hash-ref table 33))
|
||||
(equal? 'bar (hash-ref table 'foo))
|
||||
(equal? "#<hash-table 36/61>"
|
||||
(with-output-to-string (lambda () (write table)))))))
|
||||
(string-suffix? " 36/61>"
|
||||
(with-output-to-string
|
||||
(lambda () (write table)))))))
|
||||
|
||||
;; 1 and 1 are equal? and eqv? and eq?
|
||||
(pass-if (equal? 'foo
|
||||
|
@ -240,8 +242,9 @@
|
|||
(pass-if (equal? 'equal (hashx-ref hash assoc table 2/64)))
|
||||
(pass-if (equal? 'equal (hashx-ref hash assoc table 2/66)))
|
||||
(pass-if (equal? 'equal (hashx-ref hash assoc table 34)))
|
||||
(pass-if (equal? "#<hash-table 33/61>"
|
||||
(with-output-to-string (lambda () (write table)))))))
|
||||
(pass-if (string-suffix? " 33/61>"
|
||||
(with-output-to-string
|
||||
(lambda () (write table)))))))
|
||||
|
||||
(with-test-prefix
|
||||
"hashx"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;;;; tree-il.test --- test suite for compiling tree-il -*- scheme -*-
|
||||
;;;; Andy Wingo <wingo@pobox.com> --- May 2009
|
||||
;;;;
|
||||
;;;; Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
;;;; Copyright (C) 2009, 2010, 2011, 2012 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
|
||||
|
@ -546,7 +546,24 @@
|
|||
(primcall +
|
||||
(primcall values (const 1) (const 2)))
|
||||
(program () (std-prelude 0 0 #f) (label _)
|
||||
(const 1) (call return 1))))
|
||||
(const 1) (call return 1)))
|
||||
|
||||
;; Testing `(values foo)' in push context with RA.
|
||||
(assert-tree-il->glil without-partial-evaluation
|
||||
(apply (primitive cdr)
|
||||
(letrec (lp) (#{lp ~V9KrhVD4PFEL6oCTrLg3A}#)
|
||||
((lambda ((name . lp))
|
||||
(lambda-case ((() #f #f #f () ())
|
||||
(apply (toplevel values) (const (one two)))))))
|
||||
(apply (lexical lp #{lp ~V9KrhVD4PFEL6oCTrLg3A}#))))
|
||||
(program () (std-prelude 0 0 #f) (label _)
|
||||
(branch br _) ;; entering the fix, jump to :2
|
||||
;; :1 body of lp, jump to :3
|
||||
(label _) (bind) (const (one two)) (branch br _) (unbind)
|
||||
;; :2 initial call of lp, jump to :1
|
||||
(label _) (bind) (branch br _) (label _) (unbind)
|
||||
;; :3 the push continuation
|
||||
(call cdr 1) (call return 1))))
|
||||
|
||||
;; FIXME: binding info for or-hacked locals might bork the disassembler,
|
||||
;; and could be tightened in any case
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue