<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- -*- coding:utf-8 -*- -->

<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">

  <link rel="icon"          href="/favicon.ico" type="image/x-icon">
  <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
  <link rel="stylesheet"    href="../default.css"  type="text/css">

    <style type="text/css">
    <!--
      pre {
        color: #00ff00;
        background-color: #000000;
      }
      .comment {
        /* font-lock-comment-face */
        color: #ff0000;
      }
      .comment-delimiter {
        /* font-lock-comment-delimiter-face */
        color: #ff0000;
      }
      .constant {
        /* font-lock-constant-face */
        color: #7fffd4;
      }
      .function-name {
        /* font-lock-function-name-face */
        color: #87cefa;
      }
      .keyword {
        /* font-lock-keyword-face */
        color: #00ffff;
      }
      .negation-char {
      }
      .preprocessor {
        /* font-lock-preprocessor-face */
        color: #b0c4de;
      }
      .string {
        /* font-lock-string-face */
        color: #da70d6;
      }
      .type {
        /* font-lock-type-face */
        color: #98fb98;
      }
      .variable-name {
        /* font-lock-variable-name-face */
        color: #eedd82;
      }

      pre a {
        color: inherit;
        background-color: inherit;
        font: inherit;
        text-decoration: inherit;
      }
      pre a:hover {
        text-decoration: underline;
      }

img.floatLeft {
    float: left;
    margin: 4px;
}
img.floatRight {
    float: right;
    margin: 4px;
}

    -->
    </style>


  <META NAME="author"             CONTENT="Pascal J. Bourguignon">
  <META HTTP-EQUIV="Description"
        NAME="description"        CONTENT="Libraries and trick to help Lisp programmer survive in a C++ environment.">
  <META NAME="keywords"           CONTENT="Lisp, Common Lisp, Scheme, C++, C, Life saver, library">
  <title>Life Saver -- How a Lisp programmer can survive in a C++ environment</title>
</HEAD>

<BODY>

<!--TOP-BEGIN-->
<!-- This section is automatically generated by html-update, -->
<!-- from data in 'node.el'.    Please, do not edit it here. -->
<DIV CLASS="TOP"></DIV>
<!--TOP-END-->
<!--MENU-BEGIN-->
<!-- This section is automatically generated by html-update, -->
<!-- from data in 'node.el'.    Please, do not edit it here. -->
<DIV CLASS="MENU"><HR><P>|
 <A CLASS="button" HREF="../toc.html">Contents</a> |
 <A CLASS="button" HREF="../index.html">Home</a> |
 <A CLASS="button" HREF="cl-types/index.html">Previous</a> |
 <A CLASS="button" HREF="usenet.html">Up</a> |
 <A CLASS="button" HREF="emacs-colors/index.html">Next</a> |
</P><HR></DIV>
<!--MENU-END-->

<div class="document" id="emacs-color">

<img src="lifesaver.jpg" class="floatRight"
     alt="A picture of a life saver of the Titanic, the later representing about any C++ project...">

<h1>Life Saver &#8212; Help to the Lisp programmer having to write C++ code</h1>


<p>If you have to write a program in C++, condolences.</p>

<p>Now to relieve the pain somewhat, here are some libraries and tools that may be of use.</p>


<small>
<ol>
<li><a href="#openc++">Metaprogramming: OpenC++</a>
<li><a href="#lpp">Sexps and Dynamic Data Structures: Lpp</a>
<li><a href="#sexp">Writing Sexp-formated data: Rivest's SEXP</a>
<li><a href="#intelib">Writing Lisp code in C++: InteLib</a>
<li><a href="#boehmgc">Garbage Collection: BoehmGC</a>
</ol>
</small>

<p><small>Colophon: The examples below are taken from the
documentations of each of these libraries, and are copyrighted by
their respective authors.  The diagram is linked directly from the
OpenC++ site.  The Titanic life saver picture has been ruthelessly
copied from the web.  The examples are formated with the <a
href="http://www.gnu.org/software/emacs">GNU emacs</a>
<code>htmlize-region</code> command.</small></p>





<!-- ======================================================================== -->
<br><hr><br><a name="openc++">
<h2>Metaprogramming: OpenC++</h2>

<p><a href="http://opencxx.sourceforge.net">OpenC++</a>
is a pre-processor to C++, which extends C++ with a Meta Object
Protocol (MOP), which allow you to do metaprogramming in a sane way
(nothing to do with templates and boost hell).</p>


<center>
<img src="http://opencxx.sourceforge.net/opencxx/html/occ.gif"
     alt="[metal-level program .cc] --> <OpenC++ compiler> --> <C++ compiler> --> [C++ module .so],[base-level program .cc] --> [OpenC++ compiler] --> [C++ compiler] --> [object .o]">
</center>


<blockquote>
<em>Notice that gcc 4.4.3 on Linux x86_64 can't compile occ programs:</em>
<pre>
/usr/include/wchar.h:220: parse error before `"wcschr"'
/usr/include/stdlib.h:525: parse error before `"at_quick_exit"'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3
</pre>
<em>We'd probably need to use an older gcc.</em>
</blockquote>



<p>Meta programs have the same form and syntax as normal C++ program,
the only syntactic extensions being a <em>metaclass</em> keyword.<p>


<p><code>VerboseClass.cc</code>:
    <pre>

<span class="comment-delimiter">// </span><span class="comment">VerboseClass.mc
</span><span class="preprocessor">#include</span> <span class="string">"mop.h"</span>
<span class="keyword">class</span> <span class="type">VerboseClass</span> : <span class="keyword">public</span> <span class="type">Class</span> {
<span class="keyword">public</span>:
    <span class="type">Ptree</span>* <span class="function-name">TranslateMemberCall</span>(<span class="type">Environment</span>*, <span class="type">Ptree</span>*, <span class="type">Ptree</span>*,
                               <span class="type">Ptree</span>*, <span class="type">Ptree</span>*);
};
<span class="type">Ptree</span>* <span class="constant">VerboseClass</span>::<span class="function-name">TranslateMemberCall</span>(<span class="type">Environment</span>* <span class="variable-name">env</span>,
                                         <span class="type">Ptree</span>* <span class="variable-name">object</span>, <span class="type">Ptree</span>* <span class="variable-name">op</span>, <span class="type">Ptree</span>* <span class="variable-name">member</span>, <span class="type">Ptree</span>* <span class="variable-name">arglist</span>)
{
    <span class="keyword">return</span> <span class="constant">Ptree</span>::Make(<span class="string">"(puts(\"%p()\"), %p)"</span>,
                       member,
                       <span class="constant">Class</span>::TranslateMemberCall(env, object,
                                                  op,
                                                  member, arglist));
}

</pre>

<code>person.cc</code>:
<pre>

<span class="comment-delimiter">// </span><span class="comment">person.cc
</span><span class="preprocessor">#include</span> <span class="string">&lt;stdio.h&gt;</span>
metaclass <span class="type">VerboseClass</span> <span class="variable-name">Person</span>; <span class="comment-delimiter">// </span><span class="comment">metaclass declaration
</span><span class="keyword">class</span> <span class="type">Person</span> {
<span class="keyword">public</span>:
    <span class="function-name">Person</span>(<span class="type">int</span> <span class="variable-name">age</span>);
    <span class="type">int</span> <span class="function-name">Age</span>() { <span class="keyword">return</span> age; }
    <span class="type">int</span> <span class="function-name">BirthdayComes</span>() { <span class="keyword">return</span> ++age; }
    2
    <span class="keyword">private</span>:
    <span class="type">int</span> age;
};
<span class="function-name">main</span>()
{
    <span class="type">Person</span> <span class="variable-name">billy</span>(24);
    printf(<span class="string">"age %d\n"</span>, billy.Age());
    printf(<span class="string">"age %d\n"</span>, billy.BirthdayComes());
}

</pre>

When compiled with:

<pre>

% occ -m -- -g VerboseClass.mc
% occ -- -g -o person person.cc

</pre>

produces:

<pre>

% person
Age()
age 24
BirthdayComes()
age 25

</pre>

<p>It also allow to easily define new control structures (patterned after
the existing ones) such as:

<pre>

{
    <span class="type">Matrix</span> <span class="variable-name">m</span>;
    m.forall(e){ e = 0.0; }
}

</pre>



<p>Notice that the OpenC++ preprocessor is able to output the syntax
tree of a C++ source in a processable form!</p>

    <pre>

% myocc -s person.cc
[<span class="keyword">typedef</span> [<span class="type">char</span>] [* __gnuc_va_list] ;]
    :
    :
[metaclass VerboseClass Person nil ;]
[[[class Person nil [{ [
                        [public :]
                        [nil [Person ( [[[<span class="type">int</span>] [i]]] )] [{ [
                                                            [[age = i] ;]
                                                            ] }]]
                        [[<span class="type">int</span>] [Age ( nil )] [{ [
                                                 [<span class="keyword">return</span> age ;]
                                                 ] }]]
                        [[<span class="type">int</span>] [BirthdayComes ( nil )] [{ [
                                                           [<span class="keyword">return</span> [++ age] ;]
                                                           ] }]]
                        [private :]
                        [[<span class="type">int</span>] [age] ;]
                        ] }]]] ;]
[nil nil [main ( nil )] [{ [
                            [[Person] [billy ( [24] )] ;]
                            [[printf [( [<span class="string">"age %d\n"</span> , [billy . Age [( nil )]]] )]] ;]
                            [[printf [( [<span class="string">"age %d\n"</span> , [billy . BirthdayComes ...
                                                       ] }]]
%

</pre>






<!-- ======================================================================== -->
<br><hr><br><a name="lpp">
<h2>Sexps and Dynamic Data Structures: Lpp</h2>

<p><a href="http://www.interhack.net/projects/lpp/">Lpp</a> is a C++
library of Lisp-like functions and macros, providing the various data
types commonly found in Lisp, such as symbols, lists, hash-tables,
etc.

<blockquote>
<em>Unfortunately, the latest versions of <b>Lpp</b> (1.21.2 and
previous) don't compile with gcc-4.4.3; there are a lot of missing
extern declarations...</em>
</blockquote>


    <pre>

     <span class="comment-delimiter">/////////////////////////////////////////////////////////////////</span><span class="comment">
</span>     <span class="comment-delimiter">// </span><span class="comment">main.cc = Introduction Simple Data Base example.
</span>
<span class="preprocessor">     #include</span> <span class="string">&lt;Lpp.hh&gt;</span>

     <span class="comment-delimiter">// </span><span class="comment">Data Base class.
</span>     <span class="keyword">class</span> <span class="type">DataBase</span> {
       <span class="type">int</span> <span class="variable-name">size</span>;
       <span class="type">let</span> <span class="variable-name">contents</span>;
     <span class="keyword">public</span>:
       <span class="function-name">DataBase</span>();
       <span class="type">int</span> <span class="function-name">getSize</span>() {<span class="keyword">return</span> size;}
       <span class="type">void</span> <span class="function-name">addEntity</span>(<span class="type">let</span>);
       <span class="type">void</span> <span class="function-name">setValue</span>(<span class="type">let</span>, <span class="type">let</span>, <span class="type">let</span>);
       <span class="type">let</span> <span class="function-name">getValue</span>(<span class="type">let</span>, <span class="type">let</span>);};

     <span class="comment-delimiter">// </span><span class="comment">Data Base constructor.
</span>     <span class="constant">DataBase</span>::<span class="function-name">DataBase</span>() {size = 0; contents = makeHashTable();}

     <span class="comment-delimiter">// </span><span class="comment">Add an entity to the Data Base.
</span>     <span class="type">void</span> <span class="constant">DataBase</span>::<span class="function-name">addEntity</span>(<span class="type">let</span> <span class="variable-name">entity</span>) {
       <span class="keyword">if</span> (<span class="negation-char">!</span>gethash(entity, contents)) {
         puthash(entity, contents, 0);
         size++;}}

     <span class="comment-delimiter">// </span><span class="comment">Set the value of an attribute for given entity.
</span>     <span class="type">void</span> <span class="constant">DataBase</span>::<span class="function-name">setValue</span>(<span class="type">let</span> <span class="variable-name">entity</span>, <span class="type">let</span> <span class="variable-name">attribute</span>, <span class="type">let</span> <span class="variable-name">value</span>) {
       <span class="type">let</span> <span class="variable-name">attributes</span> = gethash(entity, contents);
       <span class="type">let</span> <span class="variable-name">old</span> = assoc(attribute, attributes);
       <span class="keyword">if</span> (old) rplacd(old, value);
       <span class="keyword">else</span> {
         push(cons(attribute, value), attributes);
         puthash(entity, contents, attributes);}}

     <span class="comment-delimiter">// </span><span class="comment">Return the value of an attribute for given entity.
</span>     <span class="type">let</span> <span class="constant">DataBase</span>::<span class="function-name">getValue</span>(<span class="type">let</span> <span class="variable-name">entity</span>, <span class="type">let</span> <span class="variable-name">attribute</span>) {
       <span class="keyword">return</span> cdr(assoc(attribute, gethash(entity, contents)));}

</pre>





<!-- ======================================================================== -->
<br><hr><br><a name="sexp">
<h2>Writing Sexp-formated data in C: Rivest's SEXP</h2>

<p>Ronald L. Rivest's <a href="http://people.csail.mit.edu/rivest/sexp.html">SEXP</a>
format writes and reads data in a sexp-like format, with some provision for binary data.

<p>It may be a nice alternative to JSON or XML.   Of course, one can
always read or parse Common Lisp sexps too.</p>

<p>A short example:
<pre>

    (6:issuer3:bob)

    (4:icon[12:image/bitmap]9:xxxxxxxxx)

    (7:subject(3:ref5:alice6:mother))

</pre>


<!-- ======================================================================== -->
<br><hr><br><a name="intelib">
<h2>Writing Lisp code in C++: InteLib</h2>

<p><a href="http://www.intelib.org/">InteLib</a> is a C++ library
allowing us to write dynamic code, using a subset of C++ syntax similar
to Lisp syntax, without any preprocessing.<p>

<p><code>isomorph.cpp</code>:

    <pre>

 <span class="comment-delimiter">//       </span><span class="comment">File isomorph.cpp
</span><span class="preprocessor"> #include</span> <span class="string">&lt;intelib/lisp/lisp.hpp&gt;</span>
<span class="preprocessor"> #include</span> <span class="string">&lt;intelib/lisp/lsymbol.hpp&gt;</span>
<span class="preprocessor"> #include</span> <span class="string">&lt;intelib/lfun_std.hpp&gt;</span>
<span class="preprocessor"> #include</span> <span class="string">&lt;intelib/lfun_sel.hpp&gt;</span>


 <span class="type">LSymbol</span> <span class="function-name">ISOMORPHIC</span>(<span class="string">"ISOMORPHIC"</span>);

 <span class="keyword">static</span> <span class="type">LFunctionalSymbol</span>&lt;LFunctionDefun&gt; <span class="function-name">DEFUN</span>(<span class="string">"DEFUN"</span>);
 <span class="keyword">static</span> <span class="type">LFunctionalSymbol</span>&lt;LFunctionCond&gt; <span class="function-name">COND</span>(<span class="string">"COND"</span>);
 <span class="keyword">static</span> <span class="type">LFunctionalSymbol</span>&lt;LFunctionAtom&gt; <span class="function-name">ATOM</span>(<span class="string">"ATOM"</span>);
 <span class="keyword">static</span> <span class="type">LFunctionalSymbol</span>&lt;LFunctionAnd&gt; <span class="function-name">AND</span>(<span class="string">"AND"</span>);
 <span class="keyword">static</span> <span class="type">LFunctionalSymbol</span>&lt;LFunctionCar&gt; <span class="function-name">CAR</span>(<span class="string">"CAR"</span>);
 <span class="keyword">static</span> <span class="type">LFunctionalSymbol</span>&lt;LFunctionCdr&gt; <span class="function-name">CDR</span>(<span class="string">"CDR"</span>);

 <span class="keyword">static</span> <span class="type">LListConstructor</span> <span class="variable-name">L</span>;

 <span class="type">void</span> LispInit_isomorphic() {
   <span class="keyword">static</span> <span class="type">LSymbol</span> <span class="variable-name">TREE1</span>(<span class="string">"TREE1"</span>);
   <span class="keyword">static</span> <span class="type">LSymbol</span> <span class="variable-name">TREE2</span>(<span class="string">"TREE2"</span>);
   <span class="comment-delimiter">////////////////////////////////////////////////</span><span class="comment">
</span>   <span class="comment-delimiter">//</span><span class="comment">
</span>   (L|DEFUN, ISOMORPHIC, (L|TREE1, TREE2),
     (L|COND,
       (L|(L|ATOM, TREE1), (L|ATOM, TREE2)),
       (L|(L|ATOM, TREE2), NIL),
       (L|T, (L|AND,
         (L|ISOMORPHIC, (L|CAR, TREE1),
                        (L|CAR, TREE2)),
         (L|ISOMORPHIC, (L|CDR, TREE1),
                        (L|CDR, TREE2))
   )))).Evaluate();
   <span class="comment-delimiter">//</span><span class="comment">
</span>   <span class="comment-delimiter">////////////////////////////////////////////////</span><span class="comment">
</span> }
 <span class="comment-delimiter">//      </span><span class="comment">end of file
</span>
</pre>

<code>main.cpp</code>:

<pre>

 <span class="comment-delimiter">// </span><span class="comment">file main.cpp
</span><span class="preprocessor"> #include</span> <span class="string">&lt;stdio.h&gt;</span>
<span class="preprocessor"> #include</span> <span class="string">&lt;stdlib.h&gt;</span>
<span class="preprocessor"> #include</span> <span class="string">&lt;intelib/sexpress/sexpress.hpp&gt;</span>
<span class="preprocessor"> #include</span> <span class="string">&lt;intelib/sexpress/sstring.hpp&gt;</span>
<span class="preprocessor"> #include</span> <span class="string">&lt;intelib/lisp/lsymbol.hpp&gt;</span>

 <span class="keyword">extern</span> <span class="type">LSymbol</span> <span class="variable-name">ISOMORPHIC</span>;
 <span class="type">void</span> <span class="function-name">LispInit_isomorphic</span>();

 <span class="keyword">static</span> <span class="type">LListConstructor</span> <span class="variable-name">L</span>;

 <span class="type">void</span> <span class="function-name">call_isomorph</span>(<span class="keyword">const</span> <span class="type">SReference</span> &amp;<span class="variable-name">l1</span>, <span class="keyword">const</span> <span class="type">SReference</span> &amp;<span class="variable-name">l2</span>)
 {
     <span class="type">SReference</span> <span class="variable-name">res</span> = (L|ISOMORPHIC, ~l1, ~l2).Evaluate();
     printf(<span class="string">"%s ~~ %s : %s\n"</span>,
            l1-&gt;TextRepresentation().c_str(),
            l2-&gt;TextRepresentation().c_str(),
            res-&gt;TextRepresentation().c_str());
 }

 <span class="type">int</span> <span class="function-name">main</span>(<span class="type">int</span> <span class="variable-name">argc</span>, <span class="type">char</span> *<span class="variable-name">argv</span>[])
 {
     LispInit_isomorphic();
     <span class="type">SReference</span> <span class="variable-name">ls1</span> = (L|(L|1, 2), 3, 4);         <span class="comment-delimiter">// </span><span class="comment">((1 2) 3 4)
</span>     <span class="type">SReference</span> <span class="variable-name">ls2</span> = (L|(L|<span class="string">"a"</span>, <span class="string">"b"</span>), <span class="string">"c"</span>, <span class="string">"d"</span>); <span class="comment-delimiter">// </span><span class="comment">(("a" "b") "c" "d")
</span>     <span class="type">SReference</span> <span class="variable-name">ls3</span> = (L|(L|1, 2), (L|3, 4));     <span class="comment-delimiter">// </span><span class="comment">((1 2) (3 4))
</span>     call_isomorph(ls1, ls2);
     call_isomorph(ls1, ls3);
     <span class="keyword">return</span> 0;
 }
 <span class="comment-delimiter">// </span><span class="comment">end of file
</span>
</pre>

Compiled with:

<pre>

 g++ -Wall -g isomorph.cpp main.cpp -lintelib -o isomorph && ./isomorph

</pre>

will produce:

<pre>

 ((1 2) 3 4) ~~ ((<span class="string">"a"</span> <span class="string">"b"</span>) <span class="string">"c"</span> <span class="string">"d"</span>) : T
 ((1 2) 3 4) ~~ ((1 2) (3 4)) : NIL

</pre>






<!-- ======================================================================== -->
<br><hr><br><a name="boehmgc">
<h2>Garbage Collection: BoehmGC</h2>

<p><a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/">BoehmGC</a>
is probably the most under-used piece of software worldwide.  It
should be included in any application written in C or C++.

</div>



<!--BOTTOM-BEGIN-->
<!-- This section is automatically generated by html-update, -->
<!-- from data in 'node.el'.    Please, do not edit it here. -->
<DIV CLASS="BOTTOM">
<hr><code><small>
 | <a href="http://www.informatimago.com//articles/life-saver.html">Mirror on informatimago.com</a>
 | <a href="http://informatimago.free.fr/i//articles/life-saver.html">Mirror on free.fr</a>
 | </small></code>

<BR><SMALL>
      <a href="http://validator.w3.org/check?uri=referer"><img
          src="http://www.w3.org/Icons/valid-html401"
          alt="Valid HTML 4.01!" height="31" width="88"></a>
   </SMALL>
</DIV>
<!--BOTTOM-END-->
</BODY>
</HTML>
ViewGit