From ade7a425af75448ef0116928bceb65d339bf09ef Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Thu, 6 May 2004 21:37:32 +0000 Subject: [PATCH] rename to music-function --- ChangeLog | 7 ++ .../user/programming-interface.itely | 27 ++++++ input/regression/music-head.ly | 4 +- lily/include/music-function.hh | 20 +++++ lily/include/music-head.hh | 20 ----- lily/lexer.ll | 27 +++--- lily/music-wrapper.cc | 3 +- lily/parser.yy | 89 +++++++++++++++---- 8 files changed, 146 insertions(+), 51 deletions(-) create mode 100644 lily/include/music-function.hh delete mode 100644 lily/include/music-head.hh diff --git a/ChangeLog b/ChangeLog index 6b1f9dea61..7e6eac26e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-05-06 Han-Wen Nienhuys + + * 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 * lily/music-head.cc (LY_DEFINE): change order of args. diff --git a/Documentation/user/programming-interface.itely b/Documentation/user/programming-interface.itely index 1f840e55c7..75696a6f0e 100644 --- a/Documentation/user/programming-interface.itely +++ b/Documentation/user/programming-interface.itely @@ -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 diff --git a/input/regression/music-head.ly b/input/regression/music-head.ly index 42a33c1553..0c538b655c 100644 --- a/input/regression/music-head.ly +++ b/input/regression/music-head.ly @@ -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 index 0000000000..cfc923f720 --- /dev/null +++ b/lily/include/music-function.hh @@ -0,0 +1,20 @@ +/* + music-head.hh -- declare music_function + + source file of the GNU LilyPond music typesetter + + (c) 2004 Han-Wen Nienhuys + +*/ + +#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 index b010c2278b..0000000000 --- a/lily/include/music-head.hh +++ /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 - -*/ - -#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 */ - diff --git a/lily/lexer.ll b/lily/lexer.ll index 506c047dbf..aefd759995 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -32,7 +32,7 @@ #include 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; } diff --git a/lily/music-wrapper.cc b/lily/music-wrapper.cc index b13d7fac60..3eac65aec6 100644 --- a/lily/music-wrapper.cc +++ b/lily/music-wrapper.cc @@ -8,9 +8,8 @@ */ -#include "music-wrapper.hh" - +#include "music-wrapper.hh" Music_wrapper::Music_wrapper () diff --git a/lily/parser.yy b/lily/parser.yy index 14d509f027..898c2403cd 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -359,19 +359,19 @@ or %token MARKUP_HEAD_SCM0_SCM1_SCM2 %token MARKUP_HEAD_SCM0_SCM1_MARKUP2 -%token MUSIC_HEAD_SCM -%token MUSIC_HEAD_MUSIC -%token MUSIC_HEAD_SCM_MUSIC -%token MUSIC_HEAD_MUSIC_MUSIC -%token MUSIC_HEAD_SCM_SCM_MUSIC -%token MUSIC_HEAD_SCM_MUSIC_MUSIC +%token MUSIC_FUNCTION_SCM +%token MUSIC_FUNCTION_MUSIC +%token MUSIC_FUNCTION_SCM_MUSIC +%token MUSIC_FUNCTION_MUSIC_MUSIC +%token MUSIC_FUNCTION_SCM_SCM_MUSIC +%token MUSIC_FUNCTION_SCM_MUSIC_MUSIC %token MARKUP_IDENTIFIER MARKUP_HEAD_LIST0 %type markup markup_line markup_list markup_list_body full_markup %type book_block book_body %type exclamations questions dots optional_rest -%type bass_mod +%type bass_mod %type grace_head %type oct_check %type context_mod_list @@ -385,6 +385,7 @@ or %type toplevel_music %type simple_element event_chord command_element %type Composite_music Simple_music Prefix_composite_music Generic_prefix_music +%type Generic_prefix_music_scm %type Grouped_music_list %type Repeated_music %type 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; -- 2.39.2