From: Han-Wen Nienhuys Date: Thu, 6 May 2004 22:16:17 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: release/2.3.1~20 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=e996beffe0f799b42f88fe6635d8e8f089ad3233;p=lilypond.git *** empty log message *** --- diff --git a/ChangeLog b/ChangeLog index 7e6eac26e9..d3f87d5d00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,10 @@ 2004-05-06 Han-Wen Nienhuys + * ly/music-functions-init.ly (TODO): new file. + * lily/parser.yy (Generic_prefix_music_scm): add more music_function symbols. + (Prefix_composite_music): change \apply to music-function * lily/include/music-function.hh: rename to music-function diff --git a/Documentation/user/programming-interface.itely b/Documentation/user/programming-interface.itely index 75696a6f0e..e5d06e7853 100644 --- a/Documentation/user/programming-interface.itely +++ b/Documentation/user/programming-interface.itely @@ -1,3 +1,4 @@ +@c -*-texinfo-*- @node Interfaces for programmers @appendix Interfaces for programmers @@ -5,16 +6,17 @@ @menu * Programmer interfaces for input :: -* Markup programmer interface:: -* Contexts for programmers:: +* Markup programmer interface:: +* Contexts for programmers:: @end menu @node Programmer interfaces for input @appendixsec Programmer interfaces for input @menu -* Input variables and Scheme:: +* Input variables and Scheme:: * Internal music representation:: +* Extending music syntax:: * Manipulating music expressions:: @end menu @@ -156,8 +158,41 @@ a user-defined function to a music expression. Its syntax is \apply #@var{func} @var{music} @end example -A music function is created with @code{ly:make-music-function}. +A music function is created with @code{ly:make-music-function}, +@example + (ly:make-music-function +@end example + +@code{\apply} takes a Scheme function and a Music expression as +argument. This is encoded in its first argument, + +@example + (list procedure? ly:music?) +@end example + +The function itself takes another argument, an Input location +object. That object is used to provide error messages with file names +and line numbers. The definition is the second argument of +@code{ly:make-music-function}. The body is function simply calls the +function + +@example + (lambda (where func music) + (func music)) +@end example + +The above Scheme code only defines the functionality. The tag +@code{\apply} is selected by defining + +@example + apply = #(ly:make-music-function + (list procedure? ly:music?) + (lambda (where func music) + (func music))) +@end example + +Examples of the use of @code{\apply} are in the next section. @node Manipulating music expressions @@ -259,7 +294,7 @@ LilyPond input to other formats (@inputfileref{input/test,to-xml.ly}) @menu * Markup construction in scheme:: -* Markup command definition:: +* Markup command definition:: @end menu @node Markup construction in scheme @@ -482,7 +517,7 @@ to the @code{interpret-markup} function, with the @code{paper} and @menu -* Context evaluation:: +* Context evaluation:: * Running a function on all layout objects:: @end menu diff --git a/input/regression/music-function.ly b/input/regression/music-function.ly new file mode 100644 index 0000000000..0c538b655c --- /dev/null +++ b/input/regression/music-function.ly @@ -0,0 +1,25 @@ +\header +{ +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-function + (list string?) + (lambda (where type) + (context-spec-music + (context-spec-music (make-property-set 'whichBar type) 'Timing) + 'Score)) + + )) + +\score{ + \notes { + d4 \myBar #"|:" d4 + + } +} + diff --git a/input/regression/music-head.ly b/input/regression/music-head.ly deleted file mode 100644 index 0c538b655c..0000000000 --- a/input/regression/music-head.ly +++ /dev/null @@ -1,25 +0,0 @@ -\header -{ -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-function - (list string?) - (lambda (where type) - (context-spec-music - (context-spec-music (make-property-set 'whichBar type) 'Timing) - 'Score)) - - )) - -\score{ - \notes { - d4 \myBar #"|:" d4 - - } -} - diff --git a/lily/lexer.ll b/lily/lexer.ll index aefd759995..5e2e7d99f0 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -57,7 +57,7 @@ RH 7 fix (?) void strip_trailing_white (String&); void strip_leading_white (String&); String lyric_fudge (String s); -int music_head_type (SCM); +int music_function_type (SCM); SCM lookup_markup_command (String s); bool is_valid_version (String s); @@ -892,7 +892,7 @@ lookup_markup_command (String s) int music_function_type (SCM func) { - SCM type= scm_object_property (func, ly_symbol2scm ("music-head-signature-keyword")); + SCM type= scm_object_property (func, ly_symbol2scm ("music-function-signature-keyword")); if (type == ly_symbol2scm ("scm")) { return MUSIC_FUNCTION_SCM; @@ -918,7 +918,10 @@ music_function_type (SCM func) return MUSIC_FUNCTION_SCM_SCM_MUSIC; } else - assert (false); + { + /* TODO: print location */ + error ("Can not find sigature for music function."); + } - return MUSIC_FUNCTION_SCM_MUSIC_MUSIC; + return MUSIC_FUNCTION_SCM; } diff --git a/lily/music-function.cc b/lily/music-function.cc new file mode 100644 index 0000000000..11cda8255c --- /dev/null +++ b/lily/music-function.cc @@ -0,0 +1,81 @@ +/* + music-function.cc -- implement music_function + + source file of the GNU LilyPond music typesetter + + (c) 2004 Han-Wen Nienhuys + +*/ +#include "music-function.hh" +#include "string.hh" +#include "music.hh" + +static scm_t_bits music_function_tag; + +/* Print a textual represenation of the smob to a given port. */ +static int +print_music_function (SCM b, SCM port, scm_print_state *) +{ + SCM value = SCM_CELL_OBJECT_1 (b); + + scm_puts ("#", port); + + /* Non-zero means success. */ + return 1; +} + + +LY_DEFINE (ly_make_music_function, "ly:make-music-function", 2, 0, 0, + (SCM signature, SCM func), + "Make a function to process music, to be used for the " + "parser. @code{func} is the function, and @code{signature} describes " + "Its arguments. @code{signature} is a list containing either " + "@code{ly:music?} predicates or other type predicates.") +{ + String str = ""; + for (SCM s = signature; ly_c_pair_p (s); s = ly_cdr (s)) + { + if (str != "") + str += "-"; + + if (ly_car (s) == Music_type_p_proc) + str += "music"; + else if (ly_c_procedure_p (ly_car (s))) + str += "scm"; + } + + scm_set_object_property_x (func, ly_symbol2scm ("music-function-signature"), + signature); + + scm_set_object_property_x (func, ly_symbol2scm ("music-function-signature-keyword"), + ly_symbol2scm (str.to_str0 ())); + + SCM_RETURN_NEWSMOB (music_function_tag, func); +} + +bool +is_music_function (SCM music_function) +{ + return (SCM_NIMP (music_function) && SCM_CELL_TYPE (music_function) == music_function_tag); +} + + +SCM +get_music_function_transform (SCM music_function) +{ + if (!is_music_function (music_function)) + return SCM_UNDEFINED; + + return SCM_CELL_OBJECT_1 (music_function); +} + +static void +init_music_function (void) +{ + music_function_tag = scm_make_smob_type ("music-function", 0); + scm_set_smob_mark (music_function_tag, scm_markcdr); + scm_set_smob_print (music_function_tag, print_music_function); +} +ADD_SCM_INIT_FUNC (music_function_tag, init_music_function); diff --git a/lily/music-head.cc b/lily/music-head.cc deleted file mode 100644 index 3deb46d1d7..0000000000 --- a/lily/music-head.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* - music-head.cc -- implement Music_head - - source file of the GNU LilyPond music typesetter - - (c) 2004 Han-Wen Nienhuys - -*/ -#include "music-head.hh" -#include "string.hh" -#include "music.hh" - -static scm_t_bits music_head_tag; - -/* Print a textual represenation of the smob to a given port. */ -static int -print_music_head (SCM b, SCM port, scm_print_state *) -{ - SCM value = SCM_CELL_OBJECT_1 (b); - - scm_puts ("#", port); - - /* Non-zero means success. */ - return 1; -} - - -LY_DEFINE (ly_make_music_head, "ly:make-music-head", 2, 0, 0, - (SCM signature, SCM func), - "Make a function to process music, to be used for the " - "parser. @code{func} is the function, and @code{signature} describes " - "Its arguments. @code{signature} is a list containing either " - "@code{ly:music?} predicates or other type predicates.") -{ - String str = ""; - for (SCM s = signature; ly_c_pair_p (s); s = ly_cdr (s)) - { - if (str != "") - str += "-"; - - if (ly_car (s) == Music_type_p_proc) - str += "music"; - else if (ly_c_procedure_p (ly_car (s))) - str += "scm"; - } - - scm_set_object_property_x (func, ly_symbol2scm ("music-head-signature"), - signature); - - scm_set_object_property_x (func, ly_symbol2scm ("music-head-signature-keyword"), - ly_symbol2scm (str.to_str0 ())); - - SCM_RETURN_NEWSMOB (music_head_tag, func); -} - -bool -is_music_head (SCM music_head) -{ - return (SCM_NIMP (music_head) && SCM_CELL_TYPE (music_head) == music_head_tag); -} - - -SCM -get_music_head_transform (SCM music_head) -{ - if (!is_music_head (music_head)) - return SCM_UNDEFINED; - - return SCM_CELL_OBJECT_1 (music_head); -} - -static void -init_music_head (void) -{ - music_head_tag = scm_make_smob_type ("music-head", 0); - scm_set_smob_mark (music_head_tag, scm_markcdr); - scm_set_smob_print (music_head_tag, print_music_head); -} -ADD_SCM_INIT_FUNC (music_head_tag, init_music_head); diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc index cbdc5dbdcb..971fe0ae7c 100644 --- a/lily/my-lily-lexer.cc +++ b/lily/my-lily-lexer.cc @@ -31,7 +31,6 @@ static Keyword_ent the_key_tab[] = { {"addquote", ADDQUOTE}, {"alias", ALIAS}, {"alternative", ALTERNATIVE}, - {"apply", APPLY}, {"applycontext", APPLYCONTEXT}, {"applyoutput", APPLYOUTPUT}, {"appoggiatura", APPOGGIATURA}, diff --git a/lily/parser.yy b/lily/parser.yy index 898c2403cd..f94d93a35e 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -247,7 +247,6 @@ or %token LYRICSTO %token ALIAS %token ALTERNATIVE -%token APPLY %token APPLYCONTEXT %token APPLYOUTPUT %token AUTOCHANGE @@ -1143,23 +1142,6 @@ basic music objects too, since the meaning is different. $$->set_property ("element", p->self_scm ()); scm_gc_unprotect_object (p->self_scm ()); } - | APPLY embedded_scm Music { - if (!ly_input_procedure_p ($2)) - { - THIS->parser_error (_ ("\\apply takes function argument")); - $$ = $3; - } - else - { - SCM ret = scm_call_1 ($2, $3->self_scm ()); - Music *m = unsmob_music (ret); - if (!m) { - THIS->parser_error ("\\apply must return a Music"); - m = MY_MAKE_MUSIC ("Music"); - } - $$ = m; - } - } | NOTES { SCM nn = THIS->lexer_->lookup_identifier ("pitchnames"); diff --git a/ly/declarations-init.ly b/ly/declarations-init.ly index 917e2bac90..b7a4829df0 100644 --- a/ly/declarations-init.ly +++ b/ly/declarations-init.ly @@ -5,6 +5,7 @@ breve = #(ly:make-duration -1 0) longa = #(ly:make-duration -2 0 ) maxima = #(ly:make-duration -3 0) +\include "music-functions-init.ly" \include "nederlands.ly" % dutch \include "drumpitch-init.ly" \include "chord-modifiers-init.ly"