macroprocessor: introduce tuple type. #5
parent
c342489397
commit
1285473aa1
|
@ -84,7 +84,7 @@ class MacroDriver;
|
|||
|
||||
%type <vector<string>> func_args
|
||||
%type <MacroValuePtr> expr
|
||||
%type <vector<MacroValuePtr>> comma_expr
|
||||
%type <vector<MacroValuePtr>> comma_expr tuple_comma_expr
|
||||
%%
|
||||
|
||||
%start statement_list_or_nothing;
|
||||
|
@ -136,6 +136,8 @@ expr : INTEGER
|
|||
{ $$ = make_shared<IntMV>($1); }
|
||||
| STRING
|
||||
{ $$ = make_shared<StringMV>(driver.replace_vars_in_str($1)); }
|
||||
| LPAREN tuple_comma_expr RPAREN
|
||||
{ $$ = make_shared<TupleMV>($2); }
|
||||
| NAME
|
||||
{
|
||||
try
|
||||
|
@ -213,6 +215,16 @@ comma_expr : %empty
|
|||
{ $1.push_back($3); $$ = $1; }
|
||||
;
|
||||
|
||||
tuple_comma_expr : %empty
|
||||
{ $$ = vector<MacroValuePtr>{}; } // Empty array
|
||||
| expr COMMA
|
||||
{ $$ = vector<MacroValuePtr>{$1}; }
|
||||
| expr COMMA expr
|
||||
{ $$ = vector<MacroValuePtr>{$1, $3}; }
|
||||
| tuple_comma_expr COMMA expr
|
||||
{ $1.push_back($3); $$ = $1; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
|
|
|
@ -531,3 +531,110 @@ ArrayMV::range(const MacroValuePtr &mv1, const MacroValuePtr &mv2) noexcept(fals
|
|||
result.push_back(make_shared<IntMV>(v1));
|
||||
return make_shared<ArrayMV>(result);
|
||||
}
|
||||
|
||||
TupleMV::TupleMV(vector<MacroValuePtr> values_arg) : values{move(values_arg)}
|
||||
{
|
||||
}
|
||||
|
||||
shared_ptr<IntMV>
|
||||
TupleMV::is_equal(const MacroValuePtr &mv)
|
||||
{
|
||||
auto mv2 = dynamic_pointer_cast<TupleMV>(mv);
|
||||
if (!mv2 || values.size() != mv2->values.size())
|
||||
return make_shared<IntMV>(0);
|
||||
|
||||
auto it = values.cbegin();
|
||||
auto it2 = mv2->values.cbegin();
|
||||
while (it != values.cend())
|
||||
{
|
||||
if ((*it)->is_different(*it2)->value)
|
||||
return make_shared<IntMV>(0);
|
||||
++it;
|
||||
++it2;
|
||||
}
|
||||
return make_shared<IntMV>(1);
|
||||
}
|
||||
|
||||
MacroValuePtr
|
||||
TupleMV::subscript(const MacroValuePtr &mv) noexcept(false)
|
||||
{
|
||||
vector<MacroValuePtr> result;
|
||||
|
||||
auto copy_element = [&](int i) {
|
||||
if (i < 1 || i > static_cast<int>(values.size()))
|
||||
throw OutOfBoundsError();
|
||||
result.push_back(values[i - 1]);
|
||||
};
|
||||
|
||||
auto mv2 = dynamic_pointer_cast<IntMV>(mv);
|
||||
auto mv3 = dynamic_pointer_cast<TupleMV>(mv);
|
||||
|
||||
if (mv2)
|
||||
copy_element(mv2->value);
|
||||
else if (mv3)
|
||||
for (auto &v : mv3->values)
|
||||
{
|
||||
auto v2 = dynamic_pointer_cast<IntMV>(v);
|
||||
if (!v2)
|
||||
throw TypeError("Expression inside [] must be an integer or an integer array");
|
||||
copy_element(v2->value);
|
||||
}
|
||||
else
|
||||
throw TypeError("Expression inside [] must be an integer or an integer array");
|
||||
|
||||
if (result.size() > 1 || result.size() == 0)
|
||||
return make_shared<TupleMV>(result);
|
||||
else
|
||||
return result[0];
|
||||
}
|
||||
|
||||
string
|
||||
TupleMV::toString()
|
||||
{
|
||||
ostringstream ss;
|
||||
bool print_comma = false;
|
||||
ss << "(";
|
||||
for (auto &v : values)
|
||||
{
|
||||
if (print_comma)
|
||||
ss << ", ";
|
||||
else
|
||||
print_comma = true;
|
||||
ss << v->toString();
|
||||
}
|
||||
ss << ")";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
shared_ptr<IntMV>
|
||||
TupleMV::length() noexcept(false)
|
||||
{
|
||||
return make_shared<IntMV>(values.size());
|
||||
}
|
||||
|
||||
string
|
||||
TupleMV::print()
|
||||
{
|
||||
ostringstream ss;
|
||||
ss << "(";
|
||||
for (auto it = values.begin();
|
||||
it != values.end(); it++)
|
||||
{
|
||||
if (it != values.begin())
|
||||
ss << ", ";
|
||||
|
||||
ss << (*it)->print();
|
||||
}
|
||||
ss << ")";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
shared_ptr<IntMV>
|
||||
TupleMV::in(const MacroValuePtr &mv) noexcept(false)
|
||||
{
|
||||
for (auto &v : values)
|
||||
if (v->is_equal(mv)->value)
|
||||
return make_shared<IntMV>(1);
|
||||
|
||||
return make_shared<IntMV>(0);
|
||||
}
|
||||
|
|
|
@ -212,4 +212,24 @@ public:
|
|||
static shared_ptr<ArrayMV> range(const MacroValuePtr &mv1, const MacroValuePtr &mv2) noexcept(false);
|
||||
};
|
||||
|
||||
//! Represents a tuple value in macro language
|
||||
class TupleMV : public MacroValue
|
||||
{
|
||||
public:
|
||||
TupleMV(vector<MacroValuePtr> values_arg);
|
||||
|
||||
//! Underlying vector
|
||||
const vector<MacroValuePtr> values;
|
||||
|
||||
shared_ptr<IntMV> is_equal(const MacroValuePtr &mv) override;
|
||||
//! Subscripting operator
|
||||
/*! Argument must be an ArrayMV<int>. Indexes begin at 1. Returns a StringMV. */
|
||||
MacroValuePtr subscript(const MacroValuePtr &mv) noexcept(false) override;
|
||||
//! Returns underlying string value
|
||||
string toString() override;
|
||||
string print() override;
|
||||
shared_ptr<IntMV> length() noexcept(false) override;
|
||||
shared_ptr<IntMV> in(const MacroValuePtr &mv) noexcept(false) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue