Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

[8bd5a0]: standards.xmlf Maximize Restore History

Download this file

standards.xmlf    1495 lines (1333 with data), 60.8 kB

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE book [
<!ENTITY % eclent SYSTEM "ecl.ent">
%eclent;
]>
<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en"><part xml:id="part.standards"><title>Standards</title>
<chapter xml:id="ansi.overview">
 <title>Overview</title>

 <section>
  <title>This manual</title>

  <para>&ECL; supports all Common-Lisp data types exactly as defined in the &ANSI;. All functions and macros are expected to behave as described in that document and in the HyperSpec &HyperSpec; which is the online version of &ANSI;. This part of the book is simply a complement to those official documents and its role is to describes implementation dependent features, such as
  <itemizedlist>
   <listitem><para>Platform dependent limits.</para></listitem>
   <listitem><para>Behavior which is marked as <quote>implementation specific</quote> in the standard.</para></listitem>
   <listitem><para>Some corner cases which are not described in &ANSI;.</para></listitem>
   <listitem><para>The philosophy behind certain implementation choices.</para></listitem>
  </itemizedlist>
  </para>

  <para>In addition to this, the document provides a reference for C programmers that want to create, manipulate and operate with Common Lisp objects. This material is contained in each of the "C Reference" sections below. Note that much of what is presented in those sections is redundant with the Common Lisp specification. In particular, there is a one-to-one mapping between types and functions which should be obvious given the rules explained in <xref linkend="ansi.overview.c-dict"/>.</para>

  <para>The following sections are organized following the structure in the online version of the standard &HyperSpec;: each chapter complements the one with the same name in the standard.</para>
 </section>

 <section xml:id="ansi.overview.c-dict">
  <title>C Reference</title>

  <section xml:id="cl_object">
   <title>One type for everything: <type>cl_object</type></title>

   <para>&ECL; is designed around the basic principle that Common Lisp already provides everything that a programmer could need, orienting itself around the creation and manipulation of Common Lisp objects: conses, arrays, strings, characters, ... When embedding &ECL; there should be no need to use other C/C++ types, except when interfacing data to and from those other languages.</para>

   <para>All Common Lisp objects are represented internally through the same C type, <type>cl_object</type>, which is either a pointer to a union type or an integer, depending on the situation. While the inner guts of this type are exposed through various headers, the user should never rely on these details but rather use the macros and functions that are listed in this manual</para>

   <para>There are two types of Common Lisp objects: immediate and memory allocated ones. Immediate types fit in the bits of the <type>cl_object</type> word, and do not require the garbage collector to be created. The list of such types may depend on the platform, but it includes at least the <type>fixnum</type> and <type>character</type> types.</para>

   <para>Memory allocated types on the other hand require the use of the garbage collector to be created. &ECL; abstracts this from the user providing enough constructors, either in the form of Common Lisp functions (<function>cl_make_array()</function>, <function>cl_complex()</function>,...), or in the form of C/C++ constructors (<function>ecl_make_symbol()</function>, etc).</para>

   <para>Memory allocated types must always be kept alive so that the garbage collector does not reclaim them. This involves referencing the object from one of the places that the collector scans:
   <itemizedlist>
    <listitem><para>The fields of an object (array, structure, etc) whic is itself alive.</para></listitem>
    <listitem><para>A special variable or a constant.</para></listitem>
    <listitem><para>The C stack (i.e. automatic variables in a function).</para></listitem>
    <listitem><para>Global variables or pointers that have been registered with the garbage collector.</para></listitem>
   </itemizedlist>
   Further details will be provided in the section on <link linkend="ext.memory">Memory Management</link>.</para>
  </section>

  <section>
   <title>Naming conventions</title>

   <para>As explained in the introduction, each of the chapters in the Common Lisp standard can also be implemented using C functions and types. The mapping between both languages is done using a small set of rules described below.</para>
   <itemizedlist>
    <listitem><para>Functions in the Common Lisp ("CL") package are prefixed with the characters "cl_", functions in the System ("SI") package are prefix with "si_", etc, etc.</para></listitem>
    <listitem><para>If a function takes only a fixed number of arguments, it is mapped to a C function with also a fixed number of arguments. For instance, <symbol>COS</symbol> maps to <code>cl_object cl_cos(cl_object)</code>, which takes a single Lisp object and returns a Lisp object of type <type>FLOAT</type>.</para></listitem>
    <listitem><para>If the function takes a variable number of arguments, its signature consists on an integer with the number of arguments and zero or more of required arguments and then a C vararg. This is the case of <code>cl_object cl_list(cl_narg narg, ...)</code>, which can be invoked without arguments, as in <code>cl_list(0)</code>, with one, <code>cl_list(1, a)</code>, etc.</para></listitem>
    <listitem><para>Functions return at least one value, which is either the first value output by the function, or <symbol>NIL</symbol>. The extra values may be retrieved immediately after the function call using the function <link linkend="ecl_nth_value"><function>ecl_nth_value</function></link>.</para></listitem>
   </itemizedlist>
   <para>In addition to the Common Lisp core functions (cl_*), there exist functions which are devoted only to C/C++ programming, with tasks such as coercion of objects to and from C types, optimized functions, inlined macroexpansions, etc. These functions and macros typically carry the prefix "ecl_" or "ECL_" and only return one value, if any.</para>
  </section>

  <section xml:id="ansi.OCL">
   <title>Only in Common Lisp</title>

   <para>Some parts of the language are not available as C functions, even though they can be used in Common Lisp programs. These parts are either marked in the "ANSI Dictionary" sections using the tag &OCL;, or they are simply not mentioned (macros and special constructs). This typically happens with non-translatable constructs such as</para>
   <itemizedlist>
    <listitem><para>Common Lisp macros such as <symbol>with-open-files</symbol>.</para></listitem>
    <listitem><para>Common Lisp special forms, such as <symbol>cond</symbol></para></listitem>
    <listitem><para>Common Lisp generic functions, which cannot be written in C because of their dynamical dispatch and automatic redefinition properties.</para></listitem>
   </itemizedlist>

   <para>In most of those cases there exist straightforward alternatives using the constructs and functions in &ECL;. For example, <symbol>unwind-protect</symbol> can be implemented using a C macro which is provided by &ECL;</para>
<programlisting>
cl_env_ptr env = ecl_process_env();
CL_UNWIND_PROTECT_BEGIN(env) {
    /* protected code goes here */
} CL_UNWIND_PROTECT_EXIT {
    /* exit code goes here */
} CL_UNWIND_PROTECT_END;
</programlisting>

   <para>Common Lisp generic functions can be directly accessed using <symbol>funcall</symbol> or <symbol>apply</symbol> and the function name, as shown in the code below</para>
<programlisting>
cl_object name = ecl_make_symbol("MY-GENERIC-FUNCTION","CL-USER");
cl_object output = cl_funcall(2, name, argument);
</programlisting>

   <para>Identifying these alternatives requires some knowledge of Common Lisp, which is why it is recommended to approach the embeddable components in &ECL; only when there is some familiarity with the language.</para>
  </section>
 </section>
</chapter>

<chapter xml:id="ansi.evaluation-and-compilation">
 <title>Evaluation and compilation</title>

 <section xml:id="ansi.declarations">
  <title>Declarations</title>

  <section xml:id="ansi.declarations.optimize">
   <title><function>OPTIMIZE</function></title>

   <para>The <function>OPTIMIZE</function> declaration includes three concepts:
   <function>DEBUG</function>, <function>SPEED</function>,
   <function>SAFETY</function> and <function>SPACE</function>. Each of these
   declarations can take one of the integer values 0, 1, 2 and 3. According to
   these values, the implementation may decide how to compie or interpret a
   given lisp form.</para>

   <para>&ECL; currently does not use all these declarations, but some of them
   definitely affect the speed and behavior of compiled functions. For
   instance, the <function>DEBUG</function> declaration, as shown in <xref
   linkend="table.optimize.debug"/>, if the value of debugging is zero, the
   function will not appear in the debugger and, if redefined, some functions
   might not see the redefinition.</para>

   <table xml:id="table.optimize.debug">
    <title>Behavior for different levels of DEBUG</title>
    <tgroup cols="5">
     <thead>
      <row>
       <entry>Behavior</entry>
       <entry>0</entry>
       <entry>1</entry>
       <entry>2</entry>
       <entry>3</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>Compiled functions in the same source file are called
       directly</entry>
       <entry>Y</entry>
       <entry>Y</entry>
       <entry>N</entry>
       <entry>N</entry>
      </row>
      <row>
       <entry>Compiled function appears in debugger backtrace</entry>
       <entry>N</entry>
       <entry>N</entry>
       <entry>Y</entry>
       <entry>Y</entry>
      </row>
      <row>
       <entry>All functions get a global entry, that is, SI:C-LOCAL is
       ignored.</entry>
       <entry>N</entry>
       <entry>N</entry>
       <entry>Y</entry>
       <entry>Y</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

   <para>A bit more critical is the value of <function>SAFETY</function>
   because as shown in Table <xref linkend="table.optimize.safety"/>, it may
   affect the safety checks generated by the compiler. In particular, in some
   circumstances the compiler may assume that the arguments to a function are
   properly typed. For instance, if you compile with a low value of
   <function>SAFETY</function>, and invoke <function>RPLACA</function>, the
   consequences are unspecified.</para>

   <table xml:id="table.optimize.safety">
    <title>Behavior for different levels of SAFETY</title>
    <tgroup cols="5">
     <thead>
      <row>
       <entry>Behavior</entry>
       <entry>0</entry>
       <entry>1</entry>
       <entry>2</entry>
       <entry>3</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>The compiler generates type checks for the arguments of a lambda
       form, thus enforcing any type declaration written by the user.</entry>
       <entry>N</entry>
       <entry>Y</entry>
       <entry>Y</entry>
       <entry>Y</entry>
      </row>
      <row>
       <entry>The value of an expression or a variable declared by the user is
       assumed to be right.</entry>
       <entry>Y</entry>
       <entry>Y</entry>
       <entry>N</entry>
       <entry>N</entry>
      </row>
      <row>
       <entry>We believe type declarations and type inference and, if the type
       of a form is inferred to be right for a function, slot accessor, etc,
       this may be inlined. Affects functions like CAR, CDR, etc</entry>
       <entry>Y</entry>
       <entry>Y</entry>
       <entry>N</entry>
       <entry>N</entry>
      </row>
      <row>
       <entry>We believe types defined before compiling a file not change
       before the compiled code is loaded.</entry>
       <entry>Y</entry>
       <entry>Y</entry>
       <entry>N</entry>
       <entry>N</entry>
      </row>
      <row>
       <entry>Arguments in a lisp form are assumed to have the appropriate types
       so that the form will not fail.</entry>
       <entry>Y</entry>
       <entry>N</entry>
       <entry>N</entry>
       <entry>N</entry>
      </row>
      <row>
       <entry>The slots or fields in a lisp object are accessed directly
       without type checks even if the type of the object could not be inferred
       (see line above). Affects functions like PATHNAME-TYPE, CAR, REST,
       etc.</entry>
       <entry>Y</entry>
       <entry>N</entry>
       <entry>N</entry>
       <entry>N</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  </section>
 </section>

 <xi:include href="ref_c_evaluation.xml" xpointer="ansi.evaluation.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.types-and-classes">
 <title>Types and classes</title>

 <xi:include href="ref_c_types_and_classes.xml" xpointer="ansi.types-and-classes.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.data-and-control">
 <title>Data and control flow</title>

 <section xml:id="ansi.minimal-compilation">
  <title>Minimal compilation</title>

  <para>Former versions of &ECL;, as well as many other lisps, used linked
  lists to represent code. Executing code thus meant traversing these lists
  and performing code transformations, such as macro expansion, every time
  that a statement was to be executed. The result was a slow and memory
  hungry interpreter.</para>

  <para>Beginning with version 0.3, &ECL; was shipped with a bytecodes
  compiler and interpreter which 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
  <emphasis>bytecodes</emphasis>.</para>

  <para>The bytecodes compiler is implemented in
  <filename>src/c/compiler.d</filename>. The main entry point is the lisp
  function <function>si::make-lambda</function>, 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,
  <screen>&gt; (defvar fun (si::make-lambda 'f '((x) (1+ x))))
*FUN*
&gt; (funcall fun 2)
3</screen></para>

  <para>&ECL; can only execute bytecodes. When a list is passed to
  <literal>EVAL</literal> it must be first compiled to bytecodes and, if the
  process succeeds, the resulting bytecodes are passed to the
  interpreter. Similarly, every time a function object is created, such as in
  <function>DEFUN</function> or <function>DEFMACRO</function>, the compiler
  processes the lambda form to produce a suitable bytecodes object.</para>

  <para>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:</para>
  <screen>&gt; (defmacro f (a b) `(+ ,a ,b))
F
&gt; (defun g (x y) (f x y))
G
&gt; (g 1 2)
3
&gt; (defmacro f (a b) `(- ,a ,b))
F
&gt; (g 1 2)
3</screen>

  <para>The last statement always outputs <literal>3</literal> while in former
  implementations based on simple list traversal it would produce
  <literal>-1</literal>.</para>
 </section>

 <section xml:id="ansi.functions">
  <title>Functions</title>

  <para>Functions in &ECL; can be of two types: they are either compiled to
  bytecodes or they have been compiled to machine code using a lisp to C
  translator and a C compiler. To the first category belong function loaded
  from lisp source files or entered at the toplevel. To the second category
  belong all functions in the &ECL; core environment and functions in files
  processed by <function>compile</function> or
  <function>compile-file</function>.</para>

  <para>The output of <code>(symbol-function
  <replaceable>fun</replaceable>)</code> is a list, is either a function
  object if <literal>'fun</literal> is has a function definition,
  <literal>(macro . function-object)</literal> if <literal>'fun</literal> is
  a macro, and <literal>'special</literal> if <literal>'fun</literal> is a
  special form.</para>

  <para>&ECL; usually drops the source code of a function unless the global
  variable <varname>si:*keep-definitions*</varname> was true when the
  function was translated into bytecodes. Therefore, if you wish to use
  <function>compile</function> and <function>disassemble</function> on
  defined functions, you should issue <code>(setq si:*keep-definitions*
  t)</code> at the beginning of your session.</para>

  <para>In <xref linkend="table.function.constants"/> we list all
  &CommonLisp; values related to the limits of functions.</para>

  <table xml:id="table.function.constants">
   <title>Function related constants</title>
   <tgroup cols="2">
    <tbody>
     <row>
      <entry><constant>call-arguments-limit</constant></entry>
      <entry>65536</entry>
     </row>
     <row>
      <entry><constant>lambda-parameters-limit</constant></entry>
      <entry>call-arguments-limit</entry>
     </row>
     <row>
      <entry><constant>multiple-values-limit</constant></entry>
      <entry>64</entry>
     </row>
     <row>
      <entry><constant>lambda-list-keywords</constant></entry>
      <entry><literal>(&optional; &rest; &key; &allow-other-keys; &aux;
      &whole; &environment; &body;)</literal></entry>
     </row>
    </tbody>
   </tgroup>
  </table>
 </section>

 <xi:include href="ref_c_data_flow.xml" xpointer="ansi.data-and-control.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.conditions">
 <title>Conditions</title>

 <xi:include href="ref_c_conditions.xml" xpointer="ansi.conditions.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.structures">
 <title>Structures</title>

 <xi:include href="ref_c_structures.xml" xpointer="ansi.structures.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.objects">
 <title>Objects</title>

 <xi:include href="ref_c_objects.xml" xpointer="ansi.objects.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.symbols">
 <title>Symbols</title>
 <para>There are no implementation-specific limits on the size or content of
 symbol names. It is however not allowed to write on the strings which have
 been passed to #'make-symbol or returned from #'symbol-name.</para>

 <xi:include href="ref_c_symbols.xml" xpointer="ansi.symbols.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.packages">
 <title>Packages</title>

 <table xml:id="table.all-packages">
  <title>ECL packages</title>
  <tgroup cols="3">
   <thead>
    <row>
     <entry>Name</entry>
     <entry>Nickname</entry>
     <entry>In module</entry>
     <entry>Description</entry>
    </row>
   </thead>
   <tbody>
    <row>
     <entry><package>COMMON-LISP</package></entry>
     <entry><package>CL</package>, <package>LISP</package></entry>
     <entry>&ECL; core</entry>
     <entry>Main &CommonLisp; package.</entry>
    </row>
    <row>
     <entry><package>CLOS</package></entry>
     <entry><package>MOP</package></entry>
     <entry>&ECL; core</entry>
     <entry>Symbols from the &AMOP;.</entry>
    </row>
    <row>
     <entry><package>EXT</package></entry>
     <entry></entry>
     <entry>&ECL; core</entry>
     <entry>&ECL; extensions to the language &amp; library.</entry>
    </row>
    <row>
     <entry><package>SYSTEM</package></entry>
     <entry><package>SI</package>, <package>SYS</package></entry>
     <entry>&ECL; core</entry>
     <entry>Functions and variables internal to the implementation. Never to be used.</entry>
    </row>
    <row>
     <entry><package>CMP</package></entry>
     <entry><package>C</package></entry>
     <entry><package>CMP</package></entry>
     <entry>The compiler</entry>
    </row>
    <row>
     <entry><package>XLIB</package></entry>
     <entry><package>CLX</package></entry>
     <entry><package>XLIB</package></entry>
     <entry>CLX library for X-Windows</entry>
    </row>
    <row>
     <entry><package>SB-BSD-SOCKETS</package></entry>
     <entry></entry>
     <entry><package>SOCKETS</package></entry>
     <entry>Sockets library compatible with <acronym>SBCL</acronym>'s</entry>
    </row>
    <row>
     <entry><package>SB-RT</package></entry>
     <entry><package>RT</package>, <package>REGRESSION-TEST</package></entry>
     <entry><package>RT</package></entry>
     <entry>Test units (customized for &ECL;)</entry>
    </row>
    <row>
     <entry><package>ASDF</package></entry>
     <entry></entry>
     <entry><package>ASDF</package></entry>
     <entry>System definition file with &ECL; customizations.</entry>
    </row>
   </tbody>
  </tgroup>
 </table>

 <para>In <xref linkend="table.all-packages"/> we list all packages
 available in &ECL;. The nicknames are aliases for a package. Thus,
 <symbol>system:symbol</symbol> may be written as
 <symbol>sys:symbol</symbol> or <symbol>si:symbol</symbol>. The module field
 explains which library provides what package. For instance, the
 <package>ASDF</package> is obtained when loading the
 <package>ASDF</package> library with <code>(require 'asdf)</code>; and the
 <package>XLIB</package> package when configuring and loading the
 <package>CLX</package> library.</para>

 <xi:include href="ref_c_packages.xml" xpointer="ansi.packages.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.numbers">
 <title>Numbers</title>

 <section xml:id="ansi.number-types">
  <title>Numeric types</title>

  <para>&ECL; supports all of the &CommonLisp; numeric tower, which is shown
  in <xref linkend="table.ansi.numbers"/>. The details, however, depend both
  on the platform on which &ECL; runs and on the configuration which was
  chosen when building &ECL;.</para>
  <table xml:id="table.ansi.numbers">
   <title>Numeric types in &ECL;</title>
   <tgroup cols="2">
    <thead>
     <row><entry>Type</entry><entry>Description</entry></row>
    </thead>
    <tbody>
     <row>
      <entry><type>fixnum</type></entry>
      <entry>Signed integer with a number of bits given by
      <varname>ext:fixnum-bits</varname>, fit in a machine word.</entry>
     </row>
     <row>
      <entry><type>bignum</type></entry>
      <entry>Arbitrary size integers, only limited by amount of memory.</entry>
     </row>
     <row>
      <entry><type>ratio</type></entry>
      <entry>Arbitrary size rational number, made up of two integers.</entry>
     </row>
     <row>
      <entry><type>short-float</type></entry>
      <entry>Equivalent to <type>single-float</type>.</entry>
     </row>
     <row>
      <entry><type>single-float</type></entry>
      <entry>32-bits IEEE floating point number.</entry>
     </row>
     <row>
      <entry><type>double-float</type></entry>
      <entry>64-bits IEEE floating point number.</entry>
     </row>
     <row>
      <entry><type>long-float</type></entry>
      <entry>Either equivalent to <type>double-float</type>, or a 96/128 bits IEEE floating
      point number (<type>long double</type> in C/C++).</entry>
     </row>
     <row>
      <entry><type>rational</type></entry>
      <entry>An alias for <type>(or integer ratio)</type></entry>
     </row>
     <row>
      <entry><type>float</type></entry>
      <entry>An alias for <type>(or single-float double-float short-float
      long-float)</type></entry>
     </row>
     <row>
      <entry><type>real</type></entry>
      <entry>An alias for <type>(or real integer float)</type></entry>
     </row>
     <row>
      <entry><type>complex</type></entry>
      <entry>Complex number made of two real numbers of the above mentioned
      types.</entry>
     </row>
    </tbody>
   </tgroup>
  </table>

  <para>In general, the size of a <type>FIXNUM</type> is determined by the
  word size of a machine, which ranges from 32 to 64 bits. Integers larger
  than this are implemented using the <ulink
  url="http://www.swox.com/gmp/">GNU Multiprecision library</ulink>. Rationals
  are implemented using two integers, without caring whether they are fixnum
  or not. Floating point numbers include at least the two IEEE types of 32 and
  64 bits respectively. In machines where it is supported, it is possible to
  associate the lisp <type>LONG-FLOAT</type> with the machine type <type>long
  double</type> whose size ranges from 96 to 128 bits, and which are a bit
  slower.</para>
 </section>

 <section xml:id="ansi.random-states">
  <title>Random-States</title>

  <para>&ECL; relies internally on a 32-bit or 64-bit Mersenne-Twister random number generator, using a relatively large buffer to precompute about 5000 pseud-random bytes. This implies also that random states can be printed readably and also read, using the <literal>#$</literal> macro. There is no provision to create random states from user arrays, though.</para>
 </section>

 <xi:include href="ref_c_numbers.xml" xpointer="ansi.numbers.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.characters">
 <title>Characters</title>
 <para>&ECL; is fully ANSI Common-Lisp compliant in all aspects of the character
 data type, with the following peculiarities.</para>

 <section xml:id="ansi.character-types">
  <title>Character types</title>

  <para>If compiled without Unicode support, &ECL; all characters are
  implemented using 8-bit codes and the type <type>extended-char</type>
  is empty. If compiled with Unicode support, characters are implemented
  using 24 bits and the <type>extended-char</type> type covers characters above
  code 255.</para>
  <informaltable>
   <tgroup cols="3">
    <thead>
     <row>
      <entry>Type</entry>
      <entry>With Unicode</entry>
      <entry>Without Unicode</entry>
     </row>
    </thead>
    <tbody>
     <row>
      <entry><type>standard-char</type></entry>
      <entry>#\Newline,32-126</entry>
      <entry>#\Newline,32-126</entry>
     </row>
     <row>
      <entry><type>base-char</type></entry>
      <entry>0-255</entry>
      <entry>0-255</entry>
     </row>
     <row>
      <entry><type>extended-char</type></entry>
      <entry>-</entry>
      <entry>255-16777215</entry>
     </row>
    </tbody>
   </tgroup>
  </informaltable>
 </section>

 <section xml:id="ansi.character-names">
  <title>Character names</title>

  <para>All characters have a name. For non-printing characters between 0 and 32, and for 127 we use the ordinary <acronym>ASCII</acronym> names. Characters above 127 are printed and read using hexadecimal Unicode notation, with a <literal>U</literal> followed by 24 bit hexadecimal number, as in <literal>U0126</literal>.</para>
  <table xml:id="table.character-names">
   <title>Examples of character names</title>
   <tgroup cols="2">
    <thead>
     <row>
      <entry>Character</entry>
      <entry>Code</entry>
     </row>
    </thead>
    <tbody>
     <row><entry><literal>#\Null</literal></entry><entry>0</entry></row>
     <row><entry><literal>#\Ack</literal></entry><entry>1</entry></row>
     <row><entry><literal>#\Bell</literal></entry><entry>7</entry></row>
     <row><entry><literal>#\Backspace</literal></entry><entry>8</entry></row>
     <row><entry><literal>#\Tab</literal></entry><entry>9</entry></row>
     <row><entry><literal>#\Newline</literal></entry><entry>10</entry></row>
     <row><entry><literal>#\Linefeed</literal></entry><entry>10</entry></row>
     <row><entry><literal>#\Page</literal></entry><entry>12</entry></row>
     <row><entry><literal>#\Esc</literal></entry><entry>27</entry></row>
     <row><entry><literal>#\Escape</literal></entry><entry>27</entry></row>
     <row><entry><literal>#\Space</literal></entry><entry>32</entry></row>
     <row><entry><literal>#\Rubout</literal></entry><entry>127</entry></row>
     <row><entry><literal>#\U0080</literal></entry><entry>128</entry></row>
    </tbody>
   </tgroup>
  </table>
  <para>Note that <literal>#\Linefeed</literal> is synonymous with
  <literal>#\Newline</literal> and thus is a member of
  <type>standard-char</type>.</para>
 </section>

 <section>
  <title>Line Divisions</title>

  <para>Internally, &ECL; represents the <literal>#\Newline</literal> character by a single code. However, when using external formats, &ECL; may parse character pairs as a single <literal>#\Newline</literal>, and viceversa, use multiple characters to represent a single <literal>#\Newline</literal>.</para>
 </section>

 <xi:include href="ref_c_characters.xml" xpointer="ansi.characters.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
</chapter>

<chapter xml:id="ansi.conses">
 <title>Conses</title>

 <xi:include href="ref_c_conses.xml" xpointer="ansi.conses.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
</chapter>

<chapter xml:id="ansi.arrays">
 <title>Arrays</title>
 <section xml:id="ansi.array-limits">
  <title>Array limits</title>

  <para>&ECL; arrays can have up to 64 dimensions.  Common-Lisp constants
  related to arrays have the following values in &ECL;.</para>
  <informaltable>
   <tgroup cols="2">
    <thead>
     <row>
      <entry>Constant</entry>
      <entry>Value</entry>
     </row>
    </thead>
    <tbody>
     <row>
      <entry>array-rank-limit</entry>
      <entry>64</entry>
     </row>
     <row>
      <entry>array-dimension-limit</entry>
      <entry>most-positive-fixnum</entry>
     </row>
     <row>
      <entry>array-total-size-limit</entry>
      <entry>array-dimension-limit</entry>
     </row>
    </tbody>
   </tgroup>
  </informaltable>
 </section>

 <section xml:id="ansi.array-spec">
  <title>Specializations</title>

  <para>&ECL; provides specialized array types for several element kinds. In the following table we list those types, together with the machine type which is used to implement them, and the expected size.</para>
  <informaltable>
   <tgroup cols="3">
    <thead>
     <row>
      <entry>Specialized type</entry>
      <entry>Element C type</entry>
      <entry>Size</entry>
     </row>
    </thead>
    <tbody>
     <row>
      <entry><type>bit</type></entry>
      <entry>-</entry>
      <entry>1 bit</entry>
     </row>
     <row>
      <entry><type>character</type></entry>
      <entry><type>unsigned char</type> or <type>uint32_t</type></entry>
      <entry>Depends on character range</entry>
     </row>
     <row>
      <entry><type>base-char</type></entry>
      <entry><type>unsigned char</type></entry>
      <entry></entry>
     </row>
     <row>
      <entry><type>fixnum</type></entry>
      <entry><type>cl_fixnum</type></entry>
      <entry>Machine word (32 or 64 bits)</entry>
     </row>
     <row>
      <entry><type>(signed-byte 8)</type></entry>
      <entry><type>int8_t</type></entry>
      <entry>8 bits</entry>
     </row>
     <row>
      <entry><type>(unsigned-byte 8)</type></entry>
      <entry><type>uint8_t</type></entry>
      <entry>8 bits</entry>
     </row>
     <row>
      <entry><type>(signed-byte 16)</type></entry>
      <entry><type>int16_t</type></entry>
      <entry>16 bits</entry>
     </row>
     <row>
      <entry><type>(unsigned-byte 16)</type></entry>
      <entry><type>uint16_t</type></entry>
      <entry>16 bits</entry>
     </row>
     <row>
      <entry><type>(signed-byte 32)</type></entry>
      <entry><type>int32_t</type></entry>
      <entry>32 bits</entry>
     </row>
     <row>
      <entry><type>(unsigned-byte 32)</type></entry>
      <entry><type>uint32_t</type></entry>
      <entry>32 bits</entry>
     </row>
     <row>
      <entry><type>(signed-byte 64)</type></entry>
      <entry><type>int64_t</type></entry>
      <entry>64 bits</entry>
     </row>
     <row>
      <entry><type>(unsigned-byte 64)</type></entry>
      <entry><type>uint64_t</type></entry>
      <entry>64 bits</entry>
     </row>
     <row>
      <entry><type>single-float</type> or <type>short-float</type></entry>
      <entry><type>float</type></entry>
      <entry>32-bits IEEE float</entry>
     </row>
     <row>
      <entry><type>double-float</type></entry>
      <entry><type>double</type></entry>
      <entry>64-bits IEEE float</entry>
     </row>
     <row>
      <entry><type>long-float</type></entry>
      <entry><type>long double</type></entry>
      <entry>Between 96 and 128 bits.</entry>
     </row>
     <row>
      <entry><type>t</type></entry>
      <entry><type>cl_object</type></entry>
      <entry>Size of a pointer.</entry>
     </row>
    </tbody>
   </tgroup>
  </informaltable>

  <para>Some of these specialized types might not exist in your platform. This is detected using conditional reading and features (See <xref linkend="ansi.numbers.c-types"/>).</para>
 </section>

 <xi:include href="ref_c_arrays.xml" xpointer="ansi.arrays.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.strings">
 <title>Strings</title>

 <para>The &ECL; implementation of strings is ANSI Common-Lisp
 compliant. There are basically four string types as shown in <xref
 linkend="table.ansi.strings"/>. If Unicode support is
 disabled, <type>character</type> and <type>base-character</type> are the
 same type and the last two string types are equivalent to the first
 two.</para>
 <table xml:id="table.ansi.strings">
  <title>&CommonLisp; string types</title>
  <tgroup cols="2">
   <thead>
    <row>
     <entry>Abbreviation</entry>
     <entry>Expanded type</entry>
     <entry>Remarks</entry>
    </row>
   </thead>
   <tbody>
    <row>
     <entry><type>string</type></entry>
     <entry><type>(array character (*))</type></entry>
     <entry>8 or 32 bits per character, adjustable.</entry>
    </row>
    <row>
     <entry><type>simple-string</type></entry>
     <entry><type>(simple-array character (*))</type></entry>
     <entry>8 or 32 bits per character, not adjustable nor displaced.</entry>
    </row>
    <row>
     <entry><type>base-string</type></entry>
     <entry><type>(array base-char (*))</type></entry>
     <entry>8 bits per character, adjustable.</entry>
    </row>
    <row>
     <entry><type>simple-base-string</type></entry>
     <entry><type>(simple-array base-char (*))</type></entry>
     <entry>8 bits per character, not adjustable nor displaced.</entry>
    </row>
   </tbody>
  </tgroup>
 </table>

 <para>It is important to remember that strings with unicode characters can only be printed readably when the external format supports those characters. If this is not the case, &ECL; will signal a <type>serious-condition</type>, aborting your program.</para>

 <xi:include href="ref_c_strings.xml" xpointer="ansi.strings.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.sequences">
 <title>Sequences</title>

 <xi:include href="ref_c_sequences.xml" xpointer="ansi.sequences.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
</chapter>

<chapter xml:id="ansi.hash-tables">
 <title>Hash tables</title>

 <para>...</para>

 <xi:include href="ref_c_hash_tables.xml" xpointer="ansi.hash-tables.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.filenames">
 <title>Filenames</title>

 <section xml:id="ansi.filenames.syntax">
  <title>Syntax</title>
  <para>A pathname in the file system of Common-Lisp consists of six
  elements: host, device, directory, name, type and version. Pathnames are
  read and printed using the <literal>#P</literal> reader macro followed by
  the namestring. A namestring is a string which represents a pathname. The
  syntax of namestrings for logical pathnames is well explained in the &ANSI;
  and it can be roughly summarized as follows:

  <synopsis><literal><optional><replaceable>hostname</replaceable>:</optional><optional>;</optional><optional><replaceable>directory-item</replaceable>;</optional><superscript>0 or more</superscript><optional><replaceable>name</replaceable></optional><optional>.<replaceable>type</replaceable><optional>.<replaceable>version</replaceable></optional></optional></literal>
  <replaceable>hostname</replaceable> = <replaceable>word</replaceable>
  <replaceable>directory-item</replaceable> = <replaceable>wildcard-word</replaceable>
  <replaceable>type</replaceable>, <replaceable>name</replaceable> = <replaceable>wildcard-word</replaceable> without dots</synopsis>

  Here, <replaceable>wildcard-word</replaceable> is a sequence of any
  character excluding <literal>#\Null</literal> and
  dots. <replaceable>word</replaceable> is like a
  <replaceable>wildcard-word</replaceable> but asterisks are excluded.</para>

  <para>The way &ECL; parses a namestring is by first looking for the
  <replaceable>hostname</replaceable> component in the previous template. If
  it is found and it corresponds to a previously defined logical hostname, it
  assumes that the namestring corresponds to a logical pathname. If
  <replaceable>hostname</replaceable> is not found or it is not a logical
  hostname, then &ECL; tries the physical pathname syntax

  <synopsis><literal><optional><replaceable>device</replaceable>:</optional><optional><optional>//<replaceable>hostname</replaceable></optional>/</optional><optional><replaceable>directory-item</replaceable>/</optional><superscript>0 or more</superscript><optional><replaceable>name</replaceable></optional><optional>.<replaceable>type</replaceable></optional></literal>
  <replaceable>device</replaceable>, <replaceable>hostname</replaceable> = <replaceable>word</replaceable>
  <replaceable>directory-item</replaceable> = <replaceable>wildcard-word</replaceable>
  <replaceable>type</replaceable> = <replaceable>wildcard-word</replaceable> without dots
  <replaceable>name</replaceable> = <optional>.</optional><replaceable>wildcard-word</replaceable></synopsis>

  If this syntax also fails, then the namestring is not a valid pathname
  string and a <type>parse-error</type> will be signalled.</para>

  <para>It is important to remark that in &ECL;, all physical namestrings
  result into pathnames with a version equal to
  <literal>:NEWEST</literal>. Pathnames which are not logical and have any
  other version (i. e. <literal>NIL</literal> or a number), cannot be printed
  readably, but can produce a valid namestring which results of ignoring the
  version.</para>

  <para>Finally, an important rule applies to physical namestrings: if a
  namestring contains one or more periods `.', the last period separates the
  namestring into the file name and the filetype. However, a namestring with a
  single leading period results in a name with a period in it. This is for
  compatibility with Unix filenames such as <filename>.bashrc</filename>, where
  the leading period indicates that the file is hidden.</para>

  <para>The previous rule has in important consequence, because it means that
  if you want to create a pathname without a name, you have to do it
  explicitely. In other words, <literal>".*"</literal> is equivalent to
  <code>(MAKE-PATHNAME :NAME ".*" :TYPE NIL)</code>, while <code>(MAKE-PATHNAME
  :NAME NIL :TYPE :WILD)</code> creates a pathname whose type is a
  wildcard.</para>

  <para>The following table illustrates how the physical pathnames work with
  practical examples.</para>
  <table>
   <title>Examples of physical namestrings</title>
   <tgroup cols="3">
    <thead>
     <row><entry>Namestring</entry>
     <entry>Name</entry>
     <entry>Type</entry>
     <entry>Directory</entry>
     <entry>Device</entry>
     </row>
    </thead>
    <tbody>
     <row>
      <entry>"foo.lsp"</entry>
      <entry>"foo"</entry>
      <entry>"lsp"</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
     </row>
     <row>
      <entry>".bashrc"</entry>
      <entry>".bashrc"</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
     </row>
     <row>
      <entry>".ecl.lsp"</entry>
      <entry>".ecl"</entry>
      <entry>"lsp"</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
     </row>
     <row>
      <entry>"foo.*"</entry>
      <entry>"foo"</entry>
      <entry>:WILD</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
     </row>
     <row>
      <entry>"*.*"</entry>
      <entry>:WILD</entry>
      <entry>:WILD</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
     </row>
     <row>
      <entry>"ecl/build/bare.lsp"</entry>
      <entry>"bare"</entry>
      <entry>"lsp"</entry>
      <entry>(:relative "ecl" "build")</entry>
      <entry>NIL</entry>
     </row>
     <row>
      <entry>"ecl/build/"</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
      <entry>(:relative "ecl" "build")</entry>
      <entry>NIL</entry>
     </row>
     <row>
      <entry>"../../ecl/build/"</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
      <entry>(:relative :up :up "ecl" "build")</entry>
      <entry>NIL</entry>
     </row>
     <row>
      <entry>"/etc/"</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
      <entry>(:absolute "etc")</entry>
      <entry>NIL</entry>
     </row>
     <row>
      <entry>"C:/etc/"</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
      <entry>(:absolute "etc")</entry>
      <entry>"C"</entry>
     </row>
     <row>
      <entry>".*"</entry>
      <entry>".*"</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
     </row>
     <row>
      <entry>#.(MAKE-PATHNAME :TYPE "*")</entry>
      <entry>NIL</entry>
      <entry>:WILD</entry>
      <entry>NIL</entry>
      <entry>NIL</entry>
     </row>
    </tbody>
   </tgroup>
  </table>
 </section>

 <section xml:id="ansi.pathnames.wild">
  <title>Wild pathnames and matching</title>

  <para>&ECL; accepts four kind of wildcards in pathnames.</para>
  <itemizedlist>
   <listitem>
    <para>A single wildcard in a directory component, file name, type or
    version is parsed as the <symbol>:WILD</symbol> value. See for instance
    <literal>"*.*"</literal>, <literal>"/home/*/.bashrc"</literal>, etc</para>
   </listitem>
   <listitem>
    <para>A double wildcard in a directory component, such as in
    <literal>"/home/**/"</literal> is parsed as the
    <symbol>:WILD-INFERIORS</symbol>, and matches any number of directories,
    even nested ones, such as: <filename>/home/</filename>,
    <filename>/home/jlr</filename>, <filename>/home/jlr/lib</filename>,
    etc.</para>
   </listitem>
   <listitem>
    <para>An isolated wildcard <literal>"log*.txt"</literal> matches any number
    of characters: <filename>log.txt</filename>,
    <filename>log_back.txt</filename>, etc.</para>
   </listitem>
   <listitem>
    <para>A question mark <literal>"log?.txt"</literal> matches a single
    character: <filename>log1.txt</filename>,
    <filename>log2.txt</filename>...</para>
   </listitem>
  </itemizedlist>

  <para>The matching rules in &CommonLisp; and &ECL; are simple but have some unintuitive consequences when compared to Unix/DOS rules. The most important one is that directories must always end with a trailing slash <literal>/</literal>, as in <literal>#p"/my/home/directory/"</literal>. Second to that, <symbol>NIL</symbol> values can only be matched by <symbol>NIL</symbol> and <symbol>:WILD</symbol>. Hence, <literal>"*"</literal> can only match files without file type. For some examples see <xref linkend="ansi.files.directory"/>.</para>
  </section>

 <xi:include href="ref_c_filenames.xml" xpointer="ansi.filenames.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.files">
 <title>Files</title>

 <section xml:id="ansi.files.dict">
  <title>Dictionary</title>

  <section xml:id="ansi.files.directory">
   <title><function>DIRECTORY</function></title>

   <para>This function does not have any additional arguments other than the
   ones described in &ANSI;. To list files and directories, it follows the
   rules for matching pathnames described in <xref
   linkend="ansi.pathnames.wild"/>. In short, you have the following
   practical examples:</para>
   <table>
    <title>Examples of using <function>DIRECTORY</function></title>
    <tgroup cols="2">
     <thead>
      <row><entry>Argument</entry><entry>Meaning</entry></row>
     </thead>
     <tbody>
      <row>
       <entry><literal>"/home/jlr/*.*"</literal></entry>
       <entry>List all files in directory <filename>/home/jlr/</filename> Note
       that it lists only files, not directories!</entry>
      </row>
      <row>
       <entry><literal>"/home/jlr/*"</literal></entry>
       <entry>Same as before, but only files without type.</entry>
      </row>
      <row>
       <entry><literal>"/home/jlr/*/"</literal></entry>
       <entry>List all directories contained in
       <filename>/home/jlr/</filename>. Nested directories are not
       navigated.</entry>
      </row>
      <row>
       <entry><literal>"/home/jlr/**/*.*"</literal></entry>
       <entry>List all files in all directories contained in
       <filename>/home/jlr/</filename>, recursively. Nested directories are
       navigated.</entry>
      </row>
     </tbody>
    </tgroup>
   </table>
  </section>
 </section>

 <xi:include href="ref_c_files.xml" xpointer="ansi.files.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.streams">
 <title>Streams</title>

 <section xml:id="ansi.streams.types">
  <title>Stream types</title>

  <para>&ECL; implements all stream types described in &ANSI;. Additionally,
  when configured with option <option>--enable-clos-streams</option>, &ECL;
  includes a version of Gray streams where any object that implements the
  appropiate methods (<function>stream-input-p</function>,
  <function>stream-read-char</function>, etc) is a valid argument for the
  functions that expect streams, such as <function>read</function>,
  <function>print</function>, etc.</para>

 </section>

 <section xml:id="ansi.streams.io">
  <title>Input/Output model</title>

  <para>&ECL; distinguishes between two kinds of streams: character streams
  and byte streams. In the first kind one is only allowed to write
  characters, either individually, with <function>write-char</function>, or
  in chunks, with <function>write-sequence</function> or any of the Lisp
  printer functions. The implementation of character streams in &ECL; has the
  following shortcomings:
  <itemizedlist>
   <listitem><para>No support for external formats. Reading and writing is
   performed using the 8-bit code of the character.</para></listitem>
   <listitem><para>No support for Unicode characters. The code of large
   characters is simply truncated.</para></listitem>
  </itemizedlist></para>

  <para>The other kind are binary streams. Here input and output is performed
  in chunks of bits. Binary streams are created with the function
  <function>open</function> passing as argument a subtype of
  <type>integer</type>. We distinguish two cases
  <itemizedlist>
   <listitem><para>The word size is a multiple of 8 bits: element types
   <type>(byte 8)</type>, <type>(signed-byte 32)</type>,
   etc.</para></listitem>
   <listitem><para>The word size is not a multiple of 8 bits: element types
   <type>(unsigned-byte 3)</type>, <type>(signed-byte 15)</type>,
   etc.</para></listitem>
  </itemizedlist>
  In the first case the length of the file can be deduced from the number of
  octets which are used in the filesystem. In the second case, however, one
  needs some extra information which tells how many bits in the last byte are
  significant for the content. This information is stored as a single-byte
  header at the beginning of the file.</para>
 </section>

 <xi:include href="ref_c_streams.xml" xpointer="ansi.streams.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.printer">
 <title>Printer</title>

 <para>In all situations where the rules are well specified, &ECL; prints
 objects according to &ANSI;. The specification leaves however a number of
 cases as implementation dependent behavior. The output of &ECL; in those
 cases is summarized in <xref linkend="table.printer"/>. Except for the types
 <type>character</type> and <type>random-state</type>, most of those examples
 regard non-standard written forms <literal>#&lt;...&gt;</literal> cannot be
 read back using <function>read</function>. These printed representations are
 just informative and should not be used to reconstruct or compare
 objects.</para>

 <table xml:id="table.printer">
  <title>Implementation specific printed representation</title>
  <tgroup cols="3">
   <thead>
    <row>
     <entry>Lisp type</entry>
     <entry>Format</entry>
     <entry>Remarks</entry>
    </row>
   </thead>
   <tbody>
    <row>
     <entry><type>package</type></entry>
     <entry><literal>#&lt;package <replaceable>name</replaceable>&gt;</literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry><type>random-state</type></entry>
     <entry><literal>#$<replaceable>character array</replaceable></literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry><type>bitvector</type></entry>
     <entry><literal>#&lt;bit-vector <replaceable>unique-id</replaceable>&gt;</literal></entry>
     <entry>Only when <varname>*print-array*</varname> is false.</entry>
    </row>
    <row>
     <entry><type>vector</type></entry>
     <entry><literal>#&lt;vector <replaceable>unique-id</replaceable>&gt;</literal></entry>
     <entry>Only when <varname>*print-array*</varname> is false.</entry>
    </row>
    <row>
     <entry><type>array</type></entry>
     <entry><literal>#&lt;array <replaceable>unique-id</replaceable>&gt;</literal></entry>
     <entry>Only when <varname>*print-array*</varname> is false.</entry>
    </row>
    <row>
     <entry><type>hash-table</type></entry>
     <entry><literal>#&lt;hash-table <replaceable>unique-id</replaceable>&gt;</literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry><type>readtable</type></entry>
     <entry><literal>#&lt;readtable <replaceable>unique-id</replaceable>&gt;</literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry>interpreted <type>function</type></entry>
     <entry><literal>#&lt;bytecompiled-function <replaceable>name-or-id</replaceable>&gt;</literal></entry>
     <entry>Name is a <type>symbol</type>.</entry>
    </row>
    <row>
     <entry>machine compiled <type>function</type></entry>
     <entry><literal>#&lt;compiled-function <replaceable>name</replaceable>&gt;</literal></entry>
     <entry>Name is a <type>symbol</type>.</entry>
    </row>
    <row>
     <entry><type>input-stream</type></entry>
     <entry><literal>#&lt;input stream "<replaceable>filename</replaceable>"&gt;</literal></entry>
     <entry>An stream that reads from <replaceable>filename</replaceable>.</entry>
    </row>
    <row>
     <entry><type>output-stream</type></entry>
     <entry><literal>#&lt;output stream "<replaceable>filename</replaceable>"&gt;</literal></entry>
     <entry>An stream that writes to <replaceable>filename</replaceable>.</entry>
    </row>
    <row>
     <entry><type>probe-stream</type></entry>
     <entry><literal>#&lt;probe stream "<replaceable>filename</replaceable>"&gt;</literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry><type>string-input-stream</type></entry>
     <entry><literal>#&lt;string-input stream from "<replaceable>string-piece</replaceable>"&gt;</literal></entry>
     <entry>The string is the text left to be read.</entry>
    </row>
    <row>
     <entry><type>string-output-stream</type></entry>
     <entry><literal>#&lt;string-output stream <replaceable>unique-id</replaceable>&gt;</literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry><type>two-way-stream</type></entry>
     <entry><literal>#&lt;two-way stream <replaceable>unique-id</replaceable>&gt;</literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry><type>echo-stream</type></entry>
     <entry><literal>#&lt;echo stream <replaceable>unique-id</replaceable>&gt;</literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry><type>synonym-stream</type></entry>
     <entry><literal>#&lt;synonym stream to <replaceable>symbol</replaceable>&gt;</literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry><type>broadcast-stream</type></entry>
     <entry><literal>#&lt;broadcast stream <replaceable>unique-id</replaceable>&gt;</literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry><type>concatenated-stream</type></entry>
     <entry><literal>#&lt;concatenated stream <replaceable>unique-id</replaceable>&gt;</literal></entry>
     <entry></entry>
    </row>
    <row>
     <entry><type>closed-stream</type></entry>
     <entry><literal>#&lt;closed <replaceable>...</replaceable>&gt;</literal></entry>
     <entry>The dots denote any of the above stream forms.</entry>
    </row>
   </tbody>
  </tgroup>
 </table>

 <xi:include href="ref_c_printer.xml" xpointer="ansi.printer.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.reader">
 <title>Reader</title>

 <xi:include href="ref_c_reader.xml" xpointer="ansi.reader.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.system-construction">
 <title>System Construction</title>

 <xi:include href="ref_c_system_construction.xml" xpointer="ansi.system-construction.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

<chapter xml:id="ansi.environment">
 <title>Environment</title>

 <section xml:id="ansi.environment.dict">
  <title>Dictionary</title>

  <refentry xml:id="ansi.environment.disassemble">
   <refnamediv>
    <refname><function>disassemble</function></refname>
    <refpurpose>Display the assembly code of a function</refpurpose>
   </refnamediv>

   <refsynopsisdiv>
    <funcsynopsis>
     <funcprototype>
      <funcdef>disassemble</funcdef>
      <paramdef><parameter>function-designator</parameter>*</paramdef>
     </funcprototype>
    </funcsynopsis>
    <variablelist>
     <varlistentry>
      <term><replaceable>function-designator</replaceable></term>
      <listitem><para>A symbol which is bound to a function in the global environment, or a lambda form
      </para></listitem>
     </varlistentry>
    </variablelist>
   </refsynopsisdiv>

   <refsect1>
    <title>Function</title>

    <para>As specified in &ANSI; this function outputs the internal represention of a compiled function, or of a lambda form, as it would look after being compiled.</para>

    <para>&ECL; only has a particular difference: it has two different compilers, one based on bytecodes and one based on the C language. The output will thus depend on the arguments and on which compiler is active at the moment in which this function is run.</para>
    <itemizedlist>
     <listitem><para>If the argument is a bytecompiled function, the output will be bytecodes.</para></listitem>
     <listitem><para>If the argument is a lambda form, it will be processed by the active compiler and the appropriate output (bytecodes or C) will be shown.</para></listitem>
     <listitem><para>If the argument is a C-compiled form, &ECL; will retrieve its original lambda form and process it with the currently active compiler.</para></listitem>
    </itemizedlist>
   </refsect1>
  </refentry>

  <refentry xml:id="ansi.environment.trace">
   <refnamediv>
    <refname><function>trace</function></refname>
    <refpurpose>Follow execution of functions</refpurpose>
   </refnamediv>

   <refsynopsisdiv>
    <funcsynopsis>
     <funcprototype>
      <funcdef>trace</funcdef>
      <paramdef><parameter>function-name</parameter>*</paramdef>
     </funcprototype>
    </funcsynopsis>
    <variablelist>
     <varlistentry>
      <term><replaceable>function-name</replaceable></term>
      <listitem><para>
       <synopsis>{<replaceable>symbol</replaceable> | (<replaceable>symbol</replaceable> [<replaceable>option</replaceable> <replaceable>form</replaceable>]*)}</synopsis>
      </para></listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable>symbol</replaceable></term>
      <listitem><para>A symbol which is bound to a function in the global
      environment. Not evaluated.</para></listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable>option</replaceable></term>
      <listitem><para>One of <symbol>:BREAK</symbol>,
      <symbol>:BREAK-AFTER</symbol>, <symbol>:COND-BEFORE</symbol>,
      <symbol>:COND-AFTER</symbol>, <symbol>:COND</symbol>,
      <symbol>:PRINT</symbol>, <symbol>:PRINT-AFTER</symbol>,
      <symbol>:STEP</symbol></para></listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable>form</replaceable></term>
      <listitem><para>A lisp form evaluated in an special
      environment.</para></listitem>
     </varlistentry>
     <varlistentry>
      <term>returns</term>
      <listitem><para>List of symbols with traced functions.</para></listitem>
     </varlistentry>
    </variablelist>
   </refsynopsisdiv>

   <refsect1>
    <title>Macro</title>

    <para>Causes one or more functions to be traced. Each
    <replaceable>function-name</replaceable> can be a symbol which is bound to
    a function, or a list containing that symbol plus additional options. If
    the function bound to that symbol is called, information about the
    argumetns and output of this function will be printed. Trace options will
    modify the amount of information and when it is printed.</para>

    <para>Not that if the function is called from another function compiled in
    the same file, tracing might not be enabled. If this is the case, to
    enable tracing, recompile the caller with a <literal>notinline</literal>
    declaration for the called function.</para>

    <para><function>trace</function> returns a name list of those functions
    that were traced by the call to trace.  If no
    <replaceable>function-name</replaceable> is given, <literal>trace</literal>
    simply returns a name list of all the currently traced functions.</para>

    <para>Trace options 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 and a warning might be printed. The lisp
    <replaceable>form</replaceable> accompanying the option is evaluated in an
    environment where <replaceable>sys::arglist</replaceable> is contains the
    list of arguments to the function.</para>

    <para>The following options are defined:</para>
    <variablelist>
     <varlistentry>
      <term><symbol>:cond</symbol></term>
      <term><symbol>:cond-before</symbol></term>
      <term><symbol>:cond-after</symbol></term>
      <listitem>
       <para>If <symbol>:cond-before</symbol> is specified, then
       <function>trace</function> does nothing unless
       <replaceable>form</replaceable> evaluates to true at the time of the
       call. <symbol>:cond-after</symbol> is similar, but suppresses the
       initial printout, and is tested when the function returns.
       <symbol>:cond</symbol> tries both before and after.</para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><symbol>:step</symbol></term>
      <listitem>
       <para>If <replaceable>form</replaceable> evaluates to true, the stepper
       is entered.</para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><symbol>:break</symbol></term>
      <term><symbol>:break-after</symbol></term>
      <listitem>
       <para>If specified, and <replaceable>form</replaceable> 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.</para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><symbol>:print</symbol></term>
      <term><symbol>:print-after</symbol></term>
      <listitem>
       <para>In addition to the usual printout, the result of evaluating
       <replaceable>form</replaceable> is printed at the start of the function
       or at the end of the function, depending on the option. Multiple print
       options cause multiple values to be output, in the order in which they
       were introduced.</para>
      </listitem>
     </varlistentry>
    </variablelist>
   </refsect1>
  </refentry>
 </section>

 <xi:include href="ref_c_environment.xml" xpointer="ansi.environment.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>

</chapter>

</part></book>
<!-- Keep this comment at the end of the file
 Local variables:
 mode: nxml
 sgml-indent-step: 1
 nxml-child-indent: 1
 nxml-outline-child-indent: 1
 fill-column: 79
 End:
 -->