On Jul 7, 2006, at 7:16 PM, David Balmain wrote:
This is just an idea, but it might be worth doing away with the DSL
idea and just doing it all in C
I'd thought about that. And thanks for your implementation, which is
nicely done. It has the advantage of a simple main program, to be
sure. The downsides are A) it's hard to get your head around writing
C code which writes C code which writes C code (argh, *when* does
that macro get expanded?), and B) it's kind of noisy, because
embedding C source code in printf's and C quoted strings involves a
lot of escaping. Streamlining the main app is a Good Thing, but I
think using pure C will make module-writing harder and more error-prone.
One way we can limit ourselves to a single layer of indirection is to
make the .charm files be data files, with delimited snippets of C
code. The Charmonizer application would then process the .charm file
record by record. In fact, that was the original idea (proposed as
"Configurator").
However, some of the routines in these modules are going to be very
repetitive -- if you were to spelunk Perl's Configure script, you'd
see what I mean. We'll want to abstract out some functions so that
we obey the principle of DRY. OK, then, how do we indicate what kind
of record we have, and thus what function should be used to process
it? We add another field which holds the name of the function.
At this point, our data file is starting to look like a program. But
one with awkward syntax. Sorta like programming in CSV:
"printf", "Hello, %s!\n", "\"world\""
What's more, we still need a parser for that data file.
From this point, it's a short, nimble leap to your excellent
suggestion of a DSL. We expend some energy up-front writing and
testing a slightly more sophisticated parser, and then programming,
debugging, and maintaining the modules gets easier.
My current goal with Charmonizer is to define the language API in as
forward-compatible a way as possible. I'm happy with everything
except the quoting mechanism.
It occurred to me that it wouldn't be back-compatible later to add in
support for escapes in a string surrounded by single quotes, because
this would be treated differently:
'a backslash: \'
So, I think I'll add interpolation of backslashes and single quotes,
so that Charmonizer's singly-quoted strings behave like those in Perl
and Ruby. That's not that hard.
The other thing I'm not perfectly happy with is the CH_q operator.
Here's my idea for a replacement:
/* "\nMarvin's literal text\n" */
q'DELIMITER'
Marvin's literal text
DELIMITER
Sort of a combination of here docs and the q operator in Perl (%q
operator in Ruby). We could also add support for here docs, but here
docs are fragile and quirky. The one advantage here docs have over
this construct, other than familiarity, is that they automatically
begin on the next line, which makes things slightly cleaner if you
don't want to begin with a newline:
/* Charmonizer string equivalent to "\nSalutations, earthlings!\n" */
q'DELIMITER'
Salutations, earthlings!
DELIMITER
# Perl here doc equivalent to "Salutations, earthlings!\n"
<<'DELIMITER'
Salutations, earthlings!
DELIMITER
/* Charmonizer string equivalent to "Salutations, earthlings!\n" */
q'DELIMITER'Salutations, earthlings!
DELIMITER
However, 1) I prefer the conceptual consistency and robustness of the
modified q operator, 2) we certainly won't care about the extra
newline for the C fragments we're writing, 3) I think that in
general, the extra newline would rarely turn out to be a problem, 4)
when it does turn out to be a problem, the solution looks a little
funny but is easy to understand, and 5) here docs and this operator
are equally lousy for indenting (but again, it doesn't matter for us).
So, off to finish the parser...
Marvin Humphrey
Rectangular Research
http://www.rectangular.com/