From 2d15137289d9b4095685507991d0bd908b3b8e30 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 2 Jan 2012 18:08:14 +0100 Subject: [PATCH] macroprocessor: add @#ifdef --- macro/MacroBison.yy | 4 +++- macro/MacroDriver.cc | 18 ++++++++++++++++++ macro/MacroDriver.hh | 3 +++ macro/MacroFlex.ll | 2 ++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/macro/MacroBison.yy b/macro/MacroBison.yy index 3774e34c..32e661a1 100644 --- a/macro/MacroBison.yy +++ b/macro/MacroBison.yy @@ -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 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 diff --git a/macro/MacroDriver.cc b/macro/MacroDriver.cc index 21adc04e..acf4396d 100644 --- a/macro/MacroDriver.cc +++ b/macro/MacroDriver.cc @@ -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) { diff --git a/macro/MacroDriver.hh b/macro/MacroDriver.hh index 92c95dfc..702f2f0c 100644 --- a/macro/MacroDriver.hh +++ b/macro/MacroDriver.hh @@ -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); diff --git a/macro/MacroFlex.ll b/macro/MacroFlex.ll index 1d1927cb..ba14678b 100644 --- a/macro/MacroFlex.ll +++ b/macro/MacroFlex.ll @@ -164,6 +164,8 @@ CONT \\\\ for { reading_for_statement = true; return token::FOR; } endfor { driver.error(*yylloc, "@#endfor is not matched by a @#for statement"); } +ifdef { reading_if_statement = true; return token::IFDEF; } + if { reading_if_statement = true; return token::IF; } else { driver.error(*yylloc, "@#else is not matched by an @#if statement"); } endif { driver.error(*yylloc, "@#endif is not matched by an @#if statement"); }