%token LYRICSTO
%token ALIAS
%token ALTERNATIVE
-%token APPLY
%token APPLYCONTEXT
%token APPLYOUTPUT
%token AUTOCHANGE
%token WITH
/* escaped */
+/* FIXME: this sucks. The user will get to see these names:
+ syntax error, unexpected E_CHAR:
+ \
+ %%
+ */
%token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
%token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
%token E_BACKSLASH
%token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
%token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
+%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
%type <i> sub_quotes sup_quotes
%type <music> toplevel_music
%type <music> simple_element event_chord command_element
-%type <music> Composite_music Simple_music Prefix_composite_music
+%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
$$ = Context_def::make_scm ();
unsmob_context_def ($$)->set_spot (THIS->here_input ());
}
- | CONTEXT_DEF_IDENTIFIER {
+ | CONTEXT_DEF_IDENTIFIER {
$$ = $1;
unsmob_context_def ($$)->set_spot (THIS->here_input ());
}
Simultaneous_music { $$ = $1; }
| 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:
+ 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-function-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);
+ scm_gc_protect_object (m);
+ }
+ else
+ {
+ if (ok)
+ loc->error (_ ("Music head function should return Music object."));
+ $$ = MY_MAKE_MUSIC ("Music");
+ }
+ $$->set_spot (*loc);
+ }
+ ;
+
+
Prefix_composite_music:
- AUTOCHANGE Music {
+ Generic_prefix_music {
+ $$ = $1;
+ }
+ |AUTOCHANGE Music {
SCM proc = ly_scheme_function ("make-autochange-music");
SCM res = scm_call_1 (proc, $2->self_scm ());
$$->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");
SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
THIS->lexer_->push_note_state (alist_to_hashq (nn));
}
- /* FIXME: This used to be:
+ /* FIXME: This used to be: */
Music
-*/
- Grouped_music_list
+/* Grouped_music_list */
{ $$ = $3;
THIS->lexer_->pop_state ();
}
bass_number:
DIGIT {
$$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
+ $$ = scm_list_2 (ly_scheme_function ("number-markup"),
+ $$);
}
| UNSIGNED {
$$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
+ $$ = scm_list_2 (ly_scheme_function ("number-markup"),
+ $$);
}
| STRING { $$ = $1; }
;
| STRING_IDENTIFIER {
$$ = $1;
}
+ | score_block {
+ /* WIP this is a bit arbitrary,
+ we should also allow \book or Composite_music.
+ However, you'd typically want to change paper
+ settings, and need a \score block anyway. */
+ Score *score = $1;
+ Book *book = new Book;
+ book->scores_.push (score);
+ extern Music_output_def* get_paper (My_lily_parser *parser);
+ Music_output_def *paper = get_paper (THIS);
+ SCM s = book->to_stencil (paper, THIS->header_);
+ scm_gc_unprotect_object (score->self_scm ());
+ scm_gc_unprotect_object (book->self_scm ());
+ $$ = scm_list_2 (ly_scheme_function ("stencil-markup"), s);
+ }
;
markup_list: