670 lines
46 KiB
HTML
670 lines
46 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<!-- Created by GNU Texinfo 7.0.3, https://www.gnu.org/software/texinfo/ -->
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<title>Data and control flow (ECL Manual)</title>
|
||
|
|
||
|
<meta name="description" content="Data and control flow (ECL Manual)">
|
||
|
<meta name="keywords" content="Data and control flow (ECL Manual)">
|
||
|
<meta name="resource-type" content="document">
|
||
|
<meta name="distribution" content="global">
|
||
|
<meta name="Generator" content="makeinfo">
|
||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
|
|
||
|
<link href="index.html" rel="start" title="Top">
|
||
|
<link href="Indexes.html" rel="index" title="Indexes">
|
||
|
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
|
||
|
<link href="Standards.html" rel="up" title="Standards">
|
||
|
<link href="Objects.html" rel="next" title="Objects">
|
||
|
<link href="Types-and-classes.html" rel="prev" title="Types and classes">
|
||
|
<style type="text/css">
|
||
|
<!--
|
||
|
/* colors */
|
||
|
|
||
|
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
|
||
|
div.example {margin-left: 3.2em}
|
||
|
span.r {font-family: initial; font-weight: normal; font-style: normal}
|
||
|
span:hover a.copiable-link {visibility: visible}
|
||
|
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
|
||
|
ul.mark-bullet {list-style-type: disc}
|
||
|
@media (prefers-color-scheme: dark) {
|
||
|
/* dark theme */
|
||
|
html { color: seashell;
|
||
|
background: #1A1A1A; }
|
||
|
body { background: #1A1A1A; }
|
||
|
th { border-bottom: 2px solid lightgray; }
|
||
|
h1, h2, h3, h4, h5 { background-image: linear-gradient(to left, #202020, #3A3A3A); }
|
||
|
code, var, code a { color: darkorange;
|
||
|
background: #2A2A2A; }
|
||
|
a { color: seashell; }
|
||
|
pre { background: #2A2A2A;
|
||
|
color: seashell;
|
||
|
/* mark longer code block with stripe on the left */
|
||
|
border-left: 5px solid darkorange;
|
||
|
padding-left: 10px; }
|
||
|
pre.screen { background: #2A2A2A;
|
||
|
border: 1px solid lightgray; }
|
||
|
pre.programlisting { background: #2A2A2A;
|
||
|
border-left: 1px solid lightgray;
|
||
|
border-top: 1px solid lightgray; }
|
||
|
/* we need a light background in order for the images to be readable */
|
||
|
img { background: white }
|
||
|
}
|
||
|
@media (prefers-color-scheme: light) {
|
||
|
/* light theme */
|
||
|
html { background: white }
|
||
|
body { background: white }
|
||
|
th { border-bottom: 2px solid gray; }
|
||
|
h1, h2, h3, h4, h5 { background: lightgray; }
|
||
|
code, var, code a { color: darkred;
|
||
|
background: whitesmoke; }
|
||
|
a { color: #000; }
|
||
|
pre { background: whitesmoke;
|
||
|
color: black;
|
||
|
/* mark longer code block with stripe on the left */
|
||
|
border-left: 5px solid darkred;
|
||
|
padding-left: 10px; }
|
||
|
pre.screen { background: #EEE;
|
||
|
border: 1px solid black; }
|
||
|
pre.programlisting { background: #EEEEEE;
|
||
|
border-left: 1px solid black;
|
||
|
border-top: 1px solid black; }
|
||
|
}
|
||
|
|
||
|
body {
|
||
|
margin: 1em 125px 0 10%;
|
||
|
line-height: 1.5em;
|
||
|
padding: 0 2em 1em 2em;
|
||
|
font: 13px Verdana,Arial, sans-serif
|
||
|
}
|
||
|
ul, dd, dl, dt { margin-top: 0; margin-bottom: 0; }
|
||
|
p, code, td, dl, dt {
|
||
|
line-height: 1.5em;
|
||
|
}
|
||
|
table {
|
||
|
font: inherit;
|
||
|
border-collapse: collapse;
|
||
|
}
|
||
|
th, td {
|
||
|
vertical-align: top;
|
||
|
}
|
||
|
h1, h2, h3 { padding-left: 15px; }
|
||
|
h4, h5 { padding-left: 5px; }
|
||
|
code, pre {
|
||
|
font-size: 1em;
|
||
|
font-family: monospace;
|
||
|
}
|
||
|
var {
|
||
|
font-size: 1em;
|
||
|
}
|
||
|
/* links inside code appear the same as the code itself */
|
||
|
code a {
|
||
|
font-weight: normal;
|
||
|
text-decoration: none;
|
||
|
}
|
||
|
/* but get an underline when hovering */
|
||
|
code a:hover {
|
||
|
text-decoration: underline;
|
||
|
}
|
||
|
/* ordinary links appear in bold */
|
||
|
a { font-weight: bold; }
|
||
|
pre.verbatim {
|
||
|
margin: 0 0 0 0;
|
||
|
}
|
||
|
pre {
|
||
|
overflow: auto;
|
||
|
}
|
||
|
pre.screen {
|
||
|
font-weight: bold;
|
||
|
padding: 0.5em;
|
||
|
}
|
||
|
pre.programlisting {
|
||
|
padding: 0.5em;
|
||
|
}
|
||
|
div p { padding: 0 2em }
|
||
|
li p { padding: 0; margin: 0 }
|
||
|
hr { display: none; }
|
||
|
div.funcsynopsis p {
|
||
|
text-indent: -2em;
|
||
|
}
|
||
|
div.variablelist {
|
||
|
padding: 0 2em;
|
||
|
}
|
||
|
.type, .funcsynopsis, .symbol {
|
||
|
font-family: monospace;
|
||
|
}
|
||
|
.type, .symbol, .replaceable {
|
||
|
white-space: nowrap;
|
||
|
}
|
||
|
|
||
|
-->
|
||
|
</style>
|
||
|
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body lang="en">
|
||
|
<div class="section-level-extent" id="Data-and-control-flow">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Objects.html" accesskey="n" rel="next">Objects</a>, Previous: <a href="Types-and-classes.html" accesskey="p" rel="prev">Types and classes</a>, Up: <a href="Standards.html" accesskey="u" rel="up">Standards</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h3 class="section" id="Data-and-control-flow-1">2.4 Data and control flow</h3>
|
||
|
|
||
|
|
||
|
<ul class="mini-toc">
|
||
|
<li><a href="Data-and-control-flow.html#Shadowed-bindings" accesskey="1">Shadowed bindings</a></li>
|
||
|
<li><a href="Data-and-control-flow.html#Minimal-compilation" accesskey="2">Minimal compilation</a></li>
|
||
|
<li><a href="Data-and-control-flow.html#Function-types" accesskey="3">Function types</a></li>
|
||
|
<li><a href="Data-and-control-flow.html#C-Calling-conventions" accesskey="4">C Calling conventions</a></li>
|
||
|
<li><a href="Data-and-control-flow.html#C-Reference" accesskey="5">C Reference</a></li>
|
||
|
</ul>
|
||
|
<hr>
|
||
|
<div class="subsection-level-extent" id="Shadowed-bindings">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Data-and-control-flow.html#Minimal-compilation" accesskey="n" rel="next">Minimal compilation</a>, Up: <a href="Data-and-control-flow.html#Data-and-control-flow" accesskey="u" rel="up">Data and control flow</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="Shadowed-bindings-1">2.4.1 Shadowed bindings</h4>
|
||
|
<a class="index-entry-id" id="index-Shadowed-bindings-in-let_002c-flet_002c-labels-and-lambda_002dlist"></a>
|
||
|
<p>ANSI doesn’t specify what should happen if any of the <code class="code">let</code>,
|
||
|
<code class="code">flet</code> and <code class="code">labels</code> 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.
|
||
|
</p>
|
||
|
<p>Moreover, while ANSI defines lambda list parameters in the terms of
|
||
|
<code class="code">let*</code>, 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.
|
||
|
</p>
|
||
|
<p>Described behavior is present in ECL since version 16.0.0. Previously
|
||
|
the <code class="code">let</code> operator were using first binding. Both <code class="code">flet</code> and
|
||
|
<code class="code">labels</code> were signaling an error if C compiler was used and used
|
||
|
the last binding as a visible one when the byte compiler was used.
|
||
|
</p>
|
||
|
<hr>
|
||
|
</div>
|
||
|
<div class="subsection-level-extent" id="Minimal-compilation">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Data-and-control-flow.html#Function-types" accesskey="n" rel="next">Function types</a>, Previous: <a href="Data-and-control-flow.html#Shadowed-bindings" accesskey="p" rel="prev">Shadowed bindings</a>, Up: <a href="Data-and-control-flow.html#Data-and-control-flow" accesskey="u" rel="up">Data and control flow</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="Minimal-compilation-1">2.4.2 Minimal compilation</h4>
|
||
|
<a class="index-entry-id" id="index-Bytecodes-eager-compilation"></a>
|
||
|
<a class="anchor" id="si_003a_003amake_002dlambda"></a><a class="index-entry-id" id="index-si_003a_003amake_002dlambda"></a>
|
||
|
<p>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.
|
||
|
</p>
|
||
|
<p>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 bytecodes.
|
||
|
</p>
|
||
|
<p>The bytecodes compiler is implemented in src/c/compiler.d. The main
|
||
|
entry point is the lisp function si::make-lambda, which takes a name for
|
||
|
the function and the body of the lambda lists, and produces a lisp
|
||
|
object that can be invoked. For instance,
|
||
|
</p>
|
||
|
<a class="index-entry-id" id="index-si_003a_003amake_002dlambda-usage-_0028bytecodes-compilation_0029"></a>
|
||
|
<div class="example lisp">
|
||
|
<pre class="lisp-preformatted">> (defvar fun (si::make-lambda 'f '((x) (1+ x))))
|
||
|
*FUN*
|
||
|
> (funcall fun 2)
|
||
|
3
|
||
|
</pre></div>
|
||
|
|
||
|
<p>ECL can only execute bytecodes. When a list is passed to <code class="code">eval</code> 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 <code class="code">defun</code> or
|
||
|
<code class="code">defmacro</code>, the compiler processes the lambda form to produce a
|
||
|
suitable bytecodes object.
|
||
|
</p>
|
||
|
<a class="index-entry-id" id="index-Eager-compilation-implications"></a>
|
||
|
|
||
|
<p>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:
|
||
|
</p>
|
||
|
<a class="index-entry-id" id="index-Eager-compilation-impact-on-macros"></a>
|
||
|
<div class="example lisp">
|
||
|
<pre class="lisp-preformatted">> (defmacro f (a b) `(+ ,a ,b))
|
||
|
F
|
||
|
> (defun g (x y) (f x y))
|
||
|
G
|
||
|
> (g 1 2)
|
||
|
3
|
||
|
> (defmacro f (a b) `(- ,a ,b))
|
||
|
F
|
||
|
> (g 1 2)
|
||
|
3
|
||
|
</pre></div>
|
||
|
|
||
|
<p>The last statement always outputs 3 while in former implementations
|
||
|
based on simple list traversal it would produce -1.
|
||
|
</p>
|
||
|
<hr>
|
||
|
</div>
|
||
|
<div class="subsection-level-extent" id="Function-types">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Data-and-control-flow.html#C-Calling-conventions" accesskey="n" rel="next">C Calling conventions</a>, Previous: <a href="Data-and-control-flow.html#Minimal-compilation" accesskey="p" rel="prev">Minimal compilation</a>, Up: <a href="Data-and-control-flow.html#Data-and-control-flow" accesskey="u" rel="up">Data and control flow</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="Function-types-1">2.4.3 Function types</h4>
|
||
|
|
||
|
<p>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 <code class="code">compile</code> or <code class="code">compile-file</code>.
|
||
|
</p>
|
||
|
<p>The output of <code class="code">(symbol-function fun)</code> is one of the following:
|
||
|
</p><ul class="itemize mark-bullet">
|
||
|
<li>a function object denoting the definition of the function <code class="code">fun</code>,
|
||
|
</li><li>a list of the form <code class="code">(macro . function-object)</code> when <code class="code">fun</code> denotes a macro,
|
||
|
</li><li>or simply <code class="code">'special</code>, when <code class="code">fun</code> denotes a special form, such as <code class="code">block</code>, <code class="code">if</code>, etc.
|
||
|
</li></ul>
|
||
|
|
||
|
<a class="index-entry-id" id="index-disassemble-and-compile-on-defined-functions"></a>
|
||
|
<a class="index-entry-id" id="index-Keeping-lambda-definitions-with-si_003a_002akeep_002ddefinitions_002a"></a>
|
||
|
|
||
|
<p>ECL usually keeps the source code of a function unless the global
|
||
|
variable <code class="code">si:*keep-definitions*</code> was false when the function was
|
||
|
translated into bytecodes. Therefore, if you don’t need to use compile
|
||
|
and disassemble on defined functions, you should issue <code class="code">(setq
|
||
|
si:*keep-definitions* nil)</code> at the beginning of your session.
|
||
|
</p>
|
||
|
<a class="anchor" id="si_003a_002akeep_002ddefinitions_002a"></a><a class="index-entry-id" id="index-si_003a_002akeep_002ddefinitions_002a"></a>
|
||
|
<dl class="first-defvr">
|
||
|
<dt class="defvr" id="index-si_003a_002akeep_002ddefinitions_002a-1"><span class="category-def">Variable: </span><span><strong class="def-name">si:*keep-definitions*</strong><a class="copiable-link" href='Data-and-control-flow.html#index-si_003a_002akeep_002ddefinitions_002a-1'> ¶</a></span></dt>
|
||
|
<dd><p>If set to <code class="code">t</code> ECL will preserve the compiled function source code
|
||
|
for disassembly and recompilation.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<a class="index-entry-id" id="index-Common-Lisp-functions-limits"></a>
|
||
|
<a class="anchor" id="call_002darguments_002dlimit"></a><a class="index-entry-id" id="index-call_002darguments_002dlimit"></a>
|
||
|
<a class="anchor" id="lambda_002dparameters_002dlimit"></a><a class="index-entry-id" id="index-lambda_002dparameters_002dlimit"></a>
|
||
|
<a class="anchor" id="multiple_002dvalues_002dlimit"></a><a class="index-entry-id" id="index-multiple_002dvalues_002dlimit"></a>
|
||
|
<a class="anchor" id="lambda_002dlist_002dkeywords"></a><a class="index-entry-id" id="index-lambda_002dlist_002dkeywords"></a>
|
||
|
|
||
|
<p>In <a class="ref" href="Data-and-control-flow.html#tab_003afun_002dconst">Table 2.3</a> we list all Common Lisp values related to the limits of functions.
|
||
|
</p><div class="float" id="tab_003afun_002dconst">
|
||
|
|
||
|
<table class="multitable">
|
||
|
<tbody><tr><td width="30%">call-arguments-limit</td><td width="70%"><code class="code">65536</code></td></tr>
|
||
|
<tr><td width="30%">lambda-parameters-limit</td><td width="70%"><code class="code">call-arguments-limit</code></td></tr>
|
||
|
<tr><td width="30%">multiple-values-limit</td><td width="70%"><code class="code">64</code></td></tr>
|
||
|
<tr><td width="30%">lambda-list-keywords</td><td width="70%"><code class="code">(&optional &rest &key &allow-other-keys &aux &whole &environment &body)</code></td></tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<div class="caption"><p><strong class="strong">Table 2.3: </strong>Function related constants</p></div></div>
|
||
|
<hr>
|
||
|
</div>
|
||
|
<div class="subsection-level-extent" id="C-Calling-conventions">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Data-and-control-flow.html#C-Reference" accesskey="n" rel="next">C Reference</a>, Previous: <a href="Data-and-control-flow.html#Function-types" accesskey="p" rel="prev">Function types</a>, Up: <a href="Data-and-control-flow.html#Data-and-control-flow" accesskey="u" rel="up">Data and control flow</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="C-Calling-conventions-1">2.4.4 C Calling conventions</h4>
|
||
|
<p>ECL is implemented using either a C or a C++ compiler. This is not a limiting factor, but imposes some constraints on how these languages are used to implement functions, multiple values, closures, etc. In particular, while C functions can be called with a variable number of arguments, there is no facility to check how many values were actually passed. This forces us to have two types of functions in ECL
|
||
|
</p>
|
||
|
<ul class="itemize mark-bullet">
|
||
|
<li>Functions that take a fixed number of arguments have a simple C signature, with all arguments being properly declared, as in <code class="code">cl_object cl_not(cl_object arg1)</code>.
|
||
|
</li><li>Functions with a variable number of arguments, such as those accepting <code class="code">&optional</code>, <code class="code">&rest</code> or <code class="code">&key</code> arguments, must take as first argument the number of remaining ones, as in <code class="code">cl_object cl_list(cl_narg narg, ...)</code>. Here <var class="var">narg</var> is the number of supplied arguments.
|
||
|
</li></ul>
|
||
|
|
||
|
<p>The previous conventions set some burden on the C programmer that calls ECL, for she must know the type of function that is being called and supply the right number of arguments. This burden disappears for Common Lisp programmers, though.
|
||
|
</p>
|
||
|
<p>As an example let us assume that the user wants to invoke two functions which are part of the ANSI [see <a class="pxref" href="Bibliography.html">ANSI</a>] standard and thus are exported with a C name. The first example is <code class="code">cl_cos</code>, which takes just one argument and has a signature <code class="code">cl_object cl_cos(cl_object)</code>.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">#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));
|
||
|
</pre></div>
|
||
|
|
||
|
<p>The second example also involves some Mathematics, but now we are going to use the C function corresponding to <code class="code">+</code>. As described in <a class="ref" href="Numbers.html#Numbers-_002d-ANSI-dictionary">ANSI dictionary</a>, the C name for the plus operator is <code class="code">cl_P</code> and has a signature <code class="code">cl_object cl_P(cl_narg narg,...)</code>. Our example now reads as follows
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">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));
|
||
|
</pre></div>
|
||
|
|
||
|
<p>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 class="code">cl_funcall</code> or <code class="code">cl_apply</code>. The previous examples may thus be rewritten as follows
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">/* Symbol + in package CL */
|
||
|
cl_object plus = ecl_make_symbol("+","CL");
|
||
|
cl_object one = ecl_make_fixnum(1);
|
||
|
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));
|
||
|
</pre></div>
|
||
|
|
||
|
<p>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 class="code">ECL_C_CALL_ARGUMENTS_LIMIT</code>, which is as of this writing 63. The use of this stack is transparently handled by the Common Lisp functions, such as <code class="code">apply</code>, <code class="code">funcall</code> and their C equivalents, and also by a set of macros, <code class="code">cl_va_arg</code>, which can be used for coding functions that take an arbitrary name of arguments.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
</div>
|
||
|
<div class="subsection-level-extent" id="C-Reference">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Previous: <a href="Data-and-control-flow.html#C-Calling-conventions" accesskey="p" rel="prev">C Calling conventions</a>, Up: <a href="Data-and-control-flow.html#Data-and-control-flow" accesskey="u" rel="up">Data and control flow</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="C-Reference-4">2.4.5 C Reference</h4>
|
||
|
<a class="anchor" id="ecl_005fbds_005fbind"></a><a class="index-entry-id" id="index-ecl_005fbds_005fbind"></a>
|
||
|
<a class="anchor" id="ecl_005fbds_005fpush"></a><a class="index-entry-id" id="index-ecl_005fbds_005fpush"></a>
|
||
|
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
|
||
|
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fbds_005fbind-1"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">ecl_bds_bind</strong> <code class="def-code-arguments">(cl_env_ptr cl_env, cl_object var, cl_object value);</code><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fbds_005fbind-1'> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-ecl_005fbds_005fpush-1"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">ecl_bds_push</strong> <code class="def-code-arguments">(cl_env_ptr cl_env, cl_object var);</code><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fbds_005fpush-1'> ¶</a></span></dt>
|
||
|
<dd><p>Bind a special variable
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>Establishes a variable binding for the symbol <var class="var">var</var> in the Common Lisp environment <var class="var">env</var>, assigning it <var class="var">value</var>.
|
||
|
</p>
|
||
|
<p>This macro or function is the equivalent of <a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm">let*</a> and <a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm">let</a>.
|
||
|
</p>
|
||
|
<p><code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fbds_005fpush">ecl_bds_push</a></code> does a similar thing, but reuses the old value of the same variable. It is thus the equivalent of <code class="code">(let ((var var)) ...)</code>
|
||
|
</p>
|
||
|
<p>Every variable binding must undone when no longer needed. It is best practice to match each call to <code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fbds_005fbind">ecl_bds_bind</a></code> by another call to <code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fbds_005funwind1">ecl_bds_unwind1</a></code> in the same function.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<a class="anchor" id="ecl_005fbds_005funwind1"></a><a class="index-entry-id" id="index-ecl_005fbds_005funwind1"></a>
|
||
|
<a class="anchor" id="ecl_005fbds_005funwind_005fn"></a><a class="index-entry-id" id="index-ecl_005fbds_005funwind_005fn"></a>
|
||
|
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
|
||
|
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fbds_005funwind1-1"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">ecl_bds_unwind1</strong> <code class="def-code-arguments">(cl_env_ptr cl_env);</code><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fbds_005funwind1-1'> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-ecl_005fbds_005funwind_005fn-1"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">ecl_bds_unwind_n</strong> <code class="def-code-arguments">(cl_env_ptr cl_env, int n);</code><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fbds_005funwind_005fn-1'> ¶</a></span></dt>
|
||
|
<dd><p>Undo one variable binding
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p><code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fbds_005funwind1">ecl_bds_unwind1</a></code> undoes the outermost variable binding, restoring the original value of the symbol in the process.
|
||
|
</p>
|
||
|
<p><code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fbds_005funwind_005fn">ecl_bds_unwind_n</a></code> does the same, but for the <var class="var">n</var> last variables.
|
||
|
</p>
|
||
|
<p>Every variable binding must undone when no longer needed. It is best practice to match each call to <code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fbds_005fbind">ecl_bds_bind</a></code> by another call to <code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fbds_005funwind1">ecl_bds_unwind1</a></code> in the same function.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ecl_005fsetq"></a><a class="index-entry-id" id="index-ecl_005fsetq"></a>
|
||
|
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
|
||
|
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fsetq-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_setq</strong> <code class="def-code-arguments">(cl_env_ptr cl_env, cl_object var, cl_object value);</code><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fsetq-1'> ¶</a></span></dt>
|
||
|
<dd><p>C equivalent of setq
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>Assigns <var class="var">value</var> to the special variable denoted by the symbol <var class="var">var</var>, in the Common Lisp environment <var class="var">cl_env</var>.
|
||
|
</p>
|
||
|
<p>This function implements a variable assignment, not a variable binding. It is thus the equivalent of <a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/s_setq.htm">setq</a>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ecl_005fsymbol_005fvalue"></a><a class="index-entry-id" id="index-ecl_005fsymbol_005fvalue"></a>
|
||
|
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
|
||
|
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fsymbol_005fvalue-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_symbol_value</strong> <code class="def-code-arguments">(cl_object var);</code><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fsymbol_005fvalue-1'> ¶</a></span></dt>
|
||
|
<dd>
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>Retrieves the value of the special variable or constant denoted by the symbol <var class="var">var</var>, in the Common Lisp environment <var class="var">cl_env</var>.
|
||
|
</p>
|
||
|
<p>This function implements the equivalent of <a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_symb_5.htm">symbol-value</a> and works both on special variables and constants.
|
||
|
</p>
|
||
|
<p>If the symbol is not bound, an error is signaled.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ecl_005fva_005flist"></a><a class="index-entry-id" id="index-ecl_005fva_005flist"></a>
|
||
|
<a class="anchor" id="ecl_005fva_005fstart"></a><a class="index-entry-id" id="index-ecl_005fva_005fstart"></a>
|
||
|
<a class="anchor" id="ecl_005fva_005farg"></a><a class="index-entry-id" id="index-ecl_005fva_005farg"></a>
|
||
|
<a class="anchor" id="ecl_005fva_005fend"></a><a class="index-entry-id" id="index-ecl_005fva_005fend"></a>
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-typedef-struct-_007b-_002e_002e_002e-_007d-ecl_005fva_005flist_005b1_005d_003b"><span class="category-def">Macro: </span><span><strong class="def-name">typedef struct { ... } ecl_va_list[1];</strong><a class="copiable-link" href='Data-and-control-flow.html#index-typedef-struct-_007b-_002e_002e_002e-_007d-ecl_005fva_005flist_005b1_005d_003b'> ¶</a></span></dt>
|
||
|
</dl>
|
||
|
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-ecl_005fva_005fstart-1"><span class="category-def">Macro: </span><span><strong class="def-name">ecl_va_start</strong> <var class="def-var-arguments">(ecl_va_list arglist, last_argument, narg, n_ordinary);</var><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fva_005fstart-1'> ¶</a></span></dt>
|
||
|
</dl>
|
||
|
|
||
|
<dl class="first-deftypefn">
|
||
|
<dt class="deftypefn" id="index-ecl_005fva_005farg-1"><span class="category-def">Macro: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_va_arg</strong> <code class="def-code-arguments">(ecl_va_list arglist);</code><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fva_005farg-1'> ¶</a></span></dt>
|
||
|
</dl>
|
||
|
|
||
|
<dl class="first-deftypefn">
|
||
|
<dt class="deftypefn" id="index-ecl_005fva_005fend-1"><span class="category-def">Macro: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_va_end</strong> <code class="def-code-arguments">(ecl_va_list arglist);</code><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fva_005fend-1'> ¶</a></span></dt>
|
||
|
<dd><p>Accepting a variable number of arguments
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>The macros above are used to code a function that accepts an arbitrary number of arguments. We will describe them in a practical example
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="verbatim">cl_object my_plus(cl_narg narg, cl_object required1, ...)
|
||
|
{
|
||
|
cl_env_ptr env = ecl_process_env();
|
||
|
cl_object other_value;
|
||
|
ecl_va_list varargs;
|
||
|
ecl_va_start(varargs, required1, narg, 1);
|
||
|
while (narg > 1) {
|
||
|
cl_object other_value = ecl_va_arg(varargs);
|
||
|
required1 = ecl_plus(required1, other_value);
|
||
|
}
|
||
|
ecl_va_end(varargs);
|
||
|
ecl_return1(env, required1);
|
||
|
}
|
||
|
</pre></div>
|
||
|
|
||
|
<p>The first thing to do is to declare the variable that will hold the arguments. This is <var class="var">varargs</var> in our example and it has the type <code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fva_005flist">ecl_va_list</a></code>.
|
||
|
</p>
|
||
|
<p>This arguments list is initialized with the <code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fva_005fstart">ecl_va_start</a></code> macro, based on the supplied number of arguments, <var class="var">narg</var>, the number of required arguments which are passed as ordinary C arguments (1 in this case), the last such ordinary arguments, <var class="var">required</var>, and the buffer for the argument list, <var class="var">varargs</var>.
|
||
|
</p>
|
||
|
<p>Once <var class="var">varargs</var> has been initialized, we can retrieve these values one by one using <code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fva_005farg">ecl_va_arg</a></code>. Note that the returned value always has the type <code class="code">cl_object</code>, for it is always a Common Lisp object.
|
||
|
</p>
|
||
|
<p>The last statement before returning the output of the function is <code class="code"><a class="ref" href="Data-and-control-flow.html#ecl_005fva_005fend">ecl_va_end</a></code>. This macro performs any required cleanup and should never be omitted.
|
||
|
</p>
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ecl_005fnvalues"></a><a class="index-entry-id" id="index-ecl_005fnvalues"></a>
|
||
|
<a class="anchor" id="ecl_005fnth_005fvalue"></a><a class="index-entry-id" id="index-ecl_005fnth_005fvalue"></a>
|
||
|
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
|
||
|
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fnvalues-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_nvalues</strong> <code class="def-code-arguments">(cl_env_ptr env);</code><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fnvalues-1'> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-ecl_005fnth_005fvalue-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_nth_value</strong> <code class="def-code-arguments">(cl_env_ptr env, int n);</code><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005fnth_005fvalue-1'> ¶</a></span></dt>
|
||
|
<dd><p>Accessing output values
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>Common Lisp functions may return zero, one or more values. In ECL, the first two cases do not require any special manipulation, as the C function returns either <code class="code">nil</code> or the first (zeroth) value directly. However, if one wishes to access additional values from a function, one needs to use these two macros or functions
|
||
|
</p>
|
||
|
<ul class="itemize mark-bullet">
|
||
|
<li><code class="code">ecl_nvalues(env)</code> returns the number of values that the function actually outputs. The single argument is the lisp environment. This value is larger or equal to 0 and smaller than <code class="code">ECL_MULTIPLE_VALUES_LIMIT</code>.
|
||
|
</li><li>Once we know the number of return values, they can be directly accessed using the function <code class="code">ecl_nth_value(env,n)</code>, where <var class="var">n</var> is a number larger than or equal to 1, and smaller than <code class="code">ECL_MULTIPLE_VALUES_LIMIT</code>, which must correspond to a valid output value. No checking is done.
|
||
|
</li></ul>
|
||
|
|
||
|
<p>Note that in both cases these macros and functions have to be used right after the Lisp function was called. This is so because other Lisp functions might destroy the content of the return stack.
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Example</b>
|
||
|
</p>
|
||
|
<p>A C/C++ excerpt:
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">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);
|
||
|
</pre></div>
|
||
|
|
||
|
<p>The somewhat equivalent Common Lisp code:
|
||
|
</p>
|
||
|
<div class="example lisp">
|
||
|
<pre class="lisp-preformatted">(multiple-value-bind (modulus equivalent)
|
||
|
(floor 13 6))
|
||
|
</pre></div>
|
||
|
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ecl_005freturn0"></a><a class="index-entry-id" id="index-ecl_005freturn0"></a>
|
||
|
<a class="anchor" id="ecl_005freturn1"></a><a class="index-entry-id" id="index-ecl_005freturn1"></a>
|
||
|
<a class="anchor" id="ecl_005freturn2"></a><a class="index-entry-id" id="index-ecl_005freturn2"></a>
|
||
|
<a class="anchor" id="ecl_005freturn3"></a><a class="index-entry-id" id="index-ecl_005freturn3"></a>
|
||
|
<dl class="first-deffn first-defmac-alias-first-deffn">
|
||
|
<dt class="deffn defmac-alias-deffn" id="index-ecl_005freturn0-1"><span class="category-def">Macro: </span><span><strong class="def-name">ecl_return0</strong> <var class="def-var-arguments">(cl_env_ptr cl_env);</var><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005freturn0-1'> ¶</a></span></dt>
|
||
|
<dt class="deffnx defmacx-alias-deffnx def-cmd-deffn" id="index-ecl_005freturn1-1"><span class="category-def">Macro: </span><span><strong class="def-name">ecl_return1</strong> <var class="def-var-arguments">(cl_env_ptr cl_env, cl_object value1);</var><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005freturn1-1'> ¶</a></span></dt>
|
||
|
<dt class="deffnx defmacx-alias-deffnx def-cmd-deffn" id="index-ecl_005freturn2-1"><span class="category-def">Macro: </span><span><strong class="def-name">ecl_return2</strong> <var class="def-var-arguments">(cl_env_ptr cl_env, cl_object value1, cl_object value2);</var><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005freturn2-1'> ¶</a></span></dt>
|
||
|
<dt class="deffnx defmacx-alias-deffnx def-cmd-deffn" id="index-ecl_005freturn3-1"><span class="category-def">Macro: </span><span><strong class="def-name">ecl_return3</strong> <var class="def-var-arguments">(cl_env_ptr cl_env, cl_object value1, cl_object value2, cl_object value3);</var><a class="copiable-link" href='Data-and-control-flow.html#index-ecl_005freturn3-1'> ¶</a></span></dt>
|
||
|
<dd><p>Returning multiple values
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>Returns <var class="var">N</var> values from a C/C++ function in a way that a Common Lisp function can recognize and use them. The 0-th value is returned directly, while values 1 to N are stored in the Common Lisp environment <var class="var">cl_env</var>. This macro has to be used from a function which returns an object of type <code class="code">cl_object</code>.
|
||
|
</p>
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ECL_005fBLOCK_005fBEGIN"></a><a class="index-entry-id" id="index-ECL_005fBLOCK_005fBEGIN"></a>
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-ECL_005fBLOCK_005fBEGIN-1"><span class="category-def">Macro: </span><span><strong class="def-name">ECL_BLOCK_BEGIN</strong><a class="copiable-link" href='Data-and-control-flow.html#index-ECL_005fBLOCK_005fBEGIN-1'> ¶</a></span></dt>
|
||
|
<dd><div class="example">
|
||
|
<pre class="verbatim">ECL_BLOCK_BEGIN(env,code) {
|
||
|
|
||
|
} ECL_BLOCK_END;
|
||
|
</pre></div>
|
||
|
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p><code class="code"><a class="ref" href="Data-and-control-flow.html#ECL_005fBLOCK_005fBEGIN">ECL_BLOCK_BEGIN</a></code> establishes a block named <var class="var">code</var> that becomes visible for the Common Lisp code. This block can be used then as a target for <code class="code">cl_return</code>.
|
||
|
</p>
|
||
|
<p><var class="var">env</var> must be the value of the current Common Lisp environment, obtained with <code class="code"><a class="ref" href="Evaluation-and-compilation.html#ecl_005fprocess_005fenv">ecl_process_env</a></code>.
|
||
|
</p>
|
||
|
<p>The C/C++ program has to ensure that the code in <code class="code">ECL_BLOCK_END</code> gets executed, avoiding a direct exit of the block via <code class="code">goto</code> or a C/C++ return.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ECL_005fCATCH_005fBEGIN"></a><a class="index-entry-id" id="index-ECL_005fCATCH_005fBEGIN"></a>
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-ECL_005fCATCH_005fBEGIN-1"><span class="category-def">Macro: </span><span><strong class="def-name">ECL_CATCH_BEGIN</strong><a class="copiable-link" href='Data-and-control-flow.html#index-ECL_005fCATCH_005fBEGIN-1'> ¶</a></span></dt>
|
||
|
<dd><div class="example">
|
||
|
<pre class="verbatim">ECL_CATCH_BEGIN(env,tag) {
|
||
|
|
||
|
} ECL_CATCH_END;
|
||
|
</pre></div>
|
||
|
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p><code class="code"><a class="ref" href="Data-and-control-flow.html#ECL_005fCATCH_005fBEGIN">ECL_CATCH_BEGIN</a></code> establishes a destination for <code class="code">throw</code> with the code given by <var class="var">tag</var>.
|
||
|
</p>
|
||
|
<p><var class="var">env</var> must be the value of the current Common Lisp environment, obtained with <code class="code"><a class="ref" href="Evaluation-and-compilation.html#ecl_005fprocess_005fenv">ecl_process_env</a></code>.
|
||
|
</p>
|
||
|
<p>The C/C++ program has to ensure that the code in <code class="code">ECL_CATCH_END</code> gets executed, avoiding a direct exit of the catch block via goto or a C/C++ return.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ECL_005fUNWIND_005fPROTECT_005fBEGIN"></a><a class="index-entry-id" id="index-ECL_005fUNWIND_005fPROTECT_005fBEGIN"></a>
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-ECL_005fUNWIND_005fPROTECT_005fBEGIN-1"><span class="category-def">Macro: </span><span><strong class="def-name">ECL_UNWIND_PROTECT_BEGIN</strong><a class="copiable-link" href='Data-and-control-flow.html#index-ECL_005fUNWIND_005fPROTECT_005fBEGIN-1'> ¶</a></span></dt>
|
||
|
<dd><p>C macro for unwind-protect
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Synopsis</b>
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="verbatim">ECL_UNWIND_PROTECT_BEGIN(env) {
|
||
|
|
||
|
} ECL_UNWIND_PROTECT_EXIT {
|
||
|
|
||
|
} ECL_UNWIND_PROTECT_END;
|
||
|
</pre></div>
|
||
|
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p><code class="code"><a class="ref" href="Data-and-control-flow.html#ECL_005fUNWIND_005fPROTECT_005fBEGIN">ECL_UNWIND_PROTECT_BEGIN</a></code> 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 class="code">throw</code>, <code class="code">return</code>, etc).
|
||
|
</p>
|
||
|
<p><var class="var">env</var> must be the value of the current Common Lisp environment, obtained with <code class="code"><a class="ref" href="Evaluation-and-compilation.html#ecl_005fprocess_005fenv">ecl_process_env</a></code>.
|
||
|
</p>
|
||
|
<p>The utility of this construct is limited, for it only protects against nonlocal exits caused by Common Lisp constructs: it does not interfere with C <code class="code">goto</code>, <code class="code">return</code> or with C++ exceptions.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
<ul class="mini-toc">
|
||
|
<li><a href="Data-and-control-flow.html#ANSI-Dictionary-2" accesskey="1">ANSI Dictionary</a></li>
|
||
|
</ul>
|
||
|
<div class="subsubsection-level-extent" id="ANSI-Dictionary-2">
|
||
|
<h4 class="subsubsection">2.4.5.1 ANSI Dictionary</h4>
|
||
|
<p>Common Lisp and C equivalence
|
||
|
</p>
|
||
|
<table class="multitable">
|
||
|
<thead><tr><th width="30%">Lisp symbol</th><th width="70%">C function or constant</th></tr></thead>
|
||
|
<tbody><tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_apply.htm">apply</a></td><td width="70%">cl_object cl_apply(cl_narg narg, cl_object function, ...)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/v_call_a.htm">call-arguments-limit</a></td><td width="70%">ECL_CALL_ARGUMENTS_LIMIT</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_cmpd_f.htm">compiled-function-p</a></td><td width="70%">cl_object cl_compiled_function_p(cl_object object)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_comple.htm">complement</a></td><td width="70%">cl_object cl_complement(cl_object function)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_cons_1.htm">constantly</a></td><td width="70%">cl_object cl_constantly(cl_object value)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_everyc.htm">every</a></td><td width="70%">cl_object cl_every(cl_narg narg, cl_object predicate, ...)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm">eq</a></td><td width="70%">cl_object cl_eq(cl_object x, cl_object y)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_eql.htm">eql</a></td><td width="70%">cl_object cl_eql(cl_object x, cl_object y)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_equal.htm">equal</a></td><td width="70%">cl_object cl_equal(cl_object x, cl_object y)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_equalp.htm">equalp</a></td><td width="70%">cl_object cl_equalp(cl_object x, cl_object y)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_fbound.htm">fboundp</a></td><td width="70%">cl_object cl_fboundp(cl_object function_name)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_fdefin.htm">fdefinition</a></td><td width="70%">cl_object cl_fdefinition(cl_object function_name)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_fdefin.htm">(setf fdefinition)</a></td><td width="70%">cl_object si_fset(cl_narg narg, cl_object function_name, cl_object definition, ...)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_fmakun.htm">fmakunbound</a></td><td width="70%">cl_object cl_fmakunbound(cl_object function_name)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_funcal.htm">funcall</a></td><td width="70%">cl_object cl_funcall(cl_narg narg, cl_object function, ...)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_fn_lam.htm">function-lambda-expression</a></td><td width="70%">cl_object cl_function_lambda_expression(cl_object function)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_fnp.htm">functionp</a></td><td width="70%">cl_object cl_functionp(cl_object object)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_get_se.htm">get-setf-expansion</a></td><td width="70%">cl_object cl_get_setf_expansion(cl_narg narg, cl_object place, ...)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_identi.htm">identity</a></td><td width="70%">cl_object cl_identity(cl_object x)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm">let</a>, <a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm">let*</a></td><td width="70%">cl_object ecl_bds_bind(cl_env_ptr env, cl_object symbol, cl_object value)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/v_lamb_1.htm">lambda-parameters-limit</a></td><td width="70%">ECL_LAMBDA_PARAMETERS_LIMIT</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/v_multip.htm">multiple-values-limit</a></td><td width="70%">ECL_MULTIPLE_VALUES_LIMIT</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_not.htm">not</a></td><td width="70%">cl_object cl_not(cl_object object)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_everyc.htm">notevery</a></td><td width="70%">cl_object cl_notevery(cl_narg narg, cl_object predicate, ...)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_everyc.htm">notany</a></td><td width="70%">cl_object cl_notany(cl_narg narg, cl_object predicate, ...)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_set.htm">set</a></td><td width="70%">cl_object cl_set(cl_object symbol, cl_object value)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/s_setq.htm">setq</a></td><td width="70%">cl_object ecl_setq(cl_env_ptr env, cl_object symbol, cl_object value)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_symb_5.htm">symbol-value</a></td><td width="70%">cl_object ecl_symbol_value(cl_env_ptr env, cl_object symbol)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_everyc.htm">some</a></td><td width="70%">cl_object cl_some(cl_narg narg, cl_object predicate, ...)</td></tr>
|
||
|
<tr><td width="30%"><a class="url" href="http://www.lispworks.com/documentation/HyperSpec/Body/f_vals_l.htm">values-list</a></td><td width="70%">cl_object cl_values_list(cl_object list)</td></tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
|
||
|
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<hr>
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Objects.html" accesskey="n" rel="next">Objects</a>, Previous: <a href="Types-and-classes.html" accesskey="p" rel="prev">Types and classes</a>, Up: <a href="Standards.html" accesskey="u" rel="up">Standards</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|