Refactoring of pya/rba/expressions

Goal is to support "*!" which is a variant of multiplication
without the commutative nature.

The refactoring yields a more consistent handling of
Python specializations. Now this happens when the methods
are collected, rather than later. This way, specific behavior
for identically named synonyms can be implemented for example.
This is the case for the "*" operator in Trans which is partially
commutative and partially not.
This commit is contained in:
Matthias Koefferlein 2022-10-20 23:26:14 +02:00
parent c012bb846e
commit fbd4c84d84
8 changed files with 766 additions and 682 deletions

View File

@ -932,5 +932,5 @@ if __name__ == "__main__":
include_package_data=True,
ext_modules=[_tl, _gsi, _pya, _rba, _db, _lib, _rdb, _lym, _laybasic, _layview, _ant, _edt, _img]
+ db_plugins
+ [tl, db, lib, rdb, lay])
+ [tl, db, lib, rdb, lay]
)

View File

@ -304,7 +304,7 @@ struct trans_defs
"\n"
"This convenience method has been introduced in version 0.25."
) +
method ("*", &C::concat, arg ("t"),
method ("*!", &C::concat, arg ("t"),
"@brief Returns the concatenated transformation\n"
"\n"
"The * operator returns self*t (\"t is applied before this transformation\").\n"
@ -829,7 +829,7 @@ struct cplx_trans_defs
"\n"
"This convenience method has been introduced in version 0.25."
) +
method ("*", (C (C::*) (const C &c) const) &C::concat_same, arg ("t"),
method ("*!", (C (C::*) (const C &c) const) &C::concat_same, arg ("t"),
"@brief Returns the concatenated transformation\n"
"\n"
"The * operator returns self*t (\"t is applied before this transformation\").\n"
@ -1047,7 +1047,7 @@ Class<db::DCplxTrans> decl_DCplxTrans ("db", "DCplxTrans",
"\n"
"This method has been introduced in version 0.25."
) +
method ("*", (db::CplxTrans (db::DCplxTrans::*) (const db::CplxTrans &) const) &db::DCplxTrans::concat, gsi::arg ("t"),
method ("*!", (db::CplxTrans (db::DCplxTrans::*) (const db::CplxTrans &) const) &db::DCplxTrans::concat, gsi::arg ("t"),
"@brief Multiplication (concatenation) of transformations\n"
"\n"
"The * operator returns self*t (\"t is applied before this transformation\").\n"
@ -1126,7 +1126,7 @@ Class<db::CplxTrans> decl_CplxTrans ("db", "CplxTrans",
"\n"
"This method has been introduced in version 0.25."
) +
method ("*", (db::DCplxTrans (db::CplxTrans::*) (const db::VCplxTrans &) const) &db::CplxTrans::concat, gsi::arg ("t"),
method ("*!", (db::DCplxTrans (db::CplxTrans::*) (const db::VCplxTrans &) const) &db::CplxTrans::concat, gsi::arg ("t"),
"@brief Multiplication (concatenation) of transformations\n"
"\n"
"The * operator returns self*t (\"t is applied before this transformation\").\n"
@ -1134,7 +1134,7 @@ Class<db::CplxTrans> decl_CplxTrans ("db", "CplxTrans",
"@param t The transformation to apply before\n"
"@return The modified transformation\n"
) +
method ("*", (db::CplxTrans (db::CplxTrans::*) (const db::ICplxTrans &) const) &db::CplxTrans::concat, gsi::arg ("t"),
method ("*!", (db::CplxTrans (db::CplxTrans::*) (const db::ICplxTrans &) const) &db::CplxTrans::concat, gsi::arg ("t"),
"@brief Multiplication (concatenation) of transformations\n"
"\n"
"The * operator returns self*t (\"t is applied before this transformation\").\n"
@ -1216,7 +1216,7 @@ Class<db::ICplxTrans> decl_ICplxTrans ("db", "ICplxTrans",
"\n"
"This method has been introduced in version 0.25."
) +
method ("*", (db::VCplxTrans (db::ICplxTrans::*) (const db::VCplxTrans &) const) &db::ICplxTrans::concat, gsi::arg ("t"),
method ("*!", (db::VCplxTrans (db::ICplxTrans::*) (const db::VCplxTrans &) const) &db::ICplxTrans::concat, gsi::arg ("t"),
"@brief Multiplication (concatenation) of transformations\n"
"\n"
"The * operator returns self*t (\"t is applied before this transformation\").\n"
@ -1288,7 +1288,7 @@ Class<db::VCplxTrans> decl_VCplxTrans ("db", "VCplxTrans",
"\n"
"This method has been introduced in version 0.25."
) +
method ("*", (db::VCplxTrans (db::VCplxTrans::*) (const db::DCplxTrans &) const) &db::VCplxTrans::concat, gsi::arg ("t"),
method ("*!", (db::VCplxTrans (db::VCplxTrans::*) (const db::DCplxTrans &) const) &db::VCplxTrans::concat, gsi::arg ("t"),
"@brief Multiplication (concatenation) of transformations\n"
"\n"
"The * operator returns self*t (\"t is applied before this transformation\").\n"
@ -1296,7 +1296,7 @@ Class<db::VCplxTrans> decl_VCplxTrans ("db", "VCplxTrans",
"@param t The transformation to apply before\n"
"@return The modified transformation\n"
) +
method ("*", (db::ICplxTrans (db::VCplxTrans::*) (const db::CplxTrans &) const) &db::VCplxTrans::concat, gsi::arg ("t"),
method ("*!", (db::ICplxTrans (db::VCplxTrans::*) (const db::CplxTrans &) const) &db::VCplxTrans::concat, gsi::arg ("t"),
"@brief Multiplication (concatenation) of transformations\n"
"\n"
"The * operator returns self*t (\"t is applied before this transformation\").\n"

View File

@ -199,6 +199,9 @@ private:
for (gsi::MethodBase::synonym_iterator syn = (*m)->begin_synonyms (); syn != (*m)->end_synonyms (); ++syn) {
if (syn->is_setter) {
add_method (syn->name + "=", *m);
} else if (syn->name == "*!") {
// non-commutative multiplication
add_method ("*", *m);
} else {
add_method (syn->name, *m);
}

View File

@ -85,7 +85,7 @@ void MethodBase::parse_name (const std::string &name)
{
const char *n = name.c_str ();
if (*n == '*' && n[1] && n[1] != '*' && n[1] != '=') {
if (*n == '*' && n[1] && n[1] != '*' && n[1] != '!' && n[1] != '=') {
m_protected = true;
++n;
}

View File

@ -589,3 +589,12 @@ TEST(10)
EXPECT_EQ (v.to_string (), std::string ("2"));
}
TEST(11)
{
tl::Eval e;
tl::Variant v;
// mapping of *! to *:
v = e.parse ("var b = Trans.new(1)*Trans.new(Vector.new(10, 20))").execute ();
EXPECT_EQ (v.to_string (), std::string ("r90 -20,10"));
}

View File

@ -149,6 +149,8 @@ full_name (const gsi::MethodBase::MethodSynonym &syn)
return syn.name + "?";
} else if (syn.is_setter) {
return syn.name + "=";
} else if (syn.name == "*!") {
return "*";
} else {
return syn.name;
}

File diff suppressed because it is too large Load Diff

View File

@ -1556,6 +1556,17 @@ rba_add_path (const std::string &path)
}
}
static std::string
ruby_name (const std::string &n)
{
if (n == "*!") {
// non-commutative multiplication
return "*";
} else {
return n;
}
}
namespace
{
@ -1672,7 +1683,7 @@ public:
} else if (syn->is_setter) {
mt->add_method (syn->name + "=", *m);
} else {
mt->add_method (syn->name, *m);
mt->add_method (ruby_name (syn->name), *m);
}
}
@ -1709,7 +1720,7 @@ public:
} else {
mt->add_method (syn->name, *m);
mt->add_method (ruby_name (syn->name), *m);
}
}