<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Mar 4, 2013, at 4:23 PM, Juan Jose Garcia-Ripoll <<a href="mailto:juanjose.garciaripoll@gmail.com">juanjose.garciaripoll@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr">On Mon, Mar 4, 2013 at 5:30 PM, Christian Schafmeister <span dir="ltr"><<a href="mailto:chris.schaf@verizon.net" target="_blank">chris.schaf@verizon.net</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">I've created a new implementation of Common Lisp that has a core written in C++ completely from scratch but hosts the ECL Common Lisp source code.<br>
</blockquote><div><br></div><div style="">Sounds like a lot of work.</div></div></div></div></blockquote><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
It hosts all of the ECL Common Lisp code in the ecl/src/lsp and ecl/src/clos directories of the ECL source tree.<br>
I do not use any part of the ECL CL->C compiler or the byte code compiler.<br>
I've implemented my own CL interpreter and CL->LLVM-IR->native code compiler.<br></blockquote><div><br></div><div style="">I do not understand why you reimplemented the interpreter, but the LLVM thingy looks interesting.</div></div></div></div></blockquote><div><br></div>I needed a CL interpreter which would host the compiler (which I wrote in Common Lisp) which calls the LLVM-IR library to generate llvm::Module objects which contains llvm::Function objects that are Just-In-Time compiled into machine code and called via C function pointers from the Common Lisp or C++ code. </div><div>I did not want to write a Common Lisp compiler in C++ (shudder).</div><div>This project started as an archaic Sexp walking Lisp interpreter that grew into a very slow Common Lisp Sexp walking interpreter within which I wrote a reasonably fast self-hosting Common Lisp compiler that generates LLVM-IR.</div><div><br></div><div><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">
<div style=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">It's purpose is to make possible the seamless interfacing of C++ libraries with Common Lisp code and vice versa.<br>
Within this new implementation it is trivial to interface complex C++ libraries containing classes, virtual functions, overloaded functions etc with Common Lisp code.<br></blockquote><div><br></div><div style="">Sorry, but I do not understand this. There are different things in interfacing Common-Lisp with C++, and none of them requires building a new compiler or a LLVM backend.</div></div></div></div></blockquote><div><br></div><div>I didn't know that when I started. I know that now - the bridge doesn't require the compiler and LLVM backend </div><div>- the CL/C++ bridge is all C++ template programming, lots and lots of template programming. </div><div>It's styled after the boost::python library if you are familiar with it.</div><div>Once I started writing the compiler and exposing and using the LLVM backend I just kept going.</div><div>Although, having intimate familiarity with the Common Lisp implementation I wrote has greatly facilitated the development of the bridge.</div><div><br></div><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Why - you ask? I'd be happy to explain over a beer or coffee sometime.<br>
In a nutshell - I want this for my research and prior to my writing it there was no Common Lisp implementation that interfaces seamlessly with C++.<br>
ECL does a great job with "C" but "C++" is a much more complex language to interface with and I have a lot of C++ code that I need to interface with.</blockquote><div><br></div><div style="">If you state that ECL cannot interface with C++ I would like to see that statement backed with examples. EQL is one example that interfacing is not impossible and, probably, not that hard once you can write C++ inside Common Lisp code.</div></div></div></div></blockquote><div><br></div>I did not state that ECL cannot interface with C++ - I know better than that. </div><div><br></div><div>On the other hand, I need it to be very easy to interface CL to C++ because I have a lot of C++ and nothing I saw in the CL world seemed to do the job.</div><div><br></div><div>Now if I want to interface a C++ function foo(int x, double y) to CL I add the following code to my C++ code.</div><div><br></div><div>af_def("CORE","foo",&foo);</div><div><br></div><div>Or the macro:</div><div>Defun(foo);</div><div><br></div><div>That's it for simple cases. If the function needs lambda-list processing then it is:</div><div>af_def("CORE","foo",&foo,"(x y &optional (z 999))");</div><div><br></div><div>That specifies the package, the function-name in CL, the pointer to the function and the lambda-list as a string which is parsed and associated with the wrapper for the function.</div><div><br></div><div>If I want to expose the C++ class Foo with method Foo::bar (default lambda-list processing) and Foo::baz (lambda-list processing) I currently copy-and-paste-and-edit a wrapper class Foo_O into a header file (I should be able to eliminate the need for this with more template programming) and I add the following to my C++ code.</div><div><br></div><div>class_<Foo_O>()</div><div> .def("bar",&Foo::bar)</div><div> .def("baz",&Foo::baz,"(a b &key (gamma (+ a b) gamma-p))")</div><div>;</div><div><br></div><div>That's it for this simple example. Different function arity, lambda-list processing, argument type-conversion, result-conversion, memory-management, multiple and single inheritance, virtual-function handling is all done automatically with C++ template programming.</div><div><br></div><div>We could get it to work with ECL as well if you want it - although it's going to take some work.</div><div>Then we could incorporate the LLVM-IR generating compiler into ECL.</div><div><br></div><div><br></div><div><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div style=""><br></div><div style="">But most important, the issue of interfacing Common Lisp and C++ consists on many different problems that I do not see how you solve at the same time with the help of LLVM</div><div style="">
<br>
</div><div style="">1. Integrating the C++ type system and the Common Lisp one</div><div style="">2. Being able to call C++ functions from Common Lisp and viceversa</div><div style="">3. Integrating C++ and Common Lisp memory management</div>
<div style="">4. Possibly automating the generation of wrappers for C++ code.</div><div style="">5. Resolving overloading at runtime instead of at compilation time.</div><div style="">...</div><div style=""><br></div><div style="">Many issues, some of which are mentioned in SWIG, <a href="http://www.swig.org/Doc1.3/SWIGPlus.html">http://www.swig.org/Doc1.3/SWIGPlus.html</a> but even many of which they (working long in the interface between C++ and dynamic languages) do not have an answer to.</div></div></div></div></blockquote><div><br></div>SWIG ran out of steam for me pretty early on. </div><div><div><br></div>I've had to develop solutions to all of these problems - so I'm familiar with them.</div><div><br></div><div>1) C++ classes behave like CL structures.</div><div>2) C++ functions calling CL and vice versa is taken care of.</div><div>3) Memory management is currently handled using reference counted C++ shared_ptr/weak_ptr. I plan to add mark-and-sweep GC later.</div><div>4) Virtual functions, regular functions and overloaded functions are all handles. When you have overloaded functions with different types you have to disambiguate them by getting a pointer to each function. There is no way to avoid this.</div><div><br></div><div><br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div style="">Juanjo</div><div><br></div>-- <br>Instituto de Física Fundamental, CSIC<br>c/ Serrano, 113b, Madrid 28006 (Spain) <br><a href="http://juanjose.garciaripoll.googlepages.com/" target="_blank">http://juanjose.garciaripoll.googlepages.com</a>
</div></div>
</blockquote></div><br></body></html>