source file of the GNU LilyPond music typesetter
- (c) 1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
Jan Nieuwenhuizen <janneke@gnu.org>
*/
* The rules for who is protecting what are very shady. Uniformise
this.
-* There are too many lexical modes.
-
+* There are too many lexical modes?
*/
#include <ctype.h>
+#include <stdlib.h>
#include "translator-def.hh"
#include "lily-guile.hh"
#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"
#include "event.hh"
#include "text-item.hh"
+
+
+#define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
+
+
+
+#define YYERROR_VERBOSE 1
+
+My_lily_parser* my_lily_parser;
+#define YYPARSE_PARAM my_lily_parser
+#define YYLEX_PARAM my_lily_parser
+#define THIS\
+ ((My_lily_parser *) my_lily_parser)
+
+#define yyerror THIS->parser_error
+
+
+
+
+
bool
regular_identifier_b (SCM id)
{
}
}
+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 ();
+}
-#define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
+
+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;
+}
+
+/*
+ Todo: actually also use apply iso. call too ...
+*/
+bool
+ly_input_procedure_p (SCM x)
+{
+ return gh_procedure_p (x)
+ || (gh_pair_p (x) && gh_procedure_p (gh_car (x)));
+}
Music*
set_property_music (SCM sym, SCM value)
return p;
}
-
-// needed for bison.simple's malloc () and free ()
-
-// #include <malloc.h>
-#include <stdlib.h>
-
-
-
-#define YYERROR_VERBOSE 1
-
-My_lily_parser* my_lily_parser;
-#define YYPARSE_PARAM my_lily_parser
-#define YYLEX_PARAM my_lily_parser
-#define THIS\
- ((My_lily_parser *) my_lily_parser)
-
-#define yyerror THIS->parser_error
-
%}
/* We use SCMs to do strings, because it saves us the trouble of
/* 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 SIMULTANEOUS
%token CONSISTSEND
%token DENIES
+%token DESCRIPTION
%token EXTENDER
%token FIGURES FIGURE_OPEN FIGURE_CLOSE
%token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
%token <scm> DURATION_IDENTIFIER
%token <scm> FRACTION
%token <id> IDENTIFIER
+%token <scm> CHORDNAMES CHORDNAMES_IDENTIFIER
+%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;
}
td->translator_group_type_ = $2;
td->set_spot (THIS->here_input ());
}
+ | translator_spec_body DESCRIPTION string {
+ unsmob_translator_def ($$)->description_ = $3;
+ }
| translator_spec_body STRING '=' embedded_scm {
unsmob_translator_def ($$)->add_property_assign ($2, $4);
}
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 (!ly_input_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))
+ if (!ly_input_procedure_p ($2))
THIS->parser_error (_ ("\applycontext takes function argument"));
$$ = MY_MAKE_MUSIC ("ApplyContext");
$$->set_mus_property ("procedure", $2);
scm_gc_unprotect_object (p->self_scm ());
}
| APPLY embedded_scm Music {
+ if (!ly_input_procedure_p ($2))
+ THIS->parser_error (_ ("\apply takes function argument"));
+
SCM ret = gh_call1 ($2, $3->self_scm ());
Music *m = unsmob_music (ret);
if (!m) {
$$->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");
}
;
Music *key= MY_MAKE_MUSIC("KeyChangeEvent");
key->set_mus_property ("pitch-alist", $3);
+ key->set_mus_property ("tonic", Pitch (0,0,0).smobbed_copy());
((Music*)key)->transpose (* unsmob_pitch ($2));
- $$ = key;
+
+ $$ = key;
}
;
}
| NOTENAME_PITCH sup_quotes {
Pitch p = *unsmob_pitch ($1);
- p.octave_ += $2;
+ p = p.transposed (Pitch ($2,0,0));
$$ = p.smobbed_copy ();
}
| NOTENAME_PITCH sub_quotes {
Pitch p =* unsmob_pitch ($1);
-
- p.octave_ += -$2;
+ p = p.transposed (Pitch (-$2,0,0));
$$ = p.smobbed_copy ();
-
}
;
}
| TONICNAME_PITCH sup_quotes {
Pitch p = *unsmob_pitch ($1);
- p.octave_ += $2;
+ p = p.transposed (Pitch ($2,0,0));
$$ = p.smobbed_copy ();
}
| TONICNAME_PITCH sub_quotes {
Pitch p =* unsmob_pitch ($1);
- p.octave_ += -$2;
+ p = p.transposed (Pitch (-$2,0,0));
$$ = p.smobbed_copy ();
-
}
;
$$= 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;
- m.notename_ = ($1 - 1) % 7;
- m.octave_ = $1 > 7 ? 1 : 0;
- m.alteration_ = 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;
- m.notename_ = ($1 - 1) % 7;
- m.octave_ = $1 > 7 ? 1 : 0;
- m.alteration_ = 1;
-
-
- $$ = m.smobbed_copy ();
+ $$ = make_chord_step ($1, 1);
}
| bare_unsigned CHORD_MINUS {
- Pitch m;
- m.notename_ = ($1 - 1) % 7;
- m.octave_ = $1 > 7 ? 1 : 0;
- m.alteration_ = -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;
}