* 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.
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.
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_)
{
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);
Protected_scm pitchname_tab_stack_;
Keyword_table * keytable_;
- int errorlevel_;
+ int error_level_;
My_lily_lexer (Sources*);
~My_lily_lexer ();
(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 */
class Paper_line
{
- DECLARE_SMOBS (Paper_line,);
+ DECLARE_SMOBS (Paper_line, );
SCM stencils_;
Offset dim_;
bool is_title_;
if (sval == SCM_UNDEFINED)
{
sval = SCM_UNSPECIFIED;
- errorlevel_ = 1;
+ error_level_ = 1;
}
for (int i=0; i < n; i++)
scopes_ = SCM_EOL;
add_scope (ly_make_anonymous_module ());
- errorlevel_ = 0;
+ error_level_ = 0;
main_input_b_ = false;
}
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);
}
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;
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 ()
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");
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
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);
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;
+}
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)
%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
lilypond: /* empty */
| lilypond EOI
- | lilypond toplevel_expression {}
- | lilypond assignment { }
+ | lilypond toplevel_expression {
+ }
+ | lilypond assignment {
+ }
| lilypond error {
THIS->error_level_ = 1;
}
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 {
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
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 ());
}
}
;
+/*
Composite_music_list: {};
-/* Too many s/r r/r problems
+ Too many s/r r/r problems
Composite_music {
$$ = scm_cons ($1, SCM_EOL);
}
| 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 ());
}
;
}
| 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;
))
#(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"
}