]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 3814: Allow context definitions to be provided by scheme functions
authorDavid Kastrup <dak@gnu.org>
Wed, 15 Jan 2014 20:13:34 +0000 (21:13 +0100)
committerDavid Kastrup <dak@gnu.org>
Fri, 24 Jan 2014 13:51:18 +0000 (14:51 +0100)
Also obliterates CONTEXT_DEF_IDENTIFIER

lily/parser.yy

index ccc87218f2e64b517a5fb3600608beb93e147357..4b063960d66e6d16b486c03a1098d1641da05414 100644 (file)
@@ -332,7 +332,6 @@ If we give names, Bison complains.
 %token BOOK_IDENTIFIER
 %token CHORD_MODIFIER
 %token CHORD_REPETITION
-%token CONTEXT_DEF_IDENTIFIER
 %token CONTEXT_MOD_IDENTIFIER
 %token DRUM_PITCH
 %token PITCH_IDENTIFIER
@@ -675,9 +674,14 @@ identifier_init_nonumber:
 
 context_def_spec_block:
        CONTEXT '{' context_def_spec_body '}'
-               {
+       {
                $$ = $3;
-               unsmob_context_def ($$)->origin ()->set_spot (@$);
+               Context_def *td = unsmob_context_def ($$);
+               if (!td) {
+                       $$ = Context_def::make_scm ();
+                       td = unsmob_context_def ($$);
+               }
+               td->origin ()->set_spot (@$);
        }
        ;
 
@@ -695,47 +699,54 @@ context_mod_arg:
        }
        ;
 
-context_mod_embedded:
-       context_mod_arg
-       {
-               if (unsmob_music ($1)) {
-                       SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
-                       $1 = scm_call_2 (proc, parser->self_scm (), $1);
-               }
-               if (unsmob_context_mod ($1))
-                       $$ = $1;
-               else {
-                       parser->parser_error (@1, _ ("not a context mod"));
-                       $$ = Context_mod ().smobbed_copy ();
-               }
-       }
-       ;
-
 
 context_def_spec_body:
        /**/ {
-               $$ = Context_def::make_scm ();
-       }
-       | CONTEXT_DEF_IDENTIFIER {
-               $$ = $1;
+               $$ = SCM_UNSPECIFIED;
        }
        | context_def_spec_body context_mod {
-               if (!SCM_UNBNDP ($2))
+               if (!SCM_UNBNDP ($2)) {
+                       Context_def *td = unsmob_context_def ($$);
+                       if (!td) {
+                               $$ = Context_def::make_scm ();
+                               td = unsmob_context_def ($$);
+                       }
                        unsmob_context_def ($$)->add_context_mod ($2);
+               }
        }
        | context_def_spec_body context_modification {
                 Context_def *td = unsmob_context_def ($$);
+               if (!td) {
+                       $$ = Context_def::make_scm ();
+                       td = unsmob_context_def ($$);
+               }
                 SCM new_mods = unsmob_context_mod ($2)->get_mods ();
                 for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) {
                     td->add_context_mod (scm_car (m));
                 }
        }
-       | context_def_spec_body context_mod_embedded {
-                Context_def *td = unsmob_context_def ($$);
-                SCM new_mods = unsmob_context_mod ($2)->get_mods ();
-                for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) {
-                    td->add_context_mod (scm_car (m));
-                }
+       | context_def_spec_body context_mod_arg {
+               Context_def *td = unsmob_context_def ($1);
+               if (scm_is_eq ($2, SCM_UNSPECIFIED))
+                       ;
+               else if (!td && unsmob_context_def ($2))
+                       $$ = $2;
+               else {
+                       if (!td) {
+                               $$ = Context_def::make_scm ();
+                               td = unsmob_context_def ($$);
+                       }
+                       if (unsmob_music ($2)) {
+                               SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
+                               $2 = scm_call_2 (proc, parser->self_scm (), $2);
+                       }
+                       if (Context_mod *cm = unsmob_context_mod ($2)) {
+                               for (SCM m = cm->get_mods (); scm_is_pair (m); m = scm_cdr (m)) {
+                                       td->add_context_mod (scm_car (m));
+                               }
+                       } else
+                               parser->parser_error (@2, _ ("not a context mod"));
+               }
        }
        ;
 
@@ -1332,9 +1343,19 @@ context_mod_list:
                  if (md)
                      unsmob_context_mod ($1)->add_context_mods (md->get_mods ());
         }
-       | context_mod_list context_mod_embedded {
-               unsmob_context_mod ($1)->add_context_mods
-                       (unsmob_context_mod ($2)->get_mods ());
+       | context_mod_list context_mod_arg {
+               if (scm_is_eq ($2, SCM_UNSPECIFIED))
+                       ;
+               else if (unsmob_music ($2)) {
+                       SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
+                       $2 = scm_call_2 (proc, parser->self_scm (), $2);
+               }
+               if (unsmob_context_mod ($2))
+                       unsmob_context_mod ($$)->add_context_mods
+                               (unsmob_context_mod ($2)->get_mods ());
+               else {
+                       parser->parser_error (@2, _ ("not a context mod"));
+               }
         }
         ;
 
@@ -3613,16 +3634,12 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
        } else if (scm_is_number (sid)) {
                *destination = sid;
                return NUMBER_IDENTIFIER;
-        } else if (unsmob_context_def (sid)) {
-                Context_def *def= unsmob_context_def (sid)->clone ();
-
-                *destination = def->self_scm ();
-                def->unprotect ();
-
-                return CONTEXT_DEF_IDENTIFIER;
+       } else if (unsmob_context_def (sid))
+       {
+               *destination = unsmob_context_def (sid)->clone ()->unprotect ();
+               return SCM_IDENTIFIER;
         } else if (unsmob_context_mod (sid)) {
                 *destination = unsmob_context_mod (sid)->smobbed_copy ();
-
                 return CONTEXT_MOD_IDENTIFIER;
        } else if (Music *mus = unsmob_music (sid)) {
                mus = mus->clone ();