lilypond-devel
[Top][All Lists]
Advanced

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

Music functions with pitch and duration arguments (was: Creates a glissa


From: David Kastrup
Subject: Music functions with pitch and duration arguments (was: Creates a glissando stem grob that uses stems' functionality. (issue4777044))
Date: Fri, 22 Jul 2011 03:01:59 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

address@hidden writes:

> http://codereview.appspot.com/4777044/diff/7001/input/regression/glissando-stem.ly
> File input/regression/glissando-stem.ly (right):
>
> http://codereview.appspot.com/4777044/diff/7001/input/regression/glissando-stem.ly#newcode10
> input/regression/glissando-stem.ly:10: \xenakisStem #(ly:make-duration
> 3) #32
> This should be a music function, possibly incorporating the \glissando
> for the initial note.

Well, putting aside the issue at point (where an interesting solution
accepting music in a reasonably natural manner has been proposed), I
find it excruciatingly ugly to specify arguments as #(ly:make-duration
... or #(ly:make-pitch ...

So I tried out a patch that will accept pitches (via signature
ly:pitch?) and durations (signature ly:duration?) as music function
arguments.  Durations are not accepted everywhere since that would lead
to an awful number of shift/reduce conflicts.  There _are_ combinations
of music arguments and durations that can't be resolved otherwise (since
durations are often optional at the end of music), so there is a reason
for it.  Nevertheless, there is no error recovery built in right now, so
if you really cook up a forbidden music function signature (say
ly:music? ly:duration?) and call the respective function, Lilypond will
barf out with something like

/tmp/test.ly:4:5: error: syntax error, unexpected EXPECT_DURATION

Apart from the error recovery problem for bad music/duration
combinations in the signature, the patch would appear to work as
expected.  I am not sure whether the current situation is not already
susceptible to imprudent signatures triggering syntax errors.

Anyway, this is not particularly complex either.  Could possibly pave
the way for a nicer function for setting up strings for tabulatures.
Also stuff like \transpose can be implemented by users with a
straightforward syntax accepting just pitches where pitches are asked
for, without the user needing to disassemble music in order to get at
the pitch somewhere in the center of the mess.

What do people think?  I've not yet bothered with markup, though things
like \note would be better off taking a duration argument rather than an
integer.

diff --git a/lily/include/duration.hh b/lily/include/duration.hh
index 003b9e8..69ac487 100644
--- a/lily/include/duration.hh
+++ b/lily/include/duration.hh
@@ -56,5 +56,7 @@ private:
 INSTANTIATE_COMPARE (Duration, Duration::compare);
 DECLARE_UNSMOB (Duration, duration);
 
+extern SCM Duration_type_p_proc;
+
 #endif // DURATION_HH
 
diff --git a/lily/include/pitch.hh b/lily/include/pitch.hh
index 1ef59f3..df829b2 100644
--- a/lily/include/pitch.hh
+++ b/lily/include/pitch.hh
@@ -106,5 +106,6 @@ INSTANTIATE_COMPARE (Pitch, Pitch::compare);
 
 extern SCM pitch_less_proc;
 Pitch pitch_interval (Pitch const &from, Pitch const &to);
+extern SCM Pitch_type_p_proc;
 
 #endif /* PITCH_HH */
diff --git a/lily/lexer.ll b/lily/lexer.ll
index 8824182..83a7940 100644
--- a/lily/lexer.ll
+++ b/lily/lexer.ll
@@ -46,6 +46,7 @@
 using namespace std;
 
 #include "context-def.hh"
+#include "duration.hh"
 #include "identifier-smob.hh"
 #include "international.hh"
 #include "interval.hh"
@@ -58,6 +59,7 @@ using namespace std;
 #include "music-function.hh"
 #include "parse-scm.hh"
 #include "parser.hh"
+#include "pitch.hh"
 #include "source-file.hh"
 #include "std-string.hh"
 #include "string-convert.hh"
@@ -794,11 +796,17 @@ Lily_lexer::scan_escaped_word (string str)
                push_extra_token (EXPECT_NO_MORE_ARGS);
                for (; scm_is_pair (s); s = scm_cdr (s))
                {
-                       if (scm_car (s) == ly_music_p_proc)
+                       SCM cs = scm_car (s);
+                       
+                       if (cs == ly_music_p_proc)
                                push_extra_token (EXPECT_MUSIC);
-                       else if (scm_car (s) == ly_lily_module_constant 
("markup?"))
+                       else if (cs == Pitch_type_p_proc)
+                               push_extra_token (EXPECT_PITCH);
+                       else if (cs == Duration_type_p_proc)
+                               push_extra_token (EXPECT_DURATION);
+                       else if (cs == ly_lily_module_constant ("markup?"))
                                push_extra_token (EXPECT_MARKUP);
-                       else if (ly_is_procedure (scm_car (s)))
+                       else if (ly_is_procedure (cs))
                                push_extra_token (EXPECT_SCM);
                        else programming_error ("Function parameter without 
type-checking predicate");
                }
diff --git a/lily/parser.yy b/lily/parser.yy
index 9b46bfe..057a0e8 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -270,6 +270,8 @@ If we give names, Bison complains.
 /* Artificial tokens, for more generic function syntax */
 %token <i> EXPECT_MARKUP;
 %token <i> EXPECT_MUSIC;
+%token <i> EXPECT_PITCH;
+%token <i> EXPECT_DURATION;
 %token <i> EXPECT_SCM;
 %token <i> EXPECT_MARKUP_LIST
 /* After the last argument. */
@@ -1081,6 +1083,9 @@ function_arglist_nonmusic_last:
        | EXPECT_MARKUP function_arglist simple_string {
                $$ = scm_cons ($3, $2);
        }
+       | EXPECT_PITCH function_arglist pitch {
+               $$ = scm_cons ($3, $2);
+       }
        | EXPECT_SCM function_arglist function_scm_argument {
                $$ = scm_cons ($3, $2);
        }
@@ -1095,6 +1100,12 @@ function_arglist_nonmusic: EXPECT_NO_MORE_ARGS {
        | EXPECT_MARKUP function_arglist_nonmusic simple_string {
                $$ = scm_cons ($3, $2);
        }
+       | EXPECT_PITCH function_arglist_nonmusic pitch {
+               $$ = scm_cons ($3, $2);
+       }
+       | EXPECT_DURATION function_arglist_nonmusic duration_length {
+               $$ = scm_cons ($3, $2);
+       }
        | EXPECT_SCM function_arglist_nonmusic function_scm_argument {
                $$ = scm_cons ($3, $2);
        }

-- 
David Kastrup

reply via email to

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