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

Reply via email to