Variable multi_measure_rest ("multi-measure-rest");
Variable music_function ("music-function");
Variable music_function_call_error ("music-function-call-error");
+ Variable partial_music_function ("partial-music-function");
Variable property_operation ("property-operation");
Variable repeat ("repeat");
Variable repetition_chord ("repetition-chord");
%token DESCRIPTION "\\description"
%token DRUMMODE "\\drummode"
%token DRUMS "\\drums"
+%token ETC "\\etc"
%token FIGUREMODE "\\figuremode"
%token FIGURES "\\figures"
%token HEADER "\\header"
| embedded_scm
| full_markup_list
| context_modification
+ | partial_function ETC
+ ;
+
+partial_function:
+ MUSIC_FUNCTION function_arglist_partial
+ {
+ $$ = MAKE_SYNTAX (partial_music_function, @$,
+ $1, $2);
+ }
+ | EVENT_FUNCTION function_arglist_partial
+ {
+ $$ = MAKE_SYNTAX (partial_music_function, @$,
+ $1, $2);
+ }
+ | SCM_FUNCTION function_arglist_partial
+ {
+ $$ = MAKE_SYNTAX (partial_music_function, @$,
+ $1, $2);
+ }
;
context_def_spec_block:
}
;
+// Partial function arglists are returned just in their incomplete
+// state: when combined with the music function, the missing parts of
+// the signature can be reconstructed
+//
+// To serve as a partial arglist, the argument list must absolutely
+// _not_ be in "skipping optional arguments" mode since then there is
+// some backup token that has nowhere to go before \etc.
+//
+// So we can skim off an arbitrary number of arguments from the end of
+// the argument list. The argument list remaining afterwards has to
+// be in not-skipping-optional-arguments mode.
+
+function_arglist_partial:
+ EXPECT_SCM function_arglist_optional
+ {
+ $$ = $2;
+ }
+ | EXPECT_SCM function_arglist_partial_optional
+ {
+ $$ = $2;
+ }
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup
+ {
+ $$ = $3;
+ }
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist_partial
+ {
+ $$ = $3;
+ }
+ ;
+
+function_arglist_partial_optional:
+ EXPECT_SCM function_arglist_optional
+ {
+ $$ = $2;
+ }
+ | EXPECT_SCM function_arglist_partial_optional
+ {
+ $$ = $2;
+ }
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup
+ {
+ $$ = $3;
+ }
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist_partial_optional
+ {
+ $$ = $3;
+ }
+ ;
+
function_arglist_common:
EXPECT_NO_MORE_ARGS {
$$ = SCM_EOL;
n (type-name pred) (music->make-music arg))
(*location*)))
+(define-public (partial-music-function fun args)
+ (let* ((sig (ly:music-function-signature fun))
+ (args (and (list args) (reverse! args))))
+ (and args
+ (ly:make-music-function
+ (cons (car sig) (list-tail (cdr sig) (length args)))
+ (lambda rest
+ (apply (ly:music-function-extract fun)
+ (append args rest)))))))
+
(define-public (void-music)
(ly:set-origin! (make-music 'Music)))