parser->lexer_->override_input (spot))
/* ES TODO:
-- Don't use lily module, create a new module instead.
- delay application of the function
*/
-static SCM
-syntax_call (void *arg)
-{
- SCM sarg = reinterpret_cast <SCM> (arg);
- return scm_apply_0 (scm_car (sarg), scm_cdr (sarg));
-}
-
-#define LOWLEVEL_MAKE_SYNTAX(location, args) \
- scm_c_with_fluid \
- (Lily::f_location, \
- parser->lexer_->override_input (location).smobbed_copy (), \
- syntax_call, \
- reinterpret_cast <void*> (args))
+#define LOWLEVEL_MAKE_SYNTAX(location, proc, ...) \
+ with_location \
+ (parser->lexer_->override_input (location).smobbed_copy (), \
+ proc, \
+ ##__VA_ARGS__)
/* Syntactic Sugar. */
#define MAKE_SYNTAX(name, location, ...) \
- LOWLEVEL_MAKE_SYNTAX (location, \
- scm_list_n (Lily::name, \
- ##__VA_ARGS__, SCM_UNDEFINED))
+ LOWLEVEL_MAKE_SYNTAX (location, Syntax::name, ##__VA_ARGS__)
#define START_MAKE_SYNTAX(name, ...) \
- scm_list_n (Lily::name, \
- ##__VA_ARGS__, SCM_UNDEFINED)
+ scm_list_n (Syntax::name, ##__VA_ARGS__, SCM_UNDEFINED)
#define FINISH_MAKE_SYNTAX(start, location, ...) \
- LOWLEVEL_MAKE_SYNTAX (location, \
- scm_append_x \
- (scm_list_2 (start, scm_list_n \
- (__VA_ARGS__, SCM_UNDEFINED))))
+ LOWLEVEL_MAKE_SYNTAX \
+ (location, \
+ Guile_user::apply, \
+ scm_car (start), \
+ scm_append_x \
+ (scm_list_2 (scm_cdr (start), \
+ scm_list_n (__VA_ARGS__, SCM_UNDEFINED))))
SCM get_next_unique_context_id ();
SCM get_next_unique_lyrics_context_id ();
%token DESCRIPTION "\\description"
%token DRUMMODE "\\drummode"
%token DRUMS "\\drums"
+%token ETC "\\etc"
%token FIGUREMODE "\\figuremode"
%token FIGURES "\\figures"
%token HEADER "\\header"
$$ = parser->lexer_->eval_scm_token ($1, @1);
}
| FRACTION
+ | partial_markup
| full_markup_list
| context_modification
| score_block
| FRACTION
| string
| embedded_scm
+ | partial_markup
| full_markup_list
| context_modification
+ | partial_function ETC
+ {
+ $$ = MAKE_SYNTAX (partial_music_function, @$,
+ scm_reverse_x (scm_car ($1), SCM_EOL),
+ scm_reverse_x (scm_cdr ($1), SCM_EOL));
+ }
+ ;
+
+// Partial functions
+partial_function:
+ MUSIC_FUNCTION function_arglist_partial
+ {
+ $$ = scm_cons (scm_list_1 ($1), scm_list_1 ($2));
+ }
+ | EVENT_FUNCTION function_arglist_partial
+ {
+ $$ = scm_cons (scm_list_1 ($1), scm_list_1 ($2));
+ }
+ | SCM_FUNCTION function_arglist_partial
+ {
+ $$ = scm_cons (scm_list_1 ($1), scm_list_1 ($2));
+ }
+ | MUSIC_FUNCTION EXPECT_SCM function_arglist_optional partial_function
+ {
+ $$ = scm_cons (scm_cons ($1, scm_car ($4)),
+ scm_cons ($3, scm_cdr ($4)));
+ }
+ | EVENT_FUNCTION EXPECT_SCM function_arglist_optional partial_function
+ {
+ $$ = scm_cons (scm_cons ($1, scm_car ($4)),
+ scm_cons ($3, scm_cdr ($4)));
+ }
+ | SCM_FUNCTION EXPECT_SCM function_arglist_optional partial_function
+ {
+ $$ = scm_cons (scm_cons ($1, scm_car ($4)),
+ scm_cons ($3, scm_cdr ($4)));
+ }
+ | MUSIC_FUNCTION EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup partial_function
+ {
+ $$ = scm_cons (scm_cons ($1, scm_car ($5)),
+ scm_cons ($4, scm_cdr ($5)));
+ }
+ | EVENT_FUNCTION EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup partial_function
+ {
+ $$ = scm_cons (scm_cons ($1, scm_car ($5)),
+ scm_cons ($4, scm_cdr ($5)));
+ }
+ | SCM_FUNCTION EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup partial_function
+ {
+ $$ = scm_cons (scm_cons ($1, scm_car ($5)),
+ scm_cons ($4, scm_cdr ($5)));
+ }
;
context_def_spec_block:
}
;
+// Partial function arglists are returned just in their incomplete
+// state: when combined with the music function, the missing parts of
+// the signature can be reconstructed
+//
+// To serve as a partial arglist, the argument list must absolutely
+// _not_ be in "skipping optional arguments" mode since then there is
+// some backup token that has nowhere to go before \etc.
+//
+// So we can skim off an arbitrary number of arguments from the end of
+// the argument list. The argument list remaining afterwards has to
+// be in not-skipping-optional-arguments mode.
+
+function_arglist_partial:
+ EXPECT_SCM function_arglist_optional
+ {
+ $$ = $2;
+ }
+ | EXPECT_SCM function_arglist_partial_optional
+ {
+ $$ = $2;
+ }
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup
+ {
+ $$ = $3;
+ }
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist_partial
+ {
+ $$ = $3;
+ }
+ ;
+
+function_arglist_partial_optional:
+ EXPECT_SCM function_arglist_optional
+ {
+ $$ = $2;
+ }
+ | EXPECT_SCM function_arglist_partial_optional
+ {
+ $$ = $2;
+ }
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup
+ {
+ $$ = $3;
+ }
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist_partial_optional
+ {
+ $$ = $3;
+ }
+ ;
+
function_arglist_common:
EXPECT_NO_MORE_ARGS {
$$ = SCM_EOL;
}
;
-full_markup:
+markup_mode:
MARKUP
- { parser->lexer_->push_markup_state (); }
- markup_top {
- $$ = $3;
+ {
+ parser->lexer_->push_markup_state ();
+ }
+ ;
+
+full_markup:
+ markup_mode markup_top {
+ $$ = $2;
+ parser->lexer_->pop_state ();
+ }
+ ;
+
+partial_markup:
+ markup_mode markup_head_1_list ETC
+ {
+ $$ = MAKE_SYNTAX (partial_markup, @2, $2);
parser->lexer_->pop_state ();
}
;