Let's write a compiler for MUS. What does a compiler do? A compiler transforms a program from one language (the source language) into an equivalent program in another language (the target language). The most common kind of compiler translates from a high-level language such as C++ into a low-level language such as assembly.
The made-up language NOTE will be our assembly language for music. Programs in NOTE are lists of notes with pitches, start times, and durations. Here is what a few notes in a row looks like.
The above program plays the note
'a3' at time 0 for 250 ms.
Then at time 250 ms the note
'a3' ends and the note
At time 500 ms the note
'b3' ends and the last note starts.
Finally after 1000 ms the song ends.
Why bother with the NOTE language? One nice thing about programs in NOTE is that each note is independent of the others. When you see a note, you can immediately tell when it starts and stops. You don't need to look at other parts of the song to figure out when the note will play. So in that sense it is "lower level" than the MUS language.
The first step of writing a compiler from MUS songs into NOTE songs is to figure out how long MUS songs last. This function will help us piece songs together into NOTE format.
Here's our example abstract syntax tree for reference.
Write a function
endTime that takes a start time
time in milliseconds and
a MUS expression
expr starts playing at time
the function should return the time when
You will need your solution later, copy it down somewhere for reference.