diff --git a/src/macro/MacroBison.yy b/src/macro/MacroBison.yy index 5b9bac62f1fb6544229df3802715a878effc1452..9372964d58911aec4ad66429beb08b6708505f77 100644 --- a/src/macro/MacroBison.yy +++ b/src/macro/MacroBison.yy @@ -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 diff --git a/src/macro/MacroFlex.ll b/src/macro/MacroFlex.ll index 8dae3b4a57f3172649dcb7ded5980f46b5386105..f4640784c744797202f37d2e63d304da3306f1db 100644 --- a/src/macro/MacroFlex.ll +++ b/src/macro/MacroFlex.ll @@ -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; } diff --git a/src/macro/MacroValue.cc b/src/macro/MacroValue.cc index e64ae065afcf9675e240f2531ff3a1f7dcdcc36a..6d6efe996bce80957214844e3306f832fb2e283a 100644 --- a/src/macro/MacroValue.cc +++ b/src/macro/MacroValue.cc @@ -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)} { } diff --git a/src/macro/MacroValue.hh b/src/macro/MacroValue.hh index a26b466b9577a78ad4056338bafda1bc17e2ed12..810d48d08c29efa88ea3f943cab0490a2dcca0c8 100644 --- a/src/macro/MacroValue.hh +++ b/src/macro/MacroValue.hh @@ -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