From 9e60ad96b799c9d5c89b38c5dc10bea41a705f23 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sun, 18 Apr 2004 17:25:21 +0000 Subject: [PATCH] * lily/my-lily-parser.cc (ly:parser-add-book-and-score): New function. * lily/parser.yy (toplevel_expression): Use it. * lily/include/my-lily-parser.hh: Smobbify. * lily/my-lily-parser.cc (parse_string): New method. * lily/my-lily-parser.cc (ly:parse-string): New function. --- ChangeLog | 10 +++ lily/includable-lexer.cc | 37 ++++----- lily/include/my-lily-lexer.hh | 2 +- lily/include/my-lily-parser.hh | 74 +++++++---------- lily/include/paper-line.hh | 2 +- lily/lexer.ll | 2 +- lily/my-lily-lexer.cc | 4 +- lily/my-lily-parser.cc | 148 ++++++++++++++++++++++++++------- lily/parser.yy | 73 +++++++--------- ly/declarations-init.ly | 5 +- 10 files changed, 216 insertions(+), 141 deletions(-) diff --git a/ChangeLog b/ChangeLog index e005535612..f489817fe5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2004-04-18 Jan Nieuwenhuizen + * lily/my-lily-parser.cc (ly:parser-add-book-and-score): New function. + + * lily/parser.yy (toplevel_expression): Use it. + + * lily/include/my-lily-parser.hh: Smobbify. + + * lily/my-lily-parser.cc (parse_string): New method. + + * lily/my-lily-parser.cc (ly:parse-string): New function. + * Documentation/user/lilypond.tely: Add comment and workaround for gs-8.01 crash. Fixes make web. diff --git a/lily/includable-lexer.cc b/lily/includable-lexer.cc index 587eefbba1..6c473c6d7e 100644 --- a/lily/includable-lexer.cc +++ b/lily/includable-lexer.cc @@ -40,10 +40,9 @@ Includable_lexer::Includable_lexer () allow_includes_b_ = true; } -/** set the new input to s, remember old file. -*/ +/** Set the new input file to NAME, remember old file. */ void -Includable_lexer::new_input (String s, Sources * global_sources) +Includable_lexer::new_input (String name, Sources *sources) { if (!allow_includes_b_) { @@ -51,45 +50,39 @@ Includable_lexer::new_input (String s, Sources * global_sources) return; } - Source_file *sl = global_sources->get_file (s); - if (!sl) + Source_file *file = sources->get_file (name); + if (!file) { - String msg = _f ("can't find file: `%s'", s); + String msg = _f ("can't find file: `%s'", name); msg += "\n"; msg += _f ("(search path: `%s')", - global_sources->path_->to_string ().to_str0 ()); + sources->path_->to_string ().to_str0 ()); msg += "\n"; LexerError (msg.to_str0 ()); return; } - filename_strings_.push (sl->name_string ()); + filename_strings_.push (file->name_string ()); char_count_stack_.push (0); if (yy_current_buffer) state_stack_.push (yy_current_buffer); if (verbose_global_b) - progress_indication (String ("[") + s); + progress_indication (String ("[") + name); - include_stack_.push (sl); - - /* - ugh. We'd want to create a buffer from the bytes directly. + include_stack_.push (file); - Whoops. The size argument to yy_create_buffer is not the - filelength but a BUFFERSIZE. Maybe this is why reading stdin fucks up. + /* Ugh. We'd want to create a buffer from the bytes directly. - */ - yy_switch_to_buffer (yy_create_buffer (sl->get_istream (), YY_BUF_SIZE)); + Whoops. The size argument to yy_create_buffer is not the + filelength but a BUFFERSIZE. Maybe this is why reading stdin fucks up. */ + yy_switch_to_buffer (yy_create_buffer (file->get_istream (), YY_BUF_SIZE)); } -/* - Unused. - */ void -Includable_lexer::new_input (String name, String data, Sources* sources) +Includable_lexer::new_input (String name, String data, Sources *sources) { - Source_file* file = new Source_file (name, data); + Source_file *file = new Source_file (name, data); sources->add (file); filename_strings_.push (name); diff --git a/lily/include/my-lily-lexer.hh b/lily/include/my-lily-lexer.hh index 2c115c82da..62f7693bb8 100644 --- a/lily/include/my-lily-lexer.hh +++ b/lily/include/my-lily-lexer.hh @@ -42,7 +42,7 @@ public: Protected_scm pitchname_tab_stack_; Keyword_table * keytable_; - int errorlevel_; + int error_level_; My_lily_lexer (Sources*); ~My_lily_lexer (); diff --git a/lily/include/my-lily-parser.hh b/lily/include/my-lily-parser.hh index af173c5317..eadac03ccd 100644 --- a/lily/include/my-lily-parser.hh +++ b/lily/include/my-lily-parser.hh @@ -6,20 +6,17 @@ (c) 1997--2004 Han-Wen Nienhuys */ - #ifndef MY_LILY_PARSER_HH #define MY_LILY_PARSER_HH -#include "protected-scm.hh" -#include "lily-proto.hh" -#include "string.hh" -#include "parray.hh" -#include "lily-proto.hh" +#include "array.hh" #include "duration.hh" +#include "input.hh" +#include "parray.hh" #include "pitch.hh" +#include "protected-scm.hh" +#include "smobs.hh" #include "string.hh" -#include "array.hh" -#include "input.hh" /** State for the parser. Do not ever add any variables to parse @@ -29,59 +26,52 @@ */ class My_lily_parser { -public: - My_lily_parser (Sources * sources); - ~My_lily_parser (); + DECLARE_SMOBS (My_lily_parser, ); + friend int yyparse (void*); - void do_init_file (); - void parse_file (String init, String file, String out_name); + Array define_spots_; + + char const* here_str0 () const; + Simultaneous_music *get_chord (Pitch tonic, + Array *adds, Array *subs, + Pitch *inversion, Pitch* bass, Duration d); + void set_chord_tremolo (int type_i); + void set_last_duration (Duration const *); + void set_last_pitch (Pitch const *); public: + My_lily_lexer *lexer_; + Sources *sources_; Duration default_duration_; String output_basename_; - Protected_scm header_; - int score_count_; int book_count_; - Sources *sources_; - int fatal_error_; int error_level_; - - My_lily_lexer * lexer_; bool ignore_version_b_; - SCM last_beam_start_; - void beam_check (SCM); + My_lily_parser (Sources *sources); + + DECLARE_SCHEME_CALLBACK (paper_description, ()); + Input here_input () const; - void push_spot (); Input pop_spot (); - + void beam_check (SCM); + void do_init_file (); void do_yyparse (); + void parse_file (String init, String name, String out_name); + void parse_string (String ly_code); void parser_error (String); - + void push_spot (); void set_yydebug (bool); - - - DECLARE_SCHEME_CALLBACK (paper_description, ()); -private: - - Array define_spots_; - - char const* here_str0 () const; - - Simultaneous_music * get_chord (Pitch tonic, Array* adds, - Array* subs, Pitch* inversion, - Pitch* bass, Duration d); - - void set_chord_tremolo (int type_i); - void set_last_duration (Duration const *); - void set_last_pitch (Pitch const *); - friend int yyparse (void*); }; +DECLARE_UNSMOB (My_lily_parser, my_lily_parser); + SCM ly_parse_file (SCM); +SCM ly_parse_string (SCM); +SCM ly_parser_add_book_and_score (SCM, SCM); -#endif // MY_LILY_PARSER_HH +#endif /* MY_LILY_PARSER_HH */ diff --git a/lily/include/paper-line.hh b/lily/include/paper-line.hh index 4fa1d50f4a..1281a104ae 100644 --- a/lily/include/paper-line.hh +++ b/lily/include/paper-line.hh @@ -14,7 +14,7 @@ class Paper_line { - DECLARE_SMOBS (Paper_line,); + DECLARE_SMOBS (Paper_line, ); SCM stencils_; Offset dim_; bool is_title_; diff --git a/lily/lexer.ll b/lily/lexer.ll index e0c9b74c34..b999b0477f 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -293,7 +293,7 @@ HYPHEN -- if (sval == SCM_UNDEFINED) { sval = SCM_UNSPECIFIED; - errorlevel_ = 1; + error_level_ = 1; } for (int i=0; i < n; i++) diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc index f23fdad76c..0365f15302 100644 --- a/lily/my-lily-lexer.cc +++ b/lily/my-lily-lexer.cc @@ -103,7 +103,7 @@ My_lily_lexer::My_lily_lexer (Sources *srcs) scopes_ = SCM_EOL; add_scope (ly_make_anonymous_module ()); - errorlevel_ = 0; + error_level_ = 0; main_input_b_ = false; } @@ -206,7 +206,7 @@ My_lily_lexer::LexerError (char const *s) progress_indication (_f ("error at EOF: %s", s) + String ("\n")); else { - errorlevel_ |= 1; + error_level_ |= 1; Input spot (get_source_file (), here_str0 ()); spot.error (s); } diff --git a/lily/my-lily-parser.cc b/lily/my-lily-parser.cc index df34f77a9e..e0820239f7 100644 --- a/lily/my-lily-parser.cc +++ b/lily/my-lily-parser.cc @@ -7,27 +7,24 @@ Jan Nieuwenhuizen */ +#include "book.hh" #include "file-path.hh" #include "lily-version.hh" #include "ly-module.hh" -#include "ly-module.hh" -#include "main.hh" +#include "ly-smobs.icc" #include "main.hh" #include "my-lily-lexer.hh" #include "my-lily-parser.hh" -#include "my-lily-parser.hh" #include "paper-def.hh" #include "parray.hh" #include "parser.hh" #include "scm-hash.hh" -#include "scm-hash.hh" #include "score.hh" #include "source.hh" #include "string.hh" #include "warn.hh" -#include "warn.hh" -My_lily_parser::My_lily_parser (Sources * sources) +My_lily_parser::My_lily_parser (Sources *sources) { book_count_ = 0; score_count_ = 0; @@ -36,8 +33,10 @@ My_lily_parser::My_lily_parser (Sources * sources) default_duration_ = Duration (2,0); error_level_ = 0; last_beam_start_ = SCM_EOL; + header_ = SCM_EOL; header_ = ly_make_anonymous_module (); + smobify_self (); } My_lily_parser::~My_lily_parser () @@ -45,14 +44,36 @@ My_lily_parser::~My_lily_parser () delete lexer_; } +IMPLEMENT_SMOBS (My_lily_parser); +IMPLEMENT_TYPE_P (My_lily_parser, "ly:my-lily-parser?"); +IMPLEMENT_DEFAULT_EQUAL_P (My_lily_parser); + +SCM +My_lily_parser::mark_smob (SCM s) +{ + My_lily_parser *parser = (My_lily_parser*) ly_cdr (s); + return parser->header_; +} + +int +My_lily_parser::print_smob (SCM s, SCM port, scm_print_state*) +{ + scm_puts ("#", port); + return 1; +} + + /* Process one .ly file, or book. */ void -My_lily_parser::parse_file (String init, String in_file, String out_file) +My_lily_parser::parse_file (String init, String name, String out_name) { lexer_ = new My_lily_lexer (sources_); - output_basename_ = out_file; + output_basename_ = out_name; - lexer_->main_input_name_ = in_file; + lexer_->main_input_name_ = name; progress_indication (_ ("Parsing...")); progress_indication ("\n"); @@ -70,10 +91,29 @@ My_lily_parser::parse_file (String init, String in_file, String out_file) error_level_ = 1; } - // fixme: dependencies - //input_file_->inclusion_names_ = lexer_->filename_strings_; + error_level_ = error_level_ | lexer_->error_level_; +} + +void +My_lily_parser::parse_string (String ly_code) +{ + lexer_ = new My_lily_lexer (sources_); + lexer_->main_input_name_ = ""; + lexer_->main_input_b_ = true; + SCM nn = lexer_->lookup_identifier ("pitchnames"); + lexer_->push_note_state (alist_to_hashq (nn)); + + set_yydebug (0); + lexer_->new_input (lexer_->main_input_name_, ly_code, sources_); + do_yyparse (); + + if (!define_spots_.is_empty ()) + { + define_spots_.top ().warning (_ ("Braces don't match")); + error_level_ = 1; + } - error_level_ = error_level_ | lexer_->errorlevel_; // ugh naming. + error_level_ = error_level_ | lexer_->error_level_; } void @@ -188,14 +228,14 @@ distill_inname (String str) return p; } -LY_DEFINE(ly_parse_file, "ly:parse-file", - 1,0,0, - (SCM name), - "Parse a single @code{.ly} file. If this fails, then throw @code{ly-file-failed} key. " - ) +LY_DEFINE (ly_parse_file, "ly:parse-file", + 1, 0, 0, + (SCM name), + "Parse a single @code{.ly} file. " + "Upon failure, throw @code{ly-file-failed} key.") { SCM_ASSERT_TYPE (ly_c_string_p (name), name, SCM_ARG1, __FUNCTION__, "string"); - char const *file = SCM_STRING_CHARS(name); + char const *file = SCM_STRING_CHARS (name); String infile (file); Path inpath = distill_inname (infile); @@ -243,17 +283,69 @@ LY_DEFINE(ly_parse_file, "ly:parse-file", progress_indication (_f ("Now processing `%s'", in_file.to_str0 ())); progress_indication ("\n"); - My_lily_parser parser (&sources); - parser.parse_file (init, in_file, out_file); - - if (parser.error_level_) - { - /* - TODO: pass renamed input file too. - */ - scm_throw (ly_symbol2scm ("ly-file-failed"), scm_list_1 (scm_makfrom0str (in_file.to_str0 ()))); - } + My_lily_parser *parser = new My_lily_parser (&sources); + parser->parse_file (init, in_file, out_file); + + bool error = parser->error_level_; + parser = 0; + if (error) + /* TODO: pass renamed input file too. */ + scm_throw (ly_symbol2scm ("ly-file-failed"), + scm_list_1 (scm_makfrom0str (in_file.to_str0 ()))); } return SCM_UNSPECIFIED; } +LY_DEFINE (ly_parse_string, "ly:parse-string", + 1, 0, 0, + (SCM ly_code), + "Parse the string LY_CODE. " + "Upon failure, throw @code{ly-file-failed} key.") +{ + SCM_ASSERT_TYPE (ly_c_string_p (ly_code), ly_code, SCM_ARG1, __FUNCTION__, "string"); + + Sources sources; + sources.set_path (&global_path); + My_lily_parser *parser = new My_lily_parser (&sources); + parser->parse_string (ly_scm2string (ly_code)); + parser = 0; + + return SCM_UNSPECIFIED; +} + + +LY_DEFINE (ly_parser_add_book_and_score, "ly:parser-add-book-and-score", + 2, 0, 0, + (SCM purple, SCM music), + "Handle the toplevel-music MUSIC by adding BOOK and SCORE.") +{ +#if 0 + SCM_ASSERT_TYPE (ly_c_parser_p (parser), music, SCM_ARG1, __FUNCTION__, "parser"); + SCM_ASSERT_TYPE (ly_c_music_p (music), music, SCM_ARG1, __FUNCTION__, "music"); +#endif + My_lily_parser *parser = unsmob_my_lily_parser (purple); + Score *score = new Score; + + /* URG? */ + SCM check_funcs = ly_scheme_function ("toplevel-music-functions"); + for (; ly_c_pair_p (check_funcs); check_funcs = ly_cdr (check_funcs)) + music = scm_call_1 (ly_car (check_funcs), music); + score->music_ = music; + Book *book = new Book; + book->scores_.push (score); + scm_gc_unprotect_object (score->self_scm ()); + + SCM header = parser->header_; + Path outname = split_path (parser->output_basename_); + int *c = &parser->book_count_; + if (*c) + outname.base += "-" + to_string (*c); + (*c)++; + My_lily_lexer *lexer = parser->lexer_; + Music_output_def *dp + = unsmob_music_output_def (lexer->lookup_identifier ("$defaultpaper")); + book->process (outname.to_string (), + dp ? dp->clone () : new Paper_def, header); + scm_gc_unprotect_object (book->self_scm ()); + return SCM_UNDEFINED; +} diff --git a/lily/parser.yy b/lily/parser.yy index c8c6fa4cdf..4d04513049 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -81,7 +81,13 @@ tag_music (Music *m, SCM tag, Input ip) m->set_property ("tags", tags); } - +Music_output_def* +get_paper (My_lily_parser *parser) +{ + SCM id = parser->lexer_->lookup_identifier ("$defaultpaper"); + Music_output_def *paper = unsmob_music_output_def (id); + return paper ? paper->clone () : new Paper_def; +} bool is_regular_identifier (SCM id) @@ -376,7 +382,7 @@ or %type Composite_music Simple_music %type Repeated_music %type Alternative_music -%type Composite_music_list +//%type Composite_music_list %type tremolo_type %type bare_int bare_unsigned %type script_dir @@ -426,8 +432,10 @@ prec levels in different prods */ lilypond: /* empty */ | lilypond EOI - | lilypond toplevel_expression {} - | lilypond assignment { } + | lilypond toplevel_expression { + } + | lilypond assignment { + } | lilypond error { THIS->error_level_ = 1; } @@ -441,33 +449,12 @@ toplevel_expression: THIS->header_ = $1; } | toplevel_music EOI { - Score *score = new Score; - SCM s = $1->self_scm (); - - /* URG? */ - SCM check_funcs - = ly_scheme_function ("toplevel-music-functions"); - for (; ly_c_pair_p (check_funcs); - check_funcs = ly_cdr (check_funcs)) - s = scm_call_1 (ly_car (check_funcs), s); - score->music_ = s; - - Book *book = new Book; - book->scores_.push (score); - - scm_gc_unprotect_object (score->self_scm ()); - - SCM header = THIS->header_; - Path outname = split_path (THIS->output_basename_); - int *c = &THIS->book_count_; - if (*c) - outname.base += "-" + to_string (*c); - (*c)++; - Music_output_def *dp = unsmob_music_output_def - (THIS->lexer_->lookup_identifier ("$defaultpaper")); - book->process (outname.to_string (), - dp ? dp->clone () : new Paper_def, header); - scm_gc_unprotect_object (book->self_scm ()); + Music_output_def *paper = get_paper (THIS); + // delay? + // SCM proc = paper->get_scmvar ("toplevel-music-handler"); + SCM proc = ly_scheme_function ("ly:parser-add-book-and-score"); + scm_call_2 (proc, THIS->self_scm (), $1->self_scm ()); + scm_gc_unprotect_object (paper->self_scm ()); } | add_quote { @@ -480,11 +467,10 @@ toplevel_expression: if (*c) outname.base += "-" + to_string (*c); (*c)++; - Music_output_def *dp = unsmob_music_output_def - (THIS->lexer_->lookup_identifier ("$defaultpaper")); - book->process (outname.to_string (), - dp ? dp->clone () : new Paper_def, header); + Music_output_def *paper = get_paper (THIS); + book->process (outname.to_string (), paper, header); scm_gc_unprotect_object (book->self_scm ()); + scm_gc_unprotect_object (paper->self_scm ()); } | score_block { /* TODO: implicit book, depending on --no-book/--no-page-layout @@ -508,12 +494,10 @@ toplevel_expression: if (score->defs_.is_empty ()) { - Music_output_def *id = unsmob_music_output_def - (THIS->lexer_->lookup_identifier ("$defaultpaper")); - id = id ? id->clone () : new Paper_def; - default_rendering (score->music_, id->self_scm (), head, + Music_output_def *paper = get_paper (THIS); + default_rendering (score->music_, paper->self_scm (), head, outname); - scm_gc_unprotect_object (id->self_scm ()); + scm_gc_unprotect_object (paper->self_scm ()); } scm_gc_unprotect_object (score->self_scm ()); } @@ -847,8 +831,9 @@ Alternative_music: } ; +/* Composite_music_list: {}; -/* Too many s/r r/r problems + Too many s/r r/r problems Composite_music { $$ = scm_cons ($1, SCM_EOL); } @@ -1864,7 +1849,8 @@ open_event: | E_CLOSE { Music *s= MY_MAKE_MUSIC ("PhrasingSlurEvent"); $$ = s; - s->set_property ("span-type", scm_makfrom0str ( "phrasing-slur")); + s->set_property ("span-type", + scm_makfrom0str ("phrasing-slur")); s->set_spot (THIS->here_input ()); } ; @@ -1878,7 +1864,8 @@ gen_text_def: } | string { Music *t = MY_MAKE_MUSIC ("TextScriptEvent"); - t->set_property ("text", make_simple_markup (THIS->lexer_->encoding (), $1)); + t->set_property ("text", + make_simple_markup (THIS->lexer_->encoding (), $1)); t->set_spot (THIS->here_input ()); $$ = t; diff --git a/ly/declarations-init.ly b/ly/declarations-init.ly index fb97f53a81..37eb01d06b 100644 --- a/ly/declarations-init.ly +++ b/ly/declarations-init.ly @@ -74,7 +74,10 @@ melismaEnd = #(make-span-event 'ManualMelismaEvent STOP) )) #(define page-breaking ly:ragged-page-breaks) - %#(define page-breaking ly:optimal-page-breaks) + %%#(define page-breaking ly:optimal-page-breaks) + + %% FIXME: too late? + #(define toplevel-music-handler ly:parser-add-book-and-score) \include "engraver-init.ly" } -- 2.39.5