]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/parser.yy
Merge remote-tracking branch 'origin/master' into translation
[lilypond.git] / lily / parser.yy
index 4eb488a37f53fed2e4a34e3a944b629e3352c49f..0804ce575b59f240ff3b43fcd1487ad7c9511fe0 100644 (file)
@@ -224,7 +224,7 @@ SCM get_next_unique_lyrics_context_id ();
 
 static Music *make_music_with_input (SCM name, Input where);
 SCM check_scheme_arg (Lily_parser *parser, Input loc,
-                     SCM arg, SCM args, SCM pred);
+                     SCM arg, SCM args, SCM pred, SCM disp = SCM_UNDEFINED);
 SCM make_music_from_simple (Lily_parser *parser, Input loc, SCM pitch);
 SCM loc_on_music (Input loc, SCM arg);
 SCM make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list);
@@ -1236,11 +1236,8 @@ function_arglist_nonbackup_common:
                else {
                        Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
                        t->set_property ("digit", $5);
-                       $$ = t->unprotect ();
-                       if (scm_is_true (scm_call_1 ($2, $$)))
-                               $$ = scm_cons ($$, $3);
-                       else
-                               $$ = check_scheme_arg (parser, @4, n, $3, $2);
+                       $$ = check_scheme_arg (parser, @4, t->unprotect (),
+                                              $3, $2, n);
                }
                
        }
@@ -1270,27 +1267,21 @@ function_arglist_closed_nonbackup:
        }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist SCM_IDENTIFIER
        {
-               SCM res = try_string_variants ($2, $4);
-               if (SCM_UNBNDP (res))
-                       $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-               else
-                       $$ = scm_cons (res, $3);
+               $$ = check_scheme_arg (parser, @4,
+                                      try_string_variants ($2, $4),
+                                      $3, $2, $4);
        }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist STRING
        {
-               SCM res = try_string_variants ($2, $4);
-               if (SCM_UNBNDP (res))
-                       $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-               else
-                       $$ = scm_cons (res, $3);
+               $$ = check_scheme_arg (parser, @4,
+                                      try_string_variants ($2, $4),
+                                      $3, $2, $4);
        }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist LYRICS_STRING
        {
-               SCM res = try_string_variants ($2, $4);
-               if (SCM_UNBNDP (res))
-                       $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-               else
-                       $$ = scm_cons (res, $3);
+               $$ = check_scheme_arg (parser, @4,
+                                      try_string_variants ($2, $4),
+                                      $3, $2, $4);
        }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist lyric_markup
        {
@@ -3535,14 +3526,34 @@ get_next_unique_lyrics_context_id ()
        return scm_from_locale_string (s);
 }
 
+// check_scheme_arg checks one argument with a given predicate for use
+// in an argument list and throws a syntax error if it is unusable.
+// The argument is prepended to the argument list in any case.  After
+// throwing a syntax error, the argument list is terminated with #f as
+// its last cdr in order to mark it as uncallable while not losing
+// track of its total length.
+//
+// There are a few special considerations: if optional argument disp
+// is given (otherwise it defaults to SCM_UNDEFINED), it will be used
+// instead of arg in a prospective error message.  This is useful if
+// arg is not the actual argument but rather a transformation of it.
+//
+// If arg itself is SCM_UNDEFINED, the predicate is considered false
+// and an error message using disp is produced unconditionally.
+
 SCM check_scheme_arg (Lily_parser *parser, Input loc,
-                     SCM arg, SCM args, SCM pred)
+                     SCM arg, SCM args, SCM pred, SCM disp)
 {
-       args = scm_cons (arg, args);
-       if (scm_is_true (scm_call_1 (pred, arg)))
-               return args;
+       if (SCM_UNBNDP (arg))
+               args = scm_cons (disp, args);
+       else {
+               args = scm_cons (arg, args);
+               if (scm_is_true (scm_call_1 (pred, arg)))
+                       return args;
+       }
        scm_set_cdr_x (scm_last_pair (args), SCM_EOL);
-       MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred, arg);
+       MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred,
+                    SCM_UNBNDP (disp) ? arg : disp);
        scm_set_cdr_x (scm_last_pair (args), SCM_BOOL_F);
        return args;
 }
@@ -3631,17 +3642,19 @@ make_music_from_simple (Lily_parser *parser, Input loc, SCM simple)
        if (unsmob_music (simple))
                return simple;
        if (parser->lexer_->is_note_state ()) {
-               Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
-               n->set_property ("duration", parser->default_duration_.smobbed_copy ());
-               if (scm_is_symbol (simple))
+               if (scm_is_symbol (simple)) {
+                       Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
+                       n->set_property ("duration", parser->default_duration_.smobbed_copy ());
                        n->set_property ("drum-type", simple);
-               else if (unsmob_pitch (simple))
+                       return n->unprotect ();
+               }
+               if (unsmob_pitch (simple)) {
+                       Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
+                       n->set_property ("duration", parser->default_duration_.smobbed_copy ());
                        n->set_property ("pitch", simple);
-               else {
-                       n->unprotect ();
-                       return simple;
+                       return n->unprotect ();
                }
-               return n->unprotect ();
+               return simple;
        } else if (parser->lexer_->is_lyric_state ()) {
                if (Text_interface::is_markup (simple))
                        return MAKE_SYNTAX ("lyric-event", loc, simple,