* There are too many lexical modes?
-
*/
#include <ctype.h>
#include "lilypond-input-version.hh"
#include "scm-hash.hh"
#include "auto-change-iterator.hh"
-#include "chord.hh"
#include "ly-modules.hh"
#include "music-sequence.hh"
#include "input-smob.hh"
}
+SCM
+make_chord_step (int step, int alter)
+{
+ if (step == 7)
+ alter--;
+
+ /* ugh: fucks up above 13 */
+ Pitch m(step > 7 ? 1 : 0,(step - 1) % 7, alter);
+ return m.smobbed_copy ();
+}
+
+
+SCM
+make_chord (SCM pitch, SCM dur, SCM modification_list)
+{
+ static SCM chord_ctor;
+ if (!chord_ctor)
+ chord_ctor= scm_c_eval_string ("construct-chord");
+ SCM ch= scm_call_3 (chord_ctor, pitch, dur, modification_list);
+ scm_gc_protect_object (ch);
+ return ch;
+}
+
+
Music*
set_property_music (SCM sym, SCM value)
/* tokens which are not keywords */
%token AUTOCHANGE
%token ALIAS
-%token APPLYCONTEXT
+%token APPLYCONTEXT
+%token APPLYOUTPUT
%token APPLY
%token ACCEPTS
%token ALTERNATIVE
%token BAR
%token BREATHE
-%token CHORDMODIFIERS
+%token CHORDMODIFIERS
%token CHORDS
%token CLEF
%token CONSISTS
%token <scm> FRACTION
%token <id> IDENTIFIER
%token <scm> CHORDNAMES CHORDNAMES_IDENTIFIER
-%type <scm> chordnames_block chordnames_list chord_scm
+%token <scm> CHORD_MODIFIER
%token <scm> SCORE_IDENTIFIER
%token <scm> MUSIC_OUTPUT_DEF_IDENTIFIER
%token <scm> MARKUP_HEAD_SCM0
%token <scm> MARKUP_HEAD_SCM0_MARKUP1
%token <scm> MARKUP_HEAD_SCM0_SCM1
+%token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
%token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
%token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
%type <scm> steno_pitch pitch absolute_pitch pitch_also_in_chords
%type <scm> explicit_pitch steno_tonic_pitch
-%type <scm> chord_additions chord_subtractions chord_notes chord_step
-%type <music> chord
-%type <scm> chord_note chord_inversion chord_bass
+/* %type <scm> chord_additions chord_subtractions chord_notes chord_step */
+/* %type <music> chord */
+/* %type <scm> chord_note chord_inversion chord_bass */
%type <scm> duration_length fraction
+%type <scm> new_chord step_number chord_items chord_item chord_separator step_numbers
+
%type <scm> embedded_scm scalar
%type <music> Music Sequential_music Simultaneous_music
%type <music> relative_music re_rhythmed_music part_combined_music
SCM tab = scm_make_vector (gh_int2scm (i), SCM_EOL);
for (SCM s = $1; gh_pair_p (s); s = ly_cdr (s)) {
SCM pt = ly_cdar (s);
- if (!unsmob_pitch (pt))
- THIS->parser_error ("Need pitch object.");
- else
- scm_hashq_set_x (tab, ly_caar (s), pt);
+ scm_hashq_set_x (tab, ly_caar (s), pt);
}
$$ = tab;
}
| embedded_scm {
$$ = $1;
}
- | chordnames_block {
- $$ = $1;
- }
;
-chordnames_block:
- CHORDNAMES '{'
- { THIS->lexer_->push_chord_state (); }
- chordnames_list
- { THIS->lexer_->pop_state (); }
- '}'
- {
- $$ = $4;
- }
- ;
-
-chordnames_list:
- /* empty */ {
- $$ = SCM_EOL;
- }
- | CHORDNAMES_IDENTIFIER chordnames_list {
- $$ = scm_append (scm_list_2 ($1, $2));
- }
- | chord_scm '=' full_markup chordnames_list {
- $$ = scm_cons (scm_cons ($1, $3), $4);
- };
-
-chord_scm:
- steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass {
- $$ = Chord::tonic_add_sub_to_pitches ($1, $3, $4);
- /* junk bass and inversion for now */
- };
-
translator_spec_block:
TRANSLATOR '{' translator_spec_body '}'
{
tempo_event:
TEMPO steno_duration '=' bare_unsigned {
- $$ = MY_MAKE_MUSIC("TempoEvent");
+ $$ = MY_MAKE_MUSIC("MetronomeChangeEvent");
$$->set_mus_property ("tempo-unit", $2);
$$->set_mus_property ("metronome-count", gh_int2scm ( $4));
}
Simple_music:
event_chord { $$ = $1; }
+ | APPLYOUTPUT embedded_scm {
+ if (!gh_procedure_p ($2))
+ THIS->parser_error (_ ("\applycontext takes function argument"));
+ $$ = MY_MAKE_MUSIC ("ApplyOutputEvent");
+ $$->set_mus_property ("procedure", $2);
+ $$->set_spot (THIS->here_input());
+ }
| APPLYCONTEXT embedded_scm {
if (!gh_procedure_p ($2))
THIS->parser_error (_ ("\applycontext takes function argument"));
$$->set_mus_property ("element", p->self_scm ());
scm_gc_unprotect_object (p->self_scm ());
+
$$->set_mus_property ("last-pitch", p->to_relative_octave (pit).smobbed_copy ());
}
| bare_int { $$ = gh_int2scm ($1); }
| embedded_scm { $$ = $1; }
| full_markup { $$ = $1; }
+ | DIGIT { $$ = gh_int2scm ($1); }
;
$$ = MY_MAKE_MUSIC("BreathingSignEvent");
}
| E_TILDE {
- $$ = MY_MAKE_MUSIC("PorrectusEvent");
+ $$ = MY_MAKE_MUSIC("PesOrFlexaEvent");
}
;
$$= velt;
}
- | chord {
+ | new_chord {
THIS->pop_spot ();
- if (!THIS->lexer_->chord_state_b ())
- THIS->parser_error (_ ("Have to be in Chord mode for chords"));
- $$ = $1;
+ if (!THIS->lexer_->chord_state_b ())
+ THIS->parser_error (_ ("Have to be in Chord mode for chords"));
+ $$ = unsmob_music ($1);
}
;
-
-chord:
- steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass {
- $$ = Chord::get_chord ($1, $3, $4, $5, $6, $2);
- $$->set_spot (THIS->here_input ());
- };
-
-chord_additions:
- {
- $$ = SCM_EOL;
- }
- | CHORD_COLON chord_notes {
- $$ = $2;
+new_chord:
+ steno_tonic_pitch optional_notemode_duration {
+ $$ = make_chord ($1, $2, SCM_EOL);
+ }
+ | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
+ SCM its = scm_reverse_x ($4, SCM_EOL);
+ $$ = make_chord ($1, $2, gh_cons ($3, its));
}
;
-chord_notes:
- chord_step {
- $$ = $1;
+chord_items:
+ /**/ {
+ $$ = SCM_EOL;
}
- | chord_notes '.' chord_step {
- $$ = gh_append2 ($$, $3);
+ | chord_items chord_item {
+ $$ = gh_cons ($2, $$);
}
;
-chord_subtractions:
- {
- $$ = SCM_EOL;
- }
- | CHORD_CARET chord_notes {
- $$ = $2;
+chord_separator:
+ CHORD_COLON {
+ $$ = ly_symbol2scm ("chord-colon");
}
- ;
-
-
-chord_inversion:
- {
- $$ = SCM_EOL;
+ | CHORD_CARET {
+ $$ = ly_symbol2scm ("chord-caret");
}
| CHORD_SLASH steno_tonic_pitch {
- $$ = $2;
- }
- ;
-
-chord_bass:
- {
- $$ = SCM_EOL;
+ $$ = scm_list_n (ly_symbol2scm ("chord-slash"), $2, SCM_UNDEFINED);
}
| CHORD_BASS steno_tonic_pitch {
- $$ = $2;
+ $$ = scm_list_n (ly_symbol2scm ("chord-bass"), $2, SCM_UNDEFINED);
}
;
-chord_step:
- chord_note {
- $$ = scm_cons ($1, SCM_EOL);
+chord_item:
+ chord_separator {
+ $$ = $1;
}
- | CHORDMODIFIER_PITCH {
- $$ = scm_cons (unsmob_pitch ($1)->smobbed_copy (), SCM_EOL);
+ | step_numbers {
+ $$ = scm_reverse_x ($1, SCM_EOL);
}
- | CHORDMODIFIER_PITCH chord_note { /* Ugh. */
- $$ = scm_list_n (unsmob_pitch ($1)->smobbed_copy (),
- $2, SCM_UNDEFINED);
+ | CHORD_MODIFIER {
+ $$ = $1;
}
;
-chord_note:
- bare_unsigned {
- Pitch m($1 > 7 ? 1 : 0, ($1 - 1) % 7, 0);
+step_numbers:
+ step_number { $$ = gh_cons ($1, SCM_EOL); }
+ | step_numbers '.' step_number {
+ $$ = gh_cons ($3, $$);
+ }
+ ;
- $$ = m.smobbed_copy ();
+step_number:
+ bare_unsigned {
+ $$ = make_chord_step ($1, 0);
}
| bare_unsigned '+' {
- Pitch m( $1 > 7 ? 1 : 0,($1 - 1) % 7, 1);
-
- $$ = m.smobbed_copy ();
+ $$ = make_chord_step ($1, 1);
}
| bare_unsigned CHORD_MINUS {
- Pitch m( $1 > 7 ? 1 : 0,($1 - 1) % 7, -1);
-
- $$ = m.smobbed_copy ();
+ $$ = make_chord_step ($1,-1);
}
- ;
+ ;
/*
UTILITIES
THIS->lexer_->pop_state ();
}
;
-
+
+
+/*
+This should be done more dynamically if possible.
+*/
markup:
STRING {
$$ = make_simple_markup ($1);
| MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm markup {
$$ = scm_list_n ($1, $2, $3, $4, SCM_UNDEFINED);
}
+ | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
+ $$ = scm_list_n ($1, $2, $3, $4, SCM_UNDEFINED);
+ }
| MARKUP_IDENTIFIER {
$$ = $1;
}