SCM make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list);
SCM make_chord_step (SCM step, Rational alter);
SCM make_simple_markup (SCM a);
-SCM make_duration (SCM t, int dots = 0);
+SCM make_duration (SCM t, int dots = 0, SCM factor = SCM_UNDEFINED);
bool is_regular_identifier (SCM id, bool multiple=false);
SCM try_string_variants (SCM pred, SCM str);
int yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser);
%token CHORD_REPETITION
%token CONTEXT_MOD_IDENTIFIER
%token DRUM_PITCH
-%token PITCH_IDENTIFIER
+ /* Artificial token for durations in argument lists */
+%token DURATION_ARG
%token DURATION_IDENTIFIER
%token EVENT_IDENTIFIER
%token EVENT_FUNCTION
%token MUSIC_IDENTIFIER
%token NOTENAME_PITCH
%token NUMBER_IDENTIFIER
+%token PITCH_IDENTIFIER
%token REAL
%token RESTNAME
%token SCM_ARG
{
$$ = check_scheme_arg (parser, @3, $3, $1, $2);
}
+ | function_arglist_nonbackup_reparse REPARSE reparsed_rhythm
+ {
+ $$ = check_scheme_arg (parser, @3, $3, $1, $2);
+ }
| function_arglist_nonbackup_reparse REPARSE bare_number_common
{
$$ = check_scheme_arg (parser, @3, $3, $1, $2);
}
;
+
+reparsed_rhythm:
+ DURATION_ARG dots multipliers post_events
+ {
+ $$ = make_music_from_simple (parser, @$,
+ make_duration ($1, scm_to_int ($2), $3));
+ Music *m = unsmob<Music> ($$);
+ assert (m);
+ if (scm_is_pair ($4))
+ m->set_property ("articulations",
+ scm_reverse_x ($4, SCM_EOL));
+ } %prec ':'
+ ;
+
function_arglist_nonbackup_reparse:
EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER
{
{
$$ = $3;
if (scm_is_true (scm_call_1 ($2, $4)))
+ // May be 3 \cm or similar
MYREPARSE (@4, $2, REAL, $4);
else {
SCM d = make_duration ($4);
- if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
- MYREPARSE (@4, $2, REAL, $4); // trigger error
- else
- MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
+ if (!SCM_UNBNDP (d)) {
+ if (scm_is_true (scm_call_1 ($2, d)))
+ MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
+ else if (scm_is_true
+ (scm_call_1
+ ($2, make_music_from_simple (parser, @4, d))))
+ MYREPARSE (@4, $2, DURATION_ARG, d);
+ else
+ MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error
+ } else
+ MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error
}
}
- | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup DURATION_IDENTIFIER {
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup DURATION_IDENTIFIER
+ {
$$ = $3;
- MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
+ if (scm_is_true (scm_call_1 ($2, $4)))
+ MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
+ else if (scm_is_true
+ (scm_call_1
+ ($2, make_music_from_simple (parser, @4, $4))))
+ MYREPARSE (@4, $2, DURATION_ARG, $4);
+ else
+ MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error
}
;
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup UNSIGNED
{
+ $$ = $3;
if (scm_is_true (scm_call_1 ($2, $4)))
- {
+ // May be 3 \cm or similar
MYREPARSE (@4, $2, REAL, $4);
- $$ = $3;
- } else {
+ else {
SCM d = make_duration ($4);
- if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
- {
+ if (!SCM_UNBNDP (d)) {
+ if (scm_is_true (scm_call_1 ($2, d)))
+ MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
+ else if (scm_is_true
+ (scm_call_1
+ ($2, make_music_from_simple (parser, @4, d))))
+ MYREPARSE (@4, $2, DURATION_ARG, d);
+ else {
+ $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
+ MYBACKUP (UNSIGNED, $4, @4);
+ }
+ } else {
$$ = scm_cons (loc_on_music (parser, @3, $1), $3);
MYBACKUP (UNSIGNED, $4, @4);
- } else {
- MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
- $$ = $3;
}
}
}
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup DURATION_IDENTIFIER
{
+ $$ = $3;
if (scm_is_true (scm_call_1 ($2, $4)))
- {
MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
- $$ = $3;
- } else {
+ else if (scm_is_true
+ (scm_call_1
+ ($2, make_music_from_simple (parser, @4, $4))))
+ MYREPARSE (@4, $2, DURATION_ARG, $4);
+ else {
$$ = scm_cons (loc_on_music (parser, @3, $1), $3);
MYBACKUP (DURATION_IDENTIFIER, $4, @4);
}
$$ = check_scheme_arg (parser, @3,
$3, $1, $2);
}
+ | function_arglist_backup REPARSE reparsed_rhythm
+ {
+ $$ = check_scheme_arg (parser, @3,
+ $3, $1, $2);
+ }
| function_arglist_backup REPARSE symbol_list_arg
{
$$ = check_scheme_arg (parser, @3, $3, $1, $2);
$$ = check_scheme_arg (parser, @3,
$3, $1, $2);
}
+ | function_arglist_common_reparse REPARSE reparsed_rhythm
+ {
+ $$ = check_scheme_arg (parser, @3,
+ $3, $1, $2);
+ }
| function_arglist_common_reparse REPARSE symbol_list_arg
{
$$ = check_scheme_arg (parser, @3, $3, $1, $2);
{
$$ = $2;
if (scm_is_true (scm_call_1 ($1, $3)))
+ // May be 3 \cm or similar
MYREPARSE (@3, $1, REAL, $3);
else {
SCM d = make_duration ($3);
- if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($1, d)))
- MYREPARSE (@3, $1, REAL, $3);
- else
- MYREPARSE (@3, $1, DURATION_IDENTIFIER, d);
+ if (!SCM_UNBNDP (d)) {
+ if (scm_is_true (scm_call_1 ($1, d)))
+ MYREPARSE (@3, $1, DURATION_IDENTIFIER, d);
+ else if (scm_is_true
+ (scm_call_1
+ ($1, make_music_from_simple (parser, @3, d))))
+ MYREPARSE (@3, $1, DURATION_ARG, d);
+ else
+ MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error
+ } else
+ MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error
}
}
| EXPECT_SCM function_arglist_optional DURATION_IDENTIFIER
{
$$ = $2;
- MYREPARSE (@3, $1, DURATION_IDENTIFIER, $3);
+ if (scm_is_true (scm_call_1 ($1, $3)))
+ MYREPARSE (@3, $1, DURATION_IDENTIFIER, $3);
+ else if (scm_is_true
+ (scm_call_1
+ ($1, make_music_from_simple (parser, @3, $3))))
+ MYREPARSE (@3, $1, DURATION_ARG, $3);
+ else
+ MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error
}
| EXPECT_SCM function_arglist_optional '-' UNSIGNED
{
}
}
| DURATION_IDENTIFIER dots {
- Duration *d = unsmob<Duration> ($1);
- Duration k (d->duration_log (),
- d->dot_count () + scm_to_int ($2));
- k = k.compressed (d->factor ());
- scm_remember_upto_here_1 ($1);
- $$ = k.smobbed_copy ();
+ $$ = make_duration ($1, scm_to_int ($2));
}
;
multiplied_duration:
steno_duration multipliers {
- if (scm_is_number ($2)) {
- Rational m (ly_scm2rational ($2));
- $$ = unsmob<Duration> ($1)->compressed (m).smobbed_copy ();
- } else
- $$ = $1;
+ $$ = make_duration ($1, 0, $2);
}
;
multipliers:
/* empty */
{
- $$ = SCM_UNSPECIFIED;
+ $$ = SCM_UNDEFINED;
}
| multipliers '*' UNSIGNED
{
- if (scm_is_number ($1))
+ if (!SCM_UNBNDP ($1))
$$ = scm_product ($1, $3);
else
$$ = $3;
}
| multipliers '*' FRACTION
{
- if (scm_is_number ($1))
+ if (!SCM_UNBNDP ($1))
$$ = scm_product ($1, scm_divide (scm_car ($3),
scm_cdr ($3)));
else
n->set_property ("pitch", simple);
return n->unprotect ();
}
+ SCM d = simple;
+ if (scm_is_integer (simple))
+ d = make_duration (simple);
+ if (unsmob<Duration> (d)) {
+ Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
+ n->set_property ("duration", d);
+ return n->unprotect ();
+ }
return simple;
} else if (parser->lexer_->is_lyric_state ()) {
if (Text_interface::is_markup (simple))
}
SCM
-make_duration (SCM d, int dots)
+make_duration (SCM d, int dots, SCM factor)
{
- int t = scm_to_int (d);
- if (t > 0 && (t & (t-1)) == 0)
- return Duration (intlog2 (t), dots).smobbed_copy ();
- else
- return SCM_UNDEFINED;
+ Duration k;
+
+ if (Duration *dur = unsmob<Duration> (d)) {
+ if (!dots && SCM_UNBNDP (factor))
+ return d;
+ k = *dur;
+ if (dots)
+ k = Duration (k.duration_log (), k.dot_count () + dots)
+ .compressed (k.factor ());
+ } else {
+ int t = scm_to_int (d);
+ if (t > 0 && (t & (t-1)) == 0)
+ k = Duration (intlog2 (t), dots);
+ else
+ return SCM_UNDEFINED;
+ }
+
+ if (!SCM_UNBNDP (factor))
+ k = k.compressed (ly_scm2rational (factor));
+
+ return k.smobbed_copy ();
}
SCM