]> git.donarmstrong.com Git - lilypond.git/commitdiff
rename to music-function
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Thu, 6 May 2004 21:37:32 +0000 (21:37 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Thu, 6 May 2004 21:37:32 +0000 (21:37 +0000)
ChangeLog
Documentation/user/programming-interface.itely
input/regression/music-head.ly
lily/include/music-function.hh [new file with mode: 0644]
lily/include/music-head.hh [deleted file]
lily/lexer.ll
lily/music-wrapper.cc
lily/parser.yy

index 6b1f9dea61802ebc9814649214cb9414cb618b33..7e6eac26e95e05cb1f8306c13bff060dde01534e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-05-06  Han-Wen Nienhuys   <hanwen@xs4all.nl>
+
+       * lily/parser.yy (Generic_prefix_music_scm): add more
+       music_function symbols.
+
+       * lily/include/music-function.hh: rename to music-function
+
 2004-05-05  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
        * lily/music-head.cc (LY_DEFINE): change order of args.
index 1f840e55c719cb98cf8ea0024440192bc9105fd6..75696a6f0effb1ac4de5cf496a03c8a99b04224b 100644 (file)
@@ -133,6 +133,33 @@ and @internalsref{GraceMusic} has its single argument in
 @code{element}. The body of a repeat is in @code{element} property of
 @internalsref{RepeatedMusic}, and the alternatives in @code{elements}.
 
+
+
+
+@node Extending music syntax
+@appendixsubsec Extending music syntax
+
+The syntax of composite music expressions, like
+@code{\repeat}, @code{\transpose} and @code{\context}
+follows the general form of
+
+@example
+  \@code{keyword} @var{non-music-arguments} @var{music-arguments}
+@end example
+
+Such syntax can also be defined as user code. To do this, it is
+necessary to create a @em{music function}. This is a specially marked
+Scheme function. For example, the music function @code{\apply} applies
+a user-defined function to a music expression.  Its syntax is
+
+@example
+\apply #@var{func} @var{music}
+@end example
+
+A music function is created with @code{ly:make-music-function}.
+
+
+
 @node Manipulating music expressions
 @appendixsubsec Manipulating music expressions
 
index 42a33c1553ef74196727317f2274d242eeb5725d..0c538b655cb79cc0504da9f1d5d218bcbd3cd30a 100644 (file)
@@ -1,13 +1,13 @@
 \header
 {
-texidoc = "Music heads are generic music transformation functions,
+texidoc = "Music function are generic music transformation functions,
 which can be used to extend music syntax seamlessly."
 
 }
 \version "2.3.1"
 
 #(define myBar
-  (ly:make-music-head
+  (ly:make-music-function
    (list string?)
    (lambda (where type)
     (context-spec-music
diff --git a/lily/include/music-function.hh b/lily/include/music-function.hh
new file mode 100644 (file)
index 0000000..cfc923f
--- /dev/null
@@ -0,0 +1,20 @@
+/* 
+  music-head.hh -- declare music_function
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  
+*/
+
+#ifndef MUSIC_FUNCTION_HH
+#define MUSIC_FUNCTION_HH
+
+#include "lily-guile.hh"
+
+SCM ly_make_music_function (SCM, SCM);
+SCM get_music_function_transform (SCM);
+bool is_music_function (SCM);
+
+#endif /* MUSIC_FUNCTION_HH */
+
diff --git a/lily/include/music-head.hh b/lily/include/music-head.hh
deleted file mode 100644 (file)
index b010c22..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* 
-  music-head.hh -- declare Music_head
-  
-  source file of the GNU LilyPond music typesetter
-  
-  (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
-  
-*/
-
-#ifndef MUSIC_HEAD_HH
-#define MUSIC_HEAD_HH
-
-#include "lily-guile.hh"
-
-SCM ly_make_music_head (SCM, SCM);
-SCM get_music_head_transform (SCM);
-bool is_music_head (SCM);
-
-#endif /* MUSIC_HEAD_HH */
-
index 506c047dbf0fcd20eee693c89a1c74afb57e5b43..aefd759995bbaac2ba879807abe18d94963c12a1 100644 (file)
@@ -32,7 +32,7 @@
 
 #include <iostream>
 using namespace std;
-#include "music-head.hh"
+#include "music-function.hh"
 #include "source-file.hh"
 #include "parse-scm.hh"
 #include "lily-guile.hh"
@@ -699,10 +699,11 @@ My_lily_lexer::scan_escaped_word (String str)
                return l;
        }
        SCM sid = lookup_identifier (str);
-       if (is_music_head (sid))
+       if (is_music_function (sid))
        {
-               yylval.scm = get_music_head_transform (sid); 
-               return music_head_type (yylval.scm);
+               yylval.scm = get_music_function_transform (sid);
+               
+               return music_function_type (yylval.scm);
        }
 
        if (sid != SCM_UNDEFINED)
@@ -889,31 +890,35 @@ lookup_markup_command (String s)
 
 
 int
-music_head_type (SCM func)
+music_function_type (SCM func)
 {
        SCM type= scm_object_property (func, ly_symbol2scm ("music-head-signature-keyword"));
        if (type == ly_symbol2scm ("scm"))
        {
-               return MUSIC_HEAD_SCM;
+               return MUSIC_FUNCTION_SCM;
        }
        else if (type == ly_symbol2scm ("music"))
        {
-               return MUSIC_HEAD_MUSIC;
+               return MUSIC_FUNCTION_MUSIC;
        }
        else if (type == ly_symbol2scm ("scm-music"))
        {
-               return MUSIC_HEAD_SCM_MUSIC;
+               return MUSIC_FUNCTION_SCM_MUSIC;
+       }
+       else if (type == ly_symbol2scm ("music-music"))
+       {
+               return MUSIC_FUNCTION_MUSIC_MUSIC;
        }
        else if (type == ly_symbol2scm ("scm-music-music"))
        {
-               return MUSIC_HEAD_SCM_MUSIC_MUSIC;
+               return MUSIC_FUNCTION_SCM_MUSIC_MUSIC;
        }
        else if (type == ly_symbol2scm ("scm-scm-music"))
        {
-               return MUSIC_HEAD_SCM_SCM_MUSIC;
+               return MUSIC_FUNCTION_SCM_SCM_MUSIC;
        }
        else
                assert (false);
 
-       return MUSIC_HEAD_SCM_MUSIC_MUSIC;
+       return MUSIC_FUNCTION_SCM_MUSIC_MUSIC;
 }
index b13d7fac608c3b63924d8fce5f367998acb3e28a..3eac65aec6f4688469611208c0d78cd1754ae089 100644 (file)
@@ -8,9 +8,8 @@
  */
 
 
-#include "music-wrapper.hh"
-
 
+#include "music-wrapper.hh"
 
 
 Music_wrapper::Music_wrapper ()
index 14d509f02753945789db98d7e9d553ebd798d104..898c2403cdaaa94d5ef941ffa5890d0c4a41de51 100644 (file)
@@ -359,19 +359,19 @@ or
 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
 
-%token <scm> MUSIC_HEAD_SCM 
-%token <scm> MUSIC_HEAD_MUSIC 
-%token <scm> MUSIC_HEAD_SCM_MUSIC 
-%token <scm> MUSIC_HEAD_MUSIC_MUSIC 
-%token <scm> MUSIC_HEAD_SCM_SCM_MUSIC 
-%token <scm> MUSIC_HEAD_SCM_MUSIC_MUSIC 
+%token <scm> MUSIC_FUNCTION_SCM 
+%token <scm> MUSIC_FUNCTION_MUSIC 
+%token <scm> MUSIC_FUNCTION_SCM_MUSIC 
+%token <scm> MUSIC_FUNCTION_MUSIC_MUSIC 
+%token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC 
+%token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC 
 
 %token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
 %type <scm> markup markup_line markup_list  markup_list_body full_markup
 
 %type <book>   book_block book_body
 %type <i>      exclamations questions dots optional_rest
-%type <i>       bass_mod
+%type <i>      bass_mod
 %type <scm>    grace_head
 %type <scm>    oct_check
 %type <scm>    context_mod_list
@@ -385,6 +385,7 @@ or
 %type <music>  toplevel_music
 %type <music>  simple_element event_chord command_element
 %type <music>  Composite_music Simple_music Prefix_composite_music Generic_prefix_music
+%type <scm>    Generic_prefix_music_scm 
 %type <music>  Grouped_music_list
 %type <music>  Repeated_music
 %type <scm>     Alternative_music
@@ -953,22 +954,78 @@ Grouped_music_list:
        | Sequential_music              { $$ = $1; }
        ;
 
+Generic_prefix_music_scm:
+       MUSIC_FUNCTION_SCM {
+               THIS->push_spot ();
+       } embedded_scm {
+               $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3);
+       }
+       | MUSIC_FUNCTION_MUSIC {
+               THIS->push_spot (); 
+       } Music {
+               $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3->self_scm ());
+               scm_gc_unprotect_object ($3->self_scm ());
+       }
+       | MUSIC_FUNCTION_SCM_MUSIC {
+               THIS->push_spot (); 
+       }  embedded_scm Music {
+               $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4->self_scm ());
+               scm_gc_unprotect_object ($4->self_scm ());
+       }
+       | MUSIC_FUNCTION_MUSIC_MUSIC {
+               THIS->push_spot (); 
+       }  Music  Music {
+               $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3->self_scm (), $4->self_scm ());
+               scm_gc_unprotect_object ($3->self_scm ());
+               scm_gc_unprotect_object ($4->self_scm ());
+       }
+       | MUSIC_FUNCTION_SCM_MUSIC_MUSIC {
+               THIS->push_spot (); 
+       } embedded_scm Music Music {
+               $$ = scm_list_5 ($1, make_input (THIS->pop_spot ()),
+                       $3, $4->self_scm (), $5->self_scm ());
+               scm_gc_unprotect_object ($5->self_scm ());
+               scm_gc_unprotect_object ($4->self_scm ());
+       }
+       ;
+
 Generic_prefix_music:
-       MUSIC_HEAD_SCM { THIS->push_spot (); } embedded_scm {
-               SCM m = scm_call_2 ($1, make_input (THIS->pop_spot ()),
-                       $3);
+       Generic_prefix_music_scm {
+               SCM func = ly_car ($1);
+               Input *loc = unsmob_input (ly_cadr ($1));
+               SCM args = ly_cddr ($1);
+               SCM sig = scm_object_property (func, ly_symbol2scm ("music-head-signature"));
+               int k = 0;
+               bool ok  = true; 
+               for (SCM s = sig, t = args;
+                       ok && ly_c_pair_p (s) && ly_c_pair_p (t);
+                       s = ly_cdr (s), t = ly_cdr (t)) {
+                       k++;
+                       if (scm_call_1 (ly_car (s), ly_car (t)) != SCM_BOOL_T)
+                       {
+                               loc->error (_f ("Argument %d failed typecheck", k));
+                               THIS->error_level_ = 1;
+                               ok = false;
+                       }
+               }
+               SCM m = SCM_EOL;
+               if (ok)
+                       m = scm_apply_0 (func, ly_cdr  ($1));
                if (unsmob_music (m))
-               {       $$ = unsmob_music (m);
+                       {
+                       $$ = unsmob_music (m);
                        scm_gc_protect_object (m);
-               }
+                       }
                else
-               {
-                       THIS->parser_error ("MUSIC_HEAD should return Music");
-                       $$ = MY_MAKE_MUSIC("Music");
-               }
+                       {
+                       loc->error (_ ("Music head function should return Music object.")); 
+                       $$ = MY_MAKE_MUSIC ("Music");
+                       }
+
        }
        ;
 
+
 Prefix_composite_music:
        Generic_prefix_music {
                $$ = $1;