]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/my-lily-parser.cc (ly:parser-add-book-and-score): New function.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sun, 18 Apr 2004 17:25:21 +0000 (17:25 +0000)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sun, 18 Apr 2004 17:25:21 +0000 (17:25 +0000)
* 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
lily/includable-lexer.cc
lily/include/my-lily-lexer.hh
lily/include/my-lily-parser.hh
lily/include/paper-line.hh
lily/lexer.ll
lily/my-lily-lexer.cc
lily/my-lily-parser.cc
lily/parser.yy
ly/declarations-init.ly

index e005535612e0dba63a85ce5fa05cf97cf0637389..f489817fe55822fbeefe9a46ce33056473eb14a8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2004-04-18  Jan Nieuwenhuizen  <janneke@gnu.org>
 
+       * 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.
 
index 587eefbba1105b209c8e55114e581d04f0119ef1..6c473c6d7e0b674bad7c5c4bcfa986306772c5be 100644 (file)
@@ -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, Sourcessources)
+Includable_lexer::new_input (String name, String data, Sources *sources)
 {
-  Source_filefile = new Source_file (name, data);
+  Source_file *file = new Source_file (name, data);
   sources->add (file);
   filename_strings_.push (name);
 
index 2c115c82da2508c959e7f9727960ea51c76f0ce1..62f7693bb83b39d29d4908f321d56ceb1c8f0123 100644 (file)
@@ -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 ();
index af173c5317e4674da0bf9a9920c8107021754a76..eadac03ccd4f3178abc1a98b90b5feda1646da74 100644 (file)
@@ -6,20 +6,17 @@
   (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
 */
 
-
 #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
 */
 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<Input> define_spots_;
+
+  char const* here_str0 () const;
+  Simultaneous_music *get_chord (Pitch tonic,
+                                Array<Pitch> *adds, Array<Pitch> *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<Input> define_spots_;
-
-  char const* here_str0 () const;
-
-  Simultaneous_music * get_chord (Pitch tonic, Array<Pitch>* adds,
-                                 Array<Pitch>* 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 */
index 4fa1d50f4a919def4c787c71fb8b4770e11d4052..1281a104ae1967976a8bf4693ebadd775c014c70 100644 (file)
@@ -14,7 +14,7 @@
 
 class Paper_line
 {
-  DECLARE_SMOBS (Paper_line,);
+  DECLARE_SMOBS (Paper_line, );
   SCM stencils_;
   Offset dim_;
   bool is_title_;
index e0c9b74c34acafc81fab8b16f1b6ae9b0888f336..b999b0477f3c486ab988e16ba73508bcb7ef5616 100644 (file)
@@ -293,7 +293,7 @@ HYPHEN              --
        if (sval == SCM_UNDEFINED)
        {
                sval = SCM_UNSPECIFIED;
-               errorlevel_ = 1;
+               error_level_ = 1;
        }
 
        for (int i=0; i < n; i++)
index f23fdad76c469d7e7b8355889c4a49ab87aacbeb..0365f15302f5d7922db901272f50800112ce61ff 100644 (file)
@@ -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);
     }
index df34f77a9edf3bafc518402528a82a74734e7c7e..e0820239f753a020737c0d05d8e4538149049cd4 100644 (file)
@@ -7,27 +7,24 @@
        Jan Nieuwenhuizen <janneke@gnu.org>
 */
 
+#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 ("#<my_lily_parser ", port);
+  My_lily_parser *parser = (My_lily_parser*) ly_cdr (s);
+  (void) parser;
+  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_ = "<string>";
+  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;
+}
index c8c6fa4cdf505bf15256405ae222fd72cdc4f5fc..4d04513049828de3f2f690becaeaf5f68ca524b6 100644 (file)
@@ -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 <music>  Composite_music Simple_music
 %type <music>  Repeated_music
 %type <scm>     Alternative_music
-%type <scm>     Composite_music_list
+//%type <scm>     Composite_music_list
 %type <i>      tremolo_type
 %type <i>      bare_int  bare_unsigned
 %type <i>      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;
        
index fb97f53a81ce9534f7dcf55c3580a91713faad23..37eb01d06b11c76bf4c17b08c49507ab40fe5293 100644 (file)
@@ -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"
 }