macroprocessor: union operator. #5

issue#70
Houtan Bastani 2018-08-07 12:40:59 +02:00
parent 1285473aa1
commit 039b27bbaf
4 changed files with 37 additions and 1 deletions

View File

@ -78,7 +78,7 @@ class MacroDriver;
%nonassoc IN
%nonassoc COLON
%left PLUS MINUS
%left TIMES DIVIDE
%left TIMES DIVIDE UNION
%precedence UMINUS UPLUS EXCLAMATION
%precedence LBRACKET
@ -205,6 +205,8 @@ expr : INTEGER
{ TYPERR_CATCH($$ = ArrayMV::range($1, $3), @$); }
| expr IN expr
{ TYPERR_CATCH($$ = $3->in($1), @$); }
| expr UNION expr
{ TYPERR_CATCH($$ = $1->set_union($3), @$); }
;
comma_expr : %empty

View File

@ -218,6 +218,7 @@ CONT \\\\
<STMT,EXPR>[!] { return token::EXCLAMATION; }
<STMT,EXPR>"||" { return token::LOGICAL_OR; }
<STMT,EXPR>&& { return token::LOGICAL_AND; }
<STMT,EXPR>"|" { return token::UNION; }
<STMT,EXPR>"<=" { return token::LESS_EQUAL; }
<STMT,EXPR>">=" { return token::GREATER_EQUAL; }
<STMT,EXPR>"<" { return token::LESS; }

View File

@ -126,6 +126,12 @@ MacroValue::in(const MacroValuePtr &mv) noexcept(false)
throw TypeError("Second argument of 'in' operator must be an array");
}
shared_ptr<ArrayMV>
MacroValue::set_union(const MacroValuePtr &mv) noexcept(false)
{
throw TypeError("Operator | does not exist for this type");
}
IntMV::IntMV(int value_arg) : value{value_arg}
{
}
@ -532,6 +538,30 @@ ArrayMV::range(const MacroValuePtr &mv1, const MacroValuePtr &mv2) noexcept(fals
return make_shared<ArrayMV>(result);
}
shared_ptr<ArrayMV>
ArrayMV::set_union(const MacroValuePtr &mv) noexcept(false)
{
auto mv2 = dynamic_pointer_cast<ArrayMV>(mv);
if (!mv2)
throw TypeError("Arguments of the union operator (|) must be sets");
vector<MacroValuePtr> new_values = values;
for (auto &it : mv2->values)
{
bool found = false;
for (auto &nvit : new_values)
if (nvit->is_equal(it)->value)
{
found = true;
break;
}
if (!found)
new_values.push_back(it);
}
return make_shared<ArrayMV>(new_values);
}
TupleMV::TupleMV(vector<MacroValuePtr> values_arg) : values{move(values_arg)}
{
}

View File

@ -105,6 +105,8 @@ public:
//! Applies "in" operator
/*! The argument is the element to be tested for inclusion. Returns an IntMV, equal to 0 or 1 */
virtual shared_ptr<IntMV> in(const MacroValuePtr &mv) noexcept(false);
//! Creates the union of two sets
virtual shared_ptr<ArrayMV> set_union(const MacroValuePtr &mv) noexcept(false);
};
//! Represents an integer value in macro language
@ -210,6 +212,7 @@ public:
If mv2 < mv1, returns an empty range (for consistency with MATLAB).
*/
static shared_ptr<ArrayMV> range(const MacroValuePtr &mv1, const MacroValuePtr &mv2) noexcept(false);
shared_ptr<ArrayMV> set_union(const MacroValuePtr &mvp) noexcept(false) override;
};
//! Represents a tuple value in macro language