<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jan 8, 2014 at 2:44 AM, Manuel Klimek <span dir="ltr"><<a href="mailto:klimek@google.com" target="_blank" class="cremed">klimek@google.com</a>></span> wrote:<br>
<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"><div dir="ltr">+Sam, who has written the dynamic registry stuff for ideas...</div>
<div class=""><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 7, 2014 at 7:50 PM, Christian Schafmeister <span dir="ltr"><<a href="mailto:chris.schaf@verizon.net" target="_blank" class="cremed">chris.schaf@verizon.net</a>></span> wrote:<br>

<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"><div style="word-wrap:break-word"><br><div><div><div><div>
On Jan 7, 2014, at 12:59 PM, Manuel Klimek <<a href="mailto:klimek@google.com" target="_blank" class="cremed">klimek@google.com</a>> wrote:</div>
<br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Jan 7, 2014 at 6:52 PM, Christian Schafmeister <span dir="ltr"><<a href="mailto:chris.schaf@verizon.net" target="_blank" class="cremed">chris.schaf@verizon.net</a>></span> wrote:<br>


<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"><div style="word-wrap:break-word"><br><div><div><div>On Jan 7, 2014, at 12:12 PM, Manuel Klimek <<a href="mailto:klimek@google.com" target="_blank" class="cremed">klimek@google.com</a>> wrote:</div>


<br></div><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">


<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>On Tue, Jan 7, 2014 at 5:16 PM, Christian Schafmeister<span> </span><span dir="ltr"><<a href="mailto:chris.schaf@verizon.net" target="_blank" class="cremed">chris.schaf@verizon.net</a>></span><span> </span>wrote:<br>


<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"><div style="word-wrap:break-word"><div>Hey folks,</div><div>


<br></div><div><br></div><div>I’ve written a new Common Lisp environment/compiler over the past two years.  </div><div>It uses LLVM as the back-end (by exposing the LLVM C++ library to Common Lisp) and interoperates with C++ in that it has a template library like boost::python for exposing arbitrary C++ classes/functions to Common Lisp.  </div>


<div><br></div><div>I want to do some automated refactoring to improve my C++ code so I’m exposing the Clang ASTMatcher and Refactoring libraries.</div><div><br></div><div>I also think it would be really cool to write refactoring tools in a dynamic language like Lisp - without all the exhausting boilerplate required by the C++ approach.</div>


</div></blockquote><div><br></div></div><div>C++ refactoring tools actually don't require that much boilerplate… </div></div></div></div></div></blockquote><div><br></div>Sorry, my statement sounded like a criticism - I never mean to criticize - these languages are what they are. </div>


</div></blockquote><div><br></div><div>No worries, I have no problems with criticism - and I didn't take it that way. My remark was really just meant as that - I think writing a refactoring tool has suprisingly little overhead. The main problem is actually compilation, which is why I'd be very interested in seeing more interpreted integrations.</div>


<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"><div style="word-wrap:break-word"><div>I was just speaking about my feelings from writing a few simple refactoring tools in C++ and my motivations for implementing a Common Lisp compiler and writing refactoring tools in Common Lisp.  I’m a new convert to Common Lisp - I just discovered it two years ago and most of my experience with it is writing a self-hosting compiler.</div>


<div><br></div><div><br></div><div><div><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">


<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">


<div style="word-wrap:break-word"><div>So I’m exposing the Clang AST library to this Common Lisp environment with the goal of writing a general tool for writing C++ refactoring tools in Common Lisp.</div><div><br></div><div>


My goal is to mimic C++ ASTMatchers like:</div><div><b style="color:rgb(34,34,34)"><br></b></div><div><b style="color:rgb(34,34,34)">recordDecl(hasDescendant(</b></div><div><b style="color:rgb(34,34,34)">   <span> </span>ifStmt(hasTrueExpression(</b></div>


<div><b style="color:rgb(34,34,34)">       <span> </span>expr(hasDescendant(</b></div><div><b style="color:rgb(34,34,34)">           <span> </span>ifStmt()))))))</b></div><div><br></div><div>Using S-expressions: <b>(record-decl (has-descendent (if-stmt (has-true-expression (expr (has-descendant( if-stmt))))))) </b>   </div>


<div><br></div><div>And the source-to-source translation code will be small lambda functions that use the resulting MatchResults.</div><div><br></div><div>That way I don’t have to write a lot of documentation :-).</div><div>


<br></div><div>Currently I’m looking at calling the ASTMatcher/Dynamic/VariantValue interface to build ASTMatchers from S-expressions - does that sound like a good idea - or is there a better approach I should be exploring?</div>


</div></blockquote><div><br></div><div>Well, if your boost shim can already match "arbitrary C++ classes / functions", then it should in principle be able to expose the AST matchers as is (without the need to go through the dynamic parsing).</div>


<div>After all, the matchers are mostly just template functions :)</div></div></div></div></div></blockquote><div><br></div></div>I was trying to figure out how to do that at first but the ASTMatchers looked more exotic than just simple functions.</div>


<div><br></div><div>For instance “namedDecl” has the type internal::VariadicDynCastAllOfMatcher<Decl,NamedDecl></div><div><div>VariadicDynCastAllOfMatcher is defined as:</div><div><br></div><div>template <typename SourceT, typename TargetT></div>


<div>class VariadicDynCastAllOfMatcher</div><div>    : public llvm::VariadicFunction<</div><div>        BindableMatcher<SourceT>, Matcher<TargetT>,</div><div>        makeDynCastAllOfComposite<SourceT, TargetT> > {</div>


<div>public:</div><div>  VariadicDynCastAllOfMatcher() {}</div><div>};</div></div><div><br></div><div>llvm::VariadicFunction has many templated overloads of "operator()"</div><div>I haven’t written template code to automatically wrap variadic functions (as in functions that take … ellipses).</div>


<div><br></div><div>I can wrap functions that take ArrayRef’s though - is there a function like namedDecl(ArrayRef<ASTMatcher>) for ASTMatchers?</div><div><br></div><div>I’ve only been getting deep into C++ template programming for about two months so I’m still struggling with reading complex template code.</div>


</div></blockquote><div><br></div><div>Yes, I'd actually be suprised if this was possible without major jump-through-hooping - the problem is that the compiler generates the template code only when they get instantiated - so unless you have a backend that takes the lisp code and generates C++ code from that that integrates with the template code, I wouldn't know how to do it (and that round-trip would seem like it kills a lot of the benefits of having lisp in the first place - after all, you'd still get crappy C++ error messages :P)</div>

</div></div></div></blockquote><div><br></div></div></div>Agreed.   </div><div><br></div><div>Maybe the best way to do this is to write a Registry class like the one in Dynamic/Registry.h and define “constructMatcher” and “constructBoundMatcher” that take Lisp symbols and assemble VariantMatchers that way.</div>
</div></blockquote></div></div></div></div></blockquote><div><br></div><div><div>Most of them are simple functions, but there are also a lot that are "polymorphic". That is, they return a proxy type that allows late binding of the real matcher type.</div>
<div>During the implementation of the dynamic matcher registry I changed all these polymorphic/adaptative types to provide extra type information that allowed the registry to instantiate all the required functions.</div></div>
<div><br></div><div>What about this?</div><div>Instead of wrapping the actual matchers the way it is done in C++, you could make meta matchers that really only know their name and their arguments.</div><div>Basically all matchers would be functions that return an object that has a name() method and a list of their arguments.<br>
</div><div><div>Then you can generate the C++ matcher string and use the C++ matcher parser to generate the actual matcher.</div></div><div>This way you only wrap a few [simple] functions from C++ and are shielded from the template metaprogramming craziness.</div>
<div>Hadn't thought this through, so it might be too simple to work =P.</div><div><br></div><div>_Sam</div><div><br></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">
<div class=""><div class="h5"><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">
<div style="word-wrap:break-word">
<div><div><br></div><div><br></div><div><br></div><div><br></div><div><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">
<div><br></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"><div style="word-wrap:break-word"><div><div>

<br></div><div><br></div><div><br></div><div><br>
<blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">


<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>Otherwise I think going the dynamic matcher route is a good approach.</div><div><br></div><div>Cheers,</div><div>/Manuel</div></div></div>


</div></div></blockquote></div><br></div></div></blockquote></div><br></div></div>
</blockquote></div><br></div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div></div>