mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-09 13:30:26 +02:00
Merge branch 'master' into lightning
This includes a manual cherry-pick of relevant stable-2.2 commits up to
4c91de3e45
.
This commit is contained in:
commit
41100f7786
58 changed files with 1549 additions and 468 deletions
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
((nil . ((fill-column . 72)
|
((nil . ((fill-column . 72)
|
||||||
(tab-width . 8)))
|
(tab-width . 8)))
|
||||||
(c-mode . ((c-file-style . "gnu")))
|
(c-mode . ((c-file-style . "gnu")
|
||||||
|
(indent-tabs-mode . nil)))
|
||||||
(scheme-mode
|
(scheme-mode
|
||||||
. ((indent-tabs-mode . nil)
|
. ((indent-tabs-mode . nil)
|
||||||
(eval . (put 'pass-if 'scheme-indent-function 1))
|
(eval . (put 'pass-if 'scheme-indent-function 1))
|
||||||
|
|
162
NEWS
162
NEWS
|
@ -1,5 +1,5 @@
|
||||||
Guile NEWS --- history of user-visible changes.
|
Guile NEWS --- history of user-visible changes.
|
||||||
Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||||
See the end for copying conditions.
|
See the end for copying conditions.
|
||||||
|
|
||||||
Please send Guile bug reports to bug-guile@gnu.org.
|
Please send Guile bug reports to bug-guile@gnu.org.
|
||||||
|
@ -61,10 +61,78 @@ installation with other effective versions (for example, the older Guile
|
||||||
2.2). See "Parallel Installations" in the manual for full details.
|
2.2). See "Parallel Installations" in the manual for full details.
|
||||||
Notably, the `pkg-config' file is now `guile-3.0'.
|
Notably, the `pkg-config' file is now `guile-3.0'.
|
||||||
|
|
||||||
|
|
||||||
|
Changes in 2.2.4 (since 2.2.3):
|
||||||
|
|
||||||
|
* New interfaces and functionality
|
||||||
|
|
||||||
|
** SRFI-71 (Extended LET-syntax for multiple values)
|
||||||
|
|
||||||
|
Guile now includes SRFI-71, which extends let, let*, and letrec to
|
||||||
|
support assigning multiple values. See "SRFI-71" in the manual for
|
||||||
|
details.
|
||||||
|
|
||||||
|
** (web client) export 'http-request' procedure
|
||||||
|
|
||||||
|
The 'http-request' procedure is the generalized procedure underneath
|
||||||
|
'http-get', 'http-post', etc.
|
||||||
|
|
||||||
|
** GDB support now registers the 'guile-backtrace' GDB command
|
||||||
|
|
||||||
|
The 'guile-backtrace' GDB command displays a backtrace of the VM stack
|
||||||
|
for the current thread.
|
||||||
|
|
||||||
|
** Recognize RISC-V compilation targets in (system base target)
|
||||||
|
|
||||||
|
* Bug fixes
|
||||||
|
|
||||||
|
** Fix stack-marking bug affecting multi-threaded programs
|
||||||
|
(<https://bugs.gnu.org/28211>)
|
||||||
|
|
||||||
|
** Add missing SYNC_IP calls in the VM
|
||||||
|
|
||||||
|
These could cause multi-threaded code to crash.
|
||||||
|
|
||||||
|
** Fix multi-threaded access to modules
|
||||||
|
(<https://bugs.gnu.org/30602>, <https://bugs.gnu.org/31879>,
|
||||||
|
and <https://bugs.gnu.org/31878>)
|
||||||
|
|
||||||
|
** (ice-9 match) now has better documentation
|
||||||
|
|
||||||
|
** 'get-bytevector-n' and 'get-bytevector-n!' can now read more than 4 GB
|
||||||
|
|
||||||
|
** Fix cross-compilation support for elisp
|
||||||
|
|
||||||
|
** Fix error reporting in 'load-thunk-from-memory'
|
||||||
|
|
||||||
|
** Fix GOOPS 'instance?' to work on objects that aren't structs
|
||||||
|
(<https://bugs.gnu.org/31606>)
|
||||||
|
|
||||||
|
** Fix type inference for bitwise logical operators
|
||||||
|
(<https://bugs.gnu.org/31474>)
|
||||||
|
|
||||||
|
** Avoid inexact arithmetic in the type inferrer for 'sqrt'
|
||||||
|
|
||||||
|
** Fix floating point unboxing regression in 2.2.3
|
||||||
|
(<https://bugs.gnu.org/30020>)
|
||||||
|
|
||||||
|
** Fix eta-conversion edge cases in peval (<https://bugs.gnu.org/29520>)
|
||||||
|
|
||||||
|
** Correctly interpret SRFI-18 timeout parameters
|
||||||
|
(<https://bugs.gnu.org/29704>)
|
||||||
|
|
||||||
|
** 'select' returns empty sets upon EINTR and EAGAIN
|
||||||
|
(<https://bugs.gnu.org/30368>)
|
||||||
|
|
||||||
|
** Restore pre-2.2.3 '%fresh-auto-compile' behavior
|
||||||
|
|
||||||
|
This reverts an incorrect fix for <https://bugs.gnu.org/29226>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Changes in 2.2.3 (since 2.2.2):
|
Changes in 2.2.3 (since 2.2.2):
|
||||||
|
|
||||||
* New interfaces
|
* New interfaces and functionality
|
||||||
|
|
||||||
** (web uri) module has better support for RFC 3986
|
** (web uri) module has better support for RFC 3986
|
||||||
|
|
||||||
|
@ -78,6 +146,53 @@ Identifiers" in the manual, for more.
|
||||||
These procedures should be used when accessing struct fields with type
|
These procedures should be used when accessing struct fields with type
|
||||||
`u' (unboxed). See "Structure Basics" in the manual, for full details.
|
`u' (unboxed). See "Structure Basics" in the manual, for full details.
|
||||||
|
|
||||||
|
** Improved support for arrays with non-zero lower bounds
|
||||||
|
|
||||||
|
Thanks to work by Daniel Llorens, Guile no longer exhibits buggy
|
||||||
|
behavior in "sort" or "sort!" on arrays with non-zero lower dimension
|
||||||
|
bounds. Arrays with non-zero lower dimension bounds are now allowed for
|
||||||
|
array-slice-for-each, and truncated-print now supports bitvectors and
|
||||||
|
arrays with non-zero lower bounds. General arrays are now supported as
|
||||||
|
well for random:hollow-sphere!.
|
||||||
|
|
||||||
|
** Add `uintptr_t' and `intptr_t' to FFI types.
|
||||||
|
|
||||||
|
See "Foreign Types" in the manual for full details.
|
||||||
|
|
||||||
|
* Compiler improvements
|
||||||
|
|
||||||
|
** Improve speed of compiler backend for functions without loops
|
||||||
|
|
||||||
|
This is a marginal speed improvement, especially for code compiled with
|
||||||
|
optimization level "-O1" or below.
|
||||||
|
|
||||||
|
** Disable slot pre-coloring for optimization level "-O1" or below
|
||||||
|
|
||||||
|
This improves the speed of the compiler backend.
|
||||||
|
|
||||||
|
** Improve complexity of constant subexpression elimination pass
|
||||||
|
|
||||||
|
This is a large speed improvement when compiling large files with the
|
||||||
|
default "-O2" pass.
|
||||||
|
|
||||||
|
** CPS conversion avoids generating return arity adapters if possible
|
||||||
|
|
||||||
|
In Guile, the expression in (define a EXP) may return 1 or more values.
|
||||||
|
This value elision in "value" context is implicit earlier in the Guile
|
||||||
|
compiler, in Tree-IL, but is made explicit in the CPS middle-end
|
||||||
|
language by the addition of the equivalent of explicit call-with-values
|
||||||
|
continuations that ignore additional values. However in many cases we
|
||||||
|
can avoid generating these extra continuations if we know that EXP is
|
||||||
|
single-valued, as is the case for example for constants or variable
|
||||||
|
references or the like.
|
||||||
|
|
||||||
|
Although these "arity-adapting continuations" would be removed by dead
|
||||||
|
code elimination at optimization level "-O2" or above, they were still
|
||||||
|
being needlessly generated in the first place. Guile now avoids
|
||||||
|
generating them, speeding up not only the optimizer at -O2 but also the
|
||||||
|
entire compiler pipeline at -O1 or below, as well as improving the
|
||||||
|
residual code at -O1 or below.
|
||||||
|
|
||||||
* New deprecations
|
* New deprecations
|
||||||
|
|
||||||
** Using `uri?' as a predicate on relative-refs deprecated
|
** Using `uri?' as a predicate on relative-refs deprecated
|
||||||
|
@ -131,7 +246,7 @@ slot values manually on initialization.
|
||||||
** Struct fields with opaque ("o") protection deprecated
|
** Struct fields with opaque ("o") protection deprecated
|
||||||
|
|
||||||
Struct fields are declared with a "protection", meaning read-only ('r'),
|
Struct fields are declared with a "protection", meaning read-only ('r'),
|
||||||
read-write ('w'), or opaque ('o'). There is also "hidden" ('o') which
|
read-write ('w'), or opaque ('o'). There is also "hidden" ('h') which
|
||||||
is read-write but which isn't initialized by arguments passed to
|
is read-write but which isn't initialized by arguments passed to
|
||||||
`make-struct/no-tail', but that's a detail. Opaque struct fields were
|
`make-struct/no-tail', but that's a detail. Opaque struct fields were
|
||||||
used to allocate storage in a struct that could only be accessed by C.
|
used to allocate storage in a struct that could only be accessed by C.
|
||||||
|
@ -148,6 +263,47 @@ Use the new `struct-ref/unboxed' and `struct-set!/unboxed' instead.
|
||||||
|
|
||||||
* Bug fixes
|
* Bug fixes
|
||||||
|
|
||||||
|
** guile.m4 now checks for Guile 2.2 by default
|
||||||
|
|
||||||
|
Before, it was still preferring Guile 2.0. It now also supports the
|
||||||
|
Guile 3.0 prereleases.
|
||||||
|
|
||||||
|
** Fix setting breakpoints from the REPL
|
||||||
|
|
||||||
|
** Allow GDB support to be used with GDB linked against Guile 2.0.
|
||||||
|
|
||||||
|
** Fix deadlock in `readdir' on error.
|
||||||
|
|
||||||
|
** Fix crash on ia64 during thread switches.
|
||||||
|
|
||||||
|
** Fix bug inferring range of `logand' computations with negative numbers
|
||||||
|
|
||||||
|
** Fix bug when issuing HTTP requests through proxies.
|
||||||
|
|
||||||
|
** Refactor weak hash table implementation to be more robust
|
||||||
|
|
||||||
|
Guile 2.2's weak hash table implementation had three big problems. The
|
||||||
|
first was a bug causing these tables to leak memory when they would be
|
||||||
|
resized. The second was that the implementation was designed so that
|
||||||
|
tables should be visited by the mark phase of the garbage collector in
|
||||||
|
one big piece. This could cause the garbage collector to see too many
|
||||||
|
newly marked objects at once, causing inefficies in garbage collection.
|
||||||
|
Finally, the way in which lost weak references were ultimately removed
|
||||||
|
from weak tables caused a race between the finalizer threads and the
|
||||||
|
mutator threads, leading to unbounded excess space retention in
|
||||||
|
pathological cases. All of this problems have been fixed.
|
||||||
|
|
||||||
|
** Allow garbage collection of revealed file ports
|
||||||
|
|
||||||
|
Guile can mark a file port as "revealed" if Scheme has been given access
|
||||||
|
to the file descriptor. In that case, the file descriptor will not be
|
||||||
|
closed when the port is garbage-collected. However we had a bug that
|
||||||
|
for revealed ports prevented the port from ever being garbage-collected,
|
||||||
|
leading to memory leaks of Guile's internal port buffers. This is now
|
||||||
|
fixed.
|
||||||
|
|
||||||
|
** Fix put-bytevector, unget-bytevector with start == bytevector length
|
||||||
|
|
||||||
** Enable GNU Readline 7.0's support for "bracketed paste".
|
** Enable GNU Readline 7.0's support for "bracketed paste".
|
||||||
|
|
||||||
Before, when pasting an expression that contained TAB characters into
|
Before, when pasting an expression that contained TAB characters into
|
||||||
|
|
|
@ -7261,7 +7261,7 @@ is an ordinary array of rank 1 with lower bound 2 in dimension 0.
|
||||||
is a non-uniform array of rank 2; a 2@cross{}3 matrix with index ranges 0..1
|
is a non-uniform array of rank 2; a 2@cross{}3 matrix with index ranges 0..1
|
||||||
and 0..2.
|
and 0..2.
|
||||||
|
|
||||||
@item #u32(0 1 2)
|
@item #u8(0 1 2)
|
||||||
is a uniform u8 array of rank 1.
|
is a uniform u8 array of rank 1.
|
||||||
|
|
||||||
@item #2u32@@2@@3((1 2) (2 3))
|
@item #2u32@@2@@3((1 2) (2 3))
|
||||||
|
|
|
@ -658,13 +658,21 @@ Write output bytecode to @var{ofile}. By convention, bytecode file
|
||||||
names end in @code{.go}. When @option{-o} is omitted, the output file
|
names end in @code{.go}. When @option{-o} is omitted, the output file
|
||||||
name is as for @code{compile-file} (see below).
|
name is as for @code{compile-file} (see below).
|
||||||
|
|
||||||
|
@item -x @var{extension}
|
||||||
|
Recognize @var{extension} as a valid source file name extension.
|
||||||
|
|
||||||
|
For example, to compile R6RS code, you might want to pass @command{-x
|
||||||
|
.sls} so that files ending in @file{.sls} can be found.
|
||||||
|
|
||||||
@item -W @var{warning}
|
@item -W @var{warning}
|
||||||
@itemx --warn=@var{warning}
|
@itemx --warn=@var{warning}
|
||||||
@cindex warnings, compiler
|
@cindex warnings, compiler
|
||||||
Emit warnings of type @var{warning}; use @code{--warn=help} for a list
|
Emit warnings of type @var{warning}; use @code{--warn=help} for a list
|
||||||
of available warnings and their description. Currently recognized
|
of available warnings and their description. Currently recognized
|
||||||
warnings include @code{unused-variable}, @code{unused-toplevel},
|
warnings include @code{unused-variable}, @code{unused-toplevel},
|
||||||
@code{unbound-variable}, @code{arity-mismatch}, @code{format},
|
@code{shadowed-toplevel}, @code{unbound-variable},
|
||||||
|
@code{macro-use-before-definition},
|
||||||
|
@code{arity-mismatch}, @code{format},
|
||||||
@code{duplicate-case-datum}, and @code{bad-case-datum}.
|
@code{duplicate-case-datum}, and @code{bad-case-datum}.
|
||||||
|
|
||||||
@item -f @var{lang}
|
@item -f @var{lang}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009, 2010
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009, 2010, 2017
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
@section LALR(1) Parsing
|
@section LALR(1) Parsing
|
||||||
|
|
||||||
The @code{(system base lalr)} module provides the
|
The @code{(system base lalr)} module provides the
|
||||||
@uref{http://code.google.com/p/lalr-scm/, @code{lalr-scm} LALR(1) parser
|
@uref{https://github.com/schemeway/lalr-scm/, @code{lalr-scm} LALR(1) parser
|
||||||
generator by Dominique Boucher}. @code{lalr-scm} uses the same algorithm as GNU
|
generator by Dominique Boucher}. @code{lalr-scm} uses the same algorithm as GNU
|
||||||
Bison (@pxref{Introduction, Introduction to Bison,, bison, Bison@comma{} The
|
Bison (@pxref{Introduction, Introduction to Bison,, bison, Bison@comma{} The
|
||||||
Yacc-compatible Parser Generator}). Parsers are defined using the
|
Yacc-compatible Parser Generator}). Parsers are defined using the
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000-2004, 2009-2015
|
@c Copyright (C) 1996, 1997, 2000-2004, 2009-2015, 2018
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -1280,7 +1280,7 @@ macros will be @code{eval}'d in the top-level environment.
|
||||||
|
|
||||||
In this way @code{(macroexpand @var{foo})} is equivalent to
|
In this way @code{(macroexpand @var{foo})} is equivalent to
|
||||||
@code{(macroexpand @var{foo} 'e '(eval))}. The second argument is the
|
@code{(macroexpand @var{foo} 'e '(eval))}. The second argument is the
|
||||||
mode (@code{'e} for ``eval'') and the second is the
|
mode (@code{'e} for ``eval'') and the third is the
|
||||||
eval-syntax-expanders-when parameter (only @code{eval} in this default
|
eval-syntax-expanders-when parameter (only @code{eval} in this default
|
||||||
setting).
|
setting).
|
||||||
|
|
||||||
|
|
|
@ -1012,7 +1012,7 @@ interpreted internally in two steps.
|
||||||
First, any string PEG is expanded into an s-expression PEG by the code
|
First, any string PEG is expanded into an s-expression PEG by the code
|
||||||
in the @code{(ice-9 peg string-peg)} module.
|
in the @code{(ice-9 peg string-peg)} module.
|
||||||
|
|
||||||
Then, then s-expression PEG that results is compiled into a parsing
|
Then, the s-expression PEG that results is compiled into a parsing
|
||||||
function by the @code{(ice-9 peg codegen)} module. In particular, the
|
function by the @code{(ice-9 peg codegen)} module. In particular, the
|
||||||
function @code{compile-peg-pattern} is called on the s-expression. It then
|
function @code{compile-peg-pattern} is called on the s-expression. It then
|
||||||
decides what to do based on the form it is passed.
|
decides what to do based on the form it is passed.
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
This manual documents Guile version @value{VERSION}.
|
This manual documents Guile version @value{VERSION}.
|
||||||
|
|
||||||
Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2009,
|
Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2009,
|
||||||
2010, 2011, 2012, 2013, 2014, 2015, 2016 Free Software Foundation.
|
2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Free Software
|
||||||
|
Foundation, Inc.
|
||||||
|
|
||||||
Permission is granted to copy, distribute and/or modify this document
|
Permission is granted to copy, distribute and/or modify this document
|
||||||
under the terms of the GNU Free Documentation License, Version 1.3 or
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011, 2013, 2014
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011, 2013, 2014, 2018
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ struct image @{
|
||||||
SCM update_func;
|
SCM update_func;
|
||||||
@};
|
@};
|
||||||
|
|
||||||
static SCM image_type image_type;
|
static SCM image_type;
|
||||||
|
|
||||||
void
|
void
|
||||||
init_image_type (void)
|
init_image_type (void)
|
||||||
|
|
|
@ -213,8 +213,96 @@ any @var{person} whose second slot is a promise that evaluates to a
|
||||||
one-element list containing a @var{person} whose first slot is
|
one-element list containing a @var{person} whose first slot is
|
||||||
@code{"Bob"}.
|
@code{"Bob"}.
|
||||||
|
|
||||||
Please refer to the @code{ice-9/match.upstream.scm} file in your Guile
|
The @code{(ice-9 match)} module also provides the following convenient
|
||||||
installation for more details.
|
syntactic sugar macros wrapping around @code{match}.
|
||||||
|
|
||||||
|
@deffn {Scheme Syntax} match-lambda exp clause1 clause2 @dots{}
|
||||||
|
Create a procedure of one argument that matches its argument against
|
||||||
|
each clause, and returns the result of evaluating the corresponding
|
||||||
|
expressions.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(match-lambda clause1 clause2 @dots{})
|
||||||
|
@equiv{}
|
||||||
|
(lambda (arg) (match arg clause1 clause2 @dots{}))
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@example
|
||||||
|
((match-lambda
|
||||||
|
(('hello (who))
|
||||||
|
who))
|
||||||
|
'(hello (world)))
|
||||||
|
@result{} world
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@deffn {Scheme Syntax} match-lambda* exp clause1 clause2 @dots{}
|
||||||
|
Create a procedure of any number of arguments that matches its argument
|
||||||
|
list against each clause, and returns the result of evaluating the
|
||||||
|
corresponding expressions.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(match-lambda* clause1 clause2 @dots{})
|
||||||
|
@equiv{}
|
||||||
|
(lambda args (match args clause1 clause2 @dots{}))
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@example
|
||||||
|
((match-lambda*
|
||||||
|
(('hello (who))
|
||||||
|
who))
|
||||||
|
'hello '(world))
|
||||||
|
@result{} world
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@deffn {Scheme Syntax} match-let ((pattern expression) @dots{}) body
|
||||||
|
Match each pattern to the corresponding expression, and evaluate the
|
||||||
|
body with all matched variables in scope. Raise an error if any of the
|
||||||
|
expressions fail to match. @code{match-let} is analogous to named let
|
||||||
|
and can also be used for recursive functions which match on their
|
||||||
|
arguments as in @code{match-lambda*}.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(match-let (((x y) (list 1 2))
|
||||||
|
((a b) (list 3 4)))
|
||||||
|
(list a b x y))
|
||||||
|
@result{}
|
||||||
|
(3 4 1 2)
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Syntax} match-let variable ((pattern init) @dots{}) body
|
||||||
|
Similar to @code{match-let}, but analogously to @dfn{named let}, locally
|
||||||
|
bind VARIABLE to a new procedure which accepts as many arguments as
|
||||||
|
there are INIT expressions. The procedure is initially applied to the
|
||||||
|
results of evaluating the INIT expressions. When called, the procedure
|
||||||
|
matches each argument against the corresponding PATTERN, and returns the
|
||||||
|
result(s) of evaluating the BODY expressions. @xref{while do,
|
||||||
|
Iteration}, for more on @dfn{named let}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Syntax} match-let* ((variable expression) @dots{}) body
|
||||||
|
Similar to @code{match-let}, but analogously to @code{let*}, match and
|
||||||
|
bind the variables in sequence, with preceding match variables in scope.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(match-let* (((x y) (list 1 2))
|
||||||
|
((a b) (list x 4)))
|
||||||
|
(list a b x y))
|
||||||
|
@equiv{}
|
||||||
|
(match-let (((x y) (list 1 2)))
|
||||||
|
(match-let (((a b) (list x 4)))
|
||||||
|
(list a b x y)))
|
||||||
|
@result{}
|
||||||
|
(1 4 1 2)
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Syntax} match-letrec ((variable expression) @dots{}) body
|
||||||
|
Similar to @code{match-let}, but analogously to @code{letrec}, match and
|
||||||
|
bind the variables with all match variables in scope.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
Guile also comes with a pattern matcher specifically tailored to SXML
|
Guile also comes with a pattern matcher specifically tailored to SXML
|
||||||
trees, @xref{sxml-match}.
|
trees, @xref{sxml-match}.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000-2004, 2006, 2007-2014, 2017
|
@c Copyright (C) 1996, 1997, 2000-2004, 2006, 2007-2014, 2017, 2018
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ get the relevant SRFI documents from the SRFI home page
|
||||||
* SRFI-64:: A Scheme API for test suites.
|
* SRFI-64:: A Scheme API for test suites.
|
||||||
* SRFI-67:: Compare procedures
|
* SRFI-67:: Compare procedures
|
||||||
* SRFI-69:: Basic hash tables.
|
* SRFI-69:: Basic hash tables.
|
||||||
|
* SRFI-71:: Extended let-syntax for multiple values.
|
||||||
* SRFI-87:: => in case clauses.
|
* SRFI-87:: => in case clauses.
|
||||||
* SRFI-88:: Keyword objects.
|
* SRFI-88:: Keyword objects.
|
||||||
* SRFI-98:: Accessing environment variables.
|
* SRFI-98:: Accessing environment variables.
|
||||||
|
@ -5400,6 +5401,25 @@ Answer a hash value appropriate for equality predicate @code{equal?},
|
||||||
@code{hash} is a backwards-compatible replacement for Guile's built-in
|
@code{hash} is a backwards-compatible replacement for Guile's built-in
|
||||||
@code{hash}.
|
@code{hash}.
|
||||||
|
|
||||||
|
@node SRFI-71
|
||||||
|
@subsection SRFI-71 - Extended let-syntax for multiple values
|
||||||
|
@cindex SRFI-71
|
||||||
|
|
||||||
|
This SRFI shadows the forms for @code{let}, @code{let*}, and @code{letrec}
|
||||||
|
so that they may accept multiple values. For example:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(use-modules (srfi srfi-71))
|
||||||
|
|
||||||
|
(let* ((x y (values 1 2))
|
||||||
|
(z (+ x y)))
|
||||||
|
(* z 2))
|
||||||
|
@result{} 6
|
||||||
|
@end example
|
||||||
|
|
||||||
|
See @uref{http://srfi.schemers.org/srfi-71/srfi-71.html, the
|
||||||
|
specification of SRFI-71}.
|
||||||
|
|
||||||
@node SRFI-87
|
@node SRFI-87
|
||||||
@subsection SRFI-87 => in case clauses
|
@subsection SRFI-87 => in case clauses
|
||||||
@cindex SRFI-87
|
@cindex SRFI-87
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 2008,2009,2010,2011,2013,2015
|
@c Copyright (C) 2008-2011, 2013, 2015, 2018
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -719,7 +719,7 @@ is that arguments are passed and values returned on the stack.
|
||||||
|
|
||||||
For calls, both in tail position and in non-tail position, we require
|
For calls, both in tail position and in non-tail position, we require
|
||||||
that the procedure and the arguments already be shuffled into place
|
that the procedure and the arguments already be shuffled into place
|
||||||
befor the call instruction. ``Into place'' for a tail call means that
|
before the call instruction. ``Into place'' for a tail call means that
|
||||||
the procedure should be in slot 0, relative to the @code{fp}, and the
|
the procedure should be in slot 0, relative to the @code{fp}, and the
|
||||||
arguments should follow. For a non-tail call, if the procedure is in
|
arguments should follow. For a non-tail call, if the procedure is in
|
||||||
@code{fp}-relative slot @var{n}, the arguments should follow from slot
|
@code{fp}-relative slot @var{n}, the arguments should follow from slot
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 2010, 2011, 2012, 2013, 2015 Free Software Foundation, Inc.
|
@c Copyright (C) 2010, 2011, 2012, 2013, 2015, 2018 Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
@node Web
|
@node Web
|
||||||
|
@ -1463,24 +1463,18 @@ how to install the GnuTLS bindings for Guile,, gnutls-guile,
|
||||||
GnuTLS-Guile}, for more information.
|
GnuTLS-Guile}, for more information.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} http-get uri arg...
|
@anchor{http-request}@deffn {Scheme Procedure} http-request @var{uri} @var{arg}@dots{}
|
||||||
@deffnx {Scheme Procedure} http-head uri arg...
|
|
||||||
@deffnx {Scheme Procedure} http-post uri arg...
|
|
||||||
@deffnx {Scheme Procedure} http-put uri arg...
|
|
||||||
@deffnx {Scheme Procedure} http-delete uri arg...
|
|
||||||
@deffnx {Scheme Procedure} http-trace uri arg...
|
|
||||||
@deffnx {Scheme Procedure} http-options uri arg...
|
|
||||||
|
|
||||||
Connect to the server corresponding to @var{uri} and make a request over
|
Connect to the server corresponding to @var{uri} and make a request over
|
||||||
HTTP, using the appropriate method (@code{GET}, @code{HEAD}, etc.).
|
HTTP, using @var{method} (@code{GET}, @code{HEAD}, @code{POST}, etc.).
|
||||||
|
|
||||||
All of these procedures have the same prototype: a URI followed by an
|
The following keyword arguments allow you to modify the requests in
|
||||||
optional sequence of keyword arguments. These keyword arguments allow
|
various ways, for example attaching a body to the request, or setting
|
||||||
you to modify the requests in various ways, for example attaching a body
|
specific headers. The following table lists the keyword arguments and
|
||||||
to the request, or setting specific headers. The following table lists
|
their default values.
|
||||||
the keyword arguments and their default values.
|
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
|
@item #:method 'GET
|
||||||
@item #:body #f
|
@item #:body #f
|
||||||
@item #:port (open-socket-for-uri @var{uri})]
|
@item #:port (open-socket-for-uri @var{uri})]
|
||||||
@item #:version '(1 . 1)
|
@item #:version '(1 . 1)
|
||||||
|
@ -1518,6 +1512,25 @@ body as a string, bytevector, #f value, or as a port (if
|
||||||
@var{streaming?} is true).
|
@var{streaming?} is true).
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} http-get @var{uri} @var{arg}@dots{}
|
||||||
|
@deffnx {Scheme Procedure} http-head @var{uri} @var{arg}@dots{}
|
||||||
|
@deffnx {Scheme Procedure} http-post @var{uri} @var{arg}@dots{}
|
||||||
|
@deffnx {Scheme Procedure} http-put @var{uri} @var{arg}@dots{}
|
||||||
|
@deffnx {Scheme Procedure} http-delete @var{uri} @var{arg}@dots{}
|
||||||
|
@deffnx {Scheme Procedure} http-trace @var{uri} @var{arg}@dots{}
|
||||||
|
@deffnx {Scheme Procedure} http-options @var{uri} @var{arg}@dots{}
|
||||||
|
Connect to the server corresponding to @var{uri} and make a request over
|
||||||
|
HTTP, using the appropriate method (@code{GET}, @code{HEAD},
|
||||||
|
@code{POST}, etc.).
|
||||||
|
|
||||||
|
These procedures are variants of @code{http-request} specialized with a
|
||||||
|
specific @var{method} argument, and have the same prototype: a URI
|
||||||
|
followed by an optional sequence of keyword arguments.
|
||||||
|
@xref{http-request}, for full documentation on the various keyword
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@code{http-get} is useful for making one-off requests to web sites. If
|
@code{http-get} is useful for making one-off requests to web sites. If
|
||||||
you are writing a web spider or some other client that needs to handle a
|
you are writing a web spider or some other client that needs to handle a
|
||||||
number of requests in parallel, it's better to build an event-driven URL
|
number of requests in parallel, it's better to build an event-driven URL
|
||||||
|
|
|
@ -128,9 +128,11 @@ Announcements").
|
||||||
|
|
||||||
** Update web pages
|
** Update web pages
|
||||||
|
|
||||||
- Replace any references to the previous version number and replace it
|
- Update the version number in ‘latest-guile-version’ in the (website
|
||||||
with the new one.
|
utils) module of the web site.
|
||||||
- Update news.html.
|
- Add a news item by dropping a Markdown file under posts/.
|
||||||
|
- Build the web site: =haunt build=.
|
||||||
|
- Synchronize the files under site/ over the CVS repo.
|
||||||
|
|
||||||
** Update the on-line copy of the manual
|
** Update the on-line copy of the manual
|
||||||
|
|
||||||
|
@ -165,14 +167,10 @@ Send to these places, preferably in the morning on a working day (UTC):
|
||||||
- info-gnu@gnu.org (for stable releases only!)
|
- info-gnu@gnu.org (for stable releases only!)
|
||||||
- comp.lang.scheme
|
- comp.lang.scheme
|
||||||
|
|
||||||
** Post a news item on [[http://sv.gnu.org/p/guile/][Savannah]]
|
|
||||||
|
|
||||||
The news will end up on planet.gnu.org. The text can be shorter and
|
|
||||||
more informal, with a link to the email announcement for details.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Copyright © 2011, 2012, 2013, 2017 Free Software Foundation, Inc.
|
Copyright © 2011, 2012, 2013, 2017, 2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Copying and distribution of this file, with or without modification,
|
Copying and distribution of this file, with or without modification,
|
||||||
are permitted in any medium without royalty provided the copyright
|
are permitted in any medium without royalty provided the copyright
|
||||||
|
|
|
@ -482,11 +482,10 @@ install-exec-hook:
|
||||||
rm -f $(DESTDIR)$(bindir)/guile-snarf.awk
|
rm -f $(DESTDIR)$(bindir)/guile-snarf.awk
|
||||||
|
|
||||||
## Instantiate a template.
|
## Instantiate a template.
|
||||||
INSTANTIATE = \
|
INSTANTIATE = \
|
||||||
$(SED) -e 's,[@]pkgdatadir[@],$(pkgdatadir),g' \
|
$(SED) -i -e 's,[@]pkgdatadir[@],$(pkgdatadir),g' \
|
||||||
-e 's,[@]pkglibdir[@],$(pkglibdir),g' \
|
-e 's,[@]pkglibdir[@],$(pkglibdir),g' \
|
||||||
-e 's,[@]GUILE_EFFECTIVE_VERSION[@],$(GUILE_EFFECTIVE_VERSION),g' \
|
-e 's,[@]GUILE_EFFECTIVE_VERSION[@],$(GUILE_EFFECTIVE_VERSION),g'
|
||||||
-i
|
|
||||||
|
|
||||||
install-data-hook: libguile-2.2-gdb.scm
|
install-data-hook: libguile-2.2-gdb.scm
|
||||||
@$(MKDIR_P) $(DESTDIR)$(libdir)
|
@$(MKDIR_P) $(DESTDIR)$(libdir)
|
||||||
|
|
|
@ -906,10 +906,20 @@ SCM_DEFINE (scm_select, "select", 3, 2, 0,
|
||||||
int rv = scm_std_select (max_fd + 1,
|
int rv = scm_std_select (max_fd + 1,
|
||||||
&read_set, &write_set, &except_set,
|
&read_set, &write_set, &except_set,
|
||||||
time_ptr);
|
time_ptr);
|
||||||
/* Let EINTR / EAGAIN cause a return to the user and let them loop
|
if (rv < 0)
|
||||||
to run any asyncs that might be pending. */
|
{
|
||||||
if (rv < 0 && errno != EINTR && errno != EAGAIN)
|
/* Let EINTR / EAGAIN cause a return to the user and let them
|
||||||
SCM_SYSERROR;
|
loop to run any asyncs that might be pending. */
|
||||||
|
if (errno != EINTR && errno != EAGAIN)
|
||||||
|
SCM_SYSERROR;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Return empty sets. */
|
||||||
|
FD_ZERO (&read_set);
|
||||||
|
FD_ZERO (&write_set);
|
||||||
|
FD_ZERO (&except_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return scm_list_3 (retrieve_select_type (&read_set, read_ports_ready, reads),
|
return scm_list_3 (retrieve_select_type (&read_set, read_ports_ready, reads),
|
||||||
|
|
|
@ -170,6 +170,7 @@ if the information is not available."
|
||||||
(define ip-type (type-pointer (lookup-type "scm_t_uint32")))
|
(define ip-type (type-pointer (lookup-type "scm_t_uint32")))
|
||||||
(define fp-type (type-pointer (lookup-type "SCM")))
|
(define fp-type (type-pointer (lookup-type "SCM")))
|
||||||
(define sp-type (type-pointer (lookup-type "SCM")))
|
(define sp-type (type-pointer (lookup-type "SCM")))
|
||||||
|
(define uint-type (type-pointer (lookup-type "scm_t_uintptr")))
|
||||||
|
|
||||||
(define-record-type <vm-frame>
|
(define-record-type <vm-frame>
|
||||||
(make-vm-frame ip sp fp saved-ip saved-fp)
|
(make-vm-frame ip sp fp saved-ip saved-fp)
|
||||||
|
@ -186,10 +187,16 @@ if the information is not available."
|
||||||
(make-vm-frame ip
|
(make-vm-frame ip
|
||||||
sp
|
sp
|
||||||
fp
|
fp
|
||||||
(value-dereference (value-cast (value-sub fp 1)
|
|
||||||
(type-pointer ip-type)))
|
;; fp[0] is the return address.
|
||||||
(value-dereference (value-cast (value-sub fp 2)
|
(value-dereference (value-cast fp (type-pointer ip-type)))
|
||||||
(type-pointer fp-type)))))
|
|
||||||
|
;; fp[1] is the offset to the previous frame pointer.
|
||||||
|
(value-add fp
|
||||||
|
(value->integer
|
||||||
|
(value-dereference
|
||||||
|
(value-cast (value-add fp 1)
|
||||||
|
(type-pointer uint-type)))))))
|
||||||
|
|
||||||
(define (vm-engine-frame? frame)
|
(define (vm-engine-frame? frame)
|
||||||
(let ((sym (frame-function frame)))
|
(let ((sym (frame-function frame)))
|
||||||
|
@ -217,7 +224,7 @@ if the information is not available."
|
||||||
(let ((ip (vm-frame-saved-ip frame))
|
(let ((ip (vm-frame-saved-ip frame))
|
||||||
(sp (value-sub (vm-frame-fp frame) 3))
|
(sp (value-sub (vm-frame-fp frame) 3))
|
||||||
(fp (vm-frame-saved-fp frame)))
|
(fp (vm-frame-saved-fp frame)))
|
||||||
(and (not (zero? (value->integer fp)))
|
(and (not (zero? (value->integer ip)))
|
||||||
(vm-frame ip sp fp backend))))
|
(vm-frame ip sp fp backend))))
|
||||||
|
|
||||||
(define (vm-frames)
|
(define (vm-frames)
|
||||||
|
@ -279,7 +286,7 @@ if the information is not available."
|
||||||
(define (default-name)
|
(define (default-name)
|
||||||
"[unknown]")
|
"[unknown]")
|
||||||
(cond
|
(cond
|
||||||
((vm-frame-program-debug-info frame)
|
((false-if-exception (vm-frame-program-debug-info frame))
|
||||||
=> (lambda (pdi)
|
=> (lambda (pdi)
|
||||||
(or (and=> (program-debug-info-name pdi) symbol->string)
|
(or (and=> (program-debug-info-name pdi) symbol->string)
|
||||||
"[anonymous]")))
|
"[anonymous]")))
|
||||||
|
@ -332,6 +339,14 @@ if the information is not available."
|
||||||
(dump-vm-frame frame port))
|
(dump-vm-frame frame port))
|
||||||
(vm-frames)))
|
(vm-frames)))
|
||||||
|
|
||||||
|
(register-command!
|
||||||
|
(make-command "guile-backtrace"
|
||||||
|
#:command-class COMMAND_STACK
|
||||||
|
#:doc "Display a backtrace of Guile's VM stack for the \
|
||||||
|
current thread"
|
||||||
|
#:invoke (lambda (self args from-tty)
|
||||||
|
(display-vm-frames))))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Frame filters.
|
;;; Frame filters.
|
||||||
|
@ -348,6 +363,9 @@ if the information is not available."
|
||||||
#'(begin)))))
|
#'(begin)))))
|
||||||
|
|
||||||
(compile-time-cond
|
(compile-time-cond
|
||||||
|
;; What follows depends on (gdb frame-filters), which unfortunately has
|
||||||
|
;; not yet been merged in GDB:
|
||||||
|
;; <https://sourceware.org/ml/gdb-patches/2015-02/msg00362.html>.
|
||||||
((false-if-exception (resolve-interface '(gdb frame-filters)))
|
((false-if-exception (resolve-interface '(gdb frame-filters)))
|
||||||
(use-modules (gdb frame-filters))
|
(use-modules (gdb frame-filters))
|
||||||
|
|
||||||
|
|
|
@ -1202,16 +1202,13 @@ SCM_DEFINE (scm_primitive_load_path, "primitive-load-path", 0, 0, 1,
|
||||||
*scm_loc_load_extensions, SCM_BOOL_F,
|
*scm_loc_load_extensions, SCM_BOOL_F,
|
||||||
&stat_source);
|
&stat_source);
|
||||||
|
|
||||||
if (scm_is_false (*scm_loc_fresh_auto_compile))
|
compiled_thunk = load_thunk_from_path (filename, full_filename, &stat_source,
|
||||||
compiled_thunk = load_thunk_from_path (filename, full_filename,
|
&found_stale_compiled_file);
|
||||||
&stat_source,
|
|
||||||
&found_stale_compiled_file);
|
|
||||||
else
|
|
||||||
compiled_thunk = SCM_BOOL_F;
|
|
||||||
|
|
||||||
if (scm_is_false (compiled_thunk)
|
if (scm_is_false (compiled_thunk)
|
||||||
&& scm_is_true (full_filename)
|
&& scm_is_true (full_filename)
|
||||||
&& scm_is_true (*scm_loc_compile_fallback_path)
|
&& scm_is_true (*scm_loc_compile_fallback_path)
|
||||||
|
&& scm_is_false (*scm_loc_fresh_auto_compile)
|
||||||
&& scm_is_pair (*scm_loc_load_compiled_extensions)
|
&& scm_is_pair (*scm_loc_load_compiled_extensions)
|
||||||
&& scm_is_string (scm_car (*scm_loc_load_compiled_extensions)))
|
&& scm_is_string (scm_car (*scm_loc_load_compiled_extensions)))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright 2001,2009-2015,2018
|
/* Copyright 2001,2009-2015,2017-2018
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of Guile.
|
This file is part of Guile.
|
||||||
|
@ -348,7 +348,7 @@ process_dynamic_segment (char *base, Elf_Phdr *dyn_phdr,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ABORT(msg) do { err_msg = msg; goto cleanup; } while (0)
|
#define ABORT(msg) do { err_msg = msg; errno = 0; goto cleanup; } while (0)
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
load_thunk_from_memory (char *data, size_t len, int is_read_only)
|
load_thunk_from_memory (char *data, size_t len, int is_read_only)
|
||||||
|
@ -371,7 +371,10 @@ load_thunk_from_memory (char *data, size_t len, int is_read_only)
|
||||||
header = (Elf_Ehdr*) data;
|
header = (Elf_Ehdr*) data;
|
||||||
|
|
||||||
if ((err_msg = check_elf_header (header)))
|
if ((err_msg = check_elf_header (header)))
|
||||||
goto cleanup;
|
{
|
||||||
|
errno = 0; /* not an OS error */
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (header->e_phnum == 0)
|
if (header->e_phnum == 0)
|
||||||
ABORT ("no loadable segments");
|
ABORT ("no loadable segments");
|
||||||
|
@ -466,7 +469,10 @@ load_thunk_from_memory (char *data, size_t len, int is_read_only)
|
||||||
|
|
||||||
if ((err_msg = process_dynamic_segment (data, &ph[dynamic_segment],
|
if ((err_msg = process_dynamic_segment (data, &ph[dynamic_segment],
|
||||||
&init, &entry, &frame_maps)))
|
&init, &entry, &frame_maps)))
|
||||||
goto cleanup;
|
{
|
||||||
|
errno = 0; /* not an OS error */
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (scm_is_true (init))
|
if (scm_is_true (init))
|
||||||
scm_call_0 (init);
|
scm_call_0 (init);
|
||||||
|
|
|
@ -275,6 +275,13 @@ default_duplicate_binding_handlers (void)
|
||||||
return (scm_call_0 (get_handlers));
|
return (scm_call_0 (get_handlers));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Each module has an "import obarray" that may be accessed concurrently
|
||||||
|
by several threads. This mutex protects access to any obarray. This
|
||||||
|
is coarse-grain but (1) pthread mutexes are quite cheap, and (2)
|
||||||
|
Scheme "programs" have a cache for free variables anyway. */
|
||||||
|
static scm_i_pthread_mutex_t import_obarray_mutex =
|
||||||
|
SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
/* Resolve the import of SYM in MODULE, where SYM is currently provided by
|
/* Resolve the import of SYM in MODULE, where SYM is currently provided by
|
||||||
both IFACE1 as VAR1 and IFACE2 as VAR2. Return the variable chosen by the
|
both IFACE1 as VAR1 and IFACE2 as VAR2. Return the variable chosen by the
|
||||||
duplicate binding handlers or `#f'. */
|
duplicate binding handlers or `#f'. */
|
||||||
|
@ -300,7 +307,11 @@ resolve_duplicate_binding (SCM module, SCM sym,
|
||||||
args[5] = SCM_VARIABLE_REF (var2);
|
args[5] = SCM_VARIABLE_REF (var2);
|
||||||
if (SCM_UNBNDP (args[5]))
|
if (SCM_UNBNDP (args[5]))
|
||||||
args[5] = SCM_BOOL_F;
|
args[5] = SCM_BOOL_F;
|
||||||
|
|
||||||
|
scm_i_pthread_mutex_lock (&import_obarray_mutex);
|
||||||
args[6] = scm_hashq_ref (SCM_MODULE_IMPORT_OBARRAY (module), sym, SCM_BOOL_F);
|
args[6] = scm_hashq_ref (SCM_MODULE_IMPORT_OBARRAY (module), sym, SCM_BOOL_F);
|
||||||
|
scm_i_pthread_mutex_unlock (&import_obarray_mutex);
|
||||||
|
|
||||||
args[7] = SCM_BOOL_F;
|
args[7] = SCM_BOOL_F;
|
||||||
|
|
||||||
handlers = SCM_MODULE_DUPLICATE_HANDLERS (module);
|
handlers = SCM_MODULE_DUPLICATE_HANDLERS (module);
|
||||||
|
@ -338,7 +349,11 @@ module_imported_variable (SCM module, SCM sym)
|
||||||
|
|
||||||
/* Search cached imported bindings. */
|
/* Search cached imported bindings. */
|
||||||
imports = SCM_MODULE_IMPORT_OBARRAY (module);
|
imports = SCM_MODULE_IMPORT_OBARRAY (module);
|
||||||
|
|
||||||
|
scm_i_pthread_mutex_lock (&import_obarray_mutex);
|
||||||
var = scm_hashq_ref (imports, sym, SCM_UNDEFINED);
|
var = scm_hashq_ref (imports, sym, SCM_UNDEFINED);
|
||||||
|
scm_i_pthread_mutex_unlock (&import_obarray_mutex);
|
||||||
|
|
||||||
if (SCM_BOUND_THING_P (var))
|
if (SCM_BOUND_THING_P (var))
|
||||||
return var;
|
return var;
|
||||||
|
|
||||||
|
@ -386,7 +401,9 @@ module_imported_variable (SCM module, SCM sym)
|
||||||
if (SCM_BOUND_THING_P (found_var))
|
if (SCM_BOUND_THING_P (found_var))
|
||||||
{
|
{
|
||||||
/* Save the lookup result for future reference. */
|
/* Save the lookup result for future reference. */
|
||||||
|
scm_i_pthread_mutex_lock (&import_obarray_mutex);
|
||||||
(void) scm_hashq_set_x (imports, sym, found_var);
|
(void) scm_hashq_set_x (imports, sym, found_var);
|
||||||
|
scm_i_pthread_mutex_unlock (&import_obarray_mutex);
|
||||||
return found_var;
|
return found_var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ static SCM flo_log10e;
|
||||||
|
|
||||||
#define SCM_SWAP(x, y) do { SCM __t = x; x = y; y = __t; } while (0)
|
#define SCM_SWAP(x, y) do { SCM __t = x; x = y; y = __t; } while (0)
|
||||||
|
|
||||||
/* FLOBUFLEN is the maximum number of characters neccessary for the
|
/* FLOBUFLEN is the maximum number of characters necessary for the
|
||||||
* printed or scm_string representation of an inexact number.
|
* printed or scm_string representation of an inexact number.
|
||||||
*/
|
*/
|
||||||
#define FLOBUFLEN (40+2*(sizeof(double)/sizeof(char)*SCM_CHAR_BIT*3+9)/10)
|
#define FLOBUFLEN (40+2*(sizeof(double)/sizeof(char)*SCM_CHAR_BIT*3+9)/10)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright 1995-2014,2016,2018
|
/* Copyright 1995-2014,2016-2018
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of Guile.
|
This file is part of Guile.
|
||||||
|
@ -1936,26 +1936,46 @@ SCM_DEFINE (scm_crypt, "crypt", 2, 0, 0,
|
||||||
"crypt(3) library call.")
|
"crypt(3) library call.")
|
||||||
#define FUNC_NAME s_scm_crypt
|
#define FUNC_NAME s_scm_crypt
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
SCM ret;
|
SCM ret;
|
||||||
char *c_key, *c_salt, *c_ret;
|
char *c_key, *c_salt, *c_ret;
|
||||||
|
|
||||||
scm_dynwind_begin (0);
|
scm_dynwind_begin (0);
|
||||||
scm_i_dynwind_pthread_mutex_lock (&scm_i_misc_mutex);
|
|
||||||
|
|
||||||
c_key = scm_to_locale_string (key);
|
c_key = scm_to_locale_string (key);
|
||||||
scm_dynwind_free (c_key);
|
scm_dynwind_free (c_key);
|
||||||
c_salt = scm_to_locale_string (salt);
|
c_salt = scm_to_locale_string (salt);
|
||||||
scm_dynwind_free (c_salt);
|
scm_dynwind_free (c_salt);
|
||||||
|
|
||||||
|
/* Take the lock because 'crypt' uses a static buffer. */
|
||||||
|
scm_i_dynwind_pthread_mutex_lock (&scm_i_misc_mutex);
|
||||||
|
|
||||||
/* The Linux crypt(3) man page says crypt will return NULL and set errno
|
/* The Linux crypt(3) man page says crypt will return NULL and set errno
|
||||||
on error. (Eg. ENOSYS if legal restrictions mean it cannot be
|
on error. (Eg. ENOSYS if legal restrictions mean it cannot be
|
||||||
implemented). */
|
implemented). */
|
||||||
c_ret = crypt (c_key, c_salt);
|
c_ret = crypt (c_key, c_salt);
|
||||||
if (c_ret == NULL)
|
|
||||||
SCM_SYSERROR;
|
|
||||||
|
|
||||||
ret = scm_from_locale_string (c_ret);
|
if (c_ret == NULL)
|
||||||
|
{
|
||||||
|
/* Note: Do not throw until we've released 'scm_i_misc_mutex'
|
||||||
|
since this would cause a deadlock down the path. */
|
||||||
|
err = errno;
|
||||||
|
ret = SCM_BOOL_F;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = 0;
|
||||||
|
ret = scm_from_locale_string (c_ret);
|
||||||
|
}
|
||||||
|
|
||||||
scm_dynwind_end ();
|
scm_dynwind_end ();
|
||||||
|
|
||||||
|
if (scm_is_false (ret))
|
||||||
|
{
|
||||||
|
errno = err;
|
||||||
|
SCM_SYSERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
|
@ -225,7 +225,7 @@ custom_binary_port_seek (SCM port, scm_t_off offset, int whence)
|
||||||
scm_wrong_type_arg_msg (FUNC_NAME, 0, port,
|
scm_wrong_type_arg_msg (FUNC_NAME, 0, port,
|
||||||
"R6RS custom binary port with "
|
"R6RS custom binary port with "
|
||||||
"`port-position' support");
|
"`port-position' support");
|
||||||
c_result = scm_to_int (result);
|
c_result = scm_to_off_t (result);
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
/* We just want to know the current position. */
|
/* We just want to know the current position. */
|
||||||
break;
|
break;
|
||||||
|
@ -414,11 +414,11 @@ SCM_DEFINE (scm_get_bytevector_n, "get-bytevector-n", 2, 0, 0,
|
||||||
#define FUNC_NAME s_scm_get_bytevector_n
|
#define FUNC_NAME s_scm_get_bytevector_n
|
||||||
{
|
{
|
||||||
SCM result;
|
SCM result;
|
||||||
unsigned c_count;
|
size_t c_count;
|
||||||
size_t c_read;
|
size_t c_read;
|
||||||
|
|
||||||
SCM_VALIDATE_BINARY_INPUT_PORT (1, port);
|
SCM_VALIDATE_BINARY_INPUT_PORT (1, port);
|
||||||
c_count = scm_to_uint (count);
|
c_count = scm_to_size_t (count);
|
||||||
|
|
||||||
result = scm_c_make_bytevector (c_count);
|
result = scm_c_make_bytevector (c_count);
|
||||||
|
|
||||||
|
@ -450,13 +450,13 @@ SCM_DEFINE (scm_get_bytevector_n_x, "get-bytevector-n!", 4, 0, 0,
|
||||||
#define FUNC_NAME s_scm_get_bytevector_n_x
|
#define FUNC_NAME s_scm_get_bytevector_n_x
|
||||||
{
|
{
|
||||||
SCM result;
|
SCM result;
|
||||||
unsigned c_start, c_count, c_len;
|
size_t c_start, c_count, c_len;
|
||||||
size_t c_read;
|
size_t c_read;
|
||||||
|
|
||||||
SCM_VALIDATE_BINARY_INPUT_PORT (1, port);
|
SCM_VALIDATE_BINARY_INPUT_PORT (1, port);
|
||||||
SCM_VALIDATE_BYTEVECTOR (2, bv);
|
SCM_VALIDATE_BYTEVECTOR (2, bv);
|
||||||
c_start = scm_to_uint (start);
|
c_start = scm_to_size_t (start);
|
||||||
c_count = scm_to_uint (count);
|
c_count = scm_to_size_t (count);
|
||||||
|
|
||||||
c_len = SCM_BYTEVECTOR_LENGTH (bv);
|
c_len = SCM_BYTEVECTOR_LENGTH (bv);
|
||||||
|
|
||||||
|
@ -589,7 +589,7 @@ SCM_DEFINE (scm_put_bytevector, "put-bytevector", 2, 2, 0,
|
||||||
"octets.")
|
"octets.")
|
||||||
#define FUNC_NAME s_scm_put_bytevector
|
#define FUNC_NAME s_scm_put_bytevector
|
||||||
{
|
{
|
||||||
unsigned c_start, c_count, c_len;
|
size_t c_start, c_count, c_len;
|
||||||
|
|
||||||
SCM_VALIDATE_BINARY_OUTPUT_PORT (1, port);
|
SCM_VALIDATE_BINARY_OUTPUT_PORT (1, port);
|
||||||
SCM_VALIDATE_BYTEVECTOR (2, bv);
|
SCM_VALIDATE_BYTEVECTOR (2, bv);
|
||||||
|
@ -598,11 +598,11 @@ SCM_DEFINE (scm_put_bytevector, "put-bytevector", 2, 2, 0,
|
||||||
|
|
||||||
if (!scm_is_eq (start, SCM_UNDEFINED))
|
if (!scm_is_eq (start, SCM_UNDEFINED))
|
||||||
{
|
{
|
||||||
c_start = scm_to_uint (start);
|
c_start = scm_to_size_t (start);
|
||||||
|
|
||||||
if (!scm_is_eq (count, SCM_UNDEFINED))
|
if (!scm_is_eq (count, SCM_UNDEFINED))
|
||||||
{
|
{
|
||||||
c_count = scm_to_uint (count);
|
c_count = scm_to_size_t (count);
|
||||||
if (SCM_UNLIKELY (c_start + c_count > c_len))
|
if (SCM_UNLIKELY (c_start + c_count > c_len))
|
||||||
scm_out_of_range (FUNC_NAME, count);
|
scm_out_of_range (FUNC_NAME, count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2177,6 +2177,12 @@ scm_to_stringn (SCM str, size_t *lenp, const char *encoding,
|
||||||
|
|
||||||
if (!scm_is_string (str))
|
if (!scm_is_string (str))
|
||||||
scm_wrong_type_arg_msg (NULL, 0, str, "string");
|
scm_wrong_type_arg_msg (NULL, 0, str, "string");
|
||||||
|
|
||||||
|
if (c_strcasecmp (encoding, "UTF-8") == 0)
|
||||||
|
/* This is the most common case--e.g., when calling libc bindings
|
||||||
|
while using a UTF-8 locale. */
|
||||||
|
return scm_to_utf8_stringn (str, lenp);
|
||||||
|
|
||||||
ilen = scm_i_string_length (str);
|
ilen = scm_i_string_length (str);
|
||||||
|
|
||||||
if (ilen == 0)
|
if (ilen == 0)
|
||||||
|
|
|
@ -322,6 +322,7 @@ VM_NAME (scm_thread *thread)
|
||||||
/* Empty frame, then values. */
|
/* Empty frame, then values. */
|
||||||
size_t first_value = frame_size;
|
size_t first_value = frame_size;
|
||||||
uint32_t nvals = FRAME_LOCALS_COUNT_FROM (first_value);
|
uint32_t nvals = FRAME_LOCALS_COUNT_FROM (first_value);
|
||||||
|
union scm_vm_stack_element *fp;
|
||||||
SCM ret;
|
SCM ret;
|
||||||
|
|
||||||
if (nvals == 1)
|
if (nvals == 1)
|
||||||
|
@ -336,9 +337,10 @@ VM_NAME (scm_thread *thread)
|
||||||
SCM_SET_CELL_OBJECT (ret, n+1, FP_REF (first_value + n));
|
SCM_SET_CELL_OBJECT (ret, n+1, FP_REF (first_value + n));
|
||||||
}
|
}
|
||||||
|
|
||||||
VP->ip = SCM_FRAME_VIRTUAL_RETURN_ADDRESS (VP->fp);
|
fp = VP->fp;
|
||||||
VP->sp = SCM_FRAME_PREVIOUS_SP (VP->fp);
|
VP->fp = SCM_FRAME_DYNAMIC_LINK (fp);
|
||||||
VP->fp = SCM_FRAME_DYNAMIC_LINK (VP->fp);
|
VP->ip = SCM_FRAME_VIRTUAL_RETURN_ADDRESS (fp);
|
||||||
|
VP->sp = SCM_FRAME_PREVIOUS_SP (fp);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -359,16 +361,17 @@ VM_NAME (scm_thread *thread)
|
||||||
VM_DEFINE_OP (1, call, "call", OP2 (X8_F24, X8_C24))
|
VM_DEFINE_OP (1, call, "call", OP2 (X8_F24, X8_C24))
|
||||||
{
|
{
|
||||||
uint32_t proc, nlocals;
|
uint32_t proc, nlocals;
|
||||||
union scm_vm_stack_element *old_fp;
|
union scm_vm_stack_element *old_fp, *new_fp;
|
||||||
|
|
||||||
UNPACK_24 (op, proc);
|
UNPACK_24 (op, proc);
|
||||||
UNPACK_24 (ip[1], nlocals);
|
UNPACK_24 (ip[1], nlocals);
|
||||||
|
|
||||||
old_fp = VP->fp;
|
old_fp = VP->fp;
|
||||||
VP->fp = SCM_FRAME_SLOT (old_fp, proc - 1);
|
new_fp = SCM_FRAME_SLOT (old_fp, proc - 1);
|
||||||
SCM_FRAME_SET_DYNAMIC_LINK (VP->fp, old_fp);
|
SCM_FRAME_SET_DYNAMIC_LINK (new_fp, old_fp);
|
||||||
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (VP->fp, ip + 2);
|
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (new_fp, ip + 2);
|
||||||
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (VP->fp, 0);
|
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (new_fp, 0);
|
||||||
|
VP->fp = new_fp;
|
||||||
|
|
||||||
RESET_FRAME (nlocals);
|
RESET_FRAME (nlocals);
|
||||||
|
|
||||||
|
@ -398,17 +401,18 @@ VM_NAME (scm_thread *thread)
|
||||||
{
|
{
|
||||||
uint32_t proc, nlocals;
|
uint32_t proc, nlocals;
|
||||||
int32_t label;
|
int32_t label;
|
||||||
union scm_vm_stack_element *old_fp;
|
union scm_vm_stack_element *old_fp, *new_fp;
|
||||||
|
|
||||||
UNPACK_24 (op, proc);
|
UNPACK_24 (op, proc);
|
||||||
UNPACK_24 (ip[1], nlocals);
|
UNPACK_24 (ip[1], nlocals);
|
||||||
label = ip[2];
|
label = ip[2];
|
||||||
|
|
||||||
old_fp = VP->fp;
|
old_fp = VP->fp;
|
||||||
VP->fp = SCM_FRAME_SLOT (old_fp, proc - 1);
|
new_fp = SCM_FRAME_SLOT (old_fp, proc - 1);
|
||||||
SCM_FRAME_SET_DYNAMIC_LINK (VP->fp, old_fp);
|
SCM_FRAME_SET_DYNAMIC_LINK (new_fp, old_fp);
|
||||||
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (VP->fp, ip + 3);
|
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (new_fp, ip + 3);
|
||||||
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (VP->fp, 0);
|
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (new_fp, 0);
|
||||||
|
VP->fp = new_fp;
|
||||||
|
|
||||||
RESET_FRAME (nlocals);
|
RESET_FRAME (nlocals);
|
||||||
|
|
||||||
|
@ -2383,9 +2387,11 @@ VM_NAME (scm_thread *thread)
|
||||||
*/
|
*/
|
||||||
VM_DEFINE_OP (184, return_from_interrupt, "return-from-interrupt", OP1 (X32))
|
VM_DEFINE_OP (184, return_from_interrupt, "return-from-interrupt", OP1 (X32))
|
||||||
{
|
{
|
||||||
VP->sp = sp = SCM_FRAME_PREVIOUS_SP (VP->fp);
|
union scm_vm_stack_element *fp = VP->fp;
|
||||||
ip = SCM_FRAME_VIRTUAL_RETURN_ADDRESS (VP->fp);
|
|
||||||
VP->fp = SCM_FRAME_DYNAMIC_LINK (VP->fp);
|
ip = SCM_FRAME_VIRTUAL_RETURN_ADDRESS (fp);
|
||||||
|
VP->fp = SCM_FRAME_DYNAMIC_LINK (fp);
|
||||||
|
VP->sp = sp = SCM_FRAME_PREVIOUS_SP (fp);
|
||||||
|
|
||||||
NEXT (0);
|
NEXT (0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -582,7 +582,7 @@ return_unused_stack_to_os (struct scm_vm *vp)
|
||||||
|
|
||||||
do
|
do
|
||||||
ret = madvise ((void *) lo, hi - lo, MADV_DONTNEED);
|
ret = madvise ((void *) lo, hi - lo, MADV_DONTNEED);
|
||||||
while (ret && errno == -EAGAIN);
|
while (ret && errno == EAGAIN);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
perror ("madvise failed");
|
perror ("madvise failed");
|
||||||
|
@ -991,7 +991,7 @@ cons_rest (scm_thread *thread, uint32_t base)
|
||||||
static void
|
static void
|
||||||
push_interrupt_frame (scm_thread *thread, uint8_t *mra)
|
push_interrupt_frame (scm_thread *thread, uint8_t *mra)
|
||||||
{
|
{
|
||||||
union scm_vm_stack_element *old_fp;
|
union scm_vm_stack_element *old_fp, *new_fp;
|
||||||
size_t frame_overhead = 3;
|
size_t frame_overhead = 3;
|
||||||
size_t old_frame_size = frame_locals_count (thread);
|
size_t old_frame_size = frame_locals_count (thread);
|
||||||
SCM proc = scm_i_async_pop (thread);
|
SCM proc = scm_i_async_pop (thread);
|
||||||
|
@ -1000,14 +1000,15 @@ push_interrupt_frame (scm_thread *thread, uint8_t *mra)
|
||||||
alloc_frame (thread, old_frame_size + frame_overhead + 1);
|
alloc_frame (thread, old_frame_size + frame_overhead + 1);
|
||||||
|
|
||||||
old_fp = thread->vm.fp;
|
old_fp = thread->vm.fp;
|
||||||
thread->vm.fp = SCM_FRAME_SLOT (old_fp, old_frame_size + frame_overhead - 1);
|
new_fp = SCM_FRAME_SLOT (old_fp, old_frame_size + frame_overhead - 1);
|
||||||
SCM_FRAME_SET_DYNAMIC_LINK (thread->vm.fp, old_fp);
|
SCM_FRAME_SET_DYNAMIC_LINK (new_fp, old_fp);
|
||||||
/* Arrange to return to the same handle-interrupts opcode to handle
|
/* Arrange to return to the same handle-interrupts opcode to handle
|
||||||
any additional interrupts. */
|
any additional interrupts. */
|
||||||
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (thread->vm.fp, thread->vm.ip);
|
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (new_fp, thread->vm.ip);
|
||||||
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (thread->vm.fp, mra);
|
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (new_fp, mra);
|
||||||
|
SCM_FRAME_LOCAL (new_fp, 0) = proc;
|
||||||
|
|
||||||
SCM_FRAME_LOCAL (thread->vm.fp, 0) = proc;
|
thread->vm.fp = new_fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct return_to_continuation_data
|
struct return_to_continuation_data
|
||||||
|
@ -1375,7 +1376,6 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs)
|
||||||
SCM_FRAME_SET_DYNAMIC_LINK (return_fp, vp->fp);
|
SCM_FRAME_SET_DYNAMIC_LINK (return_fp, vp->fp);
|
||||||
|
|
||||||
vp->ip = (uint32_t *) vm_boot_continuation_code;
|
vp->ip = (uint32_t *) vm_boot_continuation_code;
|
||||||
vp->fp = call_fp;
|
|
||||||
|
|
||||||
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (call_fp, vp->ip);
|
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (call_fp, vp->ip);
|
||||||
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (call_fp, 0);
|
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (call_fp, 0);
|
||||||
|
@ -1384,6 +1384,8 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs)
|
||||||
for (i = 0; i < nargs; i++)
|
for (i = 0; i < nargs; i++)
|
||||||
SCM_FRAME_LOCAL (call_fp, i + 1) = argv[i];
|
SCM_FRAME_LOCAL (call_fp, i + 1) = argv[i];
|
||||||
|
|
||||||
|
vp->fp = call_fp;
|
||||||
|
|
||||||
{
|
{
|
||||||
jmp_buf registers;
|
jmp_buf registers;
|
||||||
int resume;
|
int resume;
|
||||||
|
|
|
@ -289,6 +289,7 @@ SOURCES = \
|
||||||
srfi/srfi-64.scm \
|
srfi/srfi-64.scm \
|
||||||
srfi/srfi-67.scm \
|
srfi/srfi-67.scm \
|
||||||
srfi/srfi-69.scm \
|
srfi/srfi-69.scm \
|
||||||
|
srfi/srfi-71.scm \
|
||||||
srfi/srfi-88.scm \
|
srfi/srfi-88.scm \
|
||||||
srfi/srfi-98.scm \
|
srfi/srfi-98.scm \
|
||||||
srfi/srfi-111.scm \
|
srfi/srfi-111.scm \
|
||||||
|
|
|
@ -2591,6 +2591,14 @@ interfaces are added to the inports list."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(define (call-with-module-autoload-lock thunk)
|
||||||
|
;; This binding is overridden when (ice-9 threads) is available to
|
||||||
|
;; implement a critical section around the call to THUNK. It must be
|
||||||
|
;; used anytime 'autoloads-done' and related variables are accessed
|
||||||
|
;; and whenever submodules are accessed (via the 'nested-'
|
||||||
|
;; procedures.)
|
||||||
|
(thunk))
|
||||||
|
|
||||||
;; Now that modules are booted, give module-name its final definition.
|
;; Now that modules are booted, give module-name its final definition.
|
||||||
;;
|
;;
|
||||||
(define module-name
|
(define module-name
|
||||||
|
@ -2602,7 +2610,9 @@ interfaces are added to the inports list."
|
||||||
;; `resolve-module'. This is important as `psyntax' stores module
|
;; `resolve-module'. This is important as `psyntax' stores module
|
||||||
;; names and relies on being able to `resolve-module' them.
|
;; names and relies on being able to `resolve-module' them.
|
||||||
(set-module-name! mod name)
|
(set-module-name! mod name)
|
||||||
(nested-define-module! (resolve-module '() #f) name mod)
|
(call-with-module-autoload-lock
|
||||||
|
(lambda ()
|
||||||
|
(nested-define-module! (resolve-module '() #f) name mod)))
|
||||||
(accessor mod))))))
|
(accessor mod))))))
|
||||||
|
|
||||||
(define* (module-gensym #:optional (id " mg") (m (current-module)))
|
(define* (module-gensym #:optional (id " mg") (m (current-module)))
|
||||||
|
@ -2684,25 +2694,27 @@ deterministic."
|
||||||
(module-define-submodule! root 'guile the-root-module)
|
(module-define-submodule! root 'guile the-root-module)
|
||||||
|
|
||||||
(lambda* (name #:optional (autoload #t) (version #f) #:key (ensure #t))
|
(lambda* (name #:optional (autoload #t) (version #f) #:key (ensure #t))
|
||||||
(let ((already (nested-ref-module root name)))
|
(call-with-module-autoload-lock
|
||||||
(cond
|
(lambda ()
|
||||||
((and already
|
(let ((already (nested-ref-module root name)))
|
||||||
(or (not autoload) (module-public-interface already)))
|
(cond
|
||||||
;; A hit, a palpable hit.
|
((and already
|
||||||
(if (and version
|
(or (not autoload) (module-public-interface already)))
|
||||||
(not (version-matches? version (module-version already))))
|
;; A hit, a palpable hit.
|
||||||
(error "incompatible module version already loaded" name))
|
(if (and version
|
||||||
already)
|
(not (version-matches? version (module-version already))))
|
||||||
(autoload
|
(error "incompatible module version already loaded" name))
|
||||||
;; Try to autoload the module, and recurse.
|
already)
|
||||||
(try-load-module name version)
|
(autoload
|
||||||
(resolve-module name #f #:ensure ensure))
|
;; Try to autoload the module, and recurse.
|
||||||
(else
|
(try-load-module name version)
|
||||||
;; No module found (or if one was, it had no public interface), and
|
(resolve-module name #f #:ensure ensure))
|
||||||
;; we're not autoloading. Make an empty module if #:ensure is true.
|
(else
|
||||||
(or already
|
;; No module found (or if one was, it had no public interface), and
|
||||||
(and ensure
|
;; we're not autoloading. Make an empty module if #:ensure is true.
|
||||||
(make-modules-in root name)))))))))
|
(or already
|
||||||
|
(and ensure
|
||||||
|
(make-modules-in root name)))))))))))
|
||||||
|
|
||||||
|
|
||||||
(define (try-load-module name version)
|
(define (try-load-module name version)
|
||||||
|
@ -2936,9 +2948,6 @@ module '(ice-9 q) '(make-q q-length))}."
|
||||||
;;; {Autoloading modules}
|
;;; {Autoloading modules}
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
;;; XXX FIXME autoloads-in-progress and autoloads-done
|
|
||||||
;;; are not handled in a thread-safe way.
|
|
||||||
|
|
||||||
(define autoloads-in-progress '())
|
(define autoloads-in-progress '())
|
||||||
|
|
||||||
;; This function is called from scm_load_scheme_module in
|
;; This function is called from scm_load_scheme_module in
|
||||||
|
@ -2957,37 +2966,40 @@ but it fails to load."
|
||||||
file-name-separator-string))
|
file-name-separator-string))
|
||||||
dir-hint-module-name))))
|
dir-hint-module-name))))
|
||||||
(resolve-module dir-hint-module-name #f)
|
(resolve-module dir-hint-module-name #f)
|
||||||
(and (not (autoload-done-or-in-progress? dir-hint name))
|
|
||||||
(let ((didit #f))
|
(call-with-module-autoload-lock
|
||||||
(dynamic-wind
|
(lambda ()
|
||||||
(lambda () (autoload-in-progress! dir-hint name))
|
(and (not (autoload-done-or-in-progress? dir-hint name))
|
||||||
(lambda ()
|
(let ((didit #f))
|
||||||
(with-fluids ((current-reader #f))
|
(dynamic-wind
|
||||||
(save-module-excursion
|
(lambda () (autoload-in-progress! dir-hint name))
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(define (call/ec proc)
|
(with-fluids ((current-reader #f))
|
||||||
(let ((tag (make-prompt-tag)))
|
(save-module-excursion
|
||||||
(call-with-prompt
|
(lambda ()
|
||||||
tag
|
(define (call/ec proc)
|
||||||
(lambda ()
|
(let ((tag (make-prompt-tag)))
|
||||||
(proc (lambda () (abort-to-prompt tag))))
|
(call-with-prompt
|
||||||
(lambda (k) (values)))))
|
tag
|
||||||
;; The initial environment when loading a module is a fresh
|
(lambda ()
|
||||||
;; user module.
|
(proc (lambda () (abort-to-prompt tag))))
|
||||||
(set-current-module (make-fresh-user-module))
|
(lambda (k) (values)))))
|
||||||
;; Here we could allow some other search strategy (other than
|
;; The initial environment when loading a module is a fresh
|
||||||
;; primitive-load-path), for example using versions encoded
|
;; user module.
|
||||||
;; into the file system -- but then we would have to figure
|
(set-current-module (make-fresh-user-module))
|
||||||
;; out how to locate the compiled file, do auto-compilation,
|
;; Here we could allow some other search strategy (other than
|
||||||
;; etc. Punt for now, and don't use versions when locating
|
;; primitive-load-path), for example using versions encoded
|
||||||
;; the file.
|
;; into the file system -- but then we would have to figure
|
||||||
(call/ec
|
;; out how to locate the compiled file, do auto-compilation,
|
||||||
(lambda (abort)
|
;; etc. Punt for now, and don't use versions when locating
|
||||||
(primitive-load-path (in-vicinity dir-hint name)
|
;; the file.
|
||||||
abort)
|
(call/ec
|
||||||
(set! didit #t)))))))
|
(lambda (abort)
|
||||||
(lambda () (set-autoloaded! dir-hint name didit)))
|
(primitive-load-path (in-vicinity dir-hint name)
|
||||||
didit))))
|
abort)
|
||||||
|
(set! didit #t)))))))
|
||||||
|
(lambda () (set-autoloaded! dir-hint name didit)))
|
||||||
|
didit))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3653,7 +3665,8 @@ but it fails to load."
|
||||||
|
|
||||||
(define %auto-compilation-options
|
(define %auto-compilation-options
|
||||||
;; Default `compile-file' option when auto-compiling.
|
;; Default `compile-file' option when auto-compiling.
|
||||||
'(#:warnings (unbound-variable macro-use-before-definition arity-mismatch
|
'(#:warnings (unbound-variable shadowed-toplevel
|
||||||
|
macro-use-before-definition arity-mismatch
|
||||||
format duplicate-case-datum bad-case-datum)))
|
format duplicate-case-datum bad-case-datum)))
|
||||||
|
|
||||||
(define* (load-in-vicinity dir file-name #:optional reader)
|
(define* (load-in-vicinity dir file-name #:optional reader)
|
||||||
|
@ -3795,10 +3808,7 @@ when none is available, reading FILE-NAME with READER."
|
||||||
scmstat
|
scmstat
|
||||||
go-file-name))))))
|
go-file-name))))))
|
||||||
|
|
||||||
(let ((compiled (and scmstat
|
(let ((compiled (and scmstat (or (pre-compiled) (fallback)))))
|
||||||
(or (and (not %fresh-auto-compile)
|
|
||||||
(pre-compiled))
|
|
||||||
(fallback)))))
|
|
||||||
(if compiled
|
(if compiled
|
||||||
(begin
|
(begin
|
||||||
(if %load-hook
|
(if %load-hook
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; Parsing Guile's command-line
|
;;; Parsing Guile's command-line
|
||||||
|
|
||||||
;;; Copyright (C) 1994-1998, 2000-2017 Free Software Foundation, Inc.
|
;;; Copyright (C) 1994-1998, 2000-2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -66,7 +66,7 @@ There is NO WARRANTY, to the extent permitted by law."))
|
||||||
(define* (version-etc package version #:key
|
(define* (version-etc package version #:key
|
||||||
(port (current-output-port))
|
(port (current-output-port))
|
||||||
;; FIXME: authors
|
;; FIXME: authors
|
||||||
(copyright-year 2017)
|
(copyright-year 2018)
|
||||||
(copyright-holder "Free Software Foundation, Inc.")
|
(copyright-holder "Free Software Foundation, Inc.")
|
||||||
(copyright (format #f "Copyright (C) ~a ~a"
|
(copyright (format #f "Copyright (C) ~a ~a"
|
||||||
copyright-year copyright-holder))
|
copyright-year copyright-holder))
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;;; Copyright (C) 1996, 1998, 2001, 2002, 2003, 2006, 2010, 2011,
|
;;;; Copyright (C) 1996, 1998, 2001, 2002, 2003, 2006, 2010, 2011,
|
||||||
;;;; 2012 Free Software Foundation, Inc.
|
;;;; 2012, 2018 Free Software Foundation, Inc.
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -380,4 +380,13 @@ of applying P-PROC on ARGLISTS."
|
||||||
(loop))))))
|
(loop))))))
|
||||||
threads)))))
|
threads)))))
|
||||||
|
|
||||||
|
|
||||||
|
;; Now that thread support is loaded, make module autoloading
|
||||||
|
;; thread-safe.
|
||||||
|
(set! (@ (guile) call-with-module-autoload-lock)
|
||||||
|
(let ((mutex (make-mutex 'recursive)))
|
||||||
|
(lambda (thunk)
|
||||||
|
(with-mutex mutex
|
||||||
|
(thunk)))))
|
||||||
|
|
||||||
;;; threads.scm ends here
|
;;; threads.scm ends here
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;; Type analysis on CPS
|
;;; Type analysis on CPS
|
||||||
;;; Copyright (C) 2014, 2015, 2017, 2018 Free Software Foundation, Inc.
|
;;; Copyright (C) 2014-2015,2017-2018 Free Software Foundation, Inc.
|
||||||
;;;
|
;;;
|
||||||
;;; This library is free software: you can redistribute it and/or modify
|
;;; This library is free software: you can redistribute it and/or modify
|
||||||
;;; it under the terms of the GNU Lesser General Public License as
|
;;; it under the terms of the GNU Lesser General Public License as
|
||||||
|
@ -1432,56 +1432,96 @@ minimum, and maximum."
|
||||||
(define! result &s64 min max)
|
(define! result &s64 min max)
|
||||||
(define! result &s64 &s64-min &s64-max))))
|
(define! result &s64 &s64-min &s64-max))))
|
||||||
|
|
||||||
(define (next-power-of-two n)
|
(define-inlinable (non-negative? n)
|
||||||
(let lp ((out 1))
|
"Return true if N is non-negative, otherwise return false."
|
||||||
(if (< n out)
|
(not (negative? n)))
|
||||||
out
|
|
||||||
(lp (ash out 1)))))
|
;; Like 'lognot', but handles infinities.
|
||||||
|
(define-inlinable (lognot* n)
|
||||||
|
"Return the bitwise complement of N. If N is infinite, return -N."
|
||||||
|
(- -1 n))
|
||||||
|
|
||||||
|
(define saturate+
|
||||||
|
(case-lambda
|
||||||
|
"Let N be the least upper bound of the integer lengths of the
|
||||||
|
arguments. Return the greatest integer whose integer length is N.
|
||||||
|
If any of the arguments are infinite, return positive infinity."
|
||||||
|
((a b)
|
||||||
|
(if (or (inf? a) (inf? b))
|
||||||
|
+inf.0
|
||||||
|
(1- (ash 1 (max (integer-length a)
|
||||||
|
(integer-length b))))))
|
||||||
|
((a b c)
|
||||||
|
(saturate+ (saturate+ a b) c))
|
||||||
|
((a b c d)
|
||||||
|
(saturate+ (saturate+ a b) c d))))
|
||||||
|
|
||||||
|
(define saturate-
|
||||||
|
(case-lambda
|
||||||
|
"Let N be the least upper bound of the integer lengths of the
|
||||||
|
arguments. Return the least integer whose integer length is N.
|
||||||
|
If any of the arguments are infinite, return negative infinity."
|
||||||
|
((a b) (lognot* (saturate+ a b)))
|
||||||
|
((a b c) (lognot* (saturate+ a b c)))
|
||||||
|
((a b c d) (lognot* (saturate+ a b c d)))))
|
||||||
|
|
||||||
|
(define (logand-bounds a0 a1 b0 b1)
|
||||||
|
"Return two values: lower and upper bounds for (logand A B)
|
||||||
|
where (A0 <= A <= A1) and (B0 <= B <= B1)."
|
||||||
|
;; For each argument, we consider three cases: (1) the argument is
|
||||||
|
;; non-negative, (2) its sign is unknown, or (3) it is negative.
|
||||||
|
;; To handle both arguments, we must consider a total of 9 cases:
|
||||||
|
;;
|
||||||
|
;; -----------------------------------------------------------------------
|
||||||
|
;; LOGAND | non-negative B | unknown-sign B | negative B
|
||||||
|
;; -----------------------------------------------------------------------
|
||||||
|
;; non-negative A | 0 .. (min A1 B1) | 0 .. A1 | 0 .. A1
|
||||||
|
;; -----------------------------------------------------------------------
|
||||||
|
;; unknown-sign A | 0 .. B1 | (sat- A0 B0) | (sat- A0 B0)
|
||||||
|
;; | | .. | .. A1
|
||||||
|
;; | | (sat+ A1 B1) |
|
||||||
|
;; -----------------------------------------------------------------------
|
||||||
|
;; negative A | 0 .. B1 | (sat- A0 B0) | (sat- A0 B0)
|
||||||
|
;; | | .. B1 | .. (min A1 B1)
|
||||||
|
;; -----------------------------------------------------------------------
|
||||||
|
(values (if (or (non-negative? a0) (non-negative? b0))
|
||||||
|
0
|
||||||
|
(saturate- a0 b0))
|
||||||
|
(cond ((or (and (non-negative? a0) (non-negative? b0))
|
||||||
|
(and (negative? a1) (negative? b1)))
|
||||||
|
(min a1 b1))
|
||||||
|
((or (non-negative? a0) (negative? b1))
|
||||||
|
a1)
|
||||||
|
((or (non-negative? b0) (negative? a1))
|
||||||
|
b1)
|
||||||
|
(else
|
||||||
|
(saturate+ a1 b1)))))
|
||||||
|
|
||||||
(define-simple-type-checker (logand &exact-integer &exact-integer))
|
(define-simple-type-checker (logand &exact-integer &exact-integer))
|
||||||
(define-type-inferrer (logand a b result)
|
(define-type-inferrer (logand a b result)
|
||||||
(define (logand-min a b)
|
|
||||||
(if (and (negative? a) (negative? b))
|
|
||||||
(let ((min (min a b)))
|
|
||||||
(if (inf? min)
|
|
||||||
-inf.0
|
|
||||||
(- 1 (next-power-of-two (- min)))))
|
|
||||||
0))
|
|
||||||
(define (logand-max a b)
|
|
||||||
(cond
|
|
||||||
((or (and (positive? a) (positive? b))
|
|
||||||
(and (negative? a) (negative? b)))
|
|
||||||
(min a b))
|
|
||||||
(else (max a b))))
|
|
||||||
(restrict! a &exact-integer -inf.0 +inf.0)
|
(restrict! a &exact-integer -inf.0 +inf.0)
|
||||||
(restrict! b &exact-integer -inf.0 +inf.0)
|
(restrict! b &exact-integer -inf.0 +inf.0)
|
||||||
(define-exact-integer! result
|
(call-with-values (lambda ()
|
||||||
(logand-min (&min a) (&min b))
|
(logand-bounds (&min a) (&max a) (&min b) (&max b)))
|
||||||
(logand-max (&max a) (&max b))))
|
(lambda (min max)
|
||||||
|
(define-exact-integer! result min max))))
|
||||||
|
|
||||||
(define-type-inferrer (ulogand a b result)
|
(define-type-inferrer (ulogand a b result)
|
||||||
(restrict! a &u64 0 &u64-max)
|
(restrict! a &u64 0 &u64-max)
|
||||||
(restrict! b &u64 0 &u64-max)
|
(restrict! b &u64 0 &u64-max)
|
||||||
(define! result &u64 0 (min (&max/u64 a) (&max/u64 b))))
|
(define! result &u64 0 (min (&max/u64 a) (&max/u64 b))))
|
||||||
|
|
||||||
|
(define (logsub-bounds a0 a1 b0 b1)
|
||||||
|
"Return two values: lower and upper bounds for (logsub A B),
|
||||||
|
i.e. (logand A (lognot B)), where (A0 <= A <= A1) and (B0 <= B <= B1)."
|
||||||
|
;; Here we use 'logand-bounds' to compute the bounds, after
|
||||||
|
;; computing the bounds of (lognot B) from the bounds of B.
|
||||||
|
;; From (B0 <= B <= B1) it follows that (~B1 <= ~B <= ~B0),
|
||||||
|
;; where ~X means (lognot X).
|
||||||
|
(logand-bounds a0 a1 (lognot* b1) (lognot* b0)))
|
||||||
|
|
||||||
(define-simple-type-checker (logsub &exact-integer &exact-integer))
|
(define-simple-type-checker (logsub &exact-integer &exact-integer))
|
||||||
(define-type-inferrer (logsub a b result)
|
(define-type-inferrer (logsub a b result)
|
||||||
(define (logsub-bounds min-a max-a min-b max-b)
|
|
||||||
(cond
|
|
||||||
((negative? max-b)
|
|
||||||
;; Sign bit always set on B, so result will never be negative.
|
|
||||||
;; If A might be negative (all leftmost bits 1), we don't know
|
|
||||||
;; how positive the result might be.
|
|
||||||
(values 0 (if (negative? min-a) +inf.0 max-a)))
|
|
||||||
((negative? min-b)
|
|
||||||
;; Sign bit might be set on B.
|
|
||||||
(values min-a (if (negative? min-a) +inf.0 max-a)))
|
|
||||||
((negative? min-a)
|
|
||||||
;; Sign bit never set on B -- result will have the sign of A.
|
|
||||||
(values -inf.0 max-a))
|
|
||||||
(else
|
|
||||||
;; Sign bit never set on A and never set on B -- the nice case.
|
|
||||||
(values 0 max-a))))
|
|
||||||
(restrict! a &exact-integer -inf.0 +inf.0)
|
(restrict! a &exact-integer -inf.0 +inf.0)
|
||||||
(restrict! b &exact-integer -inf.0 +inf.0)
|
(restrict! b &exact-integer -inf.0 +inf.0)
|
||||||
(call-with-values (lambda ()
|
(call-with-values (lambda ()
|
||||||
|
@ -1494,48 +1534,116 @@ minimum, and maximum."
|
||||||
(restrict! b &u64 0 &u64-max)
|
(restrict! b &u64 0 &u64-max)
|
||||||
(define! result &u64 0 (&max/u64 a)))
|
(define! result &u64 0 (&max/u64 a)))
|
||||||
|
|
||||||
|
(define (logior-bounds a0 a1 b0 b1)
|
||||||
|
"Return two values: lower and upper bounds for (logior A B)
|
||||||
|
where (A0 <= A <= A1) and (B0 <= B <= B1)."
|
||||||
|
;; For each argument, we consider three cases: (1) the argument is
|
||||||
|
;; non-negative, (2) its sign is unknown, or (3) it is negative.
|
||||||
|
;; To handle both arguments, we must consider a total of 9 cases.
|
||||||
|
;;
|
||||||
|
;; ---------------------------------------------------------------------
|
||||||
|
;; LOGIOR | non-negative B | unknown-sign B | negative B
|
||||||
|
;; ---------------------------------------------------------------------
|
||||||
|
;; non-negative A | (max A0 B0) | B0 | B0 .. -1
|
||||||
|
;; | .. | .. |
|
||||||
|
;; | (sat+ A1 B1) | (sat+ A1 B1) |
|
||||||
|
;; ---------------------------------------------------------------------
|
||||||
|
;; unknown-sign A | A0 | (sat- A0 B0) | B0 .. -1
|
||||||
|
;; | .. | .. |
|
||||||
|
;; | (sat+ A1 B1) | (sat+ A1 B1) |
|
||||||
|
;; ---------------------------------------------------------------------
|
||||||
|
;; negative A | A0 .. -1 | A0 .. -1 | (max A0 B0) .. -1
|
||||||
|
;; ---------------------------------------------------------------------
|
||||||
|
(values (cond ((or (and (non-negative? a0) (non-negative? b0))
|
||||||
|
(and (negative? a1) (negative? b1)))
|
||||||
|
(max a0 b0))
|
||||||
|
((or (non-negative? a0) (negative? b1))
|
||||||
|
b0)
|
||||||
|
((or (non-negative? b0) (negative? a1))
|
||||||
|
a0)
|
||||||
|
(else
|
||||||
|
(saturate- a0 b0)))
|
||||||
|
(if (or (negative? a1) (negative? b1))
|
||||||
|
-1
|
||||||
|
(saturate+ a1 b1))))
|
||||||
|
|
||||||
(define-simple-type-checker (logior &exact-integer &exact-integer))
|
(define-simple-type-checker (logior &exact-integer &exact-integer))
|
||||||
(define-type-inferrer (logior a b result)
|
(define-type-inferrer (logior a b result)
|
||||||
;; Saturate all bits of val.
|
|
||||||
(define (saturate val)
|
|
||||||
(1- (next-power-of-two val)))
|
|
||||||
(define (logior-min a b)
|
|
||||||
(cond ((and (< a 0) (<= 0 b)) a)
|
|
||||||
((and (< b 0) (<= 0 a)) b)
|
|
||||||
(else (max a b))))
|
|
||||||
(define (logior-max a b)
|
|
||||||
;; If either operand is negative, just assume the max is -1.
|
|
||||||
(cond
|
|
||||||
((or (< a 0) (< b 0)) -1)
|
|
||||||
((or (inf? a) (inf? b)) +inf.0)
|
|
||||||
(else (saturate (logior a b)))))
|
|
||||||
(restrict! a &exact-integer -inf.0 +inf.0)
|
(restrict! a &exact-integer -inf.0 +inf.0)
|
||||||
(restrict! b &exact-integer -inf.0 +inf.0)
|
(restrict! b &exact-integer -inf.0 +inf.0)
|
||||||
(define-exact-integer! result
|
(call-with-values (lambda ()
|
||||||
(logior-min (&min a) (&min b))
|
(logior-bounds (&min a) (&max a) (&min b) (&max b)))
|
||||||
(logior-max (&max a) (&max b))))
|
(lambda (min max)
|
||||||
|
(define-exact-integer! result min max))))
|
||||||
|
|
||||||
(define-type-inferrer (ulogior a b result)
|
(define-type-inferrer (ulogior a b result)
|
||||||
(restrict! a &u64 0 &u64-max)
|
(restrict! a &u64 0 &u64-max)
|
||||||
(restrict! b &u64 0 &u64-max)
|
(restrict! b &u64 0 &u64-max)
|
||||||
(define! result &u64
|
(define! result &u64
|
||||||
(max (&min/0 a) (&min/0 b))
|
(max (&min/0 a) (&min/0 b))
|
||||||
(1- (next-power-of-two (logior (&max/u64 a) (&max/u64 b))))))
|
(saturate+ (&max/u64 a) (&max/u64 b))))
|
||||||
|
|
||||||
;; For our purposes, treat logxor the same as logior.
|
(define (logxor-bounds a0 a1 b0 b1)
|
||||||
(define-type-aliases logior logxor)
|
"Return two values: lower and upper bounds for (logxor A B)
|
||||||
|
where (A0 <= A <= A1) and (B0 <= B <= B1)."
|
||||||
|
;; For each argument, we consider three cases: (1) the argument is
|
||||||
|
;; non-negative, (2) its sign is unknown, or (3) it is negative.
|
||||||
|
;; To handle both arguments, we must consider a total of 9 cases.
|
||||||
|
;;
|
||||||
|
;; --------------------------------------------------------------------
|
||||||
|
;; LOGXOR | non-negative B | unknown-sign B | negative B
|
||||||
|
;; --------------------------------------------------------------------
|
||||||
|
;; non-negative A | 0 | (sat- A1 B0) | (sat- A1 B0)
|
||||||
|
;; | .. | .. | ..
|
||||||
|
;; | (sat+ A1 B1) | (sat+ A1 B1) | -1
|
||||||
|
;; --------------------------------------------------------------------
|
||||||
|
;; unknown-sign A | (sat- A0 B1) | (sat- A0 B1 A1 B0) | (sat- A1 B0)
|
||||||
|
;; | .. | .. | ..
|
||||||
|
;; | (sat+ A1 B1) | (sat+ A1 B1 A0 B0) | (sat+ A0 B0)
|
||||||
|
;; --------------------------------------------------------------------
|
||||||
|
;; negative A | (sat- A0 B1) | (sat- A0 B1) | 0
|
||||||
|
;; | .. | .. | ..
|
||||||
|
;; | -1 | (sat+ A0 B0) | (sat+ A0 B0)
|
||||||
|
;; --------------------------------------------------------------------
|
||||||
|
(values (cond ((or (and (non-negative? a0) (non-negative? b0))
|
||||||
|
(and (negative? a1) (negative? b1)))
|
||||||
|
0)
|
||||||
|
((or (non-negative? a0) (negative? b1))
|
||||||
|
(saturate- a1 b0))
|
||||||
|
((or (non-negative? b0) (negative? a1))
|
||||||
|
(saturate- a0 b1))
|
||||||
|
(else
|
||||||
|
(saturate- a0 b1 a1 b0)))
|
||||||
|
(cond ((or (and (non-negative? a0) (negative? b1))
|
||||||
|
(and (non-negative? b0) (negative? a1)))
|
||||||
|
-1)
|
||||||
|
((or (non-negative? a0) (non-negative? b0))
|
||||||
|
(saturate+ a1 b1))
|
||||||
|
((or (negative? a1) (negative? b1))
|
||||||
|
(saturate+ a0 b0))
|
||||||
|
(else
|
||||||
|
(saturate+ a1 b1 a0 b0)))))
|
||||||
|
|
||||||
|
(define-simple-type-checker (logxor &exact-integer &exact-integer))
|
||||||
|
(define-type-inferrer (logxor a b result)
|
||||||
|
(restrict! a &exact-integer -inf.0 +inf.0)
|
||||||
|
(restrict! b &exact-integer -inf.0 +inf.0)
|
||||||
|
(call-with-values (lambda ()
|
||||||
|
(logxor-bounds (&min a) (&max a) (&min b) (&max b)))
|
||||||
|
(lambda (min max)
|
||||||
|
(define! result &exact-integer min max))))
|
||||||
|
|
||||||
(define-type-inferrer (ulogxor a b result)
|
(define-type-inferrer (ulogxor a b result)
|
||||||
(restrict! a &u64 0 &u64-max)
|
(restrict! a &u64 0 &u64-max)
|
||||||
(restrict! b &u64 0 &u64-max)
|
(restrict! b &u64 0 &u64-max)
|
||||||
(define! result &u64 0 &u64-max))
|
(define! result &u64 0 (saturate+ (&max/u64 a) (&max/u64 b))))
|
||||||
|
|
||||||
(define-simple-type-checker (lognot &exact-integer))
|
(define-simple-type-checker (lognot &exact-integer))
|
||||||
(define-type-inferrer (lognot a result)
|
(define-type-inferrer (lognot a result)
|
||||||
(restrict! a &exact-integer -inf.0 +inf.0)
|
(restrict! a &exact-integer -inf.0 +inf.0)
|
||||||
(define-exact-integer! result
|
(define-exact-integer! result
|
||||||
(- -1 (&max a))
|
(lognot* (&max a))
|
||||||
(- -1 (&min a))))
|
(lognot* (&min a))))
|
||||||
|
|
||||||
(define-simple-type-checker (logtest &exact-integer &exact-integer))
|
(define-simple-type-checker (logtest &exact-integer &exact-integer))
|
||||||
(define-type-inferrer (logtest a b result)
|
(define-type-inferrer (logtest a b result)
|
||||||
|
@ -1560,13 +1668,16 @@ minimum, and maximum."
|
||||||
(define-type-inferrer (sqrt x result)
|
(define-type-inferrer (sqrt x result)
|
||||||
(let ((type (&type x)))
|
(let ((type (&type x)))
|
||||||
(cond
|
(cond
|
||||||
((and (zero? (logand type &complex)) (<= 0 (&min x)))
|
((and (zero? (logand type &complex))
|
||||||
|
(non-negative? (&min x)))
|
||||||
(define! result
|
(define! result
|
||||||
(logior type &flonum)
|
(logior type &flonum)
|
||||||
(inexact->exact (floor (sqrt (&min x))))
|
(exact-integer-sqrt (&min x))
|
||||||
(if (inf? (&max x))
|
(if (inf? (&max x))
|
||||||
+inf.0
|
+inf.0
|
||||||
(inexact->exact (ceiling (sqrt (&max x)))))))
|
(call-with-values (lambda () (exact-integer-sqrt (&max x)))
|
||||||
|
(lambda (s r)
|
||||||
|
(if (zero? r) s (+ s 1)))))))
|
||||||
(else
|
(else
|
||||||
(define! result (logior type &flonum &complex) -inf.0 +inf.0)))))
|
(define! result (logior type &flonum &complex) -inf.0 +inf.0)))))
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; Guile Emacs Lisp
|
;;; Guile Emacs Lisp
|
||||||
|
|
||||||
;; Copyright (C) 2009, 2010, 2011, 2013 Free Software Foundation, Inc.
|
;; Copyright (C) 2009-2011, 2013, 2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;; This program is free software; you can redistribute it and/or modify
|
;; This program is free software; you can redistribute it and/or modify
|
||||||
;; it under the terms of the GNU General Public License as published by
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
#:use-module (language tree-il)
|
#:use-module (language tree-il)
|
||||||
#:use-module (system base pmatch)
|
#:use-module (system base pmatch)
|
||||||
#:use-module (system base compile)
|
#:use-module (system base compile)
|
||||||
|
#:use-module (system base target)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-8)
|
#:use-module (srfi srfi-8)
|
||||||
#:use-module (srfi srfi-11)
|
#:use-module (srfi srfi-11)
|
||||||
|
@ -460,7 +461,9 @@
|
||||||
(map compile-expr args))))
|
(map compile-expr args))))
|
||||||
|
|
||||||
(defspecial eval-when-compile (loc args)
|
(defspecial eval-when-compile (loc args)
|
||||||
(make-const loc (compile `(progn ,@args) #:from 'elisp #:to 'value)))
|
(make-const loc (with-native-target
|
||||||
|
(lambda ()
|
||||||
|
(compile `(progn ,@args) #:from 'elisp #:to 'value)))))
|
||||||
|
|
||||||
(defspecial if (loc args)
|
(defspecial if (loc args)
|
||||||
(pmatch args
|
(pmatch args
|
||||||
|
@ -702,7 +705,9 @@
|
||||||
args
|
args
|
||||||
body))))
|
body))))
|
||||||
(make-const loc name))))
|
(make-const loc name))))
|
||||||
(compile tree-il #:from 'tree-il #:to 'value)
|
(with-native-target
|
||||||
|
(lambda ()
|
||||||
|
(compile tree-il #:from 'tree-il #:to 'value)))
|
||||||
tree-il)))))
|
tree-il)))))
|
||||||
|
|
||||||
(defspecial defun (loc args)
|
(defspecial defun (loc args)
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
;;; Guile Emacs Lisp
|
||||||
|
|
||||||
|
;; Copyright (C) 2011, 2017 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 the License, or (at your option) any later version.
|
||||||
|
;;;;
|
||||||
|
;;;; This library is distributed in the hope that it will be useful,
|
||||||
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
;;;; Lesser General Public License for more details.
|
||||||
|
;;;;
|
||||||
|
;;;; You should have received a copy of the GNU Lesser General Public
|
||||||
|
;;;; License along with this library; if not, write to the Free Software
|
||||||
|
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
(define-module (language elisp falias)
|
(define-module (language elisp falias)
|
||||||
#:export (falias?
|
#:export (falias?
|
||||||
make-falias
|
make-falias
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; Guile Emac Lisp
|
;;; Guile Emacs Lisp
|
||||||
|
|
||||||
;; Copyright (C) 2001, 2009, 2010 Free Software Foundation, Inc.
|
;; Copyright (C) 2001, 2009, 2010, 2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
#:use-module (language elisp parser)
|
#:use-module (language elisp parser)
|
||||||
#:use-module (system base language)
|
#:use-module (system base language)
|
||||||
#:use-module (system base compile)
|
#:use-module (system base compile)
|
||||||
|
#:use-module (system base target)
|
||||||
#:export (elisp))
|
#:export (elisp))
|
||||||
|
|
||||||
(define-language elisp
|
(define-language elisp
|
||||||
|
@ -31,5 +32,12 @@
|
||||||
#:printer write
|
#:printer write
|
||||||
#:compilers `((tree-il . ,compile-tree-il)))
|
#:compilers `((tree-il . ,compile-tree-il)))
|
||||||
|
|
||||||
(compile-and-load (%search-load-path "language/elisp/boot.el")
|
;; Compile and load the Elisp boot code for the native host
|
||||||
#:from 'elisp)
|
;; architecture. We must specifically ask for native compilation here,
|
||||||
|
;; because this module might be loaded in a dynamic environment where
|
||||||
|
;; cross-compilation has been requested using 'with-target'. For
|
||||||
|
;; example, this happens when cross-compiling Guile itself.
|
||||||
|
(with-native-target
|
||||||
|
(lambda ()
|
||||||
|
(compile-and-load (%search-load-path "language/elisp/boot.el")
|
||||||
|
#:from 'elisp)))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; TREE-IL -> GLIL compiler
|
;;; TREE-IL -> GLIL compiler
|
||||||
|
|
||||||
;; Copyright (C) 2001, 2008-2014 Free Software Foundation, Inc.
|
;; Copyright (C) 2001, 2008-2014, 2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
analyze-tree
|
analyze-tree
|
||||||
unused-variable-analysis
|
unused-variable-analysis
|
||||||
unused-toplevel-analysis
|
unused-toplevel-analysis
|
||||||
|
shadowed-toplevel-analysis
|
||||||
unbound-variable-analysis
|
unbound-variable-analysis
|
||||||
macro-use-before-definition-analysis
|
macro-use-before-definition-analysis
|
||||||
arity-analysis
|
arity-analysis
|
||||||
|
@ -813,6 +814,37 @@ given `tree-il' element."
|
||||||
|
|
||||||
(make-reference-graph vlist-null vlist-null #f))))
|
(make-reference-graph vlist-null vlist-null #f))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Shadowed top-level definition analysis.
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define shadowed-toplevel-analysis
|
||||||
|
;; Report top-level definitions that shadow previous top-level
|
||||||
|
;; definitions from the same compilation unit.
|
||||||
|
(make-tree-analysis
|
||||||
|
(lambda (x defs env locs)
|
||||||
|
;; Going down into X.
|
||||||
|
(record-case x
|
||||||
|
((<toplevel-define> name src)
|
||||||
|
(match (vhash-assq name defs)
|
||||||
|
((_ . previous-definition)
|
||||||
|
(warning 'shadowed-toplevel src name
|
||||||
|
(toplevel-define-src previous-definition))
|
||||||
|
defs)
|
||||||
|
(#f
|
||||||
|
(vhash-consq name x defs))))
|
||||||
|
(else defs)))
|
||||||
|
|
||||||
|
(lambda (x defs env locs)
|
||||||
|
;; Leaving X's scope.
|
||||||
|
defs)
|
||||||
|
|
||||||
|
(lambda (defs env)
|
||||||
|
#t)
|
||||||
|
|
||||||
|
vlist-null))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Unbound variable analysis.
|
;;; Unbound variable analysis.
|
||||||
|
|
|
@ -2319,6 +2319,7 @@ integer."
|
||||||
(define %warning-passes
|
(define %warning-passes
|
||||||
`((unused-variable . ,unused-variable-analysis)
|
`((unused-variable . ,unused-variable-analysis)
|
||||||
(unused-toplevel . ,unused-toplevel-analysis)
|
(unused-toplevel . ,unused-toplevel-analysis)
|
||||||
|
(shadowed-toplevel . ,shadowed-toplevel-analysis)
|
||||||
(unbound-variable . ,unbound-variable-analysis)
|
(unbound-variable . ,unbound-variable-analysis)
|
||||||
(macro-use-before-definition . ,macro-use-before-definition-analysis)
|
(macro-use-before-definition . ,macro-use-before-definition-analysis)
|
||||||
(arity-mismatch . ,arity-analysis)
|
(arity-mismatch . ,arity-analysis)
|
||||||
|
|
|
@ -1591,11 +1591,15 @@ top-level bindings from ENV and return the resulting expression."
|
||||||
(and (not opt) rest (not kw)
|
(and (not opt) rest (not kw)
|
||||||
(match body
|
(match body
|
||||||
(($ <primcall> _ 'apply
|
(($ <primcall> _ 'apply
|
||||||
(($ <lambda> _ _ (and lcase ($ <lambda-case>)))
|
(($ <lambda> _ _ (and lcase ($ <lambda-case> _ req1)))
|
||||||
($ <lexical-ref> _ _ sym)
|
($ <lexical-ref> _ _ sym)
|
||||||
...))
|
...))
|
||||||
(and (equal? sym gensyms)
|
(and (equal? sym gensyms)
|
||||||
(not (lambda-case-alternate lcase))
|
(not (lambda-case-alternate lcase))
|
||||||
|
(<= (length req) (length req1))
|
||||||
|
(every (lambda (s)
|
||||||
|
(= (lexical-refcount s) 1))
|
||||||
|
sym)
|
||||||
lcase))
|
lcase))
|
||||||
(_ #f))))
|
(_ #f))))
|
||||||
(let* ((vars (map lookup-var gensyms))
|
(let* ((vars (map lookup-var gensyms))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
;;;; goops.scm -- The Guile Object-Oriented Programming System
|
;;;; goops.scm -- The Guile Object-Oriented Programming System
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 1998-2003,2006,2009-2011,2013-2015,2017 Free Software Foundation, Inc.
|
;;;; Copyright (C) 1998-2003,2006,2009-2011,2013-2015,2017-2018
|
||||||
|
;;;; Free Software Foundation, Inc.
|
||||||
;;;; Copyright (C) 1993-1998 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
|
;;;; Copyright (C) 1993-1998 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
|
@ -285,7 +286,8 @@
|
||||||
(class-has-flags? (struct-vtable obj) vtable-flag-goops-slot)))
|
(class-has-flags? (struct-vtable obj) vtable-flag-goops-slot)))
|
||||||
|
|
||||||
(define-inlinable (instance? obj)
|
(define-inlinable (instance? obj)
|
||||||
(class-has-flags? (struct-vtable obj) vtable-flag-goops-class))
|
(and (struct? obj)
|
||||||
|
(class-has-flags? (struct-vtable obj) vtable-flag-goops-class)))
|
||||||
|
|
||||||
(define (class-has-statically-allocated-slots? class)
|
(define (class-has-statically-allocated-slots? class)
|
||||||
(class-has-flags? class vtable-flag-goops-static-slot-allocation))
|
(class-has-flags? class vtable-flag-goops-static-slot-allocation))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; simple.scm --- The R6RS simple I/O library
|
;;; simple.scm --- The R6RS simple I/O library
|
||||||
|
|
||||||
;; Copyright (C) 2010, 2011, 2014 Free Software Foundation, Inc.
|
;; Copyright (C) 2010, 2011, 2014, 2018 Free Software Foundation, Inc.
|
||||||
;;
|
;;
|
||||||
;; This library is free software; you can redistribute it and/or
|
;; This library is free software; you can redistribute it and/or
|
||||||
;; modify it under the terms of the GNU Lesser General Public
|
;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -118,10 +118,10 @@
|
||||||
(define display (@@ (rnrs io ports) display))
|
(define display (@@ (rnrs io ports) display))
|
||||||
|
|
||||||
(define (call-with-input-file filename proc)
|
(define (call-with-input-file filename proc)
|
||||||
(call-with-port (open-file-input-port filename) proc))
|
(call-with-port (open-input-file filename) proc))
|
||||||
|
|
||||||
(define (call-with-output-file filename proc)
|
(define (call-with-output-file filename proc)
|
||||||
(call-with-port (open-file-output-port filename) proc))
|
(call-with-port (open-output-file filename) proc))
|
||||||
|
|
||||||
(define (with-input-from-file filename thunk)
|
(define (with-input-from-file filename thunk)
|
||||||
(call-with-input-file filename
|
(call-with-input-file filename
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; Compile --- Command-line Guile Scheme compiler -*- coding: iso-8859-1 -*-
|
;;; Compile --- Command-line Guile Scheme compiler -*- coding: iso-8859-1 -*-
|
||||||
|
|
||||||
;; Copyright 2005, 2008-2011, 2013, 2014, 2015, 2018 Free Software Foundation, Inc.
|
;; Copyright 2005,2008-2011,2013-2015,2017-2018 Free Software Foundation, Inc.
|
||||||
;;
|
;;
|
||||||
;; This program is free software; you can redistribute it and/or
|
;; This program is free software; you can redistribute it and/or
|
||||||
;; modify it under the terms of the GNU Lesser General Public License
|
;; modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(define-module (scripts compile)
|
(define-module (scripts compile)
|
||||||
|
#:use-module ((system base language) #:select (lookup-language))
|
||||||
#:use-module ((system base compile) #:select (compile-file))
|
#:use-module ((system base compile) #:select (compile-file))
|
||||||
#:use-module (system base target)
|
#:use-module (system base target)
|
||||||
#:use-module (system base message)
|
#:use-module (system base message)
|
||||||
|
@ -67,6 +68,10 @@
|
||||||
(if (assoc-ref result 'output-file)
|
(if (assoc-ref result 'output-file)
|
||||||
(fail "`-o' option cannot be specified more than once")
|
(fail "`-o' option cannot be specified more than once")
|
||||||
(alist-cons 'output-file arg result))))
|
(alist-cons 'output-file arg result))))
|
||||||
|
(option '(#\x) #t #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(set! %load-extensions (cons arg %load-extensions))
|
||||||
|
result))
|
||||||
|
|
||||||
(option '(#\W "warn") #t #f
|
(option '(#\W "warn") #t #f
|
||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
|
@ -122,7 +127,7 @@
|
||||||
options."
|
options."
|
||||||
(args-fold args %options
|
(args-fold args %options
|
||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
(format (current-error-port) "~A: unrecognized option" name)
|
(format (current-error-port) "~A: unrecognized option~%" name)
|
||||||
(exit 1))
|
(exit 1))
|
||||||
(lambda (file result)
|
(lambda (file result)
|
||||||
(let ((input-files (assoc-ref result 'input-files)))
|
(let ((input-files (assoc-ref result 'input-files)))
|
||||||
|
@ -136,7 +141,7 @@ options."
|
||||||
|
|
||||||
(define (show-version)
|
(define (show-version)
|
||||||
(format #t "compile (GNU Guile) ~A~%" (version))
|
(format #t "compile (GNU Guile) ~A~%" (version))
|
||||||
(format #t "Copyright (C) 2009, 2011 Free Software Foundation, Inc.
|
(format #t "Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
License LGPLv3+: GNU LGPL version 3 or later <http://gnu.org/licenses/lgpl.html>.
|
License LGPLv3+: GNU LGPL version 3 or later <http://gnu.org/licenses/lgpl.html>.
|
||||||
This is free software: you are free to change and redistribute it.
|
This is free software: you are free to change and redistribute it.
|
||||||
There is NO WARRANTY, to the extent permitted by law.~%"))
|
There is NO WARRANTY, to the extent permitted by law.~%"))
|
||||||
|
@ -196,6 +201,7 @@ Compile each Guile source file FILE into a Guile object.
|
||||||
|
|
||||||
-L, --load-path=DIR add DIR to the front of the module load path
|
-L, --load-path=DIR add DIR to the front of the module load path
|
||||||
-o, --output=OFILE write output to OFILE
|
-o, --output=OFILE write output to OFILE
|
||||||
|
-x EXTENSION add EXTENSION to the set of source file extensions
|
||||||
|
|
||||||
-W, --warn=WARNING emit warnings of type WARNING; use `--warn=help'
|
-W, --warn=WARNING emit warnings of type WARNING; use `--warn=help'
|
||||||
for a list of available warnings
|
for a list of available warnings
|
||||||
|
@ -212,6 +218,13 @@ Report bugs to <~A>.~%"
|
||||||
%guile-bug-report-address)
|
%guile-bug-report-address)
|
||||||
(exit 0)))
|
(exit 0)))
|
||||||
|
|
||||||
|
;; Load FROM and TO before we have changed the load path. That way, when
|
||||||
|
;; cross-compiling Guile itself, we can be sure we're loading our own
|
||||||
|
;; language modules and not those of the Guile being compiled, which may
|
||||||
|
;; have incompatible .go files.
|
||||||
|
(lookup-language from)
|
||||||
|
(lookup-language to)
|
||||||
|
|
||||||
(set! %load-path (append load-path %load-path))
|
(set! %load-path (append load-path %load-path))
|
||||||
(set! %load-should-auto-compile #f)
|
(set! %load-should-auto-compile #f)
|
||||||
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
## Process this file with automake to produce Makefile.in.
|
|
||||||
##
|
|
||||||
## Copyright (C) 2000, 2004, 2006, 2008 Free Software Foundation, Inc.
|
|
||||||
##
|
|
||||||
## This file is part of GUILE.
|
|
||||||
##
|
|
||||||
## GUILE 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, or
|
|
||||||
## (at your option) any later version.
|
|
||||||
##
|
|
||||||
## GUILE is distributed in the hope that it will be useful, but
|
|
||||||
## WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
## GNU Lesser General Public License for more details.
|
|
||||||
##
|
|
||||||
## You should have received a copy of the GNU Lesser General Public
|
|
||||||
## License along with GUILE; see the file COPYING.LESSER. If not,
|
|
||||||
## write to the Free Software Foundation, Inc., 51 Franklin Street,
|
|
||||||
## Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = gnu
|
|
||||||
|
|
||||||
modpath = srfi
|
|
||||||
SOURCES = \
|
|
||||||
srfi-1.scm \
|
|
||||||
srfi-2.scm \
|
|
||||||
srfi-4.scm \
|
|
||||||
srfi-6.scm \
|
|
||||||
srfi-8.scm \
|
|
||||||
srfi-9.scm \
|
|
||||||
srfi-10.scm \
|
|
||||||
srfi-11.scm \
|
|
||||||
srfi-13.scm \
|
|
||||||
srfi-14.scm \
|
|
||||||
srfi-16.scm \
|
|
||||||
srfi-17.scm \
|
|
||||||
srfi-19.scm \
|
|
||||||
srfi-26.scm \
|
|
||||||
srfi-31.scm \
|
|
||||||
srfi-34.scm \
|
|
||||||
srfi-35.scm \
|
|
||||||
srfi-37.scm \
|
|
||||||
srfi-39.scm \
|
|
||||||
srfi-60.scm \
|
|
||||||
srfi-69.scm \
|
|
||||||
srfi-88.scm
|
|
||||||
|
|
||||||
# Will poke this later.
|
|
||||||
NOCOMP_SOURCES = srfi-18.scm
|
|
||||||
|
|
||||||
include $(top_srcdir)/am/guilec
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; srfi-18.scm --- Multithreading support
|
;;; srfi-18.scm --- Multithreading support
|
||||||
|
|
||||||
;; Copyright (C) 2008, 2009, 2010, 2012, 2014 Free Software Foundation, Inc.
|
;; Copyright (C) 2008, 2009, 2010, 2012, 2014, 2018 Free Software Foundation, Inc.
|
||||||
;;
|
;;
|
||||||
;; This library is free software; you can redistribute it and/or
|
;; This library is free software; you can redistribute it and/or
|
||||||
;; modify it under the terms of the GNU Lesser General Public
|
;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -139,6 +139,16 @@
|
||||||
(define current-thread (make-parameter (%make-thread #f #f #f #f #f)))
|
(define current-thread (make-parameter (%make-thread #f #f #f #f #f)))
|
||||||
(define thread-mutexes (make-parameter #f))
|
(define thread-mutexes (make-parameter #f))
|
||||||
|
|
||||||
|
(define (timeout->absolute-time timeout)
|
||||||
|
"Return an absolute time in seconds corresponding to TIMEOUT. TIMEOUT
|
||||||
|
can be any value authorized by SRFI-18: a number (relative time), a time
|
||||||
|
object (absolute point in time), or #f."
|
||||||
|
(cond ((number? timeout) ;seconds relative to now
|
||||||
|
(+ ((@ (guile) current-time)) timeout))
|
||||||
|
((time? timeout) ;absolute point in time
|
||||||
|
(time->seconds timeout))
|
||||||
|
(else timeout))) ;pair or #f
|
||||||
|
|
||||||
;; EXCEPTIONS
|
;; EXCEPTIONS
|
||||||
|
|
||||||
;; All threads created by SRFI-18 have an initial handler installed that
|
;; All threads created by SRFI-18 have an initial handler installed that
|
||||||
|
@ -225,9 +235,9 @@
|
||||||
(define (thread-yield!) (threads:yield) *unspecified*)
|
(define (thread-yield!) (threads:yield) *unspecified*)
|
||||||
|
|
||||||
(define (thread-sleep! timeout)
|
(define (thread-sleep! timeout)
|
||||||
(let* ((ct (time->seconds (current-time)))
|
(let* ((t (cond ((time? timeout) (- (time->seconds timeout)
|
||||||
(t (cond ((time? timeout) (- (time->seconds timeout) ct))
|
(time->seconds (current-time))))
|
||||||
((number? timeout) (- timeout ct))
|
((number? timeout) timeout)
|
||||||
(else (scm-error 'wrong-type-arg "thread-sleep!"
|
(else (scm-error 'wrong-type-arg "thread-sleep!"
|
||||||
"Wrong type argument: ~S"
|
"Wrong type argument: ~S"
|
||||||
(list timeout)
|
(list timeout)
|
||||||
|
@ -308,7 +318,8 @@
|
||||||
(with-exception-handlers-here
|
(with-exception-handlers-here
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(cond
|
(cond
|
||||||
((threads:lock-mutex (mutex-prim mutex) timeout)
|
((threads:lock-mutex (mutex-prim mutex)
|
||||||
|
(timeout->absolute-time timeout))
|
||||||
(set-mutex-owner! mutex thread)
|
(set-mutex-owner! mutex thread)
|
||||||
(when (mutex-abandoned? mutex)
|
(when (mutex-abandoned? mutex)
|
||||||
(set-mutex-abandoned?! mutex #f)
|
(set-mutex-abandoned?! mutex #f)
|
||||||
|
@ -320,20 +331,21 @@
|
||||||
(define %unlock-sentinel (list 'unlock))
|
(define %unlock-sentinel (list 'unlock))
|
||||||
(define* (mutex-unlock! mutex #:optional (cond-var %unlock-sentinel)
|
(define* (mutex-unlock! mutex #:optional (cond-var %unlock-sentinel)
|
||||||
(timeout %unlock-sentinel))
|
(timeout %unlock-sentinel))
|
||||||
(when (mutex-owner mutex)
|
(let ((timeout (timeout->absolute-time timeout)))
|
||||||
(set-mutex-owner! mutex #f)
|
(when (mutex-owner mutex)
|
||||||
(cond
|
(set-mutex-owner! mutex #f)
|
||||||
((eq? cond-var %unlock-sentinel)
|
(cond
|
||||||
(threads:unlock-mutex (mutex-prim mutex)))
|
((eq? cond-var %unlock-sentinel)
|
||||||
((eq? timeout %unlock-sentinel)
|
(threads:unlock-mutex (mutex-prim mutex)))
|
||||||
(threads:wait-condition-variable (condition-variable-prim cond-var)
|
((eq? timeout %unlock-sentinel)
|
||||||
(mutex-prim mutex))
|
(threads:wait-condition-variable (condition-variable-prim cond-var)
|
||||||
(threads:unlock-mutex (mutex-prim mutex)))
|
(mutex-prim mutex))
|
||||||
((threads:wait-condition-variable (condition-variable-prim cond-var)
|
(threads:unlock-mutex (mutex-prim mutex)))
|
||||||
(mutex-prim mutex)
|
((threads:wait-condition-variable (condition-variable-prim cond-var)
|
||||||
timeout)
|
(mutex-prim mutex)
|
||||||
(threads:unlock-mutex (mutex-prim mutex)))
|
timeout)
|
||||||
(else #f))))
|
(threads:unlock-mutex (mutex-prim mutex)))
|
||||||
|
(else #f)))))
|
||||||
|
|
||||||
;; CONDITION VARIABLES
|
;; CONDITION VARIABLES
|
||||||
;; These functions are all pass-thrus to the existing Guile implementations.
|
;; These functions are all pass-thrus to the existing Guile implementations.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; srfi-19.scm --- Time/Date Library
|
;;; srfi-19.scm --- Time/Date Library
|
||||||
|
|
||||||
;; Copyright (C) 2001-2003, 2005-2011, 2014, 2016-2017
|
;; Copyright (C) 2001-2003, 2005-2011, 2014, 2016-2018
|
||||||
;; Free Software Foundation, Inc.
|
;; Free Software Foundation, Inc.
|
||||||
;;
|
;;
|
||||||
;; This library is free software; you can redistribute it and/or
|
;; This library is free software; you can redistribute it and/or
|
||||||
|
@ -285,24 +285,6 @@
|
||||||
(define (make-time type nanosecond second)
|
(define (make-time type nanosecond second)
|
||||||
(time-normalize! (make-time-unnormalized type nanosecond second)))
|
(time-normalize! (make-time-unnormalized type nanosecond second)))
|
||||||
|
|
||||||
;; Helpers
|
|
||||||
;; FIXME: finish this and publish it?
|
|
||||||
(define (date->broken-down-time date)
|
|
||||||
(let ((result (mktime 0)))
|
|
||||||
;; FIXME: What should we do about leap-seconds which may overflow
|
|
||||||
;; set-tm:sec?
|
|
||||||
(set-tm:sec result (date-second date))
|
|
||||||
(set-tm:min result (date-minute date))
|
|
||||||
(set-tm:hour result (date-hour date))
|
|
||||||
;; FIXME: SRFI day ranges from 0-31. (not compatible with set-tm:mday).
|
|
||||||
(set-tm:mday result (date-day date))
|
|
||||||
(set-tm:mon result (- (date-month date) 1))
|
|
||||||
;; FIXME: need to signal error on range violation.
|
|
||||||
(set-tm:year result (+ 1900 (date-year date)))
|
|
||||||
(set-tm:isdst result -1)
|
|
||||||
(set-tm:gmtoff result (- (date-zone-offset date)))
|
|
||||||
result))
|
|
||||||
|
|
||||||
;;; current-time
|
;;; current-time
|
||||||
|
|
||||||
;;; specific time getters.
|
;;; specific time getters.
|
||||||
|
|
267
module/srfi/srfi-71.scm
Normal file
267
module/srfi/srfi-71.scm
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
;; Copyright (c) 2005 Sebastian Egner.
|
||||||
|
;;
|
||||||
|
;; Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
;; copy of this software and associated documentation files (the
|
||||||
|
;; ``Software''), to deal in the Software without restriction, including
|
||||||
|
;; without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
;; distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
;; permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
;; the following conditions:
|
||||||
|
;;
|
||||||
|
;; The above copyright notice and this permission notice shall be included
|
||||||
|
;; in all copies or substantial portions of the Software.
|
||||||
|
;;
|
||||||
|
;; THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
;; LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
;; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
;; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
;; Reference implementation of SRFI-71 using PLT 208's modules
|
||||||
|
;; Sebastian.Egner@philips.com, 2005-04-29
|
||||||
|
;;
|
||||||
|
;; Adjusted for Guile module system by
|
||||||
|
;; Christopher Allan Webber <cwebber@dustycloud.org>, 2017-06-29
|
||||||
|
|
||||||
|
(define-module (srfi srfi-71)
|
||||||
|
#:export (uncons unlist unvector values->list
|
||||||
|
values->vector)
|
||||||
|
#:replace ((srfi-let . let)
|
||||||
|
(srfi-let* . let*)
|
||||||
|
(srfi-letrec . letrec)))
|
||||||
|
|
||||||
|
(cond-expand-provide (current-module) '(srfi-71))
|
||||||
|
|
||||||
|
(define-syntax r5rs-let
|
||||||
|
(syntax-rules ()
|
||||||
|
((r5rs-let ((v x) ...) body1 body ...)
|
||||||
|
(let ((v x) ...) body1 body ...))
|
||||||
|
((r5rs-let tag ((v x) ...) body1 body ...)
|
||||||
|
(let tag ((v x) ...) body1 body ...))))
|
||||||
|
|
||||||
|
(define-syntax r5rs-let*
|
||||||
|
(syntax-rules ()
|
||||||
|
((r5rs-let* ((v x) ...) body1 body ...)
|
||||||
|
(let* ((v x) ...) body1 body ...))))
|
||||||
|
|
||||||
|
(define-syntax r5rs-letrec
|
||||||
|
(syntax-rules ()
|
||||||
|
((r5rs-letrec ((v x) ...) body1 body ...)
|
||||||
|
(letrec ((v x) ...) body1 body ...))))
|
||||||
|
|
||||||
|
; --- textual copy of 'letvalues.scm' starts here ---
|
||||||
|
|
||||||
|
; Reference implementation of SRFI-71 (generic part)
|
||||||
|
; Sebastian.Egner@philips.com, 20-May-2005, PLT 208
|
||||||
|
;
|
||||||
|
; In order to avoid conflicts with the existing let etc.
|
||||||
|
; the macros defined here are called srfi-let etc.,
|
||||||
|
; and they are defined in terms of r5rs-let etc.
|
||||||
|
; It is up to the actual implementation to save let/*/rec
|
||||||
|
; in r5rs-let/*/rec first and redefine let/*/rec
|
||||||
|
; by srfi-let/*/rec then.
|
||||||
|
;
|
||||||
|
; There is also a srfi-letrec* being defined (in view of R6RS.)
|
||||||
|
;
|
||||||
|
; Macros used internally are named i:<something>.
|
||||||
|
;
|
||||||
|
; Abbreviations for macro arguments:
|
||||||
|
; bs - <binding spec>
|
||||||
|
; b - component of a binding spec (values, <variable>, or <expression>)
|
||||||
|
; v - <variable>
|
||||||
|
; vr - <variable> for rest list
|
||||||
|
; x - <expression>
|
||||||
|
; t - newly introduced temporary variable
|
||||||
|
; vx - (<variable> <expression>)
|
||||||
|
; rec - flag if letrec is produced (and not let)
|
||||||
|
; cwv - call-with-value skeleton of the form (x formals)
|
||||||
|
; (call-with-values (lambda () x) (lambda formals /payload/))
|
||||||
|
; where /payload/ is of the form (let (vx ...) body1 body ...).
|
||||||
|
;
|
||||||
|
; Remark (*):
|
||||||
|
; We bind the variables of a letrec to i:undefined since there is
|
||||||
|
; no portable (R5RS) way of binding a variable to a values that
|
||||||
|
; raises an error when read uninitialized.
|
||||||
|
|
||||||
|
(define i:undefined 'undefined)
|
||||||
|
|
||||||
|
(define-syntax srfi-letrec* ; -> srfi-letrec
|
||||||
|
(syntax-rules ()
|
||||||
|
((srfi-letrec* () body1 body ...)
|
||||||
|
(srfi-letrec () body1 body ...))
|
||||||
|
((srfi-letrec* (bs) body1 body ...)
|
||||||
|
(srfi-letrec (bs) body1 body ...))
|
||||||
|
((srfi-letrec* (bs1 bs2 bs ...) body1 body ...)
|
||||||
|
(srfi-letrec (bs1) (srfi-letrec* (bs2 bs ...) body1 body ...)))))
|
||||||
|
|
||||||
|
(define-syntax srfi-letrec ; -> i:let
|
||||||
|
(syntax-rules ()
|
||||||
|
((srfi-letrec ((b1 b2 b ...) ...) body1 body ...)
|
||||||
|
(i:let "bs" #t () () (body1 body ...) ((b1 b2 b ...) ...)))))
|
||||||
|
|
||||||
|
(define-syntax srfi-let* ; -> srfi-let
|
||||||
|
(syntax-rules ()
|
||||||
|
((srfi-let* () body1 body ...)
|
||||||
|
(srfi-let () body1 body ...))
|
||||||
|
((srfi-let* (bs) body1 body ...)
|
||||||
|
(srfi-let (bs) body1 body ...))
|
||||||
|
((srfi-let* (bs1 bs2 bs ...) body1 body ...)
|
||||||
|
(srfi-let (bs1) (srfi-let* (bs2 bs ...) body1 body ...)))))
|
||||||
|
|
||||||
|
(define-syntax srfi-let ; -> i:let or i:named-let
|
||||||
|
(syntax-rules ()
|
||||||
|
((srfi-let ((b1 b2 b ...) ...) body1 body ...)
|
||||||
|
(i:let "bs" #f () () (body1 body ...) ((b1 b2 b ...) ...)))
|
||||||
|
((srfi-let tag ((b1 b2 b ...) ...) body1 body ...)
|
||||||
|
(i:named-let tag () (body1 body ...) ((b1 b2 b ...) ...)))))
|
||||||
|
|
||||||
|
(define-syntax i:let
|
||||||
|
(syntax-rules (values)
|
||||||
|
|
||||||
|
; (i:let "bs" rec (cwv ...) (vx ...) body (bs ...))
|
||||||
|
; processes the binding specs bs ... by adding call-with-values
|
||||||
|
; skeletons to cwv ... and bindings to vx ..., and afterwards
|
||||||
|
; wrapping the skeletons around the payload (let (vx ...) . body).
|
||||||
|
|
||||||
|
; no more bs to process -> wrap call-with-values skeletons
|
||||||
|
((i:let "bs" rec (cwv ...) vxs body ())
|
||||||
|
(i:let "wrap" rec vxs body cwv ...))
|
||||||
|
|
||||||
|
; recognize form1 without variable -> dummy binding for side-effects
|
||||||
|
((i:let "bs" rec cwvs (vx ...) body (((values) x) bs ...))
|
||||||
|
(i:let "bs" rec cwvs (vx ... (dummy (begin x #f))) body (bs ...)))
|
||||||
|
|
||||||
|
; recognize form1 with single variable -> just extend vx ...
|
||||||
|
((i:let "bs" rec cwvs (vx ...) body (((values v) x) bs ...))
|
||||||
|
(i:let "bs" rec cwvs (vx ... (v x)) body (bs ...)))
|
||||||
|
|
||||||
|
; recognize form1 without rest arg -> generate cwv
|
||||||
|
((i:let "bs" rec cwvs vxs body (((values v ...) x) bs ...))
|
||||||
|
(i:let "form1" rec cwvs vxs body (bs ...) (x ()) (values v ...)))
|
||||||
|
|
||||||
|
; recognize form1 with rest arg -> generate cwv
|
||||||
|
((i:let "bs" rec cwvs vxs body (((values . vs) x) bs ...))
|
||||||
|
(i:let "form1+" rec cwvs vxs body (bs ...) (x ()) (values . vs)))
|
||||||
|
|
||||||
|
; recognize form2 with single variable -> just extend vx ...
|
||||||
|
((i:let "bs" rec cwvs (vx ...) body ((v x) bs ...))
|
||||||
|
(i:let "bs" rec cwvs (vx ... (v x)) body (bs ...)))
|
||||||
|
|
||||||
|
; recognize form2 with >=2 variables -> transform to form1
|
||||||
|
((i:let "bs" rec cwvs vxs body ((b1 b2 b3 b ...) bs ...))
|
||||||
|
(i:let "form2" rec cwvs vxs body (bs ...) (b1 b2) (b3 b ...)))
|
||||||
|
|
||||||
|
; (i:let "form1" rec cwvs vxs body bss (x (t ...)) (values v1 v2 v ...))
|
||||||
|
; processes the variables in v1 v2 v ... adding them to (t ...)
|
||||||
|
; and producing a cwv when finished. There is not rest argument.
|
||||||
|
|
||||||
|
((i:let "form1" rec (cwv ...) vxs body bss (x ts) (values))
|
||||||
|
(i:let "bs" rec (cwv ... (x ts)) vxs body bss))
|
||||||
|
((i:let "form1" rec cwvs (vx ...) body bss (x (t ...)) (values v1 v ...))
|
||||||
|
(i:let "form1" rec cwvs (vx ... (v1 t1)) body bss (x (t ... t1)) (values v ...)))
|
||||||
|
|
||||||
|
; (i:let "form1+" rec cwvs vxs body bss (x (t ...)) (values v ... . vr))
|
||||||
|
; processes the variables in v ... . vr adding them to (t ...)
|
||||||
|
; and producing a cwv when finished. The rest arg is vr.
|
||||||
|
|
||||||
|
((i:let "form1+" rec cwvs (vx ...) body bss (x (t ...)) (values v1 v2 . vs))
|
||||||
|
(i:let "form1+" rec cwvs (vx ... (v1 t1)) body bss (x (t ... t1)) (values v2 . vs)))
|
||||||
|
((i:let "form1+" rec (cwv ...) (vx ...) body bss (x (t ...)) (values v1 . vr))
|
||||||
|
(i:let "bs" rec (cwv ... (x (t ... t1 . tr))) (vx ... (v1 t1) (vr tr)) body bss))
|
||||||
|
((i:let "form1+" rec (cwv ...) (vx ...) body bss (x ()) (values . vr))
|
||||||
|
(i:let "bs" rec (cwv ... (x tr)) (vx ... (vr tr)) body bss))
|
||||||
|
|
||||||
|
; (i:let "form2" rec cwvs vxs body bss (v ...) (b ... x))
|
||||||
|
; processes the binding items (b ... x) from form2 as in
|
||||||
|
; (v ... b ... x) into ((values v ... b ...) x), i.e. form1.
|
||||||
|
; Then call "bs" recursively.
|
||||||
|
|
||||||
|
((i:let "form2" rec cwvs vxs body (bs ...) (v ...) (x))
|
||||||
|
(i:let "bs" rec cwvs vxs body (((values v ...) x) bs ...)))
|
||||||
|
((i:let "form2" rec cwvs vxs body bss (v ...) (b1 b2 b ...))
|
||||||
|
(i:let "form2" rec cwvs vxs body bss (v ... b1) (b2 b ...)))
|
||||||
|
|
||||||
|
; (i:let "wrap" rec ((v x) ...) (body ...) cwv ...)
|
||||||
|
; wraps cwv ... around the payload generating the actual code.
|
||||||
|
; For letrec this is of course different than for let.
|
||||||
|
|
||||||
|
((i:let "wrap" #f vxs body)
|
||||||
|
(r5rs-let vxs . body))
|
||||||
|
((i:let "wrap" #f vxs body (x formals) cwv ...)
|
||||||
|
(call-with-values
|
||||||
|
(lambda () x)
|
||||||
|
(lambda formals (i:let "wrap" #f vxs body cwv ...))))
|
||||||
|
|
||||||
|
((i:let "wrap" #t vxs body)
|
||||||
|
(r5rs-letrec vxs . body))
|
||||||
|
((i:let "wrap" #t ((v t) ...) body cwv ...)
|
||||||
|
(r5rs-let ((v i:undefined) ...) ; (*)
|
||||||
|
(i:let "wraprec" ((v t) ...) body cwv ...)))
|
||||||
|
|
||||||
|
; (i:let "wraprec" ((v t) ...) body cwv ...)
|
||||||
|
; generate the inner code for a letrec. The variables v ...
|
||||||
|
; are the user-visible variables (bound outside), and t ...
|
||||||
|
; are the temporary variables bound by the cwv consumers.
|
||||||
|
|
||||||
|
((i:let "wraprec" ((v t) ...) (body ...))
|
||||||
|
(begin (set! v t) ... (r5rs-let () body ...)))
|
||||||
|
((i:let "wraprec" vxs body (x formals) cwv ...)
|
||||||
|
(call-with-values
|
||||||
|
(lambda () x)
|
||||||
|
(lambda formals (i:let "wraprec" vxs body cwv ...))))
|
||||||
|
|
||||||
|
))
|
||||||
|
|
||||||
|
(define-syntax i:named-let
|
||||||
|
(syntax-rules (values)
|
||||||
|
|
||||||
|
; (i:named-let tag (vx ...) body (bs ...))
|
||||||
|
; processes the binding specs bs ... by extracting the variable
|
||||||
|
; and expression, adding them to vx and turning the result into
|
||||||
|
; an ordinary named let.
|
||||||
|
|
||||||
|
((i:named-let tag vxs body ())
|
||||||
|
(r5rs-let tag vxs . body))
|
||||||
|
((i:named-let tag (vx ...) body (((values v) x) bs ...))
|
||||||
|
(i:named-let tag (vx ... (v x)) body (bs ...)))
|
||||||
|
((i:named-let tag (vx ...) body ((v x) bs ...))
|
||||||
|
(i:named-let tag (vx ... (v x)) body (bs ...)))))
|
||||||
|
|
||||||
|
; --- standard procedures ---
|
||||||
|
|
||||||
|
(define (uncons pair)
|
||||||
|
(values (car pair) (cdr pair)))
|
||||||
|
|
||||||
|
(define (uncons-2 list)
|
||||||
|
(values (car list) (cadr list) (cddr list)))
|
||||||
|
|
||||||
|
(define (uncons-3 list)
|
||||||
|
(values (car list) (cadr list) (caddr list) (cdddr list)))
|
||||||
|
|
||||||
|
(define (uncons-4 list)
|
||||||
|
(values (car list) (cadr list) (caddr list) (cadddr list) (cddddr list)))
|
||||||
|
|
||||||
|
(define (uncons-cons alist)
|
||||||
|
(values (caar alist) (cdar alist) (cdr alist)))
|
||||||
|
|
||||||
|
(define (unlist list)
|
||||||
|
(apply values list))
|
||||||
|
|
||||||
|
(define (unvector vector)
|
||||||
|
(apply values (vector->list vector)))
|
||||||
|
|
||||||
|
; --- standard macros ---
|
||||||
|
|
||||||
|
(define-syntax values->list
|
||||||
|
(syntax-rules ()
|
||||||
|
((values->list x)
|
||||||
|
(call-with-values (lambda () x) list))))
|
||||||
|
|
||||||
|
(define-syntax values->vector
|
||||||
|
(syntax-rules ()
|
||||||
|
((values->vector x)
|
||||||
|
(call-with-values (lambda () x) vector))))
|
||||||
|
|
||||||
|
; --- textual copy of 'letvalues.scm' ends here ---
|
|
@ -1,6 +1,6 @@
|
||||||
;;; User interface messages
|
;;; User interface messages
|
||||||
|
|
||||||
;; Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
;; Copyright (C) 2009, 2010, 2011, 2012, 2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;;; This library is free software; you can redistribute it and/or
|
;;; This library is free software; you can redistribute it and/or
|
||||||
;;; modify it under the terms of the GNU Lesser General Public
|
;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -109,6 +109,13 @@
|
||||||
(emit port "~A: warning: possibly unused local top-level variable `~A'~%"
|
(emit port "~A: warning: possibly unused local top-level variable `~A'~%"
|
||||||
loc name)))
|
loc name)))
|
||||||
|
|
||||||
|
(shadowed-toplevel
|
||||||
|
"report shadowed top-level variables"
|
||||||
|
,(lambda (port loc name previous-loc)
|
||||||
|
(emit port "~A: warning: shadows previous definition of `~A' at ~A~%"
|
||||||
|
loc name
|
||||||
|
(location-string previous-loc))))
|
||||||
|
|
||||||
(unbound-variable
|
(unbound-variable
|
||||||
"report possibly unbound variables"
|
"report possibly unbound variables"
|
||||||
,(lambda (port loc name)
|
,(lambda (port loc name)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; Compilation targets
|
;;; Compilation targets
|
||||||
|
|
||||||
;; Copyright (C) 2011, 2012, 2013, 2014, 2017 Free Software Foundation, Inc.
|
;; Copyright (C) 2011-2014,2017-2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;; This library is free software; you can redistribute it and/or
|
;; This library is free software; you can redistribute it and/or
|
||||||
;; modify it under the terms of the GNU Lesser General Public
|
;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
(define-module (system base target)
|
(define-module (system base target)
|
||||||
#:use-module (rnrs bytevectors)
|
#:use-module (rnrs bytevectors)
|
||||||
#:use-module (ice-9 regex)
|
#:use-module (ice-9 regex)
|
||||||
#:export (target-type with-target
|
#:export (target-type with-target with-native-target
|
||||||
|
|
||||||
target-cpu target-vendor target-os
|
target-cpu target-vendor target-os
|
||||||
|
|
||||||
|
@ -64,6 +64,12 @@
|
||||||
(%target-word-size (triplet-pointer-size target)))
|
(%target-word-size (triplet-pointer-size target)))
|
||||||
(thunk))))
|
(thunk))))
|
||||||
|
|
||||||
|
(define (with-native-target thunk)
|
||||||
|
(with-fluids ((%target-type %host-type)
|
||||||
|
(%target-endianness (native-endianness))
|
||||||
|
(%target-word-size %native-word-size))
|
||||||
|
(thunk)))
|
||||||
|
|
||||||
(define (cpu-endianness cpu)
|
(define (cpu-endianness cpu)
|
||||||
"Return the endianness for CPU."
|
"Return the endianness for CPU."
|
||||||
(if (string=? cpu (triplet-cpu %host-type))
|
(if (string=? cpu (triplet-cpu %host-type))
|
||||||
|
@ -86,6 +92,8 @@
|
||||||
(endianness big))
|
(endianness big))
|
||||||
((string=? "aarch64" cpu)
|
((string=? "aarch64" cpu)
|
||||||
(endianness little))
|
(endianness little))
|
||||||
|
((string-match "riscv[1-9][0-9]*" cpu)
|
||||||
|
(endianness little))
|
||||||
(else
|
(else
|
||||||
(error "unknown CPU endianness" cpu)))))
|
(error "unknown CPU endianness" cpu)))))
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
memory-backend?
|
memory-backend?
|
||||||
(peek memory-backend-peek)
|
(peek memory-backend-peek)
|
||||||
(open memory-backend-open)
|
(open memory-backend-open)
|
||||||
(type-name memory-backend-type-name)) ; for SMOBs and ports
|
(type-name memory-backend-type-name)) ;for SMOBs
|
||||||
|
|
||||||
(define %ffi-memory-backend
|
(define %ffi-memory-backend
|
||||||
;; The FFI back-end to access the current process's memory. The main
|
;; The FFI back-end to access the current process's memory. The main
|
||||||
|
@ -133,6 +133,18 @@ SIZE is omitted, return an unbounded port to the memory at ADDRESS."
|
||||||
(let ((bv (get-bytevector-n port %word-size)))
|
(let ((bv (get-bytevector-n port %word-size)))
|
||||||
(bytevector-uint-ref bv 0 (native-endianness) %word-size)))
|
(bytevector-uint-ref bv 0 (native-endianness) %word-size)))
|
||||||
|
|
||||||
|
(define (read-c-string backend address)
|
||||||
|
"Read a NUL-terminated string from ADDRESS, decode it as UTF-8, and
|
||||||
|
return the corresponding string."
|
||||||
|
(define port
|
||||||
|
(memory-port backend address))
|
||||||
|
|
||||||
|
(let loop ((bytes '()))
|
||||||
|
(let ((byte (get-u8 port)))
|
||||||
|
(if (zero? byte)
|
||||||
|
(utf8->string (u8-list->bytevector (reverse bytes)))
|
||||||
|
(loop (cons byte bytes))))))
|
||||||
|
|
||||||
(define-inlinable (type-number->name backend kind number)
|
(define-inlinable (type-number->name backend kind number)
|
||||||
"Return the name of the type NUMBER of KIND, where KIND is one of
|
"Return the name of the type NUMBER of KIND, where KIND is one of
|
||||||
'smob or 'port, or #f if the information is unavailable."
|
'smob or 'port, or #f if the information is unavailable."
|
||||||
|
@ -308,12 +320,24 @@ TYPE-NUMBER."
|
||||||
type-number)
|
type-number)
|
||||||
address))
|
address))
|
||||||
|
|
||||||
|
(define (inferior-port-type backend address)
|
||||||
|
"Return an object representing the 'scm_t_port_type' structure at
|
||||||
|
ADDRESS."
|
||||||
|
(inferior-object 'port-type
|
||||||
|
;; The 'name' field lives at offset 0.
|
||||||
|
(let ((name (dereference-word backend address)))
|
||||||
|
(if (zero? name)
|
||||||
|
"(nameless)"
|
||||||
|
(read-c-string backend name)))
|
||||||
|
address))
|
||||||
|
|
||||||
(define (inferior-port backend type-number address)
|
(define (inferior-port backend type-number address)
|
||||||
"Return an object representing the port at ADDRESS whose type is
|
"Return an object representing the port at ADDRESS whose type is
|
||||||
TYPE-NUMBER."
|
TYPE-NUMBER."
|
||||||
(inferior-object 'port
|
(inferior-object 'port
|
||||||
(or (type-number->name backend 'port type-number)
|
(let ((address (+ address (* 3 %word-size))))
|
||||||
type-number)
|
(inferior-port-type backend
|
||||||
|
(dereference-word backend address)))
|
||||||
address))
|
address))
|
||||||
|
|
||||||
(define %visited-cells
|
(define %visited-cells
|
||||||
|
@ -412,8 +436,8 @@ using BACKEND."
|
||||||
(inferior-object 'fluid address))
|
(inferior-object 'fluid address))
|
||||||
(((_ & #x7f = %tc7-dynamic-state))
|
(((_ & #x7f = %tc7-dynamic-state))
|
||||||
(inferior-object 'dynamic-state address))
|
(inferior-object 'dynamic-state address))
|
||||||
((((flags+type << 8) || %tc7-port))
|
((((flags << 8) || %tc7-port))
|
||||||
(inferior-port backend (logand flags+type #xff) address))
|
(inferior-port backend (logand flags #xff) address))
|
||||||
(((_ & #x7f = %tc7-program))
|
(((_ & #x7f = %tc7-program))
|
||||||
(inferior-object 'program address))
|
(inferior-object 'program address))
|
||||||
(((_ & #xffff = %tc16-bignum))
|
(((_ & #xffff = %tc16-bignum))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; Guile ELF linker
|
;;; Guile ELF linker
|
||||||
|
|
||||||
;; Copyright (C) 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
|
;; Copyright (C) 2011, 2012, 2013, 2014, 2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -478,8 +478,8 @@ section index."
|
||||||
(bv (linker-object-bv object))
|
(bv (linker-object-bv object))
|
||||||
(name (elf-section-name section)))
|
(name (elf-section-name section)))
|
||||||
(and (= (elf-section-type section) SHT_STRTAB)
|
(and (= (elf-section-type section) SHT_STRTAB)
|
||||||
(equal? (false-if-exception (string-table-ref bv name))
|
(< name (bytevector-length bv))
|
||||||
".shstrtab")
|
(string=? (string-table-ref bv name) ".shstrtab")
|
||||||
(elf-section-index section))))
|
(elf-section-index section))))
|
||||||
objects))
|
objects))
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; Web client
|
;;; Web client
|
||||||
|
|
||||||
;; Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2017 Free Software Foundation, Inc.
|
;; Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;; This library is free software; you can redistribute it and/or
|
;; This library is free software; you can redistribute it and/or
|
||||||
;; modify it under the terms of the GNU Lesser General Public
|
;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -47,6 +47,7 @@
|
||||||
#:prefix rnrs-ports:)
|
#:prefix rnrs-ports:)
|
||||||
#:export (current-http-proxy
|
#:export (current-http-proxy
|
||||||
open-socket-for-uri
|
open-socket-for-uri
|
||||||
|
http-request
|
||||||
http-get
|
http-get
|
||||||
http-head
|
http-head
|
||||||
http-post
|
http-post
|
||||||
|
@ -331,25 +332,50 @@ as is the case by default with a request returned by `build-request'."
|
||||||
(else
|
(else
|
||||||
(error "unexpected body type" body))))
|
(error "unexpected body type" body))))
|
||||||
|
|
||||||
;; We could expose this to user code if there is demand.
|
(define* (http-request uri #:key
|
||||||
(define* (request uri #:key
|
(body #f)
|
||||||
(body #f)
|
(port (open-socket-for-uri uri))
|
||||||
(port (open-socket-for-uri uri))
|
(method 'GET)
|
||||||
(method 'GET)
|
(version '(1 . 1))
|
||||||
(version '(1 . 1))
|
(keep-alive? #f)
|
||||||
(keep-alive? #f)
|
(headers '())
|
||||||
(headers '())
|
(decode-body? #t)
|
||||||
(decode-body? #t)
|
(streaming? #f)
|
||||||
(streaming? #f)
|
(request
|
||||||
(request
|
(build-request
|
||||||
(build-request
|
(ensure-uri-reference uri)
|
||||||
(ensure-uri-reference uri)
|
#:method method
|
||||||
#:method method
|
#:version version
|
||||||
#:version version
|
#:headers (if keep-alive?
|
||||||
#:headers (if keep-alive?
|
headers
|
||||||
headers
|
(cons '(connection close) headers))
|
||||||
(cons '(connection close) headers))
|
#:port port)))
|
||||||
#:port port)))
|
"Connect to the server corresponding to URI and ask for the resource,
|
||||||
|
using METHOD, defaulting to ‘GET’. If you already have a port open,
|
||||||
|
pass it as PORT. The port will be closed at the end of the request
|
||||||
|
unless KEEP-ALIVE? is true. Any extra headers in the alist HEADERS will
|
||||||
|
be added to the request.
|
||||||
|
|
||||||
|
If BODY is not ‘#f’, a message body will also be sent with the HTTP
|
||||||
|
request. If BODY is a string, it is encoded according to the
|
||||||
|
content-type in HEADERS, defaulting to UTF-8. Otherwise BODY should be
|
||||||
|
a bytevector, or ‘#f’ for no body. Although it's allowed to send a
|
||||||
|
message body along with any request, usually only POST and PUT requests
|
||||||
|
have bodies. See ‘http-put’ and ‘http-post’ documentation, for more.
|
||||||
|
|
||||||
|
If DECODE-BODY? is true, as is the default, the body of the
|
||||||
|
response will be decoded to string, if it is a textual content-type.
|
||||||
|
Otherwise it will be returned as a bytevector.
|
||||||
|
|
||||||
|
However, if STREAMING? is true, instead of eagerly reading the response
|
||||||
|
body from the server, this function only reads off the headers. The
|
||||||
|
response body will be returned as a port on which the data may be read.
|
||||||
|
Unless KEEP-ALIVE? is true, the port will be closed after the full
|
||||||
|
response body has been read.
|
||||||
|
|
||||||
|
Returns two values: the response read from the server, and the response
|
||||||
|
body as a string, bytevector, #f value, or as a port (if STREAMING? is
|
||||||
|
true)."
|
||||||
(call-with-values (lambda () (sanitize-request request body))
|
(call-with-values (lambda () (sanitize-request request body))
|
||||||
(lambda (request body)
|
(lambda (request body)
|
||||||
(let ((request (write-request request port)))
|
(let ((request (write-request request port)))
|
||||||
|
@ -376,42 +402,6 @@ as is the case by default with a request returned by `build-request'."
|
||||||
(decode-response-body response body)
|
(decode-response-body response body)
|
||||||
body))))))))))
|
body))))))))))
|
||||||
|
|
||||||
(define* (http-get uri #:key
|
|
||||||
(body #f)
|
|
||||||
(port (open-socket-for-uri uri))
|
|
||||||
(version '(1 . 1)) (keep-alive? #f)
|
|
||||||
(headers '()) (decode-body? #t) (streaming? #f))
|
|
||||||
"Connect to the server corresponding to URI and ask for the
|
|
||||||
resource, using the ‘GET’ method. If you already have a port open,
|
|
||||||
pass it as PORT. The port will be closed at the end of the
|
|
||||||
request unless KEEP-ALIVE? is true. Any extra headers in the
|
|
||||||
alist HEADERS will be added to the request.
|
|
||||||
|
|
||||||
If BODY is not ‘#f’, a message body will also be sent with the HTTP
|
|
||||||
request. If BODY is a string, it is encoded according to the
|
|
||||||
content-type in HEADERS, defaulting to UTF-8. Otherwise BODY should be
|
|
||||||
a bytevector, or ‘#f’ for no body. Although it's allowed to send a
|
|
||||||
message body along with any request, usually only POST and PUT requests
|
|
||||||
have bodies. See ‘http-put’ and ‘http-post’ documentation, for more.
|
|
||||||
|
|
||||||
If DECODE-BODY? is true, as is the default, the body of the
|
|
||||||
response will be decoded to string, if it is a textual content-type.
|
|
||||||
Otherwise it will be returned as a bytevector.
|
|
||||||
|
|
||||||
However, if STREAMING? is true, instead of eagerly reading the response
|
|
||||||
body from the server, this function only reads off the headers. The
|
|
||||||
response body will be returned as a port on which the data may be read.
|
|
||||||
Unless KEEP-ALIVE? is true, the port will be closed after the full
|
|
||||||
response body has been read.
|
|
||||||
|
|
||||||
Returns two values: the response read from the server, and the response
|
|
||||||
body as a string, bytevector, #f value, or as a port (if STREAMING? is
|
|
||||||
true)."
|
|
||||||
(request uri #:method 'GET #:body body
|
|
||||||
#:port port #:version version #:keep-alive? keep-alive?
|
|
||||||
#:headers headers #:decode-body? decode-body?
|
|
||||||
#:streaming? streaming?))
|
|
||||||
|
|
||||||
(define-syntax-rule (define-http-verb http-verb method doc)
|
(define-syntax-rule (define-http-verb http-verb method doc)
|
||||||
(define* (http-verb uri #:key
|
(define* (http-verb uri #:key
|
||||||
(body #f)
|
(body #f)
|
||||||
|
@ -422,20 +412,31 @@ true)."
|
||||||
(decode-body? #t)
|
(decode-body? #t)
|
||||||
(streaming? #f))
|
(streaming? #f))
|
||||||
doc
|
doc
|
||||||
(request uri
|
(http-request uri
|
||||||
#:body body #:method method
|
#:body body #:method method
|
||||||
#:port port #:version version #:keep-alive? keep-alive?
|
#:port port #:version version #:keep-alive? keep-alive?
|
||||||
#:headers headers #:decode-body? decode-body?
|
#:headers headers #:decode-body? decode-body?
|
||||||
#:streaming? streaming?)))
|
#:streaming? streaming?)))
|
||||||
|
|
||||||
|
(define-http-verb http-get
|
||||||
|
'GET
|
||||||
|
"Fetch message headers for the given URI using the HTTP \"GET\"
|
||||||
|
method.
|
||||||
|
|
||||||
|
This function invokes ‘http-request’, with the \"GET\" method. See
|
||||||
|
‘http-request’ for full documentation on the various keyword arguments
|
||||||
|
that are accepted by this function.
|
||||||
|
|
||||||
|
Returns two values: the resulting response, and the response body.")
|
||||||
|
|
||||||
(define-http-verb http-head
|
(define-http-verb http-head
|
||||||
'HEAD
|
'HEAD
|
||||||
"Fetch message headers for the given URI using the HTTP \"HEAD\"
|
"Fetch message headers for the given URI using the HTTP \"HEAD\"
|
||||||
method.
|
method.
|
||||||
|
|
||||||
This function is similar to ‘http-get’, except it uses the \"HEAD\"
|
This function invokes ‘http-request’, with the \"HEAD\" method. See
|
||||||
method. See ‘http-get’ for full documentation on the various keyword
|
‘http-request’ for full documentation on the various keyword arguments
|
||||||
arguments that are accepted by this function.
|
that are accepted by this function.
|
||||||
|
|
||||||
Returns two values: the resulting response, and ‘#f’. Responses to HEAD
|
Returns two values: the resulting response, and ‘#f’. Responses to HEAD
|
||||||
requests do not have a body. The second value is only returned so that
|
requests do not have a body. The second value is only returned so that
|
||||||
|
@ -445,9 +446,9 @@ other procedures can treat all of the http-foo verbs identically.")
|
||||||
'POST
|
'POST
|
||||||
"Post data to the given URI using the HTTP \"POST\" method.
|
"Post data to the given URI using the HTTP \"POST\" method.
|
||||||
|
|
||||||
This function is similar to ‘http-get’, except it uses the \"POST\"
|
This function invokes ‘http-request’, with the \"POST\" method. See
|
||||||
method. See ‘http-get’ for full documentation on the various keyword
|
‘http-request’ for full documentation on the various keyword arguments
|
||||||
arguments that are accepted by this function.
|
that are accepted by this function.
|
||||||
|
|
||||||
Returns two values: the resulting response, and the response body.")
|
Returns two values: the resulting response, and the response body.")
|
||||||
|
|
||||||
|
@ -455,9 +456,9 @@ Returns two values: the resulting response, and the response body.")
|
||||||
'PUT
|
'PUT
|
||||||
"Put data at the given URI using the HTTP \"PUT\" method.
|
"Put data at the given URI using the HTTP \"PUT\" method.
|
||||||
|
|
||||||
This function is similar to ‘http-get’, except it uses the \"PUT\"
|
This function invokes ‘http-request’, with the \"PUT\" method. See
|
||||||
method. See ‘http-get’ for full documentation on the various keyword
|
‘http-request’ for full documentation on the various keyword arguments
|
||||||
arguments that are accepted by this function.
|
that are accepted by this function.
|
||||||
|
|
||||||
Returns two values: the resulting response, and the response body.")
|
Returns two values: the resulting response, and the response body.")
|
||||||
|
|
||||||
|
@ -465,9 +466,9 @@ Returns two values: the resulting response, and the response body.")
|
||||||
'DELETE
|
'DELETE
|
||||||
"Delete data at the given URI using the HTTP \"DELETE\" method.
|
"Delete data at the given URI using the HTTP \"DELETE\" method.
|
||||||
|
|
||||||
This function is similar to ‘http-get’, except it uses the \"DELETE\"
|
This function invokes ‘http-request’, with the \"DELETE\" method. See
|
||||||
method. See ‘http-get’ for full documentation on the various keyword
|
‘http-request’ for full documentation on the various keyword arguments
|
||||||
arguments that are accepted by this function.
|
that are accepted by this function.
|
||||||
|
|
||||||
Returns two values: the resulting response, and the response body.")
|
Returns two values: the resulting response, and the response body.")
|
||||||
|
|
||||||
|
@ -475,9 +476,9 @@ Returns two values: the resulting response, and the response body.")
|
||||||
'TRACE
|
'TRACE
|
||||||
"Send an HTTP \"TRACE\" request.
|
"Send an HTTP \"TRACE\" request.
|
||||||
|
|
||||||
This function is similar to ‘http-get’, except it uses the \"TRACE\"
|
This function invokes ‘http-request’, with the \"TRACE\" method. See
|
||||||
method. See ‘http-get’ for full documentation on the various keyword
|
‘http-request’ for full documentation on the various keyword arguments
|
||||||
arguments that are accepted by this function.
|
that are accepted by this function.
|
||||||
|
|
||||||
Returns two values: the resulting response, and the response body.")
|
Returns two values: the resulting response, and the response body.")
|
||||||
|
|
||||||
|
@ -486,8 +487,8 @@ Returns two values: the resulting response, and the response body.")
|
||||||
"Query characteristics of an HTTP resource using the HTTP \"OPTIONS\"
|
"Query characteristics of an HTTP resource using the HTTP \"OPTIONS\"
|
||||||
method.
|
method.
|
||||||
|
|
||||||
This function is similar to ‘http-get’, except it uses the \"OPTIONS\"
|
This function invokes ‘http-request’, with the \"OPTIONS\" method. See
|
||||||
method. See ‘http-get’ for full documentation on the various keyword
|
‘http-request’ for full documentation on the various keyword arguments
|
||||||
arguments that are accepted by this function.
|
that are accepted by this function.
|
||||||
|
|
||||||
Returns two values: the resulting response, and the response body.")
|
Returns two values: the resulting response, and the response body.")
|
||||||
|
|
|
@ -156,6 +156,7 @@ SCM_TESTS = tests/00-initial-env.test \
|
||||||
tests/srfi-64.test \
|
tests/srfi-64.test \
|
||||||
tests/srfi-67.test \
|
tests/srfi-67.test \
|
||||||
tests/srfi-69.test \
|
tests/srfi-69.test \
|
||||||
|
tests/srfi-71.test \
|
||||||
tests/srfi-88.test \
|
tests/srfi-88.test \
|
||||||
tests/srfi-98.test \
|
tests/srfi-98.test \
|
||||||
tests/srfi-105.test \
|
tests/srfi-105.test \
|
||||||
|
@ -189,6 +190,7 @@ SCM_TESTS = tests/00-initial-env.test \
|
||||||
tests/version.test \
|
tests/version.test \
|
||||||
tests/vectors.test \
|
tests/vectors.test \
|
||||||
tests/vlist.test \
|
tests/vlist.test \
|
||||||
|
tests/vm.test \
|
||||||
tests/weaks.test \
|
tests/weaks.test \
|
||||||
tests/web-client.test \
|
tests/web-client.test \
|
||||||
tests/web-http.test \
|
tests/web-http.test \
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
;;;; i18n.test --- Exercise the i18n API. -*- coding: utf-8; mode: scheme; -*-
|
;;;; i18n.test --- Exercise the i18n API. -*- coding: utf-8; mode: scheme; -*-
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012,
|
;;;; Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012,
|
||||||
;;;; 2013, 2014, 2015, 2016, 2017 Free Software Foundation, Inc.
|
;;;; 2013, 2014, 2015, 2016, 2017, 2018 Free Software Foundation, Inc.
|
||||||
;;;; Ludovic Courtès
|
;;;; Ludovic Courtès
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
|
@ -562,6 +562,19 @@
|
||||||
;;; Numbers.
|
;;; Numbers.
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
|
(define (french-number-string=? expected result)
|
||||||
|
;; Return true if RESULT is equal to EXPECTED, modulo white space.
|
||||||
|
;; This is meant to deal with French locales: glibc 2.27+ uses
|
||||||
|
;; NO-BREAK SPACE to separate 3-digit groups, whereas earlier versions
|
||||||
|
;; used SPACE.
|
||||||
|
(or (string=? expected result)
|
||||||
|
(string=? (string-map (lambda (chr)
|
||||||
|
(case chr
|
||||||
|
((#\space) #\240)
|
||||||
|
(else chr))) ;NO-BREAK SPACE
|
||||||
|
expected)
|
||||||
|
result)))
|
||||||
|
|
||||||
(with-test-prefix "number->locale-string"
|
(with-test-prefix "number->locale-string"
|
||||||
|
|
||||||
;; We assume the global locale is "C" at this point.
|
;; We assume the global locale is "C" at this point.
|
||||||
|
@ -600,33 +613,33 @@
|
||||||
|
|
||||||
(with-test-prefix "French"
|
(with-test-prefix "French"
|
||||||
|
|
||||||
(pass-if-equal "integer"
|
(pass-if "integer"
|
||||||
"123 456"
|
|
||||||
(under-french-locale-or-unresolved
|
(under-french-locale-or-unresolved
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(let ((fr (make-locale LC_ALL %french-locale-name)))
|
(let ((fr (make-locale LC_ALL %french-locale-name)))
|
||||||
(number->locale-string 123456 #t fr)))))
|
(french-number-string=? "123 456"
|
||||||
|
(number->locale-string 123456 #t fr))))))
|
||||||
|
|
||||||
(pass-if-equal "negative integer"
|
(pass-if "negative integer"
|
||||||
"-1 234 567"
|
|
||||||
(under-french-locale-or-unresolved
|
(under-french-locale-or-unresolved
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(let ((fr (make-locale LC_ALL %french-locale-name)))
|
(let ((fr (make-locale LC_ALL %french-locale-name)))
|
||||||
(number->locale-string -1234567 #t fr)))))
|
(french-number-string=? "-1 234 567"
|
||||||
|
(number->locale-string -1234567 #t fr))))))
|
||||||
|
|
||||||
(pass-if-equal "fraction"
|
(pass-if "fraction"
|
||||||
"1 234,567"
|
|
||||||
(under-french-locale-or-unresolved
|
(under-french-locale-or-unresolved
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(let ((fr (make-locale LC_ALL %french-locale-name)))
|
(let ((fr (make-locale LC_ALL %french-locale-name)))
|
||||||
(number->locale-string 1234.567 #t fr)))))
|
(french-number-string=? "1 234,567"
|
||||||
|
(number->locale-string 1234.567 #t fr))))))
|
||||||
|
|
||||||
(pass-if-equal "fraction, 1 digit"
|
(pass-if "fraction, 1 digit"
|
||||||
"1 234,6"
|
|
||||||
(under-french-locale-or-unresolved
|
(under-french-locale-or-unresolved
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(let ((fr (make-locale LC_ALL %french-locale-name)))
|
(let ((fr (make-locale LC_ALL %french-locale-name)))
|
||||||
(number->locale-string 1234.567 1 fr)))))))
|
(french-number-string=? "1 234,6"
|
||||||
|
(number->locale-string 1234.567 1 fr))))))))
|
||||||
|
|
||||||
(with-test-prefix "format ~h"
|
(with-test-prefix "format ~h"
|
||||||
|
|
||||||
|
@ -636,13 +649,14 @@
|
||||||
|
|
||||||
(with-test-prefix "French"
|
(with-test-prefix "French"
|
||||||
|
|
||||||
(pass-if-equal "12345.678"
|
(pass-if "12345.678"
|
||||||
"12 345,678"
|
|
||||||
(under-french-locale-or-unresolved
|
(under-french-locale-or-unresolved
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(if (null? (locale-digit-grouping %french-locale))
|
(if (null? (locale-digit-grouping %french-locale))
|
||||||
(throw 'unresolved)
|
(throw 'unresolved)
|
||||||
(format #f "~:h" 12345.678 %french-locale))))))
|
(french-number-string=? "12 345,678"
|
||||||
|
(format #f "~:h" 12345.678
|
||||||
|
%french-locale)))))))
|
||||||
|
|
||||||
(with-test-prefix "English"
|
(with-test-prefix "English"
|
||||||
|
|
||||||
|
@ -659,19 +673,23 @@
|
||||||
|
|
||||||
(with-test-prefix "French"
|
(with-test-prefix "French"
|
||||||
|
|
||||||
(pass-if-equal "integer"
|
(pass-if "integer"
|
||||||
"123 456,00 +EUR"
|
|
||||||
(under-french-locale-or-unresolved
|
(under-french-locale-or-unresolved
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(let ((fr (make-locale LC_ALL %french-locale-name)))
|
(let* ((fr (make-locale LC_ALL %french-locale-name))
|
||||||
(monetary-amount->locale-string 123456 #f fr)))))
|
(str (monetary-amount->locale-string 123456 #f fr)))
|
||||||
|
;; Check for both NO-BREAK SPACE and SPACE.
|
||||||
|
(or (string=? "123 456,00 +EUR" str)
|
||||||
|
(string=? "123 456,00 +EUR" str))))))
|
||||||
|
|
||||||
(pass-if-equal "fraction"
|
(pass-if "fraction"
|
||||||
"1 234,57 EUR "
|
|
||||||
(under-french-locale-or-unresolved
|
(under-french-locale-or-unresolved
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(let ((fr (make-locale LC_ALL %french-locale-name)))
|
(let* ((fr (make-locale LC_ALL %french-locale-name))
|
||||||
(monetary-amount->locale-string 1234.567 #t fr)))))
|
(str (monetary-amount->locale-string 1234.567 #t fr)))
|
||||||
|
;; Check for both NO-BREAK SPACE and SPACE.
|
||||||
|
(or (string=? "1 234,57 EUR " str)
|
||||||
|
(string=? "1 234,57 EUR " str))))))
|
||||||
|
|
||||||
(pass-if-equal "positive inexact zero"
|
(pass-if-equal "positive inexact zero"
|
||||||
"0,00 +EUR"
|
"0,00 +EUR"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
;;;; posix.test --- Test suite for Guile POSIX functions. -*- scheme -*-
|
;;;; posix.test --- Test suite for Guile POSIX functions. -*- scheme -*-
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright 2003, 2004, 2006, 2007, 2010, 2012,
|
;;;; Copyright 2003, 2004, 2006, 2007, 2010, 2012,
|
||||||
;;;; 2015 Free Software Foundation, Inc.
|
;;;; 2015, 2017 Free Software Foundation, Inc.
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -222,3 +222,20 @@
|
||||||
(let ((me (getpid)))
|
(let ((me (getpid)))
|
||||||
(and (not (zero? (system* "something-that-does-not-exist")))
|
(and (not (zero? (system* "something-that-does-not-exist")))
|
||||||
(= me (getpid))))))
|
(= me (getpid))))))
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; crypt
|
||||||
|
;;
|
||||||
|
|
||||||
|
(with-test-prefix "crypt"
|
||||||
|
|
||||||
|
(pass-if "basic usage"
|
||||||
|
(string? (crypt "pass" "abcdefg")))
|
||||||
|
|
||||||
|
(pass-if-exception "glibc EINVAL" exception:system-error
|
||||||
|
;; This used to deadlock while trying to throw to 'system-error'.
|
||||||
|
;; This test uses the special interpretation of the salt that glibc
|
||||||
|
;; does; specifically, we pass a syntactically invalid salt here.
|
||||||
|
(if (string-contains %host-type "-gnu")
|
||||||
|
(crypt "pass" "$X$abc") ;EINVAL
|
||||||
|
(throw 'unresolved))))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;;; r6rs-ports.test --- R6RS I/O port tests. -*- coding: utf-8; -*-
|
;;;; r6rs-ports.test --- R6RS I/O port tests. -*- coding: utf-8; -*-
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2009-2012, 2013-2015 Free Software Foundation, Inc.
|
;;;; Copyright (C) 2009-2012, 2013-2015, 2018 Free Software Foundation, Inc.
|
||||||
;;;; Ludovic Courtès
|
;;;; Ludovic Courtès
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
|
@ -498,6 +498,16 @@ not `set-port-position!'"
|
||||||
(u8-list->bytevector
|
(u8-list->bytevector
|
||||||
(map char->integer (string->list "Port!")))))))
|
(map char->integer (string->list "Port!")))))))
|
||||||
|
|
||||||
|
(pass-if-equal "custom binary input port position, long offset"
|
||||||
|
(expt 2 42)
|
||||||
|
;; In Guile <= 2.2.4, 'seek' would throw to 'out-of-range'.
|
||||||
|
(let* ((port (make-custom-binary-input-port "the port"
|
||||||
|
(const 0)
|
||||||
|
(const (expt 2 42))
|
||||||
|
#f #f)))
|
||||||
|
(port-position port)))
|
||||||
|
|
||||||
|
|
||||||
(pass-if-equal "custom binary input port buffered partial reads"
|
(pass-if-equal "custom binary input port buffered partial reads"
|
||||||
"Hello Port!"
|
"Hello Port!"
|
||||||
;; Check what happens when READ! returns less than COUNT bytes.
|
;; Check what happens when READ! returns less than COUNT bytes.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
;;;; srfi-18.test --- Test suite for Guile's SRFI-18 functions. -*- scheme -*-
|
;;;; srfi-18.test --- Test suite for Guile's SRFI-18 functions. -*- scheme -*-
|
||||||
;;;; Julian Graham, 2007-10-26
|
;;;; Julian Graham, 2007-10-26
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2007, 2008, 2012 Free Software Foundation, Inc.
|
;;;; Copyright (C) 2007, 2008, 2012, 2018 Free Software Foundation, Inc.
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -94,13 +94,12 @@
|
||||||
(unspecified? (thread-sleep! future-time))))
|
(unspecified? (thread-sleep! future-time))))
|
||||||
|
|
||||||
(pass-if "thread sleep with number"
|
(pass-if "thread sleep with number"
|
||||||
(let ((old-secs (car (current-time))))
|
(unspecified? (thread-sleep! 0)))
|
||||||
(unspecified? (thread-sleep! (+ (time->seconds (current-time)))))))
|
|
||||||
|
|
||||||
(pass-if "thread sleeps fractions of a second"
|
(pass-if "thread sleeps fractions of a second"
|
||||||
(let* ((current (time->seconds (current-time)))
|
(let* ((current (time->seconds (current-time)))
|
||||||
(future (+ current 0.5)))
|
(future (+ current 0.5)))
|
||||||
(thread-sleep! future)
|
(thread-sleep! 0.5)
|
||||||
(>= (time->seconds (current-time)) future)))
|
(>= (time->seconds (current-time)) future)))
|
||||||
|
|
||||||
(pass-if "thread does not sleep on past time"
|
(pass-if "thread does not sleep on past time"
|
||||||
|
@ -233,7 +232,7 @@
|
||||||
|
|
||||||
(pass-if "mutex-lock! returns false on timeout"
|
(pass-if "mutex-lock! returns false on timeout"
|
||||||
(let* ((m (make-mutex 'mutex-lock-2))
|
(let* ((m (make-mutex 'mutex-lock-2))
|
||||||
(t (make-thread (lambda () (mutex-lock! m (current-time) #f)))))
|
(t (make-thread (lambda () (mutex-lock! m 0 #f)))))
|
||||||
(mutex-lock! m)
|
(mutex-lock! m)
|
||||||
(thread-start! t)
|
(thread-start! t)
|
||||||
(not (thread-join! t))))
|
(not (thread-join! t))))
|
||||||
|
@ -241,9 +240,7 @@
|
||||||
(pass-if "mutex-lock! returns true when lock obtained within timeout"
|
(pass-if "mutex-lock! returns true when lock obtained within timeout"
|
||||||
(let* ((m (make-mutex 'mutex-lock-3))
|
(let* ((m (make-mutex 'mutex-lock-3))
|
||||||
(t (make-thread (lambda ()
|
(t (make-thread (lambda ()
|
||||||
(mutex-lock! m (+ (time->seconds (current-time))
|
(mutex-lock! m 100 #f)))))
|
||||||
100)
|
|
||||||
#f)))))
|
|
||||||
(mutex-lock! m)
|
(mutex-lock! m)
|
||||||
(thread-start! t)
|
(thread-start! t)
|
||||||
(mutex-unlock! m)
|
(mutex-unlock! m)
|
||||||
|
@ -306,8 +303,7 @@
|
||||||
(let* ((m (make-mutex 'mutex-unlock-2))
|
(let* ((m (make-mutex 'mutex-unlock-2))
|
||||||
(t (make-thread (lambda ()
|
(t (make-thread (lambda ()
|
||||||
(mutex-lock! m)
|
(mutex-lock! m)
|
||||||
(let ((now (time->seconds (current-time))))
|
(mutex-lock! m 0.1)
|
||||||
(mutex-lock! m (+ now 0.1)))
|
|
||||||
(mutex-unlock! m))
|
(mutex-unlock! m))
|
||||||
'mutex-unlock-2)))
|
'mutex-unlock-2)))
|
||||||
(thread-start! t)
|
(thread-start! t)
|
||||||
|
@ -352,7 +348,7 @@
|
||||||
(let* ((m (make-mutex 'mutex-unlock-4))
|
(let* ((m (make-mutex 'mutex-unlock-4))
|
||||||
(c (make-condition-variable 'mutex-unlock-4)))
|
(c (make-condition-variable 'mutex-unlock-4)))
|
||||||
(mutex-lock! m)
|
(mutex-lock! m)
|
||||||
(not (mutex-unlock! m c (+ (time->seconds (current-time)) 1))))))
|
(not (mutex-unlock! m c 1)))))
|
||||||
|
|
||||||
(with-test-prefix "condition-variable?"
|
(with-test-prefix "condition-variable?"
|
||||||
|
|
||||||
|
|
46
test-suite/tests/srfi-71.test
Normal file
46
test-suite/tests/srfi-71.test
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
;;;; srfi-71.test --- Extended 'let' syntax. -*- mode: scheme; -*-
|
||||||
|
;;;;
|
||||||
|
;;;; Copyright (C) 2018 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 the License, or (at your option) any later version.
|
||||||
|
;;;;
|
||||||
|
;;;; This library is distributed in the hope that it will be useful,
|
||||||
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
;;;; Lesser General Public License for more details.
|
||||||
|
;;;;
|
||||||
|
;;;; You should have received a copy of the GNU Lesser General Public
|
||||||
|
;;;; License along with this library; if not, write to the Free Software
|
||||||
|
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
(define-module (test-suite i18n)
|
||||||
|
#:use-module (srfi srfi-71)
|
||||||
|
#:use-module (test-suite lib))
|
||||||
|
|
||||||
|
(pass-if-equal "let"
|
||||||
|
'(1 2 3)
|
||||||
|
(let ((x y z (values 1 2 3)))
|
||||||
|
(list x y z)))
|
||||||
|
|
||||||
|
(pass-if-equal "let*"
|
||||||
|
6
|
||||||
|
(let* ((x y (values 1 2))
|
||||||
|
(z (+ x y)))
|
||||||
|
(* z 2)))
|
||||||
|
|
||||||
|
(pass-if-equal "letrec"
|
||||||
|
#t
|
||||||
|
(letrec ((odd? even?
|
||||||
|
(values (lambda (n) (even? (- n 1)))
|
||||||
|
(lambda (n) (or (zero? n) (odd? (- n 1)))))))
|
||||||
|
(and (odd? 77) (even? 42))))
|
||||||
|
|
||||||
|
(pass-if-exception "too few values"
|
||||||
|
exception:wrong-num-args
|
||||||
|
;; With compiled code we would get:
|
||||||
|
;; '(vm-error . "Wrong number of values returned to continuations")
|
||||||
|
(let ((x y 1))
|
||||||
|
(+ x y)))
|
|
@ -1,7 +1,7 @@
|
||||||
;;;; tree-il.test --- test suite for compiling tree-il -*- scheme -*-
|
;;;; tree-il.test --- test suite for compiling tree-il -*- scheme -*-
|
||||||
;;;; Andy Wingo <wingo@pobox.com> --- May 2009
|
;;;; Andy Wingo <wingo@pobox.com> --- May 2009
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
|
;;;; Copyright (C) 2009-2014, 2018 Free Software Foundation, Inc.
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
#:use-module (system base message)
|
#:use-module (system base message)
|
||||||
#:use-module (language tree-il)
|
#:use-module (language tree-il)
|
||||||
#:use-module (language tree-il primitives)
|
#:use-module (language tree-il primitives)
|
||||||
|
#:use-module (ice-9 match)
|
||||||
|
#:use-module (ice-9 regex)
|
||||||
#:use-module (srfi srfi-13))
|
#:use-module (srfi srfi-13))
|
||||||
|
|
||||||
(define-syntax-rule (pass-if-primitives-resolved in expected)
|
(define-syntax-rule (pass-if-primitives-resolved in expected)
|
||||||
|
@ -218,6 +220,9 @@
|
||||||
(define %opts-w-unused-toplevel
|
(define %opts-w-unused-toplevel
|
||||||
'(#:warnings (unused-toplevel)))
|
'(#:warnings (unused-toplevel)))
|
||||||
|
|
||||||
|
(define %opts-w-shadowed-toplevel
|
||||||
|
'(#:warnings (shadowed-toplevel)))
|
||||||
|
|
||||||
(define %opts-w-unbound
|
(define %opts-w-unbound
|
||||||
'(#:warnings (unbound-variable)))
|
'(#:warnings (unbound-variable)))
|
||||||
|
|
||||||
|
@ -406,6 +411,83 @@
|
||||||
#:to 'cps
|
#:to 'cps
|
||||||
#:opts %opts-w-unused-toplevel))))))
|
#:opts %opts-w-unused-toplevel))))))
|
||||||
|
|
||||||
|
(with-test-prefix "shadowed-toplevel"
|
||||||
|
|
||||||
|
(pass-if "quiet"
|
||||||
|
(null? (call-with-warnings
|
||||||
|
(lambda ()
|
||||||
|
(let ((in (open-input-string
|
||||||
|
"(define foo 2) (define bar 3)")))
|
||||||
|
(read-and-compile in
|
||||||
|
#:to 'cps
|
||||||
|
#:opts
|
||||||
|
%opts-w-shadowed-toplevel))))))
|
||||||
|
|
||||||
|
(pass-if "internal define"
|
||||||
|
(null? (call-with-warnings
|
||||||
|
(lambda ()
|
||||||
|
(let ((in (open-input-string
|
||||||
|
"(define foo 2)
|
||||||
|
(define (bar x) (define foo (+ x 2)) (* foo x))")))
|
||||||
|
(read-and-compile in
|
||||||
|
#:to 'cps
|
||||||
|
#:opts
|
||||||
|
%opts-w-shadowed-toplevel))))))
|
||||||
|
|
||||||
|
(pass-if "one shadowing definition"
|
||||||
|
(match (call-with-warnings
|
||||||
|
(lambda ()
|
||||||
|
(let ((in (open-input-string
|
||||||
|
"(define foo 2)\n (define foo 3)")))
|
||||||
|
(read-and-compile in
|
||||||
|
#:to 'cps
|
||||||
|
#:opts
|
||||||
|
%opts-w-shadowed-toplevel))))
|
||||||
|
((message)
|
||||||
|
(->bool (string-match ":2:2:.*previous.*foo.*:1:0" message)))))
|
||||||
|
|
||||||
|
(pass-if "two shadowing definitions"
|
||||||
|
(match (call-with-warnings
|
||||||
|
(lambda ()
|
||||||
|
(let ((in (open-input-string
|
||||||
|
"(define-public foo 2)\n(define foo 3)
|
||||||
|
(define (foo x) x)")))
|
||||||
|
(read-and-compile in
|
||||||
|
#:to 'cps
|
||||||
|
#:opts
|
||||||
|
%opts-w-shadowed-toplevel))))
|
||||||
|
((message1 message2)
|
||||||
|
(->bool
|
||||||
|
(and (string-match ":2:0:.*previous.*foo.*:1:0" message1)
|
||||||
|
(string-match ":3:2:.*previous.*foo.*:1:0" message2))))))
|
||||||
|
|
||||||
|
(pass-if "define-public"
|
||||||
|
(match (call-with-warnings
|
||||||
|
(lambda ()
|
||||||
|
(let ((in (open-input-string
|
||||||
|
"(define foo 2)\n(define-public foo 3)")))
|
||||||
|
(read-and-compile in
|
||||||
|
#:to 'cps
|
||||||
|
#:opts
|
||||||
|
%opts-w-shadowed-toplevel))))
|
||||||
|
((message)
|
||||||
|
(->bool (string-match ":2:0:.*previous.*foo.*:1:0" message)))))
|
||||||
|
|
||||||
|
(pass-if "macro"
|
||||||
|
(match (call-with-warnings
|
||||||
|
(lambda ()
|
||||||
|
(let ((in (open-input-string
|
||||||
|
"(define foo 42)
|
||||||
|
(define-syntax-rule (defun proc (args ...) body ...)
|
||||||
|
(define (proc args ...) body ...))
|
||||||
|
(defun foo (a b c) (+ a b c))")))
|
||||||
|
(read-and-compile in
|
||||||
|
#:to 'cps
|
||||||
|
#:opts
|
||||||
|
%opts-w-shadowed-toplevel))))
|
||||||
|
((message)
|
||||||
|
(->bool (string-match ":4:2:.*previous.*foo.*:1:0" message))))))
|
||||||
|
|
||||||
(with-test-prefix "unbound variable"
|
(with-test-prefix "unbound variable"
|
||||||
|
|
||||||
(pass-if "quiet"
|
(pass-if "quiet"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;;; types.test --- Type tag decoding. -*- mode: scheme; coding: utf-8; -*-
|
;;;; types.test --- Type tag decoding. -*- mode: scheme; coding: utf-8; -*-
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2014, 2015 Free Software Foundation, Inc.
|
;;;; Copyright (C) 2014, 2015, 2018 Free Software Foundation, Inc.
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This file is part of GNU Guile.
|
;;;; This file is part of GNU Guile.
|
||||||
;;;;
|
;;;;
|
||||||
|
@ -98,8 +98,8 @@
|
||||||
(with-test-prefix "opaque objects"
|
(with-test-prefix "opaque objects"
|
||||||
(test-inferior-objects
|
(test-inferior-objects
|
||||||
((make-guardian) smob (? integer?))
|
((make-guardian) smob (? integer?))
|
||||||
((%make-void-port "w") port (? integer?))
|
((%make-void-port "w") port (? inferior-object?))
|
||||||
((open-input-string "hello") port (? integer?))
|
((open-input-string "hello") port (? inferior-object?))
|
||||||
((lambda () #t) program _)
|
((lambda () #t) program _)
|
||||||
((make-variable 'foo) variable _)
|
((make-variable 'foo) variable _)
|
||||||
((make-weak-vector 3 #t) weak-vector _)
|
((make-weak-vector 3 #t) weak-vector _)
|
||||||
|
@ -111,6 +111,31 @@
|
||||||
((expt 2 70) bignum _)
|
((expt 2 70) bignum _)
|
||||||
((make-fluid) fluid _)))
|
((make-fluid) fluid _)))
|
||||||
|
|
||||||
|
(define-syntax test-inferior-ports
|
||||||
|
(syntax-rules ()
|
||||||
|
"Test whether each OBJECT is a port with the given TYPE-NAME."
|
||||||
|
((_ (object type-name) rest ...)
|
||||||
|
(begin
|
||||||
|
(pass-if-equal (object->string object)
|
||||||
|
type-name
|
||||||
|
(let ((result (scm->object (object-address object))))
|
||||||
|
(and (eq? 'port (inferior-object-kind result))
|
||||||
|
(let ((type (inferior-object-sub-kind result)))
|
||||||
|
(and (eq? 'port-type (inferior-object-kind type))
|
||||||
|
(inferior-object-sub-kind type))))))
|
||||||
|
(test-inferior-ports rest ...)))
|
||||||
|
((_)
|
||||||
|
*unspecified*)))
|
||||||
|
|
||||||
|
(with-test-prefix "ports"
|
||||||
|
(test-inferior-ports
|
||||||
|
((open-input-file "/dev/null") "file")
|
||||||
|
((open-output-file "/dev/null") "file")
|
||||||
|
((open-input-string "the string") "string")
|
||||||
|
((open-output-string) "string")
|
||||||
|
((open-bytevector-input-port #vu8(1 2 3 4 5)) "r6rs-bytevector-input-port")
|
||||||
|
((open-bytevector-output-port) "r6rs-bytevector-output-port")))
|
||||||
|
|
||||||
(define-record-type <some-struct>
|
(define-record-type <some-struct>
|
||||||
(some-struct x y z)
|
(some-struct x y z)
|
||||||
some-struct?
|
some-struct?
|
||||||
|
|
54
test-suite/tests/vm.test
Normal file
54
test-suite/tests/vm.test
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
;;;; vm.test --- tests for the ELF machinery and VM -*- scheme -*-
|
||||||
|
;;;; Copyright (C) 2017 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 the License, or (at your option) any later version.
|
||||||
|
;;;;
|
||||||
|
;;;; This library is distributed in the hope that it will be useful,
|
||||||
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
;;;; Lesser General Public License for more details.
|
||||||
|
;;;;
|
||||||
|
;;;; You should have received a copy of the GNU Lesser General Public
|
||||||
|
;;;; License along with this library; if not, write to the Free Software
|
||||||
|
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
(define-module (tests vm)
|
||||||
|
#:use-module (test-suite lib)
|
||||||
|
#:use-module (system vm loader)
|
||||||
|
#:use-module (system vm elf)
|
||||||
|
#:use-module (rnrs bytevectors))
|
||||||
|
|
||||||
|
(define (elf->bytevector elf)
|
||||||
|
(let ((bv (make-bytevector 1000)))
|
||||||
|
(write-elf-header bv elf)
|
||||||
|
bv))
|
||||||
|
|
||||||
|
|
||||||
|
(with-test-prefix "load-thunk-from-memory"
|
||||||
|
|
||||||
|
(pass-if-exception "wrong byte order"
|
||||||
|
'(misc-error . "does not have native byte order")
|
||||||
|
;; This used to throw to 'system-error' with whatever value errno had.
|
||||||
|
(begin
|
||||||
|
(false-if-exception (open-output-file "/does-not-exist"))
|
||||||
|
(load-thunk-from-memory
|
||||||
|
(elf->bytevector
|
||||||
|
(make-elf #:byte-order (if (eq? (native-endianness)
|
||||||
|
(endianness little))
|
||||||
|
(endianness big)
|
||||||
|
(endianness
|
||||||
|
little))
|
||||||
|
#:shoff 0)))))
|
||||||
|
|
||||||
|
(pass-if-exception "wrong OS ABI"
|
||||||
|
'(misc-error . "OS ABI")
|
||||||
|
;; This used to throw to 'system-error' with whatever value errno had.
|
||||||
|
(begin
|
||||||
|
(false-if-exception (open-output-file "/does-not-exist"))
|
||||||
|
(load-thunk-from-memory
|
||||||
|
(elf->bytevector
|
||||||
|
(make-elf #:abi ELFOSABI_TRU64 ;RIP
|
||||||
|
#:shoff 0))))))
|
Loading…
Add table
Add a link
Reference in a new issue