RE: code generation for other languages
| The tricky | bit will be, as you say, defining a data structure that is "just" | general enough. Just start with the simplest thing which allows you to do what you want to do, and extend it as needed. The other approach -- trying to envision everything you might need and building it in at the start -- sounds to me like a black hole. But then I am a lazy (functional) programmer :) J
RE: code generation for other languages
For doinjg this sort of thing I have used asdl before which I find really useful. -Original Message- From: Manuel M. T. Chakravarty [mailto:[EMAIL PROTECTED]] Sent: 23 August 2000 14:09 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: code generation for other languages Jeffrey Straszhiem [EMAIL PROTECTED] wrote, On Wed, Aug 23, 2000 at 12:26:38PM +1000, Timothy Docker wrote: I'm writing a haskell program that generates C++ code based upon some haskell data structures. At the moment, the code is somewhat ugly with lots of stuff like mutatorDef structName (name,vtype) = "inline void\n" ++ structName ++ "::" ++ (mutatorName name) ++ "( " ++ (cppParamType vtype) ++ " v ) {\n" ++ "" ++ (storageName name) ++ " = v;\n" ++ "}\n\n" All those ++ operators working on raw strings bug me, and manually getting the indentation correct is a pain. Is there a more functional approach to generating source code? I thought this could be a common enough task that there could be a library, but a perusal of haskell.org didn't seem to show anything relevant. To make matters worse, you're likely getting lousy efficiency with all of the ++ operators. Look through the code for showS in the Prelude for better ways to hook strings together. Paul Hudak talks about the efficient use of the show functions at: http://www.haskell.org/tutorial/stdclasses.html Now, with regard to the code being ugly, my suggestion would be to check out some of the pretty printer libraries out there, and to look through them. They basically solve a similar problem, except they first parse a normal program into a tree, then flatten the tree in a standard way. In your case you'll likely build the tree directly, then call the final stages of the pretty printer. There is no shortage of pretty printer libraries for Haskell, or for FP in general. The canonical approach is to define an internal data structure that represents C++ code, then let your mutator functions generate values of that data type (instead of strings), and finally pretty print values of this C++ data structure. That's cleaner and more flexible than the ++ cascades (or the show equivalent). Depending on how restricted and/or idiomatic the generate C++ code is, it makes sense to not have a data structure that can represent arbitrary C++ programs, but only a subset that is relevant for the code generation task at hand. So, you might want functions like mutatorDef :: ... - AbstractCPlusPlus prettyPrintACPP :: AbstractCPlusPlus - String Cheers, Manuel
Re: code generation for other languages
Manuel M. T. Chakravarty writes: The canonical approach is to define an internal data structure that represents C++ code, then let your mutator functions generate values of that data type (instead of strings), and finally pretty print values of this C++ data structure. That's cleaner and more flexible than the ++ cascades (or the show equivalent). Depending on how restricted and/or idiomatic the generate C++ code is, it makes sense to not have a data structure that can represent arbitrary C++ programs, but only a subset that is relevant for the code generation task at hand. So, you might want functions like mutatorDef :: ... - AbstractCPlusPlus prettyPrintACPP :: AbstractCPlusPlus - String Thanks for the clear description (and to Julian Seward who also suggested such an approach). Alfter playing with the code a little more, I had actually already started down this approach. The tricky bit will be, as you say, defining a data structure that is "just" general enough. Tim
Re: code generation for other languages
On Wed, Aug 23, 2000 at 12:26:38PM +1000, Timothy Docker wrote: I'm writing a haskell program that generates C++ code based upon some haskell data structures. At the moment, the code is somewhat ugly with lots of stuff like mutatorDef structName (name,vtype) = "inline void\n" ++ structName ++ "::" ++ (mutatorName name) ++ "( " ++ (cppParamType vtype) ++ " v ) {\n" ++ "" ++ (storageName name) ++ " = v;\n" ++ "}\n\n" All those ++ operators working on raw strings bug me, and manually getting the indentation correct is a pain. Is there a more functional approach to generating source code? I thought this could be a common enough task that there could be a library, but a perusal of haskell.org didn't seem to show anything relevant. To make matters worse, you're likely getting lousy efficiency with all of the ++ operators. Look through the code for showS in the Prelude for better ways to hook strings together. Paul Hudak talks about the efficient use of the show functions at: http://www.haskell.org/tutorial/stdclasses.html Now, with regard to the code being ugly, my suggestion would be to check out some of the pretty printer libraries out there, and to look through them. They basically solve a similar problem, except they first parse a normal program into a tree, then flatten the tree in a standard way. In your case you'll likely build the tree directly, then call the final stages of the pretty printer. There is no shortage of pretty printer libraries for Haskell, or for FP in general. Hope this helps, at least a little :) -- -- Jeffrey Straszheim | A sufficiently advanced -- Systems Engineer, Programmer| regular expression is -- http://www.shadow.net/~stimuli | indistinguishable from -- stimuli AT shadow DOT net | magic