From 26231d3ddddc67a5d8dce11d25d7d7c9109bde3e Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Thu, 10 Oct 2002 23:02:55 +0000 Subject: [PATCH] * lily/my-lily-lexer.cc (prepare_for_next_token): use previous token for origin information. * lily/parser.yy (My_lily_lexer): do identifier location and cloning from lexer. * scm/music-functions.scm (make-multi-measure-rest): move mmrest logic out of the parser. * Documentation/user/refman.itely (Multi measure rests): add more notes about mm rests. --- ChangeLog | 14 ++++ Documentation/user/refman.itely | 30 +++++++-- Documentation/user/tutorial.itely | 2 +- lily/include/my-lily-lexer.hh | 6 +- lily/input-smob.cc | 7 +- lily/lexer.ll | 29 +-------- lily/music.cc | 28 ++++---- lily/my-lily-lexer.cc | 8 ++- lily/my-lily-parser.cc | 7 +- lily/parser.yy | 102 ++++++++++++++++++++---------- scm/music-functions.scm | 36 ++++++++++- 11 files changed, 176 insertions(+), 93 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3b387f4098..0eff07a9d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2002-10-11 Han-Wen Nienhuys + + * lily/my-lily-lexer.cc (prepare_for_next_token): use previous + token for origin information. + + * lily/parser.yy (My_lily_lexer): do identifier location and + cloning from lexer. + + * scm/music-functions.scm (make-multi-measure-rest): move mmrest + logic out of the parser. + + * Documentation/user/refman.itely (Multi measure rests): add more + notes about mm rests. + 2002-10-10 Jan Nieuwenhuizen * input/regression/bar-scripts.ly: Re-enable. diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index c71efa1033..9e05bb9b1e 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -3450,7 +3450,8 @@ fermata. This can be corrected by the following property setting Bar numbers are printed by default at the start of the line. The number itself is a property that can be set by modifying the -@code{currentBarNumber} property, i.e. +@code{currentBarNumber} property, although that is usually not +necessary, i.e. @example \property Score.currentBarNumber = #217 @end example @@ -3575,12 +3576,28 @@ Lily will not expand empty measures, and the appropriate number is added automatically. @lilypond[fragment,verbatim] - \time 3/4 r2. | R2. | R2.*2 - \property Score.skipBars = ##t R2.*17 R2.*4 + \time 4/4 r1 | R1 | R1*2 + \property Score.skipBars = ##t R1*17 R1*4 @end lilypond -Notice that the @code{R2.} is printed as a whole rest, centered in the -measure. +The @code{1} in @code{R1} is similar to the duration notation used for +notes. Hence, for time signatures other than 4/4, you must enter other +durations. This can be done with augmentation dots, or with +fractions: + +@lilypond[fragment,verbatim] + \property Score.skipBars = ##t + \time 3/4 + R2. | R2.*2 + \time 13/8 + R1*13/8 + R1*13/8*12 +@end lilypond +Notice that a @code{R} spanning a single measure is printed as a whole +rest centered in the measure, regardless of the time signature. + +[ add note about breves.] + @cindex whole rests for a full measure @@ -3590,7 +3607,8 @@ The object for this object is @internalsref{MultiMeasureRest}. Currently, there is no way to automatically condense multiple rests into a single multimeasure rest. Multi measure rests do not take part -in rest collisions. +in rest collisions. There is no way to put texts centered on +multi-measure rests. @cindex condensing rests diff --git a/Documentation/user/tutorial.itely b/Documentation/user/tutorial.itely index 288e706236..36540af6d5 100644 --- a/Documentation/user/tutorial.itely +++ b/Documentation/user/tutorial.itely @@ -284,7 +284,7 @@ File/Print inside ghostview. The DVI file (@file{test.dvi}) contains the same sheet music in a different format. DVI files are more easily processed by the computer, so viewing them usually is quicker. You can run @code{xdvi test.dvi} or -@code{kdvi test.dvi} to view the DVI file. In Xdvi, the mouse buttons +@code{kdvi test.dvi} to view the DVI file. In Xdvi, the mouse burtons activate magnifying glasses. Unfortunately, variable symbols (such as beams and slurs) are not displayed in the magnifying glasses. diff --git a/lily/include/my-lily-lexer.hh b/lily/include/my-lily-lexer.hh index 7910035d3a..3cc210b958 100644 --- a/lily/include/my-lily-lexer.hh +++ b/lily/include/my-lily-lexer.hh @@ -11,6 +11,7 @@ #include +#include "input.hh" #include "dictionary.hh" #include "lily-proto.hh" #include "flower-proto.hh" @@ -46,8 +47,11 @@ public: ~My_lily_lexer (); int yylex (); + Input last_input_; + void prepare_for_next_token (); + int try_special_identifiers (SCM* ,SCM); Input here_input () const; - + void add_scope (SCM); SCM remove_scope (); diff --git a/lily/input-smob.cc b/lily/input-smob.cc index 2e45db0b8e..deb8748e3a 100644 --- a/lily/input-smob.cc +++ b/lily/input-smob.cc @@ -47,8 +47,9 @@ LY_DEFINE(ly_input, "ly-input-location?", 1, 0, 0, } LY_DEFINE(ly_input_message, "ly-input-message", 2, 0, 0, (SCM sip, SCM msg), - "Print @var{msg} as a GNU compliant error message, pointing to the -location in @var{sip}.") + "Print @var{msg} as a GNU compliant error message, pointing to the\n" + "location in @var{sip}.\n" + ) { Input *ip = unsmob_input(sip); @@ -70,8 +71,6 @@ start_input_smobs () scm_set_smob_free (input_tag, free_smob); scm_set_smob_print (input_tag, print_smob); scm_set_smob_equalp (input_tag, 0); - - } SCM diff --git a/lily/lexer.ll b/lily/lexer.ll index 2d0b5dfa0f..ab2f85714f 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -29,7 +29,6 @@ #include #include "parse-scm.hh" -#include "score.hh" #include "lily-guile.hh" #include "string.hh" #include "string-convert.hh" @@ -40,11 +39,9 @@ #include "parser.hh" #include "warn.hh" #include "main.hh" -#include "event.hh" #include "version.hh" #include "lilypond-input-version.hh" #include "translator-def.hh" -#include "music-output-def.hh" #include "identifier-smob.hh" /* @@ -534,30 +531,8 @@ My_lily_lexer::pop_state () int My_lily_lexer::identifier_type(SCM sid) { - if (gh_string_p (sid)) { - yylval.scm = sid; - return STRING_IDENTIFIER; - } else if (gh_number_p (sid)) { - yylval.scm = sid; - return NUMBER_IDENTIFIER; - } else if (unsmob_translator_def (sid)) { - yylval.scm = sid; - return TRANSLATOR_IDENTIFIER; - } else if (unsmob_score (sid)) { - yylval.scm =sid; - return SCORE_IDENTIFIER; - } else if (Music * mus =unsmob_music (sid)) { - yylval.scm = sid; - - return dynamic_cast (mus) ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER; - } else if (unsmob_duration (sid)) { - yylval.scm = sid; - return DURATION_IDENTIFIER; - } else if (unsmob_music_output_def (sid)) { - yylval.scm = sid; - return MUSIC_OUTPUT_DEF_IDENTIFIER; - } - return SCM_IDENTIFIER; + int k = try_special_identifiers(&yylval.scm , sid); + return k >= 0 ? k : SCM_IDENTIFIER; } diff --git a/lily/music.cc b/lily/music.cc index 4dcaee74a2..b9944608c1 100644 --- a/lily/music.cc +++ b/lily/music.cc @@ -265,16 +265,15 @@ LY_DEFINE(ly_music_name, "ly-music-name", 1, 0, 0, // to do property args LY_DEFINE(ly_extended_make_music, "ly-make-bare-music", 2, 0, 0, (SCM type, SCM props), - " -Make a music object/expression of type @var{type}, init with -@var{props}. Warning: this interface will likely change in the near -future. - -Music is the data type that music expressions are stored in. The data -type does not yet offer many manipulations. - -WARNING: deprecated; use make-music-by-name. -") + "Make a music object/expression of type @var{type}, init with\n" +"@var{props}. Warning: this interface will likely change in the near\n" +"future.\n" +"\n" +"Music is the data type that music expressions are stored in. The data\n" +"type does not yet offer many manipulations.\n" +"\n" +"WARNING: only for internal use. Please use make-music-by-name. \n" +) { SCM_ASSERT_TYPE(gh_string_p (type), type, SCM_ARG1, __FUNCTION__, "string"); @@ -287,11 +286,10 @@ WARNING: deprecated; use make-music-by-name. // to do property args LY_DEFINE(ly_get_mutable_properties, "ly-get-mutable-properties", 1, 0, 0, (SCM mus), - " -Return an alist signifying the mutable properties of @var{mus}. -The immutable properties are not available; they should be initialized -by the functions make-music-by-name function. - ") +"Return an alist signifying the mutable properties of @var{mus}.\n" +"The immutable properties are not available; they should be initialized\n" +"by the functions make-music-by-name function.\n" +) { Music *m = unsmob_music (mus); SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__, "music"); diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc index 39ffb03042..2abbd0946e 100644 --- a/lily/my-lily-lexer.cc +++ b/lily/my-lily-lexer.cc @@ -201,7 +201,7 @@ My_lily_lexer::LexerError (char const *s) else { errorlevel_ |= 1; - Input spot (get_source_file (),here_str0 ()); + Input spot (get_source_file (), here_str0 ()); spot.error (s); } } @@ -230,3 +230,9 @@ My_lily_lexer::here_input () const Source_file * f= get_source_file (); return Input (f, (char*)here_str0 ()); } + +void +My_lily_lexer::prepare_for_next_token () +{ + last_input_ = here_input(); +} diff --git a/lily/my-lily-parser.cc b/lily/my-lily-parser.cc index f935f0f778..d7b798938a 100644 --- a/lily/my-lily-parser.cc +++ b/lily/my-lily-parser.cc @@ -91,10 +91,13 @@ My_lily_parser::pop_spot () Input My_lily_parser::here_input () const { - return lexer_->here_input (); + /* + Parsing looks ahead , so we really want the previous location of the + lexer, not lexer_->here_input(). + */ + return lexer_->last_input_; } -// move me? #include "paper-def.hh" #include "translator-def.hh" diff --git a/lily/parser.yy b/lily/parser.yy index 9e57da52ec..1d25c9de50 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -45,6 +45,8 @@ this. #include "chord.hh" #include "ly-modules.hh" #include "music-sequence.hh" +#include "input-smob.hh" +#include "event.hh" bool regular_identifier_b (SCM id) @@ -147,6 +149,7 @@ yylex (YYSTYPE *s, void * v) My_lily_lexer * lex = pars->lexer_; lex->lexval = (void*) s; + lex->prepare_for_next_token(); return lex->yylex (); } @@ -477,7 +480,7 @@ translator_spec_block: translator_spec_body: TRANSLATOR_IDENTIFIER { - $$ = unsmob_translator_def ($1)->clone_scm (); + $$ = $1; unsmob_translator_def ($$)-> set_spot (THIS->here_input ()); } | TYPE STRING { @@ -568,7 +571,7 @@ score_body: } | SCORE_IDENTIFIER { - $$ = new Score (*unsmob_score ($1)); + $$ = unsmob_score ($1); $$->set_spot (THIS->here_input ()); } | score_body lilypond_header { @@ -614,21 +617,21 @@ music_output_def_body: p = dynamic_cast (id->clone ()); else p = new Paper_def; - THIS-> lexer_->add_scope (p->scope_); + + THIS->lexer_->add_scope (p->scope_); $$ = p; } | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER { - Music_output_def *p = unsmob_music_output_def ($3); - p = p->clone (); - THIS->lexer_->add_scope (p->scope_); - $$ = p; + Music_output_def * o = unsmob_music_output_def ($3); + $$ =o; + + THIS->lexer_->add_scope (o->scope_); } | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER { - Music_output_def *p = unsmob_music_output_def ($3); - p = p->clone (); + Music_output_def * o = unsmob_music_output_def ($3); + $$ = o; - THIS->lexer_->add_scope (p->scope_); - $$ = p; + THIS->lexer_->add_scope (o->scope_); } | music_output_def_body assignment { @@ -798,9 +801,7 @@ Simple_music: $$ = m; } | MUSIC_IDENTIFIER { - $$ = unsmob_music ($1)->clone (); - - $$->set_spot (THIS->here_input()); + $$ = unsmob_music ($1); } | property_def | translator_change @@ -1398,8 +1399,7 @@ event_with_dir: verbose_event: EVENT_IDENTIFIER { - $$ = unsmob_music ($1)->clone (); - $$->set_spot (THIS->here_input ()); + $$ = unsmob_music ($1); } | SPANREQUEST bare_int STRING { Music * sp = make_span_req ($3); @@ -1710,7 +1710,9 @@ steno_duration: | DURATION_IDENTIFIER dots { Duration *d =unsmob_duration ($1); Duration k (d->duration_log (),d->dot_count () + $2); - $$ = k.smobbed_copy (); + + *d = k; + $$ = $1; } ; @@ -1902,25 +1904,14 @@ simple_element: | MULTI_MEASURE_REST optional_notemode_duration { THIS->pop_spot (); - Music * sk = MY_MAKE_MUSIC("SkipEvent"); - sk->set_mus_property ("duration", $2); - Music *sp1 = MY_MAKE_MUSIC("MultiMeasureRestEvent"); - Music *sp2 = MY_MAKE_MUSIC("MultiMeasureRestEvent"); - sp1-> set_mus_property ("span-direction", gh_int2scm (START)) -; - sp2-> set_mus_property ("span-direction", gh_int2scm (STOP)) -; - Music *rqc1 = MY_MAKE_MUSIC("EventChord"); - rqc1->set_mus_property ("elements", scm_list_n (sp1->self_scm (), SCM_UNDEFINED)); - Music *rqc2 = MY_MAKE_MUSIC("EventChord"); - rqc2->set_mus_property ("elements", scm_list_n (sk->self_scm (), SCM_UNDEFINED));; - Music *rqc3 = MY_MAKE_MUSIC("EventChord"); - rqc3->set_mus_property ("elements", scm_list_n (sp2->self_scm (), SCM_UNDEFINED));; - - SCM ms = scm_list_n (rqc1->self_scm (), rqc2->self_scm (), rqc3->self_scm (), SCM_UNDEFINED); + static SCM proc ; + if (!proc) + proc = scm_c_eval_string ("make-multi-measure-rest"); - $$ = MY_MAKE_MUSIC("SequentialMusic"); - $$->set_mus_property ("elements", ms); + SCM mus = scm_call_2 (proc, $2, + make_input (THIS->here_input())); + scm_gc_protect_object (mus); + $$ = unsmob_music (mus); } | STRING optional_notemode_duration { Input i = THIS->pop_spot (); @@ -2191,3 +2182,44 @@ My_lily_parser::beam_check (SCM dur) } last_beam_start_ = SCM_EOL; } + + +/* +It is a little strange, to have this function in this file, but +otherwise, we have to import music classes into the lexer. + +*/ +int +My_lily_lexer::try_special_identifiers (SCM * destination, SCM sid) +{ + if (gh_string_p (sid)) { + *destination = sid; + return STRING_IDENTIFIER; + } else if (gh_number_p (sid)) { + *destination = sid; + return NUMBER_IDENTIFIER; + } else if (unsmob_translator_def (sid)) { + *destination = unsmob_translator_def (sid)->clone_scm(); + return TRANSLATOR_IDENTIFIER; + } else if (unsmob_score (sid)) { + Score *sc = new Score (*unsmob_score (sid)); + *destination =sc->self_scm (); + return SCORE_IDENTIFIER; + } else if (Music * mus =unsmob_music (sid)) { + *destination = unsmob_music (sid)->clone ()->self_scm(); + unsmob_music (*destination)-> + set_mus_property ("origin", make_input (last_input_)); + return dynamic_cast (mus) + ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER; + } else if (unsmob_duration (sid)) { + *destination = unsmob_duration (sid)->smobbed_copy(); + return DURATION_IDENTIFIER; + } else if (unsmob_music_output_def (sid)) { + Music_output_def *p = unsmob_music_output_def (sid); + p = p->clone (); + + *destination = p->self_scm(); + return MUSIC_OUTPUT_DEF_IDENTIFIER; + } + return -1; +} diff --git a/scm/music-functions.scm b/scm/music-functions.scm index 4132342c2b..3469888450 100644 --- a/scm/music-functions.scm +++ b/scm/music-functions.scm @@ -196,7 +196,40 @@ this is not an override m )) +(define-public (make-event-chord elts) + (let* ((m (make-music-by-name 'EventChord))) + (ly-set-mus-property! m 'elements elts) + m + )) + + +(define-public (make-multi-measure-rest duration location) + (let* + ( + (start (make-music-by-name 'MultiMeasureRestEvent)) + (stop (make-music-by-name 'MultiMeasureRestEvent)) + (skip ( make-music-by-name 'SkipEvent)) + (ch (make-music-by-name 'BarCheck)) + (ch2 (make-music-by-name 'BarCheck)) + ) + + (ly-set-mus-property! start 'span-direction START) + (ly-set-mus-property! stop 'span-direction STOP) + (ly-set-mus-property! skip 'duration duration) + (map (lambda (x) (ly-set-mus-property! x 'origin location)) + (list start stop skip ch ch2)) + (make-sequential-music + (list + ch + (make-event-chord (list start)) + (make-event-chord (list skip)) + (make-event-chord (list stop)) + ch2 + )) + )) + (define-public (set-mus-properties! m alist) + "Set all of ALIST as properties of M." (if (pair? alist) (begin (ly-set-mus-property! m (caar alist) (cdar alist)) @@ -204,7 +237,7 @@ this is not an override )) (define-public (music-separator? m) - "Is M a separator." + "Is M a separator?" (let* ((ts (ly-get-mus-property m 'types ))) (memq 'separator ts) )) @@ -367,3 +400,4 @@ this is not an override ; switch-on-debugging )) + -- 2.39.2