mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-04 16:30:48 -08:00
3666 lines
139 KiB
Text
3666 lines
139 KiB
Text
\input texinfo @c -*-texinfo-*-
|
||
@c %**start of header
|
||
@setfilename ecl.info
|
||
@settitle ECL User's Guide
|
||
@setchapternewpage odd
|
||
@c %**end of header
|
||
|
||
@c Entries for @command{install-info} to use
|
||
@dircategory Lisp Programming
|
||
@direntry
|
||
* ecl: (ecl). Embeddable Common Lisp (ECL) User's Manual
|
||
@end direntry
|
||
|
||
@include macros.txi
|
||
|
||
@ifinfo
|
||
@ecl{} is an implementation of @clisp{} designed for being @emph{embeddable}
|
||
into C based applications.
|
||
|
||
@noindent
|
||
Copyright @copyright{} 2000, Juan Jose Garcia-Ripoll
|
||
@noindent
|
||
Copyright @copyright{} 1990, Giuseppe Attardi
|
||
|
||
@end ifinfo
|
||
|
||
@titlepage
|
||
@title ECL User's Guide
|
||
@author Giuseppe Attardi
|
||
@author Juan Jose Garcia Ripoll (revised version)
|
||
|
||
@page
|
||
@vskip 0pt plus 1filll
|
||
Copyright @copyright{} 1990, Giuseppe Attardi
|
||
|
||
Copyright @copyright{} 2000, Juan Jose Garcia Ripoll
|
||
@end titlepage
|
||
|
||
@c ************************ TOP NODE **************************
|
||
|
||
@ifnottex
|
||
@node Top, Introduction, (dir), (dir)
|
||
@top Top
|
||
@end ifnottex
|
||
|
||
@iftex
|
||
@page
|
||
@titlefont{Preface}
|
||
@vskip 1cm
|
||
@end iftex
|
||
|
||
@ecl{} is an implementation of @clisp{} originally designed for being
|
||
@emph{embeddable} into C based applications.
|
||
This document describes the @ecl{} implementation and how it differs from
|
||
@bibcite{ANSI} and @bibcite{Steele:84}.
|
||
See @inforef{Top,,ecldev} for details about the implementation and how to
|
||
interface with other languages.
|
||
|
||
@menu
|
||
* Introduction:: What ECL is and how to install it.
|
||
* Standards:: Deviations from standards.
|
||
* Input and output:: Accessing files with ECL.
|
||
* Memory management:: Bits and bytes of every object.
|
||
* Program development:: Tracing, steppping, error handling, etc.
|
||
* The interpreter:: The guts behind ECL.
|
||
* The compiler:: When you need speed@dots{}
|
||
* Declarations:: Helping the compiler
|
||
* OS interface:: Operating system interface.
|
||
* Macros:: Implementation dependent features of macros.
|
||
* CLOS:: Common-Lisp's Object System.
|
||
* Multithread:: Lisp lightweight processes or threads.
|
||
* Bibliography:: Some interesting books.
|
||
@end menu
|
||
|
||
@node Introduction, Standards, Top, Top
|
||
@chapter Introduction
|
||
|
||
@ecl{} is an implementation of the @clisp{} language that was developed
|
||
by Giuseppe Attardi's up from the Kyoto Common-Lisp. See @ref{Credits}
|
||
for the history of the code you are up to use.
|
||
|
||
@ecl{} (ECL for short) uses standard C calling conventions for Lisp compiled
|
||
functions, which allows C programs to easily call Lisp functions and
|
||
vice versa. No foreign function interface is required: data can be exchanged
|
||
between C and Lisp with no need for conversion.
|
||
|
||
@ecl{} is based on a Common Runtime Support (CRS) which provides basic
|
||
facilities for memory management, dynamic loading and dumping of binary images,
|
||
support for multiple threads of execution. The CRS is built into a library
|
||
that can be linked with the code of the application. @ecl{} is modular: main
|
||
modules are the program development tools (top level, debugger, trace,
|
||
stepper), the compiler, and CLOS. A native implementation of CLOS is available
|
||
in @ecl{}: one can configure @ecl{} with or without CLOS. A runtime version
|
||
of @ecl{} can be built with just the modules which are required by the
|
||
application.
|
||
|
||
The @ecl{} compiler compiles from Lisp to C, and then invokes the GNU C
|
||
compiler to produce binaries. While former releases of ECL adhere to the
|
||
the reference of the language given in @bibcite{Steele:84}, the aim of
|
||
@ecl{} is now to achieve maximum compliance with @ansi{}, the most up to
|
||
date standard for @clisp{}.
|
||
|
||
Throughout this manual we will describe the @ecl{} implementation and
|
||
how it differs from @bibcite{ANSI} and @bibcite{Steele:84}. In general, as
|
||
work in @ecl{} is completed section by section, we will drop compatibility
|
||
with @bibcite{Steele:84} and the corresponding chapter will be updated to
|
||
document @emph{only} the differences with @bibcite{ANSI}.
|
||
|
||
@menu
|
||
* Credits::
|
||
* Copyright::
|
||
* Installation:: Installing a binary distribution.
|
||
* Rebuilding ECL:: Building @ecl{} from sources.
|
||
* Invoking ECL:: Basic skills.
|
||
@end menu
|
||
|
||
@node Credits, Copyright, Introduction, Introduction
|
||
@section Credits
|
||
|
||
The @ecl{} project is an implementation of the @clisp{} language that aims to
|
||
comply with the @ansi{} standard. The first ECL implementations were developed
|
||
by Giuseppe Attardi's who produced an interpreter and compiler fully conformat
|
||
with the Common-Lisp as reported in @cite{Steele:84}. ECL derives itself mostly
|
||
from Kyoto @clisp{}, an implementation developed at the Research Institute for
|
||
Mathematical Sciences (RIMS), Kyoto University, with the cooperation of Nippon
|
||
Data General Corporation. The main developers of Kyoto @clisp{} were Taiichi
|
||
Yuasa and Masami Hagiya, of the Research Institute for Mathematical Sciences,
|
||
at Kyoto University.
|
||
|
||
I must thank Giuseppe Attardi, Yuasa and Hagiya for their wonderful work with
|
||
preceding implementations and for putting them in the Public Domain under the
|
||
GNU General Public License as published by the Free Software Foundation.
|
||
Without them this product would have never been possible.
|
||
|
||
This document is an update of the original ECL documentation, which was based
|
||
in part on the material in @bibcite{Yuasa:85}
|
||
|
||
The following people or organizations must be credited for support in the
|
||
development of Kyoto @clisp{}: Prof. Reiji Nakajima at RIMS, Kyoto University;
|
||
Nippon Data General Corporation; Teruo Yabe; Toshiyasu Harada; Takashi Suzuki;
|
||
Kibo Kurokawa; Data General Corporation; Richard Gabriel; Daniel Weinreb; Skef
|
||
Wholey; Carl Hoffman; Naruhiko Kawamura; Takashi Sakuragawa; Akinori Yonezawa;
|
||
Etsuya Shibayama; Hagiwara Laboratory; Shuji Doshita; Takashi Hattori.
|
||
|
||
William F. Schelter improved KCL in several areas and developed Austin Kyoto
|
||
@clisp{} (AKCL). Many ideas and code from AKCL have been incorporated in
|
||
@ecl{}.
|
||
|
||
The following is the full list of contributors to ECL: Taiichi Yuasa and
|
||
Masami Hagiya (KCL), William F. Schelter (Dynamic loader, conservative Gc),
|
||
Giuseppe Attardi (Top-level, trace, stepper, compiler, CLOS, multithread),
|
||
Marcus Daniels (Linux port) Cornelis van der Laan (FreeBSD port) David Rudloff
|
||
(NeXT port) Dan Stanger, Don Cohen, and Brian Spilsbury.
|
||
|
||
We have to thank for the following pieces of software that have helped in the
|
||
development of @ecl{}
|
||
@table @sc
|
||
@item Bruno Haible
|
||
For the Cltl2-compliance test
|
||
@item Peter Van Eynde
|
||
For the ANSI-compliance test
|
||
@item Symbolic's Inc.
|
||
For the ANSI-compliant LOOP macro.
|
||
@end table
|
||
|
||
The @ecl{} project also owes a lot to the people who have tested this program
|
||
and contributed with suggestions and error messages: Eric Marsden, Hannu
|
||
Koivisto and Jeff Bowden, and others whose name I may have omitted.
|
||
|
||
@node Copyright, Installation, Credits, Introduction
|
||
@section Copyright
|
||
|
||
@noindent
|
||
Copyright @copyright{} 2000 Juan Jose Garcia Ripoll
|
||
|
||
@noindent
|
||
Copyright @copyright{} 1990, 1991, 1993 Giuseppe Attardi
|
||
|
||
@noindent
|
||
Copyright @copyright{} 1984 Taiichi Yuasa and Masami Hagiya
|
||
|
||
@noindent
|
||
All Rights Reserved
|
||
|
||
@noindent
|
||
Summary:
|
||
|
||
@quotation
|
||
Permission is granted to use, copy, modify this program,
|
||
EXCEPT that the copyright notice must be reproduced on copies, and
|
||
credit should be given to the authors where it is due.
|
||
WE MAKE NO WARRANTY AND ACCEPT NO LIABILITY FOR THIS PROGRAM.
|
||
@end quotation
|
||
|
||
@noindent
|
||
In detail:
|
||
|
||
@enumerate
|
||
@item
|
||
Permission to use, copy, modify this software and its documentation
|
||
for any purpose is hereby granted without fee, provided that
|
||
@itemize
|
||
@item the above copyright notice appears in all copies,
|
||
@item both that copyright notice and this permission notice appears in supporting documentation, and that
|
||
@item you cause modified files to carry prominent notices stating that you changed the files and the date of any change.
|
||
@end itemize
|
||
|
||
@item
|
||
Please notify us if you are going to sell this software or its documentation
|
||
for profit.
|
||
|
||
@item
|
||
WE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
|
||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL WE BE LIABLE FOR
|
||
ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
|
||
USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
@end enumerate
|
||
|
||
@noindent
|
||
Additionally:
|
||
|
||
@quotation
|
||
@ecl{} is free software; you can redistribute it and/or modify it
|
||
under the terms of the GNU Library General Public License as published
|
||
by the Free Software Foundation; either version 2 of the License, or
|
||
(at your option) any later version; see file 'Copying'.
|
||
|
||
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 Library General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Library General Public License
|
||
along with this program; if not, write to the Free Software
|
||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
@end quotation
|
||
|
||
@noindent
|
||
Address for reporting bugs, comments, suggestions:
|
||
@quotation
|
||
@email{worm@@arrakis.es}
|
||
@end quotation
|
||
|
||
|
||
@node Installation, Rebuilding ECL, Copyright, Introduction
|
||
@section Installation
|
||
|
||
***
|
||
*** Building of binary distributions has been discontinued. The
|
||
*** following paragraphs do not apply
|
||
***
|
||
|
||
Usually I build current binaries for the platforms I have access to,
|
||
and these are placed in
|
||
@table @asis
|
||
@item Linux
|
||
@uref{http://www.arrakis.es/~worm/ecl-linux.tgz}
|
||
@item FreeBSD (>= 4.0)
|
||
@uref{http://www.arrakis.es/~worm/ecl-freebsd.tgz}
|
||
@end table
|
||
|
||
To install them you need only unpack them on the root directory,
|
||
and the program will install itself under
|
||
@example
|
||
/usr/local/bin ecl program
|
||
/usr/local/lib/ecl libraries and headers
|
||
/usr/local/man/man1 ecl.1 manual page
|
||
/usr/local/info ecl.info user guide
|
||
@end example
|
||
|
||
The flags which I used to build the program are summarized in
|
||
@file{/usr/local/lib/ecl/BUILD-STAMP}. You should check that they
|
||
correspond to your needs before using @ecl{} --i.e., it could be a too
|
||
old version, garbage collector might not be the right one or TCP/IP
|
||
support could have been removed.
|
||
|
||
@node Rebuilding ECL, Invoking ECL, Installation, Introduction
|
||
@section Rebuilding ECL
|
||
|
||
@enumerate
|
||
@item Obtain the distribution from @uref{http://ecls.sourceforge.net}.
|
||
The distribution is in a gzip-compressed tar file named like
|
||
@file{ecl.tgz}
|
||
|
||
@item Prepare a directory (hereafter called @dfn{ECL directory}) for
|
||
ECL. In the following examples, we suppose that the @emph{ECL
|
||
directory} is @file{/usr/local/ecl}.
|
||
|
||
@item Extract the content from the compressed tar file.
|
||
@example
|
||
zcat ecl.tgz | tar xf -
|
||
@end example
|
||
|
||
@item An auto configuration mechanism allows you to perform a standard
|
||
installation with the following commands:
|
||
@example
|
||
./configure
|
||
@end example
|
||
This example will prepare to install executable files, manual pages and
|
||
info files in standard directories like @file{/usr/local/bin},
|
||
@file{/usr/local/man/man1}, @file{/usr/local/info}.
|
||
|
||
@item If you don't have access rights to these directories, you should
|
||
give to configure alternate places. Try @code{./configure -help} for
|
||
instructions on how to supply this information to configure, but
|
||
a good starting point is
|
||
@example
|
||
./configure --prefix=$HOME
|
||
@end example
|
||
|
||
@item Make sure everything went OK with the configuration.
|
||
The configuration script figures out the machine where it is running and
|
||
creates a directory @code{machine} where to perform the installation. If the
|
||
program fails to recognize the machine, you will have to check whether it is
|
||
one of the supported machines present in @code{src/h/machine.h}.
|
||
|
||
@item Next you must build the program and install it
|
||
@example
|
||
make
|
||
make install
|
||
@end example
|
||
@end enumerate
|
||
|
||
At the end of installation, the destination directories will contain
|
||
several files. If you have not modified these directories when
|
||
invoking @file{configure} the layout should be
|
||
|
||
@example
|
||
Executable files:
|
||
/usr/local/bin/ecl the @ecl{} interpreter and compiler
|
||
|
||
Help documents:
|
||
/usr/local/lib/ecl/help.doc data for the online help
|
||
/usr/local/man/man1/ecl.1 manual page for @ecl{}
|
||
/usr/local/info/ecl.info this manual you are reading
|
||
|
||
Library files and headers:
|
||
/usr/local/lib/ecl/libecl.a the core library in C
|
||
/usr/local/lib/ecl/libgmp.a GNU library for bignums
|
||
/usr/local/lib/ecl/libgc.a Boehm-Weiser garbage collector
|
||
/usr/local/lib/ecl/*.a Other lisp compiled code
|
||
/usr/local/lib/ecl/h/ Header files
|
||
@end example
|
||
|
||
You can remove all intermediate files produced during installation with the
|
||
command @code{make clean}.
|
||
|
||
|
||
@node Invoking ECL, , Rebuilding ECL, Introduction
|
||
@section Entering and leaving @ecl{}
|
||
|
||
@ecl{} is invoked by the command @code{ecl}.
|
||
|
||
@example
|
||
% ecl
|
||
ECL (Embeddable Common-Lisp) 0.0e
|
||
Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
|
||
Copyright (C) 1993 Giuseppe Attardi
|
||
Copyright (C) 2000 Juan J. Garcia-Ripoll
|
||
ECL is free software, and you are welcome to redistribute it@c
|
||
under certain conditions; see file 'Copyright' for details.
|
||
Type :h for Help. Top level.
|
||
>
|
||
@end example
|
||
|
||
When invoked, @ecl{} will print the banner and initialize the system. The
|
||
date in the @ecl{} banner identifies the revision of @ecl{}. @code{Version
|
||
(0.8) 05/14/1993} is the value of the function
|
||
@code{lisp-implementation-version}.
|
||
|
||
If there exists a file named @file{init.lsp} in the current working directory,
|
||
@ecl{} successively evaluates the forms in the file, immediately after the
|
||
system initialization. The user may set up his or her own @ecl{} environment
|
||
(e.g., the memory configuration) with @file{init.lsp}.
|
||
|
||
After the initialization, @ecl{} enters the @dfn{top-level loop} and prints
|
||
the prompt `@code{>}'.
|
||
|
||
@example
|
||
Type :h for Help. Top level.
|
||
>
|
||
@end example
|
||
|
||
The prompt indicates that @ecl{} is now ready to receive a form from the
|
||
terminal and to evaluate it.
|
||
|
||
Usually, the current package (i.e., the value of @var{*package*}) is the user
|
||
package, and the prompt appears as above. If, however, the current package is
|
||
other than the user package, then the prompt will be prefixed by the package
|
||
name.
|
||
|
||
@example
|
||
> (in-package 'cl)
|
||
#<"COMMON-LISP" package>
|
||
COMMON-LISP> (in-package 'system)
|
||
#<"SYSTEM" package>
|
||
SYSTEM>
|
||
@end example
|
||
|
||
To exit from @ecl{}, call the function @code{quit}.
|
||
|
||
@example
|
||
>(quit)
|
||
Bye.
|
||
%
|
||
@end example
|
||
|
||
Alternatively, you may type @ctrl{D}, i.e. press the key @key{D} while pressing
|
||
down the control key (@key{Ctrl}).
|
||
|
||
@example
|
||
>@ctrl{D}Bye.
|
||
%
|
||
@end example
|
||
|
||
You can disable @ctrl{D} as the exit command by setting to @code{T} the
|
||
following variable:
|
||
@defvr {System} {*ignore-eof-on-terminal-io*}
|
||
This variable controls whether an end of file character (normally @ctrl{D})
|
||
should terminate the session. The default value is @nil{}.
|
||
@end defvr
|
||
|
||
The top-level loop of @ecl{} is almost the same as that defined in Section
|
||
20.2 of @bibcite{Steele:84}. Since the input from the terminal is in line
|
||
mode, each top-level form should be followed by a newline. If more than one
|
||
value is returned by the evaluation of the top-level form, the values will be
|
||
printed successively. If no value is returned, then nothing will be printed.
|
||
@example
|
||
>(values 1 2)
|
||
1
|
||
2
|
||
>(values)
|
||
|
||
>
|
||
@end example
|
||
|
||
When an error is signalled, control will enter the break loop.
|
||
@example
|
||
>(defun foo (x) (bar x))
|
||
foo
|
||
|
||
>(defun bar (y) (bee y y))
|
||
bar
|
||
|
||
>(foo 'lish)
|
||
Error: The function BEE is undefined.
|
||
Error signalled by BAR.
|
||
|
||
Broken at BAR.
|
||
>>
|
||
@end example
|
||
|
||
@c @vskip 1em
|
||
|
||
`@code{>>}' in the last line is the prompt of the break loop. Like in the
|
||
top-level loop, the prompt will be prefixed by the current package name, if the
|
||
current package is other than the @code{user} package.
|
||
|
||
To go back to the top-level loop, type @code{:q}
|
||
|
||
@example
|
||
>>:q
|
||
|
||
Top level.
|
||
>
|
||
@end example
|
||
|
||
@c @vskip 1em
|
||
|
||
See Section 5.4 for the details of the break loop.
|
||
|
||
The terminal interrupt (usually caused by typing @ctrl{C} (Control-@code{C}))
|
||
is a kind of error. It breaks the running program and calls the break level
|
||
loop.
|
||
|
||
Example:
|
||
@example
|
||
>(defun foo () (do () (nil)))
|
||
foo
|
||
|
||
>(foo)
|
||
@ctrl{C}
|
||
Correctable error: Console interrupt.
|
||
Signalled by DO.
|
||
|
||
Broken at FOO.
|
||
>>
|
||
@end example
|
||
|
||
@node Standards, Input and output, Introduction, Top
|
||
@chapter Standards
|
||
|
||
@ecl{} supports all @clisp{} data types exactly as defined in the
|
||
@bibcite{Steele:84}. This chapter simply complements Chapter 2 of
|
||
@bibcite{Steele:84}, by describing implementation dependent features of
|
||
@clisp{} data types. Each section in this chapter corresponds to the section
|
||
in Chapter 2 of @bibcite{Steele:84}, with the same section title.
|
||
|
||
@menu
|
||
* Numbers::
|
||
* Characters::
|
||
* Symbols::
|
||
* List and conses::
|
||
* Arrays::
|
||
* Hash tables::
|
||
* Readtables::
|
||
* Packages::
|
||
* Pathnames::
|
||
* Streams::
|
||
* Random-states::
|
||
* Structures::
|
||
* Functions::
|
||
* Unreadable data objects::
|
||
* Overlap of types::
|
||
* ANSI-CL compliance::
|
||
@end menu
|
||
|
||
|
||
@node Numbers, Characters, Standards, Standards
|
||
@section Numbers
|
||
|
||
@menu
|
||
* Integers::
|
||
* Ratios::
|
||
* Floating-point numbers::
|
||
* Complex numbers::
|
||
@end menu
|
||
|
||
|
||
@node Integers, Ratios, Numbers, Numbers
|
||
@subsection Integers
|
||
|
||
@tindexed{Fixnum}'s in @ecl{} are those integers in the range (-2^29)
|
||
to (2^29-1), inclusive. They are represented as immediate data, so no
|
||
memory allocation is involved when using @code{fixnum}'s. Other
|
||
integers are @code{bignums}. Thus 25 factorial (25!)
|
||
|
||
@example
|
||
15511210043330985984000000
|
||
@end example
|
||
|
||
@noindent
|
||
is definitely a bignum in @ecl{}.
|
||
|
||
@clisp{} constants related to integers have the following values
|
||
in @ecl{}.
|
||
|
||
@example
|
||
most-positive-fixnum = 536870911 = 2^29-1
|
||
most-negative-fixnum = -536870912 = - 2^29
|
||
boole-1 = 3
|
||
boole-2 = 5
|
||
boole-and = 1
|
||
boole-andc1 = 4
|
||
boole-andc2 = 2
|
||
boole-c1 = 12
|
||
boole-c2 = 10
|
||
boole-clr = 0
|
||
boole-eqv = 9
|
||
boole-ior = 7
|
||
boole-nand = 14
|
||
boole-nor = 8
|
||
boole-orc1 = 13
|
||
boole-orc2 = 11
|
||
boole-set = 15
|
||
boole-xor = 6
|
||
@end example
|
||
|
||
See Chapter 12 of @bibcite{Steele:84} for their meanings.
|
||
|
||
|
||
@node Ratios, Floating-point numbers, Integers, Numbers
|
||
@subsection Ratios
|
||
|
||
There are no implementation-dependent features for ratios.
|
||
|
||
@node Floating-point numbers, Complex numbers, Ratios, Numbers
|
||
@subsection Floating-Point Numbers
|
||
|
||
@ecl{} supports two floating point formats: @tindexed{single-float} and
|
||
@tindexed{double-float}. These are implemented with IEEE single and double
|
||
float arithmetic, respectively. @code{short-float} is a synonym for
|
||
@code{single-float}, and @code{long-float} is a synonym for
|
||
@code{double-float}. The initial value of @vindexed{read-default-float-format}
|
||
is @code{single-float}.
|
||
|
||
Both @code{single-float} and @code{double-float} are represented with a pointer
|
||
descriptor, so float operations can cause number consing. Number consing is
|
||
greatly reduced if type declarations are supplied in programs.
|
||
|
||
An expression such as @code{(eql 1.0s0 1.0d0)} is false, but @code{(eql 1.0f0
|
||
1.0d0)} is true. Similarly, @code{(typep 1.0l0 'short-float)} is false, but
|
||
@code{(typep 1.0l0 'double-float}) is true. For output purposes all
|
||
floating-point numbers are assumed to be of @emph{single} or @emph{double}
|
||
format.
|
||
|
||
The floating-point precisions and exponent sizes are:
|
||
|
||
@example
|
||
Format precision exponent
|
||
----------------------------
|
||
Short 24 bits 8 bits
|
||
Single 24 bits 8 bits
|
||
Double 53 bits 11 bits
|
||
Long 53 bits 11 bits
|
||
@end example
|
||
|
||
There is no ``minus zero.'' @code{(eql 0.0 -0.0)} is true.
|
||
|
||
|
||
@clisp{} constants related to floating-point numbers have the following values
|
||
in @ecl{}.
|
||
@example
|
||
most-positive-short-float
|
||
= most-positive-single-float
|
||
= - most-negative-short-float
|
||
= - most-negative-single-float
|
||
= 3.402823s38
|
||
|
||
least-positive-short-float
|
||
= least-positive-single-float
|
||
= - least-negative-short-float
|
||
= - least-negative-single-float
|
||
= 1.401298s-45
|
||
|
||
most-positive-long-float
|
||
= most-positive-double-float
|
||
= - most-negative-long-float
|
||
= - most-negative-double-float
|
||
= 1.797693134862315f308
|
||
|
||
least-positive-long-float
|
||
= least-positive-double-float
|
||
= - least-negative-long-float
|
||
= - least-negative-double-float
|
||
= 4.940656458412469f-324
|
||
|
||
short-float-epsilon
|
||
= 2.980232s-8
|
||
|
||
short-float-negative-epsilon
|
||
= 2.980232s-8
|
||
|
||
long-float-epsilon
|
||
= double-float-epsilon
|
||
= single-float-epsilon
|
||
= 5.5511151231257827f-17
|
||
|
||
long-float-negative-epsilon
|
||
= double-float-negative-epsilon
|
||
= single-float-negative-epsilon
|
||
= 5.5511151231257827f-17
|
||
|
||
pi = 3.141592653589793
|
||
@end example
|
||
|
||
See Chapter 12 of @bibcite{Steele:84} for their meanings.
|
||
|
||
@node Complex numbers, , Floating-point numbers, Numbers
|
||
@subsection Complex Numbers
|
||
|
||
There are no implementation-dependent features for complex numbers.
|
||
|
||
|
||
@node Characters, Symbols, Numbers, Standards
|
||
@section Characters
|
||
|
||
@ecl{} is fully @ansi{} compliant in all aspects of the character
|
||
data type, with the following peculiarities.
|
||
|
||
@menu
|
||
* Character types::
|
||
* Standard characters::
|
||
* Line divisions::
|
||
* Non-standard characters::
|
||
* Character attributes::
|
||
@end menu
|
||
|
||
@node Character types, Standard characters, Characters, Characters
|
||
@subsection Character types
|
||
|
||
In @ecl{} the @code{extended-character} is empty, and all characters
|
||
are implemented using 8-bit codes.
|
||
|
||
|
||
@node Standard characters, Line divisions, Character types, Characters
|
||
@subsection Standard Characters
|
||
|
||
@ecl{} supports all standard and semi-standard characters listed in Section
|
||
2.2.1 of @bibcite{Steele:84}. Non-printing characters have the following
|
||
character codes.
|
||
@example
|
||
Character Code (in octal)
|
||
--------------------------------
|
||
#@back{}Null 000
|
||
#@back{}Space 040
|
||
#@back{}Newline 012
|
||
#@back{}Backspace 010
|
||
#@back{}Tab 011
|
||
#@back{}Linefeed 012
|
||
#@back{}Page 014
|
||
#@back{}Return 015
|
||
#@back{}Rubout 177
|
||
@end example
|
||
|
||
Note that @code{#@back{}Linefeed} is synonymous with @code{#@back{}Newline} and
|
||
thus is a member of @code{standard-char}. Other semi-standard characters are
|
||
not members of @code{standard-char}.
|
||
|
||
@node Line divisions, Non-standard characters, Standard characters, Characters
|
||
@subsection Line Divisions
|
||
|
||
Since @ecl{} represents the @code{#@back{}Newline} character by a single code
|
||
12, problems with line divisions discussed in Section 2.2.2 of the
|
||
@bibcite{Steele:84} are absent in @ecl{}.
|
||
|
||
|
||
@node Non-standard characters, Character attributes, Line divisions, Characters
|
||
@subsection Non-standard Characters
|
||
|
||
@ecl{} supports no additional non-standard characters.
|
||
|
||
|
||
@node Character attributes, , Non-standard characters, Characters
|
||
@subsection Character Attributes
|
||
|
||
Characters in @ecl{} have no attributes, and thus it lacks the functions and
|
||
variables @code{#'char-bits}, @code{#'char-font}, @code{char-bits-limit}, etc,
|
||
defined in Chapter 13 of @bibcite{Steele:84}.
|
||
|
||
|
||
@node Symbols, List and conses, Characters, Standards
|
||
@section Symbols
|
||
|
||
The print name of a symbol may consist of up to 16777216 (i.e., the value of
|
||
@code{array-total-size-limit}) characters. However, when a symbol is read, the
|
||
number of characters (not counting escape characters) in the print name is
|
||
limited to 2048.
|
||
|
||
It is not recommended to write on the strings which have been passed to
|
||
#'make-symbol or returned from #'symbol-name.
|
||
|
||
@node List and conses, Arrays, Symbols, Standards
|
||
@section List and Conses
|
||
|
||
There are no implementation-dependent features for lists and conses.
|
||
|
||
|
||
@node Arrays, Hash tables, List and conses, Standards
|
||
@section Arrays
|
||
|
||
@ecl{} arrays can have up to 64 ranks.
|
||
|
||
When the value of the @clisp{} variable @code{*print-array*} (see Section
|
||
22.1.6 of @bibcite{Steele:84}) is @nil{}, then bit-vectors are printed as
|
||
@code{#<a bit-vector @var{address}>}, other vectors are printed as @code{#<a
|
||
vector @var{address}>}, and other arrays are printed as @code{#<an array
|
||
@var{address}>}. The default value for @code{*print-array*} is @nil{}.
|
||
|
||
@clisp{} constants related to arrays have the following values in @ecl{}.
|
||
|
||
@example
|
||
array-dimension-limit = 16777216
|
||
array-rank-limit = 64
|
||
array-total-size-limit = 16777216
|
||
@end example
|
||
|
||
See Section 17.1 of @bibcite{Steele:84} for their meanings.
|
||
|
||
@menu
|
||
* Vectors::
|
||
* Strings::
|
||
* Bit-Vectors::
|
||
@end menu
|
||
|
||
|
||
@node Vectors, Strings, Arrays, Arrays
|
||
@subsection Vectors
|
||
|
||
In @ecl{}, array elements are represented in one of six ways depending on the
|
||
type of the @code{array}.
|
||
|
||
@example
|
||
|
||
Array Type Element Representation
|
||
---------------------------------------------------------------
|
||
(array t) and (vector t) a cell pointer
|
||
(array fixnum) and (vector fixnum) 32 bit signed integer
|
||
(array string-char) and string 8 bit code
|
||
(array short-float) and (vector short-float) 32 bit floating point
|
||
(array long-float) and (vector long-float) 64 bit floating point
|
||
(array bit) and bit-vector 1 bit bit
|
||
@end example
|
||
|
||
|
||
@node Strings, Bit-Vectors, Vectors, Arrays
|
||
@subsection Strings
|
||
|
||
The @ecl{} implementation of strings is @ansi{} compliant. Four types 'string,
|
||
'base-string, 'simple-string and 'simple-base-string are defined, but due to
|
||
the lack of extended characters 'base-string and 'simple-base-string are
|
||
simple aliases of 'string and 'simple-string.
|
||
|
||
A string may consists of up to 16777216 (i.e., the value of
|
||
@code{array-total-size-limit}) characters. However, when a string is read, the
|
||
number of characters in it (not counting escape characters) is limited
|
||
to 2048.
|
||
|
||
|
||
@node Bit-Vectors, , Strings, Arrays
|
||
@subsection Bit-Vectors
|
||
|
||
There are no implementation-dependent features for bit-vectors.
|
||
|
||
|
||
@node Hash tables, Readtables, Arrays, Standards
|
||
@section Hash Tables
|
||
|
||
All hash tables are printed as @code{#<a hash-table @var{address}>}.
|
||
|
||
|
||
@node Readtables, Packages, Hash tables, Standards
|
||
@section Readtables
|
||
|
||
All readtables are printed as @code{#<a readtable @var{address}>}.
|
||
|
||
|
||
@node Packages, Pathnames, Readtables, Standards
|
||
@section Packages
|
||
|
||
The following packages are built into @ecl{}.
|
||
|
||
@multitable {common-lisp-user} {cl-user, user}
|
||
@item @b{Name} @tab @b{Nicknames}
|
||
@item common-lisp @tab cl, lisp
|
||
@item common-lisp-user @tab cl-user, user
|
||
@item system @tab si
|
||
@item keyword
|
||
@end multitable
|
||
|
||
For instance, the @code{system} package has two nicknames @code{sys} and
|
||
@code{si}; @code{system:symbol} may be written as @code{sys:symbol} or
|
||
@code{si:symbol}.
|
||
|
||
Depending on the configuration option by which @ecl{} has been built,
|
||
additional packages may be available:
|
||
@example
|
||
compiler clos xlib
|
||
@end example
|
||
|
||
The @code{compiler} package contains symbols used by the @ecl{} compiler.
|
||
Other packages are described in Section 11.6 of @bibcite{Steele:84}. The
|
||
@code{clos} package is used for the internal symbols of the @clisp{} Object
|
||
System, which is described in Chapter 14. The @code{xlib} package is used for
|
||
the internal symbols of CLX, the @clisp{} Language X Interface to the X Window
|
||
System, which is described in a separate manual.
|
||
|
||
Packages are printed as @code{#<@var{package-name} package>}.
|
||
|
||
|
||
@node Pathnames, Streams, Packages, Standards
|
||
@section Pathnames
|
||
|
||
@ecl{} provides a @code{#} macro @code{#P"} that reads a pathname:
|
||
@code{#P"@var{string}"} is equivalent to @code{(pathname "@var{string}"}). For
|
||
example, @code{#P"foo.lsp"} is equivalent to @code{(pathname "foo.lsp")}.
|
||
The same format is used when a pathname is printed.
|
||
|
||
The initial value of the @clisp{} variable
|
||
@var{*default-pathname-defaults*} is @code{#P""} (or, equivalently,
|
||
@code{(pathname "")}).
|
||
|
||
A pathname in the file system of @clisp{} consists of six elements:
|
||
host, device, directory, name, type and version.
|
||
|
||
Let me briefly explain how @ecl{} converts a namestring into a
|
||
pathname. First @ecl{} tries parsing the namestring using the logical
|
||
pathnames syntax, which is as follows
|
||
@example
|
||
[hostname:][;][directory-item;]*[name][.type[.version]]
|
||
hostname = word
|
||
directory-item = wildcard-word
|
||
type, name = wildcard-word without dots
|
||
version = NEWEST, newest or a number
|
||
@end example
|
||
@noindent
|
||
Here, @var{word} is a sequence of one or more characters excluding
|
||
the @code{#\Null} character and the asterisk `*'. And
|
||
@var{wildcard-word} is a sequence of any character excluding
|
||
@code{#\Null} and consecutive asterisks (i.e. @code{"**"} is not
|
||
allowed).
|
||
|
||
If @var{hostname} is not found or it is not a logical hostname, then
|
||
@ecl{} tries the physical pathname syntax,
|
||
@example
|
||
[device:][[//hostname]/][directory-item/]*[name][.type]
|
||
device, hostname = word
|
||
directory-item, type = wildcard-word
|
||
name = a wildcard-word with maybe a single leading dot
|
||
@end example
|
||
@noindent
|
||
If this syntax also fails, then the namestring is not a valid
|
||
pathname string.
|
||
|
||
It is important to remark that in @ecl{}, all physical namestrings result into
|
||
pathnames with a version equal to @code{:NEWEST}. Pathnames which are not
|
||
logical and have any other version (i. e. @code{NIL} or a number), cannot
|
||
be printed readably, but can produce a valid namestring which results of
|
||
ignoring the version.
|
||
|
||
The following rules apply to both physical and logical namestrings.
|
||
First, if a namestring contains one or more periods `.', the last period
|
||
separates the namestring into the file name and the filetype.
|
||
|
||
@example
|
||
"foo.lsp"
|
||
name: "foo"
|
||
type: "lsp"
|
||
|
||
"a.b.c"
|
||
name: "a.b"
|
||
type: "c"
|
||
@end example
|
||
|
||
If a namestring ends with a period, the filetype becomes the null string.
|
||
@example
|
||
"foo."
|
||
name: "foo"
|
||
type: "" (null string)
|
||
@end example
|
||
|
||
If a namestring begins with a period, the file name becomes @nil{}.
|
||
@example
|
||
".lsp"
|
||
name: nil
|
||
type: "lsp"
|
||
@end example
|
||
|
||
If a namestring contains no period, the filetype is @nil{}.
|
||
@example
|
||
"foo"
|
||
name: "foo"
|
||
type: nil
|
||
@end example
|
||
|
||
In a pathname, the file directory is represented as a list which
|
||
always begins with either @code{:relative} or @code{:absolute}
|
||
@example
|
||
"common/demo/foo.lsp"
|
||
";common;demo;foo.lsp"
|
||
directory: (:relative "common" "demo")
|
||
name: "foo"
|
||
type: "lsp"
|
||
"/common/demo/foo.lsp"
|
||
"common;demo;foo.lsp"
|
||
directory: (:absolute "common" "demo")
|
||
name: "foo"
|
||
type: "lsp"
|
||
@end example
|
||
|
||
If a namestring does not contain a directory, the directory component
|
||
of the pathname is @nil{}.
|
||
@example
|
||
"foo.lsp"
|
||
directory: nil
|
||
name: "foo"
|
||
type: "lsp"
|
||
@end example
|
||
|
||
The abbreviation symbols `@code{.}' and `@code{..}' may be used in a
|
||
namestring, but only the second one is translated to a standard
|
||
keyword
|
||
@example
|
||
"./demo/queen.lsp"
|
||
directory: (:relative "." "demo")
|
||
name: "queen"
|
||
type: "lsp"
|
||
|
||
"../../demo/queen.lsp"
|
||
directory: (:relative @pxlref{:up} :up "demo")
|
||
name: "queen"
|
||
type: "lsp"
|
||
@end example
|
||
|
||
The part of a namestring after the last directory separator (`@code{/}'
|
||
or `@code{;}') is always regarded as representing the file name and the
|
||
filetype. In order to represent a pathname with both the name and the
|
||
filetype @nil{}, end the pathname with a slash.
|
||
@example
|
||
"/usr/common/"
|
||
directory: (:absolute "usr" "common")
|
||
name: nil
|
||
type: nil
|
||
|
||
"/usr/common/.lsp"
|
||
directory: (:absolute "usr" "common")
|
||
name: ".lsp"
|
||
type: nil
|
||
@end example
|
||
|
||
`@code{*}' in the place of file name or filetype becomes @code{:wild}
|
||
@example
|
||
"*.lsp"
|
||
name: :wild
|
||
type: "lsp"
|
||
|
||
"foo.*"
|
||
name: "foo"
|
||
type: :wild
|
||
@end example
|
||
|
||
|
||
@node Streams, Random-states, Pathnames, Standards
|
||
@section Streams
|
||
|
||
Streams are printed in the following formats.
|
||
@table @code
|
||
@item #<input stream @var{file-name}>
|
||
An input stream from the file @var{file-name}.
|
||
|
||
@item #<output stream @var{file-name}>
|
||
An output stream to the file @var{file-name}.
|
||
|
||
@item #<string-input stream from @var{string}>
|
||
An input stream generated by @code{(make-string-input-stream
|
||
@var{string} )}.
|
||
|
||
@item #<a string-output stream>
|
||
An output stream generated by the function @code{make-string-output-stream}.
|
||
|
||
@item #<a two-way stream>
|
||
A stream generated by the function @code{make-two-way-stream}.
|
||
|
||
@item #<an echo stream>
|
||
A bidirectional stream generated by the function @code{make-echo-stream}.
|
||
|
||
@item #<synonym stream to @var{symbol}>
|
||
The stream generated by @code{(make-synonym-stream @var{symbol} )}.
|
||
|
||
@item #<a concatenated stream>
|
||
An input stream generated by the function @code{make-concatenated-stream}.
|
||
|
||
@item #<a broadcast stream>
|
||
An output stream generated by the function @code{make-broadcast-stream}.
|
||
@end table
|
||
|
||
|
||
@node Random-states, Structures, Streams, Standards
|
||
@section Random-States
|
||
|
||
@ecl{} provides a @code{#} macro `@code{#$}' that reads a random state.
|
||
@code{#$}@var{integer} is equivalent to @code{(make-random-state
|
||
@var{integer})}. The same format is used when a random state is printed.
|
||
|
||
|
||
@node Structures, Functions, Random-states, Standards
|
||
@section Structures
|
||
|
||
There are no implementation-dependent features for structures.
|
||
|
||
|
||
@node Functions, Unreadable data objects, Structures, Standards
|
||
@section Functions
|
||
|
||
All functions in @ecl{} are either compiled into bytecodes to be interpreted,
|
||
or they are translated into C and then compiled using a native C compiler.
|
||
Interpreted functions are printed using the formats
|
||
@example
|
||
#<interpreted-function @var{name}>
|
||
#<interpreted-function @code{address}>
|
||
@end example
|
||
@noindent
|
||
Compiled functions (including compiled macro-expansion functions)
|
||
are printed in the following formats.
|
||
@example
|
||
#<compiled-function @var{name}>
|
||
#<compiled-closure nil>
|
||
@end example
|
||
|
||
The output of @code{(symbol-function @var{fun})} is a list, is either a
|
||
function object if @code{'fun} is has a function definition,
|
||
@code{(macro . function-object)} if @code{'fun} is a macro, and @code{'special}
|
||
if @code{'fun} is a special form.
|
||
|
||
@ecl{} usually drops the source code of a function unless the global
|
||
variable @var{si:*keep-definitions*} was true when the function was
|
||
translated into bytecodes. Therefore, if you wish to use
|
||
@code{#'compile} and @code{#'disassemble} on defined functions, you
|
||
should issue @code{(setq si:*keep-definitions* t)} at the beginning of
|
||
your session.
|
||
|
||
@clisp{} constants related to functions have the following values in @ecl{}.
|
||
|
||
@example
|
||
call-arguments-limit = 64
|
||
lambda-list-keywords = (@optional{} @rest{} @keys{} @allow{}
|
||
@aux{} &whole &environment &body)
|
||
lambda-parameters-limit = 64
|
||
multiple-values-limit = 32
|
||
@end example
|
||
|
||
Refer to @bibcite{Steele:84} for their meanings.
|
||
|
||
|
||
@node Unreadable data objects, Overlap of types, Functions, Standards
|
||
@section Unreadable Data Objects
|
||
|
||
There are no implementation-dependent features for unreadable data objects.
|
||
|
||
|
||
@node Overlap of types, ANSI-CL compliance, Unreadable data objects, Standards
|
||
@section Overlap types
|
||
|
||
In @ecl{}, the types @code{number} and @code{array} are certainly subtypes of
|
||
@code{common}, since @ecl{} does not extend the set of objects of these types.
|
||
|
||
|
||
@node ANSI-CL compliance, , Overlap of types, Standards
|
||
@section ANSI-CL compliance
|
||
|
||
In this section we have documented the how much @ecl{} implements of
|
||
each section in @bibcite{ANSI}, and which are the most important
|
||
implementation-dependent features.
|
||
|
||
5. Data and control flow
|
||
|
||
@itemize
|
||
@item nth-value
|
||
@end itemize
|
||
|
||
10. Symbols:
|
||
|
||
@itemize
|
||
@item make-symbol: string becomes part of symbol
|
||
@item symbol-name, copy-symbol
|
||
@item gensym, fails for numeric argument >= MOST-POSITIVE-FIXNUM
|
||
@item *gensym-counter*
|
||
@end itemize
|
||
|
||
11. Packages:
|
||
|
||
@itemize
|
||
@item package-name
|
||
@item intern accepts any string designator, not only strings.
|
||
@end itemize
|
||
|
||
12. Numbers:
|
||
|
||
@itemize
|
||
@item floor, ceiling, truncate, round
|
||
@item float, complex, realpart, imagpart, numerator, denominator
|
||
@item zerop, plusp, minusp, evenp, oddp
|
||
@item =, /=, <=, >=, <, >, +, -, *, /, 1+, 1- but they do not fail for single
|
||
non numeric argument
|
||
@item max, min, but they do not contagiate floating-point nature.
|
||
@item minusp, plusp, zerop
|
||
@item sin, cos, tan
|
||
@item pi
|
||
@end itemize
|
||
@itemize
|
||
@item existence and behavior of -0.0 is not assured, with all failures
|
||
of compliance that it implies.
|
||
@item since we do not have conditions, mathematical errors are simple
|
||
errors.
|
||
@end itemize
|
||
|
||
13. Characters: complete
|
||
|
||
@itemize
|
||
@item character = base-char > standard-char
|
||
@item empty-char is an empty type
|
||
@end itemize
|
||
|
||
14. Conses:
|
||
|
||
@itemize
|
||
@item last
|
||
@end itemize
|
||
|
||
16. Strings: complete
|
||
|
||
@itemize
|
||
@item string-char = base-char
|
||
@item simple-string-char = simple-base-char
|
||
@item When :start1 or :start2 parameters are NIL they are taken as 0.
|
||
@end itemize
|
||
|
||
|
||
19. Filenames: complete, but simplistic
|
||
|
||
@itemize
|
||
@item :wild-inferiors is not supported
|
||
@item of the possible wildcard combinations, only @code{:wild} works as expected.
|
||
@item in @code{#'pathname-match-p} a @code{nil} directory is not regarded as @code{:wild}.
|
||
@item enough-namestring does not return optimal namestring
|
||
@end itemize
|
||
|
||
20. Files:
|
||
|
||
@itemize
|
||
@item truename
|
||
@item rename-file
|
||
@item directory
|
||
@end itemize
|
||
|
||
|
||
@node Input and output, Memory management, Standards, Top
|
||
@chapter Input and Output
|
||
|
||
@menu
|
||
* Read macros::
|
||
* Input/Output functions::
|
||
* Network streams::
|
||
* CLOS streams::
|
||
@end menu
|
||
|
||
|
||
@node Read macros, Input/Output functions, Input and output, Input and output
|
||
@section Read macros
|
||
|
||
@table @asis
|
||
@item #P"
|
||
@code{#"@var{string}"} reads a pathname. @code{#"@var{string}"} is equivalent
|
||
to @code{(pathname "@var{string}")}.
|
||
|
||
@item #$
|
||
@code{#$@var{integer}} reads a random state. @code{#$}@var{integer} is
|
||
equivalent to @code{(make-random-state @var{integer})}.
|
||
@end table
|
||
|
||
The @code{#} macro '@code{#,}' works as described in @bibcite{Steele:84}, only
|
||
if it is included in a constant object. The forms immediately after
|
||
@code{`#,'} below will be evaluated when the compiled code is loaded.
|
||
|
||
@example
|
||
'#,x
|
||
'(a b c (d #,e f) g)
|
||
#(1 2 3 #,(+ a b c) 5 6)
|
||
#C(0.0 #,(exp 1))
|
||
@end example
|
||
|
||
Otherwise, the effect of using '@code{#,}' is unpredictable. Note that, when
|
||
interpreted code is loaded, '@code{#,}' has the same effect as the @code{#}
|
||
macro '@code{#.}'.
|
||
|
||
|
||
@node Input/Output functions, Network streams, Read macros, Input and output
|
||
@section Input and Output Functions
|
||
|
||
The input and output functions of @ecl{} almost follow the definitions in
|
||
Chapter 22 of @bibcite{Steele:84}. Most of the differences come from the fact
|
||
that, in @ecl{}, input from the terminal is always in line mode and binary I/O
|
||
is not supported.
|
||
|
||
In @ecl{}, @code{*terminal-io*} is a two-way stream from the standard input
|
||
and to the standard output. The echoing to the terminal is performed by the
|
||
underlying operating system. In particular, when a disk file is assigned to
|
||
the standard output, nothing will be echoed at the terminal.
|
||
|
||
Those functions that deviate from the definitions in @bibcite{Steele:84} are
|
||
listed below.
|
||
|
||
@defun {load} {@var{pathname} @keys{} :print :verbose :if-does-not-exist}
|
||
If @var{pathname} does not specify the filetype of the input file, then load
|
||
uses the association list @var{si::*load-search-list*} to find out a suitable
|
||
filetype and the function to load it. Typically, this search list is made of
|
||
the elements @code{.fas}, @code{.lsp} and @code{.lisp}, in this order. If
|
||
everything fails, a file without filetype will be loaded.
|
||
@end defun
|
||
|
||
@defun {open} {}
|
||
Streams can only have element type @code{base-char}, @code{(signed-byte 8)}
|
||
and @code{(unsigned-byte 8)}. The @code{:external-format} is always @code{:default}.
|
||
@end defun
|
||
|
||
@defun {close} {}
|
||
The keyword variable @var{:abort} is always ignored.
|
||
@end defun
|
||
|
||
@defun {listen} {}
|
||
This routine requires some low level functions which are not available on
|
||
all platforms (For instance on @code{Windows}). When ECL is not able to
|
||
determine whether a stream is interactive, @code{listen} returns true unless
|
||
an end of file has been previously detected.
|
||
@end defun
|
||
|
||
@defun {clear-input} {}
|
||
The functions @code{clear-input} and @code{clear-output} do nothing.
|
||
@end defun
|
||
|
||
@defun {read-char-no-hang} {}
|
||
@code{read-char-no-hang} is equivalent to @code{read-char}.
|
||
@end defun
|
||
|
||
The functions @code{princ}, @code{write-char} and @code{write-byte} do not
|
||
always flush the stream. The stream is flushed when
|
||
@enumerate
|
||
@item a newline character is written, or
|
||
|
||
@item the input from the terminal is requested in the case that these
|
||
functions operate on @code{*terminal-io*}
|
||
@end enumerate
|
||
|
||
|
||
@node Network streams, CLOS streams, Input/Output functions, Input and output
|
||
@section Network Streams
|
||
|
||
With a configuration option, the following function is available which opens
|
||
streams across network connections.
|
||
|
||
@defun {open-client-stream} {host port}
|
||
The string @var{host} indicates the name of the host, while @var{port} is an
|
||
integer which identifies the port number to which to connect. This function
|
||
returns a two-way stream which can be used in any of the stream operations.
|
||
@end defun
|
||
|
||
@defun {open-server-stream} {host port}
|
||
A stream connected to port number @var{port} is created to which clients can
|
||
connect. This function returns a two-way stream which can be used in any of
|
||
the stream operations.
|
||
@end defun
|
||
|
||
|
||
@node CLOS streams, , Network streams, Input and output
|
||
@section CLOS Streams
|
||
|
||
When the optional CLOS subsystem is available, an interface is provided by
|
||
@ecl{} for using CLOS objects as @clisp{} input/output character streams.
|
||
Such support can be used for instance to build interactive character streams,
|
||
which may be used by applications as the stream argument for @clisp{} I/O
|
||
functions such as @code{read}, @code{listen}, @code{prin1}, etc. The
|
||
fundamental interface to @code{clos-stream} objects consists of
|
||
(generic) functions which implement the basic @clisp{} character stream
|
||
operations (see @clisp{}, Chapter 22) but whose details are implementation
|
||
dependent.
|
||
|
||
The following functions are automatically invoked by @ecl{} when a stream
|
||
operation involves a CLOS object as a stream parameter. The programmer should
|
||
define these methods for any class of objects which are to be used for
|
||
character input/output.
|
||
|
||
@menu
|
||
* CLOS Stream Input::
|
||
* CLOS Stream Output::
|
||
* CLOS Stream common::
|
||
@end menu
|
||
|
||
@node CLOS Stream Input, CLOS Stream Output, CLOS streams, CLOS streams
|
||
@subsection CLOS Stream Input
|
||
|
||
Character input from an @code{clos-stream} is implemented by the
|
||
following methods.
|
||
|
||
@deffn {Method} {stream-read-char} (object clos-stream)
|
||
Returns the next character object read from the CLOS stream @var{object}.
|
||
@end deffn
|
||
|
||
@c @deffn {Method} {stream-read-line} (object clos-stream) @rest{} make-array-options
|
||
@c Reads character objects from the CLOS stream @var{object}, up to and including
|
||
@c the next @code{#\newline} character, and returns them as a string (without the
|
||
@c @code{#\newline}. If given, the @var{make-array-options} arguments are passed
|
||
@c to @code{make-array} when the returned string is created.
|
||
@c @end deffn
|
||
|
||
@deffn {Method} {stream-unread-char} (object clos-stream) character
|
||
Unreads the character object @var{character} from the CLOS stream @var{object}.
|
||
@var{character} will be the next character read by @code{stream-read-char}.
|
||
@end deffn
|
||
|
||
@c @deffn {Method} {stream-peek-char} (object clos-stream) peek-type
|
||
@c Returns the character object which would be returned by @code{stream-read-char}
|
||
@c but does not remove it from the input buffer. If @var{peek-type} is @true{},
|
||
@c @code{steam-peek-char} skips over any whitespace characters, removing them from
|
||
@c the input buffer, and returns the next character.
|
||
@c @end deffn
|
||
|
||
@deffn {Method} {stream-listen} (object clos-stream)
|
||
Returns @nil{} is no character is immediately available from the CLOS stream
|
||
@var{object}. Otherwise, the next character is returned, as if
|
||
@code{stream-peek-char} had been called.
|
||
@end deffn
|
||
|
||
@deffn {Method} {stream-clear-input} object
|
||
Clears any buffered characters on the CLOS stream @var{object}. Returns @nil{}.
|
||
@end deffn
|
||
|
||
@node CLOS Stream Output, CLOS Stream common, CLOS Stream Input, CLOS streams
|
||
@subsection CLOS Stream Output
|
||
|
||
Character output from an @code{clos-stream} is implemented by the
|
||
following methods.
|
||
|
||
@deffn {Method} {stream-write-char} (object clos-stream) character
|
||
Outputs the character @var{character} to the CLOS stream @var{object} and
|
||
returns it.
|
||
@end deffn
|
||
|
||
@c @deffn {Method} {stream-write-line} (object clos-stream) string @optional{} start end
|
||
@c Writes character objects from the string @var{string} onto the CLOS stream
|
||
@c @var{object}. If given, the @var{start} and @var{end} arguments indicate a
|
||
@c substring that is to be output.
|
||
@c @end deffn
|
||
|
||
@c @deffn {Method} {stream-fresh-line} (object clos-stream)
|
||
@c Outputs a @code{#\back}@code{newline} character to the CLOS stream @var{object}
|
||
@c if and only if the stream is not already at the beginning of a new line.
|
||
@c Returns non-@nil{} if a @code{#\back}@code{newline} was output and @nil{}
|
||
@c otherwise.
|
||
@c @end deffn
|
||
|
||
@deffn {Method} {stream-clear-output} (object clos-stream)
|
||
Aborts any outstanding output operation on the CLOS stream @var{object} and
|
||
returns @nil{}.
|
||
@end deffn
|
||
|
||
@deffn {Method} {stream-force-output} (object clos-stream)
|
||
Initiates the emptying of the internal buffers on the CLOS stream @var{object}
|
||
and returns @nil{}.
|
||
@end deffn
|
||
|
||
@node CLOS Stream common, , CLOS Stream Output, CLOS streams
|
||
@subsection CLOS Stream common
|
||
|
||
The following functions should be available for all CLOS streams.
|
||
|
||
@deffn {Method} {stream-interactive-p} (object clos-stream)
|
||
@end deffn
|
||
|
||
@deffn {Method} {stream-close} (object clos-stream)
|
||
Closes the stream for any further input or output.
|
||
@end deffn
|
||
|
||
@node Memory management, Program development, Input and output, Top
|
||
@chapter Memory Management
|
||
|
||
The following sections only apply to the @ecl{} original garbage collector.
|
||
If @ecl{} is not compiled with @code{--disable-boehm}, then an alternative,
|
||
less restrictive garbage collector is installed, with the disadvantage
|
||
that many of the following functions @code{#'room}, @code{si:*gc-verbose*},
|
||
@dots{} do no longer work.
|
||
|
||
@menu
|
||
* Implementation types::
|
||
* Heap and relocatable areas::
|
||
* The garbage collector::
|
||
* Allocation functions::
|
||
* Storage information::
|
||
@end menu
|
||
|
||
@node Implementation types, Heap and relocatable areas, Memory management, Memory management
|
||
@section Implementation Types
|
||
|
||
Each @ecl{} object belongs to one of the 22 @emph{implementation types}. The
|
||
implementation types are shown in Table 4-1 with the corresponding @clisp{}
|
||
data types. In the table, the compiled functions are divided into three
|
||
implementation types; @code{cfun} is the type of compiled functions without
|
||
environment, @code{cclosure} is the type of compiled functions with environment
|
||
(i.e., the type of compiled closures) and @code{gfun} is the type of compiled
|
||
generic functions of CLOS.
|
||
|
||
@center Table 4-1 Implementation Types
|
||
@c @vspace{1 em}
|
||
@multitable {@emph{Implementation Type}} {@emph{@clisp{} Data Type}}
|
||
@item @code{cons} @tab @code{cons}
|
||
@item @tindexed{fixnum} @tab @tindexed{fixnum}
|
||
@item @code{bignum} @tab @code{bignum}
|
||
@item @code{ratio} @tab @code{ratio}
|
||
@item @code{short-float} @tab @code{short-float}
|
||
@item @code{long-float} @tab @code{long-float (= double-float = single-float)}
|
||
@item @code{complex} @tab @code{complex}
|
||
@item @code{character} @tab @code{character}
|
||
@item @code{symbol} @tab @code{symbol}
|
||
@item @code{package} @tab @code{package}
|
||
@item @code{hash-table} @tab @code{hash-table}
|
||
@item @code{array} @tab @code{(and array (not vector))}
|
||
@item @code{vector} @tab @code{(and vector (not string) (not bit-vector))}
|
||
@item @code{string} @tab @code{string}
|
||
@item @code{bit-vector} @tab @code{bit-vector}
|
||
@item @code{structure} @tab @code{structure}
|
||
@item @code{stream} @tab @code{stream}
|
||
@item @code{random-state} @tab @code{random-state}
|
||
@item @code{readtable} @tab @code{readtable}
|
||
@item @code{cfun} @tab @code{compiled-function without environment}
|
||
@item @code{cclosure} @tab @code{compiled-function with environment}
|
||
@item @code{gfun} @tab @code{none (CLOS generic-function)}
|
||
@item @code{instance} @tab @code{none (CLOS instance)}
|
||
@item @code{thread} @tab @code{none (thread)}
|
||
@item
|
||
@end multitable
|
||
|
||
Each object is represented by a cell allocated in the heap area of the
|
||
interpreter. The size of the cell is determined by the implementation type of
|
||
the object.
|
||
|
||
The implementation types are classified according to the size of the cells for
|
||
the objects of the type, as shown in Table 4-2. The size of the cells in the
|
||
same type class is the same.
|
||
|
||
|
||
@center Table 4-2 Classification of Implementation Types
|
||
@c @vspace{1 em}
|
||
@multitable {@emph{Class}} {@emph{Implementation Types}}
|
||
@item 1 @tab @code{CONS BIGNUM RATIO COMPLEX STRUCTURE}
|
||
@item 2 @tab @code{SHORT-FLOAT RANDOM-STATE READTABLE}
|
||
@item 3 @tab @code{LONG-FLOAT CFUN CCLOSURE}
|
||
@item 4 @tab @code{SYMBOL}
|
||
@item 5 @tab @code{PACKAGE}
|
||
@item 6 @tab @code{ARRAY HASH-TABLE VECTOR BIT-VECTOR STREAM}
|
||
@item 7 @tab @code{STRING}
|
||
@item 8 @tab @code{PATHNAME}
|
||
@end multitable
|
||
|
||
For objects of the (implementation) types @code{readtable}, @code{symbol},
|
||
@code{package}, @code{array}, @code{hash-table}, @code{vector},
|
||
@code{bit-vector}, @code{stream}, @code{cclosure}, @code{string}, @code{cfun},
|
||
and @code{structure} (or @code{instance}), the cell is simply a header of the
|
||
object. The body of the object is allocated separately from the cell and is
|
||
managed in a different manner. The memory space occupied by the body of such
|
||
an object is called a @dfn{block}. A block is either @dfn{contiguous} or
|
||
@dfn{relocatable} depending on the area in which it is allocated. The
|
||
difference between the two areas will be explained below. Table 4-3 lists
|
||
these types, along with the contents of the body and the kind of the block.
|
||
|
||
@center Table 4-3 Types with Bodies
|
||
@c @vspace{1 em}
|
||
@multitable {@emph{Type}} {@emph{Body}} {@emph{Block}}
|
||
@item @code{readtable} @tab @code{read table} @tab @code{contiguous}
|
||
@item @code{symbol} @tab @code{symbol name} @tab @code{relocatable}
|
||
@item @code{package} @tab @code{hash table} @tab @code{contiguous}
|
||
@item @code{array} @tab @code{array body} @tab @code{relocatable or contiguous}
|
||
@item @code{hash-table} @tab @code{hash table} @tab @code{relocatable}
|
||
@item @code{vector} @tab @code{vector body} @tab @code{relocatable or contiguous}
|
||
@item @code{bit-vector} @tab @code{bit-vector body} @tab @code{relocatable or contiguous}
|
||
@item @code{stream} @tab @code{I/O buffer} @tab @code{contiguous}
|
||
@item @code{cclosure} @tab @code{code} @tab @code{contiguous}
|
||
@item @code{string} @tab @code{string body} @tab @code{relocatable or contiguous}
|
||
@item @code{cfun} @tab @code{code} @tab @code{contiguous}
|
||
@item @code{structure} @tab @code{structure body} @tab @code{relocatable}
|
||
@item @code{instance} @tab @code{instance slots} @tab @code{relocatable}
|
||
@item @code{thread} @tab @code{thread data} @tab @code{contiguous}
|
||
@end multitable
|
||
|
||
Usually, the body of an array, a vector, a bit-vector, or a string is allocated
|
||
as a relocatable block. In @ecl{}, the function @code{make-array} takes an
|
||
extra keyword argument @kwd{static}. If the @kwd{static} argument is supplied
|
||
with a non-@nil{} value, then the body of the array is allocated as a
|
||
contiguous block.
|
||
|
||
|
||
@node Heap and relocatable areas, The garbage collector, Implementation types, Memory management
|
||
@section Heap and Relocatable Areas
|
||
|
||
The memory space of @ecl{} is divided into two parts: the heap area and the
|
||
relocatable area. Both areas occupy a contiguous space in the memory.
|
||
|
||
Cells of @ecl{} objects are allocated in the heap. @ecl{} divides the heap
|
||
into pages (1 page = 2048 bytes), and each page consists of cells in the same
|
||
type class (see Table 4-2). Cells in different type classes are allocated in
|
||
different pages. Some blocks are also allocated in the heap: They are called
|
||
contiguous blocks. The pages for contiguous blocks contain only contiguous
|
||
blocks. Thus each page in the heap is either a page for cells in a particular
|
||
type class, or a page for contiguous blocks. Blocks not in the heap are called
|
||
relocatable blocks and are allocated in the relocatable area.
|
||
|
||
The user may specify the maximum number of pages that can be allocated for each
|
||
type class by calling the @ecl{} specific function @code{allocate}. There is
|
||
also a limit on the number of pages for contiguous blocks; the limit can be
|
||
altered by calling the @ecl{} specific function
|
||
@code{allocate-contiguous-pages} size of the relocatable area is specified by
|
||
the @ecl{} specific function @code{allocate-relocatable-pages}. See Section
|
||
4.4 for these functions.
|
||
|
||
In some installations of @ecl{}, the total amount of memory that @ecl{} can
|
||
use is limited. In such cases, the entire memory may become exhausted before
|
||
the maximum number of pages for each type class, for contiguous blocks, or for
|
||
the relocatable area have been allocated.
|
||
|
||
The heap lies in a part of memory with lower address than the relocatable area
|
||
and there is a ``hole'' between the two areas (see Figure 4-1). On request for
|
||
a new page of heap, the page with the lowest address in the hole is used. When
|
||
the hole is exhausted, the relocatable area is shifted toward the higher
|
||
address space and a new hole of an appropriate size is created between the two
|
||
areas.
|
||
|
||
@center Figure 4-1 Heap and Relocatable Area
|
||
@c @vspace{1 em}
|
||
@example
|
||
Lower address Higher address
|
||
+--------------+-------------------+---------------+
|
||
+ HEAP | HOLE | RELOCATABLE |
|
||
+--------------+-------------------+---------------+
|
||
@end example
|
||
|
||
@node The garbage collector, Allocation functions, Heap and relocatable areas, Memory management
|
||
@section The Garbage Collector
|
||
|
||
@ecl{} uses a @emph{conservative garbage collection} technique for collecting
|
||
the C stack and a type accurate technique for areas containing Lisp objects.
|
||
Scanning conservatively the C stack, looking for potential pointers to Lisp
|
||
objects, ensures that no live Lisp objects get collected, even if they are
|
||
passed to external procedures in C or some other language. This approach
|
||
greatly simplifies integration of Lisp and C code, since it is not necessary to
|
||
protect Lisp object form collection when a foreign function is invoked.
|
||
|
||
The garbage collector of @ecl{} has three levels according to what it
|
||
collects:
|
||
@enumerate
|
||
@item cells
|
||
@item cells and relocatable blocks
|
||
@item cells, relocatable blocks and contiguous blocks.
|
||
@end enumerate
|
||
|
||
In levels 2 and 3, the relocatable area is shifted to the higher address space
|
||
to reserve an appropriate number of pages in the hole.
|
||
|
||
For each type class, @ecl{} keeps a free list of unused cells, and when the
|
||
free list is exhausted, a new page is allocated, or the garbage collector is
|
||
invoked, depending on whether the maximum number of pages for that class have
|
||
been allocated or not.
|
||
|
||
The garbage collector does not compact the heap. That is, cells and
|
||
contiguous blocks are never moved to another place. Moreover, once a page is
|
||
allocated for a particular type class or for contiguous blocks, that page will
|
||
never be freed for other classes, even if the entire page becomes garbage.
|
||
|
||
On the other hand, the relocatable area is compacted during level 2 and
|
||
level 3 of garbage collection. A relocatable block is really relocatable.
|
||
|
||
The garbage collector is automatically invoked in one of the following
|
||
situations. The number in the parentheses indicates the level of garbage
|
||
collection that is performed.
|
||
|
||
@enumerate
|
||
@item The free list of a certain type class is exhausted
|
||
after the maximum number of pages have been allocated for that type class (1).
|
||
|
||
@item The hole is exhausted (2).
|
||
|
||
@item The relocatable area is exhausted after the maximum number of
|
||
pages have been allocated for the relocatable area (2).
|
||
|
||
@item The contiguous blocks are exhausted after the maximum number of
|
||
pages have been allocated for contiguous blocks (3).
|
||
@end enumerate
|
||
|
||
The garbage collector is also invoked by the following @ecl{} specific
|
||
function.
|
||
|
||
@defun {system} {gc} {x}
|
||
The garbage collector is invoked with the level specified by @var{x}. If
|
||
@var{x} is @nil{}, the garbage collector is invoked for level 1 garbage
|
||
collection. If @var{x} is @true{}, it is invoked for level 3 garbage
|
||
collection. Otherwise, it is invoked for level 2 garbage collection. If
|
||
@code{sys:*gc-verbose*} is non-@nil{}, then it print messages at the start and
|
||
end of each garbage collection.
|
||
@end defun
|
||
|
||
@defvar{*gc-verbose*}[system] This variable controls whether to print messages
|
||
at the start and end of each garbage collection. If @code{sys:*gc-verbose*} is
|
||
@nil{}, @code{gc} fore goes printing any messages. The default value is @code{T}.
|
||
@end defvar
|
||
|
||
|
||
@node Allocation functions, Storage information, The garbage collector, Memory management
|
||
@section Allocation Functions
|
||
|
||
The following functions are used to set or inspect the (maximum)
|
||
number of pages for each type class, for contiguous blocks, or for
|
||
relocatable blocks.
|
||
|
||
@deffn {extensions} {allocate} type number
|
||
Sets the maximum number of pages for the type class of the implementation type
|
||
@var{type} to @var{number}. If more than @var{number} pages have already been
|
||
allocated, an error is signalled.
|
||
@end deffn
|
||
|
||
@deffn {sys} {allocated-pages} type
|
||
Returns the number of pages currently allocated for the type class of the
|
||
implementation type @var{type}.
|
||
@end deffn
|
||
|
||
@deffn {sys} {maximum-allocatable-pages} type
|
||
Returns the current maximum number of pages for type class of the
|
||
implementation type @var{type}.
|
||
@end deffn
|
||
|
||
@deffn {sys} {allocate-contiguous-pages} number
|
||
Sets the maximum number of pages for contiguous blocks to @var{number}.
|
||
@end deffn
|
||
|
||
@deffn {sys} {allocated-contiguous-pages}
|
||
Returns the number of pages allocated for contiguous blocks.
|
||
@end deffn
|
||
|
||
@deffn {sys} {maximum-contiguous-pages}
|
||
Returns the current maximum number of pages for contiguous blocks.
|
||
@end deffn
|
||
|
||
@deffn {sys} {allocate-relocatable-pages} number
|
||
Sets the maximum number of pages for relocatable blocks to @var{number}. The
|
||
relocatable area is expanded to @var{number} pages immediately.
|
||
Therefore,``the current maximum number'' and ``the number of pages allocated''
|
||
have the same meanings for relocatable blocks.
|
||
@end deffn
|
||
|
||
@deffn {sys} {allocated-relocatable-pages}
|
||
Returns the number of pages allocated for relocatable blocks.
|
||
@end deffn
|
||
|
||
If the pages for a particular type class are exhausted after the maximum number
|
||
of pages for that class have been allocated, and if there remain no free cells
|
||
(actually, if there remain very few cells), @ecl{} behaves as directed by the
|
||
argument that was initially passed to the @ecl{} specific function @code{(si::ignore-maximum-pages)}. If the
|
||
value is @nil{}, then @ecl{} signals a correctable error and enters the break loop.
|
||
The user can reset the maximum number by calling @code{allocate} and then
|
||
continue the execution of the program by typing @kwd{r}.
|
||
|
||
Example:
|
||
|
||
@example
|
||
|
||
>(make-list 100000)
|
||
|
||
Correctable error: The storage for CONS is exhausted.
|
||
Currently, 531 pages are allocated.
|
||
Use ALLOCATE to expand the space.
|
||
Signalled by MAKE-LIST.
|
||
|
||
Broken at FUNCALL.
|
||
>>(ALLOCATE 'CONS 1000)
|
||
t
|
||
|
||
>>:r
|
||
|
||
(nil nil nil nil nil nil nil nil nil nil ............
|
||
@end example
|
||
|
||
The user can also reset the maximum number of pages for relocatable blocks and
|
||
for contiguous blocks in a similar manner. On the other hand, if the value of
|
||
@code{(si::ignore-maximum-pages)} is non-@nil{}, then @ecl{} automatically
|
||
increments the maximum number of pages for the class by 50 percent. The
|
||
initial value of @code{(si::ignore-maximum-pages)} is @true{}.
|
||
|
||
|
||
@node Storage information, , Allocation functions, Memory management
|
||
@section Storage Information
|
||
|
||
@defun {room} {@optional{} x}
|
||
The function @code{room} prints the storage information. The argument
|
||
@var{x} is simply ignored and
|
||
the output of @code{room} is always in the same
|
||
format. @code{room} prints the following information:
|
||
@end defun
|
||
|
||
@itemize
|
||
|
||
@item for each type class
|
||
@itemize
|
||
@item the number of pages so-far allocated for the type class
|
||
@item the maximum number of pages for the type class
|
||
@item the percentage of used cells to cells so-far allocated
|
||
@item the number of times the garbage collector has been
|
||
called to collect cells of the type class
|
||
@item the implementation types that belong to the type class
|
||
@end itemize
|
||
@item the number of pages actually allocated for contiguous blocks
|
||
@item the maximum number of pages for contiguous blocks
|
||
@item the number of times the garbage collector has been called to
|
||
collect contiguous blocks
|
||
@item the number of pages in the hole
|
||
@item the maximum number of pages for relocatable blocks
|
||
@item the number of times the garbage collector has been called to
|
||
collect relocatable blocks
|
||
@item the total number of pages allocated for cells
|
||
@item the total number of pages allocated
|
||
@item the number of available pages
|
||
@item the number of pages @ecl{} can use.
|
||
@end itemize
|
||
|
||
The number of times the garbage collector has been called is not shown, if the
|
||
number is zero.
|
||
|
||
In the following example, the maximum of @code{531} pages have already been
|
||
allocated for the type class to which cons belongs, but only 16.9 percent of
|
||
the cells are actually used. The garbage collector was once invoked to collect
|
||
cells in this type class.
|
||
|
||
@example
|
||
> (room)
|
||
200/200 48.4% CONS BIGNUM RATIO COMPLEX STRUCTURE
|
||
1/5 7.4% SHORT-FLOAT RANDOM-STATE READTABLE
|
||
10/34 99.3% LONG-FLOAT CFUN CCLOSURE
|
||
47/64 71.9% SYMBOL
|
||
1/1 8.9% PACKAGE
|
||
2/69 81.8% ARRAY HASH-TABLE VECTOR BIT-VECTOR STREAM
|
||
16/40 95.9% STRING
|
||
1/1 6.8% PATHNAME
|
||
|
||
0/271 contiguous (1 blocks)
|
||
127 hole
|
||
40 3.4% relocatable
|
||
|
||
278 pages for cells
|
||
445 total pages
|
||
14709 pages available
|
||
1230 pages in heap but not gc'd + pages needed for gc marking
|
||
16384 maximum pages
|
||
@end example
|
||
|
||
|
||
@node Program development, The interpreter, Memory management, Top
|
||
@chapter Program Development Facilities
|
||
|
||
@menu
|
||
* The tracer::
|
||
* The stepper::
|
||
* Errors::
|
||
* The break loop::
|
||
* Describe and inspect::
|
||
* The profiler::
|
||
* Online help::
|
||
@end menu
|
||
|
||
@node The tracer, The stepper, Program development, Program development
|
||
@section The Tracer
|
||
|
||
The Tracer causes selected @code{functions} to be traced. When such a traced
|
||
@code{function} is invoked, it prints
|
||
@example
|
||
@var{level} > (@var{name arg1 ... argn})
|
||
@end example
|
||
|
||
On return from a traced @code{function}, it prints
|
||
@example
|
||
< @var{level} (@var{name value1 ... valuen})
|
||
@end example
|
||
|
||
@var{name} is the name of the traced @code{function}, @var{args} are the
|
||
arguments, and @var{values} are the return values. @var{level} is a number
|
||
which is incremented each time a traced @code{function} is invoked and is
|
||
decremented at the completion of the invocation. Trace print-outs are indented
|
||
according to the @var{level}.
|
||
|
||
In the current version of @ecl{}, macros and special forms cannot be traced.
|
||
|
||
@defmac {trace} {@{function-name | (function-name @{@keys{} form@}*)@}*}
|
||
|
||
Causes one or more functions to be traced. Each @var{function-name} must be a
|
||
symbol which is not evaluated. If a function is called from a compiled
|
||
function in the same file, tracing will not be enabled. If this is the case,
|
||
to enable tracing, recompile the caller with a @code{notinline} declaration for
|
||
the called function. @code{trace} returns a name list of those functions that
|
||
were traced by the call to trace. If no @var{function-name} is given,
|
||
@code{trace} simply returns a name list of all the currently traced functions.
|
||
|
||
Trace options can cause the normal printout to be suppressed, or cause extra
|
||
information to be printed. Each option is a pair of an option keyword and a
|
||
value form. If an already traced function is traced again, any new options
|
||
replace the old options. @var{form} is an expression to be evaluated in an
|
||
environment where @var{sys::arglist} is bound to the current list of arguments
|
||
to the function.
|
||
|
||
The following options are defined:
|
||
|
||
@table @asis
|
||
@item @kwd{cond} @var{form}
|
||
@item @kwd{cond-before} @var{form}
|
||
@item @kwd{cond-after} @var{form}
|
||
If @kwd{cond-before} is specified, then @code{trace} does nothing unless
|
||
@var{form} evaluates to true at the time of the call. @kwd{cond-after} is
|
||
similar, but suppresses the initial printout, and is tested when the function
|
||
returns. @kwd{cond} tries both before and after.
|
||
|
||
@item @kwd{step} @var{form}
|
||
If @var{form} evaluates to true, the stepper is entered.
|
||
|
||
@item @kwd{break} @var{form}
|
||
@item @kwd{break-after} @var{form}
|
||
If specified, and @var{form} evaluates to true, then the debugger is invoked at
|
||
the start of the function or at the end of the function according to the
|
||
respective option.
|
||
|
||
@item @kwd{print} @var{form}
|
||
@item @kwd{print-after} @var{form}
|
||
In addition to the usual printout, the result of evaluating @var{form} is
|
||
printed at the start of the function or at the end of the function, according
|
||
to the respective option. Multiple print options cause multiple values to be
|
||
@end table
|
||
@end defmac
|
||
|
||
@defmac {untrace} {@{function-name@}*}
|
||
|
||
Causes the specified functions to be not traced any more. @var{function-names}
|
||
must be symbols and they are not evaluated. @code{untrace} returns a name list
|
||
of those functions that were untraced by the call to @code{untrace}. If no
|
||
@var{function-name} is given, @code{untrace} will untrace all the currently
|
||
traced functions and will return a list of their names.
|
||
|
||
@end defmac
|
||
|
||
|
||
@node The stepper, Errors, The tracer, Program development
|
||
@section The Stepper
|
||
|
||
@defmac {step} {form}
|
||
|
||
Starts evaluating the @var{form} in the single-step mode. In this mode, before
|
||
any form is evaluated, the Stepper will print the form and prompt the user for
|
||
a Stepper command. The Stepper binds the two variables @vindexed{print-level}
|
||
and @vindexed{print-length} both to @code{2}, so that the current form may not
|
||
occupy too much space on the screen. A Stepper command will be executed when
|
||
the user types the single character for the command followed by the required
|
||
arguments, if any, and presses the newline key. If the user presses the
|
||
newline key without having typed any character, then the Stepper will assume
|
||
that the Stepper command @code{n} was abbreviated.
|
||
|
||
@end defmac
|
||
|
||
The stepper commands are:
|
||
|
||
@table @asis
|
||
@item @code{Newline}
|
||
Next. Evaluates the current form in the single-step mode.
|
||
|
||
@item @kwd{s}, @kwd{skip}
|
||
Skip. Evaluates the current form in the ordinary mode. The single-step mode
|
||
will be resumed at completion of the evaluation.
|
||
|
||
@item @kwd{b}, @kwd{back}
|
||
Backwards. Steps back to previous step form.
|
||
|
||
@item @kwd{pr}, @kwd{print}
|
||
Print. Pretty-prints the current form.
|
||
|
||
@item @kwd{form}
|
||
Form. Return the current form. Nothing is done, but the current form is
|
||
returned as the value of this command. As a consequence, it is printed by the
|
||
top level in the usual way and saved in the variable @code{*}. The main
|
||
purpose of this command is to allow the current form to be examined further by
|
||
accessing @code{*}.
|
||
|
||
@item @kwd{ret}, @kwd{return}
|
||
Return. Return without evaluating the current form.
|
||
|
||
@item @kwd{x}, @kwd{exit}
|
||
Exit. Evaluates the current form and any other forms in the ordinary mode.
|
||
|
||
@item @code{?}
|
||
Help. Lists the commands.
|
||
@end table
|
||
|
||
@node Errors, The break loop, The stepper, Program development
|
||
@section Errors
|
||
|
||
@defvar{*break-enable*}
|
||
|
||
This variable is used to determine whether to enter the break loop (see Section
|
||
5.4) when an error occurs. Even the function @code{break} checks this
|
||
variable. Initially, this variable is set to @true{}, and thus an error will
|
||
invoke the break loop. If the value is @nil{}, functions that cause fatal
|
||
errors, such as @code{ error}, will just print an error message and control
|
||
will return to the top-level loop (or to the current break loop, if already in
|
||
the break loop). Functions that cause correctable errors, such as @code{
|
||
cerror}, will print an error message and a ``continue message'', and control
|
||
will return to the next form. In @ecl{}, backtrace is not part of an error
|
||
message, but a break loop command will print backtrace. Therefore, if
|
||
@vindexed{break-enable} is @nil{}, no backtrace appears on the screen.
|
||
|
||
When the break loop is entered, @vindexed{break-enable} will be bound to
|
||
@nil{}.
|
||
|
||
@end defvar
|
||
|
||
@node The break loop, Describe and inspect, Errors, Program development
|
||
@section The Break Loop
|
||
|
||
The break loop is a read-eval-print loop similar to the top-level loop. In
|
||
addition to ordinary Lisp forms, the break loop accepts various commands with
|
||
which the user can inspect and modify the state of the program execution. Each
|
||
break loop command is identified with a keyword (i.e., a symbol in the
|
||
@code{keyword} package). A break loop command is executed when the user inputs
|
||
a list whose first element is the keyword that identifies the command. The
|
||
rest of the list is the arguments to the command. They are evaluated before
|
||
being passed to the command. If the command needs no arguments, then the user
|
||
may input only the keyword. It is an error if the given keyword does not
|
||
identify any command. Any other input to the break loop is regarded as an
|
||
ordinary Lisp form; the form will be evaluated and the resulting values will be
|
||
printed on the terminal.
|
||
|
||
There can be several instances of the break loop at the same time, and each
|
||
such instance is identified by a @emph{level number}. When the break loop is
|
||
entered during execution in the top-level loop, the break loop instance is
|
||
given the level number 1. The break loop instance that is entered from the
|
||
level @emph{n} break loop is given the level number @var{n}@code{+1}. The
|
||
prompt of the level @emph{n} break loop is @var{n}@code{+1} consecutive
|
||
@code{>}'s, occasionally prefixed with the name of the current package.
|
||
|
||
The break loop keeps track of the invocation sequence of functions (including
|
||
special forms and macro expansion functions), which led up to the break loop
|
||
from the previous break loop (or from the top-level loop, if the current break
|
||
loop is level 1). The invocation sequence is maintained in a pushdown stack of
|
||
@emph{events}. An event consists of an @emph{event function} and an
|
||
@emph{event environment}. An event function is:
|
||
@enumerate
|
||
@item an interpreted (i.e., not compiled) function (global function, local function, lambda-expression, or closure),
|
||
|
||
@item a special form within an interpreted function,
|
||
|
||
@item a macro expansion function called from an interpreted function,
|
||
|
||
@item a compiled function called from an interpreted function, or
|
||
|
||
@item a compiled function called from another compiled function which
|
||
was compiled while the @code{safety} optimize level is 3 or with a
|
||
@code{notinline} declaration for the called function (see Chapter 7).
|
||
@end enumerate
|
||
|
||
An event is pushed on the event stack when execution of its event function
|
||
begins, and is popped away at the completion of the execution. An event
|
||
environment is the `environment' of the event function at the time the next
|
||
event is pushed. Actually, an event environment is a pointer to the main stack
|
||
of @ecl{}. For each interpreted event function (i.e., event function in
|
||
classes 1, 2, and 3), the pointer points to the first entry of the three
|
||
contiguous main stack entries that hold the lexical environment of the event
|
||
function. For each compiled event function (i.e., event function in classes 4
|
||
and 5), the pointer is set to the first entry of the main stack area that is
|
||
used locally by the compiled code. In most cases, the first argument to the
|
||
compiled function is saved in the first entry, the second argument in the
|
||
second entry, and so on. The local variables of the function are allocated in
|
||
the entries following the arguments. However, this is not always the case.
|
||
Refer to Section 7.3 for variable allocations in compiled functions.
|
||
|
||
By break level commands, the user can choose one of the events as the
|
||
@emph{current event}. If the current event function is an interpreted event
|
||
function, then the break loop evaluates Lisp forms in the lexical environment
|
||
retrieved from the event environment. In particular, local variables may be
|
||
referenced by the variable names, local functions and local macros may be
|
||
invoked as usual, established blocks may be exited from, and tags may be used
|
||
as the destination of @code{go}. If the current function is a compiled
|
||
function, Lisp forms are evaluated in the null environment.
|
||
|
||
Within the break loop, each event is represented by the @emph{event symbol}.
|
||
The @kwd{backtrace} command, for example, lists events in terms of their event
|
||
symbols. If the event function is a named function (global or local) or a
|
||
macro expansion function, then the function or macro name is used as the event
|
||
symbol. If the event function is a special form, then the name of the special
|
||
form is used. If the event function is a lambda-expression (or a closure),
|
||
then the symbol lambda (or lambda-closure) is used.
|
||
|
||
To suppress unnecessary information, the user can hide (or make invisible) some
|
||
of the events. Invisible events do not appear in the backtrace, for example.
|
||
Initially, only those events are invisible whose event symbols belong to the
|
||
system internal package system. When the break loop is entered, the last
|
||
visible event becomes the current event.
|
||
|
||
The break loop commands are described below. Some of the commands allow
|
||
abbreviation in the keywords that identify them. For example, the user may
|
||
abbreviate @kwd{current} as @kwd{c}. The break loop commands return no values
|
||
at all.
|
||
|
||
@deffn {Break Command} {:current}
|
||
@deffnx {Break Command} {:c} {}
|
||
Prints the event symbol of the current event.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:previous} @optional{} n
|
||
@deffnx {Break Command} {:p} {@optional{} n}
|
||
Makes the @var{n}-th previous visible event the
|
||
new current event. Invisible events are not counted. If there are
|
||
less than @var{n} previous events, then the first visible event in the
|
||
invocation sequence becomes the new current event. @var{n} must be a
|
||
positive integer and the default is @code{1}.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:next} @optional{} n
|
||
@deffnx {Break Command} {:n} {@optional{} n}
|
||
Makes the @var{n}-th next visible event the
|
||
new current event. If there are less than @var{n} next events,
|
||
then the last visible event in the invocation sequence
|
||
becomes the new current event. @var{n} must be a positive integer and the
|
||
default is @code{1}.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:backtrace}
|
||
@deffnx {Break Command} {:b} {}
|
||
Prints the event symbols of all visible events in order. The symbol of
|
||
the current event is printed
|
||
in upper-case letters and the event symbols of other events are in lower-case.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:help}
|
||
@deffnx {Break Command} {:h} {}
|
||
Lists the break loop commands.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:quit} @optional{} n
|
||
@deffnx {Break Command} {:q} {@optional{} n}
|
||
Returns control to the level @var{n} break loop. If @var{n} is 0 or if @var{n}
|
||
is omitted, then control will return to the top-level loop. @var{n} must be a
|
||
non-negative integer smaller than the current break level.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:continue}
|
||
@deffnx {Break Command} {:c} {}
|
||
Returns control to the caller of the break loop. If the break loop has been
|
||
entered from @code{cerror}, @code{cerror} returns @nil{} as its value and
|
||
control will resume at that point. Otherwise, this command returns control to
|
||
the previous break loop (or to the top-level loop, if the current break level
|
||
is @code{1}).
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:variables}
|
||
@deffnx {Break Command} {:v} {}
|
||
Prints the names of the bound variables in the current
|
||
environment. To see the value of a bound variable, just type the
|
||
variable name.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:functions}
|
||
Prints the names of the local functions and local macros in the current
|
||
environment. To see the definition of a local function or macro, use the
|
||
function special form in the usual way. That is, @code{(function @var{name})}
|
||
will return the definition of the local function or macro whose name is
|
||
@var{name}. Local functions and local macros may be invoked as usual.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:blocks}
|
||
Prints the names of the blocks established in the current environment. If a
|
||
block @var{block} is established, then the @code{return-from} form
|
||
@code{(return-from @var{block value})} works as usual. That is, the block form
|
||
that established @var{block} will return @var{value} as its value and control
|
||
will resume at that point.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:tags}
|
||
Prints the tags established in the current environment. If a tag @var{tag} is
|
||
established, then the @code{go} form @code{(go @var{tag})} works as usual.
|
||
That is, control will resume at the position of @var{tag} in the surrounding
|
||
@code{tagbody}.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:local} @optional{} n
|
||
@deffnx {Break Command} {:l} {@optional{} n}
|
||
If @var{n} is @code{0} or if it is omitted, then this command prints the value
|
||
stored in the main stack entry that is pointed to by the current event
|
||
environment. @var{n} is an offset from that entry. If @var{n} is positive,
|
||
then the value of the @emph{n}-th next (i.e., toward the top of the main stack)
|
||
entry is printed. If @var{n} is negative, then the value of the @var{n}-th
|
||
previous (i.e., toward the bottom of the main stack) entry is printed. @var{n}
|
||
must be an integer. It is an error if the specified entry does not lie between
|
||
the bottom and the top of the stack.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:hide} symbol
|
||
Hides all events whose event symbol is @var{symbol}. In particular, by
|
||
@code{:hide 'lambda} and @code{hide 'lambda-closure}, all events become
|
||
invisible whose event functions are lambda-expressions and closures,
|
||
respectively. If the event symbol of the current event happens to be
|
||
@var{symbol}, then the last previous visible event will become the new current
|
||
event. @var{symbol} must be a symbol.
|
||
|
||
Events of @code{eval} and @code{evalhook} may never become invisible and
|
||
attempts to hide them are simply ignored. It is always the case that the first
|
||
event function is either @code{eval} or @code{evalhook}. Keeping both of them
|
||
visible is the simplest way to avoid the silly attempts of the user to hide all
|
||
events.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:hide-package} package
|
||
Hides all events whose event symbol belongs to the package
|
||
@var{package}. @var{package} may be any object that represents a package, i.e.,
|
||
a package object, a symbol, or a string. If the event symbol of the current
|
||
event happens to belong to the package @var{package}, then the last previous
|
||
visible event will become the new current event. Even if @code{lisp} package
|
||
was specified as @var{package}, events of @code{eval} and @code{evalhook} do
|
||
not become invisible. See the description of @kwd{hide} above.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:unhide} symbol
|
||
@kwd{unhide} is the inverse command of @kwd{hide}. If, however, @var{ symbol}
|
||
belongs to one of the @kwd{hide-package}d packages, events of @var{symbol}
|
||
become visible only after the package is @code{:unhide-package
|
||
'd}. @var{symbol} must be a symbol.
|
||
@end deffn
|
||
|
||
@deffn {Break Command} {:unhide-package} package
|
||
@kwd{unhide-package} is the inverse command of @kwd{hide-package}. However, an
|
||
event whose event symbol belongs to @var{package} becomes visible only after
|
||
the symbol is @code{unhide 'd}, if the symbol was @kwd{code 'd}
|
||
before. @var{package} may be any object that represents a package, i.e., a
|
||
package object, a symbol, or a string.
|
||
@end deffn
|
||
|
||
Example:
|
||
|
||
@example
|
||
> (defun fact (x) (if (= x 0) one (* x (fact (1- x)))))
|
||
fact ;;; Wrong definition for fact, the factorial.
|
||
|
||
> (fact 6) ;;; Tries to calculate factorial 6.
|
||
|
||
Error: The variable ONE is unbound.
|
||
Error signalled by IF.
|
||
|
||
Broken at IF: ;;; Enters the break-loop.
|
||
>> :h ;;; Help.
|
||
|
||
Break commands:
|
||
:q(uit) Return to some previous break level.
|
||
:pop Pop to previous break level.
|
||
:c(ontinue) Continue execution.
|
||
:b(acktrace) Print backtrace.
|
||
:f(unction) Show current function.
|
||
:p(revious) Go to previous function.
|
||
:n(ext) Go to next function.
|
||
:g(o) Go to next function.
|
||
:fs Search forward for function.
|
||
:bs Search backward for function.
|
||
:v(ariables) Show local variables, functions, blocks, and tags.
|
||
:l(ocal) Return the nth local value on the stack.
|
||
:hide Hide function.
|
||
:unhide Unhide function.
|
||
:hp Hide package.
|
||
:unhp Unhide package.
|
||
:unhide-all Unhide all variables and packages.
|
||
:vs Show value stack.
|
||
:bds Show binding stack.
|
||
:m(essage) Show error message.
|
||
:hs Help stack.
|
||
|
||
Top level commands:
|
||
:cf Compile file.
|
||
:exit or ^D Exit Lisp.
|
||
:ld Load file.
|
||
:step Single step form.
|
||
:tr(ace) Trace function.
|
||
:untr(ace) Untrace function.
|
||
|
||
Help commands:
|
||
:apropos Apropos.
|
||
:doc(ument) Document.
|
||
:h(elp) or ? Help. Type ":help help" for more information.
|
||
|
||
>> :b ;;; Backtrace.
|
||
Backtrace: eval > fact > if > fact > if > fact > if > fact >
|
||
if > fact > if > fact > if > fact > IF
|
||
|
||
>>: p ;;; Moves to the previous event.
|
||
Broken at FACT.
|
||
|
||
>> :b ;;; Now inside of fact but outside of if.
|
||
Backtrace: eval > fact > if > fact > if > fact > if > fact >
|
||
if > fact > if > fact > if > FACT > if
|
||
|
||
>> :v ;;; Shows local variables.
|
||
Local variables:
|
||
X: 1
|
||
Block names: FACT.
|
||
|
||
>> x ;;; The value of x is 1.
|
||
1
|
||
|
||
>> (return-from fact 1) ;;; Returns from the fact block with value 1.
|
||
720 ;;; Now the correct answer.
|
||
|
||
> ;;; Top-level.
|
||
@end example
|
||
|
||
|
||
@node Describe and inspect, The profiler, The break loop, Program development
|
||
@section Describe and Inspect
|
||
|
||
@defun {describe} {object}
|
||
Prints the information about @var{object} to the stream that is the value of
|
||
@code{*standard-output*}. The description of an object consists of several
|
||
fields, each of which is described in a recursive manner. For example, a
|
||
symbol may have fields such as home package, variable documentation, value,
|
||
function documentation, function binding, type documentation, @code{deftype}
|
||
definition, properties.
|
||
@end defun
|
||
|
||
@defun {inspect} {object}
|
||
Prints the information about @var{object} in an interactive manner. The output
|
||
of inspect is similar to that of @code{describe}, but after printing the label
|
||
and the value of a field (the value itself is not @code{describe 'd}), it
|
||
prompts the user to input a one-character command. The input to @code{inspect}
|
||
is taken from the stream that is the value of @code{*query-io*}. Normally, the
|
||
inspection of @var{object} terminates after all of its fields have been
|
||
inspected. The following commands are supported:
|
||
|
||
@table @asis
|
||
@item @code{n}
|
||
Next. Goes to the next level; the field is inspected recursively.
|
||
|
||
@item @code{s}
|
||
Skip. Skips the inspection of the field. @code{inspect} proceeds to the next
|
||
field.
|
||
|
||
@item @code{p}
|
||
Print. Pretty-prints the field and prompts again.
|
||
|
||
@item @code{u} @var{form}]
|
||
Update. The @var{form} is evaluated and the field is replaced by the resulting
|
||
value. If the field cannot be updated, the message @code{Not updated.} will
|
||
be printed.
|
||
|
||
@item @code{a}
|
||
Abort. Aborts the inspection of the current object. The field and
|
||
the rest of the fields are not inspected.
|
||
|
||
@item @code{e} @var{form}
|
||
Eval. Evaluates the specified form in the null environment and prints the
|
||
resulting values. Then prompts again with the same field.
|
||
|
||
@item @code{q}
|
||
Quit. Aborts the entire inspection.
|
||
|
||
@item @code{?}
|
||
Help. Lists the @code{inspect} commands.
|
||
@end table
|
||
@end defun
|
||
|
||
|
||
@node The profiler, Online help, Describe and inspect, Program development
|
||
@section The Profiler
|
||
|
||
The profiler tool is enabled by default in the basic @ecl{} configuration. It
|
||
can be disabled with the @code{configure} option @code{--disable-profiler}.
|
||
|
||
@deffn {sys} {profile} @var{grain} @optional{} @var{address}
|
||
This function activates the profiling of subsequent executions. @var{grain} is
|
||
a value between 1 and 16384 which indicates the granularity of code segments to
|
||
consider. There is a counter for each such segment. With each clock tick, the
|
||
current segment is identified and its corresponding histogram count is
|
||
incremented. A value of 0 for @var{grain} means stop profiling. @var{address}
|
||
indicates the base address for the code being profiled.
|
||
@end deffn
|
||
|
||
@deffn {sys} {display-profile}
|
||
Displays the histogram of accumulated tick counts. The ticks are attributed to
|
||
the compiled Lisp function whose base address is closest to the start of the
|
||
segment. This may not be totally accurate for system functions which invoke
|
||
some auxiliary function to do the job.
|
||
@end deffn
|
||
|
||
@deffn {sys} {clear-profile}
|
||
Clears the profile histogram.
|
||
@end deffn
|
||
|
||
@defvar {sys} {*profile-array*}
|
||
Contains the profile histogram: two short integer counters are packed in each
|
||
value of this array of fixnums.
|
||
@end defvar
|
||
|
||
|
||
@node Online help, , The profiler, Program development
|
||
@section Online Help
|
||
|
||
Online help is provided by the following functions.
|
||
|
||
@defun {help} {@optional{} @var{symbol}}
|
||
@code{help} with no arguments prints a greeting message to @ecl{} beginners.
|
||
@code{help} with a symbol argument prints the documentation associated
|
||
with the symbol.
|
||
@end defun
|
||
|
||
@defun {help*} {@var{string} @optional{} @var{package}}
|
||
Prints the documentation associated with those symbols in the specified
|
||
@var{package} whose print names contain @var{string} as substring.
|
||
@var{string} may be a symbol, in which case the print name of that symbol is
|
||
used. @var{package} is optional and defaults to the LISP package.
|
||
If @var{package} is @nil{}, then all packages are searched.
|
||
@end defun
|
||
|
||
@node The interpreter, The compiler, Program development, Top
|
||
@chapter The Interpreter
|
||
|
||
Former versions of @ecl{}, as well as many other lisps, used linked lists to
|
||
represent code. As of version 0.3 a bytecodes compiler and a bytecodes
|
||
interpreter were developed to circumvent the limitations of linked lists.
|
||
|
||
When you enter code at the lisp prompt, or when you load a source file,
|
||
@ecl{} begins a process known as minimal compilation. Barely this
|
||
process consists on parsing each form, macroexpanding it and translating
|
||
it into an intermediate language made of @emph{bytecodes}.
|
||
|
||
The bytecodes compiler is implemented in @file{src/c/compiler.d}. The main
|
||
entry point is the lisp function @code{SI::MAKE-LAMBDA}, which takes a
|
||
name for the function and the body of the lambda lists, and produces a
|
||
lisp object that can be invoked. For instance,
|
||
|
||
@example
|
||
> (defvar fun (si::make-lambda 'f '((x) (1+ x))))
|
||
*FUN*
|
||
> (funcall fun 2)
|
||
3
|
||
@end example
|
||
|
||
@ecl{} can only execute bytecodes. When a list is passed to @code{EVAL} it
|
||
must be first compiled to bytecodes and, if the process succeeds, then the
|
||
resulting bytecodes are passed to the interpreter. Similarly, every time a
|
||
function object is created, such as in @code{DEFUN} or @code{DEFMACRO}, the
|
||
bytecodes compiler processes the lambda form to produce a suitable bytecodes
|
||
object.
|
||
|
||
The fact that @ecl{} performs this eager compilation means that changes on
|
||
a macro are not immediately seen in code which was already compiled. This has
|
||
subtle implications. Take the following code:
|
||
@example
|
||
> (defmacro f (a b) `(+ ,a ,b))
|
||
F
|
||
> (defun g (x y) (f x y))
|
||
G
|
||
> (g 1 2)
|
||
3
|
||
> (defmacro f (a b) `(- ,a ,b))
|
||
F
|
||
> (g 1 2)
|
||
3
|
||
@end example
|
||
|
||
@noindent
|
||
The last statement always outputs @code{3} while in former
|
||
implementations based on processing of lambda lists it would produce @code{-1}.
|
||
|
||
|
||
@node The compiler, Declarations, The interpreter, Top
|
||
@chapter The Compiler
|
||
|
||
The @ecl{} compiler translates a Lisp program stored in a source file into a C
|
||
program, invokes the C compiler to compile the C program, and then generates an
|
||
object file, called @emph{fasl file} (or @emph{o-file} because of the actual
|
||
filetype). The compiled program in a fasl file is loaded by the function
|
||
@code{load}.
|
||
|
||
Ordinarily, the object program generated by the @ecl{} compiler scarcely does
|
||
runtime error-checking for runtime efficiency. In addition, Lisp functions in
|
||
the same source file are linked together and some system functions are
|
||
open-coded in-line. To control runtime error checking, supply appropriate
|
||
@code{optimize} declarations (see Section 7.1).
|
||
|
||
The @ecl{} compiler processes the @code{eval-when} special form exactly as
|
||
specified in @bibcite{Steele:84} (see Section 5.3.3 of @bibcite{Steele:84}).
|
||
|
||
The @ecl{} compiler is invoked by the functions @code{compile-file},
|
||
@code{compile}, and @code{disassemble} described below. In addition, the
|
||
@ecl{} compiler may be invoked directly by the Shell commands @code{ecl}.
|
||
This command requires the file name of the source file as its
|
||
argument. @code{ecl} simply adds @code{.lsp} to the file name argument to
|
||
obtain the full name of the source file.
|
||
|
||
@example
|
||
$ ecl @var{filename}
|
||
@end example
|
||
|
||
@noindent
|
||
has the same effect as the compiler invocation @code{(compile-file
|
||
@var{filename})} from within @ecl{}, and
|
||
|
||
@example
|
||
$ ecl -C @var{filename}
|
||
@end example
|
||
|
||
has the same effects as @code{(compile-file @var{filename}
|
||
:c-file t :h-file t :data-file t)}.
|
||
|
||
@defun {compile-file} {@var{pathname} @keys{} :output-file :verbose :print :c-file :h-file :data-file}
|
||
@code{compile-file} compiles the Lisp program stored in the file specified by
|
||
@var{pathname}, and generates a binary file. If @kwd{verbose} is true, a
|
||
message indicating what file is being compiled is printed. If @kwd{print}
|
||
is true, information about top-level forms in the file being compiled is
|
||
printed. @code{compile-file} generates the following temporary files:
|
||
|
||
@multitable {Temporary File} {The include file referenced in the c-file}
|
||
@item @b{Temporary File}
|
||
@tab @b{Contents}
|
||
@item @var{c-file}
|
||
@tab C version of the Lisp program
|
||
@item @var{h-file}
|
||
@tab The include file referenced in the c-file
|
||
@item @var{data-file}
|
||
@tab The Lisp data to be used at load time
|
||
@end multitable
|
||
|
||
If files of these names already exist, the old files will be deleted first.
|
||
Usually, these intermediate files are automatically deleted after execution of
|
||
@code{compile-file}.
|
||
|
||
The input-file is determined in the usual manner (see Section 2.9), except
|
||
that, if the filetype is not specified, then the default filetype @code{.lsp}
|
||
will be used. The keyword parameter @code{:output-file} defines the default
|
||
directory and the default name to be applied to the output files (i.e., the
|
||
fasl file and the temporary files). @kwd{output-file} itself defaults to
|
||
@var{input-pathname}. That is, if @kwd{output-file} is not supplied, then the
|
||
directory and the name of the input file will be used as the default directory
|
||
and the default name for the output files. The file types of the output files
|
||
are fixed as follows.
|
||
|
||
@multitable {@b{Output File}} {@b{Filetype}}
|
||
@item @b{Output File} @tab @b{Filetype}
|
||
@item fasl file @tab @code{.o}
|
||
@item c-file @tab @code{.c}
|
||
@item h-file @tab @code{.h}
|
||
@item data-file @tab @code{.data}
|
||
@end multitable
|
||
|
||
Each output file can be specified by the corresponding keyword parameter.
|
||
If the value of the keyword parameter is @nil{}, then the output file will be
|
||
deleted after execution of @code{compile-file}. If the value of the
|
||
keyword parameter is @true{}, then the output file will be left in the
|
||
default directory under the default name. Otherwise, the output file will
|
||
be left in the directory under the name specified by the keyword parameter.
|
||
The default value of @kwd{output-file} is @true{}, and the default values
|
||
of @kwd{c-file}, @kwd{:h-file}, and @kwd{data-file} are all @nil{}.
|
||
|
||
@table @code
|
||
@item (compile-file 'foo)
|
||
The source file is @code{FOO.lsp} and the fasl file is @code{FOO.o}
|
||
both in the current directory.
|
||
|
||
@item (compile-file 'foo.lish)
|
||
The source file is @code{FOO.LISH} and the fasl file is @code{FOO.o}'.
|
||
|
||
@item (compile-file "/usr/mas/foo" :output-file "/usr/tai/baa")
|
||
The source file is @code{foo.lsp} in the directory @file{/usr/mas}, and the
|
||
fasl file is @code{baa.o} in the directory @file{/usr/tai}.
|
||
@end table
|
||
@end defun
|
||
|
||
@defun {compile} {@var{name} @var{code} @optional{} @var{definition}}
|
||
If @var{definition} is not supplied, @var{name} should be the name of a
|
||
not-yet-compiled function. In this case, compile compiles the function,
|
||
replaces the previous definition of @var{name} with the compiled
|
||
function,@emph{and} returns @var{name}. If @var{definition} is supplied, it
|
||
should be a lambda-expression to be compiled and @var{name} should be a symbol.
|
||
If @var{name} is a non-@nil{} symbol, then compile installs the compiled
|
||
function as the function definition of @var{name} and returns @var{name}. If
|
||
@var{name} is @nil{}, then compile simply returns the compiled function.
|
||
|
||
The @ecl{} compiler is essentially a file compiler, and forms to be
|
||
compiled are supposed to be stored in a file. Thus compile actually
|
||
creates a source file which contains the form designated by the
|
||
arguments. Then compile calls @code{compile-file} to get a fasl file,
|
||
which is then loaded into @ecl{}. The source file and the fasl file
|
||
are given the names @file{gazonk.lsp} and @file{gazonk.fasl},
|
||
respectively. These files are not deleted automatically after the
|
||
execution of @code{compile}.
|
||
|
||
@end defun
|
||
|
||
@defun {disassemble} {@optional{} @var{thing} @keys{} :h-file :data-file}
|
||
|
||
This function does not actually disassemble. It always calls the @ecl{}
|
||
compiler and prints the contents of the c-file, i.e., the C-language code,
|
||
generated by the @ecl{} compiler. If @var{thing} is not supplied, or if it is
|
||
@nil{}, then the previously compiled form by disassemble will be compiled
|
||
again. If @var{thing} is a symbol other than @nil{}, then it must be the name
|
||
of a not-yet-compiled function, whose definition is to be compiled. In this
|
||
case, it is an error if the name is associated with a special form or a macro.
|
||
If @var{thing} is a lambda-expression @code{(lambda @var{lambda-list .
|
||
body})}, then @code{disassemble} first creates a function definition
|
||
@code{(defun gazonk @var{lambda-list . body})} and this definition is
|
||
compiled. (The function name @code{gazonk} has no special meanings. Indeed,
|
||
the displayed code is essentially independent of the function name.)
|
||
Otherwise, @var{thing} itself will be compiled as a top-level form. In any
|
||
case, @code{disassemble} does not install the compiled function.
|
||
@code{disassemble} returns no value.
|
||
|
||
No intermediate h-file is created if the keyword parameter @code{:h-file} is
|
||
@nil{} or if @kwd{h-file} is not supplied. Otherwise, an intermediate h-file
|
||
is created under the name specified by @kwd{h-file}. Similarly, the
|
||
intermediate data-file is specified by the keyword parameter @kwd{data-file}.
|
||
|
||
@end defun
|
||
|
||
|
||
@node Declarations, OS interface, The compiler, Top
|
||
@chapter Declarations
|
||
|
||
@ecl{} supports all kinds of declarations described in the
|
||
@bibcite{Steele:84}. Any valid declaration will affect the @ecl{} environment
|
||
in some way or another, although information obtained by declarations, other
|
||
than special declarations, is mainly used by the @ecl{} compiler.
|
||
|
||
As described in @bibcite{Steele:84}, @clisp{} declarations are divided into two
|
||
classes: @var{proclamations} and others. A proclamation is a global
|
||
declaration given by the function @code{proclaim}, the top-level @emph{macro}
|
||
@code{defvar}, or the top-level macro @code{defparameter}. Once given, a
|
||
proclamation remains effective during the @ecl{} session unless it is shadowed
|
||
by a local declaration or is canceled by another proclamation. Any other
|
||
declaration is a @emph{local declaration} and is given only by the special form
|
||
@code{declare}. A local declaration remains in effect only within the body of
|
||
the construct that surrounds the declaration.
|
||
|
||
In the following nonsensical example borrowed from Chapter 9 of
|
||
@bibcite{Steele:84},
|
||
@example
|
||
(defun nonsense (k x z)
|
||
(foo z x)
|
||
(let ((j (foo k x))
|
||
(x (* k k)))
|
||
(declare (inline foo) (special x z))
|
||
(foo x j z)))
|
||
@end example
|
||
@noindent
|
||
the @code{inline} and the special declarations both remain in effect within the
|
||
surrounding @code{let} form. In this case, we say that the @code{let} form is
|
||
the @emph{surrounding construct} of these declarations.
|
||
|
||
@defspec {the} {@var{value-type form}}
|
||
|
||
The @ecl{} interpreter does actually check whether the value of the
|
||
@emph{form} conforms to the data type specified by @emph{value-type} and
|
||
signals an error if the value does not. The type checking is performed by
|
||
the function @code{typep}. For example,
|
||
@end defspec
|
||
|
||
@example
|
||
(the fixnum (foo))
|
||
@end example
|
||
|
||
@noindent
|
||
is equivalent to
|
||
|
||
@example
|
||
(let ((values (multiple-value-list (foo))))
|
||
(cond ((endp values) (error ``Too few return values."))
|
||
((not (endp (cdr values)))
|
||
(error ``Too many return values."))
|
||
((typep (car values) 'fixnum) (car values))
|
||
(t (error ``~s is not of type fixnum." (car values)))))
|
||
@end example
|
||
|
||
On the other hand, the @ecl{} compiler uses the special form to
|
||
obtain type information for compiled code optimization. No code for
|
||
runtime type-checking is embedded in the compiled code.
|
||
|
||
@menu
|
||
* Declaration specifiers::
|
||
* Type specifiers::
|
||
* Type declarations::
|
||
* Variable allocations::
|
||
* Raw data functions::
|
||
* Arguments/Values passing::
|
||
@end menu
|
||
|
||
|
||
@node Declaration specifiers, Type specifiers, Declarations, Declarations
|
||
@section Declaration Specifiers
|
||
|
||
@ecl{} recognizes all declaration specifiers defined in @bibcite{Steele:84}.
|
||
The syntax of each such declaration specifier is exactly the same as defined in
|
||
@bibcite{Steele:84}. In addition, @ecl{} recognizes the @code{object}
|
||
declaration specifier which is specific to @ecl{}.
|
||
|
||
@deffn {Declaration} {special} @{@var{variable-name}@}*
|
||
The interpreter and the compiler of @ecl{} both treat special declarations
|
||
exactly as described in @bibcite{Steele:84}.
|
||
@end deffn
|
||
|
||
@deffn {Declaration} {type} @var{type} @{@var{variable-name}@}*
|
||
A @code{type} proclamation @code{(type @emph{type var1 var2} ...)} specifies
|
||
that the dynamic values of the named variables are of the type @emph{type}. A
|
||
local @code{type} declaration specifies that the variables mentioned are bound
|
||
by the surrounding construct and have values of the type @emph{type} during
|
||
execution of the surrounding construct. The compiler issues a warning if one
|
||
of the named variables is not bound by the surrounding construct. The
|
||
information given by @code{type} declarations is used by the compiler to
|
||
optimize the compiled code. The behavior of the compiled code is unpredictable
|
||
if a wrong @code{type} declaration is supplied. The compiler detects certain
|
||
wrong @code{type} declarations at compile time.
|
||
@end deffn
|
||
|
||
For example,
|
||
@example
|
||
>(defun foo (x y)
|
||
(declare (fixnum x) (character y))
|
||
(setq x y)
|
||
...))
|
||
foo
|
||
|
||
>(compile 'foo)
|
||
|
||
; (defun foo ...) is being compiled.
|
||
;; Warning: Type mismatches between x and y.
|
||
@end example
|
||
|
||
See Section 7.3 for further information on @code{type} declarations.
|
||
|
||
@deffn {Declaration} {type} @{@var{variable-name}@}*
|
||
(@var{type var1 var2} ...) is equivalent to @code{(type @var{type var1 var2}
|
||
...)}, provided that @var{type} is one of the symbols in Table 4-1 of
|
||
@bibcite{Steele:84}, other than @code{function}. Declaration specifications
|
||
that begin with @code{function} are regarded as @code{function} declarations
|
||
(see below).
|
||
@end deffn
|
||
|
||
@deffn {Declaration} {function} @var{function-name} @var{argument-types} . @var{return-types}
|
||
A @code{function} declaration is used to obtain type information for function
|
||
call forms. That is, a @code{function} declaration specifies the argument and
|
||
the return types of each form that calls the named function.
|
||
@end deffn
|
||
|
||
@example
|
||
(defun foo ()
|
||
(declare (function bar (character) fixnum))
|
||
(+ (bar (atcholi1)) (bar (atcholi2))))
|
||
@end example
|
||
|
||
In this example, the @code{function} declaration specifies that the two
|
||
functions @code{atcholi1} and @code{atcholi2} both return character objects
|
||
when called within the body of @code{foo}, and that the function bar returns
|
||
fixnum objects when called within the body of @code{foo}. The type information
|
||
given by function declarations is used by the compiler to optimize the compiled
|
||
code. The behavior of the compiled code is unpredictable if a wrong
|
||
@code{function} declaration is supplied. The compiler detects certain wrong
|
||
@code{function} declarations at compile time.
|
||
|
||
For example,
|
||
|
||
@example
|
||
>(defun foo (x)
|
||
(declare (fixnum x)
|
||
(function bar (character) fixnum))
|
||
(bar x))
|
||
foo
|
||
|
||
>(compile 'foo)
|
||
|
||
; (defun foo ...) is being compiled.
|
||
;; Warning: The type of the form x is not character.
|
||
@end example
|
||
|
||
However, the compiler does not check the number of arguments, and thus, the
|
||
following function definition will be compiled successfully without any
|
||
warnings.
|
||
|
||
@example
|
||
(defun foo ()
|
||
(declare (function bar (character character) fixnum))
|
||
(+ (bar (atcholi1)) (bar (atcholi2) (atcholi3) (atcholi4))))
|
||
@end example
|
||
|
||
For this definition, the compiler assumes that the three functions
|
||
@code{atcholi1}, @code{atcholi2}, and @code{atcholi3} will return fixnum
|
||
objects. The return type of @code{atcholi4} is unknown at compile time.
|
||
|
||
The complete syntax of a function declaration is:
|
||
|
||
@example
|
||
(function function-name
|
||
(@{type@}* [@{@optional{} | @rest{} | @keys{}@} @{thing@}*])
|
||
@{(values @{type@}* ) | @{type@}*@}
|
||
)
|
||
@end example
|
||
|
||
Although @optional{}, @rest{}, and @keys{} markers may appear in the list of
|
||
argument types, only those @var{types} are recognized that appear before any
|
||
such markers and the rest of the list is simply ignored. Note that functions
|
||
with @optional{}, @rest{}, or @keys{} parameters may still be declared by
|
||
@code{function} declarations because of the use of @code{function} declarations
|
||
mentioned above.
|
||
|
||
The @code{values} construct in the specification of return types is almost
|
||
useless: @code{(function @var{function-name argument-types} (@var{values}
|
||
@var{type1 type2} @dots{}))} is equivalent to @code{(function
|
||
@var{function-name argment-types type1 type2} @dots{})}.
|
||
|
||
See Section 7.3 for further information on @code{function} declarations.
|
||
|
||
@deffn {Declaration} {ftype} @var{function-type} @{@var{function-name}@}*
|
||
@var{function-type} must be a list whose first element is the symbol
|
||
@code{function}. @code{(ftype (function . @var{rest}) @var{function-name-1}
|
||
... @var{function-name-n})} is equivalent to @var{n} consecutive
|
||
@code{function} declarations @code{(function @var{function-name-1}
|
||
. @var{rest})} ... @code{(function @var{function-name-n} . @var{rest})}.
|
||
@end deffn
|
||
|
||
@deffn {Declaration} {notinline} @{function-name@}*
|
||
@code{(notinline @var{function1 function2} ...)} specifies that the
|
||
compiler should not compile the named functions in-line. Calls to the
|
||
named functions can be traced and an event (see Section 5.4) is pushed
|
||
on the event stack when any one of the named functions is invoked.
|
||
@end deffn
|
||
|
||
@deffn {Declaration} {inline} @{function-name@}*
|
||
An @code{inline} proclamation cancels currently effective @code{notinline}
|
||
proclamations, and a local @code{inline} declaration locally shadows currently
|
||
effective @code{notinline} declarations.
|
||
@end deffn
|
||
|
||
@example
|
||
>(defun foo (x)
|
||
(cons (car x)
|
||
(locally (declare (inline car)) (car x))))
|
||
foo
|
||
|
||
>(defun bar (x)
|
||
(cons (car x)
|
||
(locally (declare (inline car)) (car x))))
|
||
foo
|
||
|
||
>(proclaim '(notinline car))
|
||
nil
|
||
|
||
>(compile 'foo)
|
||
...
|
||
|
||
>(proclaim '(inline car))
|
||
nil
|
||
|
||
>(compile 'bar)
|
||
...
|
||
@end example
|
||
|
||
Usually, primitive functions such as @code{car} are compiled in-line.
|
||
Therefore, in this example, only the first call to @code{car} within @code{foo}
|
||
is compiled not in-line.
|
||
|
||
In general, the @ecl{} compiler compiles functions in-line whenever possible.
|
||
Thus an @code{inline} declaration @code{(inline @var{function1 function2} ...)}
|
||
is worthless if none of the named functions have previously been declared to be
|
||
@code{notinline}.
|
||
|
||
@deffn {Declaration} {ignore} @{variable-name@}*
|
||
Usually, the compiler issues a warning if a lexical variable is never referred
|
||
to. @code{(ignore @var{var1 ... varn})} causes the compiler not to issue a
|
||
warning even if the named variables are never referred to. The compiler issues
|
||
a warning if one of the named variables is not bound by the surrounding
|
||
construct, or if a named variable is actually referred to. @code{ignore}
|
||
proclamations are simply ignored.
|
||
@end deffn
|
||
|
||
@deffn {Declaration} {optimize} @{(quality value) | quality@}*
|
||
@ecl{} supports the four @code{optimize} qualities listed in the
|
||
@bibcite{Steele:84}.
|
||
|
||
@code{speed} and @code{compilation-speed} are used to set up the optimization
|
||
switch of the C language compiler which is invoked to compile the C-language
|
||
code generated by the @ecl{} compiler (see Chapter 6). @code{(optimize (speed
|
||
@var{n}))} and @code{(optimize (compilation-speed @var{m}))} are equivalent,
|
||
where @var{n} and @var{m} are integers between 0 and 3, and @var{m} is equal to
|
||
3-@var{n}. When a @ecl{} session is started, the @code{speed} quality is set
|
||
to 3. That is, by default, the compiler generates the fastest code in the
|
||
longest compilation time. The @code{space} quality specifies whether the code
|
||
size is important or not: The compiled code is a little bit larger and faster
|
||
when compiled with the space quality 0, than when compiled with the space
|
||
quality 1, 2, or 3. When a @ecl{} session is started, the @code{space}
|
||
quality is set to 0. The @code{safety} quality determines how much runtime
|
||
error checking code should be embedded in the compiled code. If the
|
||
@code{safety} quality is 0, the compiled code scarcely does runtime error
|
||
checking. If the @code{safety} quality is 1, then the compiled code for a
|
||
function will check the number of arguments to the function at runtime. If the
|
||
@code{safety} quality is 2 or 3, then the compiled code does full runtime error
|
||
checking. In addition, the highest quality value 3 causes the compiler to
|
||
treat all functions as if they were declared to be @code{notinline}. When a
|
||
@ecl{} session is started, the @code{safety} quality is set to 0.
|
||
@end deffn
|
||
|
||
@deffn {Declaration} {declaration} @{name@}*
|
||
A @code{declaration} declaration is used exactly as specified in the
|
||
@bibcite{Steele:84}.
|
||
@end deffn
|
||
|
||
@deffn {Declaration} {object} @{variable-name@}*
|
||
This is the only declaration specifier that is specific to @ecl{}.
|
||
@code{(object @var{var1 ... varn})} affects only variable bindings and
|
||
specifies that the named variables can be allocated in the C stack (see Section
|
||
7.3). The compiler issues a warning if one of the named variables is not bound
|
||
by the surrounding construct. @code{object} proclamations are simply ignored.
|
||
@end deffn
|
||
|
||
|
||
@node Type specifiers, Type declarations, Declaration specifiers, Declarations
|
||
@section Significant Type Specifiers
|
||
|
||
Whenever a declaration is encountered, each type specifier (if any) in the
|
||
declaration is converted to one of the following type specifiers, which are
|
||
collectively called the @emph{significant type specifiers}.
|
||
|
||
@example
|
||
|------------ fixnum
|
||
|------------ character
|
||
|------------ short-float
|
||
|------------ long-float
|
||
t --|---- (array t) -------------- (vector t)
|
||
|---- (array fixnum) --------- (vector fixnum)
|
||
|---- (array string-char) --- string
|
||
|---- (array short-float) --- (vector short-float)
|
||
|---- (array long-float) --- (vector long-float)
|
||
|---- (array bit) ----------- bit-vector
|
||
@end example
|
||
|
||
Here, the lines indicate subtype relations; the right type is a subtype of the
|
||
left type. For instance, @code{(vector t)} is a subtype of @code{(array t)}
|
||
and @true{}, and @code{(array t)} itself is a subtype of @true{}. However,
|
||
@code{(array t)} and @code{(array string-char)} are disjoint types.
|
||
|
||
The function @code{subtypep} is used for the conversion to significant type
|
||
specifiers: If the first value of @code{(subtypep @var{raw-type type})} is
|
||
@true{} for one of the significant type specifiers @var{type}, then the type
|
||
specifier @var{raw-type} in the declaration is converted to @var{type}. If
|
||
there are more than one such significant type specifiers, then the type
|
||
specifier that is a subtype of other specifiers is selected. For example, type
|
||
specifiers @tindexed{fixnum}, @code{(mod 3)}, and @code{(member 0 1)} are all
|
||
converted to @tindexed{fixnum}, though they are also subtypes of @true{}.
|
||
|
||
Because of this type specifier conversion, @ecl{} may sometimes regard two
|
||
seemingly distinct declarations as the same. For example, the following
|
||
@code{type} declarations are completely equivalent, internally in @ecl{}.
|
||
|
||
@example
|
||
declare (type fixnum x))
|
||
|
||
declare (type (mod 3) x))
|
||
|
||
declare (type (member 0 1) x))
|
||
@end example
|
||
|
||
Type specifiers in declaration specifications passed to the @ecl{} specific
|
||
function @code{proclamation} are also converted to significant type specifiers.
|
||
Thus, for example,
|
||
|
||
@example
|
||
>(proclaim '(function foo (fixnum) fixnum))
|
||
nil
|
||
|
||
>(proclamation '(function foo ((mod 3)) (member 0 1)))
|
||
t
|
||
|
||
>(proclamation '(function foo (number) character))
|
||
nil
|
||
@end example
|
||
|
||
The first call to @code{proclamation} returns @true{} because both @code{(mod
|
||
3)} and @code{(member 0 1)} are converted to @tindexed{fixnum} before the
|
||
function type of @code{foo} is checked.
|
||
|
||
|
||
@node Type declarations, Variable allocations, Type specifiers, Declarations
|
||
@section Treatment of Type Declarations
|
||
|
||
@ecl{} uses several runtime stacks.
|
||
|
||
Arguments to functions, lexical and temporary variables are allocated on the C
|
||
stack. Temporary values saved on the C stack may sometimes be represented as
|
||
@var{raw data} instead of pointers to heap-allocated cells. Accessing such raw
|
||
data on the C stack results in faster compiled code, partly because no pointer
|
||
dereferencing operation is necessary, and partly because no cell is newly
|
||
allocated on the heap when a new object is created. This is particularly
|
||
helpful for numeric code which computes with floating point numbers.
|
||
|
||
@ecl{} uses a conservative garbage collector to scan the C stack and find
|
||
references to live object.
|
||
|
||
@node Variable allocations, Raw data functions, Type declarations, Declarations
|
||
@section Variable Allocations
|
||
|
||
If a lexical variable is declared to be of @tindexed{fixnum}, @code{character},
|
||
@code{short-float}, @code{long-float}, or their subtypes, then it is allocated
|
||
on the C stack rather than on the value stack. In addition, the variable
|
||
always has a raw datum as its value: 32 bit signed integer for fixnums, 8 bit
|
||
character code with 24 bit padding for characters (remember that the font and
|
||
bit fields of @ecl{} characters are always 0), 32 bit floating point
|
||
representation for short-floats, and 64 bit floating point representation for
|
||
long-floats. Similarly, if a lexical variable is named in an @code{object}
|
||
declaration (see Section 7.1), then it is allocated on the C stack but, in this
|
||
case, the variable always has a cell pointer as its value. The user is
|
||
strongly recommended to make sure that objects stored in such an @code{object}
|
||
variable may never be garbage collected unexpectedly. For example,
|
||
|
||
@example
|
||
(do ((x (foo) (cdr x)))
|
||
((endp x))
|
||
(let ((y (car x)))
|
||
(declare (object y))
|
||
(bar y)))
|
||
@end example
|
||
|
||
@noindent
|
||
this @code{object} declaration is completely safe because the value of the
|
||
variable @var{y} is always a substructure of the value of @var{x}, which in
|
||
turn is protected against garbage collection. Incidentally, loop variables of
|
||
@code{dolist} may always be declared as object variables, since the
|
||
@code{dolist} form has essentially the same control structure as the @code{do}
|
||
form above. On the other hand, the result of evaluation of the following form
|
||
is unpredictable, because the cons cell pointed to from the @code{object}
|
||
variable @var{z} may be garbage collected before @code{bar} is called.
|
||
|
||
@example
|
||
(let ((z (cons x y)))
|
||
(declare (object z))
|
||
(foo (cons x y))
|
||
(bar z))
|
||
@end example
|
||
|
||
Lexical variables that are not declared to be of @tindexed{fixnum},
|
||
@tindexed{character}, @tindexed{short-float}, @tindexed{long-float}, or their
|
||
subtypes, and that are not named in @code{object} declarations are usually
|
||
allocated on the value stack, but may possibly be allocated on the C stack
|
||
automatically by the compiler.
|
||
|
||
|
||
@node Raw data functions, Arguments/Values passing, Variable allocations, Declarations
|
||
@section Built-in Functions that Operate on Raw Data Directly
|
||
|
||
Some built-in @clisp{} functions can directly operate on raw data, if
|
||
appropriate declarations are supplied. The addition function @code{+} is among
|
||
such functions.
|
||
|
||
@example
|
||
(let ((x 1))
|
||
(declare (fixnum x))
|
||
...
|
||
(setq x (+ x 2))
|
||
...
|
||
)
|
||
@end example
|
||
|
||
In the compiled code for this @code{let} form, the raw fixnum datum (i.e., the
|
||
32 bit signed integer) stored in @var{x} is simply incremented by 2 and the
|
||
resulting 32 bit signed integer is stored back into @var{x}. The compiler is
|
||
sure that the addition for 32 bit signed integers will be performed on the call
|
||
to @code{+}, because the arguments are both fixnums and the return value must
|
||
be also a fixnum since the value is to be assigned to the @tindexed{fixnum}
|
||
variable. The knowledge of both the argument types and the return type is
|
||
necessary for this decision: Addition of two fixnums may possibly produce a
|
||
bignum and addition of two bignums may happen to produce a fixnum value. If
|
||
either the argument type or the return type were not known to the compiler, the
|
||
general addition function would be called to handle the general case. In the
|
||
following form, for example, the compiler cannot be sure that the return value
|
||
of the multiplication is a fixnum or that the arguments of the addition are
|
||
fixnums.
|
||
|
||
@example
|
||
(setq x (+ (* x 3) 2))
|
||
@end example
|
||
|
||
In order to obtain the optimal code, a @code{the} special form should
|
||
surround the multiplication.
|
||
|
||
@example
|
||
(setq x (+ (the fixnum (* x 3)) 2))
|
||
@end example
|
||
|
||
Built-in @clisp{} functions that can directly operate on raw data are:
|
||
|
||
@enumerate
|
||
@item arithmetic functions such as @code{+}, @code{-},
|
||
@code{1+}, @code{1-}, @code{*}, @code{floor}, @code{mod}, @code{/}, and
|
||
@code{expt}.
|
||
|
||
@item predicates such as @code{eq}, @code{eql}, @code{equal},
|
||
@code{zerop}, @code{plusp}, @code{minusp}, @code{=}, @code{/=}, @code{<},
|
||
@code{<=}, @code{>}, @code{>=}, @code{char=}, @code{char/=}, @code{char<},
|
||
@code{char<=}, @code{char>}, and @code{char>=}.
|
||
|
||
@item sequence processing functions that receive or return one or more
|
||
fixnum values, such as @code{nth}, @code{nthcdr}, @code{length}, and
|
||
@code{elt}.
|
||
|
||
@item array access functions such as @code{svref}, @code{char}, @code{schar},
|
||
and @code{aref} (see below).
|
||
|
||
@item system-internal functions for array update (see below).
|
||
|
||
@item type-specific functions such as @code{char-code}, @code{code-char},
|
||
and @code{float}.
|
||
@end enumerate
|
||
|
||
As mentioned in Section 2.5.1, array elements are represented in one of six
|
||
ways depending on the type of the array. By supplying appropriate array type
|
||
declarations, array access and update operations can handle raw data stored in
|
||
arrays. For example,
|
||
|
||
@example
|
||
(let ((a (make-array n :element-type 'fixnum))
|
||
(sum 0))
|
||
(declare (type (array fixnum) a)
|
||
(fixnum sum))
|
||
(dotimes (i n) ;;; Array initialization.
|
||
(declare (fixnum i))
|
||
(setf (aref a i) i))
|
||
....
|
||
(dotimes (i n) ;;; Summing up the elements.
|
||
(declare (fixnum i))
|
||
(setq sum (+ (aref a i) sum)))
|
||
....
|
||
)
|
||
@end example
|
||
|
||
The @code{setf} form replaces the @code{i-th} element of the array a by the raw
|
||
fixnum value of @code{i}. The @code{aref} form retrieves the raw fixnum datum
|
||
stored in @code{a}. This raw datum is then added to the raw fixnum value of
|
||
the fixnum variable @code{sum}, producing the raw fixnum datum to be stored in
|
||
@code{sum}. Similar raw data handling is possible for arrays of types
|
||
@code{(array fixnum), (vector fixnum),
|
||
(array string-char), string,
|
||
(array short-float), (vector short-float),
|
||
(array long-float)}, and @code{(vector long-float)}.
|
||
|
||
@node Arguments/Values passing, , Raw data functions, Declarations
|
||
@section Arguments/Values Passing
|
||
|
||
Function proclamations @code{(function @var{function-name} (@var{arg-type1}
|
||
@var{arg-type2} ...) @var{return-type})} or its equivalents give the compiler
|
||
the chance to generate compiled code so that arguments to the named functions
|
||
and resulting values of the named functions will be passed via the C stack,
|
||
thus increasing the efficiency of calls to these functions. Such
|
||
arguments/values passing via the C stack is possible only if the called
|
||
function is also defined in the same source file. This is because the code for
|
||
the called function must have two entries: One entry for C arguments/values
|
||
passing and another for ordinary Lisp arguments/values passing. (An ordinary
|
||
function has only the latter entry.) When the latter entry is used, the
|
||
arguments are @emph{unboxed} and passed to the former entry. On return from
|
||
the function, the resulting value is cast into a Lisp data type.
|
||
|
||
A good example of this follows.
|
||
|
||
@example
|
||
(eval-when (compile)
|
||
(proclaim '(function tak (fixnum fixnum fixnum) fixnum)))
|
||
|
||
(defun tak (x y z)
|
||
(declare (fixnum x y z))
|
||
(if (not (< y x))
|
||
z
|
||
(tak (tak (1- x) y z)
|
||
(tak (1- y) z x)
|
||
(tak (1- z) x y))))
|
||
|
||
;;; Call (tak 18 12 6).
|
||
@end example
|
||
|
||
When @code{tak} is called with the arguments @code{18, 12}, and @code{6}, the
|
||
raw fixnum data of the arguments are set to the parameters @code{x}, @code{y},
|
||
@code{z}. After that, only raw C data are used to perform the execution: No
|
||
cell pointers are newly allocated nor even referenced. The built-in functions
|
||
@code{<} and @code{1-} directly operate on the raw data. Only at the return from
|
||
the top-level call of @code{tak}, the resulting raw data value (which happens
|
||
to be @code{7}) is reallocated on the heap. Note that both the @code{function}
|
||
proclamation and the local @tindexed{fixnum} declaration are necessary to
|
||
obtain the optimal code. The @code{function} proclamation is necessary for
|
||
arguments/values passing via the C stack and the @tindexed{fixnum} declaration
|
||
is necessary to unbox the parameters into C variables.
|
||
|
||
|
||
@node OS interface, Macros, Declarations, Top
|
||
@chapter Operating System Interface
|
||
|
||
@ecl{} provides the following facilities that are not defined in
|
||
@bibcite{Steele:84}.
|
||
|
||
@defun {system} {string}
|
||
Executes a Shell command as if @var{string} is an input to the Shell. On
|
||
return from the Shell command, @code{system} returns the exit code of the
|
||
command as an integer.
|
||
@end defun
|
||
|
||
@defun {open-pipe} {string}
|
||
Executes a Shell command as if @var{string} is an input to the Shell. It
|
||
returns a stream corresponding to the output stream of the Shell command, from
|
||
which one can read its output.
|
||
@end defun
|
||
|
||
|
||
@defun {quit} {@optional{} exit-code}
|
||
Terminates @ecl{} and returns the @var{exit-code} to the parent process.
|
||
@var{exit-code} must be an integer and its default value is @code{0}.
|
||
@end defun
|
||
|
||
@node Macros, CLOS, OS interface, Top
|
||
@chapter Macros
|
||
|
||
A @dfn{defmacro lambda-list} is a lambda-list-like construct that is used as
|
||
the third element in the @code{defmacro} form,
|
||
@example
|
||
(defmacro @var{name} @var{efmacro-lambda-list} [@var{declaration} | @var{doc-string}] @{@var{form}@}*)
|
||
@end example
|
||
|
||
The description of defmacro lambda-lists in @bibcite{Steele:84} is quite
|
||
ambiguous. @ecl{} employs the following syntax.
|
||
|
||
The complete syntax of a defmacro lambda-list is:
|
||
|
||
@example
|
||
( [&whole @var{var}]
|
||
[&environment @var{var}]
|
||
[@var{pseudo-var}]
|
||
[@optional{} @{var | ( pseudo-var [initform [pseudo-var]] )@}<7D>]
|
||
@{[@{@rest{} | &body@} pseudo-var]
|
||
[@keys{} @{var
|
||
| (@{var | (keyword pseudo-var)@} [initform [pseudo-var]])@}*
|
||
[@allow{}]]
|
||
[@aux{} @{var | (pseudo-var [initform])@}*]
|
||
| . var @}
|
||
)
|
||
@end example
|
||
|
||
@noindent
|
||
where @var{pseudo-var} is either a symbol or a list of the following
|
||
form:
|
||
|
||
@example
|
||
( @{pseudo-var@}*
|
||
[@optional{} @{var | (pseudo-var [initform [pseudo-var]])@}*]
|
||
@{[@{@rest{} | &body@} pseudo-var]
|
||
[@keys{} @{var | (@{var | (keyword pseudo-var)@}
|
||
[initform [pseudo-var]])@}*
|
||
[@allow{}]]
|
||
[@aux{} @{var | (pseudo-var [initform])@}]
|
||
| . var @}
|
||
)
|
||
@end example
|
||
|
||
The defmacro lambda-list keyword @code{&whole} may appear only at the
|
||
top-level, first in the defmacro lambda-list. It is not allowed within
|
||
@var{pseudo-var}. Use of the @code{&whole} keyword does not affect the
|
||
processing of the rest of the defmacro lambda-list:
|
||
|
||
@example
|
||
(defmacro foo (&whole w x y) ...)
|
||
@end example
|
||
and
|
||
@example
|
||
(defmacro foo (x y) ...)
|
||
@end example
|
||
|
||
@noindent
|
||
both bind the variables @code{x} and @code{y} to the second and the
|
||
third elements, respectively, of macro forms of @code{foo}.
|
||
|
||
The defmacro lambda-list keyword @code{&environment} may appear only at the
|
||
top-level, first in the defmacro lambda-list if @code{&whole} is not supplied,
|
||
or immediately after the variable that follows @code{&whole}, if @code{&whole}
|
||
is supplied. @code{&environment} is not allowed within @var{pseudo-var}. Like
|
||
@code{&whole}, use of @code{&environment} does not affect the processing of the
|
||
rest of the defmacro lambda-list. If an @code{&environment} parameter is
|
||
supplied and if this parameter is not used at all, then the @ecl{} compiler
|
||
will issue a warning. To suppress the warning, just remove the parameter from
|
||
the defmacro lambda-list, or add an @code{ignore} declaration.
|
||
|
||
The defmacro lambda-list keyword @code{&body} is completely equivalent to the
|
||
@rest{} keyword. @ecl{} takes no special action for @code{&body} parameters.
|
||
|
||
Although useless, @ecl{} allows supplied-p parameters to be destructured.
|
||
This is useless because supplied-p parameters can never be bound to a non-empty
|
||
list. Our intention is to stick to the specification in the
|
||
@bibcite{Steele:84} as far as possible, even if it is silly to do so.
|
||
|
||
Like for ordinary lambda-lists, the interpreter detects invalid arguments to
|
||
macro expansion functions. When a parameter is destructured, the structure of
|
||
the corresponding argument is also checked. Such runtime argument checking may
|
||
or may not be embedded in compiled code, depending on the environment when the
|
||
code was generated. If the code was generated while the @code{safety} optimize
|
||
level is zero (that is, while the value of @code{(proclamation '(optimize
|
||
(safety 0)))} is @true{}), then the generated code does not perform argument
|
||
checking at all. Otherwise, the compiled code does check the validity of
|
||
arguments.
|
||
|
||
|
||
@node CLOS, Multithread, Macros, Top
|
||
@chapter CLOS
|
||
|
||
@deffn {Generic} {add-method} generic-function method
|
||
@deffnx {Method} {add-method} {(generic-function standard-generic-function) (method method)}
|
||
@end deffn
|
||
|
||
@defmac {call-method} {method next-method-list}
|
||
@end defmac
|
||
|
||
@defmac {call-next-method} {@rest{} args}
|
||
@end defmac
|
||
|
||
@deffn {Generic} {change-class} instance new-class
|
||
@deffnx {Method} {change-class} {(instance standard-object) (new-class standard-class)}
|
||
@deffnx {Method} {change-class} {(instance t) (new-class symbol)}
|
||
@end deffn
|
||
|
||
@deffn {Generic} {class-name} class
|
||
@deffnx {Method} {class-name} {(class class)}
|
||
@end deffn
|
||
|
||
@deffn {Generic} {(setf class-name)} new-value class
|
||
@deffnx {Method} {(setf class-name)} {new-value (class class)}
|
||
@end deffn
|
||
|
||
@defun {class-of} {object}
|
||
The function @code{class-of} returns the class of which the given object is an
|
||
instance. The argument to class-of may be any @clisp{} object.
|
||
@end defun
|
||
|
||
@defun {compute-applicable-methods} {generic-function function-arguments}
|
||
@end defun
|
||
|
||
@defmac {defclass} {class-name (@{superclass-name@}*)} (@{slot-specifier@}*) [class-option]
|
||
@example
|
||
@var{class-name} ::= @var{symbol}
|
||
@var{superclass-name} ::= @var{symbol}
|
||
@var{slot-specifier} ::= @var{slot-name} | (@var{slot-name} [@var{slot-option}])
|
||
@var{slot-name} ::= @var{symbol}
|
||
@var{slot-option} ::= @{:reader @var{reader-function-name}@}*
|
||
| @{:writer @var{writer-function-name}@}*
|
||
| @{:accessor @var{reader-function-name}@}*
|
||
| @{:allocation @var{allocation-type}@}
|
||
| @{:initarg @var{initarg-name}@}*
|
||
| @{:initform @var{form}@}
|
||
| @{:type @var{type-specifier}@}
|
||
| @{:documentation @var{string}@}
|
||
@var{reader-function-name} ::= @var{symbol}
|
||
@var{writer-function-name} ::= @var{function-name}
|
||
@var{function-name} ::= @var{symbol} |(setf @var{symbol})
|
||
@var{initarg-name} ::= @var{symbol}
|
||
@var{allocation-type} ::= :instance | :class
|
||
@var{class-option} ::= (:default-initargs @var{initarg-list})
|
||
| (:documentation @var{string})
|
||
| (:metaclass @var{class-name})
|
||
@var{initarg-list} ::= @{@var{initarg-name} @var{default-initial-value-form}@}*
|
||
@end example
|
||
@end defmac
|
||
|
||
@defmac {defgeneric} {function-name lambda-list [option | @{method-description@}*]}
|
||
@example
|
||
@var{function-name} ::= @var{symbol} | (setf @var{symbol})
|
||
@var{lambda-list} ::= (@{@var{var}@}*
|
||
[@optional{} @{@var{var} | (@var{var})@}*]
|
||
[@rest{} @var{var}]
|
||
[@keys{} @{@var{keyword-parameter}@}* [@allow{}]])
|
||
@var{keyword-parameter} ::= @var{var} | ( @{@var{var} | (@var{keywordvar} )@})
|
||
@var{option} ::= (:argument-precedence-order @{@var{parameter-name}@}+)
|
||
| (declare @{@var{declaration}@}+)
|
||
| (:documentation @var{string})
|
||
| (:method-combination symbol @{@var{arg}@}*)
|
||
| (:generic-function-class @var{class-name})
|
||
| (:method-class @var{class-name})
|
||
@var{method-description} ::=
|
||
(:method @{@var{method-qualifier}@}* @var{specialized-lambda-list}
|
||
[@{@var{declaration}@}* | @var{documentation}]
|
||
@{@var{form}@}*)
|
||
@var{method-qualifier} ::= @var{non-nil-atom}
|
||
@var{specialized-lambda-list} ::= (@{@var{var} | (@var{var} @var{parameter-specializer-name})@}*
|
||
[@optional{} @{@var{var} | (@var{var} [@var{initform} [@var{supplied-p-parameter}]])@}*]
|
||
[@rest{} @var{var}]
|
||
[@keys{} @{@var{specialized-keyword-parameter}@}* [@allow{}]])
|
||
[@aux{} @{@var{var} | (@var{var} [@var{initform}])@}*] )
|
||
@var{specialized-keyword-parameter} ::= @var{var}
|
||
| @{(@{@var{var} | (@var{keywordvar})@} [@var{initform} [@var{supplied-p-parameter}]])@}*
|
||
@var{parameter-specializer-name} ::= @var{symbol} | (eql @var{eql-specializer-form})
|
||
@end example
|
||
@end defmac
|
||
|
||
@defmac {define-method-combination} {name [short-form-option]}
|
||
@defmacx {define-method-combination} {name lambda-list (@{method-group-specifier@}*) [(:arguments . lambda-list)] [(:generic-function generic-fn-symbol)] [@{declaration@}* | doc-string] @{form@}*}
|
||
@example
|
||
@var{short-form-option} ::= :documentation @var{string}
|
||
| :identity-with-one-argument @var{boolean}
|
||
| :operator @var{operator}
|
||
@var{method-group-specifier} ::= (@var{variable} @{@var{qualifier-pattern}@}+ | @var{predicate}
|
||
[@var{long-form-option}])
|
||
@var{long-form-option} ::= :description @var{format-string}
|
||
| :order @var{order}
|
||
| :required @var{boolean}
|
||
@end example
|
||
@end defmac
|
||
|
||
@defmac {defmethod} {function-name @{method-qualifier@}+ specialized-lambda-list [@{declaration@}* | doc-string] @{form@}*}
|
||
@example
|
||
@var{function-name} ::= @var{symbol} | (setf @var{symbol})
|
||
@var{method-qualifier} ::= @var{non-nil-atom}
|
||
@var{parameter-specializer-name} ::= @var{symbol} | (eql @var{eql-specializer-form} )
|
||
@end example
|
||
@end defmac
|
||
|
||
@deffn {Generic} {documentation} x @optional{} doc-type
|
||
@deffnx {Method} {documentation} {(method standard-method) @optional{} doc-type}
|
||
@deffnx {Method} {documentation} {(generic-function standard-generic-function) @keys{@optional{} doc-type}}
|
||
@deffnx {Method} {documentation} {(class standard-class) @optional{} doc-type}
|
||
@deffnx {Method} {doumentation} {(method-combination method-combination) @optional{} doc-type}
|
||
@deffnx {Method} {documentation} {(slot-description standard-slot-description) @keys{@optional{} doc-type}}
|
||
@deffnx {Method} {documentation} {(symbol symbol) @optional{} doc-type}
|
||
@deffnx {Method} {documentation} {(list list) @optional{} doc-type}
|
||
@end deffn
|
||
|
||
@deffn {Generic} {(setf documentation)} new-value x @optional{} doc-type
|
||
@deffnx {Method} {(setf documentation)} {new-value (method standard-method) @optional{} doc-type}
|
||
@deffnx {Method} {(setf documentation)} {new-value (class standard-class) @optional{} doc-type}
|
||
@deffnx {Method} {(setf documentation)} {new-value (method-combination method-combination)}
|
||
@deffnx {Method} {(setf documentation)} {new-value (slot-description standard-slot-description) @optional{} doc-type}
|
||
@deffnx {Method} {(setf documentation)} {new-value (symbol symbol) @optional{} doc-type}
|
||
@deffnx {Method} {(setf documentation)} {new-value (list list) @optional{} doc-type}
|
||
@end deffn
|
||
|
||
@defun {ensure-generic-function} @{function-name @keys{} lambda-list @keys :argument-precedence-order :declare :documentation :generic-function-class|ekeys{:method-combination :method-class :environment}@}
|
||
@example
|
||
function-name ::= symbol | (setf symbol)
|
||
@end example
|
||
@end defun
|
||
|
||
@defun {find-class} {symbol @optional{} errorp environment}
|
||
|
||
The function find-class returns the class object named by the given symbol in the given environment.
|
||
The first argument to find-class is a symbol.
|
||
@end defun
|
||
|
||
@deffn {Generic} {find-method} generic-function method-qualifiers specializers @optional{} errorp
|
||
@deffnx {Method} {find-method} {(generic-function standard-generic-function)}
|
||
method-qualifiers specializers @optional{} errorp
|
||
@end deffn
|
||
|
||
@deffn {Generic} {function-keywords} method
|
||
@deffnx {Method} {function-keywords} {(method standard-method)}
|
||
@end deffn
|
||
|
||
The generic function function-keywords is used to return the keyword parameter specifiers for a given method.
|
||
|
||
@defmac {generic-function} @{lambda-list \mchoice{option | @{method-description@}*}@}
|
||
|
||
@example
|
||
option ::= (:argument-precedence-order @{parameter-name@}+)
|
||
| (declare @{declaration@}+)
|
||
| (:documentation string)
|
||
| (:method-combination symbol @{arg@}*)
|
||
| (:generic-function-class class-name)
|
||
| (:method-class class-name)
|
||
method-description ::= (:method @{method-qualifier@}*
|
||
specialized-lambda-list
|
||
@{declaration | @var{documentation}@}*
|
||
@{form@}*)
|
||
@end example
|
||
The @code{generic-function} macro creates an anonymous generic function. The
|
||
generic function is created with the set of methods specified by its method
|
||
descriptions. The @var{option}, @var{method-qualifier}, and
|
||
@var{specialized-lambda-list} arguments are the same as for @code{defgeneric}.
|
||
The generic function object is returned as the result. If no method
|
||
descriptions are specified, an anonymous generic function with no methods is
|
||
created. See @macref{defgeneric}, @macref{generic-flet},
|
||
@macref{generic-labels}, @macref{defmethod}.
|
||
@end defmac
|
||
|
||
@deffn {Generic} {initialize-instance} instance @rest{} initargs
|
||
@deffnx {Method} {initialize-instance} {(instance standard-object) @rest{} initargs}
|
||
|
||
The generic function @code{initialize-instance} is called by
|
||
@code{make-instance} to initialize a newly created instance. The generic
|
||
function @code{initialize-instance} is called with the new instance and the
|
||
defaulted initialization arguments.
|
||
@end deffn
|
||
|
||
@defun {invalid-method-error} {method format-string @rest{} args}
|
||
|
||
The function @code{invalid-method-error} is used to signal an error when there
|
||
is an applicable method whose qualifiers are not valid for the method
|
||
combination type. The error message is constructed by using a format string
|
||
and any arguments to it. Because an implementation may need to add additional
|
||
contextual information to the error message, invalid-method-error should be
|
||
called only within the dynamic extent of a method combination function. The
|
||
function invalid-method-error is called automatically when a method fails to
|
||
satisfy every qualifier pattern and predicate in a define-method-combination
|
||
form. A method combination function that imposes additional restrictions
|
||
should call invalid-method-error explicitly if it encounters a method it cannot
|
||
accept.
|
||
@end defun
|
||
|
||
@deffn {Generic} {make-instance} class @rest{}@var{ initargs}
|
||
@deffnx {Method} {make-instance} {(class standard-class) @rest{} initargs}
|
||
@deffnx {Method} {make-instance} {(class symbol) @rest{} initargs}
|
||
|
||
The generic function make-instance creates and returns a new instance of the
|
||
given class. The generic function make-instance may be used as described in
|
||
section 1.9. The class argument is a class object or a symbol that names a
|
||
class. The remaining arguments form a list of alternating initialization
|
||
argument names and values. If the second of the above methods is selected,
|
||
that method invokes make-instance on the arguments (find-class class) and
|
||
initargs. The initialization arguments are checked within make-instance (see
|
||
section 1.9). The new instance is returned.
|
||
@end deffn
|
||
|
||
@deffn {Generic} {make-instances-obsolete} class
|
||
@deffnx {Method} {make-instances-obsolete} {(class standard-class)}
|
||
@deffnx {Method} {make-instances-obsolete} {(class symbol)}
|
||
@end deffn
|
||
|
||
@defun {method-combination-error} {format-string @rest{} args}
|
||
|
||
The function method-combination-error is used to signal an error in method
|
||
combination. The error message is constructed by using a format string and any
|
||
arguments to it. Because an implementation may need to add additional
|
||
contextual information to the error message, method-combination-error should be
|
||
called only within the dynamic extent of a method combination function. The
|
||
format-string argument is a control string that can be given to format, and
|
||
args are any arguments required by that string.
|
||
@end defun
|
||
|
||
@deffn {Generic} {method-qualifiers} method
|
||
@deffnx {Method} {method-qualifiers} {(method standard-method)}
|
||
|
||
The generic function method-qualifiers returns a list of the qualifiers
|
||
of the given method.
|
||
@end deffn
|
||
|
||
@defun {next-method-p} {}
|
||
|
||
The locally defined function next-method-p can be used within the body of a
|
||
method defined by a method-defining form to determine whether a next method
|
||
exists.
|
||
@end defun
|
||
|
||
@deffn {Generic} {no-applicable-method} generic-function @rest{} function-arguments
|
||
@deffnx {Method} {no-applicable-method} {(generic-function t) @rest{} function-arguments}
|
||
|
||
The generic function no-applicable-method is called when a generic function of
|
||
the class standard-generic-function is invoked and no method on that generic
|
||
function is applicable. The default method signals an error.
|
||
@end deffn
|
||
|
||
@deffn {Generic} {no-next-method} generic-function method @rest{} args
|
||
@deffnx {Method} {no-next-method} {(generic-function standard-generic-function) (method standard-method) @rest{} args}
|
||
@end deffn
|
||
|
||
@deffn {Generic} {print-object} object stream
|
||
@deffnx {Method} {print-object} {(object standard-object) stream}
|
||
|
||
The generic function print-object writes the printed representation of an
|
||
object to a stream. The function print-object is called by the print system;
|
||
it should not be called by the user.
|
||
@end deffn
|
||
|
||
@deffn {Generic} {reinitialize-instance} instance @rest{} initargs
|
||
@deffnx {Method} {reinitialize-instance} {(instance standard-object) @rest{} initargs}
|
||
|
||
The generic function reinitialize-instance can be used to change the
|
||
values of local slots according to initialization arguments. This
|
||
generic function is called by the Meta-Object Protocol. It can also be
|
||
called by users.
|
||
@end deffn
|
||
|
||
@deffn {Generic} {remove-method} generic-function method
|
||
@deffnx {Method} {remove-method} {(generic-function standard-generic-function) method}
|
||
|
||
The generic function remove-method removes a method from a generic function.
|
||
It destructively modifies the specified generic function and returns the
|
||
modified generic function as its result.
|
||
@end deffn
|
||
|
||
@deffn {Generic} {shared-initialize} @var{instance slot-names @rest{} initargs}
|
||
@deffnx {Method} {shared-initialize} {(instance standard-object) slot-names @rest{} initargs}
|
||
|
||
The generic function shared-initialize is used to fill the slots of an instance
|
||
using initialization arguments and :initform forms. It is called when an
|
||
instance is created, when an instance is re-initialized, when an instance is
|
||
updated to conform to a redefined class, and when an instance is updated to
|
||
conform to a different class. The generic function @code{shared-initialize} is
|
||
called by the system-supplied primary method for @code{initialize-instance},
|
||
@code{reinitialize-instance}, @code{update-instance-for-redefined-class}, and
|
||
@code{update-instance-for-different-class}.
|
||
@end deffn
|
||
|
||
@defun {slot-boundp} {instance slot-name}
|
||
|
||
The function slot-boundp tests whether a specific slot in an instance is bound.
|
||
The arguments are the instance and the name of the slot.
|
||
@end defun
|
||
|
||
@defun {slot-exists-p} {object slot-name}
|
||
|
||
The function slot-exists-p tests whether the specified object has a slot of the
|
||
given name. The object argument is any object. The slot-name argument is a
|
||
symbol.
|
||
@end defun
|
||
|
||
@defun {slot-makunbound} {instance slot-name}
|
||
|
||
The function slot-makunbound restores a slot in an instance to the unbound
|
||
state. The arguments to slot-makunbound are the instance and the name of the
|
||
slot.
|
||
@end defun
|
||
|
||
@deffn {Generic} {slot-missing} class object slot-name operation @optional{} new-value
|
||
@deffnx {Method} {slot-missing} {(class t) object slot-name operation @optional{} new-value}
|
||
|
||
The generic function slot-missing is invoked when an attempt is made to access
|
||
a slot in an object whose metaclass is standard-class and the name of the slot
|
||
provided is not a name of a slot in that class. The default method signals an
|
||
error.
|
||
@end deffn
|
||
|
||
@deffn {Generic} {slot-unbound} class instance slot-name
|
||
@deffnx {Method} {slot-unbound} {(class t) instance slot-name}
|
||
|
||
The generic function slot-unbound is called when an unbound slot is read in an
|
||
instance whose metaclass is standard-class. The default method signals an
|
||
error.
|
||
@end deffn
|
||
|
||
@defun {slot-value} {object slot-name}
|
||
|
||
The function slot-value returns the value contained in the slot slot-name of
|
||
the given object. If there is no slot with that name, slot-missing is called.
|
||
If the slot is unbound, slot-unbound is called. The macro setf can be used
|
||
with slot-value to change the value of a slot.
|
||
@end defun
|
||
|
||
@deffn {Generic} {update-instance-for-different-class} previous current @rest{} initargs
|
||
@deffnx {Method} {update-instance-for-different-class} {(previous standard-object) (currentstandard-object) @rest{} initargs}
|
||
@end deffn
|
||
|
||
@deffn {Generic} {update-instance-for-redefined-class} instance added-slots discarded-slots property-list @rest{} initargs
|
||
@deffnx {Method} {update-instance-for-redefined-class} {(instance standard-object) added-slots discarded-slots property-list @rest{} initargs}
|
||
@end deffn
|
||
|
||
@defmac {with-accessors} {(@{slot-entry@}*) instance-form @{declaration@}* @{form@}*}
|
||
|
||
The macro with-accessors creates a lexical environment in which specified slots
|
||
are lexically available through their accessors as if they were variables. The
|
||
macro with-accessors invokes the appropriate accessors to access the specified
|
||
slots. Both setf and setq can be used to set the value of the slot. The
|
||
result returned is that obtained by executing the forms specified by the body
|
||
argument.
|
||
@end defmac
|
||
|
||
@defmac {with-slots} {(@{slot-entry@}*) instance-form @{declaration@}* @{form@}*}
|
||
@example
|
||
@var{slot-entry} ::= @var{slot-name} | (@var{variable-name} @var{slot-name})
|
||
@end example
|
||
|
||
The macro @code{with-slots} creates a lexical context for referring to
|
||
specified slots as though they were variables. Within such a context the value
|
||
of the slot can be specified by using its slot name, as if it were a lexically
|
||
bound variable. Both @code{setf} and @code{setq} can be used to set the value
|
||
of the slot.
|
||
@end defmac
|
||
|
||
|
||
@node Multithread, Bibliography, CLOS, Top
|
||
@chapter Multithread
|
||
|
||
[To come once the interface is fixed]
|
||
|
||
@node Bibliography, , Multithread, Top
|
||
@chapter Bibliography
|
||
|
||
@table @b
|
||
@item ANSI
|
||
ANSI @clisp{} Specification, 1986.
|
||
|
||
@item Steele:84
|
||
Guy L. Steele Jr. et al. ``Common Lisp: the Language'',
|
||
Digital Press, 1984.
|
||
|
||
@item Steele:90
|
||
Guy L. Steele Jr. at al. ``Common Lisp: the Language II'', second edition,
|
||
Digital Press, 1990.
|
||
|
||
@item Yasa:85
|
||
Taiichi Yuasa and Masami Hagiya ``Kyoto @clisp{} Report'',
|
||
Research Institute for Mathematical Sciences, Kyoto University, 1988.
|
||
|
||
@item Smith:84
|
||
B.C. Smith and J. des Rivieres ``The Implementation of
|
||
Procedurally Reflective Languages'', @emph{Proc. of the 1984 ACM
|
||
Symposium on LISP and Functional Programming}, 1984.
|
||
@end table
|
||
|
||
@bye
|