Commit 143c5f56 authored by Houtan Bastani's avatar Houtan Bastani
Browse files

macroprocessor: add @#ifdef

parent 72788cf5
......@@ -6075,8 +6075,8 @@ line. The main directives are:
@item
@code{@@#define}, for defining a macro-processor variable,
@item
@code{@@#if}, @code{@@#else}, @code{@@#endif} for conditional
statements,
@code{@@#if}, @code{@@#ifdef}, @code{@@#else}, @code{@@#endif} for
conditional statements,
@item
@code{@@#for}, @code{@@#endfor} for constructing loops.
@end itemize
......@@ -6218,13 +6218,15 @@ end;
@end deffn
@deffn {Macro directive} @@#if @var{MACRO_EXPRESSION}
@deffnx {Macro directive} @@#ifdef @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} 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 @code{0}.
The lines between @code{@@#if} or @code{@@#ifdef} 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
@code{0}.
@examplehead
......@@ -6242,6 +6244,23 @@ model;
end;
@end example
@examplehead
Choose between two alternative monetary policy rules using a
macro-variable. As @code{linear_mon_pol} was not previously defined in
this example, the second equation will be chosen:
@example
model;
@@#ifdef 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
%token DEFINE LINE FOR IN IF ELSE ENDIF ECHO_DIR ERROR IFDEF
%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL
%token <int_val> INTEGER
......@@ -117,6 +117,8 @@ statement : expr
{ TYPERR_CATCH(driver.init_loop(*$2, $4), @$); delete $2; }
| IF expr
{ TYPERR_CATCH(driver.begin_if($2), @$); }
| IFDEF NAME
{ TYPERR_CATCH(driver.begin_ifdef(*$2), @$); delete $2; }
| ECHO_DIR expr
{ TYPERR_CATCH(driver.echo(@$, $2), @$); }
| ERROR expr
......
......@@ -164,6 +164,24 @@ MacroDriver::begin_if(const MacroValue *value) throw (MacroValue::TypeError)
last_if = (bool) ival->value;
}
void
MacroDriver::begin_ifdef(const string &name)
{
try
{
get_variable(name);
const MacroValue *one = new IntMV(*this, 1);
begin_if(one);
delete one;
}
catch (UnknownVariable &)
{
const MacroValue *zero = new IntMV(*this, 0);
begin_if(zero);
delete zero;
}
}
void
MacroDriver::echo(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError)
{
......
......@@ -208,6 +208,9 @@ public:
//! Begins an @#if statement
void begin_if(const MacroValue *value) throw (MacroValue::TypeError);
//! Begins an @#ifdef statement
void begin_ifdef(const string &name);
//! Executes @#echo directive
void echo(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError);
......
......@@ -164,6 +164,8 @@ CONT \\\\
<STMT>for { reading_for_statement = true; return token::FOR; }
<STMT>endfor { driver.error(*yylloc, "@#endfor is not matched by a @#for statement"); }
<STMT>ifdef { reading_if_statement = true; return token::IFDEF; }
<STMT>if { reading_if_statement = true; return token::IF; }
<STMT>else { driver.error(*yylloc, "@#else is not matched by an @#if statement"); }
<STMT>endif { driver.error(*yylloc, "@#endif is not matched by an @#if statement"); }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment