<?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">
<chapter label="7" xml:id="The-compiler">
<title>The Compiler</title>
<para>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 <emphasis>fasl file</emphasis> (or <emphasis>o-file</emphasis> because of the actual
filetype).  The compiled program in a fasl file is loaded by the function
<literal>load</literal>.</para>
<para>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
<literal>optimize</literal> declarations (see Section 7.1).</para>
<para>The &ECL; compiler processes the <literal>eval-when</literal> special form exactly as
specified in &Steele84; (see Section 5.3.3 of &Steele84;).</para>
<para>The &ECL; compiler is invoked by the functions <literal>compile-file</literal>,
<literal>compile</literal>, and <literal>disassemble</literal> described below.  In addition, the
&ECL; compiler may be invoked directly by the Shell commands <literal>ecl</literal>.
This command requires the file name of the source file as its
argument. <literal>ecl</literal> simply adds <literal>.lsp</literal> to the file name argument to
obtain the full name of the source file.</para>
<para><screen>
$ ecl <replaceable>filename</replaceable>
</screen></para>
<para role="continues">has the same effect as the compiler invocation <literal>(compile-file
<replaceable>filename</replaceable>)</literal> from within &ECL;, and</para>
<para><screen>
$ ecl -C <replaceable>filename</replaceable>
</screen></para>
<para>has the same effects as <literal>(compile-file <replaceable>filename</replaceable>
:c-file t :h-file t :data-file t)</literal>.</para>
<blockquote>
<screen><indexterm role="fn"><primary>compile-file</primary></indexterm>&#151; Function: <function>compile-file</function> <varname>pathname &amp;key :output-file :verbose :print :c-file :h-file :data-file</varname></screen>
<para><literal>compile-file</literal> compiles the Lisp program stored in the file specified by
<replaceable>pathname</replaceable>, and generates a binary file.  If <replaceable>:verbose</replaceable> is true, a
message indicating what file is being compiled is printed.  If <replaceable>:print</replaceable>
is true, information about top-level forms in the file being compiled is
printed.  <literal>compile-file</literal> generates the following temporary files:</para>
<informaltable>
<tgroup cols="2">
<colspec colwidth="16*"></colspec>
<colspec colwidth="43*"></colspec>
<tbody>
<row>
<entry><emphasis role="bold">Temporary File</emphasis></entry>
<entry><emphasis role="bold">Contents</emphasis></entry>
</row>
<row>
<entry><replaceable>c-file</replaceable></entry>
<entry>C version of the Lisp program</entry>
</row>
<row>
<entry><replaceable>h-file</replaceable></entry>
<entry>The include file referenced in the c-file</entry>
</row>
<row>
<entry><replaceable>data-file</replaceable></entry>
<entry>The Lisp data to be used at load time</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>If files of these names already exist, the old files will be deleted first.
Usually, these intermediate files are automatically deleted after execution of
<literal>compile-file</literal>.</para>
<para>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 <literal>.lsp</literal>
will be used.  The keyword parameter <literal>:output-file</literal> defines the default
directory and the default name to be applied to the output files (i.e., the
fasl file and the temporary files).  <replaceable>:output-file</replaceable> itself defaults to
<replaceable>input-pathname</replaceable>.  That is, if <replaceable>:output-file</replaceable> 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.</para>
<informaltable>
<tgroup cols="2">
<colspec colwidth="46*"></colspec>
<colspec colwidth="43*"></colspec>
<tbody>
<row>
<entry><emphasis role="bold">Output File</emphasis></entry>
<entry><emphasis role="bold">Filetype</emphasis></entry>
</row>
<row>
<entry>fasl file</entry>
<entry><literal>.o</literal></entry>
</row>
<row>
<entry>c-file</entry>
<entry><literal>.c</literal></entry>
</row>
<row>
<entry>h-file</entry>
<entry><literal>.h</literal></entry>
</row>
<row>
<entry>data-file</entry>
<entry><literal>.data</literal></entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>Each output file can be specified by the corresponding keyword parameter.
If the value of the keyword parameter is (), then the output file will be
deleted after execution of <literal>compile-file</literal>.  If the value of the
keyword parameter is <replaceable>T</replaceable>, 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 <replaceable>:output-file</replaceable> is <replaceable>T</replaceable>, and the default values
of <replaceable>:c-file</replaceable>, <replaceable>::h-file</replaceable>, and <replaceable>:data-file</replaceable> are all ().</para>
<variablelist>
<varlistentry>
<term><literal>(compile-file 'foo)</literal></term>
<listitem>
<para>The source file is <literal>FOO.lsp</literal> and the fasl file is <literal>FOO.o</literal>
both in the current directory.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>(compile-file 'foo.lish)</literal></term>
<listitem>
<para>The source file is <literal>FOO.LISH</literal> and the fasl file is <literal>FOO.o</literal>'.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>(compile-file "/usr/mas/foo" :output-file "/usr/tai/baa")</literal></term>
<listitem>
<para>The source file is <literal>foo.lsp</literal> in the directory <filename>/usr/mas</filename>, and the
fasl file is <literal>baa.o</literal> in the directory <filename>/usr/tai</filename>.</para>
</listitem>
</varlistentry>
</variablelist>
</blockquote>
<blockquote>
<screen><indexterm role="fn"><primary>compile</primary></indexterm>&#151; Function: <function>compile</function> <varname>name code &amp;optional definition</varname></screen>
<para>If <replaceable>definition</replaceable> is not supplied, <replaceable>name</replaceable> should be the name of a
not-yet-compiled function.  In this case, compile compiles the function,
replaces the previous definition of <replaceable>name</replaceable> with the compiled
function,<emphasis>and</emphasis> returns <replaceable>name</replaceable>.  If <replaceable>definition</replaceable> is supplied, it
should be a lambda-expression to be compiled and <replaceable>name</replaceable> should be a symbol.
If <replaceable>name</replaceable> is a non-() symbol, then compile installs the compiled
function as the function definition of <replaceable>name</replaceable> and returns <replaceable>name</replaceable>.  If
<replaceable>name</replaceable> is (), then compile simply returns the compiled function.</para>
<para>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 <literal>compile-file</literal> to get a fasl file,
which is then loaded into &ECL;.  The source file and the fasl file
are given the names <filename>gazonk.lsp</filename> and <filename>gazonk.fasl</filename>,
respectively.  These files are not deleted automatically after the
execution of <literal>compile</literal>.</para>
</blockquote>
<blockquote>
<screen><indexterm role="fn"><primary>disassemble</primary></indexterm>&#151; Function: <function>disassemble</function> <varname>&amp;optional thing &amp;key :h-file :data-file</varname></screen>
<para>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 <replaceable>thing</replaceable> is not supplied, or if it is
(), then the previously compiled form by disassemble will be compiled
again.  If <replaceable>thing</replaceable> is a symbol other than (), 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 <replaceable>thing</replaceable> is a lambda-expression <literal>(lambda <replaceable>lambda-list .
body</replaceable>)</literal>, then <literal>disassemble</literal> first creates a function definition
<literal>(defun gazonk <replaceable>lambda-list .  body</replaceable>)</literal> and this definition is
compiled.  (The function name <literal>gazonk</literal> has no special meanings.  Indeed,
the displayed code is essentially independent of the function name.)
Otherwise, <replaceable>thing</replaceable> itself will be compiled as a top-level form.  In any
case, <literal>disassemble</literal> does not install the compiled function.
<literal>disassemble</literal> returns no value.</para>
<para>No intermediate h-file is created if the keyword parameter <literal>:h-file</literal> is
() or if <replaceable>:h-file</replaceable> is not supplied.  Otherwise, an intermediate h-file
is created under the name specified by <replaceable>:h-file</replaceable>.  Similarly, the
intermediate data-file is specified by the keyword parameter <replaceable>:data-file</replaceable>.</para>
</blockquote>
</chapter>
<!-- Keep this comment at the end of the file
  Local variables:
  sgml-parent-document: "ecl.xml"
  sgml-indent-step: 1
  nxml-child-indent: 1
  nxml-outline-child-indent: 1
  fill-column: 79
  End:
--></book>
