[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: hash/backslash confusion
Re: hash/backslash confusion
Thu, 13 Aug 2009 15:41:25 -0600
On 8/13/09 2:42 PM, "Mark Polesky" <address@hidden> wrote:
> Carl Sorensen wrote:
>> This is *exactly* the same issue.
> Is it accurate to say that the parser is a LilyPond interpreter in
> the same sense that guile is a scheme interpreter? If so, is it
> also accurate to say that the parser temporarily hands over
> control to guile when it sees the # operator? It gets confusing
> for me because, IIUC the parser interfaces with guile even when
> there are no # expressions in the .ly file.
I don't think it is. In LilyPond there is a lexer and a parser (and I
couldn't give you a good description of what each of them do). I *think*
the lexer actuallly scans the input character string, and converts it into
tokens that the parser handles. But I may be way off in this explanation.
Again, at the risk of being told to "Use the source, Luke", I'll give you my
mental model. The lexer/parser combination scans through the whole file,
setting up global variables, contexts, and music expressions. During this
stage, only the Scheme relating to parsing is executed. The rest is put
into a music expression, waiting to be evaluated when the iterator tells the
translator/engravor to do its work.
So if you think of a LilyPond source file as a guile source file, you'll be
mistaken. In particular, it's easy to tell, even for a relatively
complicated source file, when a particular scheme expression will be handled
by a repl. The execution order is governed directly by the Scheme
In the LilyPond source file, with multiple layers of stuff happening, it
takes a deep understanding of the internal workings to tell exactly when a
Scheme expression is going to be evaluated. And I'm still a bit fuzzy on
this point, but I know enough to generally make it work.
> But the way I see it, something like a single quote (') is
> interpreted as "up an octave" in the parser but interpreted as
> the (quote ...) procedure in guile.
Yes, that is correct.
> I'm guessing something is wrong with my understanding because the
> hash (#) doesn't appear anywhere in the "LilyPond grammar",
> appendix, and I'm thinking of it as a unary operator meaning
> "interpret the following as a scheme-expression using guile".
Almost, but not quite. # tells LilyPond that the next item is a Scheme
object, not a LilyPond object. But it is not necessarily evaluated at this
time. LilyPond will do whatever it needs to do with that Scheme object, but
the LilyPond *parser* does not interpret it. At the point that the Scheme
object is to be evaluated, it will be evaluated by the guile interpreter,
often through guile calls in c++ engraver modules.
My mental cartoon model of the LilyPond parser is that of a really good
administrative assistant who has the task of handling the mail in an
executive office: Open up every envelope and see what it contains, then put
it into a box for later processing by somebody who has the authority to
handle the mail. Once all the mail has been opened and sorted, then deliver
the mail to the people who will actually do the work of responding to the
In this model, Scheme (or guile) is *not* one of the people who receives the
mail to work on. Iterators, engravers, and translators work on the mail.
Sometimes they need help, so they get it from guile. guile does specific
parts of the work at the request of the engravers and translators, as they
request the work to be done. Iterators make sure that the work gets done in
the proper sequence by scheduling the tasks of the engravers and
I don't know if any of this is helpful, or if it just confuses things
further, but it's the way I've come to understand LilyPond processing.