]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4779: Accept isolated durations as music function arguments
authorDavid Kastrup <dak@gnu.org>
Thu, 25 Feb 2016 18:36:20 +0000 (19:36 +0100)
committerDavid Kastrup <dak@gnu.org>
Fri, 4 Mar 2016 11:37:16 +0000 (12:37 +0100)
lily/parser.yy

index ae00eb64a2b8c673af628161aa9674628063efa7..3e7625f45f8cafbbe578bfa803e2d2a4819bedbe 100644 (file)
@@ -347,7 +347,8 @@ If we give names, Bison complains.
 %token CHORD_REPETITION
 %token CONTEXT_MOD_IDENTIFIER
 %token DRUM_PITCH
-%token PITCH_IDENTIFIER
+ /* Artificial token for durations in argument lists */
+%token DURATION_ARG
 %token DURATION_IDENTIFIER
 %token EVENT_IDENTIFIER
 %token EVENT_FUNCTION
@@ -361,6 +362,7 @@ If we give names, Bison complains.
 %token MUSIC_IDENTIFIER
 %token NOTENAME_PITCH
 %token NUMBER_IDENTIFIER
+%token PITCH_IDENTIFIER
 %token REAL
 %token RESTNAME
 %token SCM_ARG
@@ -1760,6 +1762,10 @@ function_arglist_nonbackup:
        {
                $$ = check_scheme_arg (parser, @3, $3, $1, $2);
        }
+       | function_arglist_nonbackup_reparse REPARSE reparsed_rhythm
+       {
+               $$ = check_scheme_arg (parser, @3, $3, $1, $2);
+       }
        | function_arglist_nonbackup_reparse REPARSE bare_number_common
        {
                $$ = check_scheme_arg (parser, @3, $3, $1, $2);
@@ -1778,6 +1784,20 @@ function_arglist_nonbackup:
        }
        ;
 
+
+reparsed_rhythm:
+       DURATION_ARG dots multipliers post_events
+       {
+               $$ = make_music_from_simple (parser, @$,
+                                            make_duration ($1, scm_to_int ($2), $3));
+               Music *m = unsmob<Music> ($$);
+               assert (m);
+               if (scm_is_pair ($4))
+                       m->set_property ("articulations",
+                                        scm_reverse_x ($4, SCM_EOL));
+       } %prec ':'
+       ;
+
 function_arglist_nonbackup_reparse:
        EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER
        {
@@ -1852,18 +1872,34 @@ function_arglist_nonbackup_reparse:
        {
                $$ = $3;
                if (scm_is_true (scm_call_1 ($2, $4)))
+                       // May be 3 \cm or similar
                        MYREPARSE (@4, $2, REAL, $4);
                else {
                        SCM d = make_duration ($4);
-                       if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
-                               MYREPARSE (@4, $2, REAL, $4); // trigger error
-                       else
-                               MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
+                       if (!SCM_UNBNDP (d)) {
+                               if (scm_is_true (scm_call_1 ($2, d)))
+                                       MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
+                               else if (scm_is_true
+                                        (scm_call_1
+                                         ($2, make_music_from_simple (parser, @4, d))))
+                                       MYREPARSE (@4, $2, DURATION_ARG, d);
+                               else
+                                       MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error
+                       } else
+                               MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error
                }
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup DURATION_IDENTIFIER {
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup DURATION_IDENTIFIER
+       {
                $$ = $3;
-               MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
+               if (scm_is_true (scm_call_1 ($2, $4)))
+                       MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
+               else if (scm_is_true
+                        (scm_call_1
+                         ($2, make_music_from_simple (parser, @4, $4))))
+                       MYREPARSE (@4, $2, DURATION_ARG, $4);
+               else
+                       MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error
        }
        ;
 
@@ -1940,19 +1976,26 @@ function_arglist_backup:
        }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup UNSIGNED
        {
+               $$ = $3;
                if (scm_is_true (scm_call_1 ($2, $4)))
-               {
+                       // May be 3 \cm or similar
                        MYREPARSE (@4, $2, REAL, $4);
-                       $$ = $3;
-               } else {
+               else {
                        SCM d = make_duration ($4);
-                       if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
-                       {
+                       if (!SCM_UNBNDP (d)) {
+                               if (scm_is_true (scm_call_1 ($2, d)))
+                                       MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
+                               else if (scm_is_true
+                                        (scm_call_1
+                                         ($2, make_music_from_simple (parser, @4, d))))
+                                       MYREPARSE (@4, $2, DURATION_ARG, d);
+                               else {
+                                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
+                                       MYBACKUP (UNSIGNED, $4, @4);
+                               }
+                       } else {
                                $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                                MYBACKUP (UNSIGNED, $4, @4);
-                       } else {
-                               MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
-                               $$ = $3;
                        }
                }
        }
@@ -2019,11 +2062,14 @@ function_arglist_backup:
        }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup DURATION_IDENTIFIER
        {
+               $$ = $3;
                if (scm_is_true (scm_call_1 ($2, $4)))
-               {
                        MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
-                       $$ = $3;
-               } else {
+               else if (scm_is_true
+                        (scm_call_1
+                         ($2, make_music_from_simple (parser, @4, $4))))
+                       MYREPARSE (@4, $2, DURATION_ARG, $4);
+               else {
                        $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (DURATION_IDENTIFIER, $4, @4);
                }
@@ -2078,6 +2124,11 @@ function_arglist_backup:
                $$ = check_scheme_arg (parser, @3,
                                       $3, $1, $2);
        }
+       | function_arglist_backup REPARSE reparsed_rhythm
+       {
+               $$ = check_scheme_arg (parser, @3,
+                                      $3, $1, $2);
+       }
        | function_arglist_backup REPARSE symbol_list_arg
        {
                $$ = check_scheme_arg (parser, @3, $3, $1, $2);
@@ -2209,6 +2260,11 @@ function_arglist_common:
                $$ = check_scheme_arg (parser, @3,
                                       $3, $1, $2);
        }
+       | function_arglist_common_reparse REPARSE reparsed_rhythm
+       {
+               $$ = check_scheme_arg (parser, @3,
+                                      $3, $1, $2);
+       }
        | function_arglist_common_reparse REPARSE symbol_list_arg
        {
                $$ = check_scheme_arg (parser, @3, $3, $1, $2);
@@ -2292,19 +2348,34 @@ function_arglist_common_reparse:
        {
                $$ = $2;
                if (scm_is_true (scm_call_1 ($1, $3)))
+                       // May be 3 \cm or similar
                        MYREPARSE (@3, $1, REAL, $3);
                else {
                        SCM d = make_duration ($3);
-                       if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($1, d)))
-                               MYREPARSE (@3, $1, REAL, $3);
-                       else
-                               MYREPARSE (@3, $1, DURATION_IDENTIFIER, d);
+                       if (!SCM_UNBNDP (d)) {
+                               if (scm_is_true (scm_call_1 ($1, d)))
+                                       MYREPARSE (@3, $1, DURATION_IDENTIFIER, d);
+                               else if (scm_is_true
+                                        (scm_call_1
+                                         ($1, make_music_from_simple (parser, @3, d))))
+                                       MYREPARSE (@3, $1, DURATION_ARG, d);
+                               else
+                                       MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error
+                       } else
+                               MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error
                }
        }
        | EXPECT_SCM function_arglist_optional DURATION_IDENTIFIER
        {
                $$ = $2;
-               MYREPARSE (@3, $1, DURATION_IDENTIFIER, $3);
+               if (scm_is_true (scm_call_1 ($1, $3)))
+                       MYREPARSE (@3, $1, DURATION_IDENTIFIER, $3);
+               else if (scm_is_true
+                        (scm_call_1
+                         ($1, make_music_from_simple (parser, @3, $3))))
+                       MYREPARSE (@3, $1, DURATION_ARG, $3);
+               else
+                       MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error
        }
        | EXPECT_SCM function_arglist_optional '-' UNSIGNED
        {