From ca066ea39803028b5229161ee278ade1a5ed85a2 Mon Sep 17 00:00:00 2001 From: Houtan Bastani <houtan@dynare.org> Date: Wed, 8 Aug 2018 15:58:49 +0200 Subject: [PATCH] macroprocessor: introduce shortcut for Cartesion product (^). #5 --- src/macro/MacroBison.yy | 6 ++++-- src/macro/MacroFlex.ll | 1 + src/macro/MacroValue.cc | 23 +++++++++++++++++++++++ src/macro/MacroValue.hh | 4 ++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/macro/MacroBison.yy b/src/macro/MacroBison.yy index 9372964d..868379b8 100644 --- a/src/macro/MacroBison.yy +++ b/src/macro/MacroBison.yy @@ -66,7 +66,7 @@ class MacroDriver; } -%token COMMA DEFINE LINE FOR IN IF ECHO_DIR ERROR IFDEF IFNDEF +%token COMMA DEFINE LINE FOR IN IF ECHO_DIR ERROR IFDEF IFNDEF POWER %token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL LENGTH ECHOMACROVARS SAVE %token <int> INTEGER @@ -78,7 +78,7 @@ class MacroDriver; %nonassoc IN %nonassoc COLON %left PLUS MINUS -%left TIMES DIVIDE UNION INTERSECTION +%left TIMES DIVIDE UNION INTERSECTION POWER %precedence UMINUS UPLUS EXCLAMATION %precedence LBRACKET @@ -209,6 +209,8 @@ expr : INTEGER { TYPERR_CATCH($$ = $1->set_union($3), @$); } | expr INTERSECTION expr { TYPERR_CATCH($$ = $1->set_intersection($3), @$); } + | expr POWER expr + { TYPERR_CATCH($$ = $1->power($3), @$); } ; comma_expr : %empty diff --git a/src/macro/MacroFlex.ll b/src/macro/MacroFlex.ll index f4640784..7502f662 100644 --- a/src/macro/MacroFlex.ll +++ b/src/macro/MacroFlex.ll @@ -220,6 +220,7 @@ CONT \\\\ <STMT,EXPR>&& { return token::LOGICAL_AND; } <STMT,EXPR>"|" { return token::UNION; } <STMT,EXPR>"&" { return token::INTERSECTION; } +<STMT,EXPR>"^" { return token::POWER; } <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 73695d94..737168c9 100644 --- a/src/macro/MacroValue.cc +++ b/src/macro/MacroValue.cc @@ -138,6 +138,12 @@ MacroValue::set_intersection(const MacroValuePtr &mv) noexcept(false) throw TypeError("Operator & does not exist for this type"); } +MacroValuePtr +MacroValue::power(const MacroValuePtr &mv) noexcept(false) +{ + throw TypeError("Operator ^ does not exist for this type"); +} + IntMV::IntMV(int value_arg) : value{value_arg} { } @@ -648,6 +654,23 @@ ArrayMV::set_intersection(const MacroValuePtr &mv) noexcept(false) return make_shared<ArrayMV>(new_values); } +MacroValuePtr +ArrayMV::power(const MacroValuePtr &mv) noexcept(false) +{ + auto mv2 = dynamic_pointer_cast<IntMV>(mv); + if (!mv2) + throw TypeError("The second argument of the power operator (^) must be an integer"); + + shared_ptr<ArrayMV> retval = make_shared<ArrayMV>(values); + for (int i = 1; i < mv2->value; i++) + { + shared_ptr<MacroValue> mvp = retval->times(make_shared<ArrayMV>(values)); + retval = make_shared<ArrayMV>(dynamic_pointer_cast<ArrayMV>(mvp)->values); + } + + return retval; +} + TupleMV::TupleMV(vector<MacroValuePtr> values_arg) : values{move(values_arg)} { } diff --git a/src/macro/MacroValue.hh b/src/macro/MacroValue.hh index 5e35292f..37a41dad 100644 --- a/src/macro/MacroValue.hh +++ b/src/macro/MacroValue.hh @@ -109,6 +109,8 @@ public: 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); + //! Power as shortcut for Cartesion product + virtual MacroValuePtr power(const MacroValuePtr &mv) noexcept(false); }; //! Represents an integer value in macro language @@ -218,6 +220,8 @@ public: shared_ptr<ArrayMV> set_intersection(const MacroValuePtr &mvp) noexcept(false) override; // Computes the Cartesian product of two sets MacroValuePtr times(const MacroValuePtr &mv) noexcept(false) override; + // Shortcut for Cartesian product of two sets + MacroValuePtr power(const MacroValuePtr &mv) noexcept(false) override; }; //! Represents a tuple value in macro language -- GitLab