preprocessor: add @#ifndef directive
parent
ebc7a783bd
commit
20f2c1760b
|
@ -6540,8 +6540,8 @@ line. The main directives are:
|
||||||
@item
|
@item
|
||||||
@code{@@#define}, for defining a macro-processor variable,
|
@code{@@#define}, for defining a macro-processor variable,
|
||||||
@item
|
@item
|
||||||
@code{@@#if}, @code{@@#ifdef}, @code{@@#else}, @code{@@#endif} for
|
@code{@@#if}, @code{@@#ifdef}, @code{@@#ifndef}, @code{@@#else},
|
||||||
conditional statements,
|
@code{@@#endif} for conditional statements,
|
||||||
@item
|
@item
|
||||||
@code{@@#for}, @code{@@#endfor} for constructing loops.
|
@code{@@#for}, @code{@@#endfor} for constructing loops.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
@ -6684,10 +6684,11 @@ end;
|
||||||
|
|
||||||
@deffn {Macro directive} @@#if @var{MACRO_EXPRESSION}
|
@deffn {Macro directive} @@#if @var{MACRO_EXPRESSION}
|
||||||
@deffnx {Macro directive} @@#ifdef @var{MACRO_VARIABLE}
|
@deffnx {Macro directive} @@#ifdef @var{MACRO_VARIABLE}
|
||||||
|
@deffnx {Macro directive} @@#ifndef @var{MACRO_VARIABLE}
|
||||||
@deffnx {Macro directive} @@#else
|
@deffnx {Macro directive} @@#else
|
||||||
@deffnx {Macro directive} @@#endif
|
@deffnx {Macro directive} @@#endif
|
||||||
Conditional inclusion of some part of the @file{.mod} file.
|
Conditional inclusion of some part of the @file{.mod} file.
|
||||||
The lines between @code{@@#if} or @code{@@#ifdef} and the next
|
The lines between @code{@@#if}, @code{@@#ifdef} or @code{@@#ifndef} and the next
|
||||||
@code{@@#else} or @code{@@#endif} is executed only if the condition
|
@code{@@#else} or @code{@@#endif} is executed only if the condition
|
||||||
evaluates to a non-null integer. The @code{@@#else} branch is optional
|
evaluates to a non-null integer. The @code{@@#else} branch is optional
|
||||||
and, if present, is only evaluated if the condition evaluates to
|
and, if present, is only evaluated if the condition evaluates to
|
||||||
|
@ -6726,6 +6727,21 @@ model;
|
||||||
end;
|
end;
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
Choose between two alternative monetary policy rules using a
|
||||||
|
macro-variable. As @code{linear_mon_pol} was not previously defined in
|
||||||
|
this example, the first equation will be chosen:
|
||||||
|
|
||||||
|
@example
|
||||||
|
model;
|
||||||
|
@@#ifndef linear_mon_pol
|
||||||
|
i = w*i(-1) + (1-w)*i_ss + w2*(pie-piestar);
|
||||||
|
@@#else
|
||||||
|
i = i(-1)^w * i_ss^(1-w) * (pie/piestar)^w2;
|
||||||
|
@@#endif
|
||||||
|
...
|
||||||
|
end;
|
||||||
|
@end example
|
||||||
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Macro directive} @@#for @var{MACRO_VARIABLE} in @var{MACRO_EXPRESSION}
|
@deffn {Macro directive} @@#for @var{MACRO_VARIABLE} in @var{MACRO_EXPRESSION}
|
||||||
|
|
|
@ -79,7 +79,7 @@ class MacroDriver;
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%token DEFINE LINE FOR IN IF ELSE ENDIF ECHO_DIR ERROR IFDEF
|
%token DEFINE LINE FOR IN IF ELSE ENDIF ECHO_DIR ERROR IFDEF IFNDEF
|
||||||
%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL
|
%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL
|
||||||
|
|
||||||
%token <int_val> INTEGER
|
%token <int_val> INTEGER
|
||||||
|
@ -119,6 +119,8 @@ statement : expr
|
||||||
{ TYPERR_CATCH(driver.begin_if($2), @$); }
|
{ TYPERR_CATCH(driver.begin_if($2), @$); }
|
||||||
| IFDEF NAME
|
| IFDEF NAME
|
||||||
{ TYPERR_CATCH(driver.begin_ifdef(*$2), @$); delete $2; }
|
{ TYPERR_CATCH(driver.begin_ifdef(*$2), @$); delete $2; }
|
||||||
|
| IFNDEF NAME
|
||||||
|
{ TYPERR_CATCH(driver.begin_ifndef(*$2), @$); delete $2; }
|
||||||
| ECHO_DIR expr
|
| ECHO_DIR expr
|
||||||
{ TYPERR_CATCH(driver.echo(@$, $2), @$); }
|
{ TYPERR_CATCH(driver.echo(@$, $2), @$); }
|
||||||
| ERROR expr
|
| ERROR expr
|
||||||
|
|
|
@ -178,6 +178,20 @@ MacroDriver::begin_ifdef(const string &name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MacroDriver::begin_ifndef(const string &name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
get_variable(name);
|
||||||
|
begin_if(new IntMV(*this, 0));
|
||||||
|
}
|
||||||
|
catch (UnknownVariable &)
|
||||||
|
{
|
||||||
|
begin_if(new IntMV(*this, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MacroDriver::echo(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError)
|
MacroDriver::echo(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError)
|
||||||
{
|
{
|
||||||
|
|
|
@ -211,6 +211,9 @@ public:
|
||||||
//! Begins an @#ifdef statement
|
//! Begins an @#ifdef statement
|
||||||
void begin_ifdef(const string &name);
|
void begin_ifdef(const string &name);
|
||||||
|
|
||||||
|
//! Begins an @#ifndef statement
|
||||||
|
void begin_ifndef(const string &name);
|
||||||
|
|
||||||
//! Executes @#echo directive
|
//! Executes @#echo directive
|
||||||
void echo(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError);
|
void echo(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError);
|
||||||
|
|
||||||
|
|
|
@ -165,10 +165,11 @@ CONT \\\\
|
||||||
<STMT>endfor { driver.error(*yylloc, "@#endfor is not matched by a @#for statement"); }
|
<STMT>endfor { driver.error(*yylloc, "@#endfor is not matched by a @#for statement"); }
|
||||||
|
|
||||||
<STMT>ifdef { reading_if_statement = true; return token::IFDEF; }
|
<STMT>ifdef { reading_if_statement = true; return token::IFDEF; }
|
||||||
|
<STMT>ifndef { reading_if_statement = true; return token::IFNDEF; }
|
||||||
|
|
||||||
<STMT>if { reading_if_statement = true; return token::IF; }
|
<STMT>if { reading_if_statement = true; return token::IF; }
|
||||||
<STMT>else { driver.error(*yylloc, "@#else is not matched by an @#if/@#ifdef statement"); }
|
<STMT>else { driver.error(*yylloc, "@#else is not matched by an @#if/@#ifdef/@#ifndef statement"); }
|
||||||
<STMT>endif { driver.error(*yylloc, "@#endif is not matched by an @#if/@#ifdef statement"); }
|
<STMT>endif { driver.error(*yylloc, "@#endif is not matched by an @#if/@#ifdef/@#ifndef statement"); }
|
||||||
|
|
||||||
<STMT>echo { return token::ECHO_DIR; }
|
<STMT>echo { return token::ECHO_DIR; }
|
||||||
<STMT>error { return token::ERROR; }
|
<STMT>error { return token::ERROR; }
|
||||||
|
@ -225,7 +226,7 @@ CONT \\\\
|
||||||
yylloc->step();
|
yylloc->step();
|
||||||
}
|
}
|
||||||
<THEN_BODY>. { then_body_tmp.append(yytext); yylloc->step(); }
|
<THEN_BODY>. { then_body_tmp.append(yytext); yylloc->step(); }
|
||||||
<THEN_BODY><<EOF>> { driver.error(if_stmt_loc_tmp, "@#if/@#ifdef not matched by an @#endif (unexpected end of file)"); }
|
<THEN_BODY><<EOF>> { driver.error(if_stmt_loc_tmp, "@#if/@#ifdef/@#ifndef not matched by an @#endif (unexpected end of file)"); }
|
||||||
<THEN_BODY>^{SPC}*@#{SPC}*else{SPC}*(\/\/.*)?{EOL} {
|
<THEN_BODY>^{SPC}*@#{SPC}*else{SPC}*(\/\/.*)?{EOL} {
|
||||||
yylloc->lines(1);
|
yylloc->lines(1);
|
||||||
yylloc->step();
|
yylloc->step();
|
||||||
|
@ -267,7 +268,7 @@ CONT \\\\
|
||||||
yylloc->step();
|
yylloc->step();
|
||||||
}
|
}
|
||||||
<ELSE_BODY>. { else_body_tmp.append(yytext); yylloc->step(); }
|
<ELSE_BODY>. { else_body_tmp.append(yytext); yylloc->step(); }
|
||||||
<ELSE_BODY><<EOF>> { driver.error(if_stmt_loc_tmp, "@#if/@#ifdef not matched by an @#endif (unexpected end of file)"); }
|
<ELSE_BODY><<EOF>> { driver.error(if_stmt_loc_tmp, "@#if/@#ifdef/@#ifndef not matched by an @#endif (unexpected end of file)"); }
|
||||||
|
|
||||||
<ELSE_BODY>^{SPC}*@#{SPC}*endif{SPC}*(\/\/.*)?{EOL} {
|
<ELSE_BODY>^{SPC}*@#{SPC}*endif{SPC}*(\/\/.*)?{EOL} {
|
||||||
yylloc->lines(1);
|
yylloc->lines(1);
|
||||||
|
|
Loading…
Reference in New Issue