lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Scheme function to print out active Voice context during interpretat


From: Carl D. Sorensen
Subject: Re: Scheme function to print out active Voice context during interpretation?
Date: Mon, 15 Dec 2008 15:27:51 -0700



On 12/15/08 3:12 PM, "Trevor Bača" <address@hidden> wrote:

> On Mon, Dec 15, 2008 at 2:09 PM, Han-Wen Nienhuys <address@hidden> wrote:
>> On Mon, Dec 15, 2008 at 5:25 PM, Carl D. Sorensen <address@hidden> wrote:
>>>> 
>>>> 
>>>> 
>>>> On 12/15/08 7:18 AM, "Han-Wen Nienhuys" <address@hidden> wrote:
>>>> 
>>>> 
>>>>>> Try not to form mental models.  Use the source instead.
>>>> 
>>>> Unfortunately, not very many of us understand the source completely, and so
>>>> we need mental models to work in LilyPond.  Of course, our mental models
>>>> will be incorrect in some detail, and we'll need to revise them from time
>>>> >> to
>>>> time.
>> 
>> sure, but if you spend a lot of time and effort on theorizing (like
>> Trevor did), you might as well invest that time & effort into looking
>> at the source code itself.
> 
> I think both are good: wanton speculation taken together with digging through
> source.
> 
> :-)
> 
> I've been digging through source this morning ... and I'm understanding much
> better ... but still unable to resolve at least one example, which I've
> included at the end of this message.
> 
> What I've found so far:
> 
> * There are 22 -iterator.cc files with Music_iterator being the base class
> from which the others all directly (or, more usually, indirectly) inherit.
> (Simple_music_iterator, Music_wrapper_iterator and Sequential_iterator are all
> popular choices to derive from, too, but all three inherit from Music_iterator
> at base.) Concrete iterators exist to iterate over regular stuff like
> EventChord and and 'simple music' (which parser.yy makes me think means
> basically notes and rests). Iterators also exist to iterate over more complex
> music expressions like grace music, time-scaled music, voltas, and music
> expressions passed to the \unfold command. My understanding of this flock of
> iterators available in the C++ source is as a type of realization of the
> visitor pattern that separates traversal from other activities like
> calculation and modification.
> 
> * Additionally, both the comments at the head of music-iterator.hh and Erik's
> thesis make it clear that the object over which the different iterators
> iterate is a (conceptual) queue of music events *that all happen at the same
> moment*. That is, when it comes time to iterate, the first thing that happens
> is that the entire context tree (starting from the Global context and
> proceeding all the way to bottom-level voice contexts) are *prepared* for
> Moment 0; then iterators iterate over all events that happen at Moment 0 *no
> matter at which level of the context tree those different events occur*. This
> helps because I was assuming (wrongly) earlier that iteration would be a
> depth-first search starting from the root of the expression tree; if that were
> the case then each context would be visited before any of its children. But,
> in fact, section 9.4 of Erik's thesis says "One of the consequences of a
> OneTimeStep stream event, is that all contexts are visited in a post-order
> tree walk; i.e., each context is visited after all its children have been
> visited." I haven't been able to verify this in the code, however.
> 
> * I've also found that a pronouncement like "\new Voice { c'4 }" is actually
> THREE expressions. The "\new Voice" is actually a music expression all by
> itself (of type ContextSpeccedMusic). There is a
> Context_specced_music_iterator defined in an eponymous .cc file and inheriting
> from Music_wrapper_iterator. The purpose of the Context_specced_music_iterator
> is to descend to the one (and only one) child that each ContextSpeccedMusic
> like "\new Voice" music have: something like Sequential is the usual option.
> So the parser (which I only understand vaguely) decomposes "\new Voice { c'4
> }" into three expressions with "\new Voice" parsed as ContextSpeccedMusic,
> with "{ }" parsed as Sequential, with "c'4" parsed as EventChord (I think).
> Further, the parser builds the resulting music expression such that
> ContextSpeccedMusic is the parent of Sequential which is, in turn, the parent
> of EventChord.
> 
> * Also, all parsing is done before any iteration is done.
> 
> * OK, so based on this understanding, can somebody please correct my
> understanding of the parsing (not the iteration, just the parsing) of the
> following expression (which is the same as my original example #2):
> 
>   {
>     \new Voice {
>       c'8 c'8 c'8 c'8
>     }
>     d'8 d'8 d'8 d'8
>   }
> 
> If I'm understanding how the parser works, then what should result here is a
> music expression that looks like this:
> 
>                  Global
>                     V
>                \new Score
>                     V
>                \new Staff
>                     V
>                \new Voice
>                     V
>                 Sequential
>                     V
>     \new Voice, d'8, d'8, d'8, d'8
>        V
>     Sequential
>        V
> c'8, c'8, c'8, c'8
> 
> 
> If I'm counting correctly, that's 15 total nodes in the expression tree. Eight
> atomic nodes and seven internal nodes. The Global, \new Score, \new Staff and
> the first \new Voice are all created implicitly.
> 
> I know that the next part in the process is iteration. But I want to stop and
> check my understanding here: am I understanding the output of the parser
> correctly at this point?
> 
> 
> Trevor.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]