macroprocessor: intersection operator. #5

issue#70
Houtan Bastani 2018-08-08 14:15:39 +02:00
parent 039b27bbaf
commit 428b5023d3
4 changed files with 32 additions and 1 deletions

View File

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

View File

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

View File

@ -132,6 +132,12 @@ MacroValue::set_union(const MacroValuePtr &mv) noexcept(false)
throw TypeError("Operator | does not exist for this type");
}
shared_ptr<ArrayMV>
MacroValue::set_intersection(const MacroValuePtr &mv) noexcept(false)
{
throw TypeError("Operator & does not exist for this type");
}
IntMV::IntMV(int value_arg) : value{value_arg}
{
}
@ -562,6 +568,25 @@ ArrayMV::set_union(const MacroValuePtr &mv) noexcept(false)
return make_shared<ArrayMV>(new_values);
}
shared_ptr<ArrayMV>
ArrayMV::set_intersection(const MacroValuePtr &mv) noexcept(false)
{
auto mv2 = dynamic_pointer_cast<ArrayMV>(mv);
if (!mv2)
throw TypeError("Arguments of the intersection operator (|) must be sets");
vector<MacroValuePtr> new_values;
for (auto &it : mv2->values)
for (auto &nvit : values)
if (nvit->is_equal(it)->value)
{
new_values.push_back(it);
break;
}
return make_shared<ArrayMV>(new_values);
}
TupleMV::TupleMV(vector<MacroValuePtr> values_arg) : values{move(values_arg)}
{
}

View File

@ -107,6 +107,8 @@ public:
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);
//! Creates the intersection of two sets
virtual shared_ptr<ArrayMV> set_intersection(const MacroValuePtr &mv) noexcept(false);
};
//! Represents an integer value in macro language
@ -213,6 +215,7 @@ public:
*/
static shared_ptr<ArrayMV> range(const MacroValuePtr &mv1, const MacroValuePtr &mv2) noexcept(false);
shared_ptr<ArrayMV> set_union(const MacroValuePtr &mvp) noexcept(false) override;
shared_ptr<ArrayMV> set_intersection(const MacroValuePtr &mvp) noexcept(false) override;
};
//! Represents a tuple value in macro language