From 045e20e284691aa1eb67ece2dd0ecb214f209f51 Mon Sep 17 00:00:00 2001 From: sebastien <sebastien@ac1d8469-bf42-47a9-8791-bf33cf982152> Date: Mon, 8 Dec 2008 15:13:08 +0000 Subject: [PATCH] trunk preprocessor/macro: added new 'in' operator for testing membership of an array git-svn-id: https://www.dynare.org/svn/dynare/dynare_v4@2300 ac1d8469-bf42-47a9-8791-bf33cf982152 --- macro/MacroBison.yy | 3 +++ macro/MacroFlex.ll | 2 +- macro/MacroValue.cc | 44 ++++++++++++++++++++++++++++++++++++++++++++ macro/MacroValue.hh | 7 ++++++- 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/macro/MacroBison.yy b/macro/MacroBison.yy index e44f5bfc..8caa736c 100644 --- a/macro/MacroBison.yy +++ b/macro/MacroBison.yy @@ -85,6 +85,7 @@ class MacroDriver; %left LOGICAL_OR %left LOGICAL_AND %left LESS GREATER LESS_EQUAL GREATER_EQUAL EQUAL_EQUAL EXCLAMATION_EQUAL +%nonassoc IN %nonassoc COLON %left PLUS MINUS %left TIMES DIVIDE @@ -180,6 +181,8 @@ expr : INTEGER { $$ = $2; } | expr COLON expr { TYPERR_CATCH($$ = IntMV::new_range(driver, $1, $3), @$); } + | expr IN expr + { TYPERR_CATCH($$ = $1->in($3), @$); } ; array_expr : expr diff --git a/macro/MacroFlex.ll b/macro/MacroFlex.ll index d74ab064..557b9733 100644 --- a/macro/MacroFlex.ll +++ b/macro/MacroFlex.ll @@ -144,6 +144,7 @@ CONT \\\\ <STMT,EXPR>[-] { return token::MINUS; } <STMT,EXPR>[*] { return token::TIMES; } <STMT,EXPR>[/] { return token::DIVIDE; } +<STMT,EXPR>in { return token::IN; } <STMT,EXPR>\"[^\"]*\" { yylval->string_val = new string(yytext + 1); @@ -155,7 +156,6 @@ CONT \\\\ <STMT>define { return token::DEFINE; } <STMT>for { reading_for_statement = true; return token::FOR; } -<STMT>in { return token::IN; } <STMT>endfor { driver.error(*yylloc, "@#endfor is not matched by a @#for statement"); } <STMT>if { reading_if_statement = true; return token::IF; } diff --git a/macro/MacroValue.cc b/macro/MacroValue.cc index d3dcce6a..be509f67 100644 --- a/macro/MacroValue.cc +++ b/macro/MacroValue.cc @@ -112,6 +112,12 @@ MacroValue::append(const MacroValue *mv) const throw (TypeError) throw TypeError("Cannot append an array at the end of another one. Should use concatenation."); } +const MacroValue * +MacroValue::in(const MacroValue *array) const throw (TypeError) +{ + throw TypeError("First argument of 'in' operator cannot be an array"); +} + const MacroValue * MacroValue::new_base_value(MacroDriver &driver, int i) { @@ -288,6 +294,25 @@ IntMV::append(const MacroValue *array) const throw (TypeError) return new ArrayMV<int>(driver, v); } +const MacroValue * +IntMV::in(const MacroValue *array) const throw (TypeError) +{ + const ArrayMV<int> *array2 = dynamic_cast<const ArrayMV<int> *>(array); + if (array2 == NULL) + throw TypeError("Type mismatch for 'in' operator"); + + int result = 0; + for(vector<int>::const_iterator it = array2->values.begin(); + it != array2->values.end(); it++) + if (*it == value) + { + result = 1; + break; + } + + return new IntMV(driver, result); +} + const MacroValue * IntMV::new_range(MacroDriver &driver, const MacroValue *mv1, const MacroValue *mv2) throw (TypeError) { @@ -392,3 +417,22 @@ StringMV::append(const MacroValue *array) const throw (TypeError) v.push_back(value); return new ArrayMV<string>(driver, v); } + +const MacroValue * +StringMV::in(const MacroValue *array) const throw (TypeError) +{ + const ArrayMV<string> *array2 = dynamic_cast<const ArrayMV<string> *>(array); + if (array2 == NULL) + throw TypeError("Type mismatch for 'in' operator"); + + int result = 0; + for(vector<string>::const_iterator it = array2->values.begin(); + it != array2->values.end(); it++) + if (*it == value) + { + result = 1; + break; + } + + return new IntMV(driver, result); +} diff --git a/macro/MacroValue.hh b/macro/MacroValue.hh index 77b6bb22..da2df145 100644 --- a/macro/MacroValue.hh +++ b/macro/MacroValue.hh @@ -91,8 +91,11 @@ public: //! Converts value to array form virtual const MacroValue *toArray() const = 0; //! Appends value at the end of an array - /*! The first argument must be an array. */ + /*! The argument must be an array. */ virtual const MacroValue *append(const MacroValue *array) const throw (TypeError); + //! Applies "in" operator + /*! The argument must be an array. Returns an IntMV, equal to 0 or 1 */ + virtual const MacroValue *in(const MacroValue *array) const throw (TypeError); //! Returns a new IntMV /*! Necessary for ArrayMV::operator[] (template issue) */ static const MacroValue *new_base_value(MacroDriver &driver, int i); @@ -144,6 +147,7 @@ public: //! Appends value at the end of an array /*! The first argument must be an integer array. */ virtual const MacroValue *append(const MacroValue *array) const throw (TypeError); + virtual const MacroValue *in(const MacroValue *array) const throw (TypeError); //! Creates a integer range /*! Arguments must be of type IntMV. Returns an integer array containing all integers between mv1 and mv2. @@ -177,6 +181,7 @@ public: //! Appends value at the end of an array /*! The first argument must be a string array. Returns a string array. */ virtual const MacroValue *append(const MacroValue *array) const throw (TypeError); + virtual const MacroValue *in(const MacroValue *array) const throw (TypeError); }; //! Represents an array in macro language -- GitLab