mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 04:10:18 +02:00
Move doc files into guile-core distribution (1)
This commit is contained in:
parent
da00aada47
commit
38a93523eb
43 changed files with 22817 additions and 0 deletions
279
doc/appendices.texi
Normal file
279
doc/appendices.texi
Normal file
|
@ -0,0 +1,279 @@
|
||||||
|
@node Obtaining and Installing Guile
|
||||||
|
@appendix Obtaining and Installing Guile
|
||||||
|
|
||||||
|
Here is the information you will need to get and install Guile and extra
|
||||||
|
packages and documentation you might need or find interesting.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* The Basic Guile Package::
|
||||||
|
* Packages not shipped with Guile::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node The Basic Guile Package
|
||||||
|
@section The Basic Guile Package
|
||||||
|
|
||||||
|
Guile can be obtained from the main GNU archive site
|
||||||
|
@url{ftp://prep.ai.mit.edu/pub/gnu} or any of its mirrors. The file
|
||||||
|
will be named guile-version.tar.gz. The current version is
|
||||||
|
@value{VERSION}, so the file you should grab is:
|
||||||
|
|
||||||
|
@url{ftp://prep.ai.mit.edu/pub/gnu/guile-@value{VERSION}.tar.gz}
|
||||||
|
|
||||||
|
To unbundle Guile use the instruction
|
||||||
|
@example
|
||||||
|
zcat guile-@value{VERSION}.tar.gz | tar xvf -
|
||||||
|
@end example
|
||||||
|
which will create a directory called @file{guile-@value{VERSION}} with
|
||||||
|
all the sources. You can look at the file @file{INSTALL} for detailed
|
||||||
|
instructions on how to build and install Guile, but you should be able
|
||||||
|
to just do
|
||||||
|
@example
|
||||||
|
cd guile-@value{VERSION}
|
||||||
|
./configure
|
||||||
|
make install
|
||||||
|
@end example
|
||||||
|
|
||||||
|
This will install the Guile executable @file{guile}, the Guile library
|
||||||
|
@file{libguile.a} and various associated header files and support
|
||||||
|
libraries. It will also install the Guile tutorial and reference manual.
|
||||||
|
|
||||||
|
@c [[include instructions for getting R4RS]]
|
||||||
|
|
||||||
|
Since this manual frequently refers to the Scheme ``standard'', also
|
||||||
|
known as R4RS, or the
|
||||||
|
@iftex
|
||||||
|
``Revised$^4$ Report on the Algorithmic Language Scheme'',
|
||||||
|
@end iftex
|
||||||
|
@ifinfo
|
||||||
|
``Revised^4 Report on the Algorithmic Language Scheme'',
|
||||||
|
@end ifinfo
|
||||||
|
we have included the report in the Guile distribution;
|
||||||
|
@xref{Top, , Introduction, r4rs, Revised(4) Report on the Algorithmic
|
||||||
|
Language Scheme}.
|
||||||
|
This will also be installed in your info directory.
|
||||||
|
|
||||||
|
|
||||||
|
@node Packages not shipped with Guile
|
||||||
|
@section Packages not shipped with Guile
|
||||||
|
|
||||||
|
We ship the Guile tutorial and reference manual with the Guile
|
||||||
|
distribution [FIXME: this is not currently true (Sat Sep 20 14:13:33 MDT
|
||||||
|
1997), but will be soon.] Since the Scheme standard (R4RS) is a stable
|
||||||
|
document, we ship that too.
|
||||||
|
|
||||||
|
Here are references (usually World Wide Web URLs) to some other freely
|
||||||
|
redistributable documents and packages which you might find useful if
|
||||||
|
you are using Guile.
|
||||||
|
|
||||||
|
@table @strong
|
||||||
|
@item SCSH
|
||||||
|
the Scheme Shell. Gary Houston has ported SCSH to Guile. The relevant
|
||||||
|
chapter (@pxref{The Scheme shell (scsh)}) has references to the SCSH web
|
||||||
|
page with all its documentation.
|
||||||
|
|
||||||
|
@item SLIB
|
||||||
|
a portable Scheme library maintained by Aubrey Jaffer. SLIB can be
|
||||||
|
obtained by ftp from @url{ftp://prep.ai.mit.edu/pub/gnu/jacal/}.
|
||||||
|
|
||||||
|
The SLIB package should be unpacked somewhere in Guile's load path. It
|
||||||
|
will typically be unpacked in @file{/usr/local/share/guile/site}, so
|
||||||
|
that it will be @file{/usr/local/share/guile/site/slib}.
|
||||||
|
|
||||||
|
Guile might have been installed with a different prefix, in which case
|
||||||
|
the load path can be checked from inside the interpreter with:
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
guile> %load-path
|
||||||
|
("/usr/local/share/guile/site" "/usr/local/share/guile/1.3a" "/usr/local/share/guile" ".")
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
The relevant chapter (@pxref{SLIB}) has details on how to use SLIB with
|
||||||
|
Guile.
|
||||||
|
|
||||||
|
@item JACAL
|
||||||
|
a symbolic math package by Aubrey Jaffer. The latest version of Jacal
|
||||||
|
can be obtained from @url{ftp://prep.ai.mit.edu/pub/gnu/jacal/}, and
|
||||||
|
should be unpacked in @file{/usr/local/share/guile/site/slib} so that
|
||||||
|
it will be in @file{/usr/local/share/guile/site/slib/jacal}.
|
||||||
|
|
||||||
|
The relevant section (@pxref{JACAL}) has details on how to use Jacal.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Debugger User Interface
|
||||||
|
@appendix Debugger User Interface
|
||||||
|
|
||||||
|
@c --- The title and introduction of this appendix need to
|
||||||
|
@c distinguish this clearly from the chapter on the internal
|
||||||
|
@c debugging interface.
|
||||||
|
|
||||||
|
When debugging a program, programmers often find it helpful to examine
|
||||||
|
the program's internal status while it runs: the values of internal
|
||||||
|
variables, the choices made in @code{if} and @code{cond} statements, and
|
||||||
|
so forth. Guile Scheme provides a debugging interface that programmers
|
||||||
|
can use to single-step through Scheme functions and examine symbol
|
||||||
|
bindings. This is different from the @ref{Debugging}, which permits
|
||||||
|
programmers to debug the Guile interpreter itself. Most programmers
|
||||||
|
will be more interested in debugging their own Scheme programs than the
|
||||||
|
interpreter which evaluates them.
|
||||||
|
|
||||||
|
[FIXME: should we include examples of traditional debuggers
|
||||||
|
and explain why they can't be used to debug interpreted Scheme or Lisp?]
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Single-Step:: Execute a program or function one step at a time.
|
||||||
|
* Trace:: Print a report each time a given function is called.
|
||||||
|
* Backtrace:: See a list of the statements that caused an error.
|
||||||
|
* Stacks and Frames:: Examine the state of an interrupted program.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Single-Step
|
||||||
|
@appendixsec Single-Step
|
||||||
|
|
||||||
|
@node Trace
|
||||||
|
@appendixsec Trace
|
||||||
|
|
||||||
|
When a function is @dfn{traced}, it means that every call to that
|
||||||
|
function is reported to the user during a program run. This can help a
|
||||||
|
programmer determine whether a function is being called at the wrong
|
||||||
|
time or with the wrong set of arguments.
|
||||||
|
|
||||||
|
@defun trace function
|
||||||
|
Enable debug tracing on @code{function}. While a program is being run, Guile
|
||||||
|
will print a brief report at each call to a traced function,
|
||||||
|
advising the user which function was called and the arguments that were
|
||||||
|
passed to it.
|
||||||
|
@end defun
|
||||||
|
|
||||||
|
@defun untrace function
|
||||||
|
Disable debug tracing for @code{function}.
|
||||||
|
@end defun
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define (rev ls)
|
||||||
|
(if (null? ls)
|
||||||
|
'()
|
||||||
|
(append (rev (cdr ls))
|
||||||
|
(cons (car ls) '())))) @result{} rev
|
||||||
|
|
||||||
|
(trace rev) @result{} (rev)
|
||||||
|
|
||||||
|
(rev '(a b c d e))
|
||||||
|
@result{} [rev (a b c d e)]
|
||||||
|
| [rev (b c d e)]
|
||||||
|
| | [rev (c d e)]
|
||||||
|
| | | [rev (d e)]
|
||||||
|
| | | | [rev (e)]
|
||||||
|
| | | | | [rev ()]
|
||||||
|
| | | | | ()
|
||||||
|
| | | | (e)
|
||||||
|
| | | (e d)
|
||||||
|
| | (e d c)
|
||||||
|
| (e d c b)
|
||||||
|
(e d c b a)
|
||||||
|
(e d c b a)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
Note the way Guile indents the output, illustrating the depth of
|
||||||
|
execution at each function call. This can be used to demonstrate, for
|
||||||
|
example, that Guile implements self-tail-recursion properly:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define (rev ls sl)
|
||||||
|
(if (null? ls)
|
||||||
|
sl
|
||||||
|
(rev (cdr ls)
|
||||||
|
(cons (car ls) sl)))) @result{} rev
|
||||||
|
|
||||||
|
(trace rev) @result{} (rev)
|
||||||
|
|
||||||
|
(rev '(a b c d e) '())
|
||||||
|
@result{} [rev (a b c d e) ()]
|
||||||
|
[rev (b c d e) (a)]
|
||||||
|
[rev (c d e) (b a)]
|
||||||
|
[rev (d e) (c b a)]
|
||||||
|
[rev (e) (d c b a)]
|
||||||
|
[rev () (e d c b a)]
|
||||||
|
(e d c b a)
|
||||||
|
(e d c b a)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
Since the tail call is effectively optimized to a @code{goto} statement,
|
||||||
|
there is no need for Guile to create a new stack frame for each
|
||||||
|
iteration. Using @code{trace} here helps us see why this is so.
|
||||||
|
|
||||||
|
@node Backtrace
|
||||||
|
@appendixsec Backtrace
|
||||||
|
|
||||||
|
@node Stacks and Frames
|
||||||
|
@appendixsec Stacks and Frames
|
||||||
|
|
||||||
|
When a running program is interrupted, usually upon reaching an error or
|
||||||
|
breakpoint, its state is represented by a @dfn{stack} of suspended
|
||||||
|
function calls, each of which is called a @dfn{frame}. The programmer
|
||||||
|
can learn more about the program's state at the point of interruption by
|
||||||
|
inspecting and modifying these frames.
|
||||||
|
|
||||||
|
@deffn primitive stack? obj
|
||||||
|
Return @code{#t} if @var{obj} is a calling stack.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive make-stack
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn syntax start-stack id exp
|
||||||
|
Evaluate @var{exp} on a new calling stack with identity @var{id}. If
|
||||||
|
@var{exp} is interrupted during evaluation, backtraces will not display
|
||||||
|
frames farther back than @var{exp}'s top-level form. This macro is a
|
||||||
|
way of artificially limiting backtraces and stack procedures, largely as
|
||||||
|
a convenience to the user.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive stack-id stack
|
||||||
|
Return the identifier given to @var{stack} by @code{start-stack}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive stack-ref
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive stack-length
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame?
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive last-stack-frame
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame-number
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame-source
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame-procedure
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame-arguments
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame-previous
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame-next
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame-real?
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame-procedure?
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame-evaluating-args?
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive frame-overflow
|
||||||
|
@end deffn
|
1818
doc/data-rep.texi
Normal file
1818
doc/data-rep.texi
Normal file
File diff suppressed because it is too large
Load diff
8
doc/deprecated.texi
Normal file
8
doc/deprecated.texi
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
@node Deprecated
|
||||||
|
@chapter Deprecated
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "tag")
|
||||||
|
@deffn primitive tag x
|
||||||
|
Return an integer corresponding to the type of X. Deprecated.
|
||||||
|
@end deffn
|
||||||
|
|
1165
doc/env.texi
Normal file
1165
doc/env.texi
Normal file
File diff suppressed because it is too large
Load diff
141
doc/expect.texi
Normal file
141
doc/expect.texi
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
@node Expect
|
||||||
|
@chapter Expect
|
||||||
|
|
||||||
|
The macros in this section are made available with:
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
(use-modules (ice-9 expect))
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
@code{expect} is a macro for selecting actions based on the output from
|
||||||
|
a port. The name comes from a tool of similar functionality by Don Libes.
|
||||||
|
Actions can be taken when a particular string is matched, when a timeout
|
||||||
|
occurs, or when end-of-file is seen on the port. The @code{expect} macro
|
||||||
|
is described below; @code{expect-strings} is a front-end to @code{expect}
|
||||||
|
based on regexec (see the regular expression documentation).
|
||||||
|
|
||||||
|
@defmac expect-strings clause @dots{}
|
||||||
|
By default, @code{expect-strings} will read from the current input port.
|
||||||
|
The first term in each clause consists of an expression evaluating to
|
||||||
|
a string pattern (regular expression). As characters
|
||||||
|
are read one-by-one from the port, they are accumulated in a buffer string
|
||||||
|
which is matched against each of the patterns. When a
|
||||||
|
pattern matches, the remaining expression(s) in
|
||||||
|
the clause are evaluated and the value of the last is returned. For example:
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
(with-input-from-file "/etc/passwd"
|
||||||
|
(lambda ()
|
||||||
|
(expect-strings
|
||||||
|
("^nobody" (display "Got a nobody user.\n")
|
||||||
|
(display "That's no problem.\n"))
|
||||||
|
("^daemon" (display "Got a daemon user.\n")))))
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
The regular expression is compiled with the @code{REG_NEWLINE} flag, so
|
||||||
|
that the ^ and $ anchors will match at any newline, not just at the start
|
||||||
|
and end of the string.
|
||||||
|
|
||||||
|
There are two other ways to write a clause:
|
||||||
|
|
||||||
|
The expression(s) to evaluate
|
||||||
|
can be omitted, in which case the result of the regular expression match
|
||||||
|
(converted to strings, as obtained from regexec with match-pick set to "")
|
||||||
|
will be returned if the pattern matches.
|
||||||
|
|
||||||
|
The symbol @code{=>} can be used to indicate that the expression is a
|
||||||
|
procedure which will accept the result of a successful regular expression
|
||||||
|
match. E.g.,
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
("^daemon" => write)
|
||||||
|
("^d\\(aemon\\)" => (lambda args (for-each write args)))
|
||||||
|
("^da\\(em\\)on" => (lambda (all sub)
|
||||||
|
(write all) (newline)
|
||||||
|
(write sub) (newline)))
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
The order of the substrings corresponds to the order in which the
|
||||||
|
opening brackets occur.
|
||||||
|
|
||||||
|
A number of variables can be used to control the behaviour
|
||||||
|
of @code{expect} (and @code{expect-strings}).
|
||||||
|
Most have default top-level bindings to the value @code{#f},
|
||||||
|
which produces the default behaviour.
|
||||||
|
They can be redefined at the
|
||||||
|
top level or locally bound in a form enclosing the expect expression.
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item expect-port
|
||||||
|
A port to read characters from, instead of the current input port.
|
||||||
|
@item expect-timeout
|
||||||
|
@code{expect} will terminate after this number of
|
||||||
|
seconds, returning @code{#f} or the value returned by expect-timeout-proc.
|
||||||
|
@item expect-timeout-proc
|
||||||
|
A procedure called if timeout occurs. The procedure takes a single argument:
|
||||||
|
the accumulated string.
|
||||||
|
@item expect-eof-proc
|
||||||
|
A procedure called if end-of-file is detected on the input port. The
|
||||||
|
procedure takes a single argument: the accumulated string.
|
||||||
|
@item expect-char-proc
|
||||||
|
A procedure to be called every time a character is read from the
|
||||||
|
port. The procedure takes a single argument: the character which was read.
|
||||||
|
@item expect-strings-compile-flags
|
||||||
|
Flags to be used when compiling a regular expression, which are passed
|
||||||
|
to @code{make-regexp} @xref{Regexp Functions}. The default value
|
||||||
|
is @code{regexp/newline}.
|
||||||
|
@item expect-strings-exec-flags
|
||||||
|
Flags to be used when executing a regular expression, which are
|
||||||
|
passed to regexp-exec @xref{Regexp Functions}.
|
||||||
|
The default value is @code{regexp/noteol}, which prevents @code{$}
|
||||||
|
from matching the end of the string while it is still accumulating,
|
||||||
|
but still allows it to match after a line break or at the end of file.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
Here's an example using all of the variables:
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
(let ((expect-port (open-input-file "/etc/passwd"))
|
||||||
|
(expect-timeout 1)
|
||||||
|
(expect-timeout-proc
|
||||||
|
(lambda (s) (display "Times up!\n")))
|
||||||
|
(expect-eof-proc
|
||||||
|
(lambda (s) (display "Reached the end of the file!\n")))
|
||||||
|
(expect-char-proc display)
|
||||||
|
(expect-strings-compile-flags (logior regexp/newline regexp/icase))
|
||||||
|
(expect-strings-exec-flags 0))
|
||||||
|
(expect-strings
|
||||||
|
("^nobody" (display "Got a nobody user\n"))))
|
||||||
|
@end smalllisp
|
||||||
|
@end defmac
|
||||||
|
|
||||||
|
@defmac expect clause @dots{}
|
||||||
|
@code{expect} is used in the same way as @code{expect-strings},
|
||||||
|
but tests are specified not as patterns, but as procedures. The
|
||||||
|
procedures are called in turn after each character is read from the
|
||||||
|
port, with two arguments: the value of the accumulated string and
|
||||||
|
a flag to indicate whether end-of-file has been reached. The flag
|
||||||
|
will usually be @code{#f}, but if end-of-file is reached, the procedures
|
||||||
|
are called an additional time with the final accumulated string and
|
||||||
|
@code{#t}.
|
||||||
|
|
||||||
|
The test is successful if the procedure returns a non-false value.
|
||||||
|
|
||||||
|
If the @code{=>} syntax is used, then if the test succeeds it must return
|
||||||
|
a list containing the arguments to be provided to the corresponding
|
||||||
|
expression.
|
||||||
|
|
||||||
|
In the following example, a string will only be matched at the beginning
|
||||||
|
of the file:
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
(let ((expect-port (open-input-file "/etc/passwd")))
|
||||||
|
(expect
|
||||||
|
((lambda (s eof?) (string=? s "fnord!"))
|
||||||
|
(display "Got a nobody user!\n"))))
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
The control variables described for @code{expect-strings} also
|
||||||
|
influence the behaviour of @code{expect}, with the exception of
|
||||||
|
variables whose names begin with @code{expect-strings-}.
|
||||||
|
@end defmac
|
23
doc/extend.texi
Normal file
23
doc/extend.texi
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
@page
|
||||||
|
@node Libguile Intro
|
||||||
|
@chapter Using Guile as an Extension Language
|
||||||
|
|
||||||
|
The chapters in this part of the manual explain how to use Guile as a
|
||||||
|
powerful application extension language.
|
||||||
|
|
||||||
|
The following chapter, ``GH: A Portable C to Scheme Interface,'' shows
|
||||||
|
how to call Guile from your application's C code, and how to add new
|
||||||
|
Scheme level procedures to Guile whose behaviour is specified by
|
||||||
|
application specific code written in C. The Guile interface functions
|
||||||
|
documented in this chapter make up a high level, portable interface
|
||||||
|
which (we hope) will also someday work with other Scheme interpreters,
|
||||||
|
allowing you to write C code which will work with any of several Scheme
|
||||||
|
systems.
|
||||||
|
|
||||||
|
The portable interface is rich enough to support simple use of Guile as
|
||||||
|
an application extension language, but is limited by its own portability
|
||||||
|
where a deeper integration is desired between Guile and your
|
||||||
|
application's code. The subsequent chapters therefore present aspects
|
||||||
|
of libguile that allow you to use more of Guile's C level features, and
|
||||||
|
to extend your application in more complex ways than is possible with
|
||||||
|
the portable interface.
|
815
doc/gh.texi
Normal file
815
doc/gh.texi
Normal file
|
@ -0,0 +1,815 @@
|
||||||
|
@node GH
|
||||||
|
@chapter GH: A Portable C to Scheme Interface
|
||||||
|
@cindex libguile - gh
|
||||||
|
@cindex gh
|
||||||
|
@cindex gh - reference manual
|
||||||
|
|
||||||
|
The Guile interpreter is based on Aubrey Jaffer's @emph{SCM} interpreter
|
||||||
|
(@pxref{Overview, SCM: a portable Scheme interpreter, Overview, scm,
|
||||||
|
SCM: a portable Scheme interpreter}) with some modifications to make it
|
||||||
|
suitable as an embedded interpreter, and further modifications as Guile
|
||||||
|
evolves.
|
||||||
|
@cindex SCM interpreter
|
||||||
|
@cindex Jaffer, Aubrey
|
||||||
|
|
||||||
|
Part of the modification has been to provide a restricted interface to
|
||||||
|
limit access to the SCM internals; this is called the @code{gh_}
|
||||||
|
interface, or @emph{libguile} interface.
|
||||||
|
@cindex gh_ interface
|
||||||
|
@cindex libguile interface
|
||||||
|
|
||||||
|
If you are @emph{programming with Guile}, you should only use the C
|
||||||
|
subroutines described in this manual, which all begin with
|
||||||
|
@code{gh_}.
|
||||||
|
|
||||||
|
If instead you are @emph{extending Guile}, you have the entire SCM
|
||||||
|
source to play with. This manual will not help you at all, but you can
|
||||||
|
consult Aubrey Jaffer's SCM manual (@pxref{Internals, SCM: a portable
|
||||||
|
Scheme interpreter, Internals, scm, SCM: a portable Scheme
|
||||||
|
interpreter}).
|
||||||
|
@cindex Guile - extending
|
||||||
|
@cindex extending Guile
|
||||||
|
@cindex SCM internals
|
||||||
|
|
||||||
|
If you are @emph{adding a module to Guile}, I recommend that you stick
|
||||||
|
to the @code{gh_} interface: this interface is guaranteed to not
|
||||||
|
change drastically, while the SCM internals might change as Guile is
|
||||||
|
developed.
|
||||||
|
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* gh preliminaries::
|
||||||
|
* Data types and constants defined by gh::
|
||||||
|
* Starting and controlling the interpreter::
|
||||||
|
* Error messages::
|
||||||
|
* Executing Scheme code::
|
||||||
|
* Defining new Scheme procedures in C::
|
||||||
|
* Converting data between C and Scheme::
|
||||||
|
* Type predicates::
|
||||||
|
* Equality predicates::
|
||||||
|
* Memory allocation and garbage collection::
|
||||||
|
* Calling Scheme procedures from C::
|
||||||
|
* Mixing gh and scm APIs::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node gh preliminaries
|
||||||
|
@section gh preliminaries
|
||||||
|
|
||||||
|
To use gh, you must have the following toward the beginning of your C
|
||||||
|
source:
|
||||||
|
@smallexample
|
||||||
|
#include <guile/gh.h>
|
||||||
|
@end smallexample
|
||||||
|
@cindex gh - headers
|
||||||
|
|
||||||
|
When you link, you will have to add at least @code{-lguile} to the list
|
||||||
|
of libraries. If you are using more of Guile than the basic Scheme
|
||||||
|
interpreter, you will have to add more libraries.
|
||||||
|
@cindex gh - linking
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Data types and constants defined by gh
|
||||||
|
@section Data types and constants defined by gh
|
||||||
|
@cindex libguile - data types
|
||||||
|
|
||||||
|
The following C constants and data types are defined in gh:
|
||||||
|
|
||||||
|
@deftp {Data type} SCM
|
||||||
|
This is a C data type used to store all Scheme data, no matter what the
|
||||||
|
Scheme type. Values are converted between C data types and the SCM type
|
||||||
|
with utility functions described below (@pxref{Converting data between C
|
||||||
|
and Scheme}). [FIXME: put in references to Jim's essay and so forth.]
|
||||||
|
@end deftp
|
||||||
|
@cindex SCM data type
|
||||||
|
|
||||||
|
@defvr Constant SCM_BOOL_T
|
||||||
|
@defvrx Constant SCM_BOOL_F
|
||||||
|
The @emph{Scheme} values returned by many boolean procedures in
|
||||||
|
libguile.
|
||||||
|
|
||||||
|
This can cause confusion because they are different from 0 and 1. In
|
||||||
|
testing a boolean function in libguile programming, you must always make
|
||||||
|
sure that you check the spec: @code{gh_} and @code{scm_} functions will
|
||||||
|
usually return @code{SCM_BOOL_T} and @code{SCM_BOOL_F}, but other C
|
||||||
|
functions usually can be tested against 0 and 1, so programmers' fingers
|
||||||
|
tend to just type @code{if (boolean_function()) @{ ... @}}
|
||||||
|
@end defvr
|
||||||
|
|
||||||
|
@defvr Constant SCM_UNSPECIFIED
|
||||||
|
This is an SCM object which does not correspond to any legal Scheme
|
||||||
|
value. It can be used in C to terminate functions with variable numbers
|
||||||
|
of arguments, such as @code{gh_list()}.
|
||||||
|
@end defvr
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Starting and controlling the interpreter
|
||||||
|
@section Starting and controlling the interpreter
|
||||||
|
@cindex libguile - start interpreter
|
||||||
|
|
||||||
|
In almost every case, your first @code{gh_} call will be:
|
||||||
|
|
||||||
|
@deftypefun void gh_enter (int @var{argc}, char *@var{argv}[], void (*@var{main_prog})())
|
||||||
|
Starts up a Scheme interpreter with all the builtin Scheme primitives.
|
||||||
|
@code{gh_enter()} never exits, and the user's code should all be in the
|
||||||
|
@code{@var{main_prog}()} function. @code{argc} and @code{argv} will be
|
||||||
|
passed to @var{main_prog}.
|
||||||
|
|
||||||
|
@deftypefun void main_prog (int @var{argc}, char *@var{argv}[])
|
||||||
|
This is the user's main program. It will be invoked by
|
||||||
|
@code{gh_enter()} after Guile has been started up.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
Note that you can use @code{gh_repl} inside @code{gh_enter} (in other
|
||||||
|
words, inside the code for @code{main-prog}) if you want the program to
|
||||||
|
be controled by a Scheme read-eval-print loop.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@cindex read eval print loop -- from the gh_ interface
|
||||||
|
@cindex REPL -- from the gh_ interface
|
||||||
|
A convenience routine which enters the Guile interpreter with the
|
||||||
|
standard Guile read-eval-print loop (@dfn{REPL}) is:
|
||||||
|
|
||||||
|
@deftypefun void gh_repl (int @var{argc}, char *@var{argv}[])
|
||||||
|
Enters the Scheme interpreter giving control to the Scheme REPL.
|
||||||
|
Arguments are processed as if the Guile program @file{guile} were being
|
||||||
|
invoked.
|
||||||
|
|
||||||
|
Note that @code{gh_repl} should be used @emph{inside} @code{gh_enter},
|
||||||
|
since any Guile interpreter calls are meaningless unless they happen in
|
||||||
|
the context of the interpreter.
|
||||||
|
|
||||||
|
Also note that when you use @code{gh_repl}, your program will be
|
||||||
|
controlled by Guile's REPL (which is written in Scheme and has many
|
||||||
|
useful features). Use straight C code inside @code{gh_enter} if you
|
||||||
|
want to maintain execution control in your C program.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
You will typically use @code{gh_enter} and @code{gh_repl} when you
|
||||||
|
want a Guile interpreter enhanced by your own libraries, but otherwise
|
||||||
|
quite normal. For example, to build a Guile--derived program that
|
||||||
|
includes some random number routines @dfn{GSL} (GNU Scientific Library),
|
||||||
|
you would write a C program that looks like this:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
#include <guile/gh.h>
|
||||||
|
#include <gsl_ran.h>
|
||||||
|
|
||||||
|
/* random number suite */
|
||||||
|
SCM gw_ran_seed(SCM s)
|
||||||
|
@{
|
||||||
|
gsl_ran_seed(gh_scm2int(s));
|
||||||
|
return SCM_UNSPECIFIED;
|
||||||
|
@}
|
||||||
|
|
||||||
|
SCM gw_ran_random()
|
||||||
|
@{
|
||||||
|
SCM x;
|
||||||
|
|
||||||
|
x = gh_ulong2scm(gsl_ran_random());
|
||||||
|
return x;
|
||||||
|
@}
|
||||||
|
|
||||||
|
SCM gw_ran_uniform()
|
||||||
|
@{
|
||||||
|
SCM x;
|
||||||
|
|
||||||
|
x = gh_double2scm(gsl_ran_uniform());
|
||||||
|
return x;
|
||||||
|
@}
|
||||||
|
SCM gw_ran_max()
|
||||||
|
@{
|
||||||
|
return gh_double2scm(gsl_ran_max());
|
||||||
|
@}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_gsl()
|
||||||
|
@{
|
||||||
|
/* random number suite */
|
||||||
|
gh_new_procedure("gsl-ran-seed", gw_ran_seed, 1, 0, 0);
|
||||||
|
gh_new_procedure("gsl-ran-random", gw_ran_random, 0, 0, 0);
|
||||||
|
gh_new_procedure("gsl-ran-uniform", gw_ran_uniform, 0, 0, 0);
|
||||||
|
gh_new_procedure("gsl-ran-max", gw_ran_max, 0, 0, 0);
|
||||||
|
@}
|
||||||
|
|
||||||
|
void
|
||||||
|
main_prog (int argc, char *argv[])
|
||||||
|
@{
|
||||||
|
init_gsl();
|
||||||
|
|
||||||
|
gh_repl(argc, argv);
|
||||||
|
@}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
@{
|
||||||
|
gh_enter (argc, argv, main_prog);
|
||||||
|
@}
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
Then, supposing the C program is in @file{guile-gsl.c}, you could
|
||||||
|
compile it with @kbd{gcc -o guile-gsl guile-gsl.c -lguile -lgsl}.
|
||||||
|
|
||||||
|
The resulting program @file{guile-gsl} would have new primitive
|
||||||
|
procedures @code{gsl-ran-random}, @code{gsl-ran-gaussian} and so forth.
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Error messages
|
||||||
|
@section Error messages
|
||||||
|
@cindex libguile - error messages
|
||||||
|
@cindex error messages in libguile
|
||||||
|
|
||||||
|
[FIXME: need to fill this based on Jim's new mechanism]
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Executing Scheme code
|
||||||
|
@section Executing Scheme code
|
||||||
|
@cindex libguile - executing Scheme
|
||||||
|
@cindex executing Scheme
|
||||||
|
|
||||||
|
Once you have an interpreter running, you can ask it to evaluate Scheme
|
||||||
|
code. There are two calls that implement this:
|
||||||
|
|
||||||
|
@deftypefun SCM gh_eval_str (char *@var{scheme_code})
|
||||||
|
This asks the interpreter to evaluate a single string of Scheme code,
|
||||||
|
and returns the result of the last expression evaluated.
|
||||||
|
|
||||||
|
Note that the line of code in @var{scheme_code} must be a well formed
|
||||||
|
Scheme expression. If you have many lines of code before you balance
|
||||||
|
parentheses, you must either concatenate them into one string, or use
|
||||||
|
@code{gh_eval_file()}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_eval_file (char *@var{fname})
|
||||||
|
@deftypefunx SCM gh_load (char *@var{fname})
|
||||||
|
@code{gh_eval_file} is completely analogous to @code{gh_eval_str()},
|
||||||
|
except that a whole file is evaluated instead of a string. Returns the
|
||||||
|
result of the last expression evaluated.
|
||||||
|
|
||||||
|
@code{gh_load} is identical to @code{gh_eval_file} (it's a macro that
|
||||||
|
calls @code{gh_eval_file} on its argument). It is provided to start
|
||||||
|
making the @code{gh_} interface match the R4RS Scheme procedures
|
||||||
|
closely.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Defining new Scheme procedures in C
|
||||||
|
@section Defining new Scheme procedures in C
|
||||||
|
@cindex libguile - new procedures
|
||||||
|
@cindex new procedures
|
||||||
|
@cindex procedures, new
|
||||||
|
@cindex new primitives
|
||||||
|
@cindex primitives, new
|
||||||
|
|
||||||
|
The real interface between C and Scheme comes when you can write new
|
||||||
|
Scheme procedures in C. This is done through the routine
|
||||||
|
|
||||||
|
|
||||||
|
@deftypefn {Libguile high} SCM gh_new_procedure (char *@var{proc_name}, SCM (*@var{fn})(), int @var{n_required_args}, int @var{n_optional_args}, int @var{restp})
|
||||||
|
@code{gh_new_procedure} defines a new Scheme procedure. Its Scheme name
|
||||||
|
will be @var{proc_name}, it will be implemented by the C function
|
||||||
|
(*@var{fn})(), it will take at least @var{n_required_args} arguments,
|
||||||
|
and at most @var{n_optional_args} extra arguments.
|
||||||
|
|
||||||
|
When the @var{restp} parameter is 1, the procedure takes a final
|
||||||
|
argument: a list of remaining parameters.
|
||||||
|
|
||||||
|
@code{gh_new_procedure} returns an SCM value representing the procedure.
|
||||||
|
|
||||||
|
The C function @var{fn} should have the form
|
||||||
|
@deftypefn {Libguile high} SCM fn (SCM @var{req1}, SCM @var{req2}, ..., SCM @var{opt1}, SCM @var{opt2}, ..., SCM @var{rest_args})
|
||||||
|
The arguments are all passed as SCM values, so the user will have to use
|
||||||
|
the conversion functions to convert to standard C types.
|
||||||
|
|
||||||
|
Examples of C functions used as new Scheme primitives can be found in
|
||||||
|
the sample programs @code{learn0} and @code{learn1}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@strong{Rationale:} this is the correct way to define new Scheme
|
||||||
|
procedures in C. The ugly mess of arguments is required because of how
|
||||||
|
C handles procedures with variable numbers of arguments.
|
||||||
|
|
||||||
|
@strong{Note:} what about documentation strings?
|
||||||
|
|
||||||
|
@cartouche
|
||||||
|
There are several important considerations to be made when writing the C
|
||||||
|
routine @code{(*fn)()}.
|
||||||
|
|
||||||
|
First of all the C routine has to return type @code{SCM}.
|
||||||
|
|
||||||
|
Second, all arguments passed to the C funcion will be of type
|
||||||
|
@code{SCM}.
|
||||||
|
|
||||||
|
Third: the C routine is now subject to Scheme flow control, which means
|
||||||
|
that it could be interrupted at any point, and then reentered. This
|
||||||
|
means that you have to be very careful with operations such as
|
||||||
|
allocating memory, modifying static data @dots{}
|
||||||
|
|
||||||
|
Fourth: to get around the latter issue, you can use
|
||||||
|
@code{GH_DEFER_INTS} and @code{GH_ALLOW_INTS}.
|
||||||
|
@end cartouche
|
||||||
|
|
||||||
|
@defmac GH_DEFER_INTS
|
||||||
|
@defmacx GH_ALLOW_INTS
|
||||||
|
These macros disable and reenable Scheme's flow control. They
|
||||||
|
@end defmac
|
||||||
|
|
||||||
|
|
||||||
|
@c [??? have to do this right; maybe using subsections, or maybe creating a
|
||||||
|
@c section called Flow control issues...]
|
||||||
|
|
||||||
|
@c [??? Go into exhaustive detail with examples of the various possible
|
||||||
|
@c combinations of required and optional args...]
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Converting data between C and Scheme
|
||||||
|
@section Converting data between C and Scheme
|
||||||
|
@cindex libguile - converting data
|
||||||
|
@cindex data conversion
|
||||||
|
@cindex converting data
|
||||||
|
|
||||||
|
Guile provides mechanisms to convert data between C and Scheme. This
|
||||||
|
allows new builtin procedures to understand their arguments (which are
|
||||||
|
of type @code{SCM}) and return values of type @code{SCM}.
|
||||||
|
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* C to Scheme::
|
||||||
|
* Scheme to C::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node C to Scheme
|
||||||
|
@subsection C to Scheme
|
||||||
|
|
||||||
|
@deftypefun SCM gh_bool2scm (int @var{x})
|
||||||
|
Returns @code{#f} if @var{x} is zero, @code{#t} otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_ulong2scm (unsigned long @var{x})
|
||||||
|
@deftypefunx SCM gh_long2scm (long @var{x})
|
||||||
|
@deftypefunx SCM gh_double2scm (double @var{x})
|
||||||
|
@deftypefunx SCM gh_char2scm (char @var{x})
|
||||||
|
Returns a Scheme object with the value of the C quantity @var{x}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_str2scm (char *@var{s}, int @var{len})
|
||||||
|
Returns a new Scheme string with the (not necessarily null-terminated) C
|
||||||
|
array @var{s} data.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_str02scm (char *@var{s})
|
||||||
|
Returns a new Scheme string with the null-terminated C string @var{s}
|
||||||
|
data.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_set_substr (char *@var{src}, SCM @var{dst}, int @var{start}, int @var{len})
|
||||||
|
Copy @var{len} characters at @var{src} into the @emph{existing} Scheme
|
||||||
|
string @var{dst}, starting at @var{start}. @var{start} is an index into
|
||||||
|
@var{dst}; zero means the beginning of the string.
|
||||||
|
|
||||||
|
If @var{start} + @var{len} is off the end of @var{dst}, signal an
|
||||||
|
out-of-range error.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_symbol2scm (char *@var{name})
|
||||||
|
Given a null-terminated string @var{name}, return the symbol with that
|
||||||
|
name.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_ints2scm (int *@var{dptr}, int @var{n})
|
||||||
|
@deftypefunx SCM gh_doubles2scm (double *@var{dptr}, int @var{n})
|
||||||
|
Make a scheme vector containing the @var{n} ints or doubles at memory
|
||||||
|
location @var{dptr}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_chars2byvect (char *@var{dptr}, int @var{n})
|
||||||
|
@deftypefunx SCM gh_shorts2svect (short *@var{dptr}, int @var{n})
|
||||||
|
@deftypefunx SCM gh_longs2ivect (long *@var{dptr}, int @var{n})
|
||||||
|
@deftypefunx SCM gh_ulongs2uvect (ulong *@var{dptr}, int @var{n})
|
||||||
|
@deftypefunx SCM gh_floats2fvect (float *@var{dptr}, int @var{n})
|
||||||
|
@deftypefunx SCM gh_doubles2dvect (double *@var{dptr}, int @var{n})
|
||||||
|
Make a scheme uniform vector containing the @var{n} chars, shorts,
|
||||||
|
longs, unsigned longs, floats or doubles at memory location @var{dptr}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@node Scheme to C
|
||||||
|
@subsection Scheme to C
|
||||||
|
|
||||||
|
@deftypefun int gh_scm2bool (SCM @var{obj})
|
||||||
|
@deftypefunx {unsigned long} gh_scm2ulong (SCM @var{obj})
|
||||||
|
@deftypefunx long gh_scm2long (SCM @var{obj})
|
||||||
|
@deftypefunx double gh_scm2double (SCM @var{obj})
|
||||||
|
@deftypefunx int gh_scm2char (SCM @var{obj})
|
||||||
|
These routines convert the Scheme object to the given C type.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun char *gh_scm2newstr (SCM @var{str}, int *@var{lenp})
|
||||||
|
Given a Scheme string @var{str}, return a pointer to a new copy of its
|
||||||
|
contents, followed by a null byte. If @var{lenp} is non-null, set
|
||||||
|
@code{*@var{lenp}} to the string's length.
|
||||||
|
|
||||||
|
This function uses malloc to obtain storage for the copy; the caller is
|
||||||
|
responsible for freeing it.
|
||||||
|
|
||||||
|
Note that Scheme strings may contain arbitrary data, including null
|
||||||
|
characters. This means that null termination is not a reliable way to
|
||||||
|
determine the length of the returned value. However, the function
|
||||||
|
always copies the complete contents of @var{str}, and sets @var{*lenp}
|
||||||
|
to the true length of the string (when @var{lenp} is non-null).
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@deftypefun void gh_get_substr (SCM str, char *return_str, int *lenp)
|
||||||
|
Copy @var{len} characters at @var{start} from the Scheme string
|
||||||
|
@var{src} to memory at @var{dst}. @var{start} is an index into
|
||||||
|
@var{src}; zero means the beginning of the string. @var{dst} has
|
||||||
|
already been allocated by the caller.
|
||||||
|
|
||||||
|
If @var{start} + @var{len} is off the end of @var{src}, signal an
|
||||||
|
out-of-range error.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun char *gh_symbol2newstr (SCM @var{sym}, int *@var{lenp})
|
||||||
|
Takes a Scheme symbol and returns a string of the form
|
||||||
|
@code{"'symbol-name"}. If @var{lenp} is non-null, the string's length
|
||||||
|
is returned in @code{*@var{lenp}}.
|
||||||
|
|
||||||
|
This function uses malloc to obtain storage for the returned string; the
|
||||||
|
caller is responsible for freeing it.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun char *gh_scm2chars (SCM @var{vector}, chars *@var{result})
|
||||||
|
@deftypefunx short *gh_scm2shorts (SCM @var{vector}, short *@var{result})
|
||||||
|
@deftypefunx long *gh_scm2longs (SCM @var{vector}, long *@var{result})
|
||||||
|
@deftypefunx float *gh_scm2floats (SCM @var{vector}, float *@var{result})
|
||||||
|
@deftypefunx double *gh_scm2doubles (SCM @var{vector}, double *@var{result})
|
||||||
|
Copy the numbers in @var{vector} to the array pointed to by @var{result}
|
||||||
|
and return it. If @var{result} is NULL, allocate a double array large
|
||||||
|
enough.
|
||||||
|
|
||||||
|
@var{vector} can be an ordinary vector, a weak vector, or a signed or
|
||||||
|
unsigned uniform vector of the same type as the result array. For
|
||||||
|
chars, @var{vector} can be a string or substring. For floats and
|
||||||
|
doubles, @var{vector} can contain a mix of inexact and integer values.
|
||||||
|
|
||||||
|
If @var{vector} is of unsigned type and contains values too large to fit
|
||||||
|
in the signed destination array, those values will be wrapped around,
|
||||||
|
that is, data will be copied as if the destination array was unsigned.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Type predicates
|
||||||
|
@section Type predicates
|
||||||
|
|
||||||
|
These C functions mirror Scheme's type predicate procedures with one
|
||||||
|
important difference. The C routines return C boolean values (0 and 1)
|
||||||
|
instead of @code{SCM_BOOL_T} and @code{SCM_BOOL_F}.
|
||||||
|
|
||||||
|
The Scheme notational convention of putting a @code{?} at the end of
|
||||||
|
predicate procedure names is mirrored in C by placing @code{_p} at the
|
||||||
|
end of the procedure. For example, @code{(pair? ...)} maps to
|
||||||
|
@code{gh_pair_p(...)}.
|
||||||
|
|
||||||
|
@deftypefun int gh_boolean_p (SCM @var{val})
|
||||||
|
Returns 1 if @var{val} is a boolean, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_symbol_p (SCM @var{val})
|
||||||
|
Returns 1 if @var{val} is a symbol, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_char_p (SCM @var{val})
|
||||||
|
Returns 1 if @var{val} is a char, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_vector_p (SCM @var{val})
|
||||||
|
Returns 1 if @var{val} is a vector, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_pair_p (SCM @var{val})
|
||||||
|
Returns 1 if @var{val} is a pair, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_procedure_p (SCM @var{val})
|
||||||
|
Returns 1 if @var{val} is a procedure, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_list_p (SCM @var{val})
|
||||||
|
Returns 1 if @var{val} is a list, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_inexact_p (SCM @var{val})
|
||||||
|
Returns 1 if @var{val} is an inexact number, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_exact_p (SCM @var{val})
|
||||||
|
Returns 1 if @var{val} is an exact number, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Equality predicates
|
||||||
|
@section Equality predicates
|
||||||
|
|
||||||
|
These C functions mirror Scheme's equality predicate procedures with one
|
||||||
|
important difference. The C routines return C boolean values (0 and 1)
|
||||||
|
instead of @code{SCM_BOOL_T} and @code{SCM_BOOL_F}.
|
||||||
|
|
||||||
|
The Scheme notational convention of putting a @code{?} at the end of
|
||||||
|
predicate procedure names is mirrored in C by placing @code{_p} at the
|
||||||
|
end of the procedure. For example, @code{(equal? ...)} maps to
|
||||||
|
@code{gh_equal_p(...)}.
|
||||||
|
|
||||||
|
@deftypefun int gh_eq_p (SCM x, SCM y)
|
||||||
|
Returns 1 if @var{x} and @var{y} are equal in the sense of Scheme's
|
||||||
|
@code{eq?} predicate, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_eqv_p (SCM x, SCM y)
|
||||||
|
Returns 1 if @var{x} and @var{y} are equal in the sense of Scheme's
|
||||||
|
@code{eqv?} predicate, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_equal_p (SCM x, SCM y)
|
||||||
|
Returns 1 if @var{x} and @var{y} are equal in the sense of Scheme's
|
||||||
|
@code{equal?} predicate, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_string_equal_p (SCM @var{s1}, SCM @var{s2})
|
||||||
|
Returns 1 if the strings @var{s1} and @var{s2} are equal, 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_null_p (SCM @var{l})
|
||||||
|
Returns 1 if @var{l} is an empty list or pair; 0 otherwise.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Memory allocation and garbage collection
|
||||||
|
@section Memory allocation and garbage collection
|
||||||
|
|
||||||
|
@c [FIXME: flesh this out with some description of garbage collection in
|
||||||
|
@c scm/guile]
|
||||||
|
|
||||||
|
@c @deftypefun SCM gh_mkarray (int size)
|
||||||
|
@c Allocate memory for a Scheme object in a garbage-collector-friendly
|
||||||
|
@c manner.
|
||||||
|
@c @end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Calling Scheme procedures from C
|
||||||
|
@section Calling Scheme procedures from C
|
||||||
|
|
||||||
|
Many of the Scheme primitives are available in the @code{gh_}
|
||||||
|
interface; they take and return objects of type SCM, and one could
|
||||||
|
basically use them to write C code that mimics Scheme code.
|
||||||
|
|
||||||
|
I will list these routines here without much explanation, since what
|
||||||
|
they do is the same as documented in @ref{Standard Procedures, R4RS, ,
|
||||||
|
r4rs, R4RS}. But I will point out that when a procedure takes a
|
||||||
|
variable number of arguments (such as @code{gh_list}), you should pass
|
||||||
|
the constant @var{SCM_EOL} from C to signify the end of the list.
|
||||||
|
|
||||||
|
@deftypefun SCM gh_define (char *@var{name}, SCM @var{val})
|
||||||
|
Corresponds to the Scheme @code{(define name val)}: it binds a value to
|
||||||
|
the given name (which is a C string). Returns the new object.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@heading Pairs and lists
|
||||||
|
|
||||||
|
@deftypefun SCM gh_cons (SCM @var{a}, SCM @var{b})
|
||||||
|
@deftypefunx SCM gh_list (SCM l0, SCM l1, ... , SCM_UNDEFINED)
|
||||||
|
These correspond to the Scheme @code{(cons a b)} and @code{(list l0 l1
|
||||||
|
...)} procedures. Note that @code{gh_list()} is a C macro that invokes
|
||||||
|
@code{scm_listify()}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_set_car (SCM @var{obj}, SCM @var{val})
|
||||||
|
@deftypefunx SCM gh_set_cdr (SCM @var{obj}, SCM @var{val})
|
||||||
|
These correspond to the Scheme @code{(set-car! ...)} and @code{(set-cdr!
|
||||||
|
...)} procedures.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@deftypefun SCM gh_car (SCM @var{obj})
|
||||||
|
@deftypefunx SCM gh_cdr (SCM @var{obj})
|
||||||
|
@dots{}
|
||||||
|
|
||||||
|
@deftypefunx SCM gh_c[ad][ad][ad][ad]r (SCM @var{obj})
|
||||||
|
These correspond to the Scheme @code{(caadar ls)} procedures etc @dots{}
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_set_car_x(SCM @var{pair}, SCM @var{value})
|
||||||
|
Modifies the CAR of @var{pair} to be @var{value}. This is equivalent to
|
||||||
|
the Scheme procedure @code{(set-car! ...)}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_set_cdr_x(SCM @var{pair}, SCM @var{value})
|
||||||
|
Modifies the CDR of @var{pair} to be @var{value}. This is equivalent to
|
||||||
|
the Scheme procedure @code{(set-cdr! ...)}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun {unsigned long} gh_length (SCM @var{ls})
|
||||||
|
Returns the length of the list.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_append (SCM @var{args})
|
||||||
|
@deftypefunx SCM gh_append2 (SCM @var{l1}, SCM @var{l2})
|
||||||
|
@deftypefunx SCM gh_append3 (SCM @var{l1}, SCM @var{l2}, @var{l3})
|
||||||
|
@deftypefunx SCM gh_append4 (SCM @var{l1}, SCM @var{l2}, @var{l3}, @var{l4})
|
||||||
|
@code{gh_append()} takes @var{args}, which is a list of lists
|
||||||
|
@code{(list1 list2 ...)}, and returns a list containing all the elements
|
||||||
|
of the individual lists.
|
||||||
|
|
||||||
|
A typical invocation of @code{gh_append()} to append 5 lists together
|
||||||
|
would be
|
||||||
|
@smallexample
|
||||||
|
gh_append(gh_list(l1, l2, l3, l4, l5, SCM_UNDEFINED));
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The functions @code{gh_append2()}, @code{gh_append2()},
|
||||||
|
@code{gh_append3()} and @code{gh_append4()} are convenience routines to
|
||||||
|
make it easier for C programs to form the list of lists that goes as an
|
||||||
|
argument to @code{gh_append()}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_reverse (SCM @var{ls})
|
||||||
|
Returns a new list that has the same elements as @var{ls} but in the
|
||||||
|
reverse order. Note that this is implemented as a macro which calls
|
||||||
|
@code{scm_reverse()}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_list_tail (SCM @var{ls}, SCM @var{k})
|
||||||
|
Returns the sublist of @var{ls} with the last @var{k} elements.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_list_ref (SCM @var{ls}, SCM @var{k})
|
||||||
|
Returns the @var{k}th element of the list @var{ls}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_memq (SCM @var{x}, SCM @var{ls})
|
||||||
|
@deftypefunx SCM gh_memv (SCM @var{x}, SCM @var{ls})
|
||||||
|
@deftypefunx SCM gh_member (SCM @var{x}, SCM @var{ls})
|
||||||
|
These functions return the first sublist of @var{ls} whose CAR is
|
||||||
|
@var{x}. They correspond to @code{(memq x ls)}, @code{(memv x ls)} and
|
||||||
|
@code{(member x ls)}, and hence use (respectively) @code{eq?},
|
||||||
|
@code{eqv?} and @code{equal?} to do comparisons.
|
||||||
|
|
||||||
|
If @var{x} does not appear in @var{ls}, the value @code{SCM_BOOL_F} (not
|
||||||
|
the empty list) is returned.
|
||||||
|
|
||||||
|
Note that these functions are implemented as macros which call
|
||||||
|
@code{scm_memq()}, @code{scm_memv()} and @code{scm_member()}
|
||||||
|
respectively.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_assq (SCM @var{x}, SCM @var{alist})
|
||||||
|
@deftypefunx SCM gh_assv (SCM @var{x}, SCM @var{alist})
|
||||||
|
@deftypefunx SCM gh_assoc (SCM @var{x}, SCM @var{alist})
|
||||||
|
These functions search an @dfn{association list} (list of pairs)
|
||||||
|
@var{alist} for the first pair whose CAR is @var{x}, and they return
|
||||||
|
that pair.
|
||||||
|
|
||||||
|
If no pair in @var{alist} has @var{x} as its CAR, the value
|
||||||
|
@code{SCM_BOOL_F} (not the empty list) is returned.
|
||||||
|
|
||||||
|
Note that these functions are implemented as macros which call
|
||||||
|
@code{scm_assq()}, @code{scm_assv()} and @code{scm_assoc()}
|
||||||
|
respectively.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@heading Symbols
|
||||||
|
|
||||||
|
@c @deftypefun SCM gh_symbol (SCM str, SCM len)
|
||||||
|
@c @deftypefunx SCM gh_tmp_symbol (SCM str, SCM len)
|
||||||
|
@c Takes the given string @var{str} of length @var{len} and returns a
|
||||||
|
@c symbol corresponding to that string.
|
||||||
|
@c @end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@heading Vectors
|
||||||
|
|
||||||
|
@deftypefun SCM gh_make_vector (SCM @var{n}, SCM @var{fill})
|
||||||
|
@deftypefunx SCM gh_vector (SCM @var{ls})
|
||||||
|
@deftypefunx SCM gh_vector_ref (SCM @var{v}, SCM @var{i})
|
||||||
|
@deftypefunx SCM gh_vector_set (SCM @var{v}, SCM @var{i}, SCM @var{val})
|
||||||
|
@deftypefunx {unsigned long} gh_vector_length (SCM @var{v})
|
||||||
|
@deftypefunx SCM gh_list_to_vector (SCM @var{ls})
|
||||||
|
These correspond to the Scheme @code{(make-vector n fill)},
|
||||||
|
@code{(vector a b c ...)} @code{(vector-ref v i)} @code{(vector-set v i
|
||||||
|
value)} @code{(vector-length v)} @code{(list->vector ls)} procedures.
|
||||||
|
|
||||||
|
The correspondence is not perfect for @code{gh_vector}: this routine
|
||||||
|
taks a list @var{ls} instead of the individual list elements, thus
|
||||||
|
making it identical to @code{gh_list_to_vector}.
|
||||||
|
|
||||||
|
There is also a difference in gh_vector_length: the value returned is a
|
||||||
|
C @code{unsigned long} instead of an SCM object.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@heading Procedures
|
||||||
|
|
||||||
|
@c @deftypefun SCM gh_make_subr (SCM (*@var{fn})(), int @var{req}, int @var{opt}, int @var{restp}, char *@var{sym})
|
||||||
|
@c Make the C function @var{fn} available to Scheme programs. The function
|
||||||
|
@c will be bound to the symbol @var{sym}. The arguments @var{req},
|
||||||
|
@c @var{opt} and @var{restp} describe @var{fn}'s calling conventions. The
|
||||||
|
@c function must take @var{req} required arguments and may take @var{opt}
|
||||||
|
@c optional arguments. Any optional arguments which are not supplied by
|
||||||
|
@c the caller will be bound to @var{SCM_UNSPECIFIED}. If @var{restp} is
|
||||||
|
@c non-zero, it means that @var{fn} may be called with an arbitrary number
|
||||||
|
@c of arguments, and that any extra arguments supplied by the caller will
|
||||||
|
@c be passed to @var{fn} as a list. The @var{restp} argument is exactly
|
||||||
|
@c like Scheme's @code{(lambda (arg1 arg2 . arglist))} calling convention.
|
||||||
|
@c
|
||||||
|
@c For example, the procedure @code{read-line}, which takes optional
|
||||||
|
@c @var{port} and @var{handle-delim} arguments, would be declared like so:
|
||||||
|
@c
|
||||||
|
@c @example
|
||||||
|
@c SCM scm_read_line (SCM port, SCM handle_delim);
|
||||||
|
@c gh_make_subr (scm_read_line, 0, 2, 0, "read-line");
|
||||||
|
@c @end example
|
||||||
|
@c
|
||||||
|
@c The @var{req} argument to @code{gh_make_subr} is 0 to indicate that
|
||||||
|
@c there are no required arguments, so @code{read-line} may be called
|
||||||
|
@c without any arguments at all. The @var{opt} argument is 2, to indicate
|
||||||
|
@c that both the @var{port} and @var{handle_delim} arguments to
|
||||||
|
@c @code{scm_read_line} are optional, and will be bound to
|
||||||
|
@c @code{SCM_UNSPECIFIED} if the calling program does not supply them.
|
||||||
|
@c Because the @var{restp} argument is 0, this function may not be called
|
||||||
|
@c with more than two arguments.
|
||||||
|
@c @end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_apply (SCM proc, SCM args)
|
||||||
|
Call the Scheme procedure @var{proc}, with the elements of @var{args} as
|
||||||
|
arguments. @var{args} must be a proper list.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun SCM gh_call0 (SCM proc)
|
||||||
|
@deftypefunx SCM gh_call1 (SCM proc, SCM arg)
|
||||||
|
@deftypefunx SCM gh_call2 (SCM proc, SCM arg1, SCM arg2)
|
||||||
|
@deftypefunx SCM gh_call3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
|
||||||
|
Call the Scheme procedure @var{proc} with no arguments
|
||||||
|
(@code{gh_call0}), one argument (@code{gh_call1}), and so on. You can
|
||||||
|
get the same effect by wrapping the arguments up into a list, and
|
||||||
|
calling @code{gh_apply}; Guile provides these functions for convenience.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@deftypefun SCM gh_catch (SCM key, SCM thunk, SCM handler)
|
||||||
|
@deftypefunx SCM gh_throw (SCM key, SCM args)
|
||||||
|
Corresponds to the Scheme @code{catch} and @code{throw} procedures,
|
||||||
|
which in Guile are provided as primitives.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@c [FIXME: must add the I/O section in gscm.h]
|
||||||
|
|
||||||
|
@deftypefun SCM gh_is_eq (SCM a, SCM b)
|
||||||
|
@deftypefunx SCM gh_is_eqv (SCM a, SCM b)
|
||||||
|
@deftypefunx SCM gh_is_equal (SCM a, SCM b)
|
||||||
|
These correspond to the Scheme @code{eq?}, @code{eqv?} and @code{equal?}
|
||||||
|
predicates.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun int gh_obj_length (SCM @var{obj})
|
||||||
|
Returns the raw object length.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@heading Data lookup
|
||||||
|
|
||||||
|
For now I just include Tim Pierce's comments from the @file{gh_data.c}
|
||||||
|
file; it should be organized into a documentation of the two functions
|
||||||
|
here.
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
/* Data lookups between C and Scheme
|
||||||
|
|
||||||
|
Look up a symbol with a given name, and return the object to which
|
||||||
|
it is bound. gh_lookup examines the Guile top level, and
|
||||||
|
gh_module_lookup checks the module namespace specified by the
|
||||||
|
`vec' argument.
|
||||||
|
|
||||||
|
The return value is the Scheme object to which SNAME is bound, or
|
||||||
|
SCM_UNDEFINED if SNAME is not bound in the given context. [FIXME:
|
||||||
|
should this be SCM_UNSPECIFIED? Can a symbol ever legitimately be
|
||||||
|
bound to SCM_UNDEFINED or SCM_UNSPECIFIED? What is the difference?
|
||||||
|
-twp] */
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Mixing gh and scm APIs
|
||||||
|
@section Mixing gh and scm APIs
|
809
doc/goops-tutorial.texi
Normal file
809
doc/goops-tutorial.texi
Normal file
|
@ -0,0 +1,809 @@
|
||||||
|
@c Original attribution:
|
||||||
|
|
||||||
|
@c
|
||||||
|
@c STk Reference manual (Appendix: An Introduction to STklos)
|
||||||
|
@c
|
||||||
|
@c Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
|
||||||
|
@c Permission to use, copy, modify, distribute,and license this
|
||||||
|
@c software and its documentation for any purpose is hereby granted,
|
||||||
|
@c provided that existing copyright notices are retained in all
|
||||||
|
@c copies and that this notice is included verbatim in any
|
||||||
|
@c distributions. No written agreement, license, or royalty fee is
|
||||||
|
@c required for any of the authorized uses.
|
||||||
|
@c This software is provided ``AS IS'' without express or implied
|
||||||
|
@c warranty.
|
||||||
|
@c
|
||||||
|
|
||||||
|
@c Adapted for use in Guile with the authors permission
|
||||||
|
|
||||||
|
@c @macro goops @c was {\stklos}
|
||||||
|
@c GOOPS
|
||||||
|
@c @end macro
|
||||||
|
|
||||||
|
@c @macro guile @c was {\stk}
|
||||||
|
@c Guile
|
||||||
|
@c @end macro
|
||||||
|
|
||||||
|
This is chapter was originally written by Erick Gallesio as an appendix
|
||||||
|
for the STk reference manual, and subsequently adapted to @goops{}.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Copyright::
|
||||||
|
* Intro::
|
||||||
|
* Class definition and instantiation::
|
||||||
|
* Inheritance::
|
||||||
|
* Generic functions::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Copyright, Intro, Tutorial, Tutorial
|
||||||
|
@section Copyright
|
||||||
|
|
||||||
|
Original attribution:
|
||||||
|
|
||||||
|
STk Reference manual (Appendix: An Introduction to STklos)
|
||||||
|
|
||||||
|
Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@@unice.fr>
|
||||||
|
Permission to use, copy, modify, distribute,and license this
|
||||||
|
software and its documentation for any purpose is hereby granted,
|
||||||
|
provided that existing copyright notices are retained in all
|
||||||
|
copies and that this notice is included verbatim in any
|
||||||
|
distributions. No written agreement, license, or royalty fee is
|
||||||
|
required for any of the authorized uses.
|
||||||
|
This software is provided ``AS IS'' without express or implied
|
||||||
|
warranty.
|
||||||
|
|
||||||
|
Adapted for use in Guile with the authors permission
|
||||||
|
|
||||||
|
@node Intro, Class definition and instantiation, Copyright, Tutorial
|
||||||
|
@section Introduction
|
||||||
|
|
||||||
|
@goops{} is the object oriented extension to @guile{}. Its
|
||||||
|
implementation is derived from @w{STk-3.99.3} by Erick Gallesio and
|
||||||
|
version 1.3 of the Gregor Kiczales @cite{Tiny-Clos}. It is very close
|
||||||
|
to CLOS, the Common Lisp Object System (@cite{CLtL2}) but is adapted for
|
||||||
|
the Scheme language.
|
||||||
|
|
||||||
|
Briefly stated, the @goops{} extension gives the user a full object
|
||||||
|
oriented system with multiple inheritance and generic functions with
|
||||||
|
multi-method dispatch. Furthermore, the implementation relies on a true
|
||||||
|
meta object protocol, in the spirit of the one defined for CLOS
|
||||||
|
(@cite{Gregor Kiczales: A Metaobject Protocol}).
|
||||||
|
|
||||||
|
The purpose of this tutorial is to introduce briefly the @goops{}
|
||||||
|
package and in no case will it replace the @goops{} reference manual
|
||||||
|
(which needs to be urgently written now@ @dots{}).
|
||||||
|
|
||||||
|
Note that the operations described in this tutorial resides in modules
|
||||||
|
that may need to be imported before being available. The main module is
|
||||||
|
imported by evaluating:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(use-modules (oop goops))
|
||||||
|
@end lisp
|
||||||
|
@findex (oop goops)
|
||||||
|
@cindex main module
|
||||||
|
@cindex loading
|
||||||
|
@cindex preparing
|
||||||
|
|
||||||
|
@node Class definition and instantiation, Inheritance, Intro, Tutorial
|
||||||
|
@section Class definition and instantiation
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Class definition::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Class definition, , Class definition and instantiation, Class definition and instantiation
|
||||||
|
@subsection Class definition
|
||||||
|
|
||||||
|
A new class is defined with the @code{define-class}@footnote{Don't
|
||||||
|
forget to import the @code{(oop goops)} module} macro. The syntax of
|
||||||
|
@code{define-class} is close to CLOS @code{defclass}:
|
||||||
|
|
||||||
|
@findex define-class
|
||||||
|
@cindex class
|
||||||
|
@lisp
|
||||||
|
(define-class @var{class} (@var{superclass} @dots{})
|
||||||
|
@var{slot-description} @dots{}
|
||||||
|
@var{class-option} @dots{})
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
Class options will not be discussed in this tutorial. The list of
|
||||||
|
@var{superclass}es specifies which classes to inherit properties from
|
||||||
|
@var{class} (see @ref{Inheritance} for more details). A
|
||||||
|
@var{slot-description} gives the name of a slot and, eventually, some
|
||||||
|
``properties'' of this slot (such as its initial value, the function
|
||||||
|
which permit to access its value, @dots{}). Slot descriptions will be
|
||||||
|
discussed in @ref{Slot description}.
|
||||||
|
@cindex slot
|
||||||
|
|
||||||
|
As an example, let us define a type for representation of complex
|
||||||
|
numbers in terms of real numbers. This can be done with the following
|
||||||
|
class definition:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-class <complex> (<number>)
|
||||||
|
r i)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
This binds the variable @code{<complex>}@footnote{@code{<complex>} is in
|
||||||
|
fact a builtin class in GOOPS. Because of this, GOOPS will create a new
|
||||||
|
class. The old class will still serve as the type for Guile's native
|
||||||
|
complex numbers.} to a new class whose instances contain two
|
||||||
|
slots. These slots are called @code{r} an @code{i} and we suppose here
|
||||||
|
that they contain respectively the real part and the imaginary part of a
|
||||||
|
complex number. Note that this class inherits from @code{<number>} which
|
||||||
|
is a pre-defined class. (@code{<number>} is the direct super class of
|
||||||
|
the pre-defined class @code{<complex>} which, in turn, is the super
|
||||||
|
class of @code{<real>} which is the super of
|
||||||
|
@code{<integer>}.)@footnote{With the new definition of @code{<complex>},
|
||||||
|
a @code{<real>} is not a @code{<complex>} since @code{<real>} inherits
|
||||||
|
from @code{ <number>} rather than @code{<complex>}. In practice,
|
||||||
|
inheritance could be modified @emph{a posteriori}, if needed. However,
|
||||||
|
this necessitates some knowledge of the meta object protocol and it will
|
||||||
|
not be shown in this document}.
|
||||||
|
|
||||||
|
@node Inheritance, Generic functions, Class definition and instantiation, Tutorial
|
||||||
|
@section Inheritance
|
||||||
|
@c \label{inheritance}
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Class hierarchy and inheritance of slots::
|
||||||
|
* Instance creation and slot access::
|
||||||
|
* Slot description::
|
||||||
|
* Class precedence list::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Class hierarchy and inheritance of slots, Instance creation and slot access, Inheritance, Inheritance
|
||||||
|
@subsection Class hierarchy and inheritance of slots
|
||||||
|
Inheritance is specified upon class definition. As said in the
|
||||||
|
introduction, @goops{} supports multiple inheritance. Here are some
|
||||||
|
class definitions:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-class A () a)
|
||||||
|
(define-class B () b)
|
||||||
|
(define-class C () c)
|
||||||
|
(define-class D (A B) d a)
|
||||||
|
(define-class E (A C) e c)
|
||||||
|
(define-class F (D E) f)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@code{A}, @code{B}, @code{C} have a null list of super classes. In this
|
||||||
|
case, the system will replace it by the list which only contains
|
||||||
|
@code{<object>}, the root of all the classes defined by
|
||||||
|
@code{define-class}. @code{D}, @code{E}, @code{F} use multiple
|
||||||
|
inheritance: each class inherits from two previously defined classes.
|
||||||
|
Those class definitions define a hierarchy which is shown in Figure@ 1.
|
||||||
|
In this figure, the class @code{<top>} is also shown; this class is the
|
||||||
|
super class of all Scheme objects. In particular, @code{<top>} is the
|
||||||
|
super class of all standard Scheme types.
|
||||||
|
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
@image{hierarchy}
|
||||||
|
@center @emph{Fig 1: A class hierarchy}
|
||||||
|
@iftex
|
||||||
|
@emph{(@code{<complex>} which is the direct subclass of @code{<number>}
|
||||||
|
and the direct superclass of @code{<real>} has been omitted in this
|
||||||
|
figure.)}
|
||||||
|
@end iftex
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The set of slots of a given class is calculated by taking the union of the
|
||||||
|
slots of all its super class. For instance, each instance of the class
|
||||||
|
D, defined before will have three slots (@code{a}, @code{b} and
|
||||||
|
@code{d}). The slots of a class can be obtained by the @code{class-slots}
|
||||||
|
primitive. For instance,
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(class-slots A) @result{} ((a))
|
||||||
|
(class-slots E) @result{} ((a) (e) (c))
|
||||||
|
(class-slots F) @result{} ((e) (c) (b) (d) (a) (f))
|
||||||
|
@c used to be ((d) (a) (b) (c) (f))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@emph{Note: } The order of slots is not significant.
|
||||||
|
|
||||||
|
@node Instance creation and slot access, Slot description, Class hierarchy and inheritance of slots, Inheritance
|
||||||
|
@subsection Instance creation and slot access
|
||||||
|
|
||||||
|
Creation of an instance of a previously defined
|
||||||
|
class can be done with the @code{make} procedure. This
|
||||||
|
procedure takes one mandatory parameter which is the class of the
|
||||||
|
instance which must be created and a list of optional
|
||||||
|
arguments. Optional arguments are generally used to initialize some
|
||||||
|
slots of the newly created instance. For instance, the following form
|
||||||
|
|
||||||
|
@findex make
|
||||||
|
@cindex instance
|
||||||
|
@lisp
|
||||||
|
(define c (make <complex>))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
will create a new @code{<complex>} object and will bind it to the @code{c}
|
||||||
|
Scheme variable.
|
||||||
|
|
||||||
|
Accessing the slots of the new complex number can be done with the
|
||||||
|
@code{slot-ref} and the @code{slot-set!} primitives. @code{Slot-set!}
|
||||||
|
primitive permits to set the value of an object slot and @code{slot-ref}
|
||||||
|
permits to get its value.
|
||||||
|
|
||||||
|
@findex slot-set!
|
||||||
|
@findex slot-ref
|
||||||
|
@lisp
|
||||||
|
@group
|
||||||
|
(slot-set! c 'r 10)
|
||||||
|
(slot-set! c 'i 3)
|
||||||
|
(slot-ref c 'r) @result{} 10
|
||||||
|
(slot-ref c 'i) @result{} 3
|
||||||
|
@end group
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
Using the @code{describe} function is a simple way to see all the
|
||||||
|
slots of an object at one time: this function prints all the slots of an
|
||||||
|
object on the standard output.
|
||||||
|
|
||||||
|
First load the module @code{(oop goops describe)}:
|
||||||
|
|
||||||
|
@example
|
||||||
|
@code{(use-modules (oop goops describe))}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The expression
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
(describe c)
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
will now print the following information on the standard output:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
#<<complex> 401d8638> is an instance of class <complex>
|
||||||
|
Slots are:
|
||||||
|
r = 10
|
||||||
|
i = 3
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@node Slot description, Class precedence list, Instance creation and slot access, Inheritance
|
||||||
|
@subsection Slot description
|
||||||
|
@c \label{slot-description}
|
||||||
|
|
||||||
|
When specifying a slot, a set of options can be given to the
|
||||||
|
system. Each option is specified with a keyword. The list of authorized
|
||||||
|
keywords is given below:
|
||||||
|
|
||||||
|
@cindex keyword
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
@code{#:init-value} permits to supply a default value for the slot. This
|
||||||
|
default value is obtained by evaluating the form given after the
|
||||||
|
@code{#:init-form} in the global environment, at class definition time.
|
||||||
|
@cindex default slot value
|
||||||
|
@findex #:init-value
|
||||||
|
@cindex top level environment
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{#:init-thunk} permits to supply a thunk that will provide a
|
||||||
|
default value for the slot. The value is obtained by evaluating the
|
||||||
|
thunk a instance creation time.
|
||||||
|
@c CHECKME: in the global environment?
|
||||||
|
@findex default slot value
|
||||||
|
@findex #:init-thunk
|
||||||
|
@cindex top level environment
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{#:init-keyword} permits to specify the keyword for initializing a
|
||||||
|
slot. The init-keyword may be provided during instance creation (i.e. in
|
||||||
|
the @code{make} optional parameter list). Specifying such a keyword
|
||||||
|
during instance initialization will supersede the default slot
|
||||||
|
initialization possibly given with @code{#:init-form}.
|
||||||
|
@findex #:init-keyword
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{#:getter} permits to supply the name for the
|
||||||
|
slot getter. The name binding is done in the
|
||||||
|
environment of the @code{define-class} macro.
|
||||||
|
@findex #:getter
|
||||||
|
@cindex top level environment
|
||||||
|
@cindex getter
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{#:setter} permits to supply the name for the
|
||||||
|
slot setter. The name binding is done in the
|
||||||
|
environment of the @code{define-class} macro.
|
||||||
|
@findex #:setter
|
||||||
|
@cindex top level environment
|
||||||
|
@cindex setter
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{#:accessor} permits to supply the name for the
|
||||||
|
slot accessor. The name binding is done in the global
|
||||||
|
environment. An accessor permits to get and
|
||||||
|
set the value of a slot. Setting the value of a slot is done with the extended
|
||||||
|
version of @code{set!}.
|
||||||
|
@findex set!
|
||||||
|
@findex #:accessor
|
||||||
|
@cindex top level environment
|
||||||
|
@cindex accessor
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{#:allocation} permits to specify how storage for
|
||||||
|
the slot is allocated. Three kinds of allocation are provided.
|
||||||
|
They are described below:
|
||||||
|
|
||||||
|
@itemize @minus
|
||||||
|
@item
|
||||||
|
@code{#:instance} indicates that each instance gets its own storage for
|
||||||
|
the slot. This is the default.
|
||||||
|
@item
|
||||||
|
@code{#:class} indicates that there is one storage location used by all
|
||||||
|
the direct and indirect instances of the class. This permits to define a
|
||||||
|
kind of global variable which can be accessed only by (in)direct
|
||||||
|
instances of the class which defines this slot.
|
||||||
|
@item
|
||||||
|
@code{#:each-subclass} indicates that there is one storage location used
|
||||||
|
by all the direct instances of the class. In other words, if two classes
|
||||||
|
are not siblings in the class hierarchy, they will not see the same
|
||||||
|
value.
|
||||||
|
@item
|
||||||
|
@code{#:virtual} indicates that no storage will be allocated for this
|
||||||
|
slot. It is up to the user to define a getter and a setter function for
|
||||||
|
this slot. Those functions must be defined with the @code{#:slot-ref}
|
||||||
|
and @code{#:slot-set!} options. See the example below.
|
||||||
|
@findex #:slot-set!
|
||||||
|
@findex #:slot-ref
|
||||||
|
@findex #:virtual
|
||||||
|
@findex #:class
|
||||||
|
@findex #:each-subclass
|
||||||
|
@findex #:instance
|
||||||
|
@findex #:allocation
|
||||||
|
@end itemize
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
To illustrate slot description, we shall redefine the @code{<complex>} class
|
||||||
|
seen before. A definition could be:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-class <complex> (<number>)
|
||||||
|
(r #:init-value 0 #:getter get-r #:setter set-r! #:init-keyword #:r)
|
||||||
|
(i #:init-value 0 #:getter get-i #:setter set-i! #:init-keyword #:i))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
With this definition, the @code{r} and @code{i} slot are set to 0 by
|
||||||
|
default. Value of a slot can also be specified by calling @code{make}
|
||||||
|
with the @code{#:r} and @code{#:i} keywords. Furthermore, the generic
|
||||||
|
functions @code{get-r} and @code{set-r!} (resp. @code{get-i} and
|
||||||
|
@code{set-i!}) are automatically defined by the system to read and write
|
||||||
|
the @code{r} (resp. @code{i}) slot.
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define c1 (make <complex> #:r 1 #:i 2))
|
||||||
|
(get-r c1) @result{} 1
|
||||||
|
(set-r! c1 12)
|
||||||
|
(get-r c1) @result{} 12
|
||||||
|
(define c2 (make <complex> #:r 2))
|
||||||
|
(get-r c2) @result{} 2
|
||||||
|
(get-i c2) @result{} 0
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
Accessors provide an uniform access for reading and writing an object
|
||||||
|
slot. Writing a slot is done with an extended form of @code{set!}
|
||||||
|
which is close to the Common Lisp @code{setf} macro. So, another
|
||||||
|
definition of the previous @code{<complex>} class, using the
|
||||||
|
@code{#:accessor} option, could be:
|
||||||
|
|
||||||
|
@findex set!
|
||||||
|
@lisp
|
||||||
|
(define-class <complex> (<number>)
|
||||||
|
(r #:init-value 0 #:accessor real-part #:init-keyword #:r)
|
||||||
|
(i #:init-value 0 #:accessor imag-part #:init-keyword #:i))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
Using this class definition, reading the real part of the @code{c}
|
||||||
|
complex can be done with:
|
||||||
|
@lisp
|
||||||
|
(real-part c)
|
||||||
|
@end lisp
|
||||||
|
and setting it to the value contained in the @code{new-value} variable
|
||||||
|
can be done using the extended form of @code{set!}.
|
||||||
|
@lisp
|
||||||
|
(set! (real-part c) new-value)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
Suppose now that we have to manipulate complex numbers with rectangular
|
||||||
|
coordinates as well as with polar coordinates. One solution could be to
|
||||||
|
have a definition of complex numbers which uses one particular
|
||||||
|
representation and some conversion functions to pass from one
|
||||||
|
representation to the other. A better solution uses virtual slots. A
|
||||||
|
complete definition of the @code{<complex>} class using virtual slots is
|
||||||
|
given in Figure@ 2.
|
||||||
|
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
@lisp
|
||||||
|
(define-class <complex> (<number>)
|
||||||
|
;; True slots use rectangular coordinates
|
||||||
|
(r #:init-value 0 #:accessor real-part #:init-keyword #:r)
|
||||||
|
(i #:init-value 0 #:accessor imag-part #:init-keyword #:i)
|
||||||
|
;; Virtual slots access do the conversion
|
||||||
|
(m #:accessor magnitude #:init-keyword #:magn
|
||||||
|
#:allocation #:virtual
|
||||||
|
#:slot-ref (lambda (o)
|
||||||
|
(let ((r (slot-ref o 'r)) (i (slot-ref o 'i)))
|
||||||
|
(sqrt (+ (* r r) (* i i)))))
|
||||||
|
#:slot-set! (lambda (o m)
|
||||||
|
(let ((a (slot-ref o 'a)))
|
||||||
|
(slot-set! o 'r (* m (cos a)))
|
||||||
|
(slot-set! o 'i (* m (sin a))))))
|
||||||
|
(a #:accessor angle #:init-keyword #:angle
|
||||||
|
#:allocation #:virtual
|
||||||
|
#:slot-ref (lambda (o)
|
||||||
|
(atan (slot-ref o 'i) (slot-ref o 'r)))
|
||||||
|
#:slot-set! (lambda(o a)
|
||||||
|
(let ((m (slot-ref o 'm)))
|
||||||
|
(slot-set! o 'r (* m (cos a)))
|
||||||
|
(slot-set! o 'i (* m (sin a)))))))
|
||||||
|
|
||||||
|
@end lisp
|
||||||
|
@center @emph{Fig 2: A @code{<complex>} number class definition using virtual slots}
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@sp 3
|
||||||
|
This class definition implements two real slots (@code{r} and
|
||||||
|
@code{i}). Values of the @code{m} and @code{a} virtual slots are
|
||||||
|
calculated from real slot values. Reading a virtual slot leads to the
|
||||||
|
application of the function defined in the @code{#:slot-ref}
|
||||||
|
option. Writing such a slot leads to the application of the function
|
||||||
|
defined in the @code{#:slot-set!} option. For instance, the following
|
||||||
|
expression
|
||||||
|
|
||||||
|
@findex #:slot-set!
|
||||||
|
@findex #:slot-ref
|
||||||
|
@lisp
|
||||||
|
(slot-set! c 'a 3)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
permits to set the angle of the @code{c} complex number. This expression
|
||||||
|
conducts, in fact, to the evaluation of the following expression
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
((lambda o m)
|
||||||
|
(let ((m (slot-ref o 'm)))
|
||||||
|
(slot-set! o 'r (* m (cos a)))
|
||||||
|
(slot-set! o 'i (* m (sin a))))
|
||||||
|
c 3)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
A more complete example is given below:
|
||||||
|
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
@lisp
|
||||||
|
(define c (make <complex> #:r 12 #:i 20))
|
||||||
|
(real-part c) @result{} 12
|
||||||
|
(angle c) @result{} 1.03037682652431
|
||||||
|
(slot-set! c 'i 10)
|
||||||
|
(set! (real-part c) 1)
|
||||||
|
(describe c) @result{}
|
||||||
|
#<<complex> 401e9b58> is an instance of class <complex>
|
||||||
|
Slots are:
|
||||||
|
r = 1
|
||||||
|
i = 10
|
||||||
|
m = 10.0498756211209
|
||||||
|
a = 1.47112767430373
|
||||||
|
@end lisp
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Since initialization keywords have been defined for the four slots, we
|
||||||
|
can now define the @code{make-rectangular} and @code{make-polar} standard
|
||||||
|
Scheme primitives.
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define make-rectangular
|
||||||
|
(lambda (x y) (make <complex> #:r x #:i y)))
|
||||||
|
|
||||||
|
(define make-polar
|
||||||
|
(lambda (x y) (make <complex> #:magn x #:angle y)))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@node Class precedence list, , Slot description, Inheritance
|
||||||
|
@subsection Class precedence list
|
||||||
|
|
||||||
|
A class may have more than one superclass. @footnote{This section is an
|
||||||
|
adaptation of Jeff Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief
|
||||||
|
introduction to CLOS}} With single inheritance (one superclass), it is
|
||||||
|
easy to order the super classes from most to least specific. This is the
|
||||||
|
rule:
|
||||||
|
|
||||||
|
@display
|
||||||
|
@cartouche
|
||||||
|
Rule 1: Each class is more specific than its superclasses.@c was \bf
|
||||||
|
@end cartouche
|
||||||
|
@end display
|
||||||
|
|
||||||
|
With multiple inheritance, ordering is harder. Suppose we have
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-class X ()
|
||||||
|
(x #:init-value 1))
|
||||||
|
|
||||||
|
(define-class Y ()
|
||||||
|
(x #:init-value 2))
|
||||||
|
|
||||||
|
(define-class Z (X Y)
|
||||||
|
(@dots{}))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
In this case, the @code{Z} class is more specific than the @code{X} or
|
||||||
|
@code{Y} class for instances of @code{Z}. However, the @code{#:init-value}
|
||||||
|
specified in @code{X} and @code{Y} leads to a problem: which one
|
||||||
|
overrides the other? The rule in @goops{}, as in CLOS, is that the
|
||||||
|
superclasses listed earlier are more specific than those listed later.
|
||||||
|
So:
|
||||||
|
|
||||||
|
@display
|
||||||
|
@cartouche
|
||||||
|
Rule 2: For a given class, superclasses listed earlier are more
|
||||||
|
specific than those listed later.
|
||||||
|
@end cartouche
|
||||||
|
@end display
|
||||||
|
|
||||||
|
These rules are used to compute a linear order for a class and all its
|
||||||
|
superclasses, from most specific to least specific. This order is
|
||||||
|
called the ``class precedence list'' of the class. Given these two
|
||||||
|
rules, we can claim that the initial form for the @code{x} slot of
|
||||||
|
previous example is 1 since the class @code{X} is placed before @code{Y}
|
||||||
|
in class precedence list of @code{Z}.
|
||||||
|
|
||||||
|
These two rules are not always enough to determine a unique order,
|
||||||
|
however, but they give an idea of how things work. Taking the @code{F}
|
||||||
|
class shown in Figure@ 1, the class precedence list is
|
||||||
|
|
||||||
|
@example
|
||||||
|
(f d e a c b <object> <top>)
|
||||||
|
@end example
|
||||||
|
|
||||||
|
However, it is usually considered a bad idea for programmers to rely on
|
||||||
|
exactly what the order is. If the order for some superclasses is important,
|
||||||
|
it can be expressed directly in the class definition.
|
||||||
|
|
||||||
|
The precedence list of a class can be obtained by the function
|
||||||
|
@code{class-precedence-list}. This function returns a ordered
|
||||||
|
list whose first element is the most specific class. For instance,
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(class-precedence-list B) @result{} (#<<class> B 401b97c8>
|
||||||
|
#<<class> <object> 401e4a10>
|
||||||
|
#<<class> <top> 4026a9d8>)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
However, this result is not too much readable; using the function
|
||||||
|
@code{class-name} yields a clearer result:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(map class-name (class-precedence-list B)) @result{} (B <object> <top>)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@node Generic functions, , Inheritance, Tutorial
|
||||||
|
@section Generic functions
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Generic functions and methods::
|
||||||
|
* Next-method::
|
||||||
|
* Example::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Generic functions and methods, Next-method, Generic functions, Generic functions
|
||||||
|
@subsection Generic functions and methods
|
||||||
|
|
||||||
|
@c \label{gf-n-methods}
|
||||||
|
Neither @goops{} nor CLOS use the message mechanism for methods as most
|
||||||
|
Object Oriented language do. Instead, they use the notion of
|
||||||
|
@dfn{generic functions}. A generic function can be seen as a methods
|
||||||
|
``tanker''. When the evaluator requested the application of a generic
|
||||||
|
function, all the methods of this generic function will be grabbed and
|
||||||
|
the most specific among them will be applied. We say that a method
|
||||||
|
@var{M} is @emph{more specific} than a method @var{M'} if the class of
|
||||||
|
its parameters are more specific than the @var{M'} ones. To be more
|
||||||
|
precise, when a generic function must be ``called'' the system will:
|
||||||
|
|
||||||
|
@cindex generic function
|
||||||
|
@enumerate
|
||||||
|
@item
|
||||||
|
search among all the generic function those which are applicable
|
||||||
|
@item
|
||||||
|
sort the list of applicable methods in the ``most specific'' order
|
||||||
|
@item
|
||||||
|
call the most specific method of this list (i.e. the first method of
|
||||||
|
the sorted methods list).
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
The definition of a generic function is done with the
|
||||||
|
@code{define-generic} macro. Definition of a new method is done with the
|
||||||
|
@code{define-method} macro. Note that @code{define-method} automatically
|
||||||
|
defines the generic function if it has not been defined
|
||||||
|
before. Consequently, most of the time, the @code{define-generic} needs
|
||||||
|
not be used.
|
||||||
|
@findex define-generic
|
||||||
|
@findex define-method
|
||||||
|
Consider the following definitions:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-generic G)
|
||||||
|
(define-method G ((a <integer>) b) 'integer)
|
||||||
|
(define-method G ((a <real>) b) 'real)
|
||||||
|
(define-method G (a b) 'top)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
The @code{define-generic} call defines @var{G} as a generic
|
||||||
|
function. Note that the signature of the generic function is not given
|
||||||
|
upon definition, contrarily to CLOS. This will permit methods with
|
||||||
|
different signatures for a given generic function, as we shall see
|
||||||
|
later. The three next lines define methods for the @var{G} generic
|
||||||
|
function. Each method uses a sequence of @dfn{parameter specializers}
|
||||||
|
that specify when the given method is applicable. A specializer permits
|
||||||
|
to indicate the class a parameter must belong to (directly or
|
||||||
|
indirectly) to be applicable. If no specializer is given, the system
|
||||||
|
defaults it to @code{<top>}. Thus, the first method definition is
|
||||||
|
equivalent to
|
||||||
|
|
||||||
|
@cindex parameter specializers
|
||||||
|
@lisp
|
||||||
|
(define-method G ((a <integer>) (b <top>)) 'integer)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
Now, let us look at some possible calls to generic function @var{G}:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(G 2 3) @result{} integer
|
||||||
|
(G 2 #t) @result{} integer
|
||||||
|
(G 1.2 'a) @result{} real
|
||||||
|
@c (G #3 'a) @result{} real @c was {\sharpsign}
|
||||||
|
(G #t #f) @result{} top
|
||||||
|
(G 1 2 3) @result{} error (since no method exists for 3 parameters)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
The preceding methods use only one specializer per parameter list. Of
|
||||||
|
course, each parameter can use a specializer. In this case, the
|
||||||
|
parameter list is scanned from left to right to determine the
|
||||||
|
applicability of a method. Suppose we declare now
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-method G ((a <integer>) (b <number>)) 'integer-number)
|
||||||
|
(define-method G ((a <integer>) (b <real>)) 'integer-real)
|
||||||
|
(define-method G ((a <integer>) (b <integer>)) 'integer-integer)
|
||||||
|
(define-method G (a (b <number>)) 'top-number)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
In this case,
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(G 1 2) @result{} integer-integer
|
||||||
|
(G 1 1.0) @result{} integer-real
|
||||||
|
(G 1 #t) @result{} integer
|
||||||
|
(G 'a 1) @result{} top-number
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@node Next-method, Example, Generic functions and methods, Generic functions
|
||||||
|
@subsection Next-method
|
||||||
|
|
||||||
|
When a generic function is called, the list of applicable methods is
|
||||||
|
built. As mentioned before, the most specific method of this list is
|
||||||
|
applied (see@ @ref{Generic functions and methods}). This method may call
|
||||||
|
the next method in the list of applicable methods. This is done by using
|
||||||
|
the special form @code{next-method}. Consider the following definitions
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-method Test ((a <integer>)) (cons 'integer (next-method)))
|
||||||
|
(define-method Test ((a <number>)) (cons 'number (next-method)))
|
||||||
|
(define-method Test (a) (list 'top))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
With those definitions,
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(Test 1) @result{} (integer number top)
|
||||||
|
(Test 1.0) @result{} (number top)
|
||||||
|
(Test #t) @result{} (top)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@node Example, , Next-method, Generic functions
|
||||||
|
@subsection Example
|
||||||
|
|
||||||
|
In this section we shall continue to define operations on the @code{<complex>}
|
||||||
|
class defined in Figure@ 2. Suppose that we want to use it to implement
|
||||||
|
complex numbers completely. For instance a definition for the addition of
|
||||||
|
two complexes could be
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-method new-+ ((a <complex>) (b <complex>))
|
||||||
|
(make-rectangular (+ (real-part a) (real-part b))
|
||||||
|
(+ (imag-part a) (imag-part b))))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
To be sure that the @code{+} used in the method @code{new-+} is the standard
|
||||||
|
addition we can do:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-generic new-+)
|
||||||
|
|
||||||
|
(let ((+ +))
|
||||||
|
(define-method new-+ ((a <complex>) (b <complex>))
|
||||||
|
(make-rectangular (+ (real-part a) (real-part b))
|
||||||
|
(+ (imag-part a) (imag-part b)))))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
The @code{define-generic} ensures here that @code{new-+} will be defined
|
||||||
|
in the global environment. Once this is done, we can add methods to the
|
||||||
|
generic function @code{new-+} which make a closure on the @code{+}
|
||||||
|
symbol. A complete writing of the @code{new-+} methods is shown in
|
||||||
|
Figure@ 3.
|
||||||
|
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
@lisp
|
||||||
|
(define-generic new-+)
|
||||||
|
|
||||||
|
(let ((+ +))
|
||||||
|
|
||||||
|
(define-method new-+ ((a <real>) (b <real>)) (+ a b))
|
||||||
|
|
||||||
|
(define-method new-+ ((a <real>) (b <complex>))
|
||||||
|
(make-rectangular (+ a (real-part b)) (imag-part b)))
|
||||||
|
|
||||||
|
(define-method new-+ ((a <complex>) (b <real>))
|
||||||
|
(make-rectangular (+ (real-part a) b) (imag-part a)))
|
||||||
|
|
||||||
|
(define-method new-+ ((a <complex>) (b <complex>))
|
||||||
|
(make-rectangular (+ (real-part a) (real-part b))
|
||||||
|
(+ (imag-part a) (imag-part b))))
|
||||||
|
|
||||||
|
(define-method new-+ ((a <number>)) a)
|
||||||
|
|
||||||
|
(define-method new-+ () 0)
|
||||||
|
|
||||||
|
(define-method new-+ args (new-+ (car args)
|
||||||
|
(apply new-+ (cdr args)))))
|
||||||
|
|
||||||
|
(set! + new-+)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@center @emph{Fig 3: Extending @code{+} for dealing with complex numbers}
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@sp 3
|
||||||
|
We use here the fact that generic function are not obliged to have the
|
||||||
|
same number of parameters, contrarily to CLOS. The four first methods
|
||||||
|
implement the dyadic addition. The fifth method says that the addition
|
||||||
|
of a single element is this element itself. The sixth method says that
|
||||||
|
using the addition with no parameter always return 0. The last method
|
||||||
|
takes an arbitrary number of parameters@footnote{The third parameter of
|
||||||
|
a @code{define-method} is a parameter list which follow the conventions
|
||||||
|
used for lambda expressions. In particular it can use the dot notation
|
||||||
|
or a symbol to denote an arbitrary number of parameters}. This method
|
||||||
|
acts as a kind of @code{reduce}: it calls the dyadic addition on the
|
||||||
|
@emph{car} of the list and on the result of applying it on its rest. To
|
||||||
|
finish, the @code{set!} permits to redefine the @code{+} symbol to our
|
||||||
|
extended addition.
|
||||||
|
|
||||||
|
@sp 3
|
||||||
|
To terminate our implementation (integration?) of complex numbers, we can
|
||||||
|
redefine standard Scheme predicates in the following manner:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define-method complex? (c <complex>) #t)
|
||||||
|
(define-method complex? (c) #f)
|
||||||
|
|
||||||
|
(define-method number? (n <number>) #t)
|
||||||
|
(define-method number? (n) #f)
|
||||||
|
@dots{}
|
||||||
|
@dots{}
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
Standard primitives in which complex numbers are involved could also be
|
||||||
|
redefined in the same manner.
|
||||||
|
|
2798
doc/goops.texi
Normal file
2798
doc/goops.texi
Normal file
File diff suppressed because it is too large
Load diff
368
doc/guile.texi
Normal file
368
doc/guile.texi
Normal file
|
@ -0,0 +1,368 @@
|
||||||
|
\input texinfo
|
||||||
|
@c -*-texinfo-*-
|
||||||
|
@c %**start of header
|
||||||
|
@setfilename guile.info
|
||||||
|
@settitle Guile Reference Manual
|
||||||
|
@c %**end of header
|
||||||
|
|
||||||
|
@c Neil's notes:
|
||||||
|
|
||||||
|
@c This file started life as a copy of guile-ref.texi, which I then
|
||||||
|
@c modified to reflect the organization described in
|
||||||
|
@c sources/jimb-org.texi.
|
||||||
|
|
||||||
|
@c Jim's notes:
|
||||||
|
|
||||||
|
@c Remember to use "subr" whereever appropriate.
|
||||||
|
@c Actually, use "primitive", not "subr." Why coin a new term?
|
||||||
|
@c FIXME: gotta change existing "subr" uses to "Primitive".
|
||||||
|
@c In my text for the Guile snarfer, I've used the term "subr" to denote
|
||||||
|
@c a C function made available to the Scheme world as a function. This
|
||||||
|
@c terminology is weird, but consistent with the function names and also
|
||||||
|
@c with Emacs Lisp, which I assume takes Maclisp's lead.
|
||||||
|
|
||||||
|
@c Tim's notes:
|
||||||
|
|
||||||
|
@c When adding a new function to the Guile manual, please document
|
||||||
|
@c it with @deffn as one of `primitive', `procedure', or `syntax'.
|
||||||
|
@c
|
||||||
|
@c The following Guile primitives are not documented. We have a lot
|
||||||
|
@c of work to do.
|
||||||
|
@c
|
||||||
|
@c arbiters.c: make-arbiter, try-arbiter, release-arbiter
|
||||||
|
@c async.c: async, async-mark, system-async, system-async-mark,
|
||||||
|
@c run-asyncs, noop, set-tick-rate, set-switch-rate,
|
||||||
|
@c unmask-signals, mask-signals
|
||||||
|
@c backtrace.c: backtrace, display-error, display-application,
|
||||||
|
@c display-backtrace
|
||||||
|
@c chars.c: char-is-both?
|
||||||
|
@c debug.c: single-step, memoized?, unmemoize, memoized-environment,
|
||||||
|
@c procedure-name, procedure-source, procedure-environment,
|
||||||
|
@c local-eval, debug-object?, debug-hang
|
||||||
|
@c dynl.c: c-registered-modules, c-clear-registered-modules,
|
||||||
|
@c dynamic-link, dynamic-object?, dynamic-unlink, dynamic-func,
|
||||||
|
@c dynamic-call, dynamic-args-call
|
||||||
|
@c eval.c: procedure->syntax, procedure->macro, procedure->memoizing-macro,
|
||||||
|
@c macro-name, macro-transformer
|
||||||
|
@c fluids.c: make-fluid, fluid?, fluid-ref, fluid-set, with-fluids*
|
||||||
|
@c gc.c: map-free-list, unhash-name
|
||||||
|
@c kw.c: make-keyword-from-dash-symbol
|
||||||
|
@c net_db.c: sethost, setnet, setproto, setserv
|
||||||
|
@c print.c: current-pstate
|
||||||
|
@c procs.c: make-cclo, closure?, thunk?
|
||||||
|
@c read.c: read-hash-extend
|
||||||
|
@c readline.c: readline, add-history
|
||||||
|
@c srcprop.c: source-properties, set-source-properties!,
|
||||||
|
@c source-property, set-source-property!
|
||||||
|
@c stacks.c: make-stack, stack-ref, stack-length,
|
||||||
|
@c frame?, last-stack-frame, frame-number, frame-source,
|
||||||
|
@c frame-procedure, frame-arguments, frame-previous, frame-next,
|
||||||
|
@c frame-real?, frame-procedure?, frame-evaluating-args?,
|
||||||
|
@c frame-overflow
|
||||||
|
@c struct.c: struct-vtable-tag
|
||||||
|
@c symbols.c: builtin-weak-bindings
|
||||||
|
@c tag.c: tag
|
||||||
|
@c threads.c: single-active-thread?, yield, call-with-new-thread,
|
||||||
|
@c make-condition-variable, wait-condition-variable,
|
||||||
|
@c signal-condition-variable
|
||||||
|
@c throw.c: lazy-catch, vector-set-length!
|
||||||
|
@c unif.c: uniform-vector-ref, uniform-array-set1!
|
||||||
|
@c variable.c: make-variable, make-undefined-variable, variable?,
|
||||||
|
@c variable-ref, variable-set!, builtin-variable, variable-bound?
|
||||||
|
@c weaks.c: make-weak-vector, weak-vector, list->weak-vector,
|
||||||
|
@c weak-vector? make-weak-key-hash-table,
|
||||||
|
@c make-weak-value-hash-table, make-doubly-weak-hash-table,
|
||||||
|
@c weak-key-hash-table?, weak-value-hash-table?,
|
||||||
|
@c doubly-weak-hash-table?
|
||||||
|
@c
|
||||||
|
@c If you have worked with some of these concepts, implemented them,
|
||||||
|
@c or just happen to know what they do, please write up a little
|
||||||
|
@c explanation -- it would be a big help. Alternatively, if you
|
||||||
|
@c know of a great reason why some of these should *not* go in the
|
||||||
|
@c manual, please let me know.
|
||||||
|
@c
|
||||||
|
@c The following functions are currently left undocumented for various reasons.
|
||||||
|
@c * should be documented in a section on debugging or Guile internals:
|
||||||
|
@c ports.c: pt-size, pt-member
|
||||||
|
@c eval.c: apply:nconc2last
|
||||||
|
@c * trivial underlying implementations of R4RS functions:
|
||||||
|
@c numbers.c: $asinh, $acosh, $atanh, $sqrt, $abs, $exp, $log, $sin,
|
||||||
|
@c $cos, $tan, $asin, $acos, $atan, $sinh, $cosh, $tanh, $expt,
|
||||||
|
@c $atan2
|
||||||
|
@c
|
||||||
|
@c Thanks. -twp
|
||||||
|
|
||||||
|
@c Define indices that are used in the Guile Scheme part of the
|
||||||
|
@c reference manual to group stuff according to whether it is R5RS or a
|
||||||
|
@c Guile extension.
|
||||||
|
@defcodeindex r5
|
||||||
|
@defcodeindex ge
|
||||||
|
|
||||||
|
@include version.texi
|
||||||
|
|
||||||
|
@c @iftex
|
||||||
|
@c @cropmarks
|
||||||
|
@c @end iftex
|
||||||
|
|
||||||
|
@dircategory The Algorithmic Language Scheme
|
||||||
|
@direntry
|
||||||
|
* Guile Reference: (guile). The Guile reference manual.
|
||||||
|
@end direntry
|
||||||
|
|
||||||
|
@setchapternewpage off
|
||||||
|
|
||||||
|
@ifinfo
|
||||||
|
Guile Reference Manual
|
||||||
|
Copyright (C) 1996 Free Software Foundation @*
|
||||||
|
Copyright (C) 1997 Free Software Foundation @*
|
||||||
|
Copyright (C) 2000 Free Software Foundation @*
|
||||||
|
Copyright (C) 2001 Free Software Foundation
|
||||||
|
|
||||||
|
Permission is granted to make and distribute verbatim copies of
|
||||||
|
this manual provided the copyright notice and this permission notice
|
||||||
|
are preserved on all copies.
|
||||||
|
|
||||||
|
@ignore
|
||||||
|
Permission is granted to process this file through TeX and print the
|
||||||
|
results, provided the printed document carries copying permission
|
||||||
|
notice identical to this one except for the removal of this paragraph
|
||||||
|
(this paragraph not being relevant to the printed manual).
|
||||||
|
@end ignore
|
||||||
|
|
||||||
|
Permission is granted to copy and distribute modified versions of this
|
||||||
|
manual under the conditions for verbatim copying, provided that the entire
|
||||||
|
resulting derived work is distributed under the terms of a permission
|
||||||
|
notice identical to this one.
|
||||||
|
|
||||||
|
Permission is granted to copy and distribute translations of this manual
|
||||||
|
into another language, under the above conditions for modified versions,
|
||||||
|
except that this permission notice may be stated in a translation approved
|
||||||
|
by the Free Software Foundation.
|
||||||
|
@end ifinfo
|
||||||
|
|
||||||
|
@titlepage
|
||||||
|
@sp 10
|
||||||
|
@comment The title is printed in a large font.
|
||||||
|
@title Guile Reference Manual
|
||||||
|
@subtitle $Id: guile.texi,v 1.1 2001-03-09 08:21:59 ossau Exp $
|
||||||
|
@subtitle For use with Guile @value{VERSION}
|
||||||
|
@author Mark Galassi
|
||||||
|
@author Cygnus Solution and Los Alamos National Laboratory
|
||||||
|
@author @email{rosalia@@cygnus.com}
|
||||||
|
@author
|
||||||
|
@author Jim Blandy
|
||||||
|
@author Free Software Foundation and MIT AI Lab
|
||||||
|
@author @email{jimb@@red-bean.com}
|
||||||
|
@author
|
||||||
|
@author Gary Houston
|
||||||
|
@author @email{ghouston@@actrix.gen.nz}
|
||||||
|
@author
|
||||||
|
@author Tim Pierce
|
||||||
|
@author @email{twp@@skepsis.com}
|
||||||
|
@author
|
||||||
|
@author Neil Jerram
|
||||||
|
@author @email{neil@@ossau.uklinux.net}
|
||||||
|
@c The following two commands start the copyright page.
|
||||||
|
@page
|
||||||
|
@vskip 0pt plus 1filll
|
||||||
|
@vskip 0pt plus 1filll
|
||||||
|
Copyright @copyright{} 1996 Free Software Foundation
|
||||||
|
|
||||||
|
Copyright @copyright{} 1997 Free Software Foundation
|
||||||
|
|
||||||
|
Copyright @copyright{} 2000 Free Software Foundation
|
||||||
|
|
||||||
|
Permission is granted to make and distribute verbatim copies of
|
||||||
|
this manual provided the copyright notice and this permission notice
|
||||||
|
are preserved on all copies.
|
||||||
|
|
||||||
|
Permission is granted to copy and distribute modified versions of this
|
||||||
|
manual under the conditions for verbatim copying, provided that the entire
|
||||||
|
resulting derived work is distributed under the terms of a permission
|
||||||
|
notice identical to this one.
|
||||||
|
|
||||||
|
Permission is granted to copy and distribute translations of this manual
|
||||||
|
into another language, under the above conditions for modified versions,
|
||||||
|
except that this permission notice may be stated in a translation approved
|
||||||
|
by Free Software Foundation.
|
||||||
|
@end titlepage
|
||||||
|
|
||||||
|
@c @smallbook
|
||||||
|
@finalout
|
||||||
|
@headings double
|
||||||
|
|
||||||
|
@c Where to find Guile examples.
|
||||||
|
@set example-dir doc/examples
|
||||||
|
|
||||||
|
@ifinfo
|
||||||
|
@node Top, Guile License, (dir), (dir)
|
||||||
|
@top The Guile Reference Manual
|
||||||
|
|
||||||
|
This reference manual documents Guile, GNU's Ubiquitous Intelligent
|
||||||
|
Language for Extensions. It describes how to use Guile in many useful
|
||||||
|
and interesting ways.
|
||||||
|
|
||||||
|
This Info file contains edition 1.0 of the reference manual,
|
||||||
|
corresponding to Guile version @value{VERSION}.
|
||||||
|
@end ifinfo
|
||||||
|
|
||||||
|
@menu
|
||||||
|
Preface
|
||||||
|
|
||||||
|
* Guile License:: Conditions for copying and using Guile.
|
||||||
|
* Manual Layout:: How to read the rest of this manual.
|
||||||
|
|
||||||
|
Part I: Introduction to Guile
|
||||||
|
|
||||||
|
* What is Guile?:: And what does it do?
|
||||||
|
* Whirlwind Tour:: An introductory whirlwind tour.
|
||||||
|
* Reporting Bugs:: Reporting bugs in Guile or this manual.
|
||||||
|
|
||||||
|
Part II: Guile Scheme
|
||||||
|
|
||||||
|
* Scheme Intro:: Introduction to Guile Scheme.
|
||||||
|
* Basic Ideas:: Basic ideas in Scheme.
|
||||||
|
* Data Types:: Data types for generic use.
|
||||||
|
* Procedures and Macros:: Procedures and macros.
|
||||||
|
* Utility Functions:: General utility functions.
|
||||||
|
* Binding Constructs:: Definitions and variable bindings.
|
||||||
|
* Control Mechanisms:: Controlling the flow of program execution.
|
||||||
|
* Input and Output:: Ports, reading and writing.
|
||||||
|
* Read/Load/Eval:: Reading and evaluating Scheme code.
|
||||||
|
* Memory Management:: Memory management and garbage collection.
|
||||||
|
* Objects:: Low level object orientation support.
|
||||||
|
* Modules:: Designing reusable code libraries.
|
||||||
|
* Scheduling:: Threads, mutexes, asyncs and dynamic roots.
|
||||||
|
* Options and Config:: Runtime options and configuration.
|
||||||
|
* Translation:: Support for translating other languages.
|
||||||
|
* Debugging:: Internal debugging interface.
|
||||||
|
* Deprecated:: Features that are planned to disappear.
|
||||||
|
* Further Reading:: Where to find out more about Scheme programming.
|
||||||
|
* R5RS Index::
|
||||||
|
* Guile Extensions Index::
|
||||||
|
|
||||||
|
Part III: Guile Modules
|
||||||
|
|
||||||
|
* SLIB:: Using the SLIB Scheme library.
|
||||||
|
* POSIX:: POSIX system calls and networking.
|
||||||
|
* Expect:: Controlling interactive programs with Guile.
|
||||||
|
* The Scheme shell (scsh)::
|
||||||
|
The SCSH compatibility module has been made an
|
||||||
|
add-on, so maybe it shouldn't be documented here
|
||||||
|
(though it is nice to have a link from here to the
|
||||||
|
Guile-scsh manual, if one exists).
|
||||||
|
* Tcl/Tk Interface::
|
||||||
|
|
||||||
|
Part IV: Guile Scripting
|
||||||
|
|
||||||
|
* Guile Scripting:: How to write Guile scripts.
|
||||||
|
|
||||||
|
Part V: Extending Applications Using Guile
|
||||||
|
|
||||||
|
* Libguile Intro:: Using Guile as an extension language.
|
||||||
|
* GH:: GH: a portable C to Scheme interface.
|
||||||
|
* Data Representation:: Data representation in Guile.
|
||||||
|
* Scheme Primitives:: Writing Scheme primitives in C.
|
||||||
|
* I/O Extensions:: Using and extending ports in C.
|
||||||
|
* Handling Errors:: How to handle errors in C code.
|
||||||
|
|
||||||
|
Appendices
|
||||||
|
|
||||||
|
* Obtaining and Installing Guile::
|
||||||
|
* Debugger User Interface::
|
||||||
|
|
||||||
|
Indices
|
||||||
|
|
||||||
|
* Concept Index::
|
||||||
|
* Procedure Index::
|
||||||
|
* Variable Index::
|
||||||
|
* Type Index::
|
||||||
|
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@include preface.texi
|
||||||
|
|
||||||
|
@c preliminary
|
||||||
|
@iftex
|
||||||
|
@page
|
||||||
|
@unnumbered{Part I: Introduction to Guile}
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@include intro.texi
|
||||||
|
|
||||||
|
@c programming in Scheme
|
||||||
|
@iftex
|
||||||
|
@page
|
||||||
|
@unnumbered{Part II: Guile Scheme}
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@include scheme-intro.texi
|
||||||
|
@include scheme-ideas.texi
|
||||||
|
@include scheme-data.texi
|
||||||
|
@include scheme-procedures.texi
|
||||||
|
@include scheme-utility.texi
|
||||||
|
@include scheme-binding.texi
|
||||||
|
@include scheme-control.texi
|
||||||
|
@include scheme-io.texi
|
||||||
|
@include scheme-evaluation.texi
|
||||||
|
@include scheme-memory.texi
|
||||||
|
@include scheme-modules.texi
|
||||||
|
@include scheme-scheduling.texi
|
||||||
|
@c object orientation support here
|
||||||
|
@include scheme-options.texi
|
||||||
|
@include scheme-translation.texi
|
||||||
|
@include scheme-debug.texi
|
||||||
|
@include deprecated.texi
|
||||||
|
@include scheme-reading.texi
|
||||||
|
@include scheme-indices.texi
|
||||||
|
|
||||||
|
@c Unix system interface
|
||||||
|
@iftex
|
||||||
|
@page
|
||||||
|
@unnumbered{Part III: Guile Modules}
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@include slib.texi
|
||||||
|
@include posix.texi
|
||||||
|
@include expect.texi
|
||||||
|
@include scsh.texi
|
||||||
|
@include tcltk.texi
|
||||||
|
|
||||||
|
@c Guile as an scripting language
|
||||||
|
@iftex
|
||||||
|
@page
|
||||||
|
@unnumbered{Part IV: Guile Scripting}
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@include scripts.texi
|
||||||
|
|
||||||
|
@c Guile as an extension language
|
||||||
|
@iftex
|
||||||
|
@page
|
||||||
|
@unnumbered{Part V: Extending Applications Using Guile}
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@include extend.texi
|
||||||
|
@include gh.texi
|
||||||
|
@include data-rep.texi
|
||||||
|
@include scm.texi
|
||||||
|
|
||||||
|
@c Appendices
|
||||||
|
@iftex
|
||||||
|
@page
|
||||||
|
@unnumbered{Appendices}
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@include appendices.texi
|
||||||
|
|
||||||
|
@c Indices
|
||||||
|
@iftex
|
||||||
|
@page
|
||||||
|
@unnumbered{Indices}
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@include indices.texi
|
||||||
|
|
||||||
|
@contents
|
||||||
|
|
||||||
|
@bye
|
0
doc/hierarchy.eps
Normal file
0
doc/hierarchy.eps
Normal file
0
doc/hierarchy.txt
Normal file
0
doc/hierarchy.txt
Normal file
31
doc/indices.texi
Normal file
31
doc/indices.texi
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
@node Concept Index
|
||||||
|
@unnumbered Concept Index
|
||||||
|
@printindex cp
|
||||||
|
|
||||||
|
|
||||||
|
@node Procedure Index
|
||||||
|
@unnumbered Procedure Index
|
||||||
|
This is an alphabetical list of all the procedures and macros in Guile.
|
||||||
|
[[Remind people to look for functions under their Scheme names as well
|
||||||
|
as their C names.]]
|
||||||
|
@printindex fn
|
||||||
|
|
||||||
|
|
||||||
|
@node Variable Index
|
||||||
|
@unnumbered Variable Index
|
||||||
|
This is an alphabetical list of all the important variables and
|
||||||
|
constants in Guile.
|
||||||
|
[[Remind people to look for variables under their Scheme names as well
|
||||||
|
as their C names.]]
|
||||||
|
@printindex vr
|
||||||
|
|
||||||
|
|
||||||
|
@c Spell out this node fully, because it is the last real node
|
||||||
|
@c in the top-level menu. Leaving off the pointers here causes
|
||||||
|
@c spurious makeinfo errors.
|
||||||
|
@node Type Index
|
||||||
|
@unnumbered Type Index
|
||||||
|
This is an alphabetical list of all the important data types defined in
|
||||||
|
the Guile Programmers Manual.
|
||||||
|
@printindex tp
|
||||||
|
|
579
doc/intro.texi
Normal file
579
doc/intro.texi
Normal file
|
@ -0,0 +1,579 @@
|
||||||
|
@c $Id: intro.texi,v 1.1 2001-03-09 08:21:59 ossau Exp $
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node What is Guile?
|
||||||
|
@chapter What is Guile?
|
||||||
|
|
||||||
|
Guile is an interpreter for the Scheme programming language, packaged
|
||||||
|
for use in a wide variety of environments. Guile implements Scheme as
|
||||||
|
described in the
|
||||||
|
@tex
|
||||||
|
Revised$^5$
|
||||||
|
@end tex
|
||||||
|
@ifinfo
|
||||||
|
Revised^5
|
||||||
|
@end ifinfo
|
||||||
|
Report on the Algorithmic Language Scheme (usually known as R5RS),
|
||||||
|
providing clean and general data and control structures. Guile goes
|
||||||
|
beyond the rather austere language presented in R5RS, extending it with
|
||||||
|
a module system, full access to POSIX system calls, networking support,
|
||||||
|
multiple threads, dynamic linking, a foreign function call interface,
|
||||||
|
powerful string processing, and many other features needed for
|
||||||
|
programming in the real world.
|
||||||
|
|
||||||
|
Like a shell, Guile can run interactively, reading expressions from the
|
||||||
|
user, evaluating them, and displaying the results, or as a script
|
||||||
|
interpreter, reading and executing Scheme code from a file. However,
|
||||||
|
Guile is also packaged as an object library, allowing other applications
|
||||||
|
to easily incorporate a complete Scheme interpreter. An application can
|
||||||
|
use Guile as an extension language, a clean and powerful configuration
|
||||||
|
language, or as multi-purpose ``glue'', connecting primitives provided
|
||||||
|
by the application. It is easy to call Scheme code from C code and vice
|
||||||
|
versa, giving the application designer full control of how and when to
|
||||||
|
invoke the interpreter. Applications can add new functions, data types,
|
||||||
|
control structures, and even syntax to Guile, creating a domain-specific
|
||||||
|
language tailored to the task at hand, but based on a robust language
|
||||||
|
design.
|
||||||
|
|
||||||
|
Guile's module system allows one to break up a large program into
|
||||||
|
manageable sections with well-defined interfaces between them. Modules
|
||||||
|
may contain a mixture of interpreted and compiled code; Guile can use
|
||||||
|
either static or dynamic linking to incorporate compiled code. Modules
|
||||||
|
also encourage developers to package up useful collections of routines
|
||||||
|
for general distribution; as of this writing, one can find Emacs
|
||||||
|
interfaces, database access routines, compilers, GUI toolkit interfaces,
|
||||||
|
and HTTP client functions, among others.
|
||||||
|
|
||||||
|
In the future, we hope to expand Guile to support other languages like
|
||||||
|
Tcl and Perl by translating them to Scheme code. This means that users
|
||||||
|
can program applications which use Guile in the language of their
|
||||||
|
choice, rather than having the tastes of the application's author
|
||||||
|
imposed on them.
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Whirlwind Tour
|
||||||
|
@chapter A Whirlwind Tour
|
||||||
|
|
||||||
|
This chapter presents a quick tour of all the ways that Guile can be
|
||||||
|
used.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Running Guile Interactively::
|
||||||
|
* Guile Scripts::
|
||||||
|
* Linking Programs With Guile::
|
||||||
|
* Writing Guile Modules::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Running Guile Interactively
|
||||||
|
@section Running Guile Interactively
|
||||||
|
|
||||||
|
In its simplest form, Guile acts as an interactive interpreter for the
|
||||||
|
Scheme programming language, reading and evaluating Scheme expressions
|
||||||
|
the user enters from the terminal. Here is a sample interaction between
|
||||||
|
Guile and a user; the user's input appears after the @code{$} and
|
||||||
|
@code{guile>} prompts:
|
||||||
|
|
||||||
|
@example
|
||||||
|
$ guile
|
||||||
|
guile> (+ 1 2 3) ; add some numbers
|
||||||
|
6
|
||||||
|
guile> (define (factorial n) ; define a function
|
||||||
|
(if (zero? n) 1 (* n (factorial (- n 1)))))
|
||||||
|
guile> (factorial 20)
|
||||||
|
2432902008176640000
|
||||||
|
guile> (getpwnam "jimb") ; find my entry in /etc/passwd
|
||||||
|
#("jimb" ".0krIpK2VqNbU" 4008 10 "Jim Blandy" "/u/jimb"
|
||||||
|
"/usr/local/bin/bash")
|
||||||
|
guile> @kbd{C-d}
|
||||||
|
$
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@c [[When we get a fancier read-eval-print loop, with features for bouncing
|
||||||
|
@c around among modules, referring to the value of the last expression,
|
||||||
|
@c etc. then this section will get longer.]]
|
||||||
|
|
||||||
|
|
||||||
|
@node Guile Scripts
|
||||||
|
@section Guile Scripts
|
||||||
|
|
||||||
|
Like AWK, Perl, or any shell, Guile can interpret script files. A Guile
|
||||||
|
script is simply a file of Scheme code with some extra information at
|
||||||
|
the beginning which tells the operating system how to invoke Guile, and
|
||||||
|
then tells Guile how to handle the Scheme code.
|
||||||
|
|
||||||
|
Before we present the details, here is a trivial Guile script:
|
||||||
|
|
||||||
|
@example
|
||||||
|
#!/usr/local/bin/guile -s
|
||||||
|
!#
|
||||||
|
(display "Hello, world!")
|
||||||
|
(newline)
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* The Top of a Script File:: How to start a Guile script.
|
||||||
|
* Scripting Examples:: Simple Guile scripts, explained.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node The Top of a Script File
|
||||||
|
@subsection The Top of a Script File
|
||||||
|
|
||||||
|
The first line of a Guile script must tell the operating system to use
|
||||||
|
Guile to evaluate the script, and then tell Guile how to go about doing
|
||||||
|
that. Here is the simplest case:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
|
||||||
|
@item
|
||||||
|
The first two characters of the file must be @samp{#!}.
|
||||||
|
|
||||||
|
The operating system interprets this to mean that the rest of the line
|
||||||
|
is the name of an executable that can interpret the script. Guile,
|
||||||
|
however, interprets these characters as the beginning of a multi-line
|
||||||
|
comment, terminated by the characters @samp{!#} on a line by themselves.
|
||||||
|
(This is an extension to the syntax described in R5RS, added to support
|
||||||
|
shell scripts.)
|
||||||
|
|
||||||
|
@item
|
||||||
|
Immediately after those two characters must come the full pathname to
|
||||||
|
the Guile interpreter. On most systems, this would be
|
||||||
|
@samp{/usr/local/bin/guile}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Then must come a space, followed by a command-line argument to pass to
|
||||||
|
Guile; this should be @samp{-s}. This switch tells Guile to run a
|
||||||
|
script, instead of soliciting the user for input from the terminal.
|
||||||
|
There are more elaborate things one can do here; see @ref{The Meta
|
||||||
|
Switch}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Follow this with a newline.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The second line of the script should contain only the characters
|
||||||
|
@samp{!#} --- just like the top of the file, but reversed. The
|
||||||
|
operating system never reads this far, but Guile treats this as the end
|
||||||
|
of the comment begun on the first line by the @samp{#!} characters.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The rest of the file should be a Scheme program.
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
Guile reads the program, evaluating expressions in the order that they
|
||||||
|
appear. Upon reaching the end of the file, Guile exits.
|
||||||
|
|
||||||
|
The function @code{command-line} returns the name of the script file and
|
||||||
|
any command-line arguments passed by the user, as a list of strings.
|
||||||
|
|
||||||
|
For example, consider the following script file:
|
||||||
|
@example
|
||||||
|
#!/usr/local/bin/guile -s
|
||||||
|
!#
|
||||||
|
(write (command-line))
|
||||||
|
(newline)
|
||||||
|
@end example
|
||||||
|
|
||||||
|
If you put that text in a file called @file{foo} in the current
|
||||||
|
directory, then you could make it executable and try it out like this:
|
||||||
|
@example
|
||||||
|
$ chmod a+x foo
|
||||||
|
$ ./foo
|
||||||
|
("./foo")
|
||||||
|
$ ./foo bar baz
|
||||||
|
("./foo" "bar" "baz")
|
||||||
|
$
|
||||||
|
@end example
|
||||||
|
|
||||||
|
As another example, here is a simple replacement for the POSIX
|
||||||
|
@code{echo} command:
|
||||||
|
@example
|
||||||
|
#!/usr/local/bin/guile -s
|
||||||
|
!#
|
||||||
|
(for-each (lambda (s) (display s) (display " "))
|
||||||
|
(cdr (command-line)))
|
||||||
|
(newline)
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@deffn procedure command-line
|
||||||
|
@deffnx primitive program-arguments
|
||||||
|
Return a list of the command-line arguments passed to the currently
|
||||||
|
running program. If the program invoked Guile with the @samp{-s},
|
||||||
|
@samp{-c} or @samp{--} switches, these procedures ignore everything up
|
||||||
|
to and including those switches.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Scripting Examples
|
||||||
|
@subsection Scripting Examples
|
||||||
|
|
||||||
|
To start with, here are some examples of invoking Guile directly:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item guile -- a b c
|
||||||
|
Run Guile interactively; @code{(command-line)} will return @*
|
||||||
|
@code{("/usr/local/bin/guile" "a" "b" "c")}.
|
||||||
|
|
||||||
|
@item guile -s /u/jimb/ex2 a b c
|
||||||
|
Load the file @file{/u/jimb/ex2}; @code{(command-line)} will return @*
|
||||||
|
@code{("/u/jimb/ex2" "a" "b" "c")}.
|
||||||
|
|
||||||
|
@item guile -c '(write %load-path) (newline)'
|
||||||
|
Write the value of the variable @code{%load-path}, print a newline,
|
||||||
|
and exit.
|
||||||
|
|
||||||
|
@item guile -e main -s /u/jimb/ex4 foo
|
||||||
|
Load the file @file{/u/jimb/ex4}, and then call the function
|
||||||
|
@code{main}, passing it the list @code{("/u/jimb/ex4" "foo")}.
|
||||||
|
|
||||||
|
@item guile -l first -ds -l last -s script
|
||||||
|
Load the files @file{first}, @file{script}, and @file{last}, in that
|
||||||
|
order. The @code{-ds} switch says when to process the @code{-s}
|
||||||
|
switch. For a more motivated example, see the scripts below.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
Here is a very simple Guile script:
|
||||||
|
@example
|
||||||
|
#!/usr/local/bin/guile -s
|
||||||
|
!#
|
||||||
|
(display "Hello, world!")
|
||||||
|
(newline)
|
||||||
|
@end example
|
||||||
|
The first line marks the file as a Guile script. When the user invokes
|
||||||
|
it, the system runs @file{/usr/local/bin/guile} to interpret the script,
|
||||||
|
passing @code{-s}, the script's filename, and any arguments given to the
|
||||||
|
script as command-line arguments. When Guile sees @code{-s
|
||||||
|
@var{script}}, it loads @var{script}. Thus, running this program
|
||||||
|
produces the output:
|
||||||
|
@example
|
||||||
|
Hello, world!
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Here is a script which prints the factorial of its argument:
|
||||||
|
@example
|
||||||
|
#!/usr/local/bin/guile -s
|
||||||
|
!#
|
||||||
|
(define (fact n)
|
||||||
|
(if (zero? n) 1
|
||||||
|
(* n (fact (- n 1)))))
|
||||||
|
|
||||||
|
(display (fact (string->number (cadr (command-line)))))
|
||||||
|
(newline)
|
||||||
|
@end example
|
||||||
|
In action:
|
||||||
|
@example
|
||||||
|
$ fact 5
|
||||||
|
120
|
||||||
|
$
|
||||||
|
@end example
|
||||||
|
|
||||||
|
However, suppose we want to use the definition of @code{fact} in this
|
||||||
|
file from another script. We can't simply @code{load} the script file,
|
||||||
|
and then use @code{fact}'s definition, because the script will try to
|
||||||
|
compute and display a factorial when we load it. To avoid this problem,
|
||||||
|
we might write the script this way:
|
||||||
|
|
||||||
|
@example
|
||||||
|
#!/usr/local/bin/guile \
|
||||||
|
-e main -s
|
||||||
|
!#
|
||||||
|
(define (fact n)
|
||||||
|
(if (zero? n) 1
|
||||||
|
(* n (fact (- n 1)))))
|
||||||
|
|
||||||
|
(define (main args)
|
||||||
|
(display (fact (string->number (cadr args))))
|
||||||
|
(newline))
|
||||||
|
@end example
|
||||||
|
This version packages the actions the script should perform in a
|
||||||
|
function, @code{main}. This allows us to load the file purely for its
|
||||||
|
definitions, without any extraneous computation taking place. Then we
|
||||||
|
used the meta switch @code{\} and the entry point switch @code{-e} to
|
||||||
|
tell Guile to call @code{main} after loading the script.
|
||||||
|
@example
|
||||||
|
$ fact 50
|
||||||
|
30414093201713378043612608166064768844377641568960512000000000000
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Suppose that we now want to write a script which computes the
|
||||||
|
@code{choose} function: given a set of @var{m} distinct objects,
|
||||||
|
@code{(choose @var{n} @var{m})} is the number of distinct subsets
|
||||||
|
containing @var{n} objects each. It's easy to write @code{choose} given
|
||||||
|
@code{fact}, so we might write the script this way:
|
||||||
|
@example
|
||||||
|
#!/usr/local/bin/guile \
|
||||||
|
-l fact -e main -s
|
||||||
|
!#
|
||||||
|
(define (choose n m)
|
||||||
|
(/ (fact m) (* (fact (- m n)) (fact n))))
|
||||||
|
|
||||||
|
(define (main args)
|
||||||
|
(let ((n (string->number (cadr args)))
|
||||||
|
(m (string->number (caddr args))))
|
||||||
|
(display (choose n m))
|
||||||
|
(newline)))
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The command-line arguments here tell Guile to first load the file
|
||||||
|
@file{fact}, and then run the script, with @code{main} as the entry
|
||||||
|
point. In other words, the @code{choose} script can use definitions
|
||||||
|
made in the @code{fact} script. Here are some sample runs:
|
||||||
|
@example
|
||||||
|
$ choose 0 4
|
||||||
|
1
|
||||||
|
$ choose 1 4
|
||||||
|
4
|
||||||
|
$ choose 2 4
|
||||||
|
6
|
||||||
|
$ choose 3 4
|
||||||
|
4
|
||||||
|
$ choose 4 4
|
||||||
|
1
|
||||||
|
$ choose 50 100
|
||||||
|
100891344545564193334812497256
|
||||||
|
@end example
|
||||||
|
|
||||||
|
|
||||||
|
@node Linking Programs With Guile
|
||||||
|
@section Linking Programs With Guile
|
||||||
|
|
||||||
|
The Guile interpreter is available as an object library, to be linked
|
||||||
|
into applications using Scheme as a configuration or extension
|
||||||
|
language. This chapter covers the mechanics of linking your program
|
||||||
|
with Guile on a typical POSIX system.
|
||||||
|
|
||||||
|
Parts III and IV of this manual describe the C functions Guile provides.
|
||||||
|
Furthermore, any Scheme function described in this manual as a
|
||||||
|
``Primitive'' is also callable from C; see @ref{Scheme Primitives}.
|
||||||
|
|
||||||
|
The header file @code{<libguile.h>} provides declarations for all of
|
||||||
|
Guile's functions and constants. You should @code{#include} it at the
|
||||||
|
head of any C source file that uses identifiers described in this
|
||||||
|
manual.
|
||||||
|
|
||||||
|
Once you've compiled your source files, you can link them against Guile
|
||||||
|
by passing the flag @code{-lguile} to your linker. If you installed
|
||||||
|
Guile with multi-thread support (by passing @code{--enable-threads} to
|
||||||
|
the @code{configure} script), you may also need to link against the
|
||||||
|
QuickThreads library, @code{-lqt}. Guile refers to various mathematical
|
||||||
|
functions, so you will probably need to link against the mathematical
|
||||||
|
library, @code{-lm}, as well.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Guile Initialization Functions:: What to call first.
|
||||||
|
* A Sample Guile Main Program:: Sources and makefiles.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Guile Initialization Functions
|
||||||
|
@subsection Guile Initialization Functions
|
||||||
|
|
||||||
|
To initialize Guile, use this function:
|
||||||
|
|
||||||
|
@deftypefun void scm_boot_guile (int @var{argc}, char **@var{argv}, void (*@var{main_func}) (), void *@var{closure})
|
||||||
|
Initialize the Guile Scheme interpreter. Then call @var{main_func},
|
||||||
|
passing it @var{closure}, @var{argc}, and @var{argv}. @var{main_func}
|
||||||
|
should do all the work of the program (initializing other packages,
|
||||||
|
defining application-specific functions, reading user input, and so on)
|
||||||
|
before returning. When @var{main_func} returns, call @code{exit (0)};
|
||||||
|
@code{scm_boot_guile} never returns. If you want some other exit value,
|
||||||
|
have @var{main_func} call exit itself.
|
||||||
|
|
||||||
|
@code{scm_boot_guile} arranges for the Scheme @code{command-line}
|
||||||
|
function to return the strings given by @var{argc} and @var{argv}. If
|
||||||
|
@var{main_func} modifies @var{argc} or @var{argv}, it should call
|
||||||
|
@code{scm_set_program_arguments} with the final list, so Scheme code
|
||||||
|
will know which arguments have been processed.
|
||||||
|
|
||||||
|
@code{scm_boot_guile} establishes a catch-all error handler which prints
|
||||||
|
an error message and exits the process. This means that Guile exits in
|
||||||
|
a coherent way if a system error occurs and the user isn't prepared to
|
||||||
|
handle it. If the user doesn't like this behavior, they can establish
|
||||||
|
their own universal catcher in @var{main_func} to shadow this one.
|
||||||
|
|
||||||
|
Why must the caller do all the real work from @var{main_func}? Guile's
|
||||||
|
garbage collector assumes that all local variables which reference
|
||||||
|
Scheme objects will be above @code{scm_boot_guile}'s stack frame on the
|
||||||
|
stack. If you try to manipulate Scheme objects after this function
|
||||||
|
returns, it's the luck of the draw whether Guile's storage manager will
|
||||||
|
be able to find the objects you allocate. So, @code{scm_boot_guile}
|
||||||
|
function exits, rather than returning, to discourage you from making
|
||||||
|
that mistake.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
One common way to use Guile is to write a set of C functions which
|
||||||
|
perform some useful task, make them callable from Scheme, and then link
|
||||||
|
the program with Guile. This yields a Scheme interpreter just like
|
||||||
|
@code{guile}, but augmented with extra functions for some specific
|
||||||
|
application --- a special-purpose scripting language.
|
||||||
|
|
||||||
|
In this situation, the application should probably process its
|
||||||
|
command-line arguments in the same manner as the stock Guile
|
||||||
|
interpreter. To make that straightforward, Guile provides this
|
||||||
|
function:
|
||||||
|
|
||||||
|
@deftypefun void scm_shell (int @var{argc}, char **@var{argv})
|
||||||
|
Process command-line arguments in the manner of the @code{guile}
|
||||||
|
executable. This includes loading the normal Guile initialization
|
||||||
|
files, interacting with the user or running any scripts or expressions
|
||||||
|
specified by @code{-s} or @code{-e} options, and then exiting.
|
||||||
|
@xref{Invoking Guile}, for more details.
|
||||||
|
|
||||||
|
Since this function does not return, you must do all
|
||||||
|
application-specific initialization before calling this function.
|
||||||
|
|
||||||
|
If you do not use this function to start Guile, you are responsible for
|
||||||
|
making sure Guile's usual initialization files, @file{init.scm} and
|
||||||
|
@file{ice-9/boot-9.scm}, get loaded. This will change soon.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@node A Sample Guile Main Program
|
||||||
|
@subsection A Sample Guile Main Program
|
||||||
|
|
||||||
|
Here is @file{simple-guile.c}, source code for a @code{main} and an
|
||||||
|
@code{inner_main} function that will produce a complete Guile
|
||||||
|
interpreter.
|
||||||
|
|
||||||
|
@example
|
||||||
|
/* simple-guile.c --- how to start up the Guile
|
||||||
|
interpreter from C code. */
|
||||||
|
|
||||||
|
/* Get declarations for all the scm_ functions. */
|
||||||
|
#include <libguile.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
inner_main (void *closure, int argc, char **argv)
|
||||||
|
@{
|
||||||
|
/* module initializations would go here */
|
||||||
|
scm_shell (argc, argv);
|
||||||
|
@}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
@{
|
||||||
|
scm_boot_guile (argc, argv, inner_main, 0);
|
||||||
|
return 0; /* never reached */
|
||||||
|
@}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The @code{main} function calls @code{scm_boot_guile} to initialize
|
||||||
|
Guile, passing it @code{inner_main}. Once @code{scm_boot_guile} is
|
||||||
|
ready, it invokes @code{inner_main}, which calls @code{scm_shell} to
|
||||||
|
process the command-line arguments in the usual way.
|
||||||
|
|
||||||
|
Here is a Makefile which you can use to compile the above program.
|
||||||
|
@example
|
||||||
|
# Use GCC, if you have it installed.
|
||||||
|
CC=gcc
|
||||||
|
|
||||||
|
# Tell the C compiler where to find <libguile.h> and -lguile.
|
||||||
|
CFLAGS=-I/usr/local/include -L/usr/local/lib
|
||||||
|
|
||||||
|
# Include -lqt and -lrx if they are present on your system.
|
||||||
|
LIBS=-lguile -lqt -lrx -lm
|
||||||
|
|
||||||
|
simple-guile: simple-guile.o
|
||||||
|
$@{CC@} $@{CFLAGS@} simple-guile.o $@{LIBS@} -o simple-guile
|
||||||
|
simple-guile.o: simple-guile.c
|
||||||
|
$@{CC@} -c $@{CFLAGS@} simple-guile.c
|
||||||
|
@end example
|
||||||
|
|
||||||
|
If you are using the GNU Autoconf package to make your application more
|
||||||
|
portable, Autoconf will settle many of the details in the Makefile above
|
||||||
|
automatically, making it much simpler and more portable; we recommend
|
||||||
|
using Autoconf with Guile. Here is a @file{configure.in} file for
|
||||||
|
@code{simple-guile}, which Autoconf can use as a template to generate a
|
||||||
|
@code{configure} script:
|
||||||
|
@example
|
||||||
|
AC_INIT(simple-guile.c)
|
||||||
|
|
||||||
|
# Find a C compiler.
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
|
# Check for libraries.
|
||||||
|
AC_CHECK_LIB(m, sin)
|
||||||
|
AC_CHECK_LIB(rx, regcomp)
|
||||||
|
AC_CHECK_LIB(qt, main)
|
||||||
|
AC_CHECK_LIB(guile, scm_boot_guile)
|
||||||
|
|
||||||
|
# Generate a Makefile, based on the results.
|
||||||
|
AC_OUTPUT(Makefile)
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Here is a @code{Makefile.in} template, from which the @code{configure}
|
||||||
|
script produces a Makefile customized for the host system:
|
||||||
|
@example
|
||||||
|
# The configure script fills in these values.
|
||||||
|
CC=@@CC@@
|
||||||
|
CFLAGS=@@CFLAGS@@
|
||||||
|
LIBS=@@LIBS@@
|
||||||
|
|
||||||
|
simple-guile: simple-guile.o
|
||||||
|
$@{CC@} $@{CFLAGS@} simple-guile.o $@{LIBS@} -o simple-guile
|
||||||
|
simple-guile.o: simple-guile.c
|
||||||
|
$@{CC@} -c $@{CFLAGS@} simple-guile.c
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The developer should use Autoconf to generate the @file{configure}
|
||||||
|
script from the @file{configure.in} template, and distribute
|
||||||
|
@file{configure} with the application. Here's how a user might go about
|
||||||
|
building the application:
|
||||||
|
|
||||||
|
@example
|
||||||
|
$ ls
|
||||||
|
Makefile.in configure* configure.in simple-guile.c
|
||||||
|
$ ./configure
|
||||||
|
creating cache ./config.cache
|
||||||
|
checking for gcc... gcc
|
||||||
|
checking whether the C compiler (gcc ) works... yes
|
||||||
|
checking whether the C compiler (gcc ) is a cross-compiler... no
|
||||||
|
checking whether we are using GNU C... yes
|
||||||
|
checking whether gcc accepts -g... yes
|
||||||
|
checking for sin in -lm... yes
|
||||||
|
checking for regcomp in -lrx... yes
|
||||||
|
checking for main in -lqt... yes
|
||||||
|
checking for scm_boot_guile in -lguile... yes
|
||||||
|
updating cache ./config.cache
|
||||||
|
creating ./config.status
|
||||||
|
creating Makefile
|
||||||
|
$ make
|
||||||
|
gcc -c -g -O2 simple-guile.c
|
||||||
|
gcc -g -O2 simple-guile.o -lguile -lqt -lrx -lm -o simple-guile
|
||||||
|
$ ./simple-guile
|
||||||
|
guile> (+ 1 2 3)
|
||||||
|
6
|
||||||
|
guile> (getpwnam "jimb")
|
||||||
|
#("jimb" "83Z7d75W2tyJQ" 4008 10 "Jim Blandy" "/u/jimb"
|
||||||
|
"/usr/local/bin/bash")
|
||||||
|
guile> (exit)
|
||||||
|
$
|
||||||
|
@end example
|
||||||
|
|
||||||
|
|
||||||
|
@node Writing Guile Modules
|
||||||
|
@section Writing Guile Modules
|
||||||
|
|
||||||
|
[to be written]
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Reporting Bugs
|
||||||
|
@chapter Reporting Bugs
|
||||||
|
|
||||||
|
Any problems with the installation should be reported to
|
||||||
|
@email{bug-guile@@gnu.org}.
|
||||||
|
|
||||||
|
[[how about an explanation of what makes a good bug report?]]
|
||||||
|
[[don't complain to us about problems with contributed modules?]]
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
987
doc/mbapi.texi
Normal file
987
doc/mbapi.texi
Normal file
|
@ -0,0 +1,987 @@
|
||||||
|
\input texinfo
|
||||||
|
@setfilename mbapi.info
|
||||||
|
@settitle Multibyte API
|
||||||
|
@setchapternewpage off
|
||||||
|
|
||||||
|
@c Open issues:
|
||||||
|
|
||||||
|
@c What's the best way to report errors? Should functions return a
|
||||||
|
@c magic value, according to C tradition, or should they signal a
|
||||||
|
@c Guile exception?
|
||||||
|
|
||||||
|
@c
|
||||||
|
|
||||||
|
|
||||||
|
@node Working With Multibyte Strings in C
|
||||||
|
@chapter Working With Multibyte Strings in C
|
||||||
|
|
||||||
|
Guile allows strings to contain characters drawn from a wide variety of
|
||||||
|
languages, including many Asian, Eastern European, and Middle Eastern
|
||||||
|
languages, in a uniform and unrestricted way. The string representation
|
||||||
|
normally used in C code --- an array of @sc{ASCII} characters --- is not
|
||||||
|
sufficient for Guile strings, since they may contain characters not
|
||||||
|
present in @sc{ASCII}.
|
||||||
|
|
||||||
|
Instead, Guile uses a very large character set, and encodes each
|
||||||
|
character as a sequence of one or more bytes. We call this
|
||||||
|
variable-width encoding a @dfn{multibyte} encoding. Guile uses this
|
||||||
|
single encoding internally for all strings, symbol names, error
|
||||||
|
messages, etc., and performs appropriate conversions upon input and
|
||||||
|
output.
|
||||||
|
|
||||||
|
The use of this variable-width encoding is almost invisible to Scheme
|
||||||
|
code. Strings are still indexed by character number, not by byte
|
||||||
|
offset; @code{string-length} still returns the length of a string in
|
||||||
|
characters, not in bytes. @code{string-ref} and @code{string-set!} are
|
||||||
|
no longer guaranteed to be constant-time operations, but Guile uses
|
||||||
|
various strategies to reduce the impact of this change.
|
||||||
|
|
||||||
|
However, the encoding is visible via Guile's C interface, which gives
|
||||||
|
the user direct access to a string's bytes. This chapter explains how
|
||||||
|
to work with Guile multibyte text in C code. Since variable-width
|
||||||
|
encodings are clumsier to work with than simple fixed-width encodings,
|
||||||
|
Guile provides a set of standard macros and functions for manipulating
|
||||||
|
multibyte text to make the job easier. Furthermore, Guile makes some
|
||||||
|
promises about the encoding which you can use in writing your own text
|
||||||
|
processing code.
|
||||||
|
|
||||||
|
While we discuss guaranteed properties of Guile's encoding, and provide
|
||||||
|
functions to operate on its character set, we do not actually specify
|
||||||
|
either the character set or encoding here. This is because we expect
|
||||||
|
both of them to change in the future: currently, Guile uses the same
|
||||||
|
encoding as GNU Emacs 20.4, but we hope to change Guile (and GNU Emacs
|
||||||
|
as well) to use Unicode and UTF-8, with some extensions. This will make
|
||||||
|
it more comfortable to use Guile with other systems which use UTF-8,
|
||||||
|
like the GTk user interface toolkit.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Multibyte String Terminology::
|
||||||
|
* Promised Properties of the Guile Multibyte Encoding::
|
||||||
|
* Functions for Operating on Multibyte Text::
|
||||||
|
* Multibyte Text Processing Errors::
|
||||||
|
* Why Guile Does Not Use a Fixed-Width Encoding::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Multibyte String Terminology, Promised Properties of the Guile Multibyte Encoding, Working With Multibyte Strings in C, Working With Multibyte Strings in C
|
||||||
|
@section Multibyte String Terminology
|
||||||
|
|
||||||
|
In the descriptions which follow, we make the following definitions:
|
||||||
|
@table @dfn
|
||||||
|
|
||||||
|
@item byte
|
||||||
|
A @dfn{byte} is a number between 0 and 255. It has no inherent textual
|
||||||
|
interpretation. So 65 is a byte, not a character.
|
||||||
|
|
||||||
|
@item character
|
||||||
|
A @dfn{character} is a unit of text. It has no inherent numeric value.
|
||||||
|
@samp{A} and @samp{.} are characters, not bytes. (This is different
|
||||||
|
from the C language's definition of @dfn{character}; in this chapter, we
|
||||||
|
will always use a phrase like ``the C language's @code{char} type'' when
|
||||||
|
that's what we mean.)
|
||||||
|
|
||||||
|
@item character set
|
||||||
|
A @dfn{character set} is an invertible mapping between numbers and a
|
||||||
|
given set of characters. @sc{ASCII} is a character set assigning
|
||||||
|
characters to the numbers 0 through 127. It maps @samp{A} onto the
|
||||||
|
number 65, and @samp{.} onto 46.
|
||||||
|
|
||||||
|
Note that a character set maps characters onto numbers, @emph{not
|
||||||
|
necessarily} onto bytes. For example, the Unicode character set maps
|
||||||
|
the Greek lower-case @samp{alpha} character onto the number 945, which
|
||||||
|
is not a byte.
|
||||||
|
|
||||||
|
(This is what Internet standards would call a "coding character set".)
|
||||||
|
|
||||||
|
@item encoding
|
||||||
|
An encoding maps numbers onto sequences of bytes. For example, the
|
||||||
|
UTF-8 encoding, defined in the Unicode Standard, would map the number
|
||||||
|
945 onto the sequence of bytes @samp{206 177}. When using the
|
||||||
|
@sc{ASCII} character set, every number assigned also happens to be a
|
||||||
|
byte, so there is an obvious trivial encoding for @sc{ASCII} in bytes.
|
||||||
|
|
||||||
|
(This is what Internet standards would call a "character encoding
|
||||||
|
scheme".)
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
Thus, to turn a character into a sequence of bytes, you need a character
|
||||||
|
set to assign a number to that character, and then an encoding to turn
|
||||||
|
that number into a sequence of bytes.
|
||||||
|
|
||||||
|
Likewise, to interpret a sequence of bytes as a sequence of characters,
|
||||||
|
you use an encoding to extract a sequence of numbers from the bytes, and
|
||||||
|
then a character set to turn the numbers into characters.
|
||||||
|
|
||||||
|
Errors can occur while carrying out either of these processes. For
|
||||||
|
example, under a particular encoding, a given string of bytes might not
|
||||||
|
correspond to any number. For example, the byte sequence @samp{128 128}
|
||||||
|
is not a valid encoding of any number under UTF-8.
|
||||||
|
|
||||||
|
Having carefully defined our terminology, we will now abuse it.
|
||||||
|
|
||||||
|
We will sometimes use the word @dfn{character} to refer to the number
|
||||||
|
assigned to a character by a character set, in contexts where it's
|
||||||
|
obvious we mean a number.
|
||||||
|
|
||||||
|
Sometimes there is a close association between a particular encoding and
|
||||||
|
a particular character set. Thus, we may sometimes refer to the
|
||||||
|
character set and encoding together as an @dfn{encoding}.
|
||||||
|
|
||||||
|
|
||||||
|
@node Promised Properties of the Guile Multibyte Encoding, Functions for Operating on Multibyte Text, Multibyte String Terminology, Working With Multibyte Strings in C
|
||||||
|
@section Promised Properties of the Guile Multibyte Encoding
|
||||||
|
|
||||||
|
Internally, Guile uses a single encoding for all text --- symbols,
|
||||||
|
strings, error messages, etc. Here we list a number of helpful
|
||||||
|
properties of Guile's encoding. It is correct to write code which
|
||||||
|
assumes these properties; code which uses these assumptions will be
|
||||||
|
portable to all future versions of Guile, as far as we know.
|
||||||
|
|
||||||
|
@b{Every @sc{ASCII} character is encoded as a single byte from 0 to 127, in
|
||||||
|
the obvious way.} This means that a standard C string containing only
|
||||||
|
@sc{ASCII} characters is a valid Guile string (except for the terminator;
|
||||||
|
Guile strings store the length explicitly, so they can contain null
|
||||||
|
characters).
|
||||||
|
|
||||||
|
@b{The encodings of non-@sc{ASCII} characters use only bytes between 128
|
||||||
|
and 255.} That is, when we turn a non-@sc{ASCII} character into a
|
||||||
|
series of bytes, none of those bytes can ever be mistaken for the
|
||||||
|
encoding of an @sc{ASCII} character. This means that you can search a
|
||||||
|
Guile string for an @sc{ASCII} character using the standard
|
||||||
|
@code{memchr} library function. By extension, you can search for an
|
||||||
|
@sc{ASCII} substring in a Guile string using a traditional substring
|
||||||
|
search algorithm --- you needn't add special checks to verify encoding
|
||||||
|
boundaries, etc.
|
||||||
|
|
||||||
|
@b{No character encoding is a subsequence of any other character
|
||||||
|
encoding.} (This is just a stronger version of the previous promise.)
|
||||||
|
This means that you can search for occurrences of one Guile string
|
||||||
|
within another Guile string just as if they were raw byte strings. You
|
||||||
|
can use the stock @code{memmem} function (provided on GNU systems, at
|
||||||
|
least) for such searches. If you don't need the ability to represent
|
||||||
|
null characters in your text, you can still use null-termination for
|
||||||
|
strings, and use the traditional string-handling functions like
|
||||||
|
@code{strlen}, @code{strstr}, and @code{strcat}.
|
||||||
|
|
||||||
|
@b{You can always determine the full length of a character's encoding
|
||||||
|
from its first byte.} Guile provides the macro @code{scm_mb_len} which
|
||||||
|
computes the encoding's length from its first byte. Given the first
|
||||||
|
rule, you can see that @code{scm_mb_len (@var{b})}, for any @code{0 <=
|
||||||
|
@var{b} <= 127}, returns 1.
|
||||||
|
|
||||||
|
@b{Given an arbitrary byte position in a Guile string, you can always
|
||||||
|
find the beginning and end of the character containing that byte without
|
||||||
|
scanning too far in either direction.} This means that, if you are sure
|
||||||
|
a byte sequence is a valid encoding of a character sequence, you can
|
||||||
|
find character boundaries without keeping track of the beginning and
|
||||||
|
ending of the overall string. This promise relies on the fact that, in
|
||||||
|
addition to storing the string's length explicitly, Guile always either
|
||||||
|
terminates the string's storage with a zero byte, or shares it with
|
||||||
|
another string which is terminated this way.
|
||||||
|
|
||||||
|
|
||||||
|
@node Functions for Operating on Multibyte Text, Multibyte Text Processing Errors, Promised Properties of the Guile Multibyte Encoding, Working With Multibyte Strings in C
|
||||||
|
@section Functions for Operating on Multibyte Text
|
||||||
|
|
||||||
|
Guile provides a variety of functions, variables, and types for working
|
||||||
|
with multibyte text.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Basic Multibyte Character Processing::
|
||||||
|
* Finding Character Encoding Boundaries::
|
||||||
|
* Multibyte String Functions::
|
||||||
|
* Exchanging Guile Text With the Outside World in C::
|
||||||
|
* Implementing Your Own Text Conversions::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Basic Multibyte Character Processing, Finding Character Encoding Boundaries, Functions for Operating on Multibyte Text, Functions for Operating on Multibyte Text
|
||||||
|
@subsection Basic Multibyte Character Processing
|
||||||
|
|
||||||
|
Here are the essential types and functions for working with Guile text.
|
||||||
|
Guile uses the C type @code{unsigned char *} to refer to text encoded
|
||||||
|
with Guile's encoding.
|
||||||
|
|
||||||
|
Note that any operation marked here as a ``Libguile Macro'' might
|
||||||
|
evaluate its argument multiple times.
|
||||||
|
|
||||||
|
@deftp {Libguile Type} scm_char_t
|
||||||
|
This is a signed integral type large enough to hold any character in
|
||||||
|
Guile's character set. All character numbers are positive.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftypefn {Libguile Macro} scm_char_t scm_mb_get (const unsigned char *@var{p})
|
||||||
|
Return the character whose encoding starts at @var{p}. If @var{p} does
|
||||||
|
not point at a valid character encoding, the behavior is undefined.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Macro} int scm_mb_put (unsigned char *@var{p}, scm_char_t @var{c})
|
||||||
|
Place the encoded form of the Guile character @var{c} at @var{p}, and
|
||||||
|
return its length in bytes. If @var{c} is not a Guile character, the
|
||||||
|
behavior is undefined.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypevr {Libguile Constant} int scm_mb_max_len
|
||||||
|
The maximum length of any character's encoding, in bytes. You may
|
||||||
|
assume this is relatively small --- less than a dozen or so.
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypefn {Libguile Macro} int scm_mb_len (unsigned char @var{b})
|
||||||
|
If @var{b} is the first byte of a character's encoding, return the full
|
||||||
|
length of the character's encoding, in bytes. If @var{b} is not a valid
|
||||||
|
leading byte, the behavior is undefined.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Macro} int scm_mb_char_len (scm_char_t @var{c})
|
||||||
|
Return the length of the encoding of the character @var{c}, in bytes.
|
||||||
|
If @var{c} is not a valid Guile character, the behavior is undefined.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} scm_char_t scm_mb_get_func (const unsigned char *@var{p})
|
||||||
|
@deftypefnx {Libguile Function} int scm_mb_put_func (unsigned char *@var{p}, scm_char_t @var{c})
|
||||||
|
@deftypefnx {Libguile Function} int scm_mb_len_func (unsigned char @var{b})
|
||||||
|
@deftypefnx {Libguile Function} int scm_mb_char_len_func (scm_char_t @var{c})
|
||||||
|
These are functions identical to the corresponding macros. You can use
|
||||||
|
them in situations where the overhead of a function call is acceptable,
|
||||||
|
and the cleaner semantics of function application are desireable.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
|
@node Finding Character Encoding Boundaries, Multibyte String Functions, Basic Multibyte Character Processing, Functions for Operating on Multibyte Text
|
||||||
|
@subsection Finding Character Encoding Boundaries
|
||||||
|
|
||||||
|
These are functions for finding the boundaries between characters in
|
||||||
|
multibyte text.
|
||||||
|
|
||||||
|
Note that any operation marked here as a ``Libguile Macro'' might
|
||||||
|
evaluate its argument multiple times, unless the definition promises
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
@deftypefn {Libguile Macro} int scm_mb_boundary_p (const unsigned char *@var{p})
|
||||||
|
Return non-zero iff @var{p} points to the start of a character in
|
||||||
|
multibyte text.
|
||||||
|
|
||||||
|
This macro will evaluate its argument only once.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} {const unsigned char *} scm_mb_floor (const unsigned char *@var{p})
|
||||||
|
``Round'' @var{p} to the previous character boundary. That is, if
|
||||||
|
@var{p} points to the middle of the encoding of a Guile character,
|
||||||
|
return a pointer to the first byte of the encoding. If @var{p} points
|
||||||
|
to the start of the encoding of a Guile character, return @var{p}
|
||||||
|
unchanged.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {libguile Function} {const unsigned char *} scm_mb_ceiling (const unsigned char *@var{p})
|
||||||
|
``Round'' @var{p} to the next character boundary. That is, if @var{p}
|
||||||
|
points to the middle of the encoding of a Guile character, return a
|
||||||
|
pointer to the first byte of the encoding of the next character. If
|
||||||
|
@var{p} points to the start of the encoding of a Guile character, return
|
||||||
|
@var{p} unchanged.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
Note that it is usually not friendly for functions to silently correct
|
||||||
|
byte offsets that point into the middle of a character's encoding. Such
|
||||||
|
offsets almost always indicate a programming error, and they should be
|
||||||
|
reported as early as possible. So, when you write code which operates
|
||||||
|
on multibyte text, you should not use functions like these to ``clean
|
||||||
|
up'' byte offsets which the originator believes to be correct; instead,
|
||||||
|
your code should signal a @code{text:not-char-boundary} error as soon as
|
||||||
|
it detects an invalid offset. @xref{Multibyte Text Processing Errors}.
|
||||||
|
|
||||||
|
|
||||||
|
@node Multibyte String Functions, Exchanging Guile Text With the Outside World in C, Finding Character Encoding Boundaries, Functions for Operating on Multibyte Text
|
||||||
|
@subsection Multibyte String Functions
|
||||||
|
|
||||||
|
These functions allow you to operate on multibyte strings: sequences of
|
||||||
|
character encodings.
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_count (const unsigned char *@var{p}, int @var{len})
|
||||||
|
Return the number of Guile characters encoded by the @var{len} bytes at
|
||||||
|
@var{p}.
|
||||||
|
|
||||||
|
If the sequence contains any invalid character encodings, or ends with
|
||||||
|
an incomplete character encoding, signal a @code{text:bad-encoding}
|
||||||
|
error.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Macro} scm_char_t scm_mb_walk (unsigned char **@var{pp})
|
||||||
|
Return the character whose encoding starts at @code{*@var{pp}}, and
|
||||||
|
advance @code{*@var{pp}} to the start of the next character. Return -1
|
||||||
|
if @code{*@var{pp}} does not point to a valid character encoding.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} {const unsigned char *} scm_mb_prev (const unsigned char *@var{p})
|
||||||
|
If @var{p} points to the middle of the encoding of a Guile character,
|
||||||
|
return a pointer to the first byte of the encoding. If @var{p} points
|
||||||
|
to the start of the encoding of a Guile character, return the start of
|
||||||
|
the previous character's encoding.
|
||||||
|
|
||||||
|
This is like @code{scm_mb_floor}, but the returned pointer will always
|
||||||
|
be before @var{p}. If you use this function to drive an iteration, it
|
||||||
|
guarantees backward progress.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} {const unsigned char *} scm_mb_next (const unsigned char *@var{p})
|
||||||
|
If @var{p} points to the encoding of a Guile character, return a pointer
|
||||||
|
to the first byte of the encoding of the next character.
|
||||||
|
|
||||||
|
This is like @code{scm_mb_ceiling}, but the returned pointer will always
|
||||||
|
be after @var{p}. If you use this function to drive an iteration, it
|
||||||
|
guarantees forward progress.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} {const unsigned char *} scm_mb_index (const unsigned char *@var{p}, int @var{len}, int @var{i})
|
||||||
|
Assuming that the @var{len} bytes starting at @var{p} are a
|
||||||
|
concatenation of valid character encodings, return a pointer to the
|
||||||
|
start of the @var{i}'th character encoding in the sequence.
|
||||||
|
|
||||||
|
This function scans the sequence from the beginning to find the
|
||||||
|
@var{i}'th character, and will generally require time proportional to
|
||||||
|
the distance from @var{p} to the returned address.
|
||||||
|
|
||||||
|
If the sequence contains any invalid character encodings, or ends with
|
||||||
|
an incomplete character encoding, signal a @code{text:bad-encoding}
|
||||||
|
error.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
It is common to process the characters in a string from left to right.
|
||||||
|
However, if you fetch each character using @code{scm_mb_index}, each
|
||||||
|
call will scan the text from the beginning, so your loop will require
|
||||||
|
time proportional to at least the square of the length of the text. To
|
||||||
|
avoid this poor performance, you can use an @code{scm_mb_cache}
|
||||||
|
structure and the @code{scm_mb_index_cached} macro.
|
||||||
|
|
||||||
|
@deftp {Libguile Type} {struct scm_mb_cache}
|
||||||
|
This structure holds information that allows a string scanning operation
|
||||||
|
to use the results from a previous scan of the string. It has the
|
||||||
|
following members:
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item character
|
||||||
|
An index, in characters, into the string.
|
||||||
|
|
||||||
|
@item byte
|
||||||
|
The index, in bytes, of the start of that character.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
In other words, @code{byte} is the byte offset of the
|
||||||
|
@code{character}'th character of the string. Note that if @code{byte}
|
||||||
|
and @code{character} are equal, then all characters before that point
|
||||||
|
must have encodings exactly one byte long, and the string can be indexed
|
||||||
|
normally.
|
||||||
|
|
||||||
|
All elements of a @code{struct scm_mb_cache} structure should be
|
||||||
|
initialized to zero before its first use, and whenever the string's text
|
||||||
|
changes.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftypefn {Libguile Macro} const unsigned char *scm_mb_index_cached (const unsigned char *@var{p}, int @var{len}, int @var{i}, struct scm_mb_cache *@var{cache})
|
||||||
|
@deftypefnx {Libguile Function} const unsigned char *scm_mb_index_cached_func (const unsigned char *@var{p}, int @var{len}, int @var{i}, struct scm_mb_cache *@var{cache})
|
||||||
|
This macro and this function are identical to @code{scm_mb_index},
|
||||||
|
except that they may consult and update *@var{cache} in order to avoid
|
||||||
|
scanning the string from the beginning. @code{scm_mb_index_cached} is a
|
||||||
|
macro, so it may have less overhead than
|
||||||
|
@code{scm_mb_index_cached_func}, but it may evaluate its arguments more
|
||||||
|
than once.
|
||||||
|
|
||||||
|
Using @code{scm_mb_index_cached} or @code{scm_mb_index_cached_func}, you
|
||||||
|
can scan a string from left to right, or from right to left, in time
|
||||||
|
proportional to the length of the string. As long as each character
|
||||||
|
fetched is less than some constant distance before or after the previous
|
||||||
|
character fetched with @var{cache}, each access will require constant
|
||||||
|
time.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
Guile also provides functions to convert between an encoded sequence of
|
||||||
|
characters, and an array of @code{scm_char_t} objects.
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} scm_char_t *scm_mb_multibyte_to_fixed (const unsigned char *@var{p}, int @var{len}, int *@var{result_len})
|
||||||
|
Convert the variable-width text in the @var{len} bytes at @var{p}
|
||||||
|
to an array of @code{scm_char_t} values. Return a pointer to the array,
|
||||||
|
and set @code{*@var{result_len}} to the number of elements it contains.
|
||||||
|
The returned array is allocated with @code{malloc}, and it is the
|
||||||
|
caller's responsibility to free it.
|
||||||
|
|
||||||
|
If the text is not a sequence of valid character encodings, this
|
||||||
|
function will signal a @code{text:bad-encoding} error.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} unsigned char *scm_mb_fixed_to_multibyte (const scm_char_t *@var{fixed}, int @var{len}, int *@var{result_len})
|
||||||
|
Convert the array of @code{scm_char_t} values to a sequence of
|
||||||
|
variable-width character encodings. Return a pointer to the array of
|
||||||
|
bytes, and set @code{*@var{result_len}} to its length, in bytes.
|
||||||
|
|
||||||
|
The returned byte sequence is terminated with a zero byte, which is not
|
||||||
|
counted in the length returned in @code{*@var{result_len}}.
|
||||||
|
|
||||||
|
The returned byte sequence is allocated with @code{malloc}; it is the
|
||||||
|
caller's responsibility to free it.
|
||||||
|
|
||||||
|
If the text is not a sequence of valid character encodings, this
|
||||||
|
function will signal a @code{text:bad-encoding} error.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
|
@node Exchanging Guile Text With the Outside World in C, Implementing Your Own Text Conversions, Multibyte String Functions, Functions for Operating on Multibyte Text
|
||||||
|
@subsection Exchanging Guile Text With the Outside World in C
|
||||||
|
|
||||||
|
[[This is kind of a heavy-weight model, given that one end of the
|
||||||
|
conversion is always going to be the Guile encoding. Any way to shorten
|
||||||
|
things a bit?]]
|
||||||
|
|
||||||
|
Guile provides functions for converting between Guile's internal text
|
||||||
|
representation and encodings popular in the outside world. These
|
||||||
|
functions are closely modeled after the @code{iconv} functions available
|
||||||
|
on some systems.
|
||||||
|
|
||||||
|
To convert text between two encodings, you should first call
|
||||||
|
@code{scm_mb_iconv_open} to indicate the source and destination
|
||||||
|
encodings; this function returns a context object which records the
|
||||||
|
conversion to perform.
|
||||||
|
|
||||||
|
Then, you should call @code{scm_mb_iconv} to actually convert the text.
|
||||||
|
This function expects input and output buffers, and a pointer to the
|
||||||
|
context you got from @var{scm_mb_iconv_open}. You don't need to pass
|
||||||
|
all your input to @code{scm_mb_iconv} at once; you can invoke it on
|
||||||
|
successive blocks of input (as you read it from a file, say), and it
|
||||||
|
will convert as much as it can each time, indicating when you should
|
||||||
|
grow your output buffer.
|
||||||
|
|
||||||
|
An encoding may be @dfn{stateless}, or @dfn{stateful}. In most
|
||||||
|
encodings, a contiguous group of bytes from the sequence completely
|
||||||
|
specifies a particular character; these are stateless encodings.
|
||||||
|
However, some encodings require you to look back an unbounded number of
|
||||||
|
bytes in the stream to assign a meaning to a particular byte sequence;
|
||||||
|
such encodings are stateful.
|
||||||
|
|
||||||
|
For example, in the @samp{ISO-2022-JP} encoding for Japanese text, the
|
||||||
|
byte sequence @samp{27 36 66} indicates that subsequent bytes should be
|
||||||
|
taken in pairs and interpreted as characters from the JIS-0208 character
|
||||||
|
set. An arbitrary number of byte pairs may follow this sequence. The
|
||||||
|
byte sequence @samp{27 40 66} indicates that subsequent bytes should be
|
||||||
|
interpreted as @sc{ASCII}. In this encoding, you cannot tell whether a
|
||||||
|
given byte is an @sc{ASCII} character without looking back an arbitrary
|
||||||
|
distance for the most recent escape sequence, so it is a stateful
|
||||||
|
encoding.
|
||||||
|
|
||||||
|
In Guile, if a conversion involves a stateful encoding, the context
|
||||||
|
object carries any necessary state. Thus, you can have many independent
|
||||||
|
conversions to or from stateful encodings taking place simultaneously,
|
||||||
|
as long as each data stream uses its own context object for the
|
||||||
|
conversion.
|
||||||
|
|
||||||
|
@deftp {Libguile Type} {struct scm_mb_iconv}
|
||||||
|
This is the type for context objects, which represent the encodings and
|
||||||
|
current state of an ongoing text conversion. A @code{struct
|
||||||
|
scm_mb_iconv} records the source and destination encodings, and keeps
|
||||||
|
track of any information needed to handle stateful encodings.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} {struct scm_mb_iconv *} scm_mb_iconv_open (const char *@var{tocode}, const char *@var{fromcode})
|
||||||
|
Return a pointer to a new @code{struct scm_mb_iconv} context object,
|
||||||
|
ready to convert from the encoding named @var{fromcode} to the encoding
|
||||||
|
named @var{tocode}. For stateful encodings, the context object is in
|
||||||
|
some appropriate initial state, ready for use with the
|
||||||
|
@code{scm_mb_iconv} function.
|
||||||
|
|
||||||
|
When you are done using a context object, you may call
|
||||||
|
@code{scm_mb_iconv_close} to free it.
|
||||||
|
|
||||||
|
If either @var{tocode} or @var{fromcode} is not the name of a known
|
||||||
|
encoding, this function will signal the @code{text:unknown-conversion}
|
||||||
|
error, described below.
|
||||||
|
|
||||||
|
@c Try to use names here from the IANA list:
|
||||||
|
@c see ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets
|
||||||
|
Guile supports at least these encodings:
|
||||||
|
@table @samp
|
||||||
|
|
||||||
|
@item US-ASCII
|
||||||
|
@sc{US-ASCII}, in the standard one-character-per-byte encoding.
|
||||||
|
|
||||||
|
@item ISO-8859-1
|
||||||
|
The usual character set for Western European languages, in its usual
|
||||||
|
one-character-per-byte encoding.
|
||||||
|
|
||||||
|
@item Guile-MB
|
||||||
|
Guile's current internal multibyte encoding. The actual encoding this
|
||||||
|
name refers to will change from one version of Guile to the next. You
|
||||||
|
should use this when converting data between external sources and the
|
||||||
|
encoding used by Guile objects.
|
||||||
|
|
||||||
|
You should @emph{not} use this as the encoding for data presented to the
|
||||||
|
outside world, for two reasons. 1) Its meaning will change over time,
|
||||||
|
so data written using the @samp{guile} encoding with one version of
|
||||||
|
Guile might not be readable with the @samp{guile} encoding in another
|
||||||
|
version of Guile. 2) It currently corresponds to @samp{Emacs-Mule},
|
||||||
|
which invented for Emacs's internal use, and was never intended to serve
|
||||||
|
as an exchange medium.
|
||||||
|
|
||||||
|
@item Guile-Wide
|
||||||
|
Guile's character set, as an array of @code{scm_char_t} values.
|
||||||
|
|
||||||
|
Note that this encoding is even less suitable for public use than
|
||||||
|
@samp{Guile}, since the exact sequence of bytes depends heavily on the
|
||||||
|
size and endianness the host system uses for @code{scm_char_t}. Using
|
||||||
|
this encoding is very much like calling the
|
||||||
|
@code{scm_mb_multibyte_to_fixed} or @code{scm_mb_fixed_to_multibyte}
|
||||||
|
functions, except that @code{scm_mb_iconv} gives you more control over
|
||||||
|
buffer allocation and management.
|
||||||
|
|
||||||
|
@item Emacs-Mule
|
||||||
|
This is the variable-length encoding for multi-lingual text by GNU
|
||||||
|
Emacs, at least through version 20.4. You probably should not use this
|
||||||
|
encoding, as it is designed only for Emacs's internal use. However, we
|
||||||
|
provide it here because it's trivial to support, and some people
|
||||||
|
probably do have @samp{emacs-mule}-format files lying around.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
(At the moment, this list doesn't include any character sets suitable for
|
||||||
|
external use that can actually handle multilingual data; this is
|
||||||
|
unfortunate, as it encourages users to write data in Emacs-Mule format,
|
||||||
|
which nobody but Emacs and Guile understands. We hope to add support
|
||||||
|
for Unicode in UTF-8 soon, which should solve this problem.)
|
||||||
|
|
||||||
|
Case is not significant in encoding names.
|
||||||
|
|
||||||
|
You can define your own conversions; see @ref{Implementing Your Own Text
|
||||||
|
Conversions}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_have_encoding (const char *@var{encoding})
|
||||||
|
Return a non-zero value if Guile supports the encoding named @var{encoding}[[]]
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} size_t scm_mb_iconv (struct scm_mb_iconv *@var{context}, const char **@var{inbuf}, size_t *@var{inbytesleft}, char **@var{outbuf}, size_t *@var{outbytesleft})
|
||||||
|
Convert a sequence of characters from one encoding to another. The
|
||||||
|
argument @var{context} specifies the encodings to use for the input and
|
||||||
|
output, and carries state for stateful encodings; use
|
||||||
|
@code{scm_mb_iconv_open} to create a @var{context} object for a
|
||||||
|
particular conversion.
|
||||||
|
|
||||||
|
Upon entry to the function, @code{*@var{inbuf}} should point to the
|
||||||
|
input buffer, and @code{*@var{inbytesleft}} should hold the number of
|
||||||
|
input bytes present in the buffer; @code{*@var{outbuf}} should point to
|
||||||
|
the output buffer, and @code{*@var{outbytesleft}} should hold the number
|
||||||
|
of bytes available to hold the conversion results in that buffer.
|
||||||
|
|
||||||
|
Upon exit from the function, @code{*@var{inbuf}} points to the first
|
||||||
|
unconsumed byte of input, and @code{*@var{inbytesleft}} holds the number
|
||||||
|
of unconsumed input bytes; @code{*@var{outbuf}} points to the byte after
|
||||||
|
the last output byte, and @code{*@var{outbyteleft}} holds the number of
|
||||||
|
bytes left unused in the output buffer.
|
||||||
|
|
||||||
|
For stateful encodings, @var{context} carries encoding state from one
|
||||||
|
call to @code{scm_mb_iconv} to the next. Thus, successive calls to
|
||||||
|
@var{scm_mb_iconv} which use the same context object can convert a
|
||||||
|
stream of data one chunk at a time.
|
||||||
|
|
||||||
|
If @var{inbuf} is zero or @code{*@var{inbuf}} is zero, then the call is
|
||||||
|
taken as a request to reset the states of the input and the output
|
||||||
|
encodings. If @var{outbuf} is non-zero and @code{*@var{outbuf}} is
|
||||||
|
non-zero, then @code{scm_mb_iconv} stores a byte sequence in the output
|
||||||
|
buffer to put the output encoding in its initial state. If the output
|
||||||
|
buffer is not large enough to hold this byte sequence,
|
||||||
|
@code{scm_mb_iconv} returns @code{scm_mb_iconv_too_big}, and leaves
|
||||||
|
the shift states of @var{context}'s input and output encodings
|
||||||
|
unchanged.
|
||||||
|
|
||||||
|
The @code{scm_mb_iconv} function always consumes only complete
|
||||||
|
characters or shift sequences from the input buffer, and the output
|
||||||
|
buffer always contains a sequence of complete characters or escape
|
||||||
|
sequences.
|
||||||
|
|
||||||
|
If the input sequence contains characters which are not expressible in
|
||||||
|
the output encoding, @code{scm_mb_iconv} converts it in an
|
||||||
|
implementation-defined way. It may simply delete the character.
|
||||||
|
|
||||||
|
Some encodings use byte sequences which do not correspond to any textual
|
||||||
|
character. For example, the escape sequence of a stateful encoding has
|
||||||
|
no textual meaning. When converting from such an encoding, a call to
|
||||||
|
@code{scm_mb_iconv} might consume input but produce no output, since the
|
||||||
|
input sequence might contain only escape sequences.
|
||||||
|
|
||||||
|
Normally, @code{scm_mb_iconv} returns the number of input characters it
|
||||||
|
could not convert perfectly to the ouput encoding. However, it may
|
||||||
|
return one of the @code{scm_mb_iconv_} codes described below, to
|
||||||
|
indicate an error. All of these codes are negative values.
|
||||||
|
|
||||||
|
If the input sequence contains an invalid character encoding, conversion
|
||||||
|
stops before the invalid input character, and @code{scm_mb_iconv}
|
||||||
|
returns the constant value @code{scm_mb_iconv_bad_encoding}.
|
||||||
|
|
||||||
|
If the input sequence ends with an incomplete character encoding,
|
||||||
|
@code{scm_mb_iconv} will leave it in the input buffer, unconsumed, and
|
||||||
|
return the constant value @code{scm_mb_iconv_incomplete_encoding}. This
|
||||||
|
is not necessarily an error, if you expect to call @code{scm_mb_iconv}
|
||||||
|
again with more data which might contain the rest of the encoding
|
||||||
|
fragment.
|
||||||
|
|
||||||
|
If the output buffer does not contain enough room to hold the converted
|
||||||
|
form of the complete input text, @code{scm_mb_iconv} converts as much as
|
||||||
|
it can, changes the input and output pointers to reflect the amount of
|
||||||
|
text successfully converted, and then returns
|
||||||
|
@code{scm_mb_iconv_too_big}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
Here are the status codes that might be returned by @code{scm_mb_iconv}.
|
||||||
|
They are all negative integers.
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item scm_mb_iconv_too_big
|
||||||
|
The conversion needs more room in the output buffer. Some characters
|
||||||
|
may have been consumed from the input buffer, and some characters may
|
||||||
|
have been placed in the available space in the output buffer.
|
||||||
|
|
||||||
|
@item scm_mb_iconv_bad_encoding
|
||||||
|
@code{scm_mb_iconv} encountered an invalid character encoding in the
|
||||||
|
input buffer. Conversion stopped before the invalid character, so there
|
||||||
|
may be some characters consumed from the input buffer, and some
|
||||||
|
converted text in the output buffer.
|
||||||
|
|
||||||
|
@item scm_mb_iconv_incomplete_encoding
|
||||||
|
The input buffer ends with an incomplete character encoding. The
|
||||||
|
incomplete encoding is left in the input buffer, unconsumed. This is
|
||||||
|
not necessarily an error, if you expect to call @code{scm_mb_iconv}
|
||||||
|
again with more data which might contain the rest of the incomplete
|
||||||
|
encoding.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
Finally, Guile provides a function for destroying conversion contexts.
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} void scm_mb_iconv_close (struct scm_mb_iconv *@var{context})
|
||||||
|
Deallocate the conversion context object @var{context}, and all other
|
||||||
|
resources allocated by the call to @code{scm_mb_iconv_open} which
|
||||||
|
returned @var{context}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
|
@node Implementing Your Own Text Conversions, , Exchanging Guile Text With the Outside World in C, Functions for Operating on Multibyte Text
|
||||||
|
@subsection Implementing Your Own Text Conversions
|
||||||
|
|
||||||
|
[[note that conversions to and from Guile must produce streams
|
||||||
|
containing only valid character encodings, or else Guile will crash]]
|
||||||
|
|
||||||
|
This section describes the interface for adding your own encoding
|
||||||
|
conversions for use with @code{scm_mb_iconv}. The interface here is
|
||||||
|
borrowed from the GNOME Project's @file{libunicode} library.
|
||||||
|
|
||||||
|
Guile's @code{scm_mb_iconv} function works by converting the input text
|
||||||
|
to a stream of @code{scm_char_t} characters, and then converting
|
||||||
|
those characters to the desired output encoding. This makes it easy
|
||||||
|
for Guile to choose the appropriate conversion back ends for an
|
||||||
|
arbitrary pair of input and output encodings, but it also means that the
|
||||||
|
accuracy and quality of the conversions depends on the fidelity of
|
||||||
|
Guile's internal character set to the source and destination encodings.
|
||||||
|
Since @code{scm_mb_iconv} will be used almost exclusively for converting
|
||||||
|
to and from Guile's internal character set, this shouldn't be a problem.
|
||||||
|
|
||||||
|
To add support for a particular encoding to Guile, you must provide one
|
||||||
|
function (called the @dfn{read} function) which converts from your
|
||||||
|
encoding to an array of @code{scm_char_t}'s, and another function
|
||||||
|
(called the @dfn{write} function) to convert from an array of
|
||||||
|
@code{scm_char_t}'s back into your encoding. To convert from some
|
||||||
|
encoding @var{a} to some other encoding @var{b}, Guile pairs up
|
||||||
|
@var{a}'s read function with @var{b}'s write function. Each call to
|
||||||
|
@code{scm_mb_iconv} passes text in encoding @var{a} through the read
|
||||||
|
function, to produce an array of @code{scm_char_t}'s, and then passes
|
||||||
|
that array to the write function, to produce text in encoding @var{b}.
|
||||||
|
|
||||||
|
For stateful encodings, a read or write function can hang its own data
|
||||||
|
structures off the conversion object, and provide its own functions to
|
||||||
|
allocate and destroy them; this allows read and write functions to
|
||||||
|
maintain whatever state they like.
|
||||||
|
|
||||||
|
The Guile conversion back end represents each available encoding with a
|
||||||
|
@code{struct scm_mb_encoding} object.
|
||||||
|
|
||||||
|
@deftp {Libguile Type} {struct scm_mb_encoding}
|
||||||
|
This data structure describes an encoding. It has the following
|
||||||
|
members:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item char **names
|
||||||
|
An array of strings, giving the various names for this encoding. The
|
||||||
|
array should be terminated by a zero pointer. Case is not significant
|
||||||
|
in encoding names.
|
||||||
|
|
||||||
|
The @code{scm_mb_iconv_open} function searches the list of registered
|
||||||
|
encodings for an encoding whose @code{names} array matches its
|
||||||
|
@var{tocode} or @var{fromcode} argument.
|
||||||
|
|
||||||
|
@item int (*init) (void **@var{cookie})
|
||||||
|
An initialization function for the encoding's private data.
|
||||||
|
@code{scm_mb_iconv_open} will call this function, passing it the address
|
||||||
|
of the cookie for this encoding in this context. (We explain cookies
|
||||||
|
below.) There is no way for the @code{init} function to tell whether
|
||||||
|
the encoding will be used for reading or writing.
|
||||||
|
|
||||||
|
Note that @code{init} receives a @emph{pointer} to the cookie, not the
|
||||||
|
cookie itself. Because the type of @var{cookie} is @code{void **}, the
|
||||||
|
C compiler will not check it as carefully as it would other types.
|
||||||
|
|
||||||
|
The @code{init} member may be zero, indicating that no initialization is
|
||||||
|
necessary for this encoding.
|
||||||
|
|
||||||
|
@item int (*destroy) (void **@var{cookie})
|
||||||
|
A deallocation function for the encoding's private data.
|
||||||
|
@code{scm_mb_iconv_close} calls this function, passing it the address of
|
||||||
|
the cookie for this encoding in this context. The @code{destroy}
|
||||||
|
function should free any data the @code{init} function allocated.
|
||||||
|
|
||||||
|
Note that @code{destroy} receives a @emph{pointer} to the cookie, not the
|
||||||
|
cookie itself. Because the type of @var{cookie} is @code{void **}, the
|
||||||
|
C compiler will not check it as carefully as it would other types.
|
||||||
|
|
||||||
|
The @code{destroy} member may be zero, indicating that this encoding
|
||||||
|
doesn't need to perform any special action to destroy its local data.
|
||||||
|
|
||||||
|
@item int (*reset) (void *@var{cookie}, char **@var{outbuf}, size_t *@var{outbytesleft})
|
||||||
|
Put the encoding into its initial shift state. Guile calls this
|
||||||
|
function whether the encoding is being used for input or output, so this
|
||||||
|
should take appropriate steps for both directions. If @var{outbuf} and
|
||||||
|
@var{outbytesleft} are valid, the reset function should emit an escape
|
||||||
|
sequence to reset the output stream to its initial state; @var{outbuf}
|
||||||
|
and @var{outbytesleft} should be handled just as for
|
||||||
|
@code{scm_mb_iconv}.
|
||||||
|
|
||||||
|
This function can return an @code{scm_mb_iconv_} error code
|
||||||
|
(@pxref{Exchanging Guile Text With the Outside World in C}). If it
|
||||||
|
returns @code{scm_mb_iconv_too_big}, then the output buffer's shift
|
||||||
|
state must be left unchanged.
|
||||||
|
|
||||||
|
Note that @code{reset} receives the cookie's value itself, not a pointer
|
||||||
|
to the cookie, as the @code{init} and @code{destroy} functions do.
|
||||||
|
|
||||||
|
The @code{reset} member may be zero, indicating that this encoding
|
||||||
|
doesn't use a shift state.
|
||||||
|
|
||||||
|
@item enum scm_mb_read_result (*read) (void *@var{cookie}, const char **@var{inbuf}, size_t *@var{inbytesleft}, scm_char_t **@var{outbuf}, size_t *@var{outcharsleft})
|
||||||
|
Read some bytes and convert into an array of Guile characters. This is
|
||||||
|
the encoding's read function.
|
||||||
|
|
||||||
|
On entry, there are *@var{inbytesleft} bytes of text at *@var{inbuf} to
|
||||||
|
be converted, and *@var{outcharsleft} characters available at
|
||||||
|
*@var{outbuf} to hold the results.
|
||||||
|
|
||||||
|
On exit, *@var{inbytesleft} and *@var{inbuf} indicate the input bytes
|
||||||
|
still not consumed. *@var{outcharsleft} and *@var{outbuf} indicate the
|
||||||
|
output buffer space still not filled. (By exclusion, these indicate
|
||||||
|
which input bytes were consumed, and which output characters were
|
||||||
|
produced.)
|
||||||
|
|
||||||
|
Return one of the @code{enum scm_mb_read_result} values, described below.
|
||||||
|
|
||||||
|
Note that @code{read} receives the cookie's value itself, not a pointer
|
||||||
|
to the cookie, as the @code{init} and @code{destroy} functions do.
|
||||||
|
|
||||||
|
@item enum scm_mb_write_result (*write) (void *@var{cookie}, scm_char_t **@var{inbuf}, size_t *@var{incharsleft}, **@var{outbuf}, size_t *@var{outbytesleft})
|
||||||
|
Convert an array of Guile characters to output bytes. This is
|
||||||
|
the encoding's write function.
|
||||||
|
|
||||||
|
On entry, there are *@var{incharsleft} Guile characters available at
|
||||||
|
*@var{inbuf}, and *@var{outbytesleft} bytes available to store output at
|
||||||
|
*@var{outbuf}.
|
||||||
|
|
||||||
|
On exit, *@var{incharsleft} and *@var{inbuf} indicate the number of
|
||||||
|
Guile characters left unconverted (because there was insufficient room
|
||||||
|
in the output buffer to hold their converted forms), and
|
||||||
|
*@var{outbytesleft} and *@var{outbuf} indicate the unused portion of the
|
||||||
|
output buffer.
|
||||||
|
|
||||||
|
Return one of the @code{scm_mb_write_result} values, described below.
|
||||||
|
|
||||||
|
Note that @code{write} receives the cookie's value itself, not a pointer
|
||||||
|
to the cookie, as the @code{init} and @code{destroy} functions do.
|
||||||
|
|
||||||
|
@item struct scm_mb_encoding *next
|
||||||
|
This is used by Guile to maintain a linked list of encodings. It is
|
||||||
|
filled in when you call @code{scm_mb_register_encoding} to add your
|
||||||
|
encoding to the list.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
Here is the enumerated type for the values an encoding's read function
|
||||||
|
can return:
|
||||||
|
|
||||||
|
@deftp {Libguile Type} {enum scm_mb_read_result}
|
||||||
|
This type represents the result of a call to an encoding's read
|
||||||
|
function. It has the following values:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item scm_mb_read_ok
|
||||||
|
The read function consumed at least one byte of input.
|
||||||
|
|
||||||
|
@item scm_mb_read_incomplete
|
||||||
|
The data present in the input buffer does not contain a complete
|
||||||
|
character encoding. No input was consumed, and no characters were
|
||||||
|
produced as output. This is not necessarily an error status, if there
|
||||||
|
is more data to pass through.
|
||||||
|
|
||||||
|
@item scm_mb_read_error
|
||||||
|
The input contains an invalid character encoding.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
Here is the enumerated type for the values an encoding's write function
|
||||||
|
can return:
|
||||||
|
|
||||||
|
@deftp {Libguile Type} {enum scm_mb_write_result}
|
||||||
|
This type represents the result of a call to an encoding's write
|
||||||
|
function. It has the following values:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item scm_mb_write_ok
|
||||||
|
The write function was able to convert all the characters in @var{inbuf}
|
||||||
|
successfully.
|
||||||
|
|
||||||
|
@item scm_mb_write_too_big
|
||||||
|
The write function filled the output buffer, but there are still
|
||||||
|
characters in @var{inbuf} left unconsumed; @var{inbuf} and
|
||||||
|
@var{incharsleft} indicate the unconsumed portion of the input buffer.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
|
||||||
|
Conversions to or from stateful encodings need to keep track of each
|
||||||
|
encoding's current state. Each conversion context contains two
|
||||||
|
@code{void *} variables called @dfn{cookies}, one for the input
|
||||||
|
encoding, and one for the output encoding. These cookies are passed to
|
||||||
|
the encodings' functions, for them to use however they please. A
|
||||||
|
stateful encoding can use its cookie to hold a pointer to some object
|
||||||
|
which maintains the context's current shift state. Stateless encodings
|
||||||
|
will probably not use their cookies.
|
||||||
|
|
||||||
|
The cookies' lifetime is the same as that of the context object. When
|
||||||
|
the user calls @code{scm_mb_iconv_close} to destroy a context object,
|
||||||
|
@code{scm_mb_iconv_close} calls the input and output encodings'
|
||||||
|
@code{destroy} functions, passing them their respective cookies, so each
|
||||||
|
encoding can free any data it allocated for that context.
|
||||||
|
|
||||||
|
Note that, if a read or write function returns a successful result code
|
||||||
|
like @code{scm_mb_read_ok} or @code{scm_mb_write_ok}, then the remaining
|
||||||
|
input, together with the output, must together represent the complete
|
||||||
|
input text; the encoding may not store any text temporarily in its
|
||||||
|
cookie. This is because, if @code{scm_mb_iconv} returns a successful
|
||||||
|
result to the user, it is correct for the user to assume that all the
|
||||||
|
consumed input has been converted and placed in the output buffer.
|
||||||
|
There is no ``flush'' operation to push any final results out of the
|
||||||
|
encodings' buffers.
|
||||||
|
|
||||||
|
Here is the function you call to register a new encoding with the
|
||||||
|
conversion system:
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} void scm_mb_register_encoding (struct scm_mb_encoding *@var{encoding})
|
||||||
|
Add the encoding described by @code{*@var{encoding}} to the set
|
||||||
|
understood by @code{scm_mb_iconv_open}. Once you have registered your
|
||||||
|
encoding, you can use it by calling @code{scm_mb_iconv_open} with one of
|
||||||
|
the names in @code{@var{encoding}->names}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
|
@node Multibyte Text Processing Errors, Why Guile Does Not Use a Fixed-Width Encoding, Functions for Operating on Multibyte Text, Working With Multibyte Strings in C
|
||||||
|
@section Multibyte Text Processing Errors
|
||||||
|
|
||||||
|
This section describes error conditions which code can signal to
|
||||||
|
indicate problems encountered while processing multibyte text. In each
|
||||||
|
case, the arguments @var{message} and @var{args} are an error format
|
||||||
|
string and arguments to be substituted into the string, as accepted by
|
||||||
|
the @code{display-error} function.
|
||||||
|
|
||||||
|
@deffn Condition text:not-char-boundary func message args object offset
|
||||||
|
By calling @var{func}, the program attempted to access a character at
|
||||||
|
byte offset @var{offset} in the Guile object @var{object}, but
|
||||||
|
@var{offset} is not the start of a character's encoding in @var{object}.
|
||||||
|
|
||||||
|
Typically, @var{object} is a string or symbol. If the function signalling
|
||||||
|
the error cannot find the Guile object that contains the text it is
|
||||||
|
inspecting, it should use @code{#f} for @var{object}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn Condition text:bad-encoding func message args object
|
||||||
|
By calling @var{func}, the program attempted to interpret the text in
|
||||||
|
@var{object}, but @var{object} contains a byte sequence which is not a
|
||||||
|
valid encoding for any character.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn Condition text:not-guile-char func message args number
|
||||||
|
By calling @var{func}, the program attempted to treat @var{number} as the
|
||||||
|
number of a character in the Guile character set, but @var{number} does
|
||||||
|
not correspond to any character in the Guile character set.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn Condition text:unknown-conversion func message args from to
|
||||||
|
By calling @var{func}, the program attempted to convert from an encoding
|
||||||
|
named @var{from} to an encoding named @var{to}, but Guile does not
|
||||||
|
support such a conversion.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deftypevr {Libguile Variable} SCM scm_text_not_char_boundary
|
||||||
|
@deftypevrx {Libguile Variable} SCM scm_text_bad_encoding
|
||||||
|
@deftypevrx {Libguile Variable} SCM scm_text_not_guile_char
|
||||||
|
These variables hold the scheme symbol objects whose names are the
|
||||||
|
condition symbols above. You can use these when signalling these
|
||||||
|
errors, instead of looking them up yourself.
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
|
||||||
|
@node Why Guile Does Not Use a Fixed-Width Encoding, , Multibyte Text Processing Errors, Working With Multibyte Strings in C
|
||||||
|
@section Why Guile Does Not Use a Fixed-Width Encoding
|
||||||
|
|
||||||
|
Multibyte encodings are clumsier to work with than encodings which use a
|
||||||
|
fixed number of bytes for every character. For example, using a
|
||||||
|
fixed-width encoding, we can extract the @var{i}th character of a string
|
||||||
|
in constant time, and we can always substitute the @var{i}th character
|
||||||
|
of a string with any other character without reallocating or copying the
|
||||||
|
string.
|
||||||
|
|
||||||
|
However, there are no fixed-width encodings which include the characters
|
||||||
|
we wish to include, and also fit in a reasonable amount of space.
|
||||||
|
Despite the Unicode standard's claims to the contrary, Unicode is not
|
||||||
|
really a fixed-width encoding. Unicode uses surrogate pairs to
|
||||||
|
represent characters outside the 16-bit range; a surrogate pair must be
|
||||||
|
treated as a single character, but occupies two 16-bit spaces. As of
|
||||||
|
this writing, there are already plans to assign characters to the
|
||||||
|
surrogate character codes. Three- and four-byte encodings are
|
||||||
|
too wasteful for a majority of Guile's users, who only need @sc{ASCII}
|
||||||
|
and a few accented characters.
|
||||||
|
|
||||||
|
Another alternative would be to have several different fixed-width
|
||||||
|
string representations, each with a different element size. For each
|
||||||
|
string, Guile would use the smallest element size capable of
|
||||||
|
accomodating the string's text. This would allow users of English and
|
||||||
|
the Western European languages to use the traditional memory-efficient
|
||||||
|
encodings. However, if Guile has @var{n} string representations, then
|
||||||
|
users must write @var{n} versions of any code which manipulates text
|
||||||
|
directly --- one for each element size. And if a user wants to operate
|
||||||
|
on two strings simultaneously, and wants to avoid testing the string
|
||||||
|
sizes within the loop, she must make @var{n}*@var{n} copies of the loop.
|
||||||
|
Most users will simply not bother. Instead, they will write code which
|
||||||
|
supports only one string size, leaving us back where we started. By
|
||||||
|
using a single internal representation, Guile makes it easier for users
|
||||||
|
to write multilingual code.
|
||||||
|
|
||||||
|
[[What about tagging each string with its encoding?
|
||||||
|
"Every extension must be written to deal with every encoding"]]
|
||||||
|
|
||||||
|
[[You don't really want to index strings anyway.]]
|
||||||
|
|
||||||
|
Finally, Guile's multibyte encoding is not so bad. Unlike a two- or
|
||||||
|
four-byte encoding, it is efficient in space for American and European
|
||||||
|
users. Furthermore, the properties described above mean that many
|
||||||
|
functions can be coded just as they would for a single-byte encoding;
|
||||||
|
see @ref{Promised Properties of the Guile Multibyte Encoding}.
|
||||||
|
|
||||||
|
@bye
|
146
doc/mltext.texi
Normal file
146
doc/mltext.texi
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
@node Working with Multilingual Text
|
||||||
|
@chapter Working with Multilingual Text
|
||||||
|
|
||||||
|
@node Guile Character Properties, Exchanging Text With The Outside World, Multibyte String Functions, Functions for Operating on Multibyte Text
|
||||||
|
@section Guile Character Properties
|
||||||
|
|
||||||
|
These functions give information about the nature of a given Guile
|
||||||
|
character. These are defined for any @code{scm_mb_char_t} value.
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_isalnum (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is an alphabetic or numeric character.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_is_alpha (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is an alphabetic character.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_iscntrl (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is a control character.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_isdigit (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is a digit.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_isgraph (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is a visible character.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_isupper (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is an upper-case character.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_islower (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is a lower-case character.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_istitle (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is a title-case character. See the Unicode
|
||||||
|
standard for an explanation of title case.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_isprint (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is a printable character.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_ispunct (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is a punctuation character.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_isspace (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is a whitespace character.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_isxdigit (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is a hexidecimal digit.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} int scm_mb_isdefined (scm_mb_char_t @var{c})
|
||||||
|
Return non-zero iff @var{c} is a valid character.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} scm_mb_char_t scm_mb_char_toupper (scm_mb_char_t @var{c})
|
||||||
|
@deftypefnx {Libguile Function} scm_mb_char_t scm_mb_char_tolower (scm_mb_char_t @var{c})
|
||||||
|
@deftypefnx {Libguile Function} scm_mb_char_t scm_mb_char_totitle (scm_mb_char_t @var{c})
|
||||||
|
Convert @var{c} to upper, lower, or title case. If @var{c} has no
|
||||||
|
equivalent in the requested case, or is already in that case, return it
|
||||||
|
unchanged.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} in scm_mb_digit_value (scm_mb_char_t @var{c})
|
||||||
|
If @var{c} is a hexidecimal digit (according to
|
||||||
|
@code{scm_mb_isxdigit}), then return its numeric value. Otherwise
|
||||||
|
return -1.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} in scm_mb_digit_value (scm_mb_char_t @var{c})
|
||||||
|
If @var{c} is a digit (according to @code{scm_mb_isdigit}), then
|
||||||
|
return its numeric value. Otherwise return -1.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
|
@node Multibyte Character Tables, Multibyte Character Categories, Exchanging Text With The Outside World, Functions for Operating on Multibyte Text
|
||||||
|
@section Multibyte Character Tables
|
||||||
|
|
||||||
|
A @dfn{character table} is a table mapping @code{scm_mb_char_t} values
|
||||||
|
onto Guile objects. Guile provides functions for creating character
|
||||||
|
tables, setting entries, and looking up characters. Character tables
|
||||||
|
are Guile objects, so they are managed by Guile's garbage collector.
|
||||||
|
|
||||||
|
A character table can have a ``parent'' table, from which it inherits
|
||||||
|
values for characters. If a character table @var{child}, with a parent
|
||||||
|
table @var{parent} maps some character @var{c} to the value
|
||||||
|
@code{SCM_UNDEFINED}, then @code{scm_c_char_table_ref (@var{child},
|
||||||
|
@var{c})} will look up @var{c} in @var{parent}, and return the value it
|
||||||
|
finds there.
|
||||||
|
|
||||||
|
This section describes only the C API for working with character tables.
|
||||||
|
For the Scheme-level API, see @ref{some other section}.
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} scm_make_char_table (SCM @var{init}, SCM @var{parent})
|
||||||
|
Return a new character table object which maps every character to
|
||||||
|
@var{init}. If @var{parent} is a character table, then @var{parent} is
|
||||||
|
the new table's parent. If @var{parent} table is @code{SCM_UNDEFINED},
|
||||||
|
then the new table has no parent. Otherwise, signal a type error.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} SCM scm_c_char_table_ref (SCM @var{table}, scm_mb_char_t @var{c})
|
||||||
|
Look up the character @var{c} in the character table @var{table}, and
|
||||||
|
return the value found there. If @var{table} maps @var{c} to
|
||||||
|
@code{SCM_UNDEFINED}, and @var{table} has a parent, then look up @var{c}
|
||||||
|
in the parent.
|
||||||
|
|
||||||
|
If @var{table} is not a character table, signal an error.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Libguile Function} SCM scm_c_char_table_set_x (SCM @var{table}, scm_mb_char_t @var{c}, SCM @var{value})
|
||||||
|
Set @var{table}'s value for the character @var{c} to @var{value}.
|
||||||
|
If @var{value} is @code{SCM_UNDEFINED}, then @var{table}'s parent's
|
||||||
|
value will show through for @var{c}.
|
||||||
|
|
||||||
|
If @var{table} is not a character table, signal an error.
|
||||||
|
|
||||||
|
This function changes only @var{table} itself, never @var{table}'s
|
||||||
|
parent.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
[[this is all wrong. what about default values?]]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@node Multibyte Character Categories, , Multibyte Character Tables, Functions for Operating on Multibyte Text
|
||||||
|
@section Multibyte Character Categories
|
||||||
|
|
||||||
|
[[This will describe an ADT representing subsets of the Guile character
|
||||||
|
set.]]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@node Exchanging Guile Text With the Outside World
|
||||||
|
@subsection Exchanging Guile Text With the Outside World
|
||||||
|
|
||||||
|
[[Scheme-level functions for converting between encodings]]
|
2247
doc/posix.texi
Normal file
2247
doc/posix.texi
Normal file
File diff suppressed because it is too large
Load diff
131
doc/preface.texi
Normal file
131
doc/preface.texi
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
@iftex
|
||||||
|
@page
|
||||||
|
@unnumbered Preface
|
||||||
|
|
||||||
|
This reference manual documents Guile, GNU's Ubiquitous Intelligent
|
||||||
|
Language for Extensions. It describes how to use Guile in many useful
|
||||||
|
and interesting ways.
|
||||||
|
|
||||||
|
This is edition 1.0 of the reference manual, and corresponds to Guile
|
||||||
|
version @value{VERSION}.
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
|
||||||
|
@iftex
|
||||||
|
@section The Guile License
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@ifnottex
|
||||||
|
@node Guile License
|
||||||
|
@chapter The Guile License
|
||||||
|
@end ifnottex
|
||||||
|
|
||||||
|
The license of Guile consists of the GNU GPL plus a special statement
|
||||||
|
giving blanket permission to link with non-free software. This is the
|
||||||
|
license statement as found in any individual file that it applies to:
|
||||||
|
|
||||||
|
@quotation
|
||||||
|
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 the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
This program 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
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this software; see the file COPYING. If not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA
|
||||||
|
|
||||||
|
As a special exception, the Free Software Foundation gives permission
|
||||||
|
for additional uses of the text contained in its release of GUILE.
|
||||||
|
|
||||||
|
The exception is that, if you link the GUILE library with other files to
|
||||||
|
produce an executable, this does not by itself cause the resulting
|
||||||
|
executable to be covered by the GNU General Public License. Your use of
|
||||||
|
that executable is in no way restricted on account of linking the GUILE
|
||||||
|
library code into it.
|
||||||
|
|
||||||
|
This exception does not however invalidate any other reasons why the
|
||||||
|
executable file might be covered by the GNU General Public License.
|
||||||
|
|
||||||
|
This exception applies only to the code released by the Free Software
|
||||||
|
Foundation under the name GUILE. If you copy code from other Free
|
||||||
|
Software Foundation releases into a copy of GUILE, as the General Public
|
||||||
|
License permits, the exception does not apply to the code that you add
|
||||||
|
in this way. To avoid misleading anyone as to the status of such
|
||||||
|
modified files, you must delete this exception notice from them.
|
||||||
|
|
||||||
|
If you write modifications of your own for GUILE, it is your choice
|
||||||
|
whether to permit this exception to apply to your modifications. If you
|
||||||
|
do not wish that, delete this exception notice.
|
||||||
|
@end quotation
|
||||||
|
|
||||||
|
|
||||||
|
@iftex
|
||||||
|
@section Layout of this Manual
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@ifnottex
|
||||||
|
@node Manual Layout
|
||||||
|
@chapter Layout of this Manual
|
||||||
|
@end ifnottex
|
||||||
|
|
||||||
|
This manual is divided into five parts.
|
||||||
|
|
||||||
|
@strong{Part I: Introduction to Guile} provides an overview of what
|
||||||
|
Guile is and how you can use it. A whirlwind tour shows how Guile can
|
||||||
|
be used interactively and as a script interpreter, how to link Guile
|
||||||
|
into your own applications, and how to write modules of interpreted and
|
||||||
|
compiled code for use with Guile. All of the ideas introduced here are
|
||||||
|
documented in full by the later parts of the manual.
|
||||||
|
|
||||||
|
@strong{Part II: Guile Scheme} documents the core Scheme language and
|
||||||
|
features that Guile implements. Although the basis for this is the
|
||||||
|
Scheme language described in R5RS, this part of the manual does not
|
||||||
|
assume any prior familiarity with R5RS in particular, or with Scheme in
|
||||||
|
general. Basic Scheme concepts, standard aspects of the Scheme language
|
||||||
|
and Guile extensions on top of R5RS are all documented from scratch, and
|
||||||
|
organized by functionality rather than by the defining standards.
|
||||||
|
|
||||||
|
@strong{Part III: Guile Modules} describes some important modules,
|
||||||
|
distributed as part of the Guile distribution, that extend the
|
||||||
|
functionality provided by the Guile Scheme core, most notably:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
the POSIX module, which provides Scheme level procedures for system and
|
||||||
|
network programming, conforming to the POSIX standard
|
||||||
|
|
||||||
|
@item
|
||||||
|
the SLIB module, which makes Aubrey Jaffer's portable Scheme library
|
||||||
|
available for use in Guile.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@strong{Part IV: Guile Scripting} documents the use of Guile as a script
|
||||||
|
interpreter, and illustrates this with a series of examples.
|
||||||
|
|
||||||
|
@strong{Part V: Extending Applications Using Guile} explains the options
|
||||||
|
available for using Guile as a application extension language. At the
|
||||||
|
simpler end of the scale, an application might use Guile to define some
|
||||||
|
application-specific primitives in C and then load an application Scheme
|
||||||
|
file. In this case most of the application code is written on the
|
||||||
|
Scheme level, and uses the application-specific primitives as an
|
||||||
|
extension to standard Scheme. At the other end of the scale, an
|
||||||
|
application might be predominantly written in C --- with its main
|
||||||
|
control loop implemented in C --- but make occasional forays into Scheme
|
||||||
|
to, say, read configuration data or run user-defined customization code.
|
||||||
|
This part of the manual covers the complete range of application
|
||||||
|
extension options.
|
||||||
|
|
||||||
|
Finally, the appendices explain how to obtain the latest version of
|
||||||
|
Guile, how to install it, where to find modules to work with Guile, and
|
||||||
|
how to use the Guile debugger.
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
0
doc/r4rs.texi
Normal file
0
doc/r4rs.texi
Normal file
0
doc/r5rs.texi
Normal file
0
doc/r5rs.texi
Normal file
37
doc/scheme-binding.texi
Normal file
37
doc/scheme-binding.texi
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
@page
|
||||||
|
@node Binding Constructs
|
||||||
|
@chapter Definitions and Variable Bindings
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Top Level:: Top level variable definitions.
|
||||||
|
* Local Bindings:: Local variable bindings.
|
||||||
|
* Internal Definitions:: Internal definitions.
|
||||||
|
* Binding Reflection:: Querying variable bindings.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Top Level
|
||||||
|
@section Top Level Variable Definitions
|
||||||
|
|
||||||
|
|
||||||
|
@node Local Bindings
|
||||||
|
@section Local Variable Bindings
|
||||||
|
|
||||||
|
|
||||||
|
@node Internal Definitions
|
||||||
|
@section Internal definitions
|
||||||
|
|
||||||
|
|
||||||
|
@node Binding Reflection
|
||||||
|
@section Querying variable bindings
|
||||||
|
|
||||||
|
@c NJFIXME explain [env]
|
||||||
|
@c docstring begin (texi-doc-string "guile" "defined?")
|
||||||
|
@deffn primitive defined? sym [env]
|
||||||
|
Return @code{#t} if @var{sym} is defined in the top-level environment.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
236
doc/scheme-control.texi
Normal file
236
doc/scheme-control.texi
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
@page
|
||||||
|
@node Control Mechanisms
|
||||||
|
@chapter Controlling the Flow of Program Execution
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* begin:: Evaluating a sequence of expressions.
|
||||||
|
* if cond case:: Simple conditional evaluation.
|
||||||
|
* and or:: Conditional evaluation of a sequence.
|
||||||
|
* while do:: Iteration mechanisms.
|
||||||
|
* Continuations:: Continuations.
|
||||||
|
* Multiple Values:: Returning and accepting multiple values.
|
||||||
|
* Exceptions:: Throwing and catching exceptions.
|
||||||
|
* Error Reporting:: Procedures for signaling errors.
|
||||||
|
* Dynamic Wind:: Guarding against non-local entrance/exit.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node begin
|
||||||
|
@section Evaluating a Sequence of Expressions
|
||||||
|
|
||||||
|
|
||||||
|
@node if cond case
|
||||||
|
@section Simple Conditional Evaluation
|
||||||
|
|
||||||
|
|
||||||
|
@node and or
|
||||||
|
@section Conditional Evaluation of a Sequence of Expressions
|
||||||
|
|
||||||
|
|
||||||
|
@node while do
|
||||||
|
@section Iteration mechanisms
|
||||||
|
|
||||||
|
|
||||||
|
@node Continuations
|
||||||
|
@section Continuations
|
||||||
|
|
||||||
|
|
||||||
|
@node Multiple Values
|
||||||
|
@section Returning and Accepting Multiple Values
|
||||||
|
|
||||||
|
@deffn primitive values . args
|
||||||
|
Delivers all of its arguments to its continuation. Except for
|
||||||
|
continuations created by the @code{call-with-values} procedure,
|
||||||
|
all continuations take exactly one value. The effect of
|
||||||
|
passing no value or more than one value to continuations that
|
||||||
|
were not created by @code{call-with-values} is unspecified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive call-with-values producer consumer
|
||||||
|
Calls its @var{producer} argument with no values and a
|
||||||
|
continuation that, when passed some values, calls the
|
||||||
|
@var{consumer} procedure with those values as arguments. The
|
||||||
|
continuation for the call to @var{consumer} is the continuation
|
||||||
|
of the call to @code{call-with-values}.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(call-with-values (lambda () (values 4 5))
|
||||||
|
(lambda (a b) b))
|
||||||
|
==> 5
|
||||||
|
|
||||||
|
@end example
|
||||||
|
@example
|
||||||
|
(call-with-values * -) ==> -1
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Exceptions
|
||||||
|
@section Exceptions
|
||||||
|
@cindex error handling
|
||||||
|
@cindex exception handling
|
||||||
|
|
||||||
|
It is traditional in Scheme to implement exception systems using
|
||||||
|
@code{call-with-current-continuation}. Guile does not do this, for
|
||||||
|
performance reasons. The implementation of
|
||||||
|
@code{call-with-current-continuation} is a stack copying implementation.
|
||||||
|
This allows it to interact well with ordinary C code. Unfortunately, a
|
||||||
|
stack-copying implementation can be slow -- creating a new continuation
|
||||||
|
involves a block copy of the stack.
|
||||||
|
|
||||||
|
Instead of using @code{call-with-current-continuation}, the exception
|
||||||
|
primitives documented here are implemented as built-ins that take
|
||||||
|
advantage of the @emph{upward only} nature of exceptions.
|
||||||
|
|
||||||
|
@c ARGFIXME tag/key
|
||||||
|
@c docstring begin (texi-doc-string "guile" "catch")
|
||||||
|
@deffn primitive catch tag thunk handler
|
||||||
|
Invoke @var{thunk} in the dynamic context of @var{handler} for
|
||||||
|
exceptions matching @var{key}. If thunk throws to the symbol @var{key},
|
||||||
|
then @var{handler} is invoked this way:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(handler key args ...)
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@var{key} is a symbol or #t.
|
||||||
|
|
||||||
|
@var{thunk} takes no arguments. If @var{thunk} returns normally, that
|
||||||
|
is the return value of @code{catch}.
|
||||||
|
|
||||||
|
Handler is invoked outside the scope of its own @code{catch}. If
|
||||||
|
@var{handler} again throws to the same key, a new handler from further
|
||||||
|
up the call chain is invoked.
|
||||||
|
|
||||||
|
If the key is @code{#t}, then a throw to @emph{any} symbol will match
|
||||||
|
this call to @code{catch}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "throw")
|
||||||
|
@deffn primitive throw key . args
|
||||||
|
Invoke the catch form matching @var{key}, passing @var{args} to the
|
||||||
|
@var{handler}.
|
||||||
|
|
||||||
|
@var{key} is a symbol. It will match catches of the same symbol or of
|
||||||
|
#t.
|
||||||
|
|
||||||
|
If there is no handler at all, an error is signaled.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "lazy-catch")
|
||||||
|
@deffn primitive lazy-catch tag thunk handler
|
||||||
|
This behaves exactly like @code{catch}, except that it does
|
||||||
|
not unwind the stack (this is the major difference), and if
|
||||||
|
handler returns, its value is returned from the throw.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Error Reporting
|
||||||
|
@section Procedures for Signaling Errors
|
||||||
|
|
||||||
|
Guile provides a set of convenience procedures for signaling error
|
||||||
|
conditions that are implemented on top of the exception primitives just
|
||||||
|
described.
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "error")
|
||||||
|
@deffn procedure error msg args @dots{}
|
||||||
|
Raise an error with key @code{misc-error} and a message constructed by
|
||||||
|
displaying @var{msg} and writing @var{args}.
|
||||||
|
@end deffn
|
||||||
|
@c end
|
||||||
|
|
||||||
|
@c ARGFIXME rest/data
|
||||||
|
@c docstring begin (texi-doc-string "guile" "scm-error")
|
||||||
|
@deffn primitive scm-error key subr message args rest
|
||||||
|
Raise an error with key @var{key}. @var{subr} can be a string naming
|
||||||
|
the procedure associated with the error, or @code{#f}. @var{message}
|
||||||
|
is the error message string, possibly containing @code{~S} and @code{~A}
|
||||||
|
escapes. When an error is reported, these are replaced by formating the
|
||||||
|
corresponding members of @var{args}: @code{~A} (was @code{%s}) formats using @code{display}
|
||||||
|
and @code{~S} (was @code{%S}) formats using @code{write}. @var{data} is a
|
||||||
|
list or @code{#f} depending on @var{key}: if @var{key} is
|
||||||
|
@code{system-error} then it should be a list
|
||||||
|
containing the Unix @code{errno} value; If @var{key} is @code{signal} then
|
||||||
|
it should be a list containing the Unix signal number; otherwise it
|
||||||
|
will usually be @code{#f}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "strerror")
|
||||||
|
@deffn primitive strerror err
|
||||||
|
Returns the Unix error message corresponding to @var{err}, an integer.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "false-if-exception")
|
||||||
|
@deffn syntax false-if-exception expr
|
||||||
|
Returns the result of evaluating its argument; however
|
||||||
|
if an exception occurs then @code{#f} is returned instead.
|
||||||
|
@end deffn
|
||||||
|
@c end
|
||||||
|
|
||||||
|
|
||||||
|
@node Dynamic Wind
|
||||||
|
@section Dynamic Wind
|
||||||
|
|
||||||
|
[FIXME: this is pasted in from Tom Lord's original guile.texi and should
|
||||||
|
be reviewed]
|
||||||
|
|
||||||
|
@c ARGFIXME in-guard/thunk1 thunk/thunk2 out-guard/thunk3
|
||||||
|
@c docstring begin (texi-doc-string "guile" "dynamic-wind")
|
||||||
|
@deffn primitive dynamic-wind thunk1 thunk2 thunk3
|
||||||
|
All three arguments must be 0-argument procedures.
|
||||||
|
|
||||||
|
@var{in-guard} is called, then @var{thunk}, then @var{out-guard}.
|
||||||
|
|
||||||
|
If, any time during the execution of @var{thunk}, the continuation
|
||||||
|
of the @code{dynamic-wind} expression is escaped non-locally, @var{out-guard}
|
||||||
|
is called. If the continuation of the dynamic-wind is re-entered,
|
||||||
|
@var{in-guard} is called. Thus @var{in-guard} and @var{out-guard} may
|
||||||
|
be called any number of times.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(define x 'normal-binding)
|
||||||
|
@result{} x
|
||||||
|
|
||||||
|
(define a-cont (call-with-current-continuation
|
||||||
|
(lambda (escape)
|
||||||
|
(let ((old-x x))
|
||||||
|
(dynamic-wind
|
||||||
|
;; in-guard:
|
||||||
|
;;
|
||||||
|
(lambda () (set! x 'special-binding))
|
||||||
|
|
||||||
|
;; thunk
|
||||||
|
;;
|
||||||
|
(lambda () (display x) (newline)
|
||||||
|
(call-with-current-continuation escape)
|
||||||
|
(display x) (newline)
|
||||||
|
x)
|
||||||
|
|
||||||
|
;; out-guard:
|
||||||
|
;;
|
||||||
|
(lambda () (set! x old-x)))))))
|
||||||
|
|
||||||
|
;; Prints:
|
||||||
|
special-binding
|
||||||
|
;; Evaluates to:
|
||||||
|
@result{} a-cont
|
||||||
|
|
||||||
|
x
|
||||||
|
@result{} normal-binding
|
||||||
|
|
||||||
|
(a-cont #f)
|
||||||
|
;; Prints:
|
||||||
|
special-binding
|
||||||
|
;; Evaluates to:
|
||||||
|
@result{} a-cont ;; the value of the (define a-cont...)
|
||||||
|
|
||||||
|
x
|
||||||
|
@result{} normal-binding
|
||||||
|
|
||||||
|
a-cont
|
||||||
|
@result{} special-binding
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
4718
doc/scheme-data.texi
Executable file
4718
doc/scheme-data.texi
Executable file
File diff suppressed because it is too large
Load diff
196
doc/scheme-debug.texi
Normal file
196
doc/scheme-debug.texi
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
@page
|
||||||
|
@node Debugging
|
||||||
|
@chapter Internal Debugging Interface
|
||||||
|
|
||||||
|
--- The name of this chapter needs to clearly distinguish it
|
||||||
|
from the appendix describing the debugger UI. The intro
|
||||||
|
should have a pointer to the UI appendix.
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "display-error")
|
||||||
|
@deffn primitive display-error stack port subr message args rest
|
||||||
|
Display an error message to the output port @var{port}.
|
||||||
|
@var{stack} is the saved stack for the error, @var{subr} is
|
||||||
|
the name of the procedure in which the error occured and
|
||||||
|
@var{message} is the actual error message, which may contain
|
||||||
|
formatting instructions. These will format the arguments in
|
||||||
|
the list @var{args} accordingly. @var{rest} is currently
|
||||||
|
ignored.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "display-application")
|
||||||
|
@deffn primitive display-application frame [port [indent]]
|
||||||
|
Display a procedure application @var{frame} to the output port
|
||||||
|
@var{port}. @var{indent} specifies the indentation of the
|
||||||
|
output.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "display-backtrace")
|
||||||
|
@deffn primitive display-backtrace stack port [first [depth]]
|
||||||
|
Display a backtrace to the output port @var{port}. @var{stack}
|
||||||
|
is the stack to take the backtrace from, @var{first} specifies
|
||||||
|
where in the stack to start and @var{depth} how much frames
|
||||||
|
to display. Both @var{first} and @var{depth} can be @code{#f},
|
||||||
|
which means that default values will be used.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "backtrace")
|
||||||
|
@deffn primitive backtrace
|
||||||
|
Display a backtrace of the stack saved by the last error
|
||||||
|
to the current output port.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "malloc-stats")
|
||||||
|
@deffn primitive malloc-stats
|
||||||
|
Return an alist ((@var{what} . @var{n}) ...) describing number
|
||||||
|
of malloced objects.
|
||||||
|
@var{what} is the second argument to @code{scm_must_malloc},
|
||||||
|
@var{n} is the number of objects of that type currently
|
||||||
|
allocated.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "debug-options-interface")
|
||||||
|
@deffn primitive debug-options-interface [setting]
|
||||||
|
Option interface for the debug options. Instead of using
|
||||||
|
this procedure directly, use the procedures @code{debug-enable},
|
||||||
|
@code{debug-disable}, @code{debug-set!} and @var{debug-options}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "with-traps")
|
||||||
|
@deffn primitive with-traps thunk
|
||||||
|
Call @var{thunk} with traps enabled.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "memoized?")
|
||||||
|
@deffn primitive memoized? obj
|
||||||
|
Return @code{#t} if @var{obj} is memoized.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "unmemoize")
|
||||||
|
@deffn primitive unmemoize m
|
||||||
|
Unmemoize the memoized expression @var{m},
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "memoized-environment")
|
||||||
|
@deffn primitive memoized-environment m
|
||||||
|
Return the environment of the memoized expression @var{m}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure-name")
|
||||||
|
@deffn primitive procedure-name proc
|
||||||
|
Return the name of the procedure @var{proc}
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure-source")
|
||||||
|
@deffn primitive procedure-source proc
|
||||||
|
Return the source of the procedure @var{proc}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure-environment")
|
||||||
|
@deffn primitive procedure-environment proc
|
||||||
|
Return the environment of the procedure @var{proc}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "debug-object?")
|
||||||
|
@deffn primitive debug-object? obj
|
||||||
|
Return @code{#t} if @var{obj} is a debug object.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame-arguments")
|
||||||
|
@deffn primitive frame-arguments frame
|
||||||
|
Return the arguments of @var{frame}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame-evaluating-args?")
|
||||||
|
@deffn primitive frame-evaluating-args? frame
|
||||||
|
Return @code{#t} if @var{frame} contains evaluated arguments.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame-next")
|
||||||
|
@deffn primitive frame-next frame
|
||||||
|
Return the next frame of @var{frame}, or @code{#f} if
|
||||||
|
@var{frame} is the last frame in its stack.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame-number")
|
||||||
|
@deffn primitive frame-number frame
|
||||||
|
Return the frame number of @var{frame}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame-overflow?")
|
||||||
|
@deffn primitive frame-overflow? frame
|
||||||
|
Return @code{#t} if @var{frame} is an overflow frame.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame-previous")
|
||||||
|
@deffn primitive frame-previous frame
|
||||||
|
Return the previous frame of @var{frame}, or @code{#f} if
|
||||||
|
@var{frame} is the first frame in its stack.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame-procedure")
|
||||||
|
@deffn primitive frame-procedure frame
|
||||||
|
Return the procedure for @var{frame}, or @code{#f} if no
|
||||||
|
procedure is associated with @var{frame}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame-procedure?")
|
||||||
|
@deffn primitive frame-procedure? frame
|
||||||
|
Return @code{#t} if a procedure is associated with @var{frame}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame-real?")
|
||||||
|
@deffn primitive frame-real? frame
|
||||||
|
Return @code{#t} if @var{frame} is a real frame.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame-source")
|
||||||
|
@deffn primitive frame-source frame
|
||||||
|
Return the source of @var{frame}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "frame?")
|
||||||
|
@deffn primitive frame? obj
|
||||||
|
Return @code{#t} if @var{obj} is a stack frame.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "last-stack-frame")
|
||||||
|
@deffn primitive last-stack-frame obj
|
||||||
|
Return a stack which consists of a single frame, which is the
|
||||||
|
last stack frame for @var{obj}. @var{obj} must be either a
|
||||||
|
debug object or a continuation.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-stack")
|
||||||
|
@deffn primitive make-stack obj . args
|
||||||
|
Create a new stack. If @var{obj} is @code{#t}, the current
|
||||||
|
evaluation stack is used for creating the stack frames,
|
||||||
|
otherwise the frames are taken from @var{obj} (which must be
|
||||||
|
either a debug object or a continuation).
|
||||||
|
@var{args} must be a list if integers and specifies how the
|
||||||
|
resulting stack will be narrowed.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "stack-id")
|
||||||
|
@deffn primitive stack-id stack
|
||||||
|
Return the identifier given to @var{stack} by @code{start-stack}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "stack-length")
|
||||||
|
@deffn primitive stack-length stack
|
||||||
|
Return the length of @var{stack}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "stack-ref")
|
||||||
|
@deffn primitive stack-ref stack i
|
||||||
|
Return the @var{i}'th frame from @var{stack}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "stack?")
|
||||||
|
@deffn primitive stack? obj
|
||||||
|
Return @code{#t} if @var{obj} is a calling stack.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
255
doc/scheme-evaluation.texi
Normal file
255
doc/scheme-evaluation.texi
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
@page
|
||||||
|
@node Read/Load/Eval
|
||||||
|
@chapter Reading and Evaluating Scheme Code
|
||||||
|
|
||||||
|
This chapter describes Guile functions that are concerned with reading,
|
||||||
|
loading and evaluating Scheme code at run time.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Scheme Syntax:: Standard and extended Scheme syntax.
|
||||||
|
* Scheme Read:: Reading Scheme code.
|
||||||
|
* Fly Evaluation:: Procedures for on the fly evaluation.
|
||||||
|
* Loading:: Loading Scheme code from file.
|
||||||
|
* Delayed Evaluation:: Postponing evaluation until it is needed.
|
||||||
|
* Local Evaluation:: Evaluation in a local environment.
|
||||||
|
* Evaluator Options::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Scheme Syntax
|
||||||
|
@section Scheme Syntax: Standard and Guile Extensions
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Expression Syntax::
|
||||||
|
* Comments::
|
||||||
|
* Block Comments::
|
||||||
|
* Case Sensitivity::
|
||||||
|
* Keyword Syntax::
|
||||||
|
* Reader Extensions::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Expression Syntax
|
||||||
|
@subsection Expression Syntax
|
||||||
|
|
||||||
|
|
||||||
|
@node Comments
|
||||||
|
@subsection Comments
|
||||||
|
|
||||||
|
|
||||||
|
@node Block Comments
|
||||||
|
@subsection Block Comments
|
||||||
|
|
||||||
|
|
||||||
|
@node Case Sensitivity
|
||||||
|
@subsection Case Sensitivity
|
||||||
|
|
||||||
|
|
||||||
|
@node Keyword Syntax
|
||||||
|
@subsection Keyword Syntax
|
||||||
|
|
||||||
|
|
||||||
|
@node Reader Extensions
|
||||||
|
@subsection Reader Extensions
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "read-hash-extend")
|
||||||
|
@deffn primitive read-hash-extend chr proc
|
||||||
|
Install the procedure @var{proc} for reading expressions
|
||||||
|
starting with the character sequence @code{#} and @var{chr}.
|
||||||
|
@var{proc} will be called with two arguments: the character
|
||||||
|
@var{chr} and the port to read further data from. The object
|
||||||
|
returned will be the return value of @code{read}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Scheme Read
|
||||||
|
@section Reading Scheme Code
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "read-options-interface")
|
||||||
|
@deffn primitive read-options-interface [setting]
|
||||||
|
Option interface for the read options. Instead of using
|
||||||
|
this procedure directly, use the procedures @code{read-enable},
|
||||||
|
@code{read-disable}, @code{read-set!} and @var{read-options}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "read")
|
||||||
|
@deffn primitive read [port]
|
||||||
|
Read an s-expression from the input port @var{port}, or from
|
||||||
|
the current input port if @var{port} is not specified.
|
||||||
|
Any whitespace before the next token is discarded.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Fly Evaluation
|
||||||
|
@section Procedures for On the Fly Evaluation
|
||||||
|
|
||||||
|
@c ARGFIXME environment/environment specifier
|
||||||
|
@c docstring begin (texi-doc-string "guile" "eval")
|
||||||
|
@deffn primitive eval exp environment
|
||||||
|
Evaluate @var{exp}, a list representing a Scheme expression, in the
|
||||||
|
environment given by @var{environment specifier}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "interaction-environment")
|
||||||
|
@deffn primitive interaction-environment
|
||||||
|
This procedure returns a specifier for the environment that contains
|
||||||
|
implementation-defined bindings, typically a superset of those listed in
|
||||||
|
the report. The intent is that this procedure will return the
|
||||||
|
environment in which the implementation would evaluate expressions
|
||||||
|
dynamically typed by the user.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "eval-string")
|
||||||
|
@deffn primitive eval-string string
|
||||||
|
Evaluate @var{string} as the text representation of a Scheme form
|
||||||
|
or forms, and return whatever value they produce.
|
||||||
|
Evaluation takes place in (interaction-environment).
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "apply:nconc2last")
|
||||||
|
@deffn primitive apply:nconc2last lst
|
||||||
|
Given a list (@var{arg1} @dots{} @var{args}), this function
|
||||||
|
conses the @var{arg1} @dots{} arguments onto the front of
|
||||||
|
@var{args}, and returns the resulting list. Note that
|
||||||
|
@var{args} is a list; thus, the argument to this function is
|
||||||
|
a list whose last element is a list.
|
||||||
|
Note: Rather than do new consing, @code{apply:nconc2last}
|
||||||
|
destroys its argument, so use with care.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive primitive-eval exp
|
||||||
|
Evaluate @var{exp} in the top-level environment specified by
|
||||||
|
the current module.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive eval2 obj env_thunk
|
||||||
|
Evaluate @var{exp}, a Scheme expression, in the environment
|
||||||
|
designated by @var{lookup}, a symbol-lookup function."
|
||||||
|
Do not use this version of eval, it does not play well
|
||||||
|
with the module system. Use @code{eval} or
|
||||||
|
@code{primitive-eval} instead.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive read-and-eval! [port]
|
||||||
|
Read a form from @var{port} (standard input by default), and evaluate it
|
||||||
|
(memoizing it in the process) in the top-level environment. If no data
|
||||||
|
is left to be read from @var{port}, an @code{end-of-file} error is
|
||||||
|
signalled.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Loading
|
||||||
|
@section Loading Scheme Code from File
|
||||||
|
|
||||||
|
@c ARGFIXME file/filename
|
||||||
|
@c docstring begin (texi-doc-string "guile" "primitive-load")
|
||||||
|
@deffn primitive primitive-load filename
|
||||||
|
Load @var{file} and evaluate its contents in the top-level environment.
|
||||||
|
The load paths are not searched; @var{file} must either be a full
|
||||||
|
pathname or be a pathname relative to the current directory. If the
|
||||||
|
variable @code{%load-hook} is defined, it should be bound to a procedure
|
||||||
|
that will be called before any code is loaded. See documentation for
|
||||||
|
@code{%load-hook} later in this section.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME file/filename
|
||||||
|
@c docstring begin (texi-doc-string "guile" "primitive-load-path")
|
||||||
|
@deffn primitive primitive-load-path filename
|
||||||
|
Search @var{%load-path} for @var{file} and load it into the top-level
|
||||||
|
environment. If @var{file} is a relative pathname and is not found in
|
||||||
|
the list of search paths, an error is signalled.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME file/filename
|
||||||
|
@c docstring begin (texi-doc-string "guile" "%search-load-path")
|
||||||
|
@deffn primitive %search-load-path filename
|
||||||
|
Search @var{%load-path} for @var{file}, which must be readable by the
|
||||||
|
current user. If @var{file} is found in the list of paths to search or
|
||||||
|
is an absolute pathname, return its full pathname. Otherwise, return
|
||||||
|
@code{#f}. Filenames may have any of the optional extensions in the
|
||||||
|
@code{%load-extensions} list; @code{%search-load-path} will try each
|
||||||
|
extension automatically.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@defvar %load-hook
|
||||||
|
A procedure to be run whenever @code{primitive-load} is called. If this
|
||||||
|
procedure is defined, it will be called with the filename argument that
|
||||||
|
was passed to @code{primitive-load}.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(define %load-hook (lambda (file)
|
||||||
|
(display "Loading ")
|
||||||
|
(display file)
|
||||||
|
(write-line "...."))) @result{} undefined
|
||||||
|
(load-from-path "foo.scm")
|
||||||
|
@print{} Loading /usr/local/share/guile/site/foo.scm....
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@end defvar
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "current-load-port")
|
||||||
|
@deffn primitive current-load-port
|
||||||
|
Return the current-load-port.
|
||||||
|
The load port is used internally by @code{primitive-load}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@defvar %load-extensions
|
||||||
|
A list of default file extensions for files containing Scheme code.
|
||||||
|
@code{%search-load-path} tries each of these extensions when looking for
|
||||||
|
a file to load. By default, @code{%load-extensions} is bound to the
|
||||||
|
list @code{("" ".scm")}.
|
||||||
|
@end defvar
|
||||||
|
|
||||||
|
|
||||||
|
@node Delayed Evaluation
|
||||||
|
@section Delayed Evaluation
|
||||||
|
|
||||||
|
[delay]
|
||||||
|
|
||||||
|
@c ARGFIXME x/obj
|
||||||
|
@c docstring begin (texi-doc-string "guile" "promise?")
|
||||||
|
@deffn primitive promise? x
|
||||||
|
Return true if @var{obj} is a promise, i.e. a delayed computation
|
||||||
|
(@pxref{Delayed evaluation,,,r4rs.info,The Revised^4 Report on Scheme}).
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "force")
|
||||||
|
@deffn primitive force x
|
||||||
|
If the promise X has not been computed yet, compute and return
|
||||||
|
X, otherwise just return the previously computed value.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Local Evaluation
|
||||||
|
@section Local Evaluation
|
||||||
|
|
||||||
|
[the-environment]
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "local-eval")
|
||||||
|
@deffn primitive local-eval exp [env]
|
||||||
|
Evaluate @var{exp} in its environment. If @var{env} is supplied,
|
||||||
|
it is the environment in which to evaluate @var{exp}. Otherwise,
|
||||||
|
@var{exp} must be a memoized code object (in which case, its environment
|
||||||
|
is implicit).
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Evaluator Options
|
||||||
|
@section Evaluator Options
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "eval-options-interface")
|
||||||
|
@deffn primitive eval-options-interface [setting]
|
||||||
|
Option interface for the evaluation options. Instead of using
|
||||||
|
this procedure directly, use the procedures @code{eval-enable},
|
||||||
|
@code{eval-disable}, @code{eval-set!} and @var{eval-options}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "evaluator-traps-interface")
|
||||||
|
@deffn primitive evaluator-traps-interface [setting]
|
||||||
|
Option interface for the evaluator trap options.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
1458
doc/scheme-ideas.texi
Normal file
1458
doc/scheme-ideas.texi
Normal file
File diff suppressed because it is too large
Load diff
17
doc/scheme-indices.texi
Normal file
17
doc/scheme-indices.texi
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
@page
|
||||||
|
@node R5RS Index
|
||||||
|
@chapter R5RS Index
|
||||||
|
|
||||||
|
@printindex r5
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Guile Extensions Index
|
||||||
|
@chapter Guile Extensions Index
|
||||||
|
|
||||||
|
@printindex ge
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
0
doc/scheme-intro.texi
Normal file
0
doc/scheme-intro.texi
Normal file
762
doc/scheme-io.texi
Normal file
762
doc/scheme-io.texi
Normal file
|
@ -0,0 +1,762 @@
|
||||||
|
@page
|
||||||
|
@node Input and Output
|
||||||
|
@chapter Input and Output
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Ports:: The idea of the port abstraction.
|
||||||
|
* Reading:: Procedures for reading from a port.
|
||||||
|
* Writing:: Procedures for writing to a port.
|
||||||
|
* Closing:: Procedures to close a port.
|
||||||
|
* Random Access:: Moving around a random access port.
|
||||||
|
* Line/Delimited:: Read and write lines or delimited text.
|
||||||
|
* Binary IO:: Save and restore Scheme objects.
|
||||||
|
* Default Ports:: Defaults for input, output and errors.
|
||||||
|
* Port Types:: Types of port and how to make them.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Ports
|
||||||
|
@section Ports
|
||||||
|
|
||||||
|
[Concept of the port abstraction.]
|
||||||
|
|
||||||
|
Sequential input/output in Scheme is represented by operations on a
|
||||||
|
@dfn{port}. Characters can be read from an input port and
|
||||||
|
written to an output port. This chapter explains the operations
|
||||||
|
that Guile provides for working with ports.
|
||||||
|
|
||||||
|
The formal definition of a port is very generic: an input port is
|
||||||
|
simply ``an object which can deliver characters on command,'' and
|
||||||
|
an output port is ``an object which can accept characters.''
|
||||||
|
Because this definition is so loose, it is easy to write functions
|
||||||
|
that simulate ports in software. @dfn{Soft ports} and @dfn{string
|
||||||
|
ports} are two interesting and powerful examples of this technique.
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "input-port?")
|
||||||
|
@deffn primitive input-port? x
|
||||||
|
Returns @code{#t} if @var{x} is an input port, otherwise returns
|
||||||
|
@code{#f}. Any object satisfying this predicate also satisfies
|
||||||
|
@code{port?}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "output-port?")
|
||||||
|
@deffn primitive output-port? x
|
||||||
|
Returns @code{#t} if @var{x} is an output port, otherwise returns
|
||||||
|
@code{#f}. Any object satisfying this predicate also satisfies
|
||||||
|
@code{port?}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "port?")
|
||||||
|
@deffn primitive port? x
|
||||||
|
Returns a boolean indicating whether @var{x} is a port.
|
||||||
|
Equivalent to @code{(or (input-port? X) (output-port? X))}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Reading
|
||||||
|
@section Reading
|
||||||
|
|
||||||
|
[Generic procedures for reading from ports.]
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "eof-object?")
|
||||||
|
@deffn primitive eof-object? x
|
||||||
|
Returns @code{#t} if @var{x} is an end-of-file object; otherwise
|
||||||
|
returns @code{#f}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "char-ready?")
|
||||||
|
@deffn primitive char-ready? [port]
|
||||||
|
Returns @code{#t} if a character is ready on input @var{port} and
|
||||||
|
returns @code{#f} otherwise. If @code{char-ready?} returns @code{#t}
|
||||||
|
then the next @code{read-char} operation on @var{port} is
|
||||||
|
guaranteed not to hang. If @var{port} is a file port at end of
|
||||||
|
file then @code{char-ready?} returns @code{#t}.
|
||||||
|
@footnote{@code{char-ready?} exists to make it possible for a
|
||||||
|
program to accept characters from interactive ports without getting
|
||||||
|
stuck waiting for input. Any input editors associated with such ports
|
||||||
|
must make sure that characters whose existence has been asserted by
|
||||||
|
@code{char-ready?} cannot be rubbed out. If @code{char-ready?} were to
|
||||||
|
return @code{#f} at end of file, a port at end of file would be
|
||||||
|
indistinguishable from an interactive port that has no ready
|
||||||
|
characters.}
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "read-char")
|
||||||
|
@deffn primitive read-char [port]
|
||||||
|
Returns the next character available from @var{port}, updating
|
||||||
|
@var{port} to point to the following character. If no more
|
||||||
|
characters are available, an end-of-file object is returned.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "peek-char")
|
||||||
|
@deffn primitive peek-char [port]
|
||||||
|
Returns the next character available from @var{port},
|
||||||
|
@emph{without} updating @var{port} to point to the following
|
||||||
|
character. If no more characters are available, an end-of-file object
|
||||||
|
is returned.@footnote{The value returned by a call to @code{peek-char}
|
||||||
|
is the same as the value that would have been returned by a call to
|
||||||
|
@code{read-char} on the same port. The only difference is that the very
|
||||||
|
next call to @code{read-char} or @code{peek-char} on that
|
||||||
|
@var{port} will return the value returned by the preceding call to
|
||||||
|
@code{peek-char}. In particular, a call to @code{peek-char} on an
|
||||||
|
interactive port will hang waiting for input whenever a call to
|
||||||
|
@code{read-char} would have hung.}
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "unread-char")
|
||||||
|
@deffn primitive unread-char cobj port
|
||||||
|
Place @var{char} in @var{port} so that it will be read by the
|
||||||
|
next read operation. If called multiple times, the unread characters
|
||||||
|
will be read again in last-in first-out order. If @var{port} is
|
||||||
|
not supplied, the current input port is used.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "unread-string")
|
||||||
|
@deffn primitive unread-string str port
|
||||||
|
Place the string @var{str} in @var{port} so that its characters will be
|
||||||
|
read in subsequent read operations. If called multiple times, the
|
||||||
|
unread characters will be read again in last-in first-out order. If
|
||||||
|
@var{port} is not supplied, the current-input-port is used.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "drain-input")
|
||||||
|
@deffn primitive drain-input port
|
||||||
|
Drain @var{port}'s read buffers (including any pushed-back
|
||||||
|
characters) and returns the content as a single string.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME port/input-port
|
||||||
|
@c docstring begin (texi-doc-string "guile" "port-column")
|
||||||
|
@c docstring begin (texi-doc-string "guile" "port-line")
|
||||||
|
@deffn primitive port-column port
|
||||||
|
@deffnx primitive port-line [input-port]
|
||||||
|
Return the current column number or line number of @var{input-port},
|
||||||
|
using the current input port if none is specified. If the number is
|
||||||
|
unknown, the result is #f. Otherwise, the result is a 0-origin integer
|
||||||
|
- i.e. the first character of the first line is line 0, column 0.
|
||||||
|
(However, when you display a file position, for example in an error
|
||||||
|
message, we recommand you add 1 to get 1-origin integers. This is
|
||||||
|
because lines and column numbers traditionally start with 1, and that is
|
||||||
|
what non-programmers will find most natural.)
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME port/input-port
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-port-column!")
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-port-line!")
|
||||||
|
@deffn primitive set-port-column! port column
|
||||||
|
@deffnx primitive set-port-line! port line
|
||||||
|
Set the current column or line number of @var{port}, using the
|
||||||
|
current input port if none is specified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive read-string!/partial str [port_or_fdes [start [end]]]
|
||||||
|
Read characters from an fport or file descriptor into a
|
||||||
|
string @var{str}. This procedure is scsh-compatible
|
||||||
|
and can efficiently read large strings. It will:
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
attempt to fill the entire string, unless the @var{start}
|
||||||
|
and/or @var{end} arguments are supplied. i.e., @var{start}
|
||||||
|
defaults to 0 and @var{end} defaults to
|
||||||
|
@code{(string-length str)}
|
||||||
|
@item
|
||||||
|
use the current input port if @var{port_or_fdes} is not
|
||||||
|
supplied.
|
||||||
|
@item
|
||||||
|
read any characters that are currently available,
|
||||||
|
without waiting for the rest (short reads are possible).
|
||||||
|
|
||||||
|
@item
|
||||||
|
wait for as long as it needs to for the first character to
|
||||||
|
become available, unless the port is in non-blocking mode
|
||||||
|
@item
|
||||||
|
return @code{#f} if end-of-file is encountered before reading
|
||||||
|
any characters, otherwise return the number of characters
|
||||||
|
read.
|
||||||
|
@item
|
||||||
|
return 0 if the port is in non-blocking mode and no characters
|
||||||
|
are immediately available.
|
||||||
|
@item
|
||||||
|
return 0 if the request is for 0 bytes, with no
|
||||||
|
end-of-file check
|
||||||
|
@end itemize
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Writing
|
||||||
|
@section Writing
|
||||||
|
|
||||||
|
[Generic procedures for writing to ports.]
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "get-print-state")
|
||||||
|
@deffn primitive get-print-state port
|
||||||
|
Return the print state of the port @var{port}. If @var{port}
|
||||||
|
has no associated print state, @code{#f} is returned.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "newline")
|
||||||
|
@deffn primitive newline [port]
|
||||||
|
Send a newline to @var{port}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "port-with-print-state")
|
||||||
|
@deffn primitive port-with-print-state port pstate
|
||||||
|
Create a new port which behaves like @var{port}, but with an
|
||||||
|
included print state @var{pstate}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "print-options-interface")
|
||||||
|
@deffn primitive print-options-interface [setting]
|
||||||
|
Option interface for the print options. Instead of using
|
||||||
|
this procedure directly, use the procedures @code{print-enable},
|
||||||
|
@code{print-disable}, @code{print-set!} and @var{print-options}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "simple-format")
|
||||||
|
@deffn primitive simple-format destination message . args
|
||||||
|
Write @var{message} to @var{destination}, defaulting to
|
||||||
|
the current output port.
|
||||||
|
@var{message} can contain @code{~A} (was @code{%s}) and
|
||||||
|
@code{~S} (was @code{%S}) escapes. When printed,
|
||||||
|
the escapes are replaced with corresponding members of
|
||||||
|
@var{ARGS}:
|
||||||
|
@code{~A} formats using @code{display} and @code{~S} formats
|
||||||
|
using @code{write}.
|
||||||
|
If @var{destination} is @code{#t}, then use the current output
|
||||||
|
port, if @var{destination} is @code{#f}, then return a string
|
||||||
|
containing the formatted text. Does not add a trailing newline.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "write-char")
|
||||||
|
@deffn primitive write-char chr [port]
|
||||||
|
Send character @var{chr} to @var{port}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@findex fflush
|
||||||
|
@c docstring begin (texi-doc-string "guile" "force-output")
|
||||||
|
@deffn primitive force-output [port]
|
||||||
|
Flush the specified output port, or the current output port if @var{port}
|
||||||
|
is omitted. The current output buffer contents are passed to the
|
||||||
|
underlying port implementation (e.g., in the case of fports, the
|
||||||
|
data will be written to the file and the output buffer will be cleared.)
|
||||||
|
It has no effect on an unbuffered port.
|
||||||
|
|
||||||
|
The return value is unspecified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "flush-all-ports")
|
||||||
|
@deffn primitive flush-all-ports
|
||||||
|
Equivalent to calling @code{force-output} on
|
||||||
|
all open output ports. The return value is unspecified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Closing
|
||||||
|
@section Closing
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "close-port")
|
||||||
|
@deffn primitive close-port port
|
||||||
|
Close the specified port object. Returns @code{#t} if it successfully
|
||||||
|
closes a port or @code{#f} if it was already
|
||||||
|
closed. An exception may be raised if an error occurs, for example
|
||||||
|
when flushing buffered output.
|
||||||
|
See also @ref{Ports and File Descriptors, close}, for a procedure
|
||||||
|
which can close file descriptors.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "close-input-port")
|
||||||
|
@deffn primitive close-input-port port
|
||||||
|
Close the specified input port object. The routine has no effect if
|
||||||
|
the file has already been closed. An exception may be raised if an
|
||||||
|
error occurs. The value returned is unspecified.
|
||||||
|
|
||||||
|
See also @ref{Ports and File Descriptors, close}, for a procedure
|
||||||
|
which can close file descriptors.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "close-output-port")
|
||||||
|
@deffn primitive close-output-port port
|
||||||
|
Close the specified output port object. The routine has no effect if
|
||||||
|
the file has already been closed. An exception may be raised if an
|
||||||
|
error occurs. The value returned is unspecified.
|
||||||
|
|
||||||
|
See also @ref{Ports and File Descriptors, close}, for a procedure
|
||||||
|
which can close file descriptors.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "port-closed?")
|
||||||
|
@deffn primitive port-closed? port
|
||||||
|
Returns @code{#t} if @var{port} is closed or @code{#f} if it is open.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Random Access
|
||||||
|
@section Random Access
|
||||||
|
|
||||||
|
@c ARGFIXME object/fd/port
|
||||||
|
@c docstring begin (texi-doc-string "guile" "seek")
|
||||||
|
@deffn primitive seek object offset whence
|
||||||
|
Sets the current position of @var{fd/port} to the integer @var{offset},
|
||||||
|
which is interpreted according to the value of @var{whence}.
|
||||||
|
|
||||||
|
One of the following variables should be supplied
|
||||||
|
for @var{whence}:
|
||||||
|
@defvar SEEK_SET
|
||||||
|
Seek from the beginning of the file.
|
||||||
|
@end defvar
|
||||||
|
@defvar SEEK_CUR
|
||||||
|
Seek from the current position.
|
||||||
|
@end defvar
|
||||||
|
@defvar SEEK_END
|
||||||
|
Seek from the end of the file.
|
||||||
|
@end defvar
|
||||||
|
|
||||||
|
If @var{fd/port} is a file descriptor, the underlying system call is
|
||||||
|
@code{lseek}. @var{port} may be a string port.
|
||||||
|
|
||||||
|
The value returned is the new position in the file. This means that
|
||||||
|
the current position of a port can be obtained using:
|
||||||
|
@smalllisp
|
||||||
|
(seek port 0 SEEK_CUR)
|
||||||
|
@end smalllisp
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME object/fd/port
|
||||||
|
@c docstring begin (texi-doc-string "guile" "fseek")
|
||||||
|
@deffn primitive fseek object offset whence
|
||||||
|
Obsolete. Almost the same as seek, above, but the return value is
|
||||||
|
unspecified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME object/fd/port
|
||||||
|
@c docstring begin (texi-doc-string "guile" "ftell")
|
||||||
|
@deffn primitive ftell object
|
||||||
|
Returns an integer representing the current position of @var{fd/port},
|
||||||
|
measured from the beginning. Equivalent to:
|
||||||
|
@smalllisp
|
||||||
|
(seek port 0 SEEK_CUR)
|
||||||
|
@end smalllisp
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@findex truncate
|
||||||
|
@findex ftruncate
|
||||||
|
@c ARGFIXME obj/object size/length
|
||||||
|
@c docstring begin (texi-doc-string "guile" "truncate-file")
|
||||||
|
@deffn primitive truncate-file object [length]
|
||||||
|
Truncates the object referred to by @var{obj} to at most @var{size} bytes.
|
||||||
|
@var{obj} can be a string containing a file name or an integer file
|
||||||
|
descriptor or a port. @var{size} may be omitted if @var{obj} is not
|
||||||
|
a file name, in which case the truncation occurs at the current port.
|
||||||
|
position.
|
||||||
|
|
||||||
|
The return value is unspecified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Line/Delimited
|
||||||
|
@section Handling Line Oriented and Delimited Text
|
||||||
|
|
||||||
|
[Line-oriented and delimited IO. Or should this be merged into the
|
||||||
|
previous two sections?]
|
||||||
|
|
||||||
|
Extended I/O procedures are available which read or write lines of text
|
||||||
|
or read text delimited by a specified set of characters.
|
||||||
|
|
||||||
|
@findex fwrite
|
||||||
|
@findex fread
|
||||||
|
Interfaces to @code{read}/@code{fread} and @code{write}/@code{fwrite} are
|
||||||
|
also available, as @code{uniform-array-read!} and @code{uniform-array-write!},
|
||||||
|
@ref{Uniform Arrays}.
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "read-line")
|
||||||
|
@deffn procedure read-line [port] [handle-delim]
|
||||||
|
Return a line of text from @var{port} if specified, otherwise from the
|
||||||
|
value returned by @code{(current-input-port)}. Under Unix, a line of text
|
||||||
|
is terminated by the first end-of-line character or by end-of-file.
|
||||||
|
|
||||||
|
If @var{handle-delim} is specified, it should be one of the following
|
||||||
|
symbols:
|
||||||
|
@table @code
|
||||||
|
@item trim
|
||||||
|
Discard the terminating delimiter. This is the default, but it will
|
||||||
|
be impossible to tell whether the read terminated with a delimiter or
|
||||||
|
end-of-file.
|
||||||
|
@item concat
|
||||||
|
Append the terminating delimiter (if any) to the returned string.
|
||||||
|
@item peek
|
||||||
|
Push the terminating delimiter (if any) back on to the port.
|
||||||
|
@item split
|
||||||
|
Return a pair containing the string read from the port and the
|
||||||
|
terminating delimiter or end-of-file object.
|
||||||
|
|
||||||
|
NOTE: if the scsh module is loaded then
|
||||||
|
multiple values are returned instead of a pair.
|
||||||
|
@end table
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "read-line!")
|
||||||
|
@deffn procedure read-line! buf [port]
|
||||||
|
Read a line of text into the supplied string @var{buf} and return the
|
||||||
|
number of characters added to @var{buf}. If @var{buf} is filled, then
|
||||||
|
@code{#f} is returned.
|
||||||
|
Read from @var{port} if
|
||||||
|
specified, otherwise from the value returned by @code{(current-input-port)}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "read-delimited")
|
||||||
|
@deffn procedure read-delimited delims [port] [handle-delim]
|
||||||
|
Read text until one of the characters in the string @var{delims} is found
|
||||||
|
or end-of-file is reached. Read from @var{port} if supplied, otherwise
|
||||||
|
from the value returned by @code{(current-input-port)}.
|
||||||
|
@var{handle-delim} takes the same values as described for @code{read-line}.
|
||||||
|
|
||||||
|
NOTE: if the scsh module is loaded then @var{delims} must be an scsh
|
||||||
|
char-set, not a string.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "read-delimited!")
|
||||||
|
@deffn procedure read-delimited! delims buf [port] [handle-delim] [start] [end]
|
||||||
|
Read text into the supplied string @var{buf} and return the number of
|
||||||
|
characters added to @var{buf} (subject to @var{handle-delim}, which takes
|
||||||
|
the same values specified for @code{read-line}. If @var{buf} is filled,
|
||||||
|
@code{#f} is returned for both the number of characters read and the
|
||||||
|
delimiter. Also terminates if one of the characters in the string
|
||||||
|
@var{delims} is found
|
||||||
|
or end-of-file is reached. Read from @var{port} if supplied, otherwise
|
||||||
|
from the value returned by @code{(current-input-port)}.
|
||||||
|
|
||||||
|
NOTE: if the scsh module is loaded then @var{delims} must be an scsh
|
||||||
|
char-set, not a string.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "write-line")
|
||||||
|
@deffn primitive write-line obj [port]
|
||||||
|
Display @var{obj} and a newline character to @var{port}. If @var{port}
|
||||||
|
is not specified, @code{(current-output-port)} is used. This function
|
||||||
|
is equivalent to:
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
(display obj [port])
|
||||||
|
(newline [port])
|
||||||
|
@end smalllisp
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
Some of the abovementioned I/O functions rely on the following C
|
||||||
|
primitives. These will mainly be of interest to people hacking Guile
|
||||||
|
internals.
|
||||||
|
|
||||||
|
@c ARGFIXME gobble/gobble?
|
||||||
|
@c docstring begin (texi-doc-string "guile" "%read-delimited!")
|
||||||
|
@deffn primitive %read-delimited! delims str gobble [port [start [end]]]
|
||||||
|
Read characters from @var{port} into @var{str} until one of the
|
||||||
|
characters in the @var{delims} string is encountered. If @var{gobble}
|
||||||
|
is true, discard the delimiter character; otherwise, leave it
|
||||||
|
in the input stream for the next read.
|
||||||
|
If @var{port} is not specified, use the value of
|
||||||
|
@code{(current-input-port)}. If @var{start} or @var{end} are specified,
|
||||||
|
store data only into the substring of @var{str} bounded by @var{start}
|
||||||
|
and @var{end} (which default to the beginning and end of the string,
|
||||||
|
respectively).
|
||||||
|
|
||||||
|
Return a pair consisting of the delimiter that terminated the string and
|
||||||
|
the number of characters read. If reading stopped at the end of file,
|
||||||
|
the delimiter returned is the @var{eof-object}; if the string was filled
|
||||||
|
without encountering a delimiter, this value is @var{#f}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "%read-line")
|
||||||
|
@deffn primitive %read-line [port]
|
||||||
|
Read a newline-terminated line from @var{port}, allocating storage as
|
||||||
|
necessary. The newline terminator (if any) is removed from the string,
|
||||||
|
and a pair consisting of the line and its delimiter is returned. The
|
||||||
|
delimiter may be either a newline or the @var{eof-object}; if
|
||||||
|
@code{%read-line} is called at the end of file, it returns the pair
|
||||||
|
@code{(#<eof> . #<eof>)}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@node Binary IO
|
||||||
|
@section Saving and Restoring Scheme Objects
|
||||||
|
|
||||||
|
@deffn primitive binary-read [port]
|
||||||
|
Read and return an object from @var{port} in a binary format.
|
||||||
|
If omitted, @var{port} defaults to the current output port.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive binary-write obj [port]
|
||||||
|
Write @var{obj} to @var{port} in a binary format.
|
||||||
|
If omitted, @var{port} defaults to the current output port.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Default Ports
|
||||||
|
@section Default Ports for Input, Output and Errors
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "current-input-port")
|
||||||
|
@deffn primitive current-input-port
|
||||||
|
Return the current input port. This is the default port used
|
||||||
|
by many input procedures. Initially, @code{current-input-port}
|
||||||
|
returns the @dfn{standard input} in Unix and C terminology.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "current-output-port")
|
||||||
|
@deffn primitive current-output-port
|
||||||
|
Return the current output port. This is the default port used
|
||||||
|
by many output procedures. Initially,
|
||||||
|
@code{current-output-port} returns the @dfn{standard output} in
|
||||||
|
Unix and C terminology.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "current-error-port")
|
||||||
|
@deffn primitive current-error-port
|
||||||
|
Return the port to which errors and warnings should be sent (the
|
||||||
|
@dfn{standard error} in Unix and C terminology).
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-current-input-port")
|
||||||
|
@deffn primitive set-current-input-port port
|
||||||
|
@deffnx primitive set-current-output-port port
|
||||||
|
@deffnx primitive set-current-error-port port
|
||||||
|
Change the ports returned by @code{current-input-port},
|
||||||
|
@code{current-output-port} and @code{current-error-port}, respectively,
|
||||||
|
so that they use the supplied @var{port} for input or output.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-current-output-port")
|
||||||
|
@deffn primitive set-current-output-port port
|
||||||
|
Set the current default output port to PORT.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-current-error-port")
|
||||||
|
@deffn primitive set-current-error-port port
|
||||||
|
Set the current default error port to PORT.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Port Types
|
||||||
|
@section Types of Port
|
||||||
|
|
||||||
|
[Types of port; how to make them.]
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* File Ports:: Ports on an operating system file.
|
||||||
|
* String Ports:: Ports on a Scheme string.
|
||||||
|
* Soft Ports:: Ports on arbitrary Scheme procedures.
|
||||||
|
* Void Ports:: Ports on nothing at all.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node File Ports
|
||||||
|
@subsection File Ports
|
||||||
|
|
||||||
|
The following procedures are used to open file ports.
|
||||||
|
See also @ref{Ports and File Descriptors, open}, for an interface
|
||||||
|
to the Unix @code{open} system call.
|
||||||
|
|
||||||
|
@c ARGFIXME string/filename mode/modes
|
||||||
|
@c docstring begin (texi-doc-string "guile" "open-file")
|
||||||
|
@deffn primitive open-file filename modes
|
||||||
|
Open the file whose name is @var{string}, and return a port
|
||||||
|
representing that file. The attributes of the port are
|
||||||
|
determined by the @var{mode} string. The way in
|
||||||
|
which this is interpreted is similar to C stdio:
|
||||||
|
|
||||||
|
The first character must be one of the following:
|
||||||
|
|
||||||
|
@table @samp
|
||||||
|
@item r
|
||||||
|
Open an existing file for input.
|
||||||
|
@item w
|
||||||
|
Open a file for output, creating it if it doesn't already exist
|
||||||
|
or removing its contents if it does.
|
||||||
|
@item a
|
||||||
|
Open a file for output, creating it if it doesn't already exist.
|
||||||
|
All writes to the port will go to the end of the file.
|
||||||
|
The "append mode" can be turned off while the port is in use
|
||||||
|
@pxref{Ports and File Descriptors, fcntl}
|
||||||
|
@end table
|
||||||
|
|
||||||
|
The following additional characters can be appended:
|
||||||
|
|
||||||
|
@table @samp
|
||||||
|
@item +
|
||||||
|
Open the port for both input and output. E.g., @code{r+}: open
|
||||||
|
an existing file for both input and output.
|
||||||
|
@item 0
|
||||||
|
Create an "unbuffered" port. In this case input and output operations
|
||||||
|
are passed directly to the underlying port implementation without
|
||||||
|
additional buffering. This is likely to slow down I/O operations.
|
||||||
|
The buffering mode can be changed while a port is in use
|
||||||
|
@pxref{Ports and File Descriptors, setvbuf}
|
||||||
|
@item l
|
||||||
|
Add line-buffering to the port. The port output buffer will be
|
||||||
|
automatically flushed whenever a newline character is written.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
In theory we could create read/write ports which were buffered in one
|
||||||
|
direction only. However this isn't included in the current interfaces.
|
||||||
|
|
||||||
|
If a file cannot be opened with the access requested,
|
||||||
|
@code{open-file} throws an exception.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "r4rs.scm" "open-input-file")
|
||||||
|
@deffn procedure open-input-file filename
|
||||||
|
Open @var{filename} for input. Equivalent to
|
||||||
|
@smalllisp
|
||||||
|
(open-file @var{filename} "r")
|
||||||
|
@end smalllisp
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "r4rs.scm" "open-output-file")
|
||||||
|
@deffn procedure open-output-file filename
|
||||||
|
Open @var{filename} for output. Equivalent to
|
||||||
|
@smalllisp
|
||||||
|
(open-file @var{filename} "w")
|
||||||
|
@end smalllisp
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "port-mode")
|
||||||
|
@deffn primitive port-mode port
|
||||||
|
Returns the port modes associated with the open port @var{port}. These
|
||||||
|
will not necessarily be identical to the modes used when the port was
|
||||||
|
opened, since modes such as "append" which are used only during
|
||||||
|
port creation are not retained.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "port-filename")
|
||||||
|
@deffn primitive port-filename port
|
||||||
|
Return the filename associated with @var{port}. This function returns
|
||||||
|
the strings "standard input", "standard output" and "standard error"
|
||||||
|
when called on the current input, output and error ports respectively.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-port-filename!")
|
||||||
|
@deffn primitive set-port-filename! port filename
|
||||||
|
Change the filename associated with @var{port}, using the current input
|
||||||
|
port if none is specified. Note that this does not change the port's
|
||||||
|
source of data, but only the value that is returned by
|
||||||
|
@code{port-filename} and reported in diagnostic output.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive file-port? obj
|
||||||
|
Determine whether @var{obj} is a port that is related to a file.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node String Ports
|
||||||
|
@subsection String Ports
|
||||||
|
|
||||||
|
The following allow string ports to be opened by analogy to R4R*
|
||||||
|
file port facilities:
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "call-with-output-string")
|
||||||
|
@deffn primitive call-with-output-string proc
|
||||||
|
Calls the one-argument procedure @var{proc} with a newly created output
|
||||||
|
port. When the function returns, the string composed of the characters
|
||||||
|
written into the port is returned.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME str/string
|
||||||
|
@c docstring begin (texi-doc-string "guile" "call-with-input-string")
|
||||||
|
@deffn primitive call-with-input-string str proc
|
||||||
|
Calls the one-argument procedure @var{proc} with a newly created input
|
||||||
|
port from which @var{string}'s contents may be read. The value yielded
|
||||||
|
by the @var{proc} is returned.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "r4rs.scm" "with-output-to-string")
|
||||||
|
@deffn procedure with-output-to-string thunk
|
||||||
|
Calls the zero-argument procedure @var{thunk} with the current output
|
||||||
|
port set temporarily to a new string port. It returns a string
|
||||||
|
composed of the characters written to the current output.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "r4rs.scm" "with-input-from-string")
|
||||||
|
@deffn procedure with-input-from-string string thunk
|
||||||
|
Calls the zero-argument procedure @var{thunk} with the current input
|
||||||
|
port set temporarily to a string port opened on the specified
|
||||||
|
@var{string}. The value yielded by @var{thunk} is returned.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
A string port can be used in many procedures which accept a port
|
||||||
|
but which are not dependent on implementation details of fports.
|
||||||
|
E.g., seeking and truncating will work on a string port,
|
||||||
|
but trying to extract the file descriptor number will fail.
|
||||||
|
|
||||||
|
At present there isn't a procedure that simply returns a new string
|
||||||
|
port. There's also no way of opening read/write string ports from
|
||||||
|
Scheme even though it's possible from C. SRFI 6 could be implemented
|
||||||
|
without much difficulty.
|
||||||
|
|
||||||
|
|
||||||
|
@node Soft Ports
|
||||||
|
@subsection Soft Ports
|
||||||
|
|
||||||
|
A @dfn{soft-port} is a port based on a vector of procedures capable of
|
||||||
|
accepting or delivering characters. It allows emulation of I/O ports.
|
||||||
|
|
||||||
|
@c ARGFIXME pv/vector
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-soft-port")
|
||||||
|
@deffn primitive make-soft-port pv modes
|
||||||
|
Returns a port capable of receiving or delivering characters as
|
||||||
|
specified by the @var{modes} string (@pxref{File Ports,
|
||||||
|
open-file}). @var{vector} must be a vector of length 6. Its components
|
||||||
|
are as follows:
|
||||||
|
|
||||||
|
@enumerate 0
|
||||||
|
@item
|
||||||
|
procedure accepting one character for output
|
||||||
|
@item
|
||||||
|
procedure accepting a string for output
|
||||||
|
@item
|
||||||
|
thunk for flushing output
|
||||||
|
@item
|
||||||
|
thunk for getting one character
|
||||||
|
@item
|
||||||
|
thunk for closing port (not by garbage collection)
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
For an output-only port only elements 0, 1, 2, and 4 need be
|
||||||
|
procedures. For an input-only port only elements 3 and 4 need be
|
||||||
|
procedures. Thunks 2 and 4 can instead be @code{#f} if there is no useful
|
||||||
|
operation for them to perform.
|
||||||
|
|
||||||
|
If thunk 3 returns @code{#f} or an @code{eof-object} (@pxref{Input,
|
||||||
|
eof-object?, ,r4rs, The Revised^4 Report on Scheme}) it indicates that
|
||||||
|
the port has reached end-of-file. For example:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(define stdout (current-output-port))
|
||||||
|
(define p (make-soft-port
|
||||||
|
(vector
|
||||||
|
(lambda (c) (write c stdout))
|
||||||
|
(lambda (s) (display s stdout))
|
||||||
|
(lambda () (display "." stdout))
|
||||||
|
(lambda () (char-upcase (read-char)))
|
||||||
|
(lambda () (display "@@" stdout)))
|
||||||
|
"rw"))
|
||||||
|
|
||||||
|
(write p p) @result{} #<input-output: soft 8081e20>
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Void Ports
|
||||||
|
@subsection Void Ports
|
||||||
|
|
||||||
|
This kind of port just causes errors if you try to use it in
|
||||||
|
a normal way.
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "%make-void-port")
|
||||||
|
@deffn primitive %make-void-port mode
|
||||||
|
Create and return a new void port. A void port acts like
|
||||||
|
/dev/null. The @var{mode} argument
|
||||||
|
specifies the input/output modes for this port: see the
|
||||||
|
documentation for @code{open-file} in @ref{File Ports}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
244
doc/scheme-memory.texi
Normal file
244
doc/scheme-memory.texi
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
@page
|
||||||
|
@node Memory Management
|
||||||
|
@chapter Memory Management and Garbage Collection
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Garbage Collection::
|
||||||
|
* Weak References::
|
||||||
|
* Guardians::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Garbage Collection
|
||||||
|
@section Garbage Collection
|
||||||
|
|
||||||
|
[FIXME: this is pasted in from Tom Lord's original guile.texi and should
|
||||||
|
be reviewed]
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "gc")
|
||||||
|
@deffn primitive gc
|
||||||
|
Scans all of SCM objects and reclaims for further use those that are
|
||||||
|
no longer accessible.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "gc-stats")
|
||||||
|
@deffn primitive gc-stats
|
||||||
|
Returns an association list of statistics about Guile's current use of storage.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "object-address")
|
||||||
|
@deffn primitive object-address obj
|
||||||
|
Return an integer that for the lifetime of @var{obj} is uniquely
|
||||||
|
returned by this function for @var{obj}
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "unhash-name")
|
||||||
|
@deffn primitive unhash-name name
|
||||||
|
Flushes the glocs for @var{name}, or all glocs if @var{name}
|
||||||
|
is @code{#t}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Weak References
|
||||||
|
@section Weak References
|
||||||
|
|
||||||
|
[FIXME: This chapter is based on Mikael Djurfeldt's answer to a question
|
||||||
|
by Michael Livshin. Any mistakes are not theirs, of course. ]
|
||||||
|
|
||||||
|
Weak references let you attach bookkeeping information to data so that
|
||||||
|
the additional information automatically disappears when the original
|
||||||
|
data is no longer in use and gets garbage collected. In a weak key hash,
|
||||||
|
the hash entry for that key disappears as soon as the key is no longer
|
||||||
|
referneced from anywhere else. For weak value hashes, the same happens
|
||||||
|
as soon as the value is no longer in use. Entries in a doubly weak hash
|
||||||
|
disappear when either the key or the value are not used anywhere else
|
||||||
|
anymore.
|
||||||
|
|
||||||
|
Property lists offer the same kind of functionality as weak key hashes
|
||||||
|
in many situations. (@pxref{Property Lists})
|
||||||
|
|
||||||
|
Here's an example (a little bit strained perhaps, but one of the
|
||||||
|
examples is actually used in Guile):
|
||||||
|
|
||||||
|
Assume that you're implementing a debugging system where you want to
|
||||||
|
associate information about filename and position of source code
|
||||||
|
expressions with the expressions themselves.
|
||||||
|
|
||||||
|
Hashtables can be used for that, but if you use ordinary hash tables
|
||||||
|
it will be impossible for the scheme interpreter to "forget" old
|
||||||
|
source when, for example, a file is reloaded.
|
||||||
|
|
||||||
|
To implement the mapping from source code expressions to positional
|
||||||
|
information it is necessary to use weak-key tables since we don't want
|
||||||
|
the expressions to be remembered just because they are in our table.
|
||||||
|
|
||||||
|
To implement a mapping from source file line numbers to source code
|
||||||
|
expressions you would use a weak-value table.
|
||||||
|
|
||||||
|
To implement a mapping from source code expressions to the procedures
|
||||||
|
they constitute a doubly-weak table has to be used.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Weak key hashes::
|
||||||
|
* Weak vectors::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Weak key hashes
|
||||||
|
@subsection Weak key hashes
|
||||||
|
|
||||||
|
@c ARGFIXME k/size
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-weak-key-hash-table")
|
||||||
|
@deffn primitive make-weak-key-hash-table k
|
||||||
|
@deffnx primitive make-weak-value-hash-table size
|
||||||
|
@deffnx primitive make-doubly-weak-hash-table size
|
||||||
|
Return a weak hash table with @var{size} buckets. As with any hash
|
||||||
|
table, choosing a good size for the table requires some caution.
|
||||||
|
|
||||||
|
You can modify weak hash tables in exactly the same way you would modify
|
||||||
|
regular hash tables. (@pxref{Hash Tables})
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME x/obj
|
||||||
|
@c docstring begin (texi-doc-string "guile" "weak-key-hash-table?")
|
||||||
|
@deffn primitive weak-key-hash-table? x
|
||||||
|
@deffnx primitive weak-value-hash-table? obj
|
||||||
|
@deffnx primitive doubly-weak-hash-table? obj
|
||||||
|
Return @var{#t} if @var{obj} is the specified weak hash table. Note
|
||||||
|
that a doubly weak hash table is neither a weak key nor a weak value
|
||||||
|
hash table.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-weak-value-hash-table")
|
||||||
|
@deffn primitive make-weak-value-hash-table k
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "weak-value-hash-table?")
|
||||||
|
@deffn primitive weak-value-hash-table? x
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-doubly-weak-hash-table")
|
||||||
|
@deffn primitive make-doubly-weak-hash-table k
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "doubly-weak-hash-table?")
|
||||||
|
@deffn primitive doubly-weak-hash-table? x
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Weak vectors
|
||||||
|
@subsection Weak vectors
|
||||||
|
|
||||||
|
Weak vectors are mainly useful in Guile's implementation of weak hash
|
||||||
|
tables.
|
||||||
|
|
||||||
|
@c ARGFIXME k/size
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-weak-vector")
|
||||||
|
@deffn primitive make-weak-vector k [fill]
|
||||||
|
Return a weak vector with @var{size} elements. If the optional
|
||||||
|
argument @var{fill} is given, all entries in the vector will be set to
|
||||||
|
@var{fill}. The default value for @var{fill} is the empty list.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c NJFIXME should vector->list here be list->vector ?
|
||||||
|
@c docstring begin (texi-doc-string "guile" "weak-vector")
|
||||||
|
@c docstring begin (texi-doc-string "guile" "list->weak-vector")
|
||||||
|
@deffn primitive weak-vector . l
|
||||||
|
@deffnx primitive list->weak-vector l
|
||||||
|
Construct a weak vector from a list: @code{weak-vector} uses the list of
|
||||||
|
its arguments while @code{list->weak-vector} uses its only argument
|
||||||
|
@var{l} (a list) to construct a weak vector the same way
|
||||||
|
@code{vector->list} would.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME x/obj
|
||||||
|
@c docstring begin (texi-doc-string "guile" "weak-vector?")
|
||||||
|
@deffn primitive weak-vector? x
|
||||||
|
Return @var{#t} if @var{obj} is a weak vector. Note that all weak
|
||||||
|
hashes are also weak vectors.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Guardians
|
||||||
|
@section Guardians
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-guardian")
|
||||||
|
@deffn primitive make-guardian [greedy?]
|
||||||
|
Create a new guardian.
|
||||||
|
A guardian protects a set of objects from garbage collection,
|
||||||
|
allowing a program to apply cleanup or other actions.
|
||||||
|
|
||||||
|
@code{make-guardian} returns a procedure representing the guardian.
|
||||||
|
Calling the guardian procedure with an argument adds the
|
||||||
|
argument to the guardian's set of protected objects.
|
||||||
|
Calling the guardian procedure without an argument returns
|
||||||
|
one of the protected objects which are ready for garbage
|
||||||
|
collection, or @code{#f} if no such object is available.
|
||||||
|
Objects which are returned in this way are removed from
|
||||||
|
the guardian.
|
||||||
|
|
||||||
|
@code{make-guardian} takes one optional argument that says whether the
|
||||||
|
new guardian should be greedy or sharing. If there is any chance
|
||||||
|
that any object protected by the guardian may be resurrected,
|
||||||
|
then you should make the guardian greedy (this is the default).
|
||||||
|
|
||||||
|
See R. Kent Dybvig, Carl Bruggeman, and David Eby (1993)
|
||||||
|
"Guardians in a Generation-Based Garbage Collector".
|
||||||
|
ACM SIGPLAN Conference on Programming Language Design
|
||||||
|
and Implementation, June 1993.
|
||||||
|
|
||||||
|
(the semantics are slightly different at this point, but the
|
||||||
|
paper still (mostly) accurately describes the interface).
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive destroy-guardian! guardian
|
||||||
|
Destroys @var{guardian}, by making it impossible to put any more
|
||||||
|
objects in it or get any objects from it. It also unguards any
|
||||||
|
objects guarded by @var{guardian}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive guardian-greedy? guardian
|
||||||
|
Return @code{#t} if @var{guardian} is a greedy guardian, otherwise @code{#f}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive guardian-destroyed? guardian
|
||||||
|
Return @code{#t} if @var{guardian} has been destroyed, otherwise @code{#f}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node Objects
|
||||||
|
@chapter Objects
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "entity?")
|
||||||
|
@deffn primitive entity? obj
|
||||||
|
Return @code{#t} if @var{obj} is an entity.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "operator?")
|
||||||
|
@deffn primitive operator? obj
|
||||||
|
Return @code{#t} if @var{obj} is an operator.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-object-procedure!")
|
||||||
|
@deffn primitive set-object-procedure! obj proc
|
||||||
|
Return the object procedure of @var{obj} to @var{proc}.
|
||||||
|
@var{obj} must be either an entity or an operator.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-class-object")
|
||||||
|
@deffn primitive make-class-object metaclass layout
|
||||||
|
Create a new class object of class @var{metaclass}, with the
|
||||||
|
slot layout specified by @var{layout}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-subclass-object")
|
||||||
|
@deffn primitive make-subclass-object class layout
|
||||||
|
Create a subclass object of @var{class}, with the slot layout
|
||||||
|
specified by @var{layout}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
675
doc/scheme-modules.texi
Normal file
675
doc/scheme-modules.texi
Normal file
|
@ -0,0 +1,675 @@
|
||||||
|
@page
|
||||||
|
@node Modules
|
||||||
|
@chapter Modules
|
||||||
|
@cindex modules
|
||||||
|
|
||||||
|
[FIXME: somewhat babbling; should be reviewed by someone who understands
|
||||||
|
modules, once the new module system is in place]
|
||||||
|
|
||||||
|
When programs become large, naming conflicts can occur when a function
|
||||||
|
or global variable defined in one file has the same name as a function
|
||||||
|
or global variable in another file. Even just a @emph{similarity}
|
||||||
|
between function names can cause hard-to-find bugs, since a programmer
|
||||||
|
might type the wrong function name.
|
||||||
|
|
||||||
|
The approach used to tackle this problem is called @emph{information
|
||||||
|
encapsulation}, which consists of packaging functional units into a
|
||||||
|
given name space that is clearly separated from other name spaces.
|
||||||
|
@cindex encapsulation
|
||||||
|
@cindex information encapsulation
|
||||||
|
@cindex name space
|
||||||
|
|
||||||
|
The language features that allow this are usually called @emph{the
|
||||||
|
module system} because programs are broken up into modules that are
|
||||||
|
compiled separately (or loaded separately in an interpreter).
|
||||||
|
|
||||||
|
Older languages, like C, have limited support for name space
|
||||||
|
manipulation and protection. In C a variable or function is public by
|
||||||
|
default, and can be made local to a module with the @code{static}
|
||||||
|
keyword. But you cannot reference public variables and functions from
|
||||||
|
another module with different names.
|
||||||
|
|
||||||
|
More advanced module systems have become a common feature in recently
|
||||||
|
designed languages: ML, Python, Perl, and Modula 3 all allow the
|
||||||
|
@emph{renaming} of objects from a foreign module, so they will not
|
||||||
|
clutter the global name space.
|
||||||
|
@cindex name space - private
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Scheme and modules::
|
||||||
|
* The Guile module system::
|
||||||
|
* Dynamic Libraries:: Loading libraries of compiled code at run time.
|
||||||
|
* Dynamic Linking from Marius::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Scheme and modules
|
||||||
|
@section Scheme and modules
|
||||||
|
|
||||||
|
Scheme, as defined in R4RS, does @emph{not} have a module system at all.
|
||||||
|
|
||||||
|
Aubrey Jaffer, mostly to support his portable Scheme library SLIB,
|
||||||
|
implemented a provide/require mechanism for many Scheme implementations.
|
||||||
|
Library files in SLIB @emph{provide} a feature, and when user programs
|
||||||
|
@emph{require} that feature, the library file is loaded in.
|
||||||
|
|
||||||
|
For example, the file @file{random.scm} in the SLIB package contains the
|
||||||
|
line
|
||||||
|
@smalllisp
|
||||||
|
(provide 'random)
|
||||||
|
@end smalllisp
|
||||||
|
so to use its procedures, a user would type
|
||||||
|
@smalllisp
|
||||||
|
(require 'random)
|
||||||
|
@end smalllisp
|
||||||
|
and they would magically become available, @emph{but still have the same
|
||||||
|
names!} So this method is nice, but not as good as a full-featured
|
||||||
|
module system.
|
||||||
|
|
||||||
|
|
||||||
|
@node The Guile module system
|
||||||
|
@section The Guile module system
|
||||||
|
|
||||||
|
In 1996 Tom Lord implemented a full-featured module system for Guile
|
||||||
|
which allows loading Scheme source files into a private name space.
|
||||||
|
|
||||||
|
This module system is regarded as being rather idiosyncratic, and will
|
||||||
|
probably change to something more like the ML module system, so for now
|
||||||
|
I will simply describe how it works for a couple of simple cases.
|
||||||
|
|
||||||
|
First of all, the Guile module system sets up a hierarchical name space,
|
||||||
|
and that name space can be represented like Unix pathnames preceded by a
|
||||||
|
@key{#} character. The root name space for all Guile-supplied modules
|
||||||
|
is called @code{ice-9}.
|
||||||
|
|
||||||
|
So for example, the SLIB interface, contained in
|
||||||
|
@file{$srcdir/ice-9/slib.scm}, starts out with
|
||||||
|
@smalllisp
|
||||||
|
(define-module (ice-9 slib))
|
||||||
|
@end smalllisp
|
||||||
|
and a user program can use
|
||||||
|
@smalllisp
|
||||||
|
(use-modules (ice-9 slib))
|
||||||
|
@end smalllisp
|
||||||
|
to have access to all procedures and variables defined within the slib
|
||||||
|
module with @code{(define-public ...)}.
|
||||||
|
|
||||||
|
So here are the functions involved:
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "define-module")
|
||||||
|
@deffn syntax define-module module-specification
|
||||||
|
@var{module-specification} is of the form @code{(hierarchy file)}. One
|
||||||
|
example of this is
|
||||||
|
@smalllisp
|
||||||
|
(use-modules (ice-9 slib))
|
||||||
|
@end smalllisp
|
||||||
|
define-module makes this module available to Guile programs under the
|
||||||
|
given @var{module-specification}.
|
||||||
|
@end deffn
|
||||||
|
@c end
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "define-public")
|
||||||
|
@deffn syntax define-public @dots{}
|
||||||
|
Makes a procedure or variable available to programs that use the current
|
||||||
|
module.
|
||||||
|
@end deffn
|
||||||
|
@c end
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "use-modules")
|
||||||
|
@deffn syntax use-modules module-specification
|
||||||
|
@var{module-specification} is of the form @code{(hierarchy file)}. One
|
||||||
|
example of this is
|
||||||
|
@smalllisp
|
||||||
|
(use-modules (ice-9 slib))
|
||||||
|
@end smalllisp
|
||||||
|
use-modules allows the current Guile program to use all publicly defined
|
||||||
|
procedures and variables in the module denoted by
|
||||||
|
@var{module-specification}.
|
||||||
|
@end deffn
|
||||||
|
@c end
|
||||||
|
|
||||||
|
[FIXME: must say more, and explain, and also demonstrate a private name
|
||||||
|
space use, and demonstrate how one would do Python's "from Tkinter
|
||||||
|
import *" versus "import Tkinter". Must also add something about paths
|
||||||
|
and standards for contributed modules.]
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "standard-eval-closure")
|
||||||
|
@deffn primitive standard-eval-closure module
|
||||||
|
Return an eval closure for the module @var{module}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
Some modules are included in the Guile distribution; here are references
|
||||||
|
to the entries in this manual which describe them in more detail:
|
||||||
|
@table @strong
|
||||||
|
@item boot-9
|
||||||
|
boot-9 is Guile's initialization module, and it is always loaded when
|
||||||
|
Guile starts up.
|
||||||
|
@item (ice-9 debug)
|
||||||
|
Mikael Djurfeldt's source-level debugging support for Guile
|
||||||
|
(@pxref{Debugger User Interface}).
|
||||||
|
@item (ice-9 threads)
|
||||||
|
Guile's support for multi threaded execution (@pxref{Scheduling}).
|
||||||
|
@item (ice-9 slib)
|
||||||
|
This module contains hooks for using Aubrey Jaffer's portable Scheme
|
||||||
|
library SLIB from Guile (@pxref{SLIB}).
|
||||||
|
@item (ice-9 jacal)
|
||||||
|
This module contains hooks for using Aubrey Jaffer's symbolic math
|
||||||
|
packge Jacal from Guile (@pxref{JACAL}).
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@node Dynamic Libraries
|
||||||
|
@section Dynamic Libraries
|
||||||
|
|
||||||
|
Often you will want to extend Guile by linking it with some existing
|
||||||
|
system library. For example, linking Guile with a @code{curses} or
|
||||||
|
@code{termcap} library would be useful if you want to implement a
|
||||||
|
full-screen user interface for a Guile application. However, if you
|
||||||
|
were to link Guile with these libraries at compile time, it would bloat
|
||||||
|
the interpreter considerably, affecting everyone on the system even if
|
||||||
|
the new libraries are useful only to you. Also, every time a new
|
||||||
|
library is installed, you would have to reconfigure, recompile and
|
||||||
|
relink Guile merely in order to provide a new interface.
|
||||||
|
|
||||||
|
Many Unix systems permit you to get around this problem by using
|
||||||
|
@dfn{dynamic loading}. When a new library is linked, it can be made a
|
||||||
|
@dfn{dynamic library} by passing certain switches to the linker. A
|
||||||
|
dynamic library does not need to be linked with an executable image at
|
||||||
|
link time; instead, the executable may choose to load it dynamically at
|
||||||
|
run time. This is a powerful concept that permits an executable to link
|
||||||
|
itself with almost any library without reconfiguration, if it has been
|
||||||
|
written properly.
|
||||||
|
|
||||||
|
Guile's dynamic linking functions make it relatively easy to write a
|
||||||
|
module that incorporates code from third-party object code libraries.
|
||||||
|
|
||||||
|
@c ARGFIXME fname/library-file
|
||||||
|
@c docstring begin (texi-doc-string "guile" "dynamic-link")
|
||||||
|
@deffn primitive dynamic-link fname
|
||||||
|
Open the dynamic library @var{library-file}. A library handle
|
||||||
|
representing the opened library is returned; this handle should be used
|
||||||
|
as the @var{lib} argument to the following functions.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "dynamic-object?")
|
||||||
|
@deffn primitive dynamic-object? obj
|
||||||
|
Return @code{#t} if @var{obj} is a dynamic library handle, or @code{#f}
|
||||||
|
otherwise.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME dobj/dynobj/library-handle
|
||||||
|
@c docstring begin (texi-doc-string "guile" "dynamic-unlink")
|
||||||
|
@deffn primitive dynamic-unlink dobj
|
||||||
|
Unlink the library represented by @var{library-handle},
|
||||||
|
and remove any imported symbols from the address space.
|
||||||
|
GJB:FIXME:DOC: 2nd version below:
|
||||||
|
Unlink the indicated object file from the application. The
|
||||||
|
argument @var{dynobj} must have been obtained by a call to
|
||||||
|
@code{dynamic-link}. After @code{dynamic-unlink} has been
|
||||||
|
called on @var{dynobj}, its content is no longer accessible.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME symb/func/function dobj/lib/dynobj
|
||||||
|
@c docstring begin (texi-doc-string "guile" "dynamic-func")
|
||||||
|
@deffn primitive dynamic-func name dobj
|
||||||
|
Search the dynamic object @var{dobj} for the C function
|
||||||
|
indicated by the string @var{name} and return some Scheme
|
||||||
|
handle that can later be used with @code{dynamic-call} to
|
||||||
|
actually call the function.
|
||||||
|
|
||||||
|
Regardless whether your C compiler prepends an underscore @samp{_} to
|
||||||
|
the global names in a program, you should @strong{not} include this
|
||||||
|
underscore in @var{function}. Guile knows whether the underscore is
|
||||||
|
needed or not and will add it when necessary.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME lib-thunk/func/function lib/dobj/dynobj
|
||||||
|
@c docstring begin (texi-doc-string "guile" "dynamic-call")
|
||||||
|
@deffn primitive dynamic-call func dobj
|
||||||
|
Call @var{lib-thunk}, a procedure of no arguments. If @var{lib-thunk}
|
||||||
|
is a string, it is assumed to be a symbol found in the dynamic library
|
||||||
|
@var{lib} and is fetched with @code{dynamic-func}. Otherwise, it should
|
||||||
|
be a function handle returned by a previous call to @code{dynamic-func}.
|
||||||
|
The return value is unspecified.
|
||||||
|
GJB:FIXME:DOC 2nd version below
|
||||||
|
Call the C function indicated by @var{function} and @var{dynobj}. The
|
||||||
|
function is passed no arguments and its return value is ignored. When
|
||||||
|
@var{function} is something returned by @code{dynamic-func}, call that
|
||||||
|
function and ignore @var{dynobj}. When @var{function} is a string (or
|
||||||
|
symbol, etc.), look it up in @var{dynobj}; this is equivalent to
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
(dynamic-call (dynamic-func @var{function} @var{dynobj} #f))
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
Interrupts are deferred while the C function is executing (with
|
||||||
|
@code{SCM_DEFER_INTS}/@code{SCM_ALLOW_INTS}).
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME func/proc/function dobj/dynobj
|
||||||
|
@c docstring begin (texi-doc-string "guile" "dynamic-args-call")
|
||||||
|
@deffn primitive dynamic-args-call func dobj args
|
||||||
|
Call @var{proc}, a dynamically loaded function, passing it the argument
|
||||||
|
list @var{args} (a list of strings). As with @code{dynamic-call},
|
||||||
|
@var{proc} should be either a function handle or a string, in which case
|
||||||
|
it is first fetched from @var{lib} with @code{dynamic-func}.
|
||||||
|
|
||||||
|
@var{proc} is assumed to return an integer, which is used as the return
|
||||||
|
value from @code{dynamic-args-call}.
|
||||||
|
|
||||||
|
GJB:FIXME:DOC 2nd version below
|
||||||
|
Call the C function indicated by @var{function} and @var{dynobj}, just
|
||||||
|
like @code{dynamic-call}, but pass it some arguments and return its
|
||||||
|
return value. The C function is expected to take two arguments and
|
||||||
|
return an @code{int}, just like @code{main}:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
int c_func (int argc, char **argv);
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The parameter @var{args} must be a list of strings and is converted into
|
||||||
|
an array of @code{char *}. The array is passed in @var{argv} and its
|
||||||
|
size in @var{argc}. The return value is converted to a Scheme number
|
||||||
|
and returned from the call to @code{dynamic-args-call}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "c-registered-modules")
|
||||||
|
@deffn primitive c-registered-modules
|
||||||
|
Return a list of the object code modules that have been imported into
|
||||||
|
the current Guile process. Each element of the list is a pair whose
|
||||||
|
car is the name of the module, and whose cdr is the function handle
|
||||||
|
for that module's initializer function. The name is the string that
|
||||||
|
has been passed to scm_register_module_xxx.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "c-clear-registered-modules")
|
||||||
|
@deffn primitive c-clear-registered-modules
|
||||||
|
Destroy the list of modules registered with the current Guile process.
|
||||||
|
The return value is unspecified. @strong{Warning:} this function does
|
||||||
|
not actually unlink or deallocate these modules, but only destroys the
|
||||||
|
records of which modules have been loaded. It should therefore be used
|
||||||
|
only by module bookkeeping operations.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
[FIXME: provide a brief example here of writing the C hooks for an
|
||||||
|
object code module, and using dynamic-link and dynamic-call to load the
|
||||||
|
module.]
|
||||||
|
|
||||||
|
|
||||||
|
@node Dynamic Linking from Marius
|
||||||
|
@section Dynamic Linking from Marius
|
||||||
|
|
||||||
|
@c NJFIXME primitive documentation here duplicates (and is generally
|
||||||
|
@c better than) documentation for the same primitives earlier on.
|
||||||
|
|
||||||
|
Most modern Unices have something called @dfn{shared libraries}. This
|
||||||
|
ordinarily means that they have the capability to share the executable
|
||||||
|
image of a library between several running programs to save memory and
|
||||||
|
disk space. But generally, shared libraries give a lot of additional
|
||||||
|
flexibility compared to the traditional static libraries. In fact,
|
||||||
|
calling them `dynamic' libraries is as correct as calling them `shared'.
|
||||||
|
|
||||||
|
Shared libraries really give you a lot of flexibility in addition to the
|
||||||
|
memory and disk space savings. When you link a program against a shared
|
||||||
|
library, that library is not closely incorporated into the final
|
||||||
|
executable. Instead, the executable of your program only contains
|
||||||
|
enough information to find the needed shared libraries when the program
|
||||||
|
is actually run. Only then, when the program is starting, is the final
|
||||||
|
step of the linking process performed. This means that you need not
|
||||||
|
recompile all programs when you install a new, only slightly modified
|
||||||
|
version of a shared library. The programs will pick up the changes
|
||||||
|
automatically the next time they are run.
|
||||||
|
|
||||||
|
Now, when all the necessary machinery is there to perform part of the
|
||||||
|
linking at run-time, why not take the next step and allow the programmer
|
||||||
|
to explicitly take advantage of it from within his program? Of course,
|
||||||
|
many operating systems that support shared libraries do just that, and
|
||||||
|
chances are that Guile will allow you to access this feature from within
|
||||||
|
your Scheme programs. As you might have guessed already, this feature
|
||||||
|
is called @dfn{dynamic linking}@footnote{Some people also refer to the
|
||||||
|
final linking stage at program startup as `dynamic linking', so if you
|
||||||
|
want to make yourself perfectly clear, it is probably best to use the
|
||||||
|
more technical term @dfn{dlopening}, as suggested by Gordon Matzigkeit
|
||||||
|
in his libtool documentation.}
|
||||||
|
|
||||||
|
As with many aspects of Guile, there is a low-level way to access the
|
||||||
|
dynamic linking apparatus, and a more high-level interface that
|
||||||
|
integrates dynamically linked libraries into the module system.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Low level dynamic linking::
|
||||||
|
* Compiled Code Modules::
|
||||||
|
* Dynamic Linking and Compiled Code Modules::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Low level dynamic linking
|
||||||
|
@subsection Low level dynamic linking
|
||||||
|
|
||||||
|
When using the low level procedures to do your dynamic linking, you have
|
||||||
|
complete control over which library is loaded when and what get's done
|
||||||
|
with it.
|
||||||
|
|
||||||
|
@deffn primitive dynamic-link library
|
||||||
|
Find the shared library denoted by @var{library} (a string) and link it
|
||||||
|
into the running Guile application. When everything works out, return a
|
||||||
|
Scheme object suitable for representing the linked object file.
|
||||||
|
Otherwise an error is thrown. How object files are searched is system
|
||||||
|
dependent.
|
||||||
|
|
||||||
|
Normally, @var{library} is just the name of some shared library file
|
||||||
|
that will be searched for in the places where shared libraries usually
|
||||||
|
reside, such as in @file{/usr/lib} and @file{/usr/local/lib}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive dynamic-object? val
|
||||||
|
Determine whether @var{val} represents a dynamically linked object file.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive dynamic-unlink dynobj
|
||||||
|
Unlink the indicated object file from the application. The argument
|
||||||
|
@var{dynobj} should be one of the values returned by
|
||||||
|
@code{dynamic-link}. When @code{dynamic-unlink} has been called on
|
||||||
|
@var{dynobj}, it is no longer usable as an argument to the functions
|
||||||
|
below and you will get type mismatch errors when you try to.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive dynamic-func function dynobj
|
||||||
|
Search the C function indicated by @var{function} (a string or symbol)
|
||||||
|
in @var{dynobj} and return some Scheme object that can later be used
|
||||||
|
with @code{dynamic-call} to actually call this function. Right now,
|
||||||
|
these Scheme objects are formed by casting the address of the function
|
||||||
|
to @code{long} and converting this number to its Scheme representation.
|
||||||
|
|
||||||
|
Regardless whether your C compiler prepends an underscore @samp{_} to
|
||||||
|
the global names in a program, you should @strong{not} include this
|
||||||
|
underscore in @var{function}. Guile knows whether the underscore is
|
||||||
|
needed or not and will add it when necessary.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive dynamic-call function dynobj
|
||||||
|
Call the C function indicated by @var{function} and @var{dynobj}. The
|
||||||
|
function is passed no arguments and its return value is ignored. When
|
||||||
|
@var{function} is something returned by @code{dynamic-func}, call that
|
||||||
|
function and ignore @var{dynobj}. When @var{function} is a string (or
|
||||||
|
symbol, etc.), look it up in @var{dynobj}; this is equivalent to
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
(dynamic-call (dynamic-func @var{function} @var{dynobj} #f))
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
Interrupts are deferred while the C function is executing (with
|
||||||
|
@code{SCM_DEFER_INTS}/@code{SCM_ALLOW_INTS}).
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn primitive dynamic-args-call function dynobj args
|
||||||
|
Call the C function indicated by @var{function} and @var{dynobj}, just
|
||||||
|
like @code{dynamic-call}, but pass it some arguments and return its
|
||||||
|
return value. The C function is expected to take two arguments and
|
||||||
|
return an @code{int}, just like @code{main}:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
int c_func (int argc, char **argv);
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The parameter @var{args} must be a list of strings and is converted into
|
||||||
|
an array of @code{char *}. The array is passed in @var{argv} and its
|
||||||
|
size in @var{argc}. The return value is converted to a Scheme number
|
||||||
|
and returned from the call to @code{dynamic-args-call}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
When dynamic linking is disabled or not supported on your system,
|
||||||
|
the above functions throw errors, but they are still available.
|
||||||
|
|
||||||
|
Here is a small example that works on GNU/Linux:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
(define libc-obj (dynamic-link "libc.so"))
|
||||||
|
libc-obj
|
||||||
|
@result{} #<dynamic-object "libc.so">
|
||||||
|
(dynamic-args-call 'rand libc-obj '())
|
||||||
|
@result{} 269167349
|
||||||
|
(dynamic-unlink libc-obj)
|
||||||
|
libc-obj
|
||||||
|
@result{} #<dynamic-object "libc.so" (unlinked)>
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
As you can see, after calling @code{dynamic-unlink} on a dynamically
|
||||||
|
linked library, it is marked as @samp{(unlinked)} and you are no longer
|
||||||
|
able to use it with @code{dynamic-call}, etc. Whether the library is
|
||||||
|
really removed from you program is system-dependent and will generally
|
||||||
|
not happen when some other parts of your program still use it. In the
|
||||||
|
example above, @code{libc} is almost certainly not removed from your
|
||||||
|
program because it is badly needed by almost everything.
|
||||||
|
|
||||||
|
The functions to call a function from a dynamically linked library,
|
||||||
|
@code{dynamic-call} and @code{dynamic-args-call}, are not very powerful.
|
||||||
|
They are mostly intended to be used for calling specially written
|
||||||
|
initialization functions that will then add new primitives to Guile.
|
||||||
|
For example, we do not expect that you will dynamically link
|
||||||
|
@file{libX11} with @code{dynamic-link} and then construct a beautiful
|
||||||
|
graphical user interface just by using @code{dynamic-call} and
|
||||||
|
@code{dynamic-args-call}. Instead, the usual way would be to write a
|
||||||
|
special Guile<->X11 glue library that has intimate knowledge about both
|
||||||
|
Guile and X11 and does whatever is necessary to make them inter-operate
|
||||||
|
smoothly. This glue library could then be dynamically linked into a
|
||||||
|
vanilla Guile interpreter and activated by calling its initialization
|
||||||
|
function. That function would add all the new types and primitives to
|
||||||
|
the Guile interpreter that it has to offer.
|
||||||
|
|
||||||
|
From this setup the next logical step is to integrate these glue
|
||||||
|
libraries into the module system of Guile so that you can load new
|
||||||
|
primitives into a running system just as you can load new Scheme code.
|
||||||
|
|
||||||
|
There is, however, another possibility to get a more thorough access to
|
||||||
|
the functions contained in a dynamically linked library. Anthony Green
|
||||||
|
has written @file{libffi}, a library that implements a @dfn{foreign
|
||||||
|
function interface} for a number of different platforms. With it, you
|
||||||
|
can extend the Spartan functionality of @code{dynamic-call} and
|
||||||
|
@code{dynamic-args-call} considerably. There is glue code available in
|
||||||
|
the Guile contrib archive to make @file{libffi} accessible from Guile.
|
||||||
|
|
||||||
|
@node Compiled Code Modules
|
||||||
|
@subsection Putting Compiled Code into Modules
|
||||||
|
|
||||||
|
The new primitives that you add to Guile with @code{gh_new_procedure} or
|
||||||
|
with any of the other mechanisms are normally placed into the same
|
||||||
|
module as all the other builtin procedures (like @code{display}).
|
||||||
|
However, it is also possible to put new primitives into their own
|
||||||
|
module.
|
||||||
|
|
||||||
|
The mechanism for doing so is not very well thought out and is likely to
|
||||||
|
change when the module system of Guile itself is revised, but it is
|
||||||
|
simple and useful enough to document it as it stands.
|
||||||
|
|
||||||
|
What @code{gh_new_procedure} and the functions used by the snarfer
|
||||||
|
really do is to add the new primitives to whatever module is the
|
||||||
|
@emph{current module} when they are called. This is analogous to the
|
||||||
|
way Scheme code is put into modules: the @code{define-module} expression
|
||||||
|
at the top of a Scheme source file creates a new module and makes it the
|
||||||
|
current module while the rest of the file is evaluated. The
|
||||||
|
@code{define} expressions in that file then add their new definitions to
|
||||||
|
this current module.
|
||||||
|
|
||||||
|
Therefore, all we need to do is to make sure that the right module is
|
||||||
|
current when calling @code{gh_new_procedure} for our new primitives.
|
||||||
|
Unfortunately, there is not yet an easy way to access the module system
|
||||||
|
from C, so we are better off with a more indirect approach. Instead of
|
||||||
|
adding our primitives at initialization time we merely register with
|
||||||
|
Guile that we are ready to provide the contents of a certain module,
|
||||||
|
should it ever be needed.
|
||||||
|
|
||||||
|
@deftypefun void scm_register_module_xxx (char *@var{name}, void (*@var{initfunc})(void))
|
||||||
|
Register with Guile that @var{initfunc} will provide the contents of the
|
||||||
|
module @var{name}.
|
||||||
|
|
||||||
|
The function @var{initfunc} should perform the usual initialization
|
||||||
|
actions for your new primitives, like calling @code{gh_new_procedure} or
|
||||||
|
including the file produced by the snarfer. When @var{initfunc} is
|
||||||
|
called, the current module is a newly created module with a name as
|
||||||
|
indicated by @var{name}. Each definition that is added to it will be
|
||||||
|
automatically exported.
|
||||||
|
|
||||||
|
The string @var{name} indicates the hierachical name of the new module.
|
||||||
|
It should consist of the individual components of the module name
|
||||||
|
separated by single spaces. That is, the Scheme module name @code{(foo
|
||||||
|
bar)}, which is a list, should be written as @code{"foo bar"} for the
|
||||||
|
@var{name} parameter.
|
||||||
|
|
||||||
|
You can call @code{scm_register_module_xxx} at any time, even before
|
||||||
|
Guile has been initialized. This might be useful when you want to put
|
||||||
|
the call to it in some initialization code that is magically called
|
||||||
|
before main, like constructors for global C++ objects.
|
||||||
|
|
||||||
|
An example for @code{scm_register_module_xxx} appears in the next section.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
Now, instead of calling the initialization function at program startup,
|
||||||
|
you should simply call @code{scm_register_module_xxx} and pass it the
|
||||||
|
initialization function. When the named module is later requested by
|
||||||
|
Scheme code with @code{use-modules} for example, Guile will notice that
|
||||||
|
it knows how to create this module and will call the initialization
|
||||||
|
function at the right time in the right context.
|
||||||
|
|
||||||
|
@node Dynamic Linking and Compiled Code Modules
|
||||||
|
@subsection Dynamic Linking and Compiled Code Modules
|
||||||
|
|
||||||
|
The most interesting application of dynamically linked libraries is
|
||||||
|
probably to use them for providing @emph{compiled code modules} to
|
||||||
|
Scheme programs. As much fun as programming in Scheme is, every now and
|
||||||
|
then comes the need to write some low-level C stuff to make Scheme even
|
||||||
|
more fun.
|
||||||
|
|
||||||
|
Not only can you put these new primitives into their own module (see the
|
||||||
|
previous section), you can even put them into a shared library that is
|
||||||
|
only then linked to your running Guile image when it is actually
|
||||||
|
needed.
|
||||||
|
|
||||||
|
An example will hopefully make everything clear. Suppose we want to
|
||||||
|
make the Bessel functions of the C library available to Scheme in the
|
||||||
|
module @samp{(math bessel)}. First we need to write the appropriate
|
||||||
|
glue code to convert the arguments and return values of the functions
|
||||||
|
from Scheme to C and back. Additionally, we need a function that will
|
||||||
|
add them to the set of Guile primitives. Because this is just an
|
||||||
|
example, we will only implement this for the @code{j0} function, tho.
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
#include <math.h>
|
||||||
|
#include <guile/gh.h>
|
||||||
|
|
||||||
|
SCM
|
||||||
|
j0_wrapper (SCM x)
|
||||||
|
@{
|
||||||
|
return gh_double2scm (j0 (gh_scm2double (x)));
|
||||||
|
@}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_math_bessel ()
|
||||||
|
@{
|
||||||
|
gh_new_procedure1_0 ("j0", j0_wrapper);
|
||||||
|
@}
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
We can already try to bring this into action by manually calling the low
|
||||||
|
level functions for performing dynamic linking. The C source file needs
|
||||||
|
to be compiled into a shared library. Here is how to do it on
|
||||||
|
GNU/Linux, please refer to the @code{libtool} documentation for how to
|
||||||
|
create dynamically linkable libraries portably.
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
gcc -shared -o libbessel.so -fPIC bessel.c
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
Now fire up Guile:
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
(define bessel-lib (dynamic-link "./libbessel.so"))
|
||||||
|
(dynamic-call "init_math_bessel" bessel-lib)
|
||||||
|
(j0 2)
|
||||||
|
@result{} 0.223890779141236
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
The filename @file{./libbessel.so} should be pointing to the shared
|
||||||
|
library produced with the @code{gcc} command above, of course. The
|
||||||
|
second line of the Guile interaction will call the
|
||||||
|
@code{init_math_bessel} function which in turn will register the C
|
||||||
|
function @code{j0_wrapper} with the Guile interpreter under the name
|
||||||
|
@code{j0}. This function becomes immediately available and we can call
|
||||||
|
it from Scheme.
|
||||||
|
|
||||||
|
Fun, isn't it? But we are only half way there. This is what
|
||||||
|
@code{apropos} has to say about @code{j0}:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
(apropos 'j0)
|
||||||
|
@print{} the-root-module: j0 #<primitive-procedure j0>
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
As you can see, @code{j0} is contained in the root module, where all
|
||||||
|
the other Guile primitives like @code{display}, etc live. In general,
|
||||||
|
a primitive is put into whatever module is the @dfn{current module} at
|
||||||
|
the time @code{gh_new_procedure} is called. To put @code{j0} into its
|
||||||
|
own module named @samp{(math bessel)}, we need to make a call to
|
||||||
|
@code{scm_register_module_xxx}. Additionally, to have Guile perform
|
||||||
|
the dynamic linking automatically, we need to put @file{libbessel.so}
|
||||||
|
into a place where Guile can find it. The call to
|
||||||
|
@code{scm_register_module_xxx} should be contained in a specially
|
||||||
|
named @dfn{module init function}. Guile knows about this special name
|
||||||
|
and will call that function automatically after having linked in the
|
||||||
|
shared library. For our example, we add the following code to
|
||||||
|
@file{bessel.c}:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
void scm_init_math_bessel_module ()
|
||||||
|
@{
|
||||||
|
scm_register_module_xxx ("math bessel", init_math_bessel);
|
||||||
|
@}
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The general pattern for the name of a module init function is:
|
||||||
|
@samp{scm_init_}, followed by the name of the module where the
|
||||||
|
individual hierarchical components are concatenated with underscores,
|
||||||
|
followed by @samp{_module}. It should call
|
||||||
|
@code{scm_register_module_xxx} with the correct module name and the
|
||||||
|
appropriate initialization function. When that initialization function
|
||||||
|
will be called, a newly created module with the right name will be the
|
||||||
|
@emph{current module} so that all definitions that the initialization
|
||||||
|
functions makes will end up in the correct module.
|
||||||
|
|
||||||
|
After @file{libbessel.so} has been rebuild, we need to place the shared
|
||||||
|
library into the right place. When Guile tries to autoload the
|
||||||
|
@samp{(math bessel)} module, it looks not only for a file called
|
||||||
|
@file{math/bessel.scm} in its @code{%load-path}, but also for
|
||||||
|
@file{math/libbessel.so}. So all we need to do is to create a directory
|
||||||
|
called @file{math} somewhere in Guile's @code{%load-path} and place
|
||||||
|
@file{libbessel.so} there. Normally, the current directory @file{.} is
|
||||||
|
in the @code{%load-path}, so we just use that for this example.
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
% mkdir maths
|
||||||
|
% cd maths
|
||||||
|
% ln -s ../libbessel.so .
|
||||||
|
% cd ..
|
||||||
|
% guile
|
||||||
|
guile> (use-modules (math bessel))
|
||||||
|
guile> (j0 2)
|
||||||
|
0.223890779141236
|
||||||
|
guile> (apropos 'j0)
|
||||||
|
@print{} bessel: j0 #<primitive-procedure j0>
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
That's it!
|
||||||
|
|
||||||
|
Note that we used a symlink to make @file{libbessel.so} appear in the
|
||||||
|
right spot. This is probably not a bad idea in general. The
|
||||||
|
directories that the @file{%load-path} normally contains are supposed to
|
||||||
|
contain only architecture independent files. They are not really the
|
||||||
|
right place for a shared library. You might want to install the
|
||||||
|
libraries somewhere below @samp{exec_prefix} and then symlink to them
|
||||||
|
from the architecture independent directory. This will at least work on
|
||||||
|
heterogenous systems where the architecture dependent stuff resides in
|
||||||
|
the same place on all machines (which seems like a good idea to me
|
||||||
|
anyway).
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
337
doc/scheme-options.texi
Normal file
337
doc/scheme-options.texi
Normal file
|
@ -0,0 +1,337 @@
|
||||||
|
@page
|
||||||
|
@node Options and Config
|
||||||
|
@chapter Runtime Options and Configuration
|
||||||
|
|
||||||
|
Guile's behaviour can be modified by setting options. For example, is
|
||||||
|
the language that Guile accepts case sensitive, or should the debugger
|
||||||
|
automatically show a backtrace on error?
|
||||||
|
|
||||||
|
Guile has two levels of interface for managing options: a low-level
|
||||||
|
control interface, and a user-level interface which allows the enabling
|
||||||
|
or disabling of options.
|
||||||
|
|
||||||
|
Moreover, the options are classified in groups according to whether they
|
||||||
|
configure @emph{reading}, @emph{printing}, @emph{debugging} or
|
||||||
|
@emph{evaluating}.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* General option interface::
|
||||||
|
* Reader options::
|
||||||
|
* Printing options::
|
||||||
|
* Debugger options::
|
||||||
|
* Evaluator options::
|
||||||
|
* Examples of option use::
|
||||||
|
* Install Config:: Installation and configuration data.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node General option interface
|
||||||
|
@section General option interface
|
||||||
|
|
||||||
|
We will use the expression @code{<group>} to represent @code{read},
|
||||||
|
@code{print}, @code{debug} or @code{evaluator}.
|
||||||
|
|
||||||
|
@subheading Low level
|
||||||
|
|
||||||
|
@c NJFIXME
|
||||||
|
@deffn primitive <group>-options-interface
|
||||||
|
@deffnx primitive read-options-interface [SOME-INT]
|
||||||
|
@deffnx primitive print-options-interface [SOME-INT]
|
||||||
|
@deffnx primitive evaluator-traps-interface [SOME-INT]
|
||||||
|
@deffnx primitive read-options-interface [SOME-INT]
|
||||||
|
[FIXME: I have just taken the comments for C routine scm_options that
|
||||||
|
implements all of these. It needs to be presented better.]
|
||||||
|
|
||||||
|
If scm_options is called without arguments, the current option setting
|
||||||
|
is returned. If the argument is an option setting, options are altered
|
||||||
|
and the old setting is returned. If the argument isn't a list, a list
|
||||||
|
of sublists is returned, where each sublist contains option name, value
|
||||||
|
and documentation string.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@subheading User level
|
||||||
|
|
||||||
|
@c @deftp {Data type} scm_option
|
||||||
|
@c @code{scm_option} is used to represent run time options. It can be a
|
||||||
|
@c @emph{boolean} type, in which case the option will be set by the strings
|
||||||
|
@c @code{"yes"} and @code{"no"}. It can be a
|
||||||
|
@c @end deftp
|
||||||
|
|
||||||
|
@c NJFIXME
|
||||||
|
@deffn procedure <group>-options [arg]
|
||||||
|
@deffnx procedure read-options [arg]
|
||||||
|
@deffnx procedure print-options [arg]
|
||||||
|
@deffnx procedure debug-options [arg]
|
||||||
|
@deffnx procedure traps [arg]
|
||||||
|
These functions list the options in their group. The optional argument
|
||||||
|
@var{arg} is a symbol which modifies the form in which the options are
|
||||||
|
presented.
|
||||||
|
|
||||||
|
With no arguments, @code{<group>-options} returns the values of the
|
||||||
|
options in that particular group. If @var{arg} is @code{'help}, a
|
||||||
|
description of each option is given. If @var{arg} is @code{'full},
|
||||||
|
programmers' options are also shown.
|
||||||
|
|
||||||
|
@var{arg} can also be a list representing the state of all options. In
|
||||||
|
this case, the list contains single symbols (for enabled boolean
|
||||||
|
options) and symbols followed by values.
|
||||||
|
@end deffn
|
||||||
|
[FIXME: I don't think 'full is ever any different from 'help. What's
|
||||||
|
up?]
|
||||||
|
|
||||||
|
@c NJFIXME
|
||||||
|
@deffn procedure <group>-enable option-symbol
|
||||||
|
@deffnx procedure read-enable option-symbol
|
||||||
|
@deffnx procedure print-enable option-symbol
|
||||||
|
@deffnx procedure debug-enable option-symbol
|
||||||
|
@deffnx procedure trap-enable option-symbol
|
||||||
|
These functions set the specified @var{option-symbol} in their options
|
||||||
|
group. They only work if the option is boolean, and throw an error
|
||||||
|
otherwise.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c NJFIXME
|
||||||
|
@deffn procedure <group>-disable option-symbol
|
||||||
|
@deffnx procedure read-disable option-symbol
|
||||||
|
@deffnx procedure print-disable option-symbol
|
||||||
|
@deffnx procedure debug-disable option-symbol
|
||||||
|
@deffnx procedure trap-disable option-symbol
|
||||||
|
These functions turn off the specified @var{option-symbol} in their
|
||||||
|
options group. They only work if the option is boolean, and throw an
|
||||||
|
error otherwise.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c NJFIXME
|
||||||
|
@deffn syntax <group>-set! option-symbol value
|
||||||
|
@deffnx syntax read-set! option-symbol value
|
||||||
|
@deffnx syntax print-set! option-symbol value
|
||||||
|
@deffnx syntax debug-set! option-symbol value
|
||||||
|
@deffnx syntax trap-set! option-symbol value
|
||||||
|
These functions set a non-boolean @var{option-symbol} to the specified
|
||||||
|
@var{value}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Reader options
|
||||||
|
@section Reader options
|
||||||
|
@cindex options - read
|
||||||
|
@cindex read options
|
||||||
|
|
||||||
|
Here is the list of reader options generated by typing
|
||||||
|
@code{(read-options 'full)} in Guile. You can also see the default
|
||||||
|
values.
|
||||||
|
@smalllisp
|
||||||
|
keywords #f Style of keyword recognition: #f or 'prefix
|
||||||
|
case-insensitive no Convert symbols to lower case.
|
||||||
|
positions yes Record positions of source code expressions.
|
||||||
|
copy no Copy source code expressions.
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
Notice that while Standard Scheme is case insensitive, to ease
|
||||||
|
translation of other Lisp dialects, notably Emacs Lisp, into Guile,
|
||||||
|
Guile is case-sensitive by default.
|
||||||
|
|
||||||
|
To make Guile case insensitive, you can type
|
||||||
|
@smalllisp
|
||||||
|
(read-enable 'case-insensitive)
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
@node Printing options
|
||||||
|
@section Printing options
|
||||||
|
|
||||||
|
Here is the list of print options generated by typing
|
||||||
|
@code{(print-options 'full)} in Guile. You can also see the default
|
||||||
|
values.
|
||||||
|
@smallexample
|
||||||
|
source no Print closures with source.
|
||||||
|
closure-hook #f Hook for printing closures.
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
|
||||||
|
@node Evaluator options
|
||||||
|
@section Evaluator options
|
||||||
|
|
||||||
|
Here is the list of print options generated by typing
|
||||||
|
@code{(traps 'full)} in Guile. You can also see the default
|
||||||
|
values.
|
||||||
|
@smallexample
|
||||||
|
exit-frame no Trap when exiting eval or apply.
|
||||||
|
apply-frame no Trap when entering apply.
|
||||||
|
enter-frame no Trap when eval enters new frame.
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
|
||||||
|
@node Debugger options
|
||||||
|
@section Debugger options
|
||||||
|
|
||||||
|
Here is the list of print options generated by typing
|
||||||
|
@code{(debug-options 'full)} in Guile. You can also see the default
|
||||||
|
values.
|
||||||
|
@smallexample
|
||||||
|
stack 20000 Stack size limit (0 = no check).
|
||||||
|
debug yes Use the debugging evaluator.
|
||||||
|
backtrace no Show backtrace on error.
|
||||||
|
depth 20 Maximal length of printed backtrace.
|
||||||
|
maxdepth 1000 Maximal number of stored backtrace frames.
|
||||||
|
frames 3 Maximum number of tail-recursive frames in backtrace.
|
||||||
|
indent 10 Maximal indentation in backtrace.
|
||||||
|
backwards no Display backtrace in anti-chronological order.
|
||||||
|
procnames yes Record procedure names at definition.
|
||||||
|
trace no *Trace mode.
|
||||||
|
breakpoints no *Check for breakpoints.
|
||||||
|
cheap yes *Flyweight representation of the stack at traps.
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
|
||||||
|
@node Examples of option use
|
||||||
|
@section Examples of option use
|
||||||
|
|
||||||
|
Here is an example of a session in which some read and debug option
|
||||||
|
handling procedures are used. In this example, the user
|
||||||
|
|
||||||
|
@enumerate
|
||||||
|
@item
|
||||||
|
Notices that the symbols @code{abc} and @code{aBc} are not the same
|
||||||
|
@item
|
||||||
|
Examines the @code{read-options}, and sees that @code{case-insensitive}
|
||||||
|
is set to ``no''.
|
||||||
|
@item
|
||||||
|
Enables @code{case-insensitive}
|
||||||
|
@item
|
||||||
|
Verifies that now @code{aBc} and @code{abc} are the same
|
||||||
|
@item
|
||||||
|
Disables @code{case-insensitive} and enables debugging @code{backtrace}
|
||||||
|
@item
|
||||||
|
Reproduces the error of displaying @code{aBc} with backtracing enabled
|
||||||
|
[FIXME: this last example is lame because there is no depth in the
|
||||||
|
backtrace. Need to give a better example, possibly putting debugging
|
||||||
|
option examples in a separate session.]
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
guile> (define abc "hello")
|
||||||
|
guile> abc
|
||||||
|
"hello"
|
||||||
|
guile> aBc
|
||||||
|
ERROR: In expression aBc:
|
||||||
|
ERROR: Unbound variable: aBc
|
||||||
|
ABORT: (misc-error)
|
||||||
|
|
||||||
|
Type "(backtrace)" to get more information.
|
||||||
|
guile> (read-options 'help)
|
||||||
|
keywords #f Style of keyword recognition: #f or 'prefix
|
||||||
|
case-insensitive no Convert symbols to lower case.
|
||||||
|
positions yes Record positions of source code expressions.
|
||||||
|
copy no Copy source code expressions.
|
||||||
|
guile> (debug-options 'help)
|
||||||
|
stack 20000 Stack size limit (0 = no check).
|
||||||
|
debug yes Use the debugging evaluator.
|
||||||
|
backtrace no Show backtrace on error.
|
||||||
|
depth 20 Maximal length of printed backtrace.
|
||||||
|
maxdepth 1000 Maximal number of stored backtrace frames.
|
||||||
|
frames 3 Maximum number of tail-recursive frames in backtrace.
|
||||||
|
indent 10 Maximal indentation in backtrace.
|
||||||
|
backwards no Display backtrace in anti-chronological order.
|
||||||
|
procnames yes Record procedure names at definition.
|
||||||
|
trace no *Trace mode.
|
||||||
|
breakpoints no *Check for breakpoints.
|
||||||
|
cheap yes *Flyweight representation of the stack at traps.
|
||||||
|
guile> (read-enable 'case-insensitive)
|
||||||
|
(keywords #f case-insensitive positions)
|
||||||
|
guile> aBc
|
||||||
|
"hello"
|
||||||
|
guile> (read-disable 'case-insensitive)
|
||||||
|
(keywords #f positions)
|
||||||
|
guile> (debug-enable 'backtrace)
|
||||||
|
(stack 20000 debug backtrace depth 20 maxdepth 1000 frames 3 indent 10 procnames cheap)
|
||||||
|
guile> aBc
|
||||||
|
|
||||||
|
Backtrace:
|
||||||
|
0* aBc
|
||||||
|
|
||||||
|
ERROR: In expression aBc:
|
||||||
|
ERROR: Unbound variable: aBc
|
||||||
|
ABORT: (misc-error)
|
||||||
|
guile>
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
|
||||||
|
@node Install Config
|
||||||
|
@section Installation and Configuration Data
|
||||||
|
|
||||||
|
It is often useful to have site-specific information about the current
|
||||||
|
Guile installation. This chapter describes how to find out about
|
||||||
|
Guile's configuration at run time.
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "version")
|
||||||
|
@c docstring begin (texi-doc-string "guile" "major-version")
|
||||||
|
@c docstring begin (texi-doc-string "guile" "minor-version")
|
||||||
|
@deffn primitive version
|
||||||
|
@deffnx primitive major-version
|
||||||
|
@deffnx primitive minor-version
|
||||||
|
Return a string describing Guile's version number, or its major or minor
|
||||||
|
version numbers, respectively.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(version) @result{} "1.3a"
|
||||||
|
(major-version) @result{} "1"
|
||||||
|
(minor-version) @result{} "3a"
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c NJFIXME not in libguile!
|
||||||
|
@deffn primitive libguile-config-stamp
|
||||||
|
Return a string describing the date on which @code{libguile} was
|
||||||
|
configured. This is used to determine whether the Guile core
|
||||||
|
interpreter and the ice-9 runtime have grown out of date with one
|
||||||
|
another.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "%package-data-dir")
|
||||||
|
@deffn primitive %package-data-dir
|
||||||
|
Return the name of the directory where Scheme packages, modules and
|
||||||
|
libraries are kept. On most Unix systems, this will be
|
||||||
|
@samp{/usr/local/share/guile}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "%library-dir")
|
||||||
|
@deffn primitive %library-dir
|
||||||
|
Return the directory where the Guile Scheme library files are installed.
|
||||||
|
E.g., may return "/usr/share/guile/1.3.5".
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "%site-dir")
|
||||||
|
@deffn primitive %site-dir
|
||||||
|
Return the directory where the Guile site files are installed.
|
||||||
|
E.g., may return "/usr/share/guile/site".
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "parse-path")
|
||||||
|
@deffn primitive parse-path path [tail]
|
||||||
|
Parse @var{path}, which is expected to be a colon-separated
|
||||||
|
string, into a list and return the resulting list with
|
||||||
|
@var{tail} appended. If @var{path} is @code{#f}, @var{tail}
|
||||||
|
is returned.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "search-path")
|
||||||
|
@deffn primitive search-path path filename [extensions]
|
||||||
|
Search @var{path} for a directory containing a file named
|
||||||
|
@var{filename}. The file must be readable, and not a directory.
|
||||||
|
If we find one, return its full filename; otherwise, return
|
||||||
|
@code{#f}. If @var{filename} is absolute, return it unchanged.
|
||||||
|
If given, @var{extensions} is a list of strings; for each
|
||||||
|
directory in @var{path}, we search for @var{filename}
|
||||||
|
concatenated with each @var{extension}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@defvar %load-path
|
||||||
|
Return the list of directories which should be searched for Scheme
|
||||||
|
modules and libraries.
|
||||||
|
@end defvar
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
206
doc/scheme-procedures.texi
Normal file
206
doc/scheme-procedures.texi
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
@page
|
||||||
|
@node Procedures and Macros
|
||||||
|
@chapter Procedures and Macros
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Lambda:: Basic procedure creation using lambda.
|
||||||
|
* Optional Arguments:: Handling keyword, optional and rest arguments.
|
||||||
|
* Procedure Properties:: Procedure properties and metainformation.
|
||||||
|
* Procedures with Setters:: Procedures with setters.
|
||||||
|
* Macros:: Macros.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Lambda
|
||||||
|
@section Lambda: Basic Procedure Creation
|
||||||
|
|
||||||
|
|
||||||
|
@node Optional Arguments
|
||||||
|
@section Optional Arguments
|
||||||
|
|
||||||
|
|
||||||
|
@node Procedure Properties
|
||||||
|
@section Procedure Properties and Metainformation
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure-properties")
|
||||||
|
@deffn primitive procedure-properties proc
|
||||||
|
Return @var{obj}'s property list.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure-property")
|
||||||
|
@deffn primitive procedure-property p k
|
||||||
|
Return the property of @var{obj} with name @var{key}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-procedure-properties!")
|
||||||
|
@deffn primitive set-procedure-properties! proc new_val
|
||||||
|
Set @var{obj}'s property list to @var{alist}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-procedure-property!")
|
||||||
|
@deffn primitive set-procedure-property! p k v
|
||||||
|
In @var{obj}'s property list, set the property named @var{key} to
|
||||||
|
@var{value}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure-documentation")
|
||||||
|
@deffn primitive procedure-documentation proc
|
||||||
|
Return the documentation string associated with @code{proc}. By
|
||||||
|
convention, if a procedure contains more than one expression and the
|
||||||
|
first expression is a string constant, that string is assumed to contain
|
||||||
|
documentation for that procedure.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "closure?")
|
||||||
|
@deffn primitive closure? obj
|
||||||
|
Return @code{#t} if @var{obj} is a closure.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure?")
|
||||||
|
@deffn primitive procedure? obj
|
||||||
|
Return @code{#t} if @var{obj} is a procedure.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "thunk?")
|
||||||
|
@deffn primitive thunk? obj
|
||||||
|
Return @code{#t} if @var{obj} is a thunk.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-source-properties!")
|
||||||
|
@deffn primitive set-source-properties! obj plist
|
||||||
|
Install the association list @var{plist} as the source property
|
||||||
|
list for @var{obj}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-source-property!")
|
||||||
|
@deffn primitive set-source-property! obj key datum
|
||||||
|
Set the source property of object @var{obj}, which is specified by
|
||||||
|
@var{key} to @var{datum}. Normally, the key will be a symbol.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "source-properties")
|
||||||
|
@deffn primitive source-properties obj
|
||||||
|
Return the source property association list of @var{obj}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "source-property")
|
||||||
|
|
||||||
|
@deffn primitive source-property obj key
|
||||||
|
Return the source property specified by @var{key} from
|
||||||
|
@var{obj}'s source property list.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Procedures with Setters
|
||||||
|
@section Procedures with Setters
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-procedure-with-setter")
|
||||||
|
@deffn primitive make-procedure-with-setter procedure setter
|
||||||
|
Create a new procedure which behaves like @var{procedure}, but
|
||||||
|
with the associated setter @var{setter}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure-with-setter?")
|
||||||
|
@deffn primitive procedure-with-setter? obj
|
||||||
|
Return @code{#t} if @var{obj} is a procedure with an
|
||||||
|
associated setter procedure.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure")
|
||||||
|
@deffn primitive procedure proc
|
||||||
|
Return the procedure of @var{proc}, which must be either a
|
||||||
|
procedure with setter, or an operator struct.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "setter")
|
||||||
|
@deffn primitive setter proc
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Macros
|
||||||
|
@section Macros
|
||||||
|
|
||||||
|
[FIXME: This needs some more text on the difference between procedures,
|
||||||
|
macros and memoizing macros. Also, any definitions listed here should
|
||||||
|
be double-checked by someone who knows what's going on. Ask Mikael, Jim
|
||||||
|
or Aubrey for help. -twp]
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure->syntax")
|
||||||
|
@deffn primitive procedure->syntax code
|
||||||
|
Returns a @dfn{macro} which, when a symbol defined to this value
|
||||||
|
appears as the first symbol in an expression, returns the result
|
||||||
|
of applying @var{code} to the expression and the environment.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure->macro")
|
||||||
|
@deffn primitive procedure->macro code
|
||||||
|
Returns a @dfn{macro} which, when a symbol defined to this value
|
||||||
|
appears as the first symbol in an expression, evaluates the result
|
||||||
|
of applying @var{code} to the expression and the environment.
|
||||||
|
The value returned from @var{code} which has been passed to
|
||||||
|
@code{procedure->memoizing-macro} replaces the form passed to
|
||||||
|
@var{code}. For example:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(define trace
|
||||||
|
(procedure->macro
|
||||||
|
(lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x))))))
|
||||||
|
|
||||||
|
(trace @i{foo}) @equiv{} (set! @i{foo} (tracef @i{foo} '@i{foo})).
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "procedure->memoizing-macro")
|
||||||
|
@deffn primitive procedure->memoizing-macro code
|
||||||
|
Returns a @dfn{macro} which, when a symbol defined to this value
|
||||||
|
appears as the first symbol in an expression, evaluates the result
|
||||||
|
of applying @var{proc} to the expression and the environment.
|
||||||
|
The value returned from @var{proc} which has been passed to
|
||||||
|
@code{procedure->memoizing-macro} replaces the form passed to
|
||||||
|
@var{proc}. For example:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(define trace
|
||||||
|
(procedure->macro
|
||||||
|
(lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x))))))
|
||||||
|
|
||||||
|
(trace @i{foo}) @equiv{} (set! @i{foo} (tracef @i{foo} '@i{foo})).
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "macro?")
|
||||||
|
@deffn primitive macro? obj
|
||||||
|
Return @code{#t} if @var{obj} is a regular macro, a memoizing macro or a
|
||||||
|
syntax transformer.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME m/obj
|
||||||
|
@c docstring begin (texi-doc-string "guile" "macro-type")
|
||||||
|
@deffn primitive macro-type m
|
||||||
|
Return one of the symbols @code{syntax}, @code{macro} or @code{macro!},
|
||||||
|
depending on whether @var{obj} is a syntax tranformer, a regular macro,
|
||||||
|
or a memoizing macro, respectively. If @var{obj} is not a macro,
|
||||||
|
@code{#f} is returned.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "macro-name")
|
||||||
|
@deffn primitive macro-name m
|
||||||
|
Return the name of the macro @var{m}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "macro-transformer")
|
||||||
|
@deffn primitive macro-transformer m
|
||||||
|
Return the transformer of the macro @var{m}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "cons-source")
|
||||||
|
@deffn primitive cons-source xorig x y
|
||||||
|
Create and return a new pair whose car and cdr are @var{x} and @var{y}.
|
||||||
|
Any source properties associated with @var{xorig} are also associated
|
||||||
|
with the new pair.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
27
doc/scheme-reading.texi
Normal file
27
doc/scheme-reading.texi
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
@page
|
||||||
|
@node Further Reading
|
||||||
|
@chapter Further Reading
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
Dorai Sitaram's online Scheme tutorial, @dfn{Teach Yourself Scheme in
|
||||||
|
Fixnum Days}, at
|
||||||
|
http://www.cs.rice.edu/~dorai/t-y-scheme/t-y-scheme.html. Includes a
|
||||||
|
nice explanation of continuations.
|
||||||
|
|
||||||
|
@item
|
||||||
|
http://wombat.doc.ic.ac.uk/foldoc/.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The complete text of @dfn{Structure and Interpretation of Computer
|
||||||
|
Programs}, the classic introduction to computer science and Scheme by
|
||||||
|
Hal Abelson, Jerry Sussman and Julie Sussman, is now available online at
|
||||||
|
http://mitpress.mit.edu/sicp/sicp.html. This site also provides
|
||||||
|
teaching materials related to the book, and all the source code used in
|
||||||
|
the book, in a form suitable for loading and running.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
381
doc/scheme-scheduling.texi
Normal file
381
doc/scheme-scheduling.texi
Normal file
|
@ -0,0 +1,381 @@
|
||||||
|
@page
|
||||||
|
@node Scheduling
|
||||||
|
@chapter Threads, Mutexes, Asyncs and Dynamic Roots
|
||||||
|
|
||||||
|
[FIXME: This is pasted in from Tom Lord's original guile.texi chapter
|
||||||
|
plus the Cygnus programmer's manual; it should be *very* carefully
|
||||||
|
reviewed and largely reorganized.]
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Arbiters::
|
||||||
|
* Asyncs::
|
||||||
|
* Dynamic Roots::
|
||||||
|
* Threads::
|
||||||
|
* Fluids::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Arbiters
|
||||||
|
@section Arbiters
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-arbiter")
|
||||||
|
@deffn primitive make-arbiter name
|
||||||
|
Return an object of type arbiter and name @var{name}. Its
|
||||||
|
state is initially unlocked. Arbiters are a way to achieve
|
||||||
|
process synchronization.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "try-arbiter")
|
||||||
|
@deffn primitive try-arbiter arb
|
||||||
|
Return @code{#t} and lock the arbiter @var{arb} if the arbiter
|
||||||
|
was unlocked. Otherwise, return @code{#f}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "release-arbiter")
|
||||||
|
@deffn primitive release-arbiter arb
|
||||||
|
Return @code{#t} and unlock the arbiter @var{arb} if the
|
||||||
|
arbiter was locked. Otherwise, return @code{#f}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Asyncs
|
||||||
|
@section Asyncs
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "async")
|
||||||
|
@deffn primitive async thunk
|
||||||
|
Create a new async for the procedure @var{thunk}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "system-async")
|
||||||
|
@deffn primitive system-async thunk
|
||||||
|
Create a new async for the procedure @var{thunk}. Also
|
||||||
|
add it to the system's list of active async objects.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "async-mark")
|
||||||
|
@deffn primitive async-mark a
|
||||||
|
Mark the async @var{a} for future execution.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "system-async-mark")
|
||||||
|
@deffn primitive system-async-mark a
|
||||||
|
Mark the async @var{a} for future execution.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "run-asyncs")
|
||||||
|
@deffn primitive run-asyncs list_of_a
|
||||||
|
Execute all thunks from the asyncs of the list @var{list_of_a}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "noop")
|
||||||
|
@deffn primitive noop . args
|
||||||
|
Do nothing. When called without arguments, return @code{#f},
|
||||||
|
otherwise return the first argument.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "unmask-signals")
|
||||||
|
@deffn primitive unmask-signals
|
||||||
|
Unmask signals. The returned value is not specified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "mask-signals")
|
||||||
|
@deffn primitive mask-signals
|
||||||
|
Mask signals. The returned value is not specified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Dynamic Roots
|
||||||
|
@section Dynamic Roots
|
||||||
|
@cindex dynamic roots
|
||||||
|
|
||||||
|
A @dfn{dynamic root} is a root frame of Scheme evaluation.
|
||||||
|
The top-level repl, for example, is an instance of a dynamic root.
|
||||||
|
|
||||||
|
Each dynamic root has its own chain of dynamic-wind information. Each
|
||||||
|
has its own set of continuations, jump-buffers, and pending CATCH
|
||||||
|
statements which are inaccessible from the dynamic scope of any
|
||||||
|
other dynamic root.
|
||||||
|
|
||||||
|
In a thread-based system, each thread has its own dynamic root. Therefore,
|
||||||
|
continuations created by one thread may not be invoked by another.
|
||||||
|
|
||||||
|
Even in a single-threaded system, it is sometimes useful to create a new
|
||||||
|
dynamic root. For example, if you want to apply a procedure, but to
|
||||||
|
not allow that procedure to capture the current continuation, calling
|
||||||
|
the procedure under a new dynamic root will do the job.
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "call-with-dynamic-root")
|
||||||
|
@deffn primitive call-with-dynamic-root thunk handler
|
||||||
|
Evaluate @code{(thunk)} in a new dynamic context, returning its value.
|
||||||
|
|
||||||
|
If an error occurs during evaluation, apply @var{handler} to the
|
||||||
|
arguments to the throw, just as @code{throw} would. If this happens,
|
||||||
|
@var{handler} is called outside the scope of the new root -- it is
|
||||||
|
called in the same dynamic context in which
|
||||||
|
@code{call-with-dynamic-root} was evaluated.
|
||||||
|
|
||||||
|
If @var{thunk} captures a continuation, the continuation is rooted at
|
||||||
|
the call to @var{thunk}. In particular, the call to
|
||||||
|
@code{call-with-dynamic-root} is not captured. Therefore,
|
||||||
|
@code{call-with-dynamic-root} always returns at most one time.
|
||||||
|
|
||||||
|
Before calling @var{thunk}, the dynamic-wind chain is un-wound back to
|
||||||
|
the root and a new chain started for @var{thunk}. Therefore, this call
|
||||||
|
may not do what you expect:
|
||||||
|
|
||||||
|
@example
|
||||||
|
;; Almost certainly a bug:
|
||||||
|
(with-output-to-port
|
||||||
|
some-port
|
||||||
|
|
||||||
|
(lambda ()
|
||||||
|
(call-with-dynamic-root
|
||||||
|
(lambda ()
|
||||||
|
(display 'fnord)
|
||||||
|
(newline))
|
||||||
|
(lambda (errcode) errcode))))
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The problem is, on what port will @samp{fnord} be displayed? You
|
||||||
|
might expect that because of the @code{with-output-to-port} that
|
||||||
|
it will be displayed on the port bound to @code{some-port}. But it
|
||||||
|
probably won't -- before evaluating the thunk, dynamic winds are
|
||||||
|
unwound, including those created by @code{with-output-to-port}.
|
||||||
|
So, the standard output port will have been re-set to its default value
|
||||||
|
before @code{display} is evaluated.
|
||||||
|
|
||||||
|
(This function was added to Guile mostly to help calls to functions in C
|
||||||
|
libraries that can not tolerate non-local exits or calls that return
|
||||||
|
multiple times. If such functions call back to the interpreter, it should
|
||||||
|
be under a new dynamic root.)
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "dynamic-root")
|
||||||
|
@deffn primitive dynamic-root
|
||||||
|
Return an object representing the current dynamic root.
|
||||||
|
|
||||||
|
These objects are only useful for comparison using @code{eq?}.
|
||||||
|
They are currently represented as numbers, but your code should
|
||||||
|
in no way depend on this.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "quit")
|
||||||
|
@deffn procedure quit [exit_val]
|
||||||
|
Throw back to the error handler of the current dynamic root.
|
||||||
|
|
||||||
|
If integer @var{exit_val} is specified and if Guile is being used
|
||||||
|
stand-alone and if quit is called from the initial dynamic-root,
|
||||||
|
@var{exit_val} becomes the exit status of the Guile process and the
|
||||||
|
process exits.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
When Guile is run interactively, errors are caught from within the
|
||||||
|
read-eval-print loop. An error message will be printed and @code{abort}
|
||||||
|
called. A default set of signal handlers is installed, e.g., to allow
|
||||||
|
user interrupt of the interpreter.
|
||||||
|
|
||||||
|
It is possible to switch to a "batch mode", in which the interpreter
|
||||||
|
will terminate after an error and in which all signals cause their
|
||||||
|
default actions. Switching to batch mode causes any handlers installed
|
||||||
|
from Scheme code to be removed. An example of where this is useful is
|
||||||
|
after forking a new process intended to run non-interactively.
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "batch-mode?")
|
||||||
|
@deffn procedure batch-mode?
|
||||||
|
Returns a boolean indicating whether the interpreter is in batch mode.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (scm-doc-string "boot-9.scm" "set-batch-mode?!")
|
||||||
|
@deffn procedure set-batch-mode?! arg
|
||||||
|
If @var{arg} is true, switches the interpreter to batch mode.
|
||||||
|
The @code{#f} case has not been implemented.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@node Threads
|
||||||
|
@section Threads
|
||||||
|
@cindex threads
|
||||||
|
@cindex Guile threads
|
||||||
|
|
||||||
|
@strong{[NOTE: this chapter was written for Cygnus Guile and has not yet
|
||||||
|
been updated for the Guile 1.x release.]}
|
||||||
|
|
||||||
|
Here is a the reference for Guile's threads. In this chapter I simply
|
||||||
|
quote verbatim Tom Lord's description of the low-level primitives
|
||||||
|
written in C (basically an interface to the POSIX threads library) and
|
||||||
|
Anthony Green's description of the higher-level thread procedures
|
||||||
|
written in scheme.
|
||||||
|
@cindex posix threads
|
||||||
|
@cindex Lord, Tom
|
||||||
|
@cindex Green, Anthony
|
||||||
|
|
||||||
|
When using Guile threads, keep in mind that each guile thread is
|
||||||
|
executed in a new dynamic root.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Low level thread primitives::
|
||||||
|
* Higher level thread procedures::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Low level thread primitives
|
||||||
|
@subsection Low level thread primitives
|
||||||
|
|
||||||
|
@c NJFIXME no current mechanism for making sure that these docstrings
|
||||||
|
@c are in sync.
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "call-with-new-thread")
|
||||||
|
@deffn primitive call-with-new-thread thunk error-thunk
|
||||||
|
Evaluate @code{(thunk)} in a new thread, and new dynamic context,
|
||||||
|
returning a new thread object representing the thread.
|
||||||
|
|
||||||
|
If an error occurs during evaluation, call error-thunk, passing it an
|
||||||
|
error code describing the condition. [Error codes are currently
|
||||||
|
meaningless integers. In the future, real values will be specified.]
|
||||||
|
If this happens, the error-thunk is called outside the scope of the new
|
||||||
|
root -- it is called in the same dynamic context in which
|
||||||
|
with-new-thread was evaluated, but not in the callers thread.
|
||||||
|
|
||||||
|
All the evaluation rules for dynamic roots apply to threads.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "join-thread")
|
||||||
|
@deffn primitive join-thread thread
|
||||||
|
Suspend execution of the calling thread until the target @var{thread}
|
||||||
|
terminates, unless the target @var{thread} has already terminated.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "yield")
|
||||||
|
@deffn primitive yield
|
||||||
|
If one or more threads are waiting to execute, calling yield forces an
|
||||||
|
immediate context switch to one of them. Otherwise, yield has no effect.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "make-mutex")
|
||||||
|
@deffn primitive make-mutex
|
||||||
|
Create a new mutex object.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "lock-mutex")
|
||||||
|
@deffn primitive lock-mutex mutex
|
||||||
|
Lock @var{mutex}. If the mutex is already locked, the calling thread
|
||||||
|
blocks until the mutex becomes available. The function returns when
|
||||||
|
the calling thread owns the lock on @var{mutex}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "unlock-mutex")
|
||||||
|
@deffn primitive unlock-mutex mutex
|
||||||
|
Unlocks @var{mutex} if the calling thread owns the lock on @var{mutex}.
|
||||||
|
Calling unlock-mutex on a mutex not owned by the current thread results
|
||||||
|
in undefined behaviour. Once a mutex has been unlocked, one thread
|
||||||
|
blocked on @var{mutex} is awakened and grabs the mutex lock.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "make-condition-variable")
|
||||||
|
@deffn primitive make-condition-variable
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "wait-condition-variable")
|
||||||
|
@deffn primitive wait-condition-variable cond-var mutex
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "signal-condition-variable")
|
||||||
|
@deffn primitive signal-condition-variable cond-var
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Higher level thread procedures
|
||||||
|
@subsection Higher level thread procedures
|
||||||
|
|
||||||
|
@c NJFIXME the following doc is a repeat of the previous node!
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "call-with-new-thread")
|
||||||
|
@deffn primitive call-with-new-thread thunk error-thunk
|
||||||
|
Evaluate @code{(thunk)} in a new thread, and new dynamic context,
|
||||||
|
returning a new thread object representing the thread.
|
||||||
|
|
||||||
|
If an error occurs during evaluation, call error-thunk, passing it an
|
||||||
|
error code describing the condition. [Error codes are currently
|
||||||
|
meaningless integers. In the future, real values will be specified.]
|
||||||
|
If this happens, the error-thunk is called outside the scope of the new
|
||||||
|
root -- it is called in the same dynamic context in which
|
||||||
|
with-new-thread was evaluated, but not in the callers thread.
|
||||||
|
|
||||||
|
All the evaluation rules for dynamic roots apply to threads.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "join-thread")
|
||||||
|
@deffn primitive join-thread thread
|
||||||
|
Suspend execution of the calling thread until the target @var{thread}
|
||||||
|
terminates, unless the target @var{thread} has already terminated.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "yield")
|
||||||
|
@deffn primitive yield
|
||||||
|
If one or more threads are waiting to execute, calling yield forces an
|
||||||
|
immediate context switch to one of them. Otherwise, yield has no effect.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "make-mutex")
|
||||||
|
@deffn primitive make-mutex
|
||||||
|
Create a new mutex object.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c begin (texi-doc-string "guile" "lock-mutex")
|
||||||
|
@deffn primitive lock-mutex mutex
|
||||||
|
Lock @var{mutex}. If the mutex is already locked, the calling thread
|
||||||
|
blocks until the mutex becomes available. The function returns when
|
||||||
|
the calling thread owns the lock on @var{mutex}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "unlock-mutex")
|
||||||
|
@deffn primitive unlock-mutex mutex
|
||||||
|
Unlocks @var{mutex} if the calling thread owns the lock on @var{mutex}.
|
||||||
|
Calling unlock-mutex on a mutex not owned by the current thread results
|
||||||
|
in undefined behaviour. Once a mutex has been unlocked, one thread
|
||||||
|
blocked on @var{mutex} is awakened and grabs the mutex lock.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Fluids
|
||||||
|
@section Fluids
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "make-fluid")
|
||||||
|
@deffn primitive make-fluid
|
||||||
|
Return a newly created fluid.
|
||||||
|
Fluids are objects of a certain type (a smob) that can hold one SCM
|
||||||
|
value per dynamic root. That is, modifications to this value are
|
||||||
|
only visible to code that executes within the same dynamic root as
|
||||||
|
the modifying code. When a new dynamic root is constructed, it
|
||||||
|
inherits the values from its parent. Because each thread executes
|
||||||
|
in its own dynamic root, you can use fluids for thread local storage.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "fluid?")
|
||||||
|
@deffn primitive fluid? obj
|
||||||
|
Return #t iff @var{obj} is a fluid; otherwise, return #f.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "fluid-ref")
|
||||||
|
@deffn primitive fluid-ref fluid
|
||||||
|
Return the value associated with @var{fluid} in the current dynamic root.
|
||||||
|
If @var{fluid} has not been set, then this returns #f.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "fluid-set!")
|
||||||
|
@deffn primitive fluid-set! fluid value
|
||||||
|
Set the value associated with @var{fluid} in the current dynamic root.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "with-fluids*")
|
||||||
|
@deffn primitive with-fluids* fluids values thunk
|
||||||
|
Set @var{fluids} to @var{values} temporary, and call @var{thunk}.
|
||||||
|
@var{fluids} must be a list of fluids and @var{values} must be the same
|
||||||
|
number of their values to be applied. Each substitution is done
|
||||||
|
one after another. @var{thunk} must be a procedure with no argument.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
49
doc/scheme-translation.texi
Normal file
49
doc/scheme-translation.texi
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
@page
|
||||||
|
@node Translation
|
||||||
|
@chapter Support for Translating Other Languages
|
||||||
|
|
||||||
|
[Describe translation framework.]
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Emacs Lisp Support:: Helper primitives for Emacs Lisp.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Emacs Lisp Support
|
||||||
|
@section Emacs Lisp Support
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "nil-car")
|
||||||
|
@deffn primitive nil-car x
|
||||||
|
Return the car of @var{x}, but convert it to LISP nil if it
|
||||||
|
is Scheme's end-of-list.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "nil-cdr")
|
||||||
|
@deffn primitive nil-cdr x
|
||||||
|
Return the cdr of @var{x}, but convert it to LISP nil if it
|
||||||
|
is Scheme's end-of-list.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "nil-cons")
|
||||||
|
@deffn primitive nil-cons x y
|
||||||
|
Create a new cons cell with @var{x} as the car and @var{y} as
|
||||||
|
the cdr, but convert @var{y} to Scheme's end-of-list if it is
|
||||||
|
a LISP nil.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "nil-eq")
|
||||||
|
@deffn primitive nil-eq x y
|
||||||
|
Compare @var{x} and @var{y} and return LISP's t if they are
|
||||||
|
@code{eq?}, return LISP's nil otherwise.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "null")
|
||||||
|
@deffn primitive null x
|
||||||
|
Return LISP's @code{t} if @var{x} is nil in the LISP sense,
|
||||||
|
return LISP's nil otherwise.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
219
doc/scheme-utility.texi
Normal file
219
doc/scheme-utility.texi
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
@page
|
||||||
|
@node Utility Functions
|
||||||
|
@chapter General Utility Functions
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Equality:: When are two values `the same'?
|
||||||
|
* Property Lists:: Managing metainformation about Scheme objects.
|
||||||
|
* Primitive Properties:: A modern low-level interface to object properties.
|
||||||
|
* Sorting:: Sort utility procedures.
|
||||||
|
* Copying:: Copying deep structures.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Equality
|
||||||
|
@section Equality
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "eq?")
|
||||||
|
@deffn primitive eq? x y
|
||||||
|
Return @code{#t} iff @var{x} references the same object as @var{y}.
|
||||||
|
@code{eq?} is similar to @code{eqv?} except that in some cases it is
|
||||||
|
capable of discerning distinctions finer than those detectable by
|
||||||
|
@code{eqv?}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "eqv?")
|
||||||
|
@deffn primitive eqv? x y
|
||||||
|
The @code{eqv?} procedure defines a useful equivalence relation on objects.
|
||||||
|
Briefly, it returns @code{#t} if @var{x} and @var{y} should normally be
|
||||||
|
regarded as the same object. This relation is left slightly open to
|
||||||
|
interpretation, but works for comparing immediate integers, characters,
|
||||||
|
and inexact numbers.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "equal?")
|
||||||
|
@deffn primitive equal? x y
|
||||||
|
Return @code{#t} iff @var{x} and @var{y} are recursively @code{eqv?} equivalent.
|
||||||
|
@code{equal?} recursively compares the contents of pairs,
|
||||||
|
vectors, and strings, applying @code{eqv?} on other objects such as
|
||||||
|
numbers and symbols. A rule of thumb is that objects are generally
|
||||||
|
@code{equal?} if they print the same. @code{equal?} may fail to
|
||||||
|
terminate if its arguments are circular data structures.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Property Lists
|
||||||
|
@section Property Lists
|
||||||
|
|
||||||
|
Every object in the system can have a @dfn{property list} that may
|
||||||
|
be used for information about that object. For example, a
|
||||||
|
function may have a property list that includes information about
|
||||||
|
the source file in which it is defined.
|
||||||
|
|
||||||
|
Property lists are implemented as assq lists (@pxref{Association Lists}).
|
||||||
|
|
||||||
|
Currently, property lists are implemented differently for procedures and
|
||||||
|
closures than for other kinds of objects. Therefore, when manipulating
|
||||||
|
a property list associated with a procedure object, use the
|
||||||
|
@code{procedure} functions; otherwise, use the @code{object} functions.
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "object-properties")
|
||||||
|
@deffn primitive object-properties obj
|
||||||
|
@deffnx primitive procedure-properties obj
|
||||||
|
Return @var{obj}'s property list.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME alist/plist
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-object-properties!")
|
||||||
|
@deffn primitive set-object-properties! obj plist
|
||||||
|
@deffnx primitive set-procedure-properties! obj alist
|
||||||
|
Set @var{obj}'s property list to @var{alist}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "object-property")
|
||||||
|
@deffn primitive object-property obj key
|
||||||
|
@deffnx primitive procedure-property obj key
|
||||||
|
Return the property of @var{obj} with name @var{key}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ARGFIXME val/value
|
||||||
|
@c docstring begin (texi-doc-string "guile" "set-object-property!")
|
||||||
|
@deffn primitive set-object-property! obj key val
|
||||||
|
@deffnx primitive set-procedure-property! obj key value
|
||||||
|
In @var{obj}'s property list, set the property named @var{key} to
|
||||||
|
@var{value}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
[Interface bug: there should be a second level of interface in which
|
||||||
|
the user provides a "property table" that is possibly private.]
|
||||||
|
|
||||||
|
|
||||||
|
@node Primitive Properties
|
||||||
|
@section Primitive Properties
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "primitive-make-property")
|
||||||
|
@deffn primitive primitive-make-property not_found_proc
|
||||||
|
Create a @dfn{property token} that can be used with
|
||||||
|
@code{primitive-property-ref} and @code{primitive-property-set!}.
|
||||||
|
See @code{primitive-property-ref} for the significance of
|
||||||
|
@var{not_found_proc}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "primitive-property-ref")
|
||||||
|
@deffn primitive primitive-property-ref prop obj
|
||||||
|
Return the property @var{prop} of @var{obj}. When no value
|
||||||
|
has yet been associated with @var{prop} and @var{obj}, call
|
||||||
|
@var{not-found-proc} instead (see @code{primitive-make-property})
|
||||||
|
and use its return value. That value is also associated with
|
||||||
|
@var{obj} via @code{primitive-property-set!}. When
|
||||||
|
@var{not-found-proc} is @code{#f}, use @code{#f} as the
|
||||||
|
default value of @var{prop}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "primitive-property-set!")
|
||||||
|
@deffn primitive primitive-property-set! prop obj val
|
||||||
|
Associate @var{code} with @var{prop} and @var{obj}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "primitive-property-del!")
|
||||||
|
@deffn primitive primitive-property-del! prop obj
|
||||||
|
Remove any value associated with @var{prop} and @var{obj}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Sorting
|
||||||
|
@section Sorting
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "merge!")
|
||||||
|
@deffn primitive merge! alist blist less
|
||||||
|
Takes two lists @var{alist} and @var{blist} such that
|
||||||
|
@code{(sorted? alist less?)} and @code{(sorted? blist less?)} and
|
||||||
|
returns a new list in which the elements of @var{alist} and
|
||||||
|
@var{blist} have been stably interleaved so that
|
||||||
|
@code{(sorted? (merge alist blist less?) less?)}.
|
||||||
|
This is the destructive variant of @code{merge}
|
||||||
|
Note: this does _not_ accept vectors.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "merge")
|
||||||
|
@deffn primitive merge alist blist less
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "restricted-vector-sort!")
|
||||||
|
@deffn primitive restricted-vector-sort! vec less startpos endpos
|
||||||
|
Sort the vector @var{vec}, using @var{less} for comparing
|
||||||
|
the vector elements. @var{startpos} and @var{endpos} delimit
|
||||||
|
the range of the vector which gets sorted. The return value
|
||||||
|
is not specified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "sort!")
|
||||||
|
@deffn primitive sort! items less
|
||||||
|
Sort the sequence @var{items}, which may be a list or a
|
||||||
|
vector. @var{less} is used for comparing the sequence
|
||||||
|
elements. The sorting is destructive, that means that the
|
||||||
|
input sequence is modified to produce the sorted result.
|
||||||
|
This is not a stable sort.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "sort")
|
||||||
|
@deffn primitive sort items less
|
||||||
|
Sort the sequence @var{items}, which may be a list or a
|
||||||
|
vector. @var{less} is used for comparing the sequence
|
||||||
|
elements. This is not a stable sort.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "sort-list!")
|
||||||
|
@deffn primitive sort-list! items less
|
||||||
|
Sort the list @var{items}, using @var{less} for comparing the
|
||||||
|
list elements. The sorting is destructive, that means that the
|
||||||
|
input list is modified to produce the sorted result.
|
||||||
|
This is a stable sort.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "sort-list")
|
||||||
|
@deffn primitive sort-list items less
|
||||||
|
Sort the list @var{items}, using @var{less} for comparing the
|
||||||
|
list elements. This is a stable sort.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "sorted?")
|
||||||
|
@deffn primitive sorted? items less
|
||||||
|
Return @code{#t} iff @var{items} is a list or a vector such that
|
||||||
|
for all 1 <= i <= m, the predicate @var{less} returns true when
|
||||||
|
applied to all elements i - 1 and i
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "stable-sort!")
|
||||||
|
@deffn primitive stable-sort! items less
|
||||||
|
Sort the sequence @var{items}, which may be a list or a
|
||||||
|
vector. @var{less} is used for comparing the sequence elements.
|
||||||
|
The sorting is destructive, that means that the input sequence
|
||||||
|
is modified to produce the sorted result.
|
||||||
|
This is a stable sort.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "stable-sort")
|
||||||
|
@deffn primitive stable-sort items less
|
||||||
|
Sort the sequence @var{items}, which may be a list or a
|
||||||
|
vector. @var{less} is used for comparing the sequence elements.
|
||||||
|
This is a stable sort.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Copying
|
||||||
|
@section Copying Deep Structures
|
||||||
|
|
||||||
|
@c docstring begin (texi-doc-string "guile" "copy-tree")
|
||||||
|
@deffn primitive copy-tree obj
|
||||||
|
Recursively copy the data tree that is bound to @var{obj}, and return a
|
||||||
|
pointer to the new data structure. @code{copy-tree} recurses down the
|
||||||
|
contents of both pairs and vectors (since both cons cells and vector
|
||||||
|
cells may point to arbitrary objects), and stops recursing when it hits
|
||||||
|
any other object.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c TeX-master: "guile.texi"
|
||||||
|
@c End:
|
453
doc/scm.texi
Normal file
453
doc/scm.texi
Normal file
|
@ -0,0 +1,453 @@
|
||||||
|
@page
|
||||||
|
@node Scheme Primitives
|
||||||
|
@c @chapter Writing Scheme primitives in C
|
||||||
|
@c - according to the menu in guile.texi - NJ 2001/1/26
|
||||||
|
@chapter Relationship between Scheme and C functions
|
||||||
|
|
||||||
|
@c Chapter contents contributed by Thien-Thi Nguyen <ttn@gnu.org>.
|
||||||
|
|
||||||
|
Scheme procedures marked "primitive functions" have a regular interface
|
||||||
|
when calling from C, reflected in two areas: the name of a C function, and
|
||||||
|
the convention for passing non-required arguments to this function.
|
||||||
|
|
||||||
|
@c Although the vast majority of functions support these relationships,
|
||||||
|
@c there are some exceptions.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Transforming Scheme name to C name::
|
||||||
|
* Structuring argument lists for C functions::
|
||||||
|
@c * Exceptions to the regularity::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Transforming Scheme name to C name
|
||||||
|
@section Transforming Scheme name to C name
|
||||||
|
|
||||||
|
Normally, the name of a C function can be derived given its Scheme name,
|
||||||
|
using some simple textual transformations:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
|
||||||
|
@item
|
||||||
|
Replace @code{-} (hyphen) with @code{_} (underscore).
|
||||||
|
|
||||||
|
@item
|
||||||
|
Replace @code{?} (question mark) with "_p".
|
||||||
|
|
||||||
|
@item
|
||||||
|
Replace @code{!} (exclamation point) with "_x".
|
||||||
|
|
||||||
|
@item
|
||||||
|
Replace internal @code{->} with "_to_".
|
||||||
|
|
||||||
|
@item
|
||||||
|
Replace @code{<=} (less than or equal) with "_leq".
|
||||||
|
|
||||||
|
@item
|
||||||
|
Replace @code{>=} (greater than or equal) with "_geq".
|
||||||
|
|
||||||
|
@item
|
||||||
|
Replace @code{<} (less than) with "_less".
|
||||||
|
|
||||||
|
@item
|
||||||
|
Replace @code{>} (greater than) with "_gr".
|
||||||
|
|
||||||
|
@item
|
||||||
|
Replace @code{@@} with "at". [Omit?]
|
||||||
|
|
||||||
|
@item
|
||||||
|
Prefix with "gh_" (or "scm_" if you are ignoring the gh interface).
|
||||||
|
|
||||||
|
@item
|
||||||
|
[Anything else? --ttn, 2000/01/16 15:17:28]
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
Here is an Emacs Lisp command that prompts for a Scheme function name and
|
||||||
|
inserts the corresponding C function name into the buffer.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(defun insert-scheme-to-C (name &optional use-gh)
|
||||||
|
"Transforms Scheme NAME, a string, to its C counterpart, and inserts it.
|
||||||
|
Prefix arg non-nil means use \"gh_\" prefix, otherwise use \"scm_\" prefix."
|
||||||
|
(interactive "sScheme name: \nP")
|
||||||
|
(let ((transforms '(("-" . "_")
|
||||||
|
("?" . "_p")
|
||||||
|
("!" . "_x")
|
||||||
|
("->" . "_to_")
|
||||||
|
("<=" . "_leq")
|
||||||
|
(">=" . "_geq")
|
||||||
|
("<" . "_less")
|
||||||
|
(">" . "_gr")
|
||||||
|
("@" . "at"))))
|
||||||
|
(while transforms
|
||||||
|
(let ((trigger (concat "\\(.*\\)"
|
||||||
|
(regexp-quote (caar transforms))
|
||||||
|
"\\(.*\\)"))
|
||||||
|
(sub (cdar transforms))
|
||||||
|
(m nil))
|
||||||
|
(while (setq m (string-match trigger name))
|
||||||
|
(setq name (concat (match-string 1 name)
|
||||||
|
sub
|
||||||
|
(match-string 2 name)))))
|
||||||
|
(setq transforms (cdr transforms))))
|
||||||
|
(insert (if use-gh "gh_" "scm_") name))
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@node Structuring argument lists for C functions
|
||||||
|
@section Structuring argument lists for C functions
|
||||||
|
|
||||||
|
The C function's arguments will be all of the Scheme procedure's
|
||||||
|
argumements, both required and optional; if the Scheme procedure takes a
|
||||||
|
``rest'' argument, that will be a final argument to the C function. The
|
||||||
|
C function's arguments, as well as its return type, will be @code{SCM}.
|
||||||
|
|
||||||
|
@c @node Exceptions to the regularity
|
||||||
|
@c @section Exceptions to the regularity
|
||||||
|
@c
|
||||||
|
@c There are some exceptions to the regular structure described above.
|
||||||
|
|
||||||
|
|
||||||
|
@page
|
||||||
|
@node I/O Extensions
|
||||||
|
@chapter Using and Extending Ports in C
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* C Port Interface:: Using ports from C.
|
||||||
|
* Port Implementation:: How to implement a new port type in C.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node C Port Interface
|
||||||
|
@section C Port Interface
|
||||||
|
|
||||||
|
This section describes how to use Scheme ports from C.
|
||||||
|
|
||||||
|
@subsection Port basics
|
||||||
|
|
||||||
|
There are two main data structures. A port type object (ptob) is of
|
||||||
|
type @code{scm_ptob_descriptor}. A port instance is of type
|
||||||
|
@code{scm_port}. Given an @code{SCM} variable which points to a port,
|
||||||
|
the corresponding C port object can be obtained using the
|
||||||
|
@code{SCM_PTAB_ENTRY} macro. The ptob can be obtained by using
|
||||||
|
@code{SCM_PTOBNUM} to give an index into the @code{scm_ptobs}
|
||||||
|
global array.
|
||||||
|
|
||||||
|
@subsection Port buffers
|
||||||
|
|
||||||
|
An input port always has a read buffer and an output port always has a
|
||||||
|
write buffer. However the size of these buffers is not guaranteed to be
|
||||||
|
more than one byte (e.g., the @code{shortbuf} field in @code{scm_port}
|
||||||
|
which is used when no other buffer is allocated). The way in which the
|
||||||
|
buffers are allocated depends on the implementation of the ptob. For
|
||||||
|
example in the case of an fport, buffers may be allocated with malloc
|
||||||
|
when the port is created, but in the case of an strport the underlying
|
||||||
|
string is used as the buffer.
|
||||||
|
|
||||||
|
@subsection The @code{rw_random} flag
|
||||||
|
|
||||||
|
Special treatment is required for ports which can be seeked at random.
|
||||||
|
Before various operations, such as seeking the port or changing from
|
||||||
|
input to output on a bidirectional port or vice versa, the port
|
||||||
|
implemention must be given a chance to update its state. The write
|
||||||
|
buffer is updated by calling the @code{flush} ptob procedure and the
|
||||||
|
input buffer is updated by calling the @code{end_input} ptob procedure.
|
||||||
|
In the case of an fport, @code{flush} causes buffered output to be
|
||||||
|
written to the file descriptor, while @code{end_input} causes the
|
||||||
|
descriptor position to be adjusted to account for buffered input which
|
||||||
|
was never read.
|
||||||
|
|
||||||
|
The special treatment must be performed if the @code{rw_random} flag in
|
||||||
|
the port is non-zero.
|
||||||
|
|
||||||
|
@subsection The @code{rw_active} variable
|
||||||
|
|
||||||
|
The @code{rw_active} variable in the port is only used if
|
||||||
|
@code{rw_random} is set. It's defined as an enum with the following
|
||||||
|
values:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item SCM_PORT_READ
|
||||||
|
the read buffer may have unread data.
|
||||||
|
|
||||||
|
@item SCM_PORT_WRITE
|
||||||
|
the write buffer may have unwritten data.
|
||||||
|
|
||||||
|
@item SCM_PORT_NEITHER
|
||||||
|
neither the write nor the read buffer has data.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@subsection Reading from a port.
|
||||||
|
|
||||||
|
To read from a port, it's possible to either call existing libguile
|
||||||
|
procedures such as @code{scm_getc} and @code{scm_read_line} or to read
|
||||||
|
data from the read buffer directly. Reading from the buffer involves
|
||||||
|
the following steps:
|
||||||
|
|
||||||
|
@enumerate
|
||||||
|
@item
|
||||||
|
Flush output on the port, if @code{rw_active} is @code{SCM_PORT_WRITE}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Fill the read buffer, if it's empty, using @code{scm_fill_input}.
|
||||||
|
|
||||||
|
@item Read the data from the buffer and update the read position in
|
||||||
|
the buffer. Steps 2) and 3) may be repeated as many times as required.
|
||||||
|
|
||||||
|
@item Set rw_active to @code{SCM_PORT_READ} if @code{rw_random} is set.
|
||||||
|
|
||||||
|
@item update the port's line and column counts.
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
@subsection Writing to a port.
|
||||||
|
|
||||||
|
To write data to a port, calling @code{scm_lfwrite} should be sufficient for
|
||||||
|
most purposes. This takes care of the following steps:
|
||||||
|
|
||||||
|
@enumerate
|
||||||
|
@item
|
||||||
|
End input on the port, if @code{rw_active} is @code{SCM_PORT_READ}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Pass the data to the ptob implementation using the @code{write} ptob
|
||||||
|
procedure. The advantage of using the ptob @code{write} instead of
|
||||||
|
manipulating the write buffer directly is that it allows the data to be
|
||||||
|
written in one operation even if the port is using the single-byte
|
||||||
|
@code{shortbuf}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Set @code{rw_active} to @code{SCM_PORT_WRITE} if @code{rw_random}
|
||||||
|
is set.
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
|
||||||
|
@node Port Implementation
|
||||||
|
@section Port Implementation
|
||||||
|
|
||||||
|
This section describes how to implement a new port type in C.
|
||||||
|
|
||||||
|
As described in the previous section, a port type object (ptob) is
|
||||||
|
a structure of type @code{scm_ptob_descriptor}. A ptob is created by
|
||||||
|
calling @code{scm_make_port_type}.
|
||||||
|
|
||||||
|
All of the elements of the ptob, apart from @code{name}, are procedures
|
||||||
|
which collectively implement the port behaviour. Creating a new port
|
||||||
|
type mostly involves writing these procedures.
|
||||||
|
|
||||||
|
@code{scm_make_port_type} initialises three elements of the structure
|
||||||
|
(@code{name}, @code{fill_input} and @code{write}) from its arguments.
|
||||||
|
The remaining elements are initialised with default values and can be
|
||||||
|
set later if required.
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item name
|
||||||
|
A pointer to a NUL terminated string: the name of the port type. This
|
||||||
|
is the only element of @code{scm_ptob_descriptor} which is not
|
||||||
|
a procedure. Set via the first argument to @code{scm_make_port_type}.
|
||||||
|
|
||||||
|
@item mark
|
||||||
|
Called during garbage collection to mark any SCM objects that a port
|
||||||
|
object may contain. It doesn't need to be set unless the port has
|
||||||
|
@code{SCM} components. Set using @code{scm_set_port_mark}.
|
||||||
|
|
||||||
|
@item free
|
||||||
|
Called when the port is collected during gc. It
|
||||||
|
should free any resources used by the port.
|
||||||
|
Set using @code{scm_set_port_free}.
|
||||||
|
|
||||||
|
@item print
|
||||||
|
Called when @code{write} is called on the port object, to print a
|
||||||
|
port description. e.g., for an fport it may produce something like:
|
||||||
|
@code{#<input: /etc/passwd 3>}. Set using @code{scm_set_port_print}.
|
||||||
|
|
||||||
|
@item equalp
|
||||||
|
Not used at present. Set using @code{scm_set_port_equalp}.
|
||||||
|
|
||||||
|
@item close
|
||||||
|
Called when the port is closed, unless it was collected during gc. It
|
||||||
|
should free any resources used by the port.
|
||||||
|
Set using @code{scm_set_port_close}.
|
||||||
|
|
||||||
|
@item write
|
||||||
|
Accept data which is to be written using the port. The port implementation
|
||||||
|
may choose to buffer the data instead of processing it directly.
|
||||||
|
Set via the third argument to @code{scm_make_port_type}.
|
||||||
|
|
||||||
|
@item flush
|
||||||
|
Complete the processing of buffered output data. Reset the value of
|
||||||
|
@code{rw_active} to @code{SCM_PORT_NEITHER}.
|
||||||
|
Set using @code{scm_set_port_flush}.
|
||||||
|
|
||||||
|
@item end_input
|
||||||
|
Perform any synchronisation required when switching from input to output
|
||||||
|
on the port. Reset the value of @code{rw_active} to @code{SCM_PORT_NEITHER}.
|
||||||
|
Set using @code{scm_set_port_end_input}.
|
||||||
|
|
||||||
|
@item fill_input
|
||||||
|
Read new data into the read buffer and return the first character. It
|
||||||
|
can be assumed that the read buffer is empty when this procedure is called.
|
||||||
|
Set via the second argument to @code{scm_make_port_type}.
|
||||||
|
|
||||||
|
@item input_waiting
|
||||||
|
Return a lower bound on the number of bytes that could be read from the
|
||||||
|
port without blocking. It can be assumed that the current state of
|
||||||
|
@code{rw_active} is @code{SCM_PORT_NEITHER}.
|
||||||
|
Set using @code{scm_set_port_input_waiting}.
|
||||||
|
|
||||||
|
@item seek
|
||||||
|
Set the current position of the port. The procedure can not make
|
||||||
|
any assumptions about the value of @code{rw_active} when it's
|
||||||
|
called. It can reset the buffers first if desired by using something
|
||||||
|
like:
|
||||||
|
|
||||||
|
@example
|
||||||
|
if (pt->rw_active == SCM_PORT_READ)
|
||||||
|
scm_end_input (object);
|
||||||
|
else if (pt->rw_active == SCM_PORT_WRITE)
|
||||||
|
ptob->flush (object);
|
||||||
|
@end example
|
||||||
|
|
||||||
|
However note that this will have the side effect of discarding any data
|
||||||
|
in the unread-char buffer, in addition to any side effects from the
|
||||||
|
@code{end_input} and @code{flush} ptob procedures. This is undesirable
|
||||||
|
when seek is called to measure the current position of the port, i.e.,
|
||||||
|
@code{(seek p 0 SEEK_CUR)}. The libguile fport and string port
|
||||||
|
implementations take care to avoid this problem.
|
||||||
|
|
||||||
|
The procedure is set using @code{scm_set_port_seek}.
|
||||||
|
|
||||||
|
@item truncate
|
||||||
|
Truncate the port data to be specified length. It can be assumed that the
|
||||||
|
current state of @code{rw_active} is @code{SCM_PORT_NEITHER}.
|
||||||
|
Set using @code{scm_set_port_truncate}.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@node Handling Errors
|
||||||
|
@chapter How to Handle Errors in C Code
|
||||||
|
|
||||||
|
Error handling is based on catch and throw. Errors are always thrown with
|
||||||
|
a key and four arguments:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
key: a symbol which indicates the type of error. The symbols used
|
||||||
|
by libguile are listed below.
|
||||||
|
|
||||||
|
@item
|
||||||
|
subr: the name of the procedure from which the error is thrown, or #f.
|
||||||
|
|
||||||
|
@item
|
||||||
|
message: a string (possibly language and system dependent) describing the
|
||||||
|
error. The tokens %s and %S can be embedded within the message: they
|
||||||
|
will be replaced with members of the args list when the message is
|
||||||
|
printed. %s indicates an argument printed using "display", while %S
|
||||||
|
indicates an argument printed using "write". message can also be #f,
|
||||||
|
to allow it to be derived from the key by the error handler (may be
|
||||||
|
useful if the key is to be thrown from both C and Scheme).
|
||||||
|
|
||||||
|
@item
|
||||||
|
args: a list of arguments to be used to expand %s and %S tokens in message.
|
||||||
|
Can also be #f if no arguments are required.
|
||||||
|
|
||||||
|
@item
|
||||||
|
rest: a list of any additional objects required. e.g., when the key is
|
||||||
|
'system-error, this contains the C errno value. Can also be #f if no
|
||||||
|
additional objects are required.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
In addition to catch and throw, the following Scheme facilities are
|
||||||
|
available:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
(scm-error key subr message args rest): throw an error, with arguments
|
||||||
|
as described above.
|
||||||
|
|
||||||
|
@item
|
||||||
|
(error msg arg ...) Throw an error using the key 'misc-error. The error
|
||||||
|
message is created by displaying msg and writing the args.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
The following are the error keys defined by libguile and the situations
|
||||||
|
in which they are used:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
error-signal: thrown after receiving an unhandled fatal signal such as
|
||||||
|
SIGSEV, SIGBUS, SIGFPE etc. The "rest" argument in the throw contains
|
||||||
|
the coded signal number (at present this is not the same as the usual
|
||||||
|
Unix signal number).
|
||||||
|
|
||||||
|
@item
|
||||||
|
system-error: thrown after the operating system indicates an error
|
||||||
|
condition. The "rest" argument in the throw contains the errno value.
|
||||||
|
|
||||||
|
@item
|
||||||
|
numerical-overflow: numerical overflow.
|
||||||
|
|
||||||
|
@item
|
||||||
|
out-of-range: the arguments to a procedure do not fall within the
|
||||||
|
accepted domain.
|
||||||
|
|
||||||
|
@item
|
||||||
|
wrong-type-arg: an argument to a procedure has the wrong thpe.
|
||||||
|
|
||||||
|
@item
|
||||||
|
wrong-number-of-args: a procedure was called with the wrong number of
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
@item
|
||||||
|
memory-allocation-error: memory allocation error.
|
||||||
|
|
||||||
|
@item
|
||||||
|
stack-overflow: stack overflow error.
|
||||||
|
|
||||||
|
@item
|
||||||
|
regex-error: errors generated by the regular expression library.
|
||||||
|
|
||||||
|
@item
|
||||||
|
misc-error: other errors.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
@section C Support
|
||||||
|
|
||||||
|
SCM scm_error (SCM key, char *subr, char *message, SCM args, SCM rest)
|
||||||
|
|
||||||
|
Throws an error, after converting the char * arguments to Scheme strings.
|
||||||
|
subr is the Scheme name of the procedure, NULL is converted to #f.
|
||||||
|
Likewise a NULL message is converted to #f.
|
||||||
|
|
||||||
|
The following procedures invoke scm_error with various error keys and
|
||||||
|
arguments. The first three call scm_error with the system-error key
|
||||||
|
and automatically supply errno in the "rest" argument: scm_syserror
|
||||||
|
generates messages using strerror, scm_sysmissing is used when
|
||||||
|
facilities are not available. Care should be taken that the errno
|
||||||
|
value is not reset (e.g. due to an interrupt).
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
void scm_syserror (char *subr);
|
||||||
|
@item
|
||||||
|
void scm_syserror_msg (char *subr, char *message, SCM args);
|
||||||
|
@item
|
||||||
|
void scm_sysmissing (char *subr);
|
||||||
|
@item
|
||||||
|
void scm_num_overflow (char *subr);
|
||||||
|
@item
|
||||||
|
void scm_out_of_range (char *subr, SCM bad_value);
|
||||||
|
@item
|
||||||
|
void scm_wrong_num_args (SCM proc);
|
||||||
|
@item
|
||||||
|
void scm_wrong_type_arg (char *subr, int pos, SCM bad_value);
|
||||||
|
@item
|
||||||
|
void scm_memory_error (char *subr);
|
||||||
|
@item
|
||||||
|
static void scm_regex_error (char *subr, int code); (only used in rgx.c).
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
Exception handlers can also be installed from C, using
|
||||||
|
scm_internal_catch, scm_lazy_catch, or scm_stack_catch from
|
||||||
|
libguile/throw.c. These have not yet been documented, however the
|
||||||
|
source contains some useful comments.
|
202
doc/scripts.texi
Normal file
202
doc/scripts.texi
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
|
||||||
|
@node Guile Scripting
|
||||||
|
@chapter Guile Scripting
|
||||||
|
|
||||||
|
Like AWK, Perl, or any shell, Guile can interpret script files. A Guile
|
||||||
|
script is simply a file of Scheme code with some extra information at
|
||||||
|
the beginning which tells the operating system how to invoke Guile, and
|
||||||
|
then tells Guile how to handle the Scheme code.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Invoking Guile:: How to start a Guile script.
|
||||||
|
* The Meta Switch:: Passing complex argument lists to Guile
|
||||||
|
from shell scripts.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Invoking Guile
|
||||||
|
@section Invoking Guile
|
||||||
|
|
||||||
|
Here we describe Guile's command-line processing in detail. Guile
|
||||||
|
processes its arguments from left to right, recognizing the switches
|
||||||
|
described below. For examples, see @ref{Scripting Examples}.
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item -s @var{script} @var{arg...}
|
||||||
|
Read and evaluate Scheme source code from the file @var{script}, as the
|
||||||
|
@code{load} function would. After loading @var{script}, exit. Any
|
||||||
|
command-line arguments @var{arg...} following @var{script} become the
|
||||||
|
script's arguments; the @code{command-line} function returns a list of
|
||||||
|
strings of the form @code{(@var{script} @var{arg...})}.
|
||||||
|
|
||||||
|
@item -c @var{expr} @var{arg...}
|
||||||
|
Evaluate @var{expr} as Scheme code, and then exit. Any command-line
|
||||||
|
arguments @var{arg...} following @var{expr} become command-line arguments; the
|
||||||
|
@code{command-line} function returns a list of strings of the form
|
||||||
|
@code{(@var{guile} @var{arg...})}, where @var{guile} is the path of the
|
||||||
|
Guile executable.
|
||||||
|
|
||||||
|
@item -- @var{arg...}
|
||||||
|
Run interactively, prompting the user for expressions and evaluating
|
||||||
|
them. Any command-line arguments @var{arg...} following the @code{--}
|
||||||
|
become command-line arguments for the interactive session; the
|
||||||
|
@code{command-line} function returns a list of strings of the form
|
||||||
|
@code{(@var{guile} @var{arg...})}, where @var{guile} is the path of the
|
||||||
|
Guile executable.
|
||||||
|
|
||||||
|
@item -l @var{file}
|
||||||
|
Load Scheme source code from @var{file}, and continue processing the
|
||||||
|
command line.
|
||||||
|
|
||||||
|
@item -e @var{function}
|
||||||
|
Make @var{function} the @dfn{entry point} of the script. After loading
|
||||||
|
the script file (with @code{-s}) or evaluating the expression (with
|
||||||
|
@code{-c}), apply @var{function} to a list containing the program name
|
||||||
|
and the command-line arguments --- the list provided by the
|
||||||
|
@code{command-line} function.
|
||||||
|
|
||||||
|
A @code{-e} switch can appear anywhere in the argument list, but Guile
|
||||||
|
always invokes the @var{function} as the @emph{last} action it performs.
|
||||||
|
This is weird, but because of the way script invocation works under
|
||||||
|
POSIX, the @code{-s} option must always come last in the list.
|
||||||
|
|
||||||
|
@xref{Scripting Examples}.
|
||||||
|
|
||||||
|
@item -ds
|
||||||
|
Treat a final @code{-s} option as if it occurred at this point in the
|
||||||
|
command line; load the script here.
|
||||||
|
|
||||||
|
This switch is necessary because, although the POSIX script invocation
|
||||||
|
mechanism effectively requires the @code{-s} option to appear last, the
|
||||||
|
programmer may well want to run the script before other actions
|
||||||
|
requested on the command line. For examples, see @ref{Scripting
|
||||||
|
Examples}.
|
||||||
|
|
||||||
|
@item \
|
||||||
|
Read more command-line arguments, starting from the second line of the
|
||||||
|
script file. @xref{The Meta Switch}.
|
||||||
|
|
||||||
|
@item --emacs
|
||||||
|
Assume Guile is running as an inferior process of Emacs, and use a
|
||||||
|
special protocol to communicate with Emacs's Guile interaction mode.
|
||||||
|
This switch sets the global variable use-emacs-interface to @code{#t}.
|
||||||
|
|
||||||
|
This switch is still experimental.
|
||||||
|
|
||||||
|
@item -h@r{, }--help
|
||||||
|
Display help on invoking Guile, and then exit.
|
||||||
|
|
||||||
|
@item -v@r{, }--version
|
||||||
|
Display the current version of Guile, and then exit.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@node The Meta Switch
|
||||||
|
@section The Meta Switch
|
||||||
|
|
||||||
|
Guile's command-line switches allow the programmer to describe
|
||||||
|
reasonably complicated actions in scripts. Unfortunately, the POSIX
|
||||||
|
script invocation mechanism only allows one argument to appear on the
|
||||||
|
@samp{#!} line after the path to the Guile executable, and imposes
|
||||||
|
arbitrary limits on that argument's length. Suppose you wrote a script
|
||||||
|
starting like this:
|
||||||
|
@example
|
||||||
|
#!/usr/local/bin/guile -e main -s
|
||||||
|
!#
|
||||||
|
(define (main args)
|
||||||
|
(map (lambda (arg) (display arg) (display " "))
|
||||||
|
(cdr args))
|
||||||
|
(newline))
|
||||||
|
@end example
|
||||||
|
The intended meaning is clear: load the file, and then call @code{main}
|
||||||
|
on the command-line arguments. However, the system will treat
|
||||||
|
everything after the Guile path as a single argument --- the string
|
||||||
|
@code{"-e main -s"} --- which is not what we want.
|
||||||
|
|
||||||
|
As a workaround, the meta switch @code{\} allows the Guile programmer to
|
||||||
|
specify an arbitrary number of options without patching the kernel. If
|
||||||
|
the first argument to Guile is @code{\}, Guile will open the script file
|
||||||
|
whose name follows the @code{\}, parse arguments starting from the
|
||||||
|
file's second line (according to rules described below), and substitute
|
||||||
|
them for the @code{\} switch.
|
||||||
|
|
||||||
|
Working in concert with the meta switch, Guile treats the characters
|
||||||
|
@samp{#!} as the beginning of a comment which extends through the next
|
||||||
|
line containing only the characters @samp{!#}. This sort of comment may
|
||||||
|
appear anywhere in a Guile program, but it is most useful at the top of
|
||||||
|
a file, meshing magically with the POSIX script invocation mechanism.
|
||||||
|
|
||||||
|
Thus, consider a script named @file{/u/jimb/ekko} which starts like this:
|
||||||
|
@example
|
||||||
|
#!/usr/local/bin/guile \
|
||||||
|
-e main -s
|
||||||
|
!#
|
||||||
|
(define (main args)
|
||||||
|
(map (lambda (arg) (display arg) (display " "))
|
||||||
|
(cdr args))
|
||||||
|
(newline))
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Suppose a user invokes this script as follows:
|
||||||
|
@example
|
||||||
|
$ /u/jimb/ekko a b c
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Here's what happens:
|
||||||
|
@itemize @bullet
|
||||||
|
|
||||||
|
@item
|
||||||
|
the operating system recognizes the @samp{#!} token at the top of the
|
||||||
|
file, and rewrites the command line to:
|
||||||
|
@example
|
||||||
|
/usr/local/bin/guile \ /u/jimb/ekko a b c
|
||||||
|
@end example
|
||||||
|
This is the usual behavior, prescribed by POSIX.
|
||||||
|
|
||||||
|
@item
|
||||||
|
When Guile sees the first two arguments, @code{\ /u/jimb/ekko}, it opens
|
||||||
|
@file{/u/jimb/ekko}, parses the three arguments @code{-e}, @code{main},
|
||||||
|
and @code{-s} from it, and substitutes them for the @code{\} switch.
|
||||||
|
Thus, Guile's command line now reads:
|
||||||
|
@example
|
||||||
|
/usr/local/bin/guile -e main -s /u/jimb/ekko a b c
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@item
|
||||||
|
Guile then processes these switches: it loads @file{/u/jimb/ekko} as a
|
||||||
|
file of Scheme code (treating the first three lines as a comment), and
|
||||||
|
then performs the application @code{(main "/u/jimb/ekko" "a" "b" "c")}.
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
When Guile sees the meta switch @code{\}, it parses command-line
|
||||||
|
argument from the script file according to the following rules:
|
||||||
|
@itemize @bullet
|
||||||
|
|
||||||
|
@item
|
||||||
|
Each space character terminates an argument. This means that two
|
||||||
|
spaces in a row introduce an argument @code{""}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The tab character is not permitted (unless you quote it with the
|
||||||
|
backslash character, as described below), to avoid confusion.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The newline character terminates the sequence of arguments, and will
|
||||||
|
also terminate a final non-empty argument. (However, a newline
|
||||||
|
following a space will not introduce a final empty-string argument;
|
||||||
|
it only terminates the argument list.)
|
||||||
|
|
||||||
|
@item
|
||||||
|
The backslash character is the escape character. It escapes backslash,
|
||||||
|
space, tab, and newline. The ANSI C escape sequences like @code{\n} and
|
||||||
|
@code{\t} are also supported. These produce argument constituents; the
|
||||||
|
two-character combination @code{\n} doesn't act like a terminating
|
||||||
|
newline. The escape sequence @code{\@var{NNN}} for exactly three octal
|
||||||
|
digits reads as the character whose ASCII code is @var{NNN}. As above,
|
||||||
|
characters produced this way are argument constituents. Backslash
|
||||||
|
followed by other characters is not allowed.
|
||||||
|
|
||||||
|
@end itemize
|
0
doc/scsh.texi
Normal file
0
doc/scsh.texi
Normal file
0
doc/slib.texi
Normal file
0
doc/slib.texi
Normal file
0
doc/tcltk.texi
Normal file
0
doc/tcltk.texi
Normal file
0
doc/texinfo.tex
Normal file
0
doc/texinfo.tex
Normal file
Loading…
Add table
Add a link
Reference in a new issue