mirror of https://github.com/KLayout/klayout.git
WIP: keyword arguments for expressions
This commit is contained in:
parent
4a4db5ea6e
commit
f685fe3adf
|
|
@ -431,7 +431,7 @@ public:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector <tl::Variant> &vv) const
|
||||
void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector <tl::Variant> &vv, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (vv.size () != 0) {
|
||||
throw tl::EvalError (tl::to_string (tr ("Annotation function must not have arguments")), context);
|
||||
|
|
|
|||
|
|
@ -2194,7 +2194,7 @@ public:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args) const
|
||||
void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (args.size () > 0) {
|
||||
throw tl::EvalError (tl::to_string (tr ("Query function does not allow parameters")), context);
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ namespace db
|
|||
args.push_back (value);
|
||||
}
|
||||
tl::ExpressionParserContext context;
|
||||
ref.user_cls ()->eval_cls ()->execute (context, out, ref, m, args);
|
||||
ref.user_cls ()->eval_cls ()->execute (context, out, ref, m, args, 0);
|
||||
|
||||
ref = out;
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ namespace db
|
|||
|
||||
std::vector<tl::Variant> args;
|
||||
tl::ExpressionParserContext context;
|
||||
ref.user_cls ()->eval_cls ()->execute (context, out, ref, m, args);
|
||||
ref.user_cls ()->eval_cls ()->execute (context, out, ref, m, args, 0);
|
||||
|
||||
ref = out;
|
||||
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ SaveLayoutOptions::set_option_by_name (const std::string &method, const tl::Vari
|
|||
tl::Variant out;
|
||||
std::vector<tl::Variant> args;
|
||||
args.push_back (value);
|
||||
eval_cls->execute (context, out, options_ref, method + "=", args);
|
||||
eval_cls->execute (context, out, options_ref, method + "=", args, 0);
|
||||
}
|
||||
|
||||
tl::Variant
|
||||
|
|
@ -151,7 +151,7 @@ SaveLayoutOptions::get_option_by_name (const std::string &method)
|
|||
|
||||
tl::Variant out;
|
||||
std::vector<tl::Variant> args;
|
||||
eval_cls->execute (context, out, options_ref, method, args);
|
||||
eval_cls->execute (context, out, options_ref, method, args, 0);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ public:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void execute (const tl::ExpressionParserContext & /*context*/, tl::Variant &out, const std::vector<tl::Variant> &args) const
|
||||
void execute (const tl::ExpressionParserContext & /*context*/, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
out = mp_proc->receiver (args);
|
||||
}
|
||||
|
|
@ -506,7 +506,7 @@ public:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void execute (const tl::ExpressionParserContext & /*context*/, tl::Variant & /*out*/, const std::vector<tl::Variant> &args) const
|
||||
void execute (const tl::ExpressionParserContext & /*context*/, tl::Variant & /*out*/, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
mp_proc->put (m_ix, m_iy, m_tile_box, args);
|
||||
}
|
||||
|
|
@ -526,7 +526,7 @@ public:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void execute (const tl::ExpressionParserContext & /*context*/, tl::Variant & /*out*/, const std::vector<tl::Variant> & /*args*/) const
|
||||
void execute (const tl::ExpressionParserContext & /*context*/, tl::Variant & /*out*/, const std::vector<tl::Variant> & /*args*/, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
// TODO: ... implement ..
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ template<class T, bool> struct _var_user_to_string_impl;
|
|||
template<class T>
|
||||
struct _var_user_to_string_impl<T, true>
|
||||
{
|
||||
static std::string call (const T *a, const VariantUserClassImpl * /*delegate*/) { return a->to_string (); }
|
||||
static std::string call (const T *a, const VariantUserClassImpl * /*delegate*/) { return a ? a->to_string () : std::string (); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
|
|
|||
|
|
@ -266,9 +266,15 @@ public:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void execute (const tl::ExpressionParserContext & /*context*/, tl::Variant &out, const std::vector<tl::Variant> &args) const
|
||||
bool supports_keyword_parameters () const
|
||||
{
|
||||
if (! args.empty ()) {
|
||||
// for future extensions
|
||||
return true;
|
||||
}
|
||||
|
||||
void execute (const tl::ExpressionParserContext & /*context*/, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const
|
||||
{
|
||||
if (! args.empty () || kwargs) {
|
||||
throw tl::Exception (tl::to_string (tr ("Class '%s' is not a function - use 'new' to create a new object")), mp_var_cls->name ());
|
||||
}
|
||||
out = tl::Variant ((void *) 0, mp_var_cls, false);
|
||||
|
|
@ -532,12 +538,12 @@ VariantUserClassImpl::to_double_impl (void *obj) const
|
|||
}
|
||||
|
||||
void
|
||||
VariantUserClassImpl::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const
|
||||
VariantUserClassImpl::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const
|
||||
{
|
||||
if (mp_object_cls == 0 && method == "is_a") {
|
||||
|
||||
if (args.size () != 1) {
|
||||
throw tl::EvalError (tl::to_string (tr ("'is_a' method requires exactly one argument")), context);
|
||||
if (args.size () != 1 || kwargs) {
|
||||
throw tl::EvalError (tl::to_string (tr ("'is_a' method requires exactly one argument (no keyword arguments)")), context);
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
|
|
@ -550,7 +556,7 @@ VariantUserClassImpl::execute (const tl::ExpressionParserContext &context, tl::V
|
|||
|
||||
out = ret;
|
||||
|
||||
} else if (mp_object_cls != 0 && method == "new" && args.size () == 0) {
|
||||
} else if (mp_object_cls != 0 && method == "new" && args.size () == 0 && ! kwargs) {
|
||||
|
||||
void *obj = mp_cls->create ();
|
||||
if (obj) {
|
||||
|
|
@ -574,8 +580,8 @@ VariantUserClassImpl::execute (const tl::ExpressionParserContext &context, tl::V
|
|||
|
||||
} else if (mp_object_cls == 0 && method == "dup") {
|
||||
|
||||
if (args.size () != 0) {
|
||||
throw tl::EvalError (tl::to_string (tr ("'dup' method does not allow arguments")), context);
|
||||
if (args.size () != 0 || kwargs) {
|
||||
throw tl::EvalError (tl::to_string (tr ("'dup' method does not allow arguments (no keyword arguments)")), context);
|
||||
}
|
||||
|
||||
void *obj = mp_cls->create ();
|
||||
|
|
@ -602,7 +608,7 @@ VariantUserClassImpl::execute (const tl::ExpressionParserContext &context, tl::V
|
|||
|
||||
} else {
|
||||
try {
|
||||
execute_gsi (context, out, object, method, args);
|
||||
execute_gsi (context, out, object, method, args, kwargs);
|
||||
} catch (tl::EvalError &) {
|
||||
throw;
|
||||
} catch (tl::Exception &ex) {
|
||||
|
|
@ -709,8 +715,92 @@ static const gsi::ClassBase *find_class_scope (const gsi::ClassBase *cls, const
|
|||
return 0;
|
||||
}
|
||||
|
||||
inline int
|
||||
num_args (const gsi::MethodBase *m)
|
||||
{
|
||||
return int (m->end_arguments () - m->begin_arguments ());
|
||||
}
|
||||
|
||||
static bool
|
||||
compatible_with_args (const gsi::MethodBase *m, int argc, const std::map<std::string, tl::Variant> *kwargs)
|
||||
{
|
||||
int nargs = num_args (m);
|
||||
|
||||
if (argc >= nargs) {
|
||||
// no more arguments to consider
|
||||
return argc == nargs && (! kwargs || kwargs->empty ());
|
||||
}
|
||||
|
||||
if (kwargs) {
|
||||
|
||||
int nkwargs = int (kwargs->size ());
|
||||
int kwargs_taken = 0;
|
||||
|
||||
while (argc < nargs) {
|
||||
const gsi::ArgType &atype = m->begin_arguments () [argc];
|
||||
auto i = kwargs->find (atype.spec ()->name ());
|
||||
if (i == kwargs->end ()) {
|
||||
if (! atype.spec ()->has_default ()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
++kwargs_taken;
|
||||
}
|
||||
++argc;
|
||||
}
|
||||
|
||||
// matches if all keyword arguments are taken
|
||||
return kwargs_taken == nkwargs;
|
||||
|
||||
} else {
|
||||
|
||||
while (argc < nargs) {
|
||||
const gsi::ArgType &atype = m->begin_arguments () [argc];
|
||||
if (! atype.spec ()->has_default ()) {
|
||||
return false;
|
||||
}
|
||||
++argc;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static std::string
|
||||
describe_overload (const gsi::MethodBase *m, int argc, const std::map<std::string, tl::Variant> *kwargs)
|
||||
{
|
||||
std::string res = m->to_string ();
|
||||
if (compatible_with_args (m, argc, kwargs)) {
|
||||
res += " " + tl::to_string (tr ("[match candidate]"));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static std::string
|
||||
describe_overloads (const ExpressionMethodTable *mt, int mid, int argc, const std::map<std::string, tl::Variant> *kwargs)
|
||||
{
|
||||
std::string res;
|
||||
for (auto m = mt->begin (mid); m != mt->end (mid); ++m) {
|
||||
res += std::string (" ") + describe_overload (*m, argc, kwargs) + "\n";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static const tl::Variant *
|
||||
get_kwarg (const gsi::ArgType &atype, const std::map<std::string, tl::Variant> *kwargs)
|
||||
{
|
||||
if (kwargs) {
|
||||
auto i = kwargs->find (atype.spec ()->name ());
|
||||
if (i != kwargs->end ()) {
|
||||
return &i->second;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context*/, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const
|
||||
VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context*/, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const
|
||||
{
|
||||
tl_assert (object.is_user ());
|
||||
|
||||
|
|
@ -762,7 +852,7 @@ VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context
|
|||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Signals are not supported inside expressions (event %s)")), method.c_str ()));
|
||||
} else if ((*m)->is_callback()) {
|
||||
// ignore callbacks
|
||||
} else if ((*m)->compatible_with_num_args ((unsigned int) args.size ())) {
|
||||
} else if (compatible_with_args (*m, int (args.size ()), kwargs)) {
|
||||
++candidates;
|
||||
meth = *m;
|
||||
}
|
||||
|
|
@ -771,20 +861,7 @@ VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context
|
|||
|
||||
// no candidate -> error
|
||||
if (! meth) {
|
||||
|
||||
std::set<unsigned int> nargs;
|
||||
for (ExpressionMethodTableEntry::method_iterator m = mt->begin (mid); m != mt->end (mid); ++m) {
|
||||
nargs.insert (std::distance ((*m)->begin_arguments (), (*m)->end_arguments ()));
|
||||
}
|
||||
std::string nargs_s;
|
||||
for (std::set<unsigned int>::const_iterator na = nargs.begin (); na != nargs.end (); ++na) {
|
||||
if (na != nargs.begin ()) {
|
||||
nargs_s += "/";
|
||||
}
|
||||
nargs_s += tl::to_string (*na);
|
||||
}
|
||||
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Invalid number of arguments for method %s, class %s (got %d, expected %s)")), method.c_str (), mp_cls->name (), int (args.size ()), nargs_s));
|
||||
throw tl::Exception (tl::to_string (tr ("Can't match arguments. Variants are:\n")) + describe_overloads (mt, mid, int (args.size ()), kwargs));
|
||||
}
|
||||
|
||||
// more than one candidate -> refine by checking the arguments
|
||||
|
|
@ -800,13 +877,16 @@ VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context
|
|||
if (! (*m)->is_callback () && ! (*m)->is_signal ()) {
|
||||
|
||||
// check arguments (count and type)
|
||||
bool is_valid = (*m)->compatible_with_num_args ((unsigned int) args.size ());
|
||||
bool is_valid = compatible_with_args (*m, (int) args.size (), kwargs);
|
||||
int sc = 0;
|
||||
int i = 0;
|
||||
for (gsi::MethodBase::argument_iterator a = (*m)->begin_arguments (); is_valid && i < int (args.size ()) && a != (*m)->end_arguments (); ++a, ++i) {
|
||||
if (gsi::test_arg (*a, args [i], false /*strict*/)) {
|
||||
for (gsi::MethodBase::argument_iterator a = (*m)->begin_arguments (); is_valid && a != (*m)->end_arguments (); ++a, ++i) {
|
||||
const tl::Variant *arg = i >= int (args.size ()) ? get_kwarg (*a, kwargs) : &args[i];
|
||||
if (! arg) {
|
||||
is_valid = a->spec ()->has_default ();
|
||||
} else if (gsi::test_arg (*a, *arg, false /*strict*/)) {
|
||||
++sc;
|
||||
} else if (test_arg (*a, args [i], true /*loose*/)) {
|
||||
} else if (test_arg (*a, *arg, true /*loose*/)) {
|
||||
// non-scoring match
|
||||
} else {
|
||||
is_valid = false;
|
||||
|
|
@ -831,12 +911,17 @@ VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context
|
|||
|
||||
if (is_valid) {
|
||||
|
||||
// otherwise take the candidate with the better score
|
||||
if (candidates > 0 && sc > score) {
|
||||
candidates = 1;
|
||||
meth = *m;
|
||||
score = sc;
|
||||
} else if (candidates == 0 || sc == score) {
|
||||
// otherwise take the candidate with the better score or the least number of arguments (faster)
|
||||
if (candidates > 0) {
|
||||
if (sc > score || (sc == score && num_args (meth) > num_args (*m))) {
|
||||
candidates = 1;
|
||||
meth = *m;
|
||||
score = sc;
|
||||
} else if (sc == score && num_args (meth) == num_args (*m)) {
|
||||
++candidates;
|
||||
meth = *m;
|
||||
}
|
||||
} else {
|
||||
++candidates;
|
||||
meth = *m;
|
||||
score = sc;
|
||||
|
|
@ -851,11 +936,11 @@ VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context
|
|||
}
|
||||
|
||||
if (! meth) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("No method with matching arguments for method %s, class %s")), method.c_str (), mp_cls->name ()));
|
||||
throw tl::Exception (tl::to_string (tr ("No overload with matching arguments. Variants are:\n")) + describe_overloads (mt, mid, int (args.size ()), kwargs));
|
||||
}
|
||||
|
||||
if (candidates > 1) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Ambiguous overload variants for method %s, class %s - multiple method declarations match arguments")), method.c_str (), mp_cls->name ()));
|
||||
throw tl::Exception (tl::to_string (tr ("Ambiguous overload variants - multiple method declarations match arguments. Variants are:\n")) + describe_overloads (mt, mid, int (args.size ()), kwargs));
|
||||
}
|
||||
|
||||
if (m_is_const && ! meth->is_const ()) {
|
||||
|
|
@ -869,22 +954,76 @@ VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context
|
|||
|
||||
} else if (meth->smt () != gsi::MethodBase::None) {
|
||||
|
||||
if (kwargs) {
|
||||
throw tl::Exception (tl::to_string (tr ("Keyword arguments not permitted")));
|
||||
}
|
||||
|
||||
out = special_method_impl (meth->smt (), object, args);
|
||||
|
||||
} else {
|
||||
|
||||
gsi::SerialArgs arglist (meth->argsize ());
|
||||
tl::Heap heap;
|
||||
size_t narg = 0;
|
||||
for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments () && narg < args.size (); ++a, ++narg) {
|
||||
|
||||
int iarg = 0;
|
||||
int kwargs_taken = 0;
|
||||
int nkwargs = kwargs ? int (kwargs->size ()) : 0;
|
||||
|
||||
for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments (); ++a, ++iarg) {
|
||||
|
||||
try {
|
||||
// Note: this const_cast is ugly, but it will basically enable "out" parameters
|
||||
// TODO: clean this up.
|
||||
gsi::push_arg (arglist, *a, const_cast<tl::Variant &> (args [narg]), &heap);
|
||||
|
||||
const tl::Variant *arg = iarg >= int (args.size ()) ? get_kwarg (*a, kwargs) : &args[iarg];
|
||||
if (! arg) {
|
||||
if (a->spec ()->has_default ()) {
|
||||
if (kwargs_taken == nkwargs) {
|
||||
// leave it to the consumer to establish the default values (that is faster)
|
||||
break;
|
||||
}
|
||||
tl::Variant def_value = a->spec ()->default_value ();
|
||||
gsi::push_arg (arglist, *a, def_value, &heap);
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string ("No argument provided (positional or keyword) and no default value available"));
|
||||
}
|
||||
} else {
|
||||
if (iarg >= int (args.size ())) {
|
||||
++kwargs_taken;
|
||||
}
|
||||
// Note: this const_cast is ugly, but it will basically enable "out" parameters
|
||||
// TODO: clean this up.
|
||||
gsi::push_arg (arglist, *a, const_cast<tl::Variant &> (*arg), &heap);
|
||||
}
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
std::string msg = ex.msg () + tl::sprintf (tl::to_string (tr (" (argument '%s')")), a->spec ()->name ());
|
||||
throw tl::Exception (msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (kwargs_taken != nkwargs) {
|
||||
|
||||
// check if there are any left-over keyword parameters with unknown names
|
||||
|
||||
std::set<std::string> valid_names;
|
||||
for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments (); ++a) {
|
||||
valid_names.insert (a->spec ()->name ());
|
||||
}
|
||||
|
||||
std::set<std::string> invalid_names;
|
||||
for (auto i = kwargs->begin (); i != kwargs->end (); ++i) {
|
||||
if (valid_names.find (i->first) == valid_names.end ()) {
|
||||
invalid_names.insert (i->first);
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid_names.size () > 1) {
|
||||
std::string names_str = tl::join (invalid_names.begin (), invalid_names.end (), ", ");
|
||||
throw tl::Exception (tl::to_string (tr ("Unknown keyword parameters: ")) + names_str);
|
||||
} else if (invalid_names.size () == 1) {
|
||||
throw tl::Exception (tl::to_string (tr ("Unknown keyword parameter: ")) + *invalid_names.begin ());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SerialArgs retlist (meth->retsize ());
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public:
|
|||
int to_int_impl (void *) const;
|
||||
double to_double_impl (void *) const;
|
||||
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const;
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const;
|
||||
|
||||
void initialize (const gsi::ClassBase *cls, const tl::VariantUserClassBase *self, const tl::VariantUserClassBase *object_cls, bool is_const);
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ private:
|
|||
const tl::VariantUserClassBase *mp_self, *mp_object_cls;
|
||||
bool m_is_const;
|
||||
|
||||
virtual void execute_gsi (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const;
|
||||
virtual void execute_gsi (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs = 0) const;
|
||||
|
||||
bool has_method (const std::string &method) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -564,7 +564,7 @@ class CollectFunction
|
|||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
virtual void execute (const tl::ExpressionParserContext & /*context*/, tl::Variant &out, const std::vector<tl::Variant> &args) const
|
||||
virtual void execute (const tl::ExpressionParserContext & /*context*/, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
out = tl::Variant ();
|
||||
if (args.size () > 0) {
|
||||
|
|
@ -623,3 +623,32 @@ TEST(11)
|
|||
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"));
|
||||
}
|
||||
|
||||
TEST(12)
|
||||
{
|
||||
// Keyword arguments are best tested on transformations, here CplxTrans
|
||||
|
||||
tl::Eval e;
|
||||
tl::Variant v;
|
||||
|
||||
v = e.parse ("var t = CplxTrans.new()").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("r0 *1 0,0"));
|
||||
v = e.parse ("var t = CplxTrans.new(1.5)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("r0 *1.5 0,0"));
|
||||
v = e.parse ("var t = CplxTrans.new(1, 2)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("r0 *1 1,2"));
|
||||
v = e.parse ("var t = CplxTrans.new(1, y=2)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("r0 *1 1,2"));
|
||||
v = e.parse ("var t = CplxTrans.new(x=1, y=2)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("r0 *1 1,2"));
|
||||
v = e.parse ("var t = CplxTrans.new(u=DVector.new(1, 2))").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("r0 *1 1,2"));
|
||||
v = e.parse ("var t = CplxTrans.new(DVector.new(1, 2))").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("r0 *1 1,2"));
|
||||
v = e.parse ("var t = CplxTrans.new(u=Vector.new(1, 2))").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("r0 *1 1,2"));
|
||||
v = e.parse ("var t = CplxTrans.new(u=[1, 2])").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("r0 *1 1,2"));
|
||||
v = e.parse ("var t = CplxTrans.new(mag=1.5)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("r0 *1.5 0,0"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -436,7 +436,7 @@ public:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector <tl::Variant> &vv) const
|
||||
void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector <tl::Variant> &vv, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (vv.size () != 0) {
|
||||
throw tl::EvalError (tl::to_string (tr ("Layer source function must not have arguments")), context);
|
||||
|
|
|
|||
|
|
@ -531,11 +531,11 @@ private:
|
|||
}
|
||||
|
||||
if (! meth) {
|
||||
throw tl::TypeError (tl::to_string (tr ("No overload with matching arguments. Variants are:\n")) + describe_overloads (argc, kwargs));
|
||||
throw tl::Exception (tl::to_string (tr ("No overload with matching arguments. Variants are:\n")) + describe_overloads (argc, kwargs));
|
||||
}
|
||||
|
||||
if (candidates > 1) {
|
||||
throw tl::TypeError (tl::to_string (tr ("Ambiguous overload variants - multiple method declarations match arguments. Variants are:\n")) + describe_overloads (argc, kwargs));
|
||||
throw tl::Exception (tl::to_string (tr ("Ambiguous overload variants - multiple method declarations match arguments. Variants are:\n")) + describe_overloads (argc, kwargs));
|
||||
}
|
||||
|
||||
if (is_const && ! meth->is_const ()) {
|
||||
|
|
|
|||
|
|
@ -306,12 +306,12 @@ class TL_PUBLIC ListClass
|
|||
: public EvalClass
|
||||
{
|
||||
public:
|
||||
void execute (const ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const
|
||||
void execute (const ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const
|
||||
{
|
||||
if (method == "push") {
|
||||
|
||||
if (args.size () != 1) {
|
||||
throw EvalError (tl::to_string (tr ("'push' method expects one argument")), context);
|
||||
if (args.size () != 1 || kwargs) {
|
||||
throw EvalError (tl::to_string (tr ("'push' method expects one argument (keyword arguments not permitted)")), context);
|
||||
}
|
||||
|
||||
object.push (args [0]);
|
||||
|
|
@ -319,7 +319,7 @@ public:
|
|||
|
||||
} else if (method == "size") {
|
||||
|
||||
if (args.size () != 0) {
|
||||
if (args.size () != 0 || kwargs) {
|
||||
throw EvalError (tl::to_string (tr ("'size' method does not accept an argument")), context);
|
||||
}
|
||||
|
||||
|
|
@ -343,12 +343,12 @@ class TL_PUBLIC ArrayClass
|
|||
: public EvalClass
|
||||
{
|
||||
public:
|
||||
void execute (const ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const
|
||||
void execute (const ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const
|
||||
{
|
||||
if (method == "insert") {
|
||||
|
||||
if (args.size () != 2) {
|
||||
throw EvalError (tl::to_string (tr ("'insert' method expects two arguments")), context);
|
||||
if (args.size () != 2 || kwargs) {
|
||||
throw EvalError (tl::to_string (tr ("'insert' method expects two arguments (keyword arguments not permitted)")), context);
|
||||
}
|
||||
|
||||
object.insert (args [0], args [1]);
|
||||
|
|
@ -356,7 +356,7 @@ public:
|
|||
|
||||
} else if (method == "size") {
|
||||
|
||||
if (args.size () != 0) {
|
||||
if (args.size () != 0 || kwargs) {
|
||||
throw EvalError (tl::to_string (tr ("'size' method does not accept an argument")), context);
|
||||
}
|
||||
|
||||
|
|
@ -364,7 +364,7 @@ public:
|
|||
|
||||
} else if (method == "keys") {
|
||||
|
||||
if (args.size () != 0) {
|
||||
if (args.size () != 0 || kwargs) {
|
||||
throw EvalError (tl::to_string (tr ("'keys' method does not accept an argument")), context);
|
||||
}
|
||||
|
||||
|
|
@ -375,7 +375,7 @@ public:
|
|||
|
||||
} else if (method == "values") {
|
||||
|
||||
if (args.size () != 0) {
|
||||
if (args.size () != 0 || kwargs) {
|
||||
throw EvalError (tl::to_string (tr ("'keys' method does not accept an argument")), context);
|
||||
}
|
||||
|
||||
|
|
@ -411,7 +411,7 @@ ExpressionNode::ExpressionNode (const ExpressionParserContext &context, size_t c
|
|||
}
|
||||
|
||||
ExpressionNode::ExpressionNode (const ExpressionNode &other, const tl::Expression *expr)
|
||||
: m_context (other.m_context)
|
||||
: m_context (other.m_context), m_name (other.m_name)
|
||||
{
|
||||
m_context.set_expr (expr);
|
||||
m_c.reserve (other.m_c.size ());
|
||||
|
|
@ -517,7 +517,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "<", vv);
|
||||
c->execute (m_context, o, v.get (), "<", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else {
|
||||
|
|
@ -567,7 +567,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "<=", vv);
|
||||
c->execute (m_context, o, v.get (), "<=", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else {
|
||||
|
|
@ -617,7 +617,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), ">", vv);
|
||||
c->execute (m_context, o, v.get (), ">", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else {
|
||||
|
|
@ -667,7 +667,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), ">=", vv);
|
||||
c->execute (m_context, o, v.get (), ">=", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else {
|
||||
|
|
@ -717,7 +717,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "==", vv);
|
||||
c->execute (m_context, o, v.get (), "==", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else {
|
||||
|
|
@ -767,7 +767,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "!=", vv);
|
||||
c->execute (m_context, o, v.get (), "!=", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else {
|
||||
|
|
@ -817,7 +817,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "~", vv);
|
||||
c->execute (m_context, o, v.get (), "~", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
mp_eval->match_substrings ().clear ();
|
||||
|
|
@ -914,7 +914,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "!~", vv);
|
||||
c->execute (m_context, o, v.get (), "!~", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else {
|
||||
|
|
@ -1085,7 +1085,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "<<", vv);
|
||||
c->execute (m_context, o, v.get (), "<<", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_longlong ()) {
|
||||
|
|
@ -1141,7 +1141,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), ">>", vv);
|
||||
c->execute (m_context, o, v.get (), ">>", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_longlong ()) {
|
||||
|
|
@ -1197,7 +1197,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "+", vv);
|
||||
c->execute (m_context, o, v.get (), "+", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_a_string () || b->is_a_string ()) {
|
||||
|
|
@ -1259,7 +1259,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "-", vv);
|
||||
c->execute (m_context, o, v.get (), "-", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_double () || b->is_double ()) {
|
||||
|
|
@ -1319,7 +1319,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "*", vv);
|
||||
c->execute (m_context, o, v.get (), "*", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_a_string ()) {
|
||||
|
|
@ -1409,7 +1409,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "/", vv);
|
||||
c->execute (m_context, o, v.get (), "/", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_double () || b->is_double ()) {
|
||||
|
|
@ -1493,7 +1493,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "%", vv);
|
||||
c->execute (m_context, o, v.get (), "%", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_ulonglong () || b->is_ulonglong ()) {
|
||||
|
|
@ -1565,7 +1565,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "&", vv);
|
||||
c->execute (m_context, o, v.get (), "&", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_ulonglong () || b->is_ulonglong ()) {
|
||||
|
|
@ -1621,7 +1621,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "|", vv);
|
||||
c->execute (m_context, o, v.get (), "|", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_ulonglong () || b->is_ulonglong ()) {
|
||||
|
|
@ -1677,7 +1677,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*b);
|
||||
c->execute (m_context, o, v.get (), "^", vv);
|
||||
c->execute (m_context, o, v.get (), "^", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_ulonglong () || b->is_ulonglong ()) {
|
||||
|
|
@ -1733,7 +1733,7 @@ public:
|
|||
tl::Variant o;
|
||||
std::vector <tl::Variant> vv;
|
||||
vv.push_back (*e);
|
||||
c->execute (m_context, o, v.get (), "[]", vv);
|
||||
c->execute (m_context, o, v.get (), "[]", vv, 0);
|
||||
v.swap (o);
|
||||
|
||||
} else if (v->is_list ()) {
|
||||
|
|
@ -2025,11 +2025,17 @@ public:
|
|||
m_c[0]->execute (v);
|
||||
|
||||
std::vector <tl::Variant> vv;
|
||||
std::map <std::string, tl::Variant> kwargs;
|
||||
|
||||
vv.reserve (m_c.size () - 1);
|
||||
for (std::vector<ExpressionNode *>::const_iterator c = m_c.begin () + 1; c != m_c.end (); ++c) {
|
||||
EvalTarget a;
|
||||
(*c)->execute (a);
|
||||
vv.push_back (*a);
|
||||
if (! (*c)->name ().empty ()) {
|
||||
kwargs [(*c)->name ()] = *a;
|
||||
} else {
|
||||
vv.push_back (*a);
|
||||
}
|
||||
}
|
||||
|
||||
const EvalClass *c = 0;
|
||||
|
|
@ -2048,7 +2054,7 @@ public:
|
|||
}
|
||||
|
||||
tl::Variant o;
|
||||
c->execute (m_context, o, v.get (), m_method, vv);
|
||||
c->execute (m_context, o, v.get (), m_method, vv, kwargs.empty () ? 0 : &kwargs);
|
||||
v.swap (o);
|
||||
}
|
||||
|
||||
|
|
@ -2188,16 +2194,26 @@ public:
|
|||
void execute (EvalTarget &v) const
|
||||
{
|
||||
std::vector<tl::Variant> vv;
|
||||
std::map<std::string, tl::Variant> kwargs;
|
||||
|
||||
vv.reserve (m_c.size ());
|
||||
|
||||
for (std::vector<ExpressionNode *>::const_iterator c = m_c.begin (); c != m_c.end (); ++c) {
|
||||
EvalTarget a;
|
||||
(*c)->execute (a);
|
||||
vv.push_back (*a);
|
||||
if ((*c)->name ().empty ()) {
|
||||
vv.push_back (*a);
|
||||
} else {
|
||||
kwargs[(*c)->name ()] = *a;
|
||||
}
|
||||
}
|
||||
|
||||
if (! kwargs.empty () && ! mp_func->supports_keyword_parameters ()) {
|
||||
throw EvalError (tl::to_string (tr ("Keyword parameters not permitted")), m_context);
|
||||
}
|
||||
|
||||
tl::Variant o;
|
||||
mp_func->execute (m_context, o, vv);
|
||||
mp_func->execute (m_context, o, vv, kwargs.empty () ? 0 : &kwargs);
|
||||
v.swap (o);
|
||||
}
|
||||
|
||||
|
|
@ -2939,7 +2955,7 @@ public:
|
|||
ms_functions.erase (m_name);
|
||||
}
|
||||
|
||||
void execute (const ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args) const
|
||||
void execute (const ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
m_func (context, out, args);
|
||||
}
|
||||
|
|
@ -3556,8 +3572,19 @@ Eval::eval_suffix (ExpressionParserContext &ex, std::unique_ptr<ExpressionNode>
|
|||
|
||||
do {
|
||||
|
||||
tl::Extractor exn = ex;
|
||||
std::string n;
|
||||
if (exn.try_read_word (n, "_") && exn.test ("=")) {
|
||||
// keyword parameter -> read name again to skip it
|
||||
ex.read_word (n, "_");
|
||||
ex.expect ("=");
|
||||
} else {
|
||||
n.clear ();
|
||||
}
|
||||
|
||||
std::unique_ptr<ExpressionNode> a;
|
||||
eval_assign (ex, a);
|
||||
a->set_name (n);
|
||||
m->add_child (a.release ());
|
||||
|
||||
if (ex.test (")")) {
|
||||
|
|
|
|||
|
|
@ -186,7 +186,25 @@ public:
|
|||
/**
|
||||
* @brief Add a child node
|
||||
*/
|
||||
void add_child (ExpressionNode *node);
|
||||
void add_child (ExpressionNode *node);
|
||||
|
||||
/**
|
||||
* @brief Gets the name
|
||||
*
|
||||
* The name is used for named arguments for example.
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the name
|
||||
*/
|
||||
void set_name (const std::string &name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute the node
|
||||
|
|
@ -201,6 +219,7 @@ public:
|
|||
protected:
|
||||
std::vector <ExpressionNode *> m_c;
|
||||
ExpressionParserContext m_context;
|
||||
std::string m_name;
|
||||
|
||||
/**
|
||||
* @brief Sets the expression parent
|
||||
|
|
@ -244,7 +263,7 @@ public:
|
|||
*
|
||||
* If no method of this kind exists, the implementation may throw a NoMethodError.
|
||||
*/
|
||||
virtual void execute (const ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const = 0;
|
||||
virtual void execute (const ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -263,6 +282,11 @@ public:
|
|||
*/
|
||||
virtual ~EvalFunction () { }
|
||||
|
||||
/**
|
||||
* @brief Specifies whether keyword parameters are supported
|
||||
*/
|
||||
virtual bool supports_keyword_parameters () const { return false; }
|
||||
|
||||
/**
|
||||
* @brief The actual execution method
|
||||
*
|
||||
|
|
@ -270,7 +294,7 @@ public:
|
|||
* @param args The arguments of the method
|
||||
* @return The return value
|
||||
*/
|
||||
virtual void execute (const ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args) const = 0;
|
||||
virtual void execute (const ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ private:
|
|||
class BoxClassClass : public tl::VariantUserClassBase, private tl::EvalClass
|
||||
{
|
||||
public:
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const;
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const;
|
||||
|
||||
virtual void *create () const { tl_assert (false); }
|
||||
virtual void destroy (void *) const { tl_assert (false); }
|
||||
|
|
@ -473,7 +473,7 @@ BoxClassClass BoxClassClass::instance;
|
|||
class BoxClass : public tl::VariantUserClassImpl<Box>, private tl::EvalClass
|
||||
{
|
||||
public:
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const;
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const;
|
||||
|
||||
virtual const tl::EvalClass *eval_cls () const { return this; }
|
||||
static BoxClass instance;
|
||||
|
|
@ -481,7 +481,7 @@ public:
|
|||
|
||||
BoxClass BoxClass::instance;
|
||||
|
||||
void BoxClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const
|
||||
void BoxClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (method == "width") {
|
||||
out = object.to_user<Box> ().width ();
|
||||
|
|
@ -501,7 +501,7 @@ void BoxClass::execute (const tl::ExpressionParserContext &context, tl::Variant
|
|||
}
|
||||
}
|
||||
|
||||
void BoxClassClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant & /*object*/, const std::string &method, const std::vector<tl::Variant> &args) const
|
||||
void BoxClassClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant & /*object*/, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (method == "new") {
|
||||
out = tl::Variant (new Box (args[0].to_long(), args[1].to_long(), args[2].to_long(), args[3].to_long()), &BoxClass::instance, true);
|
||||
|
|
@ -513,7 +513,7 @@ void BoxClassClass::execute (const tl::ExpressionParserContext &context, tl::Var
|
|||
class EdgeClassClass : public tl::VariantUserClassBase, private tl::EvalClass
|
||||
{
|
||||
public:
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const;
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> *kwargs) const;
|
||||
|
||||
virtual void *create () const { tl_assert (false); }
|
||||
virtual void destroy (void *) const { tl_assert (false); }
|
||||
|
|
@ -541,7 +541,7 @@ EdgeClassClass EdgeClassClass::instance;
|
|||
class EdgeClass : public tl::VariantUserClassImpl<Edge>, private tl::EvalClass
|
||||
{
|
||||
public:
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (method == "dx") {
|
||||
out = object.to_user<Edge> ().dx ();
|
||||
|
|
@ -566,7 +566,7 @@ public:
|
|||
EdgeClass EdgeClass::instance;
|
||||
|
||||
void
|
||||
EdgeClassClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant & /*object*/, const std::string &method, const std::vector<tl::Variant> &args) const
|
||||
EdgeClassClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant & /*object*/, const std::string &method, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (method == "new") {
|
||||
out = tl::Variant (new Edge (args[0].to_long(), args[1].to_long(), args[2].to_long(), args[3].to_long()), &EdgeClass::instance, true);
|
||||
|
|
@ -996,7 +996,7 @@ class F0
|
|||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector <tl::Variant> &) const
|
||||
void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector <tl::Variant> &, const std::map<std::string, tl::Variant> *) const
|
||||
{
|
||||
out = tl::Variant (17);
|
||||
}
|
||||
|
|
@ -1006,7 +1006,7 @@ class F1
|
|||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector <tl::Variant> &vv) const
|
||||
void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector <tl::Variant> &vv, const std::map<std::string, tl::Variant> *) const
|
||||
{
|
||||
out = tl::Variant (vv[0].to_long() + 1);
|
||||
}
|
||||
|
|
@ -1016,7 +1016,7 @@ class F2
|
|||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector <tl::Variant> &vv) const
|
||||
void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector <tl::Variant> &vv, const std::map<std::string, tl::Variant> *) const
|
||||
{
|
||||
out = tl::Variant (vv[0].to_long() + 2);
|
||||
}
|
||||
|
|
@ -1026,7 +1026,7 @@ class F3
|
|||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector <tl::Variant> &vv) const
|
||||
void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector <tl::Variant> &vv, const std::map<std::string, tl::Variant> *) const
|
||||
{
|
||||
out = tl::Variant (vv[0].to_long() + 3);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue