Commit 68b22e52 authored by Marius Gerbershagen's avatar Marius Gerbershagen

doc: cosmetic changes

    Small improvements to css, correct indentation for examples.
parent 3c3a02ea
......@@ -32,14 +32,15 @@ The demerits are:
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:
@verbatim
@lisp
(defvar *delta* 2)
(defun add1 (x) (+ *delta* x))
@end verbatim
@end lisp
The compiler generates the following intermediate C code.
@example
@verbatim
/* function definition for ADD1 */
/* optimize speed 3, debug 0, space 0, safety 2 */
......@@ -88,12 +89,13 @@ L2:;
ecl_cmp_defun(VV[2]); /* ADD1 */
}
@end verbatim
@end example
The C function @code{L1add1} implements the Lisp function @code{add1}. This relation is established by @code{ecl_cmp_defun} in the initialization function @code{init_fas_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}, while @code{VV[2]} holds the function object for @code{add1}, which is created during initialization of the module. @code{VM} in the definition of @code{L1add1} 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., 3 in this example. Thus the following macro definition is found in the H-file.
@verbatim
@example
#define VM 3
@end verbatim
@end example
@subsection 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.
......@@ -106,16 +108,16 @@ Later, when the compiled closure is invoked, a pointer is set up to each lexical
Let us see an example. Suppose the following function has been compiled.
@verbatim
@lisp
(defun foo (x)
(let ((a #'(lambda () (incf x)))
(y x))
(values a #'(lambda () (incf x y)))))
@end verbatim
@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}.
@verbatim
@example
>(multiple-value-setq (f g) (foo 10))
#<compiled-closure nil>
......@@ -126,7 +128,7 @@ Let us see an example. Suppose the following function has been compiled.
21
>
@end verbatim
@end example
After this, the two compiled closures look like:
......@@ -148,7 +150,7 @@ After this, the two compiled closures look like:
@subsection 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 Common-Lisp declarations added,
@verbatim
@lisp
(eval-when (:compile-toplevel)
(proclaim '(ftype (function (fixnum fixnum) fixnum) tak))
(proclaim '(optimize (speed 3) (debug 0) (safety 0))))
......@@ -159,10 +161,11 @@ Declarations, especially type and function declarations, increase the efficiency
y
(tak (tak (1- x) y)
(tak (1- y) x))))
@end verbatim
@end lisp
The compiler generates the following C code (Note that the tail-recursive call of @code{TAK} was replaced by iteration):
@example
@verbatim
/* function definition for TAK */
/* optimize speed 3, debug 0, space 0, safety 0 */
......@@ -198,6 +201,7 @@ L1:;
goto TTL;
}
@end verbatim
@end example
@subsection Inspecting generated C code
Common-Lisp defines a function disassemble, which is supposed to disassemble a compiled function and to display the assembler code. According to @cite{Common-Lisp: The Language},
......@@ -208,6 +212,7 @@ This is primary useful for debugging the compiler, ..\\
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.
@example
@verbatim
> (defun add1 (x) (1+ x))
......@@ -230,3 +235,4 @@ TTL:
}
}
@end verbatim
@end example
......@@ -21,6 +21,7 @@ C-program is written to standard output.
The function definition:
@exindex dpp: function definition
@example
@verbatim
@(defun name ({var}*
[&optional {var | (var [initform [svar]])}*]
......@@ -38,6 +39,7 @@ The function definition:
} @)
@end verbatim
@end example
name is the name of the lisp function
......@@ -57,9 +59,11 @@ it should be surrounded by backquotes (`).
Function return:
@example
@verbatim
@(return {form}*);
@end verbatim
@end example
Return function expands into a lexical block @verb{|{}|}, so if it's
used inside IF/ELSE, then it should be enclosed, even if we
......@@ -68,16 +72,20 @@ instruction.
Symbols:
@example
@verbatim
@'name'
@end verbatim
@end example
Expands into a C statement, whole value is the given symbol
from symbols_list.h
@example
@verbatim
@[name]
@end verbatim
@end example
Expands into a C statement, whole value is a fixnum
corresponding to the index in the builtin symbols table of the
......
......@@ -37,6 +37,7 @@ it returns the first one and the remaining ones are kept in a global
To show the argument/value passing mechanism, here we list the actual
code for the Common-Lisp function last.
@example
@verbatim
cl_object
cl_last(cl_narg narg, cl_object l, ...)
......@@ -58,6 +59,7 @@ cl_last(cl_narg narg, cl_object l, ...)
return __value0;
}
@end verbatim
@end example
ECL adopts the convention that the name of a function that implements
a Common-Lisp function begins with a short package name (@code{cl} for
......@@ -83,12 +85,14 @@ lisp representation of the statements that output values, and of the
function definitions. For instance, the actual source code for
@code{cl_last} in @code{src/c/list.d}
@example
@verbatim
@(defun last (l &optional (k ecl_make_fixnum(1)))
@
@(return ecl_last(l, ecl_to_size(k)));
@)
@end verbatim
@end example
@node The lexical environment
@subsection The lexical environment
......@@ -133,73 +137,75 @@ after function invocation.
Let us see how these invocation records are used for debugging.
@example
@verbatim
> (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.
> (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 verbatim
@end example
html { background: #FFF; }
html { background: #FFF; }
body {
margin: 1em 125px 0 10%;
line-height: 1.5em;
padding: 0 2em 1em 2em;
line-height: 1.5em;
padding: 0 2em 1em 2em;
background: #FFF;
font: 12px Verdana,Arial, sans-serif
}
......@@ -19,10 +19,15 @@ th, td {
h1, h2, h3, h4, h5 { background: #EEE; }
code, pre {
font-size: 1em;
font-family: fixed;
font-family: monospace;
}
code {
background: #CDC;
}
pre.verbatim {
margin: 0 0 0 0;
}
pre {
line-height: 1em;
overflow: auto;
}
pre.screen {
......@@ -48,7 +53,7 @@ div.variablelist {
padding: 0 2em;
}
.type, .funcsynopsis, .symbol {
font-family: fixed;
font-family: monospace;
}
.type, .symbol, .replaceable {
white-space: nowrap;
......
......@@ -133,13 +133,13 @@ This macro is compatible with the one in SBCL and as such it also defines three
@code{mp:with-local-interrupts} executes its body with interrupts enabled provided that there is an @code{mp:allow-with-interrupts} for every @code{mp:without-interrupts} surrounding the current one. @code{mp:with-local-interrupts} is equivalent to:
@verbatim
@lisp
(allow-with-interrupts (with-interrupts ...))
@end verbatim
@end lisp
Care must be taken not to let either @code{mp:allow-with-interrupts} or @code{mp:with-local-interrupts} appear in a function that escapes from inside the @code{mp:without-interrupts} in:
@verbatim
@lisp
(without-interrupts
;; The body of the lambda would be executed with WITH-INTERRUPTS allowed
;; regardless of the interrupt policy in effect when it is called.
......@@ -149,6 +149,6 @@ Care must be taken not to let either @code{mp:allow-with-interrupts} or @code{mp
;; The body of the lambda would be executed with interrupts enabled
;; regardless of the interrupt policy in effect when it is called.
(lambda () (with-local-interrupts ...)))
@end verbatim
@end lisp
@end defmac
......@@ -128,40 +128,40 @@ Finally, the function @code{si_make_array} does a similar job to @code{si_make_f
Create one-dimensional @code{base-string} with room for 11 characters:
@verbatim
@example
cl_object s = ecl_alloc_simple_vector(ecl_aet_bc, 11);
@end verbatim
@end example
Create a one-dimensional @code{array} with a fill pointer
@verbatim
@example
cl_object type = ecl_make_symbol("BYTE8","EXT");
cl_object a = si_make_vector(ecl_make_fixnum(16), type, ECL_NIL, /* adjustable */
ecl_make_fixnum(0) /* fill-pointer */,
ECL_NIL /* displaced_to */,
ECL_NIL /* displacement */);
@end verbatim
@end example
An alternative formulation
@verbatim
@example
cl_object type = ecl_make_symbol("BYTE8","EXT");
cl_object a = si_make_array(ecl_make_fixnum(16), type, ECL_NIL, /* adjustable */
ecl_make_fixnum(0) /* fill-pointer */,
ECL_NIL /* displaced_to */,
ECL_NIL /* displacement */);
@end verbatim
@end example
Create a 2-by-3 two-dimensional @code{array}, specialized for an integer type:
@verbatim
@example
cl_object dims = cl_list(2, ecl_make_fixnum(2), ecl_make_fixnum(3));
cl_object type = ecl_make_symbol("BYTE8","EXT");
cl_object a = si_make_array(dims, type, ECL_NIL, /* adjustable */
ECL_NIL /* fill-pointer */,
ECL_NIL /* displaced_to */,
ECL_NIL /* displacement */);
@end verbatim
@end example
@subsubsection Accessors
@cppindex ecl_aref
......
......@@ -8,6 +8,7 @@
@deffn Macro ECL_HANDLER_CASE
C macro for @clhs{m_hand_1.htm,handler-case}
@subsubheading Synopsis
@example
@verbatim
ECL_HANDLER_CASE_BEGIN(env,names) {
......@@ -15,6 +16,7 @@ ECL_HANDLER_CASE_BEGIN(env,names) {
} ECL_HANDLER_CASE_END;
@end verbatim
@end example
@subsubheading Description
@code{ECL_HANDLER_CASE_BEGIN} runs a block of C code with a set of error handlers bound to the names given by the list @var{names}. The subsequent @code{ECL_HANDLER_CASE} statements specify what to do when the @var{n}-th type of conditions is found, where @var{n} is an integer denoting the position of the name in the list @var{names}.
......@@ -23,6 +25,7 @@ When a condition is signaled, ECL scans the list of signal handlers, looking for
The following example shows how to establish a handler for @code{ERROR} conditions. Note how the first value to @code{ECL_HANDLER_CASE} matches the position of the condition name in the list:
@example
@verbatim
cl_object error = ecl_make_symbol("ERROR","CL");
ECL_HANDLER_CASE_BEGIN(the_env, ecl_list1(error)) {
......@@ -34,6 +37,7 @@ ECL_HANDLER_CASE_BEGIN(the_env, ecl_list1(error)) {
output = condition;
} ECL_HANDLER_CASE_END;
@end verbatim
@end example
@end deffn
......@@ -41,6 +45,7 @@ ECL_HANDLER_CASE_BEGIN(the_env, ecl_list1(error)) {
@deffn Macro ECL_RESTART_CASE
C macro for @clhs{m_rst_ca.htm,restart-case}
@subsubheading Synopsis
@example
@verbatim
ECL_RESTART_CASE_BEGIN(env,names) {
......@@ -48,6 +53,7 @@ ECL_RESTART_CASE_BEGIN(env,names) {
} ECL_RESTART_CASE_END;
@end verbatim
@end example
@subsubheading Description
@code{ECL_RESTART_CASE_BEGIN} runs a block of C code with a set of restarts bound to the names given by the list @var{names}. The subsequent @code{ECL_RESTART_CASE} statements specify what to do when the @var{n}-th restart is invoked, where @var{n} is an integer denoting the position of the name in the list @var{names}.
......@@ -56,6 +62,7 @@ When the restart is invoked, it can receive any number of arguments, which are g
The following example shows how to establish an @var{ABORT} and a @var{USE-VALUE} restart. Note how the first value to @var{ECL_RESTART_CASE} matches the position of the restart name in the list:
@example
@verbatim
cl_object abort = ecl_make_symbol("ABORT","CL");
cl_object use_value = ecl_make_symbol("USE-VALUE","CL");
......@@ -70,6 +77,7 @@ ECL_RESTART_CASE_BEGIN(the_env, cl_list(2, abort, use_value)) {
output = ECL_CAR(args);
} ECL_RESTART_CASE_END;
@end verbatim
@end example
@end deffn
@subsubsection ANSI dictionary
......
......@@ -11,21 +11,21 @@
@node Shadowed bindings
@subsection Shadowed bindings
@cindex Shadowed bindings in LET, FLET, LABELS and lambda-list
ANSI doesn't specify what should happen if any of the @code{LET},
@code{FLET} and @code{LABELS} special operators contain many bindings
@cindex Shadowed bindings in let, flet, labels and lambda-list
ANSI doesn't specify what should happen if any of the @code{let},
@code{flet} and @code{labels} special operators contain many bindings
sharing the same name. Because the behavior varies between the
implementations and the programmer can't rely on the spec ECL signals an
error if such situation occur.
Moreover, while ANSI defines lambda list parameters in the terms of
@code{LET*}, when used in function context programmer can't provide an
@code{let*}, when used in function context programmer can't provide an
initialization forms for required parameters. If required parameters
share the same name an error is signaled.
Described behavior is present in ECL since version 16.0.0. Previously
the @code{LET} operator were using first binding. Both @code{FLET} and
@code{LABELS} were signaling an error if C compiler was used and used
the @code{let} operator were using first binding. Both @code{flet} and
@code{labels} were signaling an error if C compiler was used and used
the last binding as a visible one when the byte compiler was used.
@node Minimal compilation
......@@ -156,27 +156,27 @@ The previous conventions set some burden on the C programmer that calls ECL, for
As an example let us assume that the user wants to invoke two functions which are part of the ANSI @bibcite{ANSI} standard and thus are exported with a C name. The first example is cl_cos, which takes just one argument and has a signature @code{cl_object cl_cos(cl_object)}.
@verbatim
@example
#include <math.h>
...
cl_object angle = ecl_make_double_float(M_PI);
cl_object c = cl_cos(angle);
printf("\nThe cosine of PI is %g\n", ecl_double_float(c));
@end verbatim
@end example
The second example also involves some Mathematics, but now we are going to use the C function corresponding to @code{+}. As described in @ref{Numbers - ANSI dictionary}, the C name for the plus operator is @code{cl_P} and has a signature @code{cl_object cl_P(cl_narg narg,...)}. Our example now reads as follows
@verbatim
@example
cl_object one = ecl_make_fixnum(1);
cl_object two = cl_P(2, one, one);
cl_object three = cl_P(3, one, one, one);
printf("\n1 + 1 is %d\n", ecl_fixnum(two));
printf("\n1 + 1 + 1 is %d\n", ecl_fixnum(three));
@end verbatim
@end example
Note that most Common Lisp functions will not have a C name. In this case one must use the symbol that names them to actually call the functions, using @code{cl_funcall} or @code{cl_apply}. The previous examples may thus be rewritten as follows
@verbatim
@example
/* Symbol + in package CL */
cl_object plus = ecl_make_symbol("+","CL");
cl_object one = ecl_make_fixnum(1);
......@@ -184,7 +184,7 @@ cl_object two = cl_funcall(3, plus, one, one);
cl_object three = cl_funcall(4, plus, one, one, one);
printf("\n1 + 1 is %d\n", ecl_fixnum(two));
printf("\n1 + 1 + 1 is %d\n", ecl_fixnum(three));
@end verbatim
@end example
Another restriction of C and C++ is that functions can only take a limited number of arguments. In order to cope with this problem, ECL uses an internal stack to pass any argument above a hardcoded limit, @code{ECL_C_CALL_ARGUMENTS_LIMIT}, which is as of this writing 63. The use of this stack is transparently handled by the Common Lisp functions, such as apply, funcall and their C equivalents, and also by a set of macros, @code{cl_va_arg}, which can be used for coding functions that take an arbitrary name of arguments.
......@@ -265,6 +265,7 @@ Accepting a variable number of arguments
@subsubheading Description
The macros above are used to code a function that accepts an arbitrary number of arguments. We will describe them in a practical example
@example
@verbatim
cl_object my_plus(cl_narg narg, cl_object required1, ...)
{
......@@ -280,6 +281,7 @@ cl_object my_plus(cl_narg narg, cl_object required1, ...)
ecl_return1(env, required1);
}
@end verbatim
@end example
The first thing to do is to declare the variable that will hold the arguments. This is @var{varargs} in our example and it has the type @code{ecl_va_list}.
......@@ -312,20 +314,20 @@ Note that in both cases these macros and functions have to be used right after t
@subsubheading Example
A C/C++ excerpt:
@verbatim
@example
cl_env_ptr env = ecl_process_env();
cl_object a = ecl_make_fixnum(13);
cl_object b = ecl_make_fixnum(6);
cl_object modulus = cl_floor(2, a, b);
cl_object remainder = ecl_nth_value(env, 1);
@end verbatim
@end example
The somewhat equivalent Common Lisp code:
@verbatim
@lisp
(multiple-value-bind (modulus equivalent)
(floor 13 6))
@end verbatim
@end lisp
@end deftypefun
......@@ -351,11 +353,13 @@ Returns @var{N} values from a C/C++ function in a way that a Common Lisp functio
@cppindex ECL_BLOCK_BEGIN
@deffn Macro ECL_BLOCK_BEGIN
@example
@verbatim
ECL_BLOCK_BEGIN(env,code) {
} ECL_BLOCK_END;
@end verbatim
@end example
@subsubheading Description
@code{ECL_BLOCK_BEGIN} establishes a block named @var{code} that becomes visible for the Common Lisp code. This block can be used then as a target for @code{cl_return}.
......@@ -368,11 +372,13 @@ The C/C++ program has to ensure that the code in @code{ECL_BLOCK_END} gets execu
@cppindex ECL_CATCH_BEGIN
@deffn Macro ECL_CATCH_BEGIN
@example
@verbatim
ECL_CATCH_BEGIN(env,tag) {
} ECL_CATCH_END;
@end verbatim
@end example
@subsubheading Description
@code{ECL_CATCH_BEGIN} establishes a destination for @code{throw} with the code given by @var{tag}.
......@@ -388,6 +394,7 @@ The C/C++ program has to ensure that the code in @code{ECL_CATCH_END} gets execu
C macro for unwind-protect
@subsubheading Synopsis
@example
@verbatim
ECL_UNWIND_PROTECT_BEGIN(env) {
......@@ -395,6 +402,7 @@ ECL_UNWIND_PROTECT_BEGIN(env) {
} ECL_UNWIND_PROTECT_END;
@end verbatim
@end example
@subsubheading Description
@code{ECL_UNWIND_PROTECT_BEGIN} establishes two blocks of C code that work like the equivalent ones in Common Lisp: a protected block, contained between the "BEGIN" and the "EXIT" statement, and the exit block, appearing immediately afterwards. The form guarantees that the exit block is always executed, even if the protected block attempts to exit via some nonlocal jump construct (@code{throw}, @code{return}, etc).
......
......@@ -168,6 +168,7 @@ In most of those cases there exist straightforward alternatives using
the constructs and functions in ECL. For example, @code{unwind-protect}
can be implemented using a C macro which is provided by ECL
@example
@verbatim
cl_env_ptr env = ecl_process_env();
CL_UNWIND_PROTECT_BEGIN(env) {
......@@ -176,6 +177,7 @@ CL_UNWIND_PROTECT_BEGIN(env) {
/* exit code goes here */
} CL_UNWIND_PROTECT_END;
@end verbatim
@end example
Common Lisp generic functions can be directly accessed using
@code{funcall} or @code{apply} and the function name, as shown in the
......
......@@ -22,13 +22,13 @@ Many Lisp functions take keyword arguments. When invoking a function with keywor
@subsubheading Example
The following example converts a section of a string to uppercase characters:
@verbatim