static Music *make_music_with_input (SCM name, Input where);
SCM check_scheme_arg (Lily_parser *parser, Input loc,
- SCM arg, SCM args, SCM pred);
+ SCM arg, SCM args, SCM pred, SCM disp = SCM_UNDEFINED);
SCM make_music_from_simple (Lily_parser *parser, Input loc, SCM pitch);
SCM loc_on_music (Input loc, SCM arg);
SCM make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list);
%token SCM_FUNCTION
%token SCM_IDENTIFIER
%token SCM_TOKEN
-%token SCORE_IDENTIFIER
%token STRING
%token SYMBOL_LIST
%token TONICNAME_PITCH
unsmob_score ($$)->origin ()->set_spot (@$);
}
- | SCORE_IDENTIFIER {
+ | embedded_scm_active {
+ Score *score;
+ if (unsmob_score ($1))
+ score = new Score (*unsmob_score ($1));
+ else {
+ score = new Score;
+ parser->parser_error (@1, _("score expected"));
+ }
unsmob_score ($$)->origin ()->set_spot (@$);
+ $$ = score->unprotect ();
}
| score_body
{
else {
Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
t->set_property ("digit", $5);
- $$ = t->unprotect ();
- if (scm_is_true (scm_call_1 ($2, $$)))
- $$ = scm_cons ($$, $3);
- else
- $$ = check_scheme_arg (parser, @4, n, $3, $2);
+ $$ = check_scheme_arg (parser, @4, t->unprotect (),
+ $3, $2, n);
}
}
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist SCM_IDENTIFIER
{
- SCM res = try_string_variants ($2, $4);
- if (SCM_UNBNDP (res))
- $$ = check_scheme_arg (parser, @4, $4, $3, $2);
- else
- $$ = scm_cons (res, $3);
+ $$ = check_scheme_arg (parser, @4,
+ try_string_variants ($2, $4),
+ $3, $2, $4);
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist STRING
{
- SCM res = try_string_variants ($2, $4);
- if (SCM_UNBNDP (res))
- $$ = check_scheme_arg (parser, @4, $4, $3, $2);
- else
- $$ = scm_cons (res, $3);
+ $$ = check_scheme_arg (parser, @4,
+ try_string_variants ($2, $4),
+ $3, $2, $4);
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist LYRICS_STRING
{
- SCM res = try_string_variants ($2, $4);
- if (SCM_UNBNDP (res))
- $$ = check_scheme_arg (parser, @4, $4, $3, $2);
- else
- $$ = scm_cons (res, $3);
+ $$ = check_scheme_arg (parser, @4,
+ try_string_variants ($2, $4),
+ $3, $2, $4);
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist lyric_markup
{
make_simple_markup ($1));
$$ = t->unprotect ();
}
- | embedded_scm_bare
+ | embedded_scm_closed
{
Music *m = unsmob_music ($1);
if (m && m->is_mus_type ("post-event"))
*destination = unsmob_context_mod (sid)->smobbed_copy ();
return CONTEXT_MOD_IDENTIFIER;
- } else if (unsmob_score (sid)) {
- Score *score = new Score (*unsmob_score (sid));
- *destination = score->self_scm ();
-
- score->unprotect ();
- return SCORE_IDENTIFIER;
} else if (Music *mus = unsmob_music (sid)) {
mus = mus->clone ();
*destination = mus->self_scm ();
return scm_from_locale_string (s);
}
+// check_scheme_arg checks one argument with a given predicate for use
+// in an argument list and throws a syntax error if it is unusable.
+// The argument is prepended to the argument list in any case. After
+// throwing a syntax error, the argument list is terminated with #f as
+// its last cdr in order to mark it as uncallable while not losing
+// track of its total length.
+//
+// There are a few special considerations: if optional argument disp
+// is given (otherwise it defaults to SCM_UNDEFINED), it will be used
+// instead of arg in a prospective error message. This is useful if
+// arg is not the actual argument but rather a transformation of it.
+//
+// If arg itself is SCM_UNDEFINED, the predicate is considered false
+// and an error message using disp is produced unconditionally.
+
SCM check_scheme_arg (Lily_parser *parser, Input loc,
- SCM arg, SCM args, SCM pred)
+ SCM arg, SCM args, SCM pred, SCM disp)
{
- args = scm_cons (arg, args);
- if (scm_is_true (scm_call_1 (pred, arg)))
- return args;
+ if (SCM_UNBNDP (arg))
+ args = scm_cons (disp, args);
+ else {
+ args = scm_cons (arg, args);
+ if (scm_is_true (scm_call_1 (pred, arg)))
+ return args;
+ }
scm_set_cdr_x (scm_last_pair (args), SCM_EOL);
- MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred, arg);
+ MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred,
+ SCM_UNBNDP (disp) ? arg : disp);
scm_set_cdr_x (scm_last_pair (args), SCM_BOOL_F);
return args;
}
if (unsmob_music (simple))
return simple;
if (parser->lexer_->is_note_state ()) {
- Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
- n->set_property ("duration", parser->default_duration_.smobbed_copy ());
- if (scm_is_symbol (simple))
+ if (scm_is_symbol (simple)) {
+ Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
+ n->set_property ("duration", parser->default_duration_.smobbed_copy ());
n->set_property ("drum-type", simple);
- else if (unsmob_pitch (simple))
+ return n->unprotect ();
+ }
+ if (unsmob_pitch (simple)) {
+ Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
+ n->set_property ("duration", parser->default_duration_.smobbed_copy ());
n->set_property ("pitch", simple);
- else {
- n->unprotect ();
- return simple;
+ return n->unprotect ();
}
- return n->unprotect ();
+ return simple;
} else if (parser->lexer_->is_lyric_state ()) {
if (Text_interface::is_markup (simple))
return MAKE_SYNTAX ("lyric-event", loc, simple,