]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/parser.yy
Merge tag 'upstream/2.18.2' into debian
[lilypond.git] / lily / parser.yy
index f6baee2096eeb0fbcdf78a8bfa08f73ba4b5d993..8a7f4675d4bf004c792284b5e22698bc76a87308 100644 (file)
 #define YYLLOC_DEFAULT(Current,Rhs,N) \
        ((Current).set_location ((Rhs)[1], (Rhs)[N]))
 
-#define YYPRINT(file, type, value)                                      \
-        do {                                                            \
-                if (scm_is_eq (value, SCM_UNSPECIFIED))                 \
-                        break;                                          \
-                char *p = scm_to_locale_string                          \
-                        (scm_simple_format (SCM_BOOL_F,                 \
-                                            scm_from_locale_string ("~S"), \
-                                            scm_list_1 (value)));       \
-                fputs (p, file);                                        \
-                free (p);                                               \
-        } while (0)
+#define YYPRINT(file, type, value)                                     \
+       do {                                                            \
+               if (scm_is_eq (value, SCM_UNSPECIFIED))                 \
+                       break;                                          \
+               SCM s = scm_call_2 (ly_lily_module_constant ("value->lily-string"), \
+                                   value,                              \
+                                   parser->self_scm ());               \
+               char *p = scm_to_locale_string (s);                     \
+               fputs (p, file);                                        \
+               free (p);                                               \
+       } while (0)
 
 %}
 
@@ -406,6 +406,13 @@ toplevel_expression:
                SCM proc = parser->lexer_->lookup_identifier ("toplevel-bookpart-handler");
                scm_call_2 (proc, parser->self_scm (), $1);
        }
+       | BOOK_IDENTIFIER {
+               SCM proc = parser->lexer_->lookup_identifier
+                       (unsmob_book($1)->paper_
+                        ? "toplevel-book-handler"
+                        : "toplevel-bookpart-handler");
+               scm_call_2 (proc, parser->self_scm (), $1);
+       }
        | score_block {
                SCM proc = parser->lexer_->lookup_identifier ("toplevel-score-handler");
                scm_call_2 (proc, parser->self_scm (), $1);
@@ -424,7 +431,7 @@ toplevel_expression:
        }
        | SCM_TOKEN {
                // Evaluate and ignore #xxx, as opposed to \xxx
-               parser->lexer_->eval_scm_token ($1);
+               parser->lexer_->eval_scm_token ($1, @1);
        }
        | embedded_scm_active
        {
@@ -437,6 +444,10 @@ toplevel_expression:
                {
                        SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
                        scm_call_2 (proc, parser->self_scm (), out);
+               } else if (unsmob_score ($1))
+               {
+                       SCM proc = parser->lexer_->lookup_identifier ("toplevel-score-handler");
+                       scm_call_2 (proc, parser->self_scm (), $1);
                } else if (!scm_is_eq ($1, SCM_UNSPECIFIED))
                        parser->parser_error (@1, _("bad expression type"));
        }
@@ -458,7 +469,7 @@ toplevel_expression:
 embedded_scm_bare:
        SCM_TOKEN
        {
-               $$ = parser->lexer_->eval_scm_token ($1);
+               $$ = parser->lexer_->eval_scm_token ($1, @1);
        }
        | SCM_IDENTIFIER
        ;
@@ -472,7 +483,7 @@ embedded_scm_bare_arg:
        SCM_ARG
        | SCM_TOKEN
        {
-               $$ = parser->lexer_->eval_scm_token ($1);
+               $$ = parser->lexer_->eval_scm_token ($1, @1);
        }
        | FRACTION
        | full_markup_list
@@ -740,7 +751,7 @@ book_body:
        }
        | book_body SCM_TOKEN {
                // Evaluate and ignore #xxx, as opposed to \xxx
-               parser->lexer_->eval_scm_token ($2);
+               parser->lexer_->eval_scm_token ($2, @2);
        }
        | book_body embedded_scm_active
        {
@@ -753,6 +764,10 @@ book_body:
                {
                        SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
                        scm_call_2 (proc, $1, out);
+               } else if (unsmob_score ($2))
+               {
+                       SCM proc = parser->lexer_->lookup_identifier ("book-score-handler");
+                       scm_call_2 (proc, $1, $2);
                } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
                        parser->parser_error (@2, _("bad expression type"));
        }
@@ -806,7 +821,7 @@ bookpart_body:
        }
        | bookpart_body SCM_TOKEN {
                // Evaluate and ignore #xxx, as opposed to \xxx
-               parser->lexer_->eval_scm_token ($2);
+               parser->lexer_->eval_scm_token ($2, @2);
        }
        | bookpart_body embedded_scm_active
        {
@@ -819,6 +834,10 @@ bookpart_body:
                {
                        SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
                        scm_call_2 (proc, $1, out);
+               } else if (unsmob_score ($2))
+               {
+                       SCM proc = parser->lexer_->lookup_identifier ("bookpart-score-handler");
+                       scm_call_2 (proc, $1, $2);
                } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
                        parser->parser_error (@2, _("bad expression type"));
        }
@@ -838,27 +857,69 @@ bookpart_body:
 
 score_block:
        SCORE '{' score_body '}'        {
+               unsmob_score ($3)->origin ()->set_spot (@$);
                $$ = $3;
        }
        ;
 
+score_headers:
+       /* empty */
+       {
+               $$ = SCM_EOL;
+       }
+       | score_headers
+       {
+               if (!scm_is_pair ($1)
+                   || !ly_is_module (scm_car ($1)))
+                       $1 = scm_cons (ly_make_module (false), $1);
+               parser->lexer_->add_scope (scm_car ($1));
+       } lilypond_header
+       {
+               $$ = $1;
+       }
+       | score_headers output_def
+       {
+                Output_def *od = unsmob_output_def ($2);
+               if (od->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
+               {
+                       parser->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
+
+               }
+               else
+               {
+                       if (scm_is_pair ($1) && ly_is_module (scm_car ($1)))
+                               scm_set_cdr_x ($1, scm_cons ($2, scm_cdr ($1)));
+                       else
+                               $$ = scm_cons ($2, $1);
+               }
+       }
+       ;
+
+               
+
 score_body:
-       music {
+       score_headers music {
                SCM scorify = ly_lily_module_constant ("scorify-music");
-               $$ = scm_call_2 (scorify, $1, parser->self_scm ());
+               $$ = scm_call_2 (scorify, $2, parser->self_scm ());
 
-               unsmob_score ($$)->origin ()->set_spot (@$);
+               if (scm_is_pair ($1) && ly_is_module (scm_car ($1)))
+               {
+                       unsmob_score ($$)->set_header (scm_car ($1));
+                       $1 = scm_cdr ($1);
+               }
+               for (SCM p = scm_reverse_x ($1, SCM_EOL);
+                    scm_is_pair (p); p = scm_cdr (p))
+               {
+                       unsmob_score ($$)->
+                               add_output_def (unsmob_output_def (scm_car (p)));
+               }
        }
        | embedded_scm_active {
-               Score *score;
-               if (unsmob_score ($1))
-                       score = new Score (*unsmob_score ($1));
-               else {
-                       score = new Score;
+               if (!unsmob_score ($1))
+               {
+                       $$ = (new Score)->unprotect ();
                        parser->parser_error (@1, _("score expected"));
                }
-               unsmob_score ($$)->origin ()->set_spot (@$);
-               $$ = score->unprotect ();
        }
        | score_body
        {
@@ -2622,6 +2683,7 @@ chord_body_element:
 music_function_chord_body:
        music_function_call
        | MUSIC_IDENTIFIER
+       | embedded_scm
        ;
 
 // Event functions may only take closed arglists, otherwise it would
@@ -3524,6 +3586,7 @@ simple_markup:
                SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
                parser->lexer_->push_note_state (nn);
        } '{' score_body '}' {
+               unsmob_score ($4)->origin ()->set_spot (@$);
                $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $4);
                parser->lexer_->pop_state ();
        }
@@ -3615,6 +3678,9 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
                *destination = p->self_scm ();
                p->unprotect ();
                return OUTPUT_DEF_IDENTIFIER;
+       } else if (unsmob_score (sid)) {
+               *destination = unsmob_score (sid)->clone ()->unprotect ();
+               return SCM_IDENTIFIER;
        }
 
        return -1;