diff --git a/src/CHANGELOG b/src/CHANGELOG index 0dec7dfc3..9647110d5 100755 --- a/src/CHANGELOG +++ b/src/CHANGELOG @@ -58,6 +58,10 @@ ECL 10.3.2: - ECL restores the habit of installing manual pages for ecl and ecl-config. + - We have removed the obsolete versions of the documentation files. The + up to date documentation now lives in a separate source repository, + as explained in http://ecls.sourceforge.net/download.html + ECL 10.3.1: =========== diff --git a/src/doc/BUGS b/src/doc/BUGS deleted file mode 100644 index 23bef800c..000000000 --- a/src/doc/BUGS +++ /dev/null @@ -1,67 +0,0 @@ -THINGS IN THIS FILE -=================== - -This file documents assumptions which are made throughout the ECLS code. Most -of them are critical and a lot of code relies on them, some others are very -localized but in critical points (eval, apply, etc). In general great care -must be taken so that changes in ECLS do not break these "invariants". - - -REAL BUGS -========= - -* Routines in bind.c do not check length of arguments and may cause buffer - overflows. - -GCC SPECIFICS -============= - -* Functions with a variable number of arguments are called with the - same protocol as ordinary functions, i.e., the following code is - valid - - #in "foo.c" - extern int fa(int foo, ...); - int test(object x) { - faa(1, x); - } - - #in "faa.c" - int faa(int foo, object x) { - ... - } - - -OPERATING SYSTEM -================ - -* Stack checks are required in compiled code to make sure recursion - does not get too deep. This makes sense in multithreaded code, but - do unix-like operating systems really provide no stack protection? - - -ECLS CODE INVARIANTS -==================== - -* C structs are aligned at least at 4 bytes, so that Cnil is a valid - object pointer. - -* "struct ecl_symbol" and "struct ecl_cons" share fields so that - Cnil->c.c_car == Cnil->c.c_cdr == Cnil. - -* "struct ecl_array", "struct ecl_vector", "struct ecl_string, "struct - ecl_bitvector" share a number of fields, such as "*_dim", "*_self", etc. - -* Boehm's garbage collector returns pointers with two lower bits set - to zero, i.e., - - ((int)GC_malloc(n)) & 3 == 0 - -* Frame/binding/history stacks cannot be resized. - -* DATA_START % LISP_PAGESIZE == 0 - -;;; Local Variables: *** -;;; mode:text *** -;;; fill-column:79 *** -;;; End: *** diff --git a/src/doc/basic.css b/src/doc/basic.css deleted file mode 100644 index 6ad3dd6ea..000000000 --- a/src/doc/basic.css +++ /dev/null @@ -1,32 +0,0 @@ -html { background: #000; } -body { - margin: 4em 10% 0 10%; - line-height: 1.4; - padding: 0 2em 1em 2em; - font-family: sans-serif; - background: #FFF; -} -h1, h2, h3, h4, h5, div.node { background: #DDD; } -body p { text-align: justify; max-width: 100%; } -code, pre { font-family: monospace; font-size: 1em; } -pre.smallformat, pre.example { - font: bold smaller monospace; - max-width: 100%; - background: #EEE; - overflow: auto; - border: 1px solid #000; -} -pre.smallformat { padding: 0.5em; } -a { color: #000; font-weight: bold; } -div.node { - position: fixed; - top: 0; - height: 3em; - width: 80%; - left: 10%; - line-height: 1; - font-weight: bold; - text-align: center; -} -div p { padding: 0 2em } -hr { display: none; } diff --git a/src/doc/devel.txi b/src/doc/devel.txi deleted file mode 100644 index 49bc201df..000000000 --- a/src/doc/devel.txi +++ /dev/null @@ -1,1714 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename ecldev.info -@settitle ECL Developers' Guide -@setchapternewpage odd -@c %**end of header - -@c Entries for @command{install-info} to use -@dircategory Lisp Programming -@direntry -* ecldev: (ecldev). Embeddable Common Lisp (ECL) Developer's Manual -@end direntry - -@include macros.txi - -@ifinfo -@ecl{} is an implementation of @clisp{} designed for being @emph{embeddable} -into C based applications. This manual documents the interface for C programmers. - -@noindent -Copyright @copyright{} 2001, Juan Jose Garcia-Ripoll -@end ifinfo - -@titlepage -@title ECL Developers' Guide -@author Juan Jose Garcia Ripoll - -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 2001, 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 guts of the @ecl{} implementation and how it can cooperate with -code written in other languages, such as C and C++. See -@inforef{Top,,ecl} for details about the @clisp{} implementation and how it -differs from standards. - - -@menu -* Introduction:: How @ecl{} relates to C/C++. -* Building programs:: How to build programs using ECL. -* Lisp objects:: Dealing with lisp object from C. -* The interpreter:: Understanding the interpreter. -* The compiler:: How the Lisp2C translator works. -* The Garbage Collector:: Get the GC to do the right thing -* Porting ECL:: Porting @ecl{} to other architectures. -@end menu - -@c --------------------------------------------------------------------- - -@node Introduction, Building programs, Top, Top -@chapter Introduction - -@ecl{} is an implementation of the @clisp{} language that is based on a kernel -written in C plus a set of libraries written in @clisp{}. The kernel includes a -bytecodes compiler, an interpreter, and enough functions to create and -manipulate all lisp objects. The lisp libraries provide higher level constructs -such as macro definitions, LOOPs, an implementation of CLOS, and a translator -from Lisp to C. - -As a result of this design, which dates back to the Kyoto CL and was later -improved in Giuseppe Attardi's ECoLisp, @ecl{} can be used as -@itemize -@item As a standalone implementation of the @clisp{} language -@item As an embedded interpreter subject to the control of a larger C program. -@item As a @clisp{} environment with C/C++ extensions. -@end itemize -@noindent -This manual describes the facility of @ecl{} to interface the C language and -@ecl{}. With this facility, the user can arrange his or her C-language -programs so that they can be invoked from @ecl{}. In addition, the user can -write Lisp function definitions in the C language to increase runtime -efficiency. - -@c --------------------------------------------------------------------- - -@node Building programs, Lisp objects, Introduction, Top -@chapter Building programs - -In this chapter we describe how you can use @ecl{} to build programs and -loadable extensions that you can later on distribute to other people. -@menu -* What can ECL do?:: -* Compiling files:: -* Building standalone executables:: -* Building libraries:: -* File names:: -* Compiler examples:: -@end menu - -@node What can ECL do?, Compiling files, Building programs, Building programs -@section What can @ecl{} do? - -Some day for some reasons you will be in the need to distribute code that -has been developed using @ecl{}. In the following sections we will describe -the means that @ecl{} offers you to do so. Basically, these are the -alternatives - -@table @sc -@item Source code -You distribute your programs in source code form. This is the easiest and most -portable way, but not the fastest one. -@item Standalone programs -You translate all your lisp code to C using the @ecl{} compiler. The final -object files can be linked against other C/C++ libraries to obtain a standalone -executable. -@item You can build statically and dynamically linked libraries. -You translate all your lisp code to C and combine the resulting object files -into a single library with @file{.a} extension. You can distribute this library -to other people and the final users can utilize these libraries to build -standalone programs. -@item You can build dynamically loadable files. -This is the most flexible way. You translate all lisp code to C and link it -against possibly other C/C++ libraries to obtain a dynamically loadable library -(file type @file{.so} under unix). This library can be loaded a startup time to -add new functionality to the @ecl{} environment. -@end table - -In several of these options, we have mentioned the possibility to include C/C++ -code. Even if this is possible, you cannot use ordinary C/C++ compilers and -makefiles to build @ecl{} extensions, let it be programs or -libraries. Briefly, you have to organize your code as follows -@enumerate -@item Organize the C code as a library, let it be static or dynamic. -@item Build a function, say @code{mymain()}, in which the initialization phase -for your library is performed. -@item Group the code that interfaces to Lisp in separate C files, all of which -should include @code{#include } at the beginning. -@item Compile your lisp source files. -@item Let @ecl{} build the final executable or library. -@end enumerate -@noindent -In the final step there are ways to instruct @ecl{} to call your -initialization function (@code{mymain()} in the example above). These means -are explained in the following sections. - -@c --------------------------------------------------------------------- - -@node Compiling files, Building standalone executables, What can ECL do?, Building programs -@section Compiling files - -@ecl{} supports two types of compilation. One is bytecodes compilation. This -process is performed on-the-fly, as you load source files with lisp code. This -leads to a series of bytes for each instruction, the so called -"bytecodes". These bytecodes are interpreted in a virtual machine, which is -written in C and which is reasonably fast. - -The other type of compilation is the so-called "native" compilation. This -process consists on translating the lisp source file to C language. The -intermediate file is later compiled using a C compiler. The result is an object -file which may have different purposes. - -@table @sc -@item Dynamically loadable files or FASL (FASt Loadable) files -These are produced in a @ecl{} built with support for dynamically loadable -libraries (Feature @kwd{DLOPEN} is in @var{*features*}), when no extra -arguments are passed to @code{compile-file}. These object files typically have -the @file{.fas} extension, and can be loaded with @code{load}. They cannot be used -to build libraries nor standalone executable programs. - -@item linkable object files -These are produced when invoking @code{compile-file} with the keyword argument -@kwd{system-p} set to true. The object file typically has the @file{.o} -extension. It cannot be loaded with @code{load}, but it can be used to build -libraries, standalone executable programs, or larger FASL files. -@end table - -@c --------------------------------------------------------------------- - -@node Building standalone executables, Building libraries, Compiling files, Building programs -@section Building standalone executables - -To build an executable you need a working @ecl{} image with the -compiler. The function to build customized images is -@var{c::build-program}. The description of this function is as -follows. Care should be taken that @var{image-name} differs from any -filename in @var{lisp-files}. - -@defun {c:build-program} @{@var{image-name} @keys{} @var{lisp-files} @var{ld-flags} @var{prologue-code} @var{epilogue-code}@} - -This function builds a lisp image up from the core lisp library, plus all -components listed in @var{lisp-files}. Each component is either: -@itemize -@item A symbol: Names a statically linked library built from lisp code. -@item A string: Denotes an object file built from lisp code. -@end itemize -@noindent -@var{ld-flags} is a list of strings with additional parameters to be passed -to the linker. You can include here your favorite C/C++ libraries. - -@var{prologue-code} and @var{epilogue-code} are used to customize the -initialization process of the lisp image. In order to build the executable, -@var{c:build-program} first writes down a piece of C code which initializes the -lisp environment. You can customize the initialization process by suppling code -to be executed before (@var{prologue-code}) or after (@var{epilogue-code}) -setting up the lisp environment. Typically @var{prologue-code} defaults to an -empty string, while @var{epilogue-code} invokes the classical lisp -@var{top-level}. Additionally, as a convenience, @var{epilogue-code} can -be either a string with C code or also a list with a lisp form, which -will be interpreted at run time. -@end defun - -@c --------------------------------------------------------------------- - -@node Building libraries, File names, Building standalone executables, Building programs -@section Building libraries - -To build a library you proceed more or less the same way as with standalone -executables. There are two different functions depending on whether you need -to build static or shared libraries. - -@defun {c:build-static-library} @{@var{library-name} @keys{} @var{lisp-files} @var{prologue-code} @var{epilogue-code} @var{init-name}@} -@defunx {c:build-shared-library} @{@var{library-name} @keys{} @var{lisp-files} @var{prologue-code} @var{epilogue-code} @var{ld-flags} @var{init-name}@} - -This function builds a library file up from the object files listed in -@var{lisp-files}. Each of the arguments to @var{lisp-file} must name a single -object file produced with @code{compile-file}. - -@var{library-name} is the physical pathname corresponding to the library. The -value of @var{library-name} must follow some system-specific conventions. To -make your program portable, @var{library-name} should be built using the -output of @code{compile-file-pathname}. - -@var{prologue-code} and @var{epilogue-code} are strings with C code to be -executed before and after initializing the library, respectively. For -dynamically linked libraries you can also provide a list of strings in -@var{ld-flags}. These strings are additional parameters for the linker and -their purpose is to link C/C++ extensions into the library. - -@var{init-name} gives the initialization function of the library a -user-specified name. Thus a the generated library may be used and/or -linked to a C application. -@end defun - -@c ---------------------------------------------------------------------- -@node File names, Compiler examples, Building libraries, Building programs -@section File names - -@defun {compile-file-pathname} @{@var{filename-base} @keys{} @var{output-file} @var{type}@} - -When compiling lisp files, creating libraries, etc, a number of files are -produced which are of interest for the user or programmer. However, the name -of these files will change from system to system. The purpose of the function -@code{compile-file-pathname} is to query the compiler about the name of the -different files that it can produce. Possible values of the @var{type} -argument include: - -@table @sc -@item :fas (default) -Standard compiled files that can be loaded with @code{load}. -@item :c, :data, :h -Intermediate files produced by the Lisp-to-C translator. -@item :o -Linkable object files. -@item :lib, :static-library -A normal library produced with @code{c:build-static-library}. -@item :dll, :shared-library -A dynamically linked library produced with @code{c:build-shared-library}. -@item :program -An executable produced with @code{c:build-program}. -@end table - -The output of this function is system specific. For example, under FreeBSD -@smallformat -> (compile-file-pathname "/this/path/mylib" :type :lib) -#P"/this/path/libmylib.a" -> (compile-file-pathname "/this/path/mylib" :type :dll) -#P"/this/path/libmylib.so" -> (compile-file-pathname "/this/path/mycode") -#P"/this/path/mycode.fas" -@end smallformat -@end defun - -@c --------------------------------------------------------------------- - -@node Compiler examples, , File names, Building programs -@section Compiler examples - -@subsection The @file{hello.lisp} file -In the following examples we will use the same lisp program. You have to -create a file called @file{hello.lisp} which contains the following lines -@lisp -(princ "Hello world!") -(terpri) -(quit) -@end lisp -@noindent -If you start @ecl{} and load this file in the Common-Lisp environment you -will see the @code{"Hello world!"} message and the interpreter will be closed. -@smallformat -ECL (Embeddable Common-Lisp) 0.9d -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 -under certain conditions; see file 'Copyright' for details. -Type :h for Help. Top level. -> @b{(load "hello.lisp")} -;;; Loading "hello.lisp" -Hello World! -@end smallformat - -@subsection Example of loadable object file -You can only perform the example in this section if your @ecl{} image supports -dynamically loading of object files. This is true if you find the keyword -@kwd{dlopen} in the @var{*features*} variable. This is true, for instance, -in a typical FreeBSD or Linux box, -@smallformat -Type :h for Help. Top level. -> @b{*features*} -(:IEEE-FLOATING-POINT :IBM-PC :I386 :BSD :UNIX :DLOPEN :ANSI-CL :CLOS - :BOEHM-GC :ECL :COMMON) -@end smallformat - -In this example we build a loadable extension which prints the @code{"Hello -world!"} message. First you need to create a the @file{hello.lisp} file. Next -you have to enter the @ecl{} environment and type @code{(compile-file -"hello.lisp")}. This produces a loadable object file. - -@smallformat -Type :h for Help. Top level. -> @b{(compile-file "hello.lisp")} -;;; Loading #P"/usr/lib/ecl/cmp.fas" -;;; Loading #P"/usr/lib/ecl/sysfun.lsp" -;;; Compiling hello.lisp. -;;; End of Pass 1. -;;; Calling the C compiler... -;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "hello.c" -o "hello.o" -;;; Invoking external command: gcc -o "hello.fas" -L"/usr/lib/ecl/" "hello.o" -Wl,--rpath,/usr/lib/ecl/ -shared -lecl -lgmp -lgc -ldl -lm -;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3 -;;; Finished compiling hello.lisp. -#P"hello.fas" -Top level. -> @b{(load "hello")} -;;; Loading #P"hello.fas" -Hello World! -@end smallformat - -@subsection Example of standalone program -In this example we build a standalone program which prints the @code{"Hello -world!"} message and does nothing else. First you must create the -@file{hello.lisp} file shown above. Next you have to enter the @ecl{} -environment and type @code{(compile-file "hello.lisp" :system-p t)}. This -produces an object file that can be linked against the @ecl{} core image. - -@smallformat -Type :h for Help. Top level. -> @b{(compile-file "hello.lisp" :system-p t)} -;;; Loading #P"/usr/lib/ecl/cmp.fas" -;;; Loading #P"/usr/lib/ecl/sysfun.lsp" -;;; Compiling hello.lisp. -;;; End of Pass 1. -;;; Calling the C compiler... -;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "hello.c" -o "hello.o" -;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3 -;;; Finished compiling hello.lisp. -#P"hello.o" -@end smallformat - -@noindent -The final step is to build the executable using the @code{c:build-program} -instruction. -@smallformat -> @b{(c:build-program "myecl" :lisp-files '("hello.o"))} -;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "myecl.c" -o "myecl.o" -;;; Invoking external command: gcc -o "myecl" -L"/usr/lib/ecl/" "myecl.o" "hello.o" -Wl,--rpath,/usr/lib/ecl/ -lecl -lgmp -lgc -ldl -lm -#P"myecl" -Top level. -@end smallformat -@noindent -Now you can execute this program from your favorite shell. - -@smallformat -% @b{./myecl} -Hello world! -@end smallformat - -@subsection Combining files into a larger FASL -You can only perform the example in this section if your @ecl{} image supports -dynamically loading of object files. In this example we build a loadable -library which prints the @code{"Hello world!"} message and does nothing -else. First you must create the @file{hello.lisp} file shown above. Next you -have to enter the @ecl{} environment and type @code{(compile-file "hello.lisp" -:system-p t)}. This produces an object file that can be linked to form a loadable -library. - -@smallformat -Type :h for Help. Top level. -> (compile-file "hello.lisp" :system-p t) -;;; Loading #P"/usr/lib/ecl/cmp.fas" -;;; Loading #P"/usr/lib/ecl/sysfun.lsp" -;;; Compiling hello.lisp. -;;; End of Pass 1. -;;; Calling the C compiler... -;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "hello.c" -o "hello.o" -;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3 -;;; Finished compiling hello.lisp. -#P"hello.o" -@end smallformat - -@noindent -The final step is to build the library using the @code{c:build-fasl} -instruction. -@smallformat -> (c:build-fasl "myecl" :lisp-files '("hello.o")) -;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "myecl.c" -o "myecl.o" -;;; Invoking external command: gcc -o "libmyecl.so" -L"/usr/lib/ecl/" "myecl.o" "hello.o" -Wl,--rpath,/usr/lib/ecl/ -shared -lecl -lgmp -lgc -ldl -lm -#P"libmyecl.so" -@end smallformat -@noindent -Now you can load this extension from any @ecl{} image, even those you produce -with @code{c:build-program}. - -@smallformat -<<<<<<<< THIS EXAMPLE IS WRONG?! >>>>>>>>> -> (load "myecl") -;;; Loading myecl.fas -Hello world! -Bye. -@end smallformat - -@c --------------------------------------------------------------------- - -@node Lisp objects, The interpreter, Building programs, Top -@chapter Manipulating Lisp objects - -If you want to extend, fix or simply customize @ecl{} for your own needs, -you should understand how the implementation works. - -@menu -* Objects representation:: -* Constructing objects:: -* Integers:: -* Characters:: -* Arrays:: -* Strings:: -* Bitvectors:: -* Streams:: -* Structures:: -* Instances:: -* Bytecodes:: -@end menu - - -@node Objects representation, Constructing objects, Lisp objects, Lisp objects -@section Objects representation - -In @ecl{} a lisp object is represented by a type called @code{cl_object}. This -type is a word which is long enough to host both an integer and a pointer. The -least significant bits of this word, also called the tag bits, determine -whether it is a pointer to a C structure representing a complex object, or -whether it is an immediate data, such as a fixnum or a character. -@verbatim - |-------------------|--| - | Fixnum value |01| - |-------------------|--| - - |------------|------|--| - | Unused bits| char |10| - |------------|------|--| - - |----------------------| |--------|--------|-----|--------| - | Pointer to cell |---->| word-1 | word-2 | ... | word-n | - |----------------------| |--------|--------|-----|--------| - | ...................00| | actual data of the object | - |----------------------| |--------------------------------| -@end verbatim - -The fixnums and characters are called immediate datatypes, because they require -no more than the @code{cl_object} datatype to store all information. All other -@ecl{} objects are non-immediate and they are represented by a pointer to a -cell that is allocated on the heap. Each cell consists of several words of -memory and contains all the information related to that object. By storing data -in multiples of a word size, we make sure that the least significant bits of a -pointer are zero, which distinguishes pointers from immediate data. - -In an immediate datatype, the tag bits determine the type of the object. In -non-immediate datatypes, the first byte in the cell contains the secondary type -indicator, and distinguishes between different types of non immediate data. The -use of the remaining bytes differs for each type of object. For instance, a -cons cell consists of three words: -@verbatim - |---------|----------| - |CONS| | | - |---------|----------| - | car-pointer | - |--------------------| - | cdr-pointer | - |--------------------| -@end verbatim - -There is one important function which tells the type of an object, plus several -macros which group several tests. - -@deftp {C type} cl_object -This is the type of a lisp object. For your C/C++ program, a @code{cl_object} -can be either a fixnum, a character, or a pointer to a union of structures (See -the header @file{object.h}). The actual interpretation of that object can be -guessed with the macro @code{type_of}. - -For example, if @var{x} is of type @code{cl_object}, and it is of type fixnum, -we may retrieve its value -@example -if (type_of(x) == t_fixnum) - printf("Integer value: %d\n", fix(x)); -@end example -@noindent -If @var{x} is of type @code{cl_object} and it does not contain an immediate -datatype, you may inspect the cell associated to the lisp object using @var{x} -as a pointer. For example, -@example -if (type_of(x) == t_cons) - printf("CAR = %x, CDR = %x\n", x->cons.car, x->cons.cdr); -else if (type_of(x) == t_string) - printf("String: %s\n", x->string.self); -@end example -@noindent -You should see the following sections and the header @file{object.h} to learn -how to use the different fields of a @code{cl_object} pointer. -@end deftp - -@deftp {C type} cl_type -Enumeration type which distinguishes the different types of lisp objects. The -most important values are t_cons, t_fixnum, t_character, t_bignum, t_ratio, -t_singlefloat, t_doublefloat, t_complex, t_symbol, t_package, t_hashtable, -t_array, t_vector, t_string, t_bitvector, t_stream, t_random, t_readtable, -t_pathname, t_bytecodes, t_cfun, t_cclosure, t_gfun, t_instance, t_foreign and -t_thread. -@end deftp - -@deftypefun cl_type type_of (cl_object @var{O}) -If @var{O} is a valid lisp object, @code{type_of(@var{O})} returns an integer -denoting the type that lisp object. That integer is one of the values of the -enumeration type @code{cl_type}. -@end deftypefun - -@deftypefun bool FIXNUMP (cl_object @var{o}) -@deftypefunx bool CHARACTERP (cl_object @var{o}) -@deftypefunx bool CONSP (cl_object @var{o}) -@deftypefunx bool LISTP (cl_object @var{o}) -@deftypefunx bool ATOM (cl_object @var{o}) -@deftypefunx bool ARRAYP (cl_object @var{o}) -@deftypefunx bool VECTORP (cl_object @var{o}) -@deftypefunx bool STRINGP (cl_object @var{o}) - -Different macros that check whether @var{o} belongs to the specified type. -These checks have been optimized, and are preferred over several calls to -@code{type_of}. -@end deftypefun - -@deftypefun bool IMMEDIATE (cl_object @var{o}) -Tells whether @var{o} is an immediate datatype. -@end deftypefun - -@c ---------------------------------------------------------------------- - -@node Constructing objects, Integers, Objects representation, Lisp objects -@section Constructing objects - -On each of the following sections we will document the standard interface for -building objects of different types. For some objects, though, it is too -difficult to make a C interface that resembles all of the functionality in the -lisp environment. In those cases you need to - -@enumerate -@item build the objects from their textual representation, or -@item use the evaluator to build these objects. -@end enumerate -@noindent -The first way makes use of a C or Lisp string to construct an object. The two -functions you need to know are the following ones. - -@deftypefun cl_object c_string_to_object (const char *@var{s}) -@deftypefunx cl_object string_to_object (cl_object @var{o}) -@code{c_string_to_object} builds a lisp object from a C string which contains a -suitable representation of a lisp object. @code{string_to_object} performs the -same task, but uses a lisp string, and therefore it is less useful. Two -examples of their use - -@example -/* Using a C string */ -cl_object array1 = c_string_to_object("#(1 2 3 4)"); - -/* Using a Lisp string */ -cl_object string = make_simple_string("#(1 2 3 4)"); -cl_object array2 = string_to_object(string); -@end example -@end deftypefun - -@c ---------------------------------------------------------------------- - -@node Integers, Characters, Constructing objects, Lisp objects -@section Integers - -@clisp{} distinguishes two types of integer types: bignums and fixnums. A -fixnum is a small integer, which ideally occupies only a word of memory and -which is between the values @var{MOST-NEGATIVE-FIXNUM} and -@var{MOST-POSITIVE-FIXNUM}. A bignum is any integer which is not a fixnum and -it is only constrained by the amount of memory available to represent it. - -In @ecl{} a fixnum is an integer that, together with the tag bits, fits in a -word of memory. The size of a word, and thus the size of a fixnum, varies from -one architecture to another, and you should refer to the types and constants in -the @file{ecl.h} header to make sure that your C extensions are portable. -All other integers are stored as bignums, they are not immediate objects, they -take up a variable amount of memory and the GNU Multiprecision Library is -required to create, manipulate and calculate with them. - -@deftp {C type} cl_fixnum -This is a C signed integer type capable of holding a whole fixnum without any -loss of precision. The opposite is not true, and you may create a -@code{cl_fixnum} which exceeds the limits of a fixnum and should be stored as a -bignum. -@end deftp - -@deftp {C type} cl_index -This is a C unsigned integer type capable of holding a nonnegative fixnum without -loss of precision. Typically, a @code{cl_index} is used as an index into an array, -or into a proper list, etc. -@end deftp - -@defvr {Constant} MOST_NEGATIVE_FIXNUM -@defvrx {Constant} MOST_POSITIVE_FIXNUM -These constants mark the limits of a fixnum. -@end defvr - -@deftypefun bool FIXNUM_MINUSP (cl_object @var{o}) -@deftypefunx bool FIXNUM_PLUSP (cl_object @var{o}) -These functions perform the checks (@var{o} < 0) and (0 <= @var{o}), -respectively. -@end deftypefun - -@deftypefun cl_object MAKE_FIXNUM (cl_fixnum @var{n}) -@deftypefunx cl_fixnum fix (cl_object @var{o}) - -@code{MAKE_FIXNUM} and @code{fix} convert from an integer to a lisp object -of fixnum type and vice versa. These functions no not check their arguments. -@end deftypefun - -@deftypefun cl_fixnum fixint (cl_object @var{o}) -Converts a lisp fixnum to a C integer of the appropriate size. Signals an error -if @var{o} is not of fixnum type. -@end deftypefun - -@deftypefun cl_index fixnnint (cl_object @var{o}) -Similar to @code{fixint} but also ensures that @var{o} is not negative. -@end deftypefun - -@c ---------------------------------------------------------------------- - -@node Characters, Arrays, Integers, Lisp objects -@section Characters - -@ecl{} has only one type of characters, which fits in the C type @code{char}. -The following constants and functions operate on characters. - -@defvr {Constant} CHAR_CODE_LIMIT -Each character is assigned an integer code which ranges from 0 to -(@var{CHAR_CODE_LIMIT}-1). -@end defvr - -@deftypefun cl_fixnum CHAR_CODE (cl_object @var{o}) -@deftypefunx cl_fixnum char_code (cl_object @var{o}) -Returns the integer code associated to a lisp character. Only @code{char_code} -checks its arguments. -@end deftypefun - -@deftypefun cl_object CODE_CHAR (cl_fixnum @var{o}) -Returns the lisp character associated to an integer code. It does not check -its arguments. -@end deftypefun - -@deftypefun cl_object coerce_to_character (cl_object @var{o}) -Coerces a lisp object to type character. Valid arguments are a character, -or a string designator of length 1. In all other cases an error is signaled. -@end deftypefun - -@deftypefun bool char_eq (cl_object @var{x}, cl_object @var{y}) -@deftypefunx bool char_equal (cl_object @var{x}, cl_object @var{y}) -Compare two characters for equality. @code{char_eq} take case into account and -@code{char_equal} ignores it. -@end deftypefun - -@deftypefun int char_cmp (cl_object @var{x}, cl_object @var{y}) -@deftypefunx int char_compare (cl_object @var{x}, cl_object @var{y}) -Compare the relative order of two characters. @code{char_cmp} takes care of -case and @code{char_compare} converts all characters to uppercase before -comparing them. -@end deftypefun - -@c ---------------------------------------------------------------------- - -@node Arrays, Strings, Characters, Lisp objects -@section Arrays - -An array is an aggregate of data of a common type, which can be accessed with -one or more nonnegative indices. @ecl{} stores arrays as a C structure with a -pointer to the region of memory which contains the actual data. The cell -of an array datatype varies depending on whether it is a vector, a bytevector, -a multidimensional array or a string. - -If @var{x} contains a vector, you can access the following fields: -@table @code -@item x->vector.elttype -The type of the elements of the vector. -@item x->vector.dim -The maximum number of elements. -@item x->vector.fillp -Actual number of elements in the vector or "fill pointer". -@item x->vector.self -Union of pointers of different types. You should choose the right pointer -depending on @code{x->vector.elltype} -@item x->vector.hasfillp -Whether @code{x->vector.fillp} can be smaller than @code{x->vector.dim}. -@end table - -If @var{x} contains a multidimensional array, the cell elements become -@table @code -@item x->array.elttype -The type of the elements of the array. -@item x->array.dim -Number of elements in the array. -@item x->array.rank -Number of dimensions of the array. -@item x->array.dims[] -Array with the dimensions of the array. The elements range from -@code{x->array.dim[0]} to @code{x->array.dim[x->array.rank-1]}. -@item x->array.self -Union of pointers to the actual data. You should choose the right pointer -depending on @code{x->array.elltype}. -@item x->array.rank -Whether @code{x->vector.fillp} can be smaller than @code{x->vector.dim}. -@end table -@noindent -Bitvectors and strings are treated separately. - -Each array is of an specialized type which is the type of the elements of the -array. @ecl{} has arrays only a few following specialized types, and for each -of these types there is a C integer which is the corresponding value of -@code{x->array.elttype} or @code{x->vector.elttype}. We list those types -together with the C constant that denotes that type: -@table @var -@item T -@code{aet_object} -@item CHARACTER -@code{aet_ch} -@item FIXNUM -@code{aet_fix} -@item BIT -@code{aet_bit} -@item SINGLE-FLOAT -@code{aet_sf} -@item DOUBLE-FLOAT -@code{aet_df} -@end table - -@deftypefun cl_elttype array_elttype (cl_object @var{o}) -Returns the element type of the array @var{o}, which can be a string, a -bitvector, vector, or a multidimensional array. For example, the code -@code{array_elttype(c_string_to_object("\"AAA\""))} returns @code{aet_ch}, -while the @code{array_elttype(c_string_to_object("#(A B C)"))} returns -@code{aet_object}. -@end deftypefun - -@deftypefun cl_object aref (cl_object @var{array}, cl_index @var{index}) -@deftypefunx cl_object aset (cl_object @var{array}, cl_index @var{index}, cl_object @var{value}) -These functions are used to retrieve and set the elements of an array. The -elements are accessed with one index, @var{index}, as in the lisp function -@code{ROW-MAJOR-AREF}. For example - -@example -cl_object array = c_string_to_object("#2A((1 2) (3 4))"); -cl_object x = aref(array, 3); -cl_print(1, x); /* Outputs 4 */ -aset(array, 3, MAKE_FIXNUM(5)); -cl_print(1, array); /* Outputs #2A((1 2) (3 5)) */ -@end example -@end deftypefun - -@deftypefun cl_object aref1 (cl_object @var{vector}, cl_index @var{index}) -@deftypefunx cl_object aset1 (cl_object @var{vector}, cl_index @var{index}, cl_object @var{value}) -These functions are similar to @code{aref} and @code{aset}, but they operate on -vectors. -@example -cl_object array = c_string_to_object("#(1 2 3 4)"); -cl_object x = aref1(array, 3); -cl_print(1, x); /* Outputs 4 */ -aset1(array, 3, MAKE_FIXNUM(5)); -cl_print(1, array); /* Outputs #(1 2 3 5) */ -@end example -@end deftypefun - -@c ---------------------------------------------------------------------- - -@node Strings, Bitvectors, Arrays, Lisp objects -@section Strings - -A string, both in @clisp{} and in @ecl{} is nothing but a vector of -characters. Therefore, almost everything mentioned in the section of arrays -remains valid here. The only important difference is that @ecl{} stores -strings as a lisp object with a pointer to a zero terminated C string. Thus, if -a string has @var{n} characters, @ecl{} will reserve @var{n}+1 bytes for the -string. This allows us to pass the string @code{self} pointer to any C -routine. - -If @var{x} is a lisp object of type string, we can access the following fields: -@table @code -@item x->string.dim -Maximum number of characters that it can contain. -@item x->string.fillp -Actual number of characters in the string. -@item x->string.self -Pointer to the characters. -@item x->string.hasfillp -True if @code{x->string.fillp} can be smaller than @code{x->string.dim}. -@end table - -@deftypefun cl_object make_simple_string (char *@var{s}) -@deftypefunx cl_object make_string_copy (char *@var{s}) -Both routines build a lisp string from a C string. @code{make_string_copy} -allocates new space and copies the content of the string to -it. @code{make_simple_string} simply uses the memory pointed by @var{s}, which -should not be deallocated. Both routines use @code{strlen} to calculate the -length of the string. -@end deftypefun - -@node Bitvectors, Streams, Strings, Lisp objects -@section Bitvectors - -@node Streams, Structures, Bitvectors, Lisp objects -@section Streams - -@node Structures, Instances, Streams, Lisp objects -@section Structures - -@node Instances, Bytecodes, Structures, Lisp objects -@section Instances - -@c --------------------------------------------------------------------- - -@node Bytecodes, , Instances, Lisp objects -@section Bytecodes - -A bytecodes object is a lisp object with a piece of code that can be -interpreted. The objects of type @code{t_bytecode} are implicitly constructed -by a call to @code{eval}, but can also be explicitly constructed with the -@code{make_lambda} function. - -@deftypefun cl_object cl_safe_eval (cl_object @var{form}, cl_object @var{env}, cl_object @var{err_value} -@deftypefunx cl_object cl_eval (cl_object @var{form}) - -@code{cl_safe_eval} evaluates @var{form} in the lexical environment @var{env}, -which can be @var{nil}. Before evaluating it, the expression @var{form} must -be bytecompiled. @code{cl_eval} is the equivalent of @code{cl_safe_eval} but -without environment and with @var{err_value} set to @var{nil}. It exists only -for compatibility with previous versions. -@example -cl_object form = c_string_to_object("(print 1)"); -cl_safe_eval(form,Cnil); -cl_safe_eval(form, Cnil); -@end example -@end deftypefun - -@deftypefun cl_object si_make_lambda (cl_object @var{name}, cl_object @var{def}) -Builds an interpreted lisp function with name given by the symbol @var{name} -and body given by @var{def}. For instance, we would achieve the equivalent of -@lisp -(funcall #'(lambda (x y) (block foo (+ x y))) - 1 2) -@end lisp -@noindent -with the following code -@example -cl_object def = c_string_to_object("((x y) (+ x y))"); -cl_object name = _intern("foo") -cl_object fun = si_make_lambda(name, def); -return funcall(fun, MAKE_FIXNUM(1), MAKE_FIXNUM(2)); -@end example -@noindent Notice that @code{si_safe_lambda} performs a bytecodes compilation -of the definition and thus it may signal some errors. Such errors are not -handled by the routine itself you might consider using @code{cl_safe_eval} -or @code{cl_eval} instead: -@example -cl_object def = c_string_to_object("#'(lambda-block foo (x y) (+ x y))"); -cl_object fun = cl_eval(def); -return funcall(fun, MAKE_FIXNUM(1), MAKE_FIXNUM(2)); -@end example -@end deftypefun - -@c --------------------------------------------------------------------- - -@node The interpreter, The compiler, Lisp objects, Top -@chapter The interpreter - -@menu -* ECL stacks:: -* Procedure Call Conventions:: -* The lexical environment:: -* The interpreter stack:: -@end menu - - -@node ECL stacks, Procedure Call Conventions, The interpreter, The interpreter -@section @ecl{} stacks - -@ecl{} uses the following stacks: - -@table @sc -@item Frame Stack -consisting of catch, block, tagbody frames - -@item Bind Stack -for shallow binding of dynamic variables - -@item Interpreter Stack -acts as a Forth data stack, keeping intermediate arguments to -interpreted functions, plus a history of called functions. - -@item C Control Stack -used for arguments/values passing, typed lexical variables, -temporary values, and function invocation. -@end table - - -@node Procedure Call Conventions, The lexical environment, ECL stacks, The interpreter -@section Procedure Call Conventions - -@ecl{} employs standard C calling conventions to achieve efficiency and -interoperability with other languages. -Each Lisp function is implemented as a C function which takes as many -argument as the Lisp original plus one additional integer argument -which holds the number of actual arguments. The function sets @code{NValues} -to the number of Lisp values produced, it returns the first one and the -remaining ones are kept in a global (per thread) array (@code{VALUES}). - -To show the argument/value passing mechanism, here we list the actual -code for the @clisp{} function @code{cons}. - -@example -cl_cons(int narg, object car, object cdr) -@{ object x; - check_arg(2); - x = alloc_object(t_cons); - CAR(x) = car; - CDR(x) = cdr; - NValues = 1; - return x; -@} -@end example - -@ecl{} adopts the convention that the name of a function that implements a -@clisp{} function begins with a short package name (@code{cl} for COMMON-LISP, -@code{si} for SYSTEM, etc), followed by @code{L}, and followed by the name of -the @clisp{} function. (Strictly speaking, `@code{-}' and `@code{*}' in the -@clisp{} function name are replaced by `@code{_}' and `@code{A}', respectively, -to obey the syntax of C.) - -@code{check_arg(2)} in the code of @code{cl_cons} checks that exactly two -arguments are supplied to @code{cons}. That is, it checks that @code{narg} is -2, and otherwise, it causes an error. @code{allocate_object(t_cons)} allocates -a cons cell in the heap and returns the pointer to the cell. After the -@code{CAR} and the @code{CDR} fields of the cell are set, the cell pointer is -returned directly. The number assigned to NValues set by the function (1 in -this case) represents the number of values of the function. - -In general, if one is to play with the C kernel of @ecl{} there is no need to -know about all these conventions. There is a preprocessor that takes care of -the details, by using a lisp representation of the statements that output -values, and of the function definitions. For instance, the actual source code -for @code{cl_cons} in @file{src/c/lists.d} - -@example -@@(defun cons (car cdr) -@@ - @@(return CONS(car, cdr)) -@@) -@end example - -@node The lexical environment, The interpreter stack, Procedure Call Conventions, The interpreter -@section The lexical environment - -The @ecl{} interpreter uses two A-lists (Association lists) to -represent lexical environments. - -@itemize -@item One for variable bindings -@item One for local function/macro/tag/block bindings -@end itemize - -When a function closure is created, the current two A-lists are -saved in the closure along with the lambda expression. Later, when the -closure is invoked, the saved A-lists are -used to recover the lexical environment. - - -@node The interpreter stack, , The lexical environment, The interpreter -@section The interpreter stack - -The bytecodes interpreter uses a stack of its own to save and restore values -from intermediate calculations. This Forth-like data stack is also used in -other parts of the C kernel for various purposes, such as saving compiled code, -keeping arguments to FORMAT, etc. - -However, one of the most important roles of the Interpreter Stack is to keep a -log of the functions which are called during the execution of bytecodes. For -each function invoked, the interpreter keeps three lisp objects on the stack: -@verbatim - +----------+------------------------------------------------+ - | function | lexical environment | index to previous record | - +----------+---------------------+--------------------------+ -@end verbatim - -The first item is the object which is funcalled. It can be a bytecodes object, -a compiled function or a generic function. In the last two cases the lexical -environment is just NIL. In the first case, the second item on the stack is -the lexical environment on which the code is executed. Each of these records -are popped out of the stack after function invocation. - -Let us see how these invocation records are used for debugging. -@smallformat ->(defun fact (x) ;;; Wrong definition of the - (if (= x 0) ;;; factorial function. - one ;;; one should be 1. - (* x (fact (1- x))))) -FACT - ->(fact 3) ;;; Tries 3! -Error: The variable ONE is unbound. -Error signalled by IF. -Broken at IF. ->>:b ;;; Backtrace. -Backtrace: eval > fact > if > fact > if > fact > if > fact > IF - ;;; Currently at the last IF. ->>: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. -: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. - ->>:p ;;; Move to the last call of FACT. -Broken at IF. - ->>:b -Backtrace: eval > fact > if > fact > if > fact > if > FACT > if - ;;; Now at the last FACT. ->>:v ;;; The environment at the last call -Local variables: ;;; to FACT is recovered. - X: 0 ;;; X is the only bound variable. -Block names: FACT. ;;; The block FACT is established. - ->>x -0 ;;; The value of x is 0. - ->>(return-from fact 1) ;;; Return from the last call of -6 ;;; FACT with the value of 0. - ;;; The execution is resumed and -> ;;; the value 6 is returned. - ;;; Again at the top-level loop. -@end smallformat - -@c --------------------------------------------------------------------- - -@node The compiler, The Garbage Collector, The interpreter, Top -@chapter The compiler - -@menu -* The compiler translates to C:: -* The compiler mimics human C programmer:: -* Implementation of Compiled Closures:: -* Use of Declarations to Improve Efficiency:: -* Inspecting generated C code:: -* Embedding C code:: -* The C language interface:: -* The old C language interface:: -@end menu - -@node The compiler translates to C, The compiler mimics human C programmer, The compiler, The compiler -@section The compiler translates to C - -The @ecl{} compiler is essentially a translator from @clisp{} to C. Given -a Lisp source file, the compiler first generates three intermediate -files: - -@itemize -@item a C-file which consists of the C version of the Lisp program -@item an H-file which consists of declarations referenced in the C-file -@item a Data-file which consists of Lisp data to be used at load time -@end itemize - -The @ecl{} compiler then invokes the C compiler to compile the -C-file into an object file. Finally, the contents of the Data-file is -appended to the object file to make a @emph{Fasl-file}. The generated -Fasl-file can be loaded into the @ecl{} system by the @clisp{} -function @code{load}. By default, the three intermediate files are -deleted after the compilation, but, if asked, the compiler leaves -them. - -The merits of the use of C as the intermediate language are: - -@itemize - -@item The @ecl{} compiler is highly portable. - -@item Cross compilation is possible, because the contents of the -intermediate files are common to all versions of @ecl{}. For example, -one can compile his or her Lisp program by the @ecl{} compiler on -a Sun, bring the intermediate files to DOS, compile the C-file with -the gcc compiler under DOS, and then append the Data-file to the object -file. This procedure generates the Fasl-file for the @ecl{} system on -DOS. This kind of cross compilation makes it easier to port @ecl{}. - -@item Hardware-dependent optimizations such as register allocations -are done by the C compiler. -@end itemize - -The demerits are: - -@itemize - -@item At those sites where no C compiler is available, -the users cannot compile their Lisp programs. - -@item The compilation time is long. 70% to 80% of the -compilation time is used by the C compiler. The @ecl{} compiler is -therefore slower than compiler generating machine code directly. -@end itemize - -@node The compiler mimics human C programmer, Implementation of Compiled Closures, The compiler translates to C, The compiler -@section The compiler mimics human C programmer - -The format of the intermediate C code generated by the @ecl{} compiler is the -same as the hand-coded C code of the @ecl{} source programs. For example, -supposing that the Lisp source file contains the -following function definition: - -@lisp -(defvar *delta* 2) -(defun add1 (x) (+ *delta* x)) -@end lisp - -@noindent -The compiler generates the following intermediate C code. - -@example -/* function definition for ADD1 */ -static cl_object L1(cl_object V1) -@{ VT2 VLEX2 CLSR2 - cl_object value0; - value0=number_plus(symbol_value(VV[0]),V1); NVALUES=1; - return value0; -@} -/* initialization of this module */ -void init_CODE(cl_object flag) -@{ VT1 CLSR1 - cl_object value0; - if (!FIXNUMP(flag))@{ - Cblock=flag; - #ifndef ECL_DYNAMIC_VV - flag->cblock.data = VV; - #endif - flag->cblock.self_destruct=0; - flag->cblock.data_size = VM; - flag->cblock.data_text = compiler_data_text; - flag->cblock.data_text_size = compiler_data_text_size; - return;@} - #ifdef ECL_DYNAMIC_VV - VV = Cblock->cblock.data; - #endif - T0= MAKE_FIXNUM(2); - si_Xmake_special(VV[0]) - if(SYM_VAL(T0)!=OBJNULL) cl_setq(VV[0],T0); - cl_def_c_function(VV[1],(void*)L1,1); -@} -@end example - -The C function @code{L1} implements the Lisp function @code{add1}. -This relation is established by @code{cl_def_c_function} in the -initialization function @code{init_CODE}, which is invoked at load -time. There, the vector @code{VV} consists of Lisp objects; -@code{VV[0]} and @code{VV[1]} in this example hold the Lisp symbols -@code{*delta*} and @code{add1}. @code{VM} in the definition of -@code{L1} is a C macro declared in the corresponding H-file. The -actual value of @code{VM} is the number of value stack locations used -by this module, i.e., 2 in this example. Thus the following macro -definition is found in the H-file. -@example -#define VM 2 -@end example - - -@node Implementation of Compiled Closures, Use of Declarations to Improve Efficiency, The compiler mimics human C programmer, The compiler -@section Implementation of Compiled Closures - -The @ecl{} compiler takes two passes before it invokes the C -compiler. The major role of the first pass is to detect function -closures and to detect, for each function closure, those lexical -objects (i.e., lexical variable, local function definitions, tags, and -block-names) to be enclosed within the closure. This check must be -done before the C code generation in the second pass, because lexical -objects to be enclosed in function closures are treated in a different -way from those not enclosed. - -Ordinarily, lexical variables in a compiled function @emph{f} -are allocated on the C stack. However, if a lexical variable is -to be enclosed in function closures, it is allocated on a list, called -the ``environment list'', which is local to @emph{f}. In addition, a -local variable is created which points to the lexical -variable's location (within the environment list), so that -the variable may be accessed through an indirection rather than by list -traversal. - -@ignore -\bf{Rewrite this} -@end ignore - -The environment list is a pushdown list: It is empty when @emph{f} is called. -An element is pushed on the environment list when a variable to be enclosed in -closures is bound, and is popped when the binding is no more in effect. That -is, at any moment during execution of @emph{f}, the environment list contains -those lexical variables whose binding is still in effect and which should be -enclosed in closures. When a compiled closure is created during execution of -@emph{f}, the compiled code for the closure is coupled with the environment -list at that moment to form the compiled closure. - -Later, when the compiled closure is invoked, a pointer is set up to each -lexical variable in the environment list, so that each object may be referenced -through a memory indirection. - -Let us see an example. Suppose the following function has been compiled. - -@lisp -(defun foo (x) - (let ((a #'(lambda () (incf x))) - (y x)) - (values a #'(lambda () (incf x y))))) -@end lisp - -@code{foo} returns two compiled closures. The first closure increments @var{x} -by one, whereas the second closure increments @var{x} by the initial value of -@var{x}. Both closures return the incremented value of @var{x}. - -@smallformat ->(multiple-value-setq (f g) (foo 10)) -# - ->(funcall f) -11 - ->(funcall g) -21 - -> -@end smallformat - -After this, the two compiled closures look like: -@verbatim -second closure y: x: -|-------|------| |-------|------| |------|------| -| ** | --|----->| 10 | --|------>| 21 | nil | -|-------|------| |-------|------| |------|------| - ^ - first closure | - |-------|------| | - | * | --|----------| - |-------|------| - - * : address of the compiled code for #'(lambda () (incf x)) -** : address of the compiled code for #'(lambda () (incf x y)) -@end verbatim - - -@node Use of Declarations to Improve Efficiency, Inspecting generated C code, Implementation of Compiled Closures, The compiler -@section Use of Declarations to Improve Efficiency - -Declarations, especially type and function declarations, -increase the efficiency of the compiled code. For example, for the -following Lisp source file, with two @clisp{} declarations added, - -@lisp -(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)))) -@end lisp - -The compiler generates the following C code: - -@example -/* local entry for function TAK */ -static int LI1(register int V1,register int V2,register int V3) -@{ VT3 VLEX3 CLSR3 -TTL: - if (V2 < V1) @{ - goto L2;@} - return(V3); -L2: - @{ int V5; - V5 = LI1((V1)-1,V2,V3); - @{ int V6; - V6 = LI1((V2)-1,V3,V1); - V3 = LI1((V3)-1,V1,V2); - V2 = V6; - V1 = V5;@}@} - goto TTL; -;;; Note: Tail-recursive call of TAK was replaced by iteration. -@} -@end example - - -@node Inspecting generated C code, Embedding C code, Use of Declarations to Improve Efficiency, The compiler -@section Inspecting generated C code - -@clisp{} defines a function disassemble, which is -supposed to disassemble a compiled function and to display the -assembler code. According to @cltl{}, - - @emph{This is primary useful for debugging the compiler}, ..\\ - -@c FIXME: Actually disassemble shows bytecode -This is, however, @emph{useless} in our case, because we are -not concerned with assembly language. Rather, we are interested in -the C code generated by the @ecl{} compiler. Thus the disassemble -function in @ecl{} accepts not-yet-compiled functions only and displays -the translated C code. - -@smallformat -> (defun add1 (x) (1+ x)) -ADD1 -> (disassemble *) -;;; Compiling (DEFUN ADD1 ...). -;;; Emitting code for ADD1. - -/* function definition for ADD1 */ -static L1(int narg, object V1) -@{ VT3 VLEX3 CLSR3 -TTL: - VALUES(0) = one_plus((V1)); - RETURN(1); -@} -@end smallformat - - -@node Embedding C code, The C language interface, Inspecting generated C code, The compiler -@section Embedding C code in lisp source - -There are several mechanism to integrate C code within @ecl{}, but -everything is built around two functions that allow the user to embed -arbitrary C/C++ code into Lisp source code. - -The two mechanisms are the @code{Clines} and the @code{c-inline} special -forms. The first one permits to insert code in the intermediate C/C++ file -generated by the @ecl{} compiler. Such a form outputs no value and takes -no arguments, except a series of strings which are inserted literally, -such as @code{#include} or @code{#define} statements, function definitions, etc. - -@defmac {Clines} @{@{string@}*@} -When the @ecl{} compiler encounters a macro form @code{(Clines @var{string1 -... stringn})}, it simply outputs the @var{strings} into the c-file. The -arguments are not evaluated and each argument must be a string. Each -@var{string} may consist of any number of lines, and separate lines in the -@var{string} are placed in separate lines in the c-file. In addition, each -@var{string} opens a fresh line in the c-file, i.e., the first character in the -@var{string} is placed at the first column of a line. Therefore, C-language -preprocessor commands such as @code{#define} and @code{#include} will be -recognized as such by the C compiler, if the ' # ' sign appears as the first -character of the @var{string} or as the first character of a line within the -@var{string}. - -When interpreted, a @code{Clines} macro form expands to @nil{}. - -@end defmac - -@lisp -(use-package "FFI") - -(Clines -" int tak(x, y, z) " -" int x, y, z; " -" @{ if (y >= x) return(z); " -" else return(tak(tak(x-1, y, z), " -" tak(y-1, z, x), " -" tak(z-1, x, y))); " -" @} " -) - -(defun tak (x y z) - (c-inline (x y z) (:int :int :int) :int - "tak(#0,#1,#2)" :one-liner t)) -@end lisp - -The second mechanism, which you already appreciate in the example above, is the -@code{c-inline} special form. This powerful method allows the user to insert C -code which is evaluated, and which can accept values and return values from and -to the Lisp world, with an automatic convertion taking place in both directions. - -@defmac {c-inline} @{@var{args-list} @var{arg-C-types} @var{output-C-type} @var{C-expr} @keys{} (@var{side-effects} @code{T}) (@var{one-liner} @code{T})@} - -@code{c-inline} is a special form that can only be used in compiled -code. For all purposes it behaves as a Lisp form, which takes the -arguments given in @var{args-list} and produces a single value. Behind -the curtains, the arguments of @var{args-list} (which can be any valid -Lisp form) are coerced to the the C types given in @var{arg-C-types}, -passed to the C expression @var{C-expr}, and coerced back to Lisp -using the C type @var{output-C-type} as a guide. Multiple return -values can be returned by setting @var{output-C-type} to @code{(values -type-1 type-2 ...)}. - -@var{C-expr} is a string containing C code and maybe some special -escape codes. First, the arguments of the form may be retrieved as -@code{#0}, @code{#1}, etc. Second, if the @code{c-inline} form is a -one-line C expression (That is, @var{one-liner} is true), then the -whole expression is interpreted as the output value. But if the code, -on the other hand, is a multiline expression (@var{one-liner} is -false), the form has to be output using @code{@@(return) -=...}. Multiple values are returned as @code{@@(return 0)=... ; -@@(return 1)=...;}. Finally, Lisp constants may be used in the C code -making use of the prefix @code{@@}. - -@lisp -(use-package "FFI") - -(Clines " -#include - -double foo (double x, double y) @{ - return sinh(x) * y; -@}") - -(defvar *a* - (c-inline (1.23) (:double) :double - "foo(#0,1.44)" - :side-effects nil - :one-liner t)) - -(defvar *b* - (c-inline (1.23) (:double) :double - "@{cl_object x = symbol_value(@@*a*); - @@(return) = foo(#0,object_to_float(x));@}" - :side-effects nil - :one-liner nil)) -@end lisp -@end defmac - - -@node The C language interface, The old C language interface, Embedding C code, The compiler -@section The C language interface - -Using these special forms @code{clines} and @code{c-inline}, plus the ability to -handle pointers to foreign data, we have built a rather complete FFI for -interfacing with the C world. This interface is compatible with the UFFI -specification, which can be found in the web. We recommend you to grab the -documentation from this package and read it carefully. All examples should -run unmodified under @ecl{} (Of course, you do not need to download UFFI -itself, as everything is already implemented in @ecl{}. - -However, because @ecl{} provides some additional functionality which escapes the -UFFI, and also for compatibility with older versions of the @ecl{} environment, -we provide additional toplevel forms, which are listed in the next section. - - -@node The old C language interface, , The C language interface, The compiler -@section The old C language interface - -In this section we list several macros and toplevel forms which are provided -either for convenience or for compatibility with older versions of @ecl{}. -You should avoid using them when the UFFI-compatible interface provides -similar functionality. - -We define some terminology here which is used throughout this Chapter. A -@emph{C-id} is either a Lisp string consisting of a valid C-language -identifier, or a Lisp symbol whose print-name, with all its alphabetic -characters turned into lower case, is a valid C identifier. Thus the symbol -@code{foo} is equivalent to the string @code{"foo"} when used as a C-id. -Similarly, a @emph{C-expr} is a string that may be regarded as a -C-language expression. A @emph{C-type} is one of the Lisp symbols -@code{:int, :char, :float, :double,...} and @code{:object}. -Each corresponds to a data type in the C language; @code{:object} is -the type of Lisp object and other C-types are primitive data types in C. - -@defmac {defentry} @{@var{function} @var{parameter-list} @var{C-function}@} - -@code{defentry} defines a Lisp function whose body consists of the calling -sequence to a C-language function. @var{function} is the name of the Lisp -function to be defined, and @var{C-function} specifies the C function to be -invoked. @var{C-function} must be either a list @code{(@var{type C-id})} or -@var{C-id}, where @var{type} and @var{C-id} are the type and the name of the C -function. @var{type} must be a C-type or the symbol @code{void} which means -that the C function returns no value. @code{(object @var{C-id})} may be -abbreviated as @var{C-id}. @var{parameter-list} is a list of C-types for the -parameters of the C function. For example, the following @code{defentry} form -defines a Lisp function @code{tak} from which the C function @code{tak} above -is called. - -@end defmac - -@lisp -(defentry tak (:int :int :int) (:int tak)) -@end lisp - -The Lisp function @code{tak} defined by this @code{defentry} form requires -three arguments. The arguments are converted to @code{int} values before they -are passed to the C function. On return from the C function, the returned -@code{int} value is converted to a Lisp integer (actually a fixnum) and this -fixnum will be returned as the value of the Lisp function. See below for type -conversion between Lisp and the C language. - -A @code{defentry} form is treated in the above way only when it appears as a -top-level form of a Lisp source file. Otherwise, a @code{defentry} form -expands to @nil{}. - -@defmac {defla} @{name lambda-list @{declaration | doc-string@}*@} - -When interpreted, @code{defla} is exactly the same as @code{defun}. That is, -@code{(defla @var{name lambda-list . body})} expands to @code{(defun @var{name -lambda-list . body})}. However, @code{defla} forms are completely ignored by -the compiler; no C-language code will be generated for @code{defla} forms. The -primary use of @code{defla} is to define a Lisp function in two ways within a -single Lisp source file; one in the C language and the other in Lisp. -@code{defla} is short for @emph{DEF}ine @emph{L}isp @emph{A}lternative. -@end defmac - -Suppose you have a Lisp source file whose contents are: - -@lisp -(use-package "FFI") - -;;; C version of TAK. -(Clines " - - int tak(x, y, z) - int x, y, z; - @{ if (y >= x) return(z); - else return(tak(tak(x-1, y, z), - tak(y-1, z, x), - tak(z-1, x, y))); - @} -" -) - -;;; TAK calls the C function tak defined above. -(defentry tak (:int :int :int) (:int tak)) -;;; The alternative Lisp definition of TAK. -(defla tak (x y z) - (if (>= y x) - z - (tak (tak (1- x) y z) - (tak (1- y) z x) - (tak (1- z) x y)))) -@end lisp - -When this file is loaded into @ecl{}, the interpreter uses the Lisp version of -the @code{tak} definition. Once this file has been compiled, and when the -generated fasl file is loaded into @ecl{}, a function call to @code{tak} is -actually the call to the C version of @code{tak}. - -@defun {defCbody} {name args-types result-type C-expr} -The @ecl{} compiler produces a function named @var{name} with as many -arguments as @var{arg-types}. The @var{C-expr} is an arbitrary C expression -where the arguments to the function are denoted by @code{#@emph{i}}, where -@code{@emph{i}} is the integer corresponding to the argument position. The -@var{args-types} is the list of @clisp types of the arguments to the function, -while @var{result-type} is the @clisp type of the result. The actual arguments -are coerced to the required types before executing the @var{C-expr} and the -result is converted into a Lisp object. @code{defCbody} is ignored by the -interpreter. -@end defun - -For example, the logical AND of two integers could be defined as: -@lisp -(defCbody logand (fixnum fixnum) fixnum "(#0) & (#1)") -@end lisp - -@defun {definline} @{name args-types result-type C-expr@} -@code{definline} behaves exactly as @code{defCbody}. Moreover, after a -@code{definline} definition has been supplied, the @ecl{} compiler will expand -inline any call to function @var{name} into code corresponding to the C -language expression @var{C-expr}, provided that the actual arguments are of the -specified type. If the actual arguments cannot be coerced to those types, the -inline expansion is not performed. @code{definline} is ignored by the -interpreter. - -@end defun - -For example, a function to access the n-th byte of a string and return it as an -integer can be defined as follows: - -@lisp -(definline aref-byte (string fixnum) fixnum - "(#0)->ust.ust_self[#1]") -@end lisp - -The definitions of the C data structures used to represent \clisp objects can -be found in file @code{ecl.h} in the directory @code{"src/h"} of the source -distribution. - -@ecl{} converts a Lisp object into a C-language data by using the @clisp{} -function @code{coerce}: For the C-type @code{int} (or @code{char}), the object -is first coerced to a Lisp integer and the least significant 32-bit (or 8-bit) -field is used as the C @code{int} (or @code{char}). For the C-type -@code{float} (or @code{double}), the object is coerced to a single-float (or a -double-float) and this value is used as the @code{C float} (or @code{double}). -Conversion from a C data into a Lisp object is obvious: @code{C char, int, -float,} and @code{double} become the equivalent Lisp @code{character}, -@code{fixnum}, @code{single-float}, and @code{double-float}, respectively. - -Here we list the complete syntax of @code{Clines}, @code{defentry}, -@code{definline} and @code{defCbody} macro forms. - -@verbatim -Clines-form: - (Clines @{string@}*) - -defentry-form: - (defentry symbol (@{C-type@}*) - @{C-function-name | (@{C-type | void@} C-function-name)@}) - -defCbody-form: - (defCbody symbol (@{type@}*) type C-expr) - -definline-form: - (defCbody symbol (@{type@}*) type C-expr) - -C-function-name: - @{ string | symbol @} -C-expr: - string -C-type: - @{ object | int | char | float | double @} -@end verbatim - -@c --------------------------------------------------------------------- - -@node The Garbage Collector, Porting ECL, The compiler, Top -@chapter The Garbage Collector - -Using @ecl{} in existing application sometimes involves keeping Lisp -objects where the garbage collector normally cannot see them. - -@c FIXME: Complete this... - -@c --------------------------------------------------------------------- - -@node Porting ECL, , The Garbage Collector, Top -@chapter Porting @ecl{} - -To port @ecl{} to a new architecture, the following steps are required: - -@enumerate -@item Ensure that the GNU Multiprecision library supports this machine. - -@item Ensure that the Boehm-Weiser garbage collector is supported by that -architecture. Alternatively, port ECL's own garbage collector -@file{src/c/alloc.d} and @file{src/c/gbc.d} to that platform. - -@item Fix @file{src/aclocal.in}, @file{src/h/ecl.h} and @file{src/h/ecl-cmp.h} -so that they supply flags for the new host machine. - -@item Fix the machine dependent code in @file{src/c/}. The most critical -parts are in the @file{unix*} and @file{thread*} files. - -@item Compile as in any other platform. - -@item Run the tests and compare to the results of other platforms. -@end enumerate -@bye diff --git a/src/doc/macros.txi b/src/doc/macros.txi deleted file mode 100644 index df0045c66..000000000 --- a/src/doc/macros.txi +++ /dev/null @@ -1,97 +0,0 @@ -@macro myctrl {a} -^\a\@c -@end macro -@rmacro mopt {a} -[\a\]@c -@end rmacro -@macro mchoice {a} -<\a\>@c -@end macro -@rmacro mstar {a} -@{\a\@}*@c -@end rmacro -@rmacro mplus {a} -@{\a\@}+@c -@end rmacro -@rmacro mgroup {a} -@{\a\@},@c -@end rmacro - -@macro kwd{a} -@var{:\a\}@c -@end macro - -@macro pxlref{a} -\a\@c -@end macro - -@macro defec{a} -@defun \a\ -@end macro - -@macro aux -&aux@c -@end macro -@macro keys -&key@c -@end macro -@macro rest -&rest@c -@end macro -@macro optional -&optional@c -@end macro -@macro allow -&allow-other-keys@c -@end macro - -@macro macref{foo} -\foo\@c -@end macro -@macro tindexed{foo} -\foo\@c -@end macro -@macro cindexed{foo} -\foo\@c -@end macro -@macro vindexed{foo} -\foo\@c -@end macro -@ifhtml -@macro bibcite{foo} -[@pxref{Bibliography, \foo\}] -@end macro -@end ifhtml -@ifnothtml -@macro bibcite{foo} -[\foo\, @pxref{Bibliography}] -@end macro -@end ifnothtml - -@macro back -\\@c -@end macro - -@macro nil -()@c -@end macro - -@macro true -@var{T}@c -@end macro - -@macro ansi -@r{ANSI Common-Lisp}@c -@end macro -@macro ecl -@b{@r{ECL}} -@end macro -@macro clisp -@r{Common-Lisp}@c -@end macro -@macro llisp -@b{@r{Lisp}} -@end macro -@macro cltl -@emph{@clisp{}: The Language}@c -@end macro diff --git a/src/doc/todo.txt b/src/doc/todo.txt deleted file mode 100644 index fa77d4294..000000000 --- a/src/doc/todo.txt +++ /dev/null @@ -1,290 +0,0 @@ -GOODIES: -======== - -* Improve fixnum_times. - -* expand parse_namestring() to accept scaped strings, spaces, etc. - -* Make the version with Boehm's GC and the version without it binary - compatible. - -* Complete the MOP. - -* Write general functions that implement the ~E, ~F and ~G formatters and use - them in the printer, so that both PRINT, PRINC, etc and FORMAT produce - exactly the same representation of floating point numbers. - -* Implemment type checking in structure slot setters. - -COMPILER: -========= - -! Use conditions to signal warnings and errors. - -* In local functions, remove unused arguments. - -* It should be possible, in local functions that do not reference variables - from the enclosing code, and do not call any other functions that do it, - to remove the "lex*" arguments. - -* Optimize out (multiple-value-call ... (values ...)). - -* Implement memory collection based on mmap() - -* Improve the garbage collector using kernel information about dirty - pages. - -* In the list of objects *.data, remove those which are not referenced. - This requires major changes to the way locations are produced since - right now they are assigned in the C1 phase, while some objects are - discarded late in the C2 phase. - -THREADS: -======== - -Variables with locked access: - packages_list, ecl_packages_to_be_created, - pathname_translations -Variables to be included in cl_env: - + variables in list.d - + bignum_register - + fmt_aux_stream (format.d) - + c_env (compiler.d) - + base (disassembler.d) -Variables to be redesigned as global: - ARGC, ARGV -Unknown variables - dispatch_reader - default_dispatch_macro - -KNOWN BUGS: -=========== - -* An array might have a->array.displaced != Cnil and still not be - displaced. This is the case of an array that had some vectors displaced - to it!!! - -* #'unread-char does not fail when the character differs from the - original one. - -* vector-push-extend may succeed even if the vector is not - adjustable. Should we be more strict? - -* should we relax ASSOC? (See lists156.tst) - -* When building :AROUND, :AFTER or :BEFORE methods for REINITIALIZE-INSTANCE, - one may introduce new initialization options, that CHECK-INITARGS ignores. - (See REINITIALIZE-INSTANCE.10 in Paul Dietz' test suite). - -* Why is this considered a failure? What does (SETF CLASS-NAME) have to do? - -Test CLASS-0309.1 failed -Form: (PROGN - (SETF (FIND-CLASS 'CLASS-0309) NIL) - (LET* ((CLASS1 (EVAL '(DEFCLASS CLASS-0309 NIL ((A) (B) (C))))) - (OBJ1 (MAKE-INSTANCE 'CLASS-0309))) - (SETF (CLASS-NAME CLASS1) NIL) - (LET ((CLASS2 (EVAL '(DEFCLASS CLASS-0309 NIL ((A) (B) (C)))))) - (VALUES (EQT (CLASS-OF OBJ1) CLASS1) (EQT CLASS1 CLASS2) - (TYPEP* OBJ1 CLASS1) (TYPEP* OBJ1 CLASS2))))) -Expected values: T - NIL - T - NIL -Actual values: T - T - T - T. - - -OLD: (Maybe out of date) -======================== - -* error-set can be eliminated, as well as FRS_CATCHALL fr_class and - Kcatchall keyword. - -* Removed call - (wt-data nil) - before loop (dolist (x *linking-calls*) ..) in ctop-write. - Created inconsistency in size of data vector in cfun. - What was it for? - -* For local entry functions the binding for args which are special - should be done after the label TTL: has been emitted. - -* From triang-mod.cl. The following: - (setf (aref board (aref a i)) 0) - compiles to: - {object V3; - object V4; - V3= (VV[10]->s.s_dbind); - V4= MAKE_FIXNUM(((VV[15]->s.s_dbind))->fixa.fixa_self[V1]); - ((V3))->fixa.fixa_self[fix((V4))]= 0; - } - even though: - (proclaim '(type (vector fixnum) board sequence a b c)) - -* When compiling do/do* references to variables in test forms should - be considered multiple. - -* The mechanism for printing circular structure fails on sun when - size exceeds PRINTcircleSIZE. - -* disassemble does not behave as in help.doc. - -* c1apply-optimize could emit code for testing whether there are - sufficient elements in the list - -* Update code to use constants in - -* The mechanism of local/global entries in cmptop.lsp is worth while - only if all arguments are unboxed. - -* Lavori piu' impegnativi: - - Rifare il trattamento di ihs - - introdurre dichiarazione :dynamic-extent - - aggiungere agli ottimizzatori i flags usati da Sherlis - -* Completare la modifica di print-doc (describe.lsp) per stampare - intestazioni ripetute per quei simboli (list, *, etc.) che hanno - documentazione multipla. - -* Completare l'aggiunta di nomi di caratteri: - #\F1, ... , #\F12, #\C-F1, .. , #\C-F12, #\M-F1, .. , #\M-F12 - #\Up, #\Down, #\Left, #\Right, #\C-Up, #\C-Down, #\C-Left, #\C-Right - #\PgUp, #\PgDn, #\Home, #\End, #\C-PgUp, #\C-PgDn, #\C-Home, #\C-End - -* verificare se usando una VAR come *destination* - (let* ((kind (var-kind var)) - (lcl (next-lcl)) - (temp (list 'VAR (make-var :kind kind :loc lcl)))) - (wt-nl "{" *volatile* (rep-type kind)) (wt-lcl lcl) (wt ";") - (let ((*destination* temp)) (c2expr* form)) - si puo' semplificare inline-args evitando l'uso di coerce-loc. - -* questa clausola di cmpinline.lsp - ((or (eq (var-kind var) 'LEXICAL) - (eq (var-kind var) 'OBJECT)) - (let ((lcl-loc (list 'LCL (next-lcl)))) - (wt-nl "{object " lcl-loc "= " - (wt-lcl (var-loc var)) (wt ";") - (push (coerce-loc lcl-loc type) locs) - (incf *inline-blocks*)))) - e' dubbia: (wt-lcl (var-loc var)) per un LEXICAL? - -* parameter closure-p in t3local-fun could be eliminated: it is present - in (fun-closure fun). - -* All loops of the kind: - for (i = 0; i < maxpage; i++) { - in gbc.c, could be changed to i = minpage, where: - minpage = page(heap_end); - just after - heap_end = core_end = sbrk(0); - in alloc.c - -* In macro_expand1: - (lex_env[1] == OBJNULL) ? Cnil : - dovrebbe forse essere - (lex_env[1] == Cnil) ? Cnil : - -* trattamento or non soddisfacente: - (let ((dir (or (and output-file - (pathname-directory output-file)) - (pathname-directory input-pathname))) - - if((V2)==Cnil){ - VALUES(0) = Cnil; - goto L42;} - Lpathname_directory(1,(V2)) /* PATHNAME-DIRECTORY*/; -L42: - if(VALUES(0)==Cnil)goto L41; - V11= VALUES(0); - goto L40; -L41: - Lpathname_directory(1,(V1)) /* PATHNAME-DIRECTORY*/; - V11= VALUES(0); -L40: - if((V2)==Cnil){ - VALUES(0) = Cnil; - goto L45;} - Lpathname_name(1,(V2)) /* PATHNAME-NAME */; -L45: - if(VALUES(0)==Cnil)goto L44; - V12= VALUES(0); - goto L43; -L44: - Lpathname_name(1,(V1)) /* PATHNAME-NAME */; - V12= VALUES(0); -L43: - -* in sysfun, scambiare never-change-special-var-p con - change-special-var-p per evitare creazione di troppe plist - -* (setq spec (pop vl)) produces: - {object V12; /* G4356 */ - V12= CAR((V1)); - V1= CDR((V1)); - V2= (V12); - } - -* (or (and (foo) - (listp args)) - ... - if(VALUES(0)!=Cnil){ - goto L21;} - VALUES(0) = Cnil; - goto L20; -L21: - VALUES(0) = (type_of((V2))==t_cons||(V2)==Cnil?Ct:Cnil); -L20: - if(VALUES(0)==Cnil)goto L19; - - potrebbe essere migliorata. c2or dovrebbe chiamare c2expr con - JUMP-TRUE come *destination*, ma dovrebbe sapere in quale - locazione unwind-exit mette il risultato facendoselo ritornare. - -* cambiare vref1 perche' ritorni solo var anziche' (var) - -* (min (* *step-level* 2) 20) produce - (number_compare(number_times((VV[58]->s.s_dbind),MAKE_FIXNUM(2)),MAKE_FIXNUM(20))<=0?number_times((VV[58]->s.s_dbind),MAKE_FIXNUM(2)):MAKE_FIXNUM(20)) - -* Aggiungere ottimizzazione travel_push_type in print.d per - la stampa ciclica, come AKCL. - -* Rimettere #. in default-init in cmptype.lsp (finito bootstrap - da AKCL) - -* ricorsione diretta in c2call-global (utile per labels) - da' problemi a flet. - -* unwind-exit caso FRAME considera SIMPLE-FUNCALL. Deve considerare - anche FUN-VAL? - -* (let ((start start) (end end)) - (declare (fixnum start end)) - puo' evitare di creare variabili object e poi relative unboxed - -* scambiare ordine argomenti di si:putprop per facilitare (setf get). - -* aggiungere funzioni di lwp.d in cmp/sysfun.lsp - -* Rewrite setjmp.s so that PC is stored in slot 0 of buf, consistently - with _setjmp. - -* Change lex.h and elsewhere so that: - - lex-var: (symbol value) ; for local binding - (.... or ....) - symbol ; for special binding - - lex-fd: (fun-name 'FUNCTION' . function) - (.... or ...) - (macro-name 'MACRO' . expansion-function) - - lex-tag: (tag 'TAG' . frame-id) - (.... or ....) - (block-name 'BLOCK' . frame-id) - -* Funzione directory non funziona sotto DOS: la free chiamata - da setbuf fallisce. diff --git a/src/doc/tutorial.txt b/src/doc/tutorial.txt deleted file mode 100644 index 6f963f8a5..000000000 --- a/src/doc/tutorial.txt +++ /dev/null @@ -1,1131 +0,0 @@ - Common LISP Hints - Geoffrey J. Gordon - - Friday, February 5, 1993 - - Modified by - Giuseppe Attardi - - -Note: This tutorial introduction to Common Lisp was written for the -CMU environment, so some of the details of running lisp toward the end -may differ from site to site. - - -Further Information - -The best LISP textbook I know of is - - Guy L. Steele Jr. _Common LISP: the Language_. Digital Press. 1984. - -The first edition is easier to read; the second describes a more recent -standard. (The differences between the two standards shouldn't affect -casual programmers.) - -A book by Dave Touretsky has also been recommended to me, although I -haven't read it, so I can't say anything about it. - - - -Symbols - -A symbol is just a string of characters. There are restrictions on what -you can include in a symbol and what the first character can be, but as -long as you stick to letters, digits, and hyphens, you'll be safe. -(Except that if you use only digits and possibly an initial hyphen, -LISP will think you typed an integer rather than a symbol.) Some -examples of symbols: - - a - b - c1 - foo - bar - baaz-quux-garply - -Some things you can do with symbols follow. (Things after a ">" prompt -are what you type to the LISP interpreter, while other things are what -the LISP interpreter prints back to you. The ";" is LISP's comment -character: everything from a ";" to the end of line is ignored.) - -> (setq a 5) ;store a number as the value of a symbol -5 -> a ;take the value of a symbol -5 -> (let ((a 6)) a) ;bind the value of a symbol temporarily to 6 -6 -> a ;the value returns to 5 once the let is finished -5 -> (+ a 6) ;use the value of a symbol as an argument to a function -11 -> b ;try to take the value of a symbol which has no value -Error: Attempt to take the value of the unbound symbol B - -There are two special symbols, t and nil. The value of t is defined -always to be t, and the value of nil is defined always to be nil. LISP -uses t and nil to represent true and false. An example of this use is -in the if statement, described more fully later: - -> (if t 5 6) -5 -> (if nil 5 6) -6 -> (if 4 5 6) -5 - -The last example is odd but correct: nil means false, and anything else -means true. (Unless we have a reason to do otherwise, we use t to mean -true, just for the sake of clarity.) - -Symbols like t and nil are called self-evaluating symbols, because -they evaluate to themselves. There is a whole class of self-evaluating -symbols called keywords; any symbol whose name starts with a colon is a -keyword. (See below for some uses for keywords.) Some examples: - -> :this-is-a-keyword -:THIS-IS-A-KEYWORD -> :so-is-this -:SO-IS-THIS -> :me-too -:ME-TOO - - - -Numbers - -An integer is a string of digits optionally preceded by + or -. A real -number looks like an integer, except that it has a decimal point and -optionally can be written in scientific notation. A rational looks like -two integers with a / between them. LISP supports complex numbers, -which are written #c(r i) (where r is the real part and i is the -imaginary part). A number is any of the above. Here are some numbers: - - 5 - 17 - -34 - +6 - 3.1415 - 1.722e-15 - #c(1.722e-15 0.75) - -The standard arithmetic functions are all available: +, -, *, /, floor, -ceiling, mod, sin, cos, tan, sqrt, exp, expt, and so forth. All of them -accept any kind of number as an argument. +, -, *, and / return a -number according to type contagion: an integer plus a rational is a -rational, a rational plus a real is a real, and a real plus a complex -is a complex. Here are some examples: - -> (+ 3 3/4) ;type contagion -15/4 -> (exp 1) ;e -2.7182817 -> (exp 3) ;e*e*e -20.085537 -> (expt 3 4.2) ;exponent with a base other than e -100.90418 -> (+ 5 6 7 (* 8 9 10)) ;the fns +-*/ all accept multiple arguments - -There is no limit to the absolute value of an integer except the memory -size of your computer. Be warned that computations with bignums (as -large integers are called) can be slow. (So can computations with -rationals, especially compared to the corresponding computations with -small integers or floats.) - - - -Conses - -A cons is just a two-field record. The fields are called "car" and -"cdr", for historical reasons. (On the first machine where LISP was -implemented, there were two instructions CAR and CDR which stood for -"contents of address register" and "contents of decrement register". -Conses were implemented using these two registers.) - -Conses are easy to use: - -> (cons 4 5) ;Allocate a cons. Set the car to 4 and the cdr to 5. -(4 . 5) -> (cons (cons 4 5) 6) -((4 . 5) . 6) -> (car (cons 4 5)) -4 -> (cdr (cons 4 5)) -5 - - - -Lists - -You can build many structures out of conses. Perhaps the simplest is a -linked list: the car of each cons points to one of the elements of the -list, and the cdr points either to another cons or to nil. You can -create such a linked list with the list fuction: - -> (list 4 5 6) -(4 5 6) - -Notice that LISP prints linked lists a special way: it omits some of -the periods and parentheses. The rule is: if the cdr of a cons is nil, -LISP doesn't bother to print the period or the nil; and if the cdr of -cons A is cons B, then LISP doesn't bother to print the period for cons -A or the parentheses for cons B. So: - -> (cons 4 nil) -(4) -> (cons 4 (cons 5 6)) -(4 5 . 6) -> (cons 4 (cons 5 (cons 6 nil))) -(4 5 6) - -The last example is exactly equivalent to the call (list 4 5 6). Note -that nil now means the list with no elements: the cdr of (a b), a list -with 2 elements, is (b), a list with 1 element; and the cdr of (b), a -list with 1 element, is nil, which therefore must be a list with no -elements. - -The car and cdr of nil are defined to be nil. - -If you store your list in a variable, you can make it act like a stack: - -> (setq a nil) -NIL -> (push 4 a) -(4) -> (push 5 a) -(5 4) -> (pop a) -5 -> a -(4) -> (pop a) -4 -> (pop a) -NIL -> a -NIL - - - -Functions - -You saw one example of a function above. Here are some more: - -> (+ 3 4 5 6) ;this function takes any number of arguments -18 -> (+ (+ 3 4) (+ (+ 4 5) 6)) ;isn't prefix notation fun? -22 -> (defun foo (x y) (+ x y 5)) ;defining a function -FOO -> (foo 5 0) ;calling a function -10 -> (defun fact (x) ;a recursive function - (if (> x 0) - (* x (fact (- x 1))) - 1 - ) ) -FACT -> (fact 5) -120 -> (defun a (x) (if (= x 0) t (b (- x)))) ;mutually recursive functions -A -> (defun b (x) (if (> x 0) (a (- x 1)) (a (+ x 1)))) -B -> (a 5) -T -> (defun bar (x) ;a function with multiple statements in - (setq x (* x 3)) ;its body -- it will return the value - (setq x (/ x 2)) ;returned by its final statement - (+ x 4) - ) -BAR -> (bar 6) -13 - -When we defined foo, we gave it two arguments, x and y. Now when we -call foo, we are required to provide exactly two arguments: the first -will become the value of x for the duration of the call to foo, and the -second will become the value of y for the duration of the call. In -LISP, most variables are lexically scoped; that is, if foo calls bar -and bar tries to reference x, bar will not get foo's value for x. - -The process of assigning a symbol a value for the duration of some -lexical scope is called binding. - -You can specify optional arguments for your functions. Any argument -after the symbol &optional is optional: - -> (defun bar (x &optional y) (if y x 0)) -BAR -> (defun baaz (&optional (x 3) (z 10)) (+ x z)) -BAAZ -> (bar 5) -0 -> (bar 5 t) -5 -> (baaz 5) -15 -> (baaz 5 6) -11 -> (baaz) -13 - -It is legal to call the function bar with either one or two arguments. -If it is called with one argument, x will be bound to the value of that -argument and y will be bound to nil; if it is called with two -arguments, x and y will be bound to the values of the first and second -argument, respectively. - -The function baaz has two optional arguments. It specifies a default -value for each of them: if the caller specifies only one argument, z -will be bound to 10 instead of to nil, and if the caller specifies no -arguments, x will be bound to 3 and z to 10. - -You can make your function accept any number of arguments by ending its -argument list with an &rest parameter. LISP will collect all arguments -not otherwise accounted for into a list and bind the &rest parameter to -that list. So: - -> (defun foo (x &rest y) y) -FOO -> (foo 3) -NIL -> (foo 4 5 6) -(5 6) - -Finally, you can give your function another kind of optional argument -called a keyword argument. The caller can give these arguments in any -order, because they're labelled with keywords. - -> (defun foo (&key x y) (cons x y)) -FOO -> (foo :x 5 :y 3) -(5 . 3) -> (foo :y 3 :x 5) -(5 . 3) -> (foo :y 3) -(NIL . 3) -> (foo) -(NIL) - -An &key parameter can have a default value too: - -> (defun foo (&key (x 5)) x) -FOO -> (foo :x 7) -7 -> (foo) -5 - - - -Printing - -Some functions can cause output. The simplest one is print, which -prints its argument and then returns it. - -> (print 3) -3 -3 - -The first 3 above was printed, the second was returned. - -If you want more complicated output, you will need to use format. -Here's an example: - -> (format t "An atom: ~S~%and a list: ~S~%and an integer: ~D~%" - nil (list 5) 6) -An atom: NIL -and a list: (5) -and an integer: 6 - -The first argument to format is either t, nil, or a stream. T specifies -output to the terminal. Nil means not to print anything but to return a -string containing the output instead. Streams are general places for -output to go: they can specify a file, or the terminal, or another -program. This handout will not describe streams in any further detail. - -The second argument is a formatting template, which is a string -optionally containing formatting directives. - -All remaining arguments may be referred to by the formatting -directives. LISP will replace the directives with some appropriate -characters based on the arguments to which they refer and then print -the resulting string. - -Format always returns nil unless its first argument is nil, in which -case it prints nothing and returns a string. - -There are three different directives in the above example: ~S, ~D, and -~%. The first one accepts any LISP object and is replaced by a printed -representation of that object (the same representation which is -produced by print). The second one accepts only integers. The third one -doesn't refer to an argument; it is always replaced by a carriage -return. - -Another useful directive is ~~, which is replaced by a single ~. - -Refer to a LISP manual for (many, many) additional formatting -directives. - - - -Forms and the Top-Level Loop - -The things which you type to the LISP interpreter are called forms; the -LISP interpreter repeatedly reads a form, evaluates it, and prints the -result. This procedure is called the read-eval-print loop. - -Some forms will cause errors. After an error, LISP will put you into -the debugger so you can try to figure out what caused the error. LISP -debuggers are all different; but most will respond to the command -"help" or ":help" by giving some form of help. - -In general, a form is either an atom (for example, a symbol, an -integer, or a string) or a list. If the form is an atom, LISP evaluates -it immediately. Symbols evaluate to their value; integers and strings -evaluate to themselves. If the form is a list, LISP treats its first -element as the name of a function; it evaluates the remaining elements -recursively, and then calls the function with the values of the -remaining elements as arguments. - -For example, if LISP sees the form (+ 3 4), it treats + as the name of -a function. It then evaluates 3 to get 3 and 4 to get 4; finally it -calls + with 3 and 4 as the arguments. The + function returns 7, which -LISP prints. - -The top-level loop provides some other conveniences; one particularly -convenient convenience is the ability to talk about the results of -previously typed forms. LISP always saves its most recent three -results; it stores them as the values of the symbols *, **, and ***. -For example: - -> 3 -3 -> 4 -4 -> 5 -5 -> *** -3 -> *** -4 -> *** -5 -> ** -4 -> * -4 - - - -Special forms - -There are a number of special forms which look like function calls but -aren't. These include control constructs such as if statements and do -loops; assignments like setq, setf, push, and pop; definitions such as -defun and defstruct; and binding constructs such as let. (Not all of -these special forms have been mentioned yet. See below.) - -One useful special form is the quote form: quote prevents its argument -from being evaluated. For example: - -> (setq a 3) -3 -> a -3 -> (quote a) -A -> 'a ;'a is an abbreviation for (quote a) -A - -Another similar special form is the function form: function causes its -argument to be interpreted as a function rather than being evaluated. -For example: - -> (setq + 3) -3 -> + -3 -> '+ -+ -> (function +) -# -> #'+ ;#'+ is an abbreviation for (function +) -# - -The function special form is useful when you want to pass a function as -an argument to another function. See below for some examples of -functions which take functions as arguments. - - - -Binding - -Binding is lexically scoped assignment. It happens to the variables in -a function's parameter list whenever the function is called: the formal -parameters are bound to the actual parameters for the duration of the -function call. You can bind variables anywhere in a program with the -let special form, which looks like this: - - (let ((var1 val1) - (var2 val2) - ... - ) - body - ) - -Let binds var1 to val1, var2 to val2, and so forth; then it executes -the statements in its body. The body of a let follows exactly the same -rules that a function body does. Some examples: - -> (let ((a 3)) (+ a 1)) -4 -> (let ((a 2) - (b 3) - (c 0)) - (setq c (+ a b)) - c - ) -5 -> (setq c 4) -4 -> (let ((c 5)) c) -5 -> c -4 - -Instead of (let ((a nil) (b nil)) ...), you can write (let (a b) ...). - -The val1, val2, etc. inside a let cannot reference the variables var1, -var2, etc. that the let is binding. For example, - -> (let ((x 1) - (y (+ x 1))) - y - ) -Error: Attempt to take the value of the unbound symbol X - -If the symbol x already has a global value, stranger happenings will -result: - -> (setq x 7) -7 -> (let ((x 1) - (y (+ x 1))) - y - ) -8 - -The let* special form is just like let except that it allows values to -reference variables defined earlier in the let*. For example, - -> (setq x 7) -7 -> (let* ((x 1) - (y (+ x 1))) - y - ) -2 - -The form - - (let* ((x a) - (y b)) - ... - ) - -is equivalent to - - (let ((x a)) - (let ((y b)) - ... - ) ) - - - -Dynamic Scoping - -The let and let* forms provide lexical scoping, which is what you -expect if you're used to programming in C or Pascal. Dynamic scoping is -what you get in BASIC: if you assign a value to a dynamically scoped -variable, every mention of that variable returns that value until you -assign another value to the same variable. - -In LISP, dynamically scoped variables are called special variables. You -can declare a special variable with the defvar special form. Here are -some examples of lexically and dynamically scoped variables. - -In this example, the function check-regular references a regular (ie, -lexically scoped) variable. Since check-regular is lexically outside of -the let which binds regular, check-regular returns the variable's -global value. - -> (setq regular 5) -5 -> (defun check-regular () regular) -CHECK-REGULAR -> (check-regular) -5 -> (let ((regular 6)) (check-regular)) -5 - -In this example, the function check-special references a special (ie, -dynamically scoped) variable. Since the call to check-special is -temporally inside of the let which binds special, check-special returns -the variable's local value. - -> (defvar *special* 5) -*SPECIAL* -> (defun check-special () *special*) -CHECK-SPECIAL -> (check-special) -5 -> (let ((*special* 6)) (check-special)) -6 - -By convention, the name of a special variable begins and ends with a *. -Special variables are chiefly used as global variables, since -programmers usually expect lexical scoping for local variables and -dynamic scoping for global variables. - -For more information on the difference between lexical and dynamic -scoping, see _Common LISP: the Language_. - - - -Arrays - -The function make-array makes an array. The aref function accesses its -elements. All elements of an array are initially set to nil. For -example: - -> (make-array '(3 3)) -#2a((NIL NIL NIL) (NIL NIL NIL) (NIL NIL NIL)) -> (aref * 1 1) -NIL -> (make-array 4) ;1D arrays don't need the extra parens -#(NIL NIL NIL NIL) - -Array indices always start at 0. - -See below for how to set the elements of an array. - - - -Strings - -A string is a sequence of characters between double quotes. LISP -represents a string as a variable-length array of characters. You can -write a string which contains a double quote by preceding the quote -with a backslash; a double backslash stands for a single backslash. For -example: - - "abcd" has 4 characters - "\"" has 1 character - "\\" has 1 character - -Here are some functions for dealing with strings: - -> (concatenate 'string "abcd" "efg") -"abcdefg" -> (char "abc" 1) -#\b ;LISP writes characters preceded by #\ -> (aref "abc" 1) -#\b ;remember, strings are really arrays - -The concatenate function can actually work with any type of sequence: - -> (concatenate 'string '(#\a #\b) '(#\c)) -"abc" -> (concatenate 'list "abc" "de") -(#\a #\b #\c #\d #\e) -> (concatenate 'vector '#(3 3 3) '#(3 3 3)) -#(3 3 3 3 3 3) - - - -Structures - -LISP structures are analogous to C structs or Pascal records. Here is -an example: - -> (defstruct foo - bar - baaz - quux - ) -FOO - -This example defines a data type called foo which is a structure -containing 3 fields. It also defines 4 functions which operate on this -data type: make-foo, foo-bar, foo-baaz, and foo-quux. The first one -makes a new object of type foo; the others access the fields of an -object of type foo. Here is how to use these functions: - -> (make-foo) -#s(FOO :BAR NIL :BAAZ NIL :QUUX NIL) -> (make-foo :baaz 3) -#s(FOO :BAR NIL :BAAZ 3 :QUUX NIL) -> (foo-bar *) -NIL -> (foo-baaz **) -3 - -The make-foo function can take a keyword argument for each of the -fields a structure of type foo can have. The field access functions -each take one argument, a structure of type foo, and return the -appropriate field. - -See below for how to set the fields of a structure. - - - -Setf - -Certain forms in LISP naturally define a memory location. For example, -if the value of x is a structure of type foo, then (foo-bar x) defines -the bar field of the value of x. Or, if the value of y is a one- -dimensional array, (aref y 2) defines the third element of y. - -The setf special form uses its first argument to define a place in -memory, evaluates its second argument, and stores the resulting value -in the resulting memory location. For example, - -> (setq a (make-array 3)) -#(NIL NIL NIL) -> (aref a 1) -NIL -> (setf (aref a 1) 3) -3 -> a -#(NIL 3 NIL) -> (aref a 1) -3 -> (defstruct foo bar) -FOO -> (setq a (make-foo)) -#s(FOO :BAR NIL) -> (foo-bar a) -NIL -> (setf (foo-bar a) 3) -3 -> a -#s(FOO :BAR 3) -> (foo-bar a) -3 - -Setf is the only way to set the fields of a structure or the elements -of an array. - -Here are some more examples of setf and related functions. - -> (setf a (make-array 1)) ;setf on a variable is equivalent to setq -#(NIL) -> (push 5 (aref a 1)) ;push can act like setf -(5) -> (pop (aref a 1)) ;so can pop -5 -> (setf (aref a 1) 5) -5 -> (incf (aref a 1)) ;incf reads from a place, increments, -6 ;and writes back -> (aref a 1) -6 - - - -Booleans and Conditionals - -LISP uses the self-evaluating symbol nil to mean false. Anything other -than nil means true. Unless we have a reason not to, we usually use the -self-evaluating symbol t to stand for true. - -LISP provides a standard set of logical functions, for example and, or, -and not. The and and or connectives are short-circuiting: and will not -evaluate any arguments to the right of the first one which evaluates to -nil, while or will not evaluate any arguments to the right of the first -one which evaluates to t. - -LISP also provides several special forms for conditional execution. The -simplest of these is if. The first argument of if determines whether -the second or third argument will be executed: - -> (if t 5 6) -5 -> (if nil 5 6) -6 -> (if 4 5 6) -5 - -If you need to put more than one statement in the then or else clause -of an if statement, you can use the progn special form. Progn executes -each statement in its body, then returns the value of the final one. - -> (setq a 7) -7 -> (setq b 0) -0 -> (setq c 5) -5 -> (if (> a 5) - (progn - (setq a (+ b 7)) - (setq b (+ c 8))) - (setq b 4) - ) -13 - -An if statement which lacks either a then or an else clause can be -written using the when or unless special form: - -> (when t 3) -3 -> (when nil 3) -NIL -> (unless t 3) -NIL -> (unless nil 3) -3 - -When and unless, unlike if, allow any number of statements in their -bodies. (Eg, (when x a b c) is equivalent to (if x (progn a b c)).) - -> (when t - (setq a 5) - (+ a 6) - ) -11 - -More complicated conditionals can be defined using the cond special -form, which is equivalent to an if ... else if ... fi construction. - -A cond consists of the symbol cond followed by a number of cond -clauses, each of which is a list. The first element of a cond clause is -the condition; the remaining elements (if any) are the action. The cond -form finds the first clause whose condition evaluates to true (ie, -doesn't evaluate to nil); it then executes the corresponding action and -returns the resulting value. None of the remaining conditions are -evaluated; nor are any actions except the one corresponding to the -selected condition. For example: - -> (setq a 3) -3 -> (cond - ((evenp a) a) ;if a is even return a - ((> a 7) (/ a 2)) ;else if a is bigger than 7 return a/2 - ((< a 5) (- a 1)) ;else if a is smaller than 5 return a-1 - (t 17) ;else return 17 - ) -2 - -If the action in the selected cond clause is missing, cond returns what -the condition evaluated to: - -> (cond ((+ 3 4))) -7 - -Here's a clever little recursive function which uses cond. You might be -interested in trying to prove that it terminates for all integers x at -least 1. (If you succeed, please publish the result.) - -> (defun hotpo (x steps) ;hotpo stands for Half Or Triple Plus One - (cond - ((= x 1) steps) - ((oddp x) (hotpo (+ 1 (* x 3)) (+ 1 steps))) - (t (hotpo (/ x 2) (+ 1 steps))) - ) ) -A -> (hotpo 7 0) -16 - -The LISP case statement is like a C switch statement: - -> (setq x 'b) -B -> (case x - (a 5) - ((d e) 7) - ((b f) 3) - (otherwise 9) - ) -3 - -The otherwise clause at the end means that if x is not a, b, d, e, or -f, the case statement will return 9. - - - -Iteration - -The simplest iteration construct in LISP is loop: a loop construct -repeatedly executes its body until it hits a return special form. For -example, - -> (setq a 4) -4 -> (loop - (setq a (+ a 1)) - (when (> a 7) (return a)) - ) -8 -> (loop - (setq a (- a 1)) - (when (< a 3) (return)) - ) -NIL - -The next simplest is dolist: dolist binds a variable to the elements of -a list in order and stops when it hits the end of the list. - -> (dolist (x '(a b c)) (print x)) -A -B -C -NIL - -Dolist always returns nil. Note that the value of x in the above -example was never nil: the NIL below the C was the value that dolist -returned, printed by the read-eval-print loop. - -The most complicated iteration primitive is called do. A do statement -looks like this: - -> (do ((x 1 (+ x 1)) - (y 1 (* y 2))) - ((> x 5) y) - (print y) - (print 'working) - ) -1 -WORKING -2 -WORKING -4 -WORKING -8 -WORKING -16 -WORKING -32 - -The first part of a do specifies what variables to bind, what their -initial values are, and how to update them. The second part specifies a -termination condition and a return value. The last part is the body. A -do form binds its variables to their initial values like a let, then -checks the termination condition. As long as the condition is false, it -executes the body repeatedly; when the condition becomes true, it -returns the value of the return-value form. - -The do* form is to do as let* is to let. - - - -Non-local Exits - -The return special form mentioned in the section on iteration is an -example of a nonlocal return. Another example is the return-from form, -which returns a value from the surrounding function: - -> (defun foo (x) - (return-from foo 3) - x - ) -FOO -> (foo 17) -3 - -Actually, the return-from form can return from any named block -- it's -just that functions are the only blocks which are named by default. You -can create a named block with the block special form: - -> (block foo - (return-from foo 7) - 3 - ) -7 - -The return special form can return from any block named nil. Loops are -by default labelled nil, but you can make your own nil-labelled blocks: - -> (block nil - (return 7) - 3 - ) -7 - -Another form which causes a nonlocal exit is the error form: - -> (error "This is an error") -Error: This is an error - -The error form applies format to its arguments, then places you in the -debugger. - - - -Funcall, Apply, and Mapcar - -Earlier I promised to give some functions which take functions as -arguments. Here they are: - -> (funcall #'+ 3 4) -7 -> (apply #'+ 3 4 '(3 4)) -14 -> (mapcar #'not '(t nil t nil t nil)) -(NIL T NIL T NIL T) - -Funcall calls its first argument on its remaining arguments. - -Apply is just like funcall, except that its final argument should be a -list; the elements of that list are treated as if they were additional -arguments to a funcall. - -The first argument to mapcar must be a function of one argument; mapcar -applies this function to each element of a list and collects the -results in another list. - -Funcall and apply are chiefly useful when their first argument is a -variable. For instance, a search engine could take a heuristic function -as a parameter and use funcall or apply to call that function on a -state description. The sorting functions described later use funcall -to call their comparison functions. - -Mapcar, along with nameless functions (see below), can replace many -loops. - - - -Lambda - -If you just want to create a temporary function and don't want to -bother giving it a name, lambda is what you need. - -> #'(lambda (x) (+ x 3)) -(LAMBDA (X) (+ X 3)) -> (funcall * 5) -8 - -The combination of lambda and mapcar can replace many loops. For -example, the following two forms are equivalent: - -> (do ((x '(1 2 3 4 5) (cdr x)) - (y nil)) - ((null x) (reverse y)) - (push (+ (car x) 2) y) - ) -(3 4 5 6 7) -> (mapcar #'(lambda (x) (+ x 2)) '(1 2 3 4 5)) -(3 4 5 6 7) - - - -Sorting - -LISP provides two primitives for sorting: sort and stable-sort. - -> (sort '(2 1 5 4 6) #'<) -(1 2 4 5 6) -> (sort '(2 1 5 4 6) #'>) -(6 5 4 2 1) - -The first argument to sort is a list; the second is a comparison -function. The sort function does not guarantee stability: if there are -two elements a and b such that (and (not (< a b)) (not (< b a))), sort -may arrange them in either order. The stable-sort function is exactly -like sort, except that it guarantees that two equivalent elements -appear in the sorted list in the same order that they appeared in the -original list. - -Be careful: sort is allowed to destroy its argument, so if the original -sequence is important to you, make a copy with the copy-list or copy-seq -function. - - - -Equality - -LISP has many different ideas of equality. Numerical equality is -denoted by =. Two symbols are eq if and only if they are identical. Two -copies of the same list are not eq, but they are equal. - -> (eq 'a 'a) -T -> (eq 'a 'b) -NIL -> (= 3 4) -T -> (eq '(a b c) '(a b c)) -NIL -> (equal '(a b c) '(a b c)) -T -> (eql 'a 'a) -T -> (eql 3 3) -T - -The eql predicate is equivalent to eq for symbols and to = for numbers. - -The equal predicate is equivalent to eql for symbols and numbers. It is -true for two conses if and only if their cars are equal and their cdrs -are equal. It is true for two structures if and only if the structures -are the same type and their corresponding fields are equal. - - - -Some Useful List Functions - -These functions all manipulate lists. - -> (append '(1 2 3) '(4 5 6)) ;concatenate lists -(1 2 3 4 5 6) -> (reverse '(1 2 3)) ;reverse the elements of a list -(3 2 1) -> (member 'a '(b d a c)) ;set membership -- returns the first tail -(A C) ;whose car is the desired element -> (find 'a '(b d a c)) ;another way to do set membership -A -> (find '(a b) '((a d) (a d e) (a b d e) ()) :test #'subsetp) -(A B D E) ;find is more flexible though -> (subsetp '(a b) '(a d e)) ;set containment -NIL -> (intersection '(a b c) '(b)) ;set intersection -(B) -> (union '(a) '(b)) ;set union -(A B) -> (set-difference '(a b) '(a)) ;set difference -(B) - -Subsetp, intersection, union, and set-difference all assume that each -argument contains no duplicate elements -- (subsetp '(a a) '(a b b)) is -allowed to fail, for example. - -Find, subsetp, intersection, union, and set-difference can all take a -:test keyword argument; by default, they all use eql. - - - -Getting Started with Emacs - -You can use Emacs to edit LISP code: most Emacses are set up to enter -LISP mode automatically when they find a file which ends in .lisp, but -if yours isn't, you can type M-x lisp-mode. - -You can run LISP under Emacs, too: make sure that there is a command in -your path called "lisp" which runs your favorite LISP. For example, you -could type - - ln -s /usr/local/bin/ecl ~/bin/lisp - -Then in Emacs type M-x run-lisp. You can send LISP code to the LISP you -just started, and do all sorts of other cool things; for more -information, type C-h m from any buffer which is in LISP mode. - -Actually, you don't even need to make a link. Emacs has a variable -called inferior-lisp-program; so if you add the line - - (setq inferior-lisp-program "/usr/local/bin/ecl") - -to your .emacs file, Emacs will know where to find ECL when -you type M-x run-lisp. - diff --git a/src/doc/user.txi b/src/doc/user.txi deleted file mode 100644 index 689b3d8e7..000000000 --- a/src/doc/user.txi +++ /dev/null @@ -1,3481 +0,0 @@ -\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:: -* Building 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, Building ECL, 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 Building ECL, Invoking ECL, Copyright, Introduction -@section Building 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. -@smallformat -$ zcat ecl.tgz | tar xf - -@end smallformat - -@item An auto configuration mechanism allows you to perform a standard -installation with the following commands: -@smallformat -$ ./configure -@end smallformat -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 -@smallformat -$ ./configure --prefix=$HOME -@end smallformat - -@c FIXME: This information seems wrong! -@c @item Make sure everything went OK with the configuration. -@c The configuration script figures out the machine where it is running and -@c creates a directory @code{machine} where to perform the installation. If the -@c program fails to recognize the machine, you will have to check whether it is -@c one of the supported machines present in @code{src/h/machine.h}. - -@item Next you must build the program and install it -@smallformat -$ make -$ make install -@end smallformat -@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 - -@multitable @columnfractions .5 .5 -@item @b{Executable files:} @tab -@item @file{$HOME/bin/ecl} @tab the @ecl{} interpreter and compiler -@item @b{Help documents:} @tab -@item @file{$HOME/lib/ecl/help.doc} @tab data for the online help -@item @file{$HOME/man/man1/ecl.1} @tab manual page for @ecl{} -@item @file{$HOME/info/ecl.info} @tab this manual you are reading -@item @b{Library files and headers:} @tab -@item @file{$HOME/lib/ecl/libecl.a} @tab the core library in C -@item @file{$HOME/lib/ecl/libgmp.a} @tab GNU library for bignums -@item @file{$HOME/lib/ecl/libgc.a} @tab Boehm-Weiser garbage collector -@item @file{$HOME/lib/ecl/*.a} @tab Other lisp compiled code -@item @file{$HOME/lib/ecl/ecl/} @tab Header files -@end multitable - -You can remove all intermediate files produced during installation with the -command @code{make clean}. - - -@node Invoking ECL, , Building ECL, Introduction -@section Entering and leaving @ecl{} - -@ecl{} is invoked by the command @code{ecl}. - -@smallformat -% 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 -under certain conditions; see file 'Copyright' for details. -Type :h for Help. Top level. -> -@end smallformat - -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{>}'. - -@smallformat -Type :h for Help. Top level. -> -@end smallformat - -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. - -@smallformat -> (in-package 'cl) -#<"COMMON-LISP" package> -COMMON-LISP> (in-package 'system) -#<"SYSTEM" package> -SYSTEM> -@end smallformat - -To exit from @ecl{}, call the function @code{quit}. - -@smallformat ->(quit) -Bye. -% -@end smallformat - -Alternatively, you may type @myctrl{D}, i.e. press the key @key{D} while pressing -down the control key (@key{Ctrl}). - -@smallformat ->@myctrl{D}Bye. -% -@end smallformat - -You can disable @myctrl{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 @myctrl{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. -@smallformat ->(values 1 2) -1 -2 ->(values) - -> -@end smallformat - -When an error is signalled, control will enter the break loop. -@smallformat ->(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 smallformat - -@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} - -@smallformat ->>:q - -Top level. -> -@end smallformat - -@c @vskip 1em - -See Section 5.4 for the details of the break loop. - -The terminal interrupt (usually caused by typing @myctrl{C} (Control-@code{C})) -is a kind of error. It breaks the running program and calls the break level -loop. - -Example: -@smallformat ->(defun foo () (do () (nil))) -foo - ->(foo) -@myctrl{C} -Correctable error: Console interrupt. -Signalled by DO. - -Broken at FOO. ->> -@end smallformat - -@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:: -@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: -@multitable {Format} {precision} {exponent} -@item @b{Format} @tab @b{precision} @tab @b{exponent} -@item Short @tab 24 bits @tab 8 bits -@item Single @tab 24 bits @tab 8 bits -@item Double @tab 53 bits @tab 11 bits -@item Long @tab 32 bits @tab 11 bits -@end multitable - -There is no ``minus zero.'' @code{(eql 0.0 -0.0)} is true. - -@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. -@multitable {Character} {Code (in octal)} -@item @b{Character} @tab @b{Code (in octal)} -@item #@back{}Null @tab 000 -@item #@back{}Space @tab 040 -@item #@back{}Newline @tab 012 -@item #@back{}Backspace @tab 010 -@item #@back{}Tab @tab 011 -@item #@back{}Linefeed @tab 012 -@item #@back{}Page @tab 014 -@item #@back{}Return @tab 015 -@item #@back{}Rubout @tab 177 -@end multitable - -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 - -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{#}, other vectors are printed as @code{#}, and other arrays are printed as @code{#}. The default value for @code{*print-array*} is @nil{}. - -@ecl{} arrays can have up to 64 dimensions. -@clisp{} constants related to arrays have the following values in @ecl{}. -@multitable {array-total-size-limit} {array-dimension-limit} -@item array-rank-limit @tab 64 -@item array-dimension-limit @tab most-positive-fixnum -@item array-total-size-limit @tab array-dimension-limit -@end multitable - -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}. - -@multitable {(array short-float) and (vector short-float)} {64 bit floating point} -@item @b{Array Type} @tab @b{Element Representation} -@item (array t) and (vector t) - @tab a cell pointer -@item (array fixnum) and (vector fixnum) - @tab 32 bit signed integer -@item (array string-char) and string - @tab 8 bit code -@item (array short-float) and (vector short-float) - @tab 32 bit floating point -@item (array long-float) and (vector long-float) - @tab 64 bit floating point -@item (array bit) and bit-vector - @tab 1 bit bit -@end multitable - - -@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{#}. - - -@node Readtables, Packages, Hash tables, Standards -@section Readtables - -All readtables are printed as @code{#}. - - -@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: @code{compiler}, @code{clos} and -@code{xlib}. - -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 -@verbatim - [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 verbatim -@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, -@verbatim - [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 verbatim -@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. - -@verbatim - "foo.lsp" - name: "foo" - type: "lsp" - - "a.b.c" - name: "a.b" - type: "c" -@end verbatim - -If a namestring ends with a period, the filetype becomes the null string. -@verbatim - "foo." - name: "foo" - type: "" (null string) -@end verbatim - -If a namestring begins with a period, the file name becomes @nil{}. -@verbatim - ".lsp" - name: nil - type: "lsp" -@end verbatim - -If a namestring contains no period, the filetype is @nil{}. -@verbatim - "foo" - name: "foo" - type: nil -@end verbatim - -In a pathname, the file directory is represented as a list which -always begins with either @code{:relative} or @code{:absolute} -@verbatim - "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 verbatim - -If a namestring does not contain a directory, the directory component -of the pathname is @nil{}. -@verbatim - "foo.lsp" - directory: nil - name: "foo" - type: "lsp" -@end verbatim - -The abbreviation symbols `@code{.}' and `@code{..}' may be used in a -namestring, but only the second one is translated to a standard -keyword -@verbatim - "./demo/queen.lsp" - directory: (:relative "." "demo") - name: "queen" - type: "lsp" - - "../../demo/queen.lsp" - directory: (:relative @pxlref{:up} :up "demo") - name: "queen" - type: "lsp" -@end verbatim - -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. -@verbatim - "/usr/common/" - directory: (:absolute "usr" "common") - name: nil - type: nil - - "/usr/common/.lsp" - directory: (:absolute "usr" "common") - name: ".lsp" - type: nil -@end verbatim - -`@code{*}' in the place of file name or filetype becomes @code{:wild} -@verbatim - "*.lsp" - name: :wild - type: "lsp" - - "foo.*" - name: "foo" - type: :wild -@end verbatim - - -@node Streams, Random-states, Pathnames, Standards -@section Streams - -Streams are printed in the following formats. -@table @code -@item # -An input stream from the file @var{file-name}. - -@item # -An output stream to the file @var{file-name}. - -@item # -An input stream generated by @code{(make-string-input-stream -@var{string} )}. - -@item # -An output stream generated by the function @code{make-string-output-stream}. - -@item # -A stream generated by the function @code{make-two-way-stream}. - -@item # -A bidirectional stream generated by the function @code{make-echo-stream}. - -@item # -The stream generated by @code{(make-synonym-stream @var{symbol} )}. - -@item # -An input stream generated by the function @code{make-concatenated-stream}. - -@item # -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 -@verbatim - # - # -@end verbatim -@noindent -Compiled functions (including compiled macro-expansion functions) -are printed in the following formats. -@verbatim - # - # -@end verbatim - -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{}. -@verbatim - call-arguments-limit = 64 - lambda-list-keywords = (@optional{} @rest{} @keys{} @allow{} - @aux{} &whole &environment &body) - lambda-parameters-limit = 64 - multiple-values-limit = 32 -@end verbatim - -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, , 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 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 @b{@emph{Implementation Type}} @tab @b{@emph{@clisp{} Data Type}} -@item @code{cons} @tab @code{cons} -@item @code{fixnum} @tab @code{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} -@verbatim - Lower address Higher address - +--------------+-------------------+---------------+ - + HEAP | HOLE | RELOCATABLE | - +--------------+-------------------+---------------+ -@end verbatim - -@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: - -@smallformat ->(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 smallformat - -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. - -@smallformat -> (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 smallformat - - -@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: - -@smallformat -> (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 smallformat - - -@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, - -@smallformat -> (defvar fun (si::make-lambda 'f '((x) (1+ x)))) -*FUN* -> (funcall fun 2) -3 -@end smallformat - -@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: -@smallformat -> (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 smallformat - -@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. - -@smallformat - $ ecl @var{filename} -@end smallformat - -@noindent -has the same effect as the compiler invocation @code{(compile-file -@var{filename})} from within @ecl{}, and - -@smallformat - $ ecl -C @var{filename} -@end smallformat - -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}, -@lisp -(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 lisp -@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 - -@lisp -(the fixnum (foo)) -@end lisp - -@noindent -is equivalent to - -@lisp -(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 lisp - -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, -@smallformat ->(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 smallformat - -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 - -@lisp -(defun foo () - (declare (function bar (character) fixnum)) - (+ (bar (atcholi1)) (bar (atcholi2)))) -@end lisp - -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, - -@smallformat ->(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 smallformat - -However, the compiler does not check the number of arguments, and thus, the -following function definition will be compiled successfully without any -warnings. - -@lisp -(defun foo () - (declare (function bar (character character) fixnum)) - (+ (bar (atcholi1)) (bar (atcholi2) (atcholi3) (atcholi4)))) -@end lisp - -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 - -@smallformat ->(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 smallformat - -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}. -@verbatim - |------------ 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 verbatim - -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{}. - -@lisp -(declare (type fixnum x))) - -(declare (type (mod 3) x)) - -(declare (type (member 0 1) x)) -@end lisp - -Type specifiers in declaration specifications passed to the @ecl{} specific -function @code{proclamation} are also converted to significant type specifiers. -Thus, for example, - -@smallformat ->(proclaim '(function foo (fixnum) fixnum)) -nil ->(proclamation '(function foo ((mod 3)) (member 0 1))) -t ->(proclamation '(function foo (number) character)) -nil -@end smallformat - -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, - -@lisp -(do ((x (foo) (cdr x))) - ((endp x)) - (let ((y (car x))) - (declare (object y)) - (bar y))) -@end lisp - -@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. - -@lisp -(let ((z (cons x y))) - (declare (object z)) - (foo (cons x y)) - (bar z)) -@end lisp - -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. - -@lisp -(let ((x 1)) - (declare (fixnum x)) - ... - (setq x (+ x 2)) - ... - ) -@end lisp - -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. - -@lisp -(setq x (+ (* x 3) 2)) -@end lisp - -In order to obtain the optimal code, a @code{the} special form should -surround the multiplication. - -@lisp -(setq x (+ (the fixnum (* x 3)) 2)) -@end lisp - -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, - -@lisp -(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 lisp - -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. - -@lisp -(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 lisp - -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]] )@}] - @{[@{@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: - -@lisp -(defmacro foo (&whole w x y) ...) -@end lisp -and -@lisp -(defmacro foo (x y) ...) -@end lisp - -@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