Hi all! I'm using Clojure to generate java source (enums, specifically) and am looking for ideas.
Currently my generator consists of a collection of function which call each other tree-recursion-like. Input: Each function takes a map of input. Much of this is constant for any one run of the generator. Only a few of the leaf functions don't follow this convention and instead ask for exactly what they need. I hit on this solution as a way to avoid a lot of global state while at the same time not causing rippling changes in parameter lists every time some leaf procedure needs some extra bit of information. Output: Instead of printing directly to *out* or returning a String, I have all the functions return a sequence of values. The result of a run of the code generator is then initially a tree of things-that-can-be-made-into-strings, which I flatten and concatenate at the very end. Strings concatenate as themselves. Symbols and keywords as their (name). Class objects print as their fully qualified class name. BigDecimals are formatted as appropriate constructor calls. By not printing eagerly, I can revise the result of called procdures, e.g. by using interpose to insert commas between a sequence of fragments produce by another function or for comprehension. A small example: (defn getter [method field type] [" public " (unbox type) " " (name method) "() { return " (name field) "; }\n"]) Another: (defn constructor "Defines the enum's constructor. The constructor uses the arguments it is given to initialize all fields declared by (fields). Each (member) is a call to this constructor." [{:keys [class-name fields] :as cfg}] [" " class-name "(" (formal-params cfg) ") {\n" (statement-list (for [f fields] [" this." f " = " f ])) " }\n"]) Where: (defn statement-list [list] (concat (interpose ";\n" list) [";\n"])) The templating aspect of all this is solved with constructs Clojure already gives me (vectors and plain old clojure expressions), which is kind of nice. It's also reasonably friendly for exploratory testing and interactive development. Still, I'm not really happy with it. This works, OK, but it feels pretty hokey. Indentation is totally ad-hoc. I mean, it works, but I can't help but think that there must be a better way. I've had a few false starts trying to improve on this idea and am looking for a new approach. Currently I think I'd like a way to write/construct a *simple* parse-tree for a java subset as Clojure data along with some way to serialize this as syntactically correct Java. That sounds like a lot of work, maybe there's an easier way that I'm overlooking? // Ben -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en