macroprocessor: introduce shortcut for Cartesion product (^). #5

issue#70
Houtan Bastani 2018-08-08 15:58:49 +02:00
parent d9c0568075
commit ca066ea398
4 changed files with 32 additions and 2 deletions

View File

@ -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

View File

@ -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; }

View File

@ -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)}
{
}

View File

@ -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