Commit 045e20e2 authored by sebastien's avatar sebastien
Browse files

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
parent 6a80037d
......@@ -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
......
......@@ -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; }
......
......@@ -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);
}
......@@ -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
......
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