preprocessor: add @#ifndef directive
parent
ebc7a783bd
commit
20f2c1760b
|
@ -6540,8 +6540,8 @@ line. The main directives are:
|
|||
@item
|
||||
@code{@@#define}, for defining a macro-processor variable,
|
||||
@item
|
||||
@code{@@#if}, @code{@@#ifdef}, @code{@@#else}, @code{@@#endif} for
|
||||
conditional statements,
|
||||
@code{@@#if}, @code{@@#ifdef}, @code{@@#ifndef}, @code{@@#else},
|
||||
@code{@@#endif} for conditional statements,
|
||||
@item
|
||||
@code{@@#for}, @code{@@#endfor} for constructing loops.
|
||||
@end itemize
|
||||
|
@ -6684,10 +6684,11 @@ end;
|
|||
|
||||
@deffn {Macro directive} @@#if @var{MACRO_EXPRESSION}
|
||||
@deffnx {Macro directive} @@#ifdef @var{MACRO_VARIABLE}
|
||||
@deffnx {Macro directive} @@#ifndef @var{MACRO_VARIABLE}
|
||||
@deffnx {Macro directive} @@#else
|
||||
@deffnx {Macro directive} @@#endif
|
||||
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
|
||||
evaluates to a non-null integer. The @code{@@#else} branch is optional
|
||||
and, if present, is only evaluated if the condition evaluates to
|
||||
|
@ -6726,6 +6727,21 @@ model;
|
|||
end;
|
||||
@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
|
||||
|
||||
@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 <int_val> INTEGER
|
||||
|
@ -119,6 +119,8 @@ statement : expr
|
|||
{ TYPERR_CATCH(driver.begin_if($2), @$); }
|
||||
| IFDEF NAME
|
||||
{ TYPERR_CATCH(driver.begin_ifdef(*$2), @$); delete $2; }
|
||||
| IFNDEF NAME
|
||||
{ TYPERR_CATCH(driver.begin_ifndef(*$2), @$); delete $2; }
|
||||
| ECHO_DIR expr
|
||||
{ TYPERR_CATCH(driver.echo(@$, $2), @$); }
|
||||
| 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
|
||||
MacroDriver::echo(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError)
|
||||
{
|
||||
|
|
|
@ -211,6 +211,9 @@ public:
|
|||
//! Begins an @#ifdef statement
|
||||
void begin_ifdef(const string &name);
|
||||
|
||||
//! Begins an @#ifndef statement
|
||||
void begin_ifndef(const string &name);
|
||||
|
||||
//! Executes @#echo directive
|
||||
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>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>else { driver.error(*yylloc, "@#else is not matched by an @#if/@#ifdef statement"); }
|
||||
<STMT>endif { driver.error(*yylloc, "@#endif 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/@#ifndef statement"); }
|
||||
|
||||
<STMT>echo { return token::ECHO_DIR; }
|
||||
<STMT>error { return token::ERROR; }
|
||||
|
@ -225,7 +226,7 @@ CONT \\\\
|
|||
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} {
|
||||
yylloc->lines(1);
|
||||
yylloc->step();
|
||||
|
@ -267,7 +268,7 @@ CONT \\\\
|
|||
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} {
|
||||
yylloc->lines(1);
|
||||
|
|
Loading…
Reference in New Issue