expressions - implement unary and binary function expression nodes
(sample functions: exp, pow, sin, cos, min, max, tan, atan)
This commit is contained in:
parent
48c23f27dc
commit
4adb0abb64
7 changed files with 134 additions and 29 deletions
|
@ -126,9 +126,17 @@ struct evaluate_expression : util::static_visitor<T>
|
|||
#endif
|
||||
}
|
||||
|
||||
value_type operator() (function_call const& fun) const
|
||||
value_type operator() (unary_function_call const& call) const
|
||||
{
|
||||
return value_type(123);// FIXME
|
||||
value_type arg = util::apply_visitor(*this, call.arg);
|
||||
return call.fun(arg);
|
||||
}
|
||||
|
||||
value_type operator() (binary_function_call const& call) const
|
||||
{
|
||||
value_type arg1 = util::apply_visitor(*this, call.arg1);
|
||||
value_type arg2 = util::apply_visitor(*this, call.arg2);
|
||||
return call.fun(arg1, arg2);
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
|
@ -217,11 +225,18 @@ struct evaluate_expression<T, boost::none_t> : util::static_visitor<T>
|
|||
#endif
|
||||
}
|
||||
|
||||
value_type operator() (function_call const& fun) const
|
||||
value_type operator() (unary_function_call const& call) const
|
||||
{
|
||||
return value_type(123);// FIXME
|
||||
value_type arg = util::apply_visitor(*this, call.arg);
|
||||
return call.fun(arg);
|
||||
}
|
||||
|
||||
value_type operator() (binary_function_call const& call) const
|
||||
{
|
||||
value_type arg1 = util::apply_visitor(*this, call.arg1);
|
||||
value_type arg2 = util::apply_visitor(*this, call.arg2);
|
||||
return call.fun(arg1, arg2);
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
value_type operator() (ValueType const& val) const
|
||||
|
|
|
@ -149,9 +149,17 @@ struct evaluate : util::static_visitor<T1>
|
|||
#endif
|
||||
}
|
||||
|
||||
value_type operator() (function_call const& fun) const
|
||||
value_type operator() (unary_function_call const& call) const
|
||||
{
|
||||
return value_integer(123);// FIXME
|
||||
value_type arg = util::apply_visitor(*this, call.arg);
|
||||
return call.fun(arg);
|
||||
}
|
||||
|
||||
value_type operator() (binary_function_call const& call) const
|
||||
{
|
||||
value_type arg1 = util::apply_visitor(*this, call.arg1);
|
||||
value_type arg2 = util::apply_visitor(*this, call.arg2);
|
||||
return call.fun(arg1, arg2);
|
||||
}
|
||||
|
||||
feature_type const& feature_;
|
||||
|
|
|
@ -39,8 +39,15 @@
|
|||
// stl
|
||||
#include <functional>
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(mapnik::function_call,
|
||||
(mapnik::function_impl, fun)(mapnik::function_call::arguments_type, arguments))
|
||||
BOOST_FUSION_ADAPT_STRUCT(mapnik::unary_function_call,
|
||||
(mapnik::unary_function_impl, fun)
|
||||
(mapnik::unary_function_call::argument_type, arg))
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(mapnik::binary_function_call,
|
||||
(mapnik::binary_function_impl, fun)
|
||||
(mapnik::binary_function_call::argument_type, arg1)
|
||||
(mapnik::binary_function_call::argument_type, arg2))
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
|
@ -122,16 +129,68 @@ inline value_type exp_impl (value_type const& val)
|
|||
{
|
||||
return std::exp(val.to_double());
|
||||
}
|
||||
|
||||
struct function_types : qi::symbols<char, function_impl>
|
||||
// sin
|
||||
inline value_type sin_impl (value_type const& val)
|
||||
{
|
||||
function_types()
|
||||
return std::sin(val.to_double());
|
||||
}
|
||||
// cos
|
||||
inline value_type cos_impl (value_type const& val)
|
||||
{
|
||||
return std::cos(val.to_double());
|
||||
}
|
||||
// tan
|
||||
inline value_type tan_impl (value_type const& val)
|
||||
{
|
||||
return std::tan(val.to_double());
|
||||
}
|
||||
// atan
|
||||
inline value_type atan_impl (value_type const& val)
|
||||
{
|
||||
return std::atan(val.to_double());
|
||||
}
|
||||
|
||||
struct unary_function_types : qi::symbols<char, unary_function_impl>
|
||||
{
|
||||
unary_function_types()
|
||||
{
|
||||
add
|
||||
("exp", unary_function_impl { &exp_impl })
|
||||
("sin", unary_function_impl(sin_impl))
|
||||
("cos", unary_function_impl(cos_impl))
|
||||
("tan", unary_function_impl(tan_impl))
|
||||
("atan", unary_function_impl(atan_impl))
|
||||
("exp", unary_function_impl(exp_impl))
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
// binary functions
|
||||
// min
|
||||
inline value_type min_impl(value_type const& arg1, value_type const& arg2)
|
||||
{
|
||||
return std::min(arg1.to_double(), arg2.to_double());
|
||||
}
|
||||
// max
|
||||
inline value_type max_impl(value_type const& arg1, value_type const& arg2)
|
||||
{
|
||||
return std::max(arg1.to_double(), arg2.to_double());
|
||||
}
|
||||
// pow
|
||||
inline value_type pow_impl(value_type const& arg1, value_type const& arg2)
|
||||
{
|
||||
return std::pow(arg1.to_double(), arg2.to_double());
|
||||
}
|
||||
|
||||
struct binary_function_types : qi::symbols<char, binary_function_impl>
|
||||
{
|
||||
binary_function_types()
|
||||
{
|
||||
add
|
||||
("min", binary_function_impl(min_impl))
|
||||
("max", binary_function_impl(max_impl))
|
||||
("pow", binary_function_impl(pow_impl))
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
@ -168,7 +227,8 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
|||
rule_type unary_expr;
|
||||
rule_type not_expr;
|
||||
rule_type primary_expr;
|
||||
qi::rule<Iterator, function_call() , space_type> function_expr;
|
||||
qi::rule<Iterator, unary_function_call() , space_type> unary_function_expr;
|
||||
qi::rule<Iterator, binary_function_call() , space_type> binary_function_expr;
|
||||
qi::rule<Iterator, std::string() > regex_match_expr;
|
||||
qi::rule<Iterator, expr_node(expr_node), qi::locals<std::string,std::string>, space_type> regex_replace_expr;
|
||||
qi::rule<Iterator, std::string() , space_type> attr;
|
||||
|
@ -179,7 +239,8 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
|||
qi::symbols<char const, char const> unesc_char;
|
||||
qi::rule<Iterator, char() > quote_char;
|
||||
geometry_types geom_type;
|
||||
function_types func_type;
|
||||
unary_function_types unary_func_type;
|
||||
binary_function_types binary_func_type;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -150,7 +150,10 @@ expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
|
|||
)
|
||||
;
|
||||
|
||||
function_expr = func_type >> lit('(') >> expr >> lit(')')
|
||||
unary_function_expr = unary_func_type > lit('(') > expr > lit(')')
|
||||
;
|
||||
|
||||
binary_function_expr = binary_func_type > lit('(') > expr > lit(',') > expr > lit(')')
|
||||
;
|
||||
|
||||
unary_expr = primary_expr [_val = _1]
|
||||
|
@ -169,6 +172,8 @@ expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
|
|||
| attr [_val = construct<mapnik::attribute>( _1 ) ]
|
||||
| global_attr [_val = construct<mapnik::global_attribute>( _1 )]
|
||||
| lit("not") >> expr [_val = !_1]
|
||||
| unary_function_expr [_val = _1]
|
||||
| binary_function_expr [_val = _1]
|
||||
| '(' >> expr [_val = _1 ] >> ')'
|
||||
| ustring[_val = unicode_(_1)] // if we get here then try parsing as unquoted string
|
||||
;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <boost/regex.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace mapnik
|
||||
|
@ -125,23 +126,32 @@ struct regex_replace_node
|
|||
};
|
||||
#endif
|
||||
|
||||
using nullary_function_impl = std::function<value_type()>;
|
||||
using unary_function_impl = std::function<value_type(value_type const&)>;
|
||||
using binary_function_impl = std::function<value_type(value_type const&, value_type const&)>;
|
||||
|
||||
typedef util::variant<nullary_function_impl, unary_function_impl, binary_function_impl> function_impl;
|
||||
|
||||
struct function_call
|
||||
struct unary_function_call
|
||||
{
|
||||
using arguments_type = std::vector<expr_node>;
|
||||
function_call(function_impl fun, arguments_type const& arguments)
|
||||
: fun(fun), arguments(arguments) { }
|
||||
using argument_type = expr_node;
|
||||
unary_function_call() = default;
|
||||
unary_function_call(unary_function_impl fun, argument_type const& arg)
|
||||
: fun(fun), arg(arg) {}
|
||||
|
||||
function_impl fun;
|
||||
arguments_type arguments;
|
||||
unary_function_impl fun;
|
||||
argument_type arg;
|
||||
};
|
||||
|
||||
inline expr_node& operator- (expr_node& expr)
|
||||
struct binary_function_call
|
||||
{
|
||||
using argument_type = expr_node;
|
||||
binary_function_call() = default;
|
||||
binary_function_call(binary_function_impl fun, argument_type const& arg1, argument_type const& arg2)
|
||||
: fun(fun), arg1(arg1), arg2(arg2) {}
|
||||
binary_function_impl fun;
|
||||
argument_type arg1;
|
||||
argument_type arg2;
|
||||
};
|
||||
|
||||
inline expr_node & operator- (expr_node& expr)
|
||||
{
|
||||
return expr = unary_node<tags::negate>(expr);
|
||||
}
|
||||
|
|
|
@ -163,7 +163,8 @@ struct regex_replace_node;
|
|||
struct attribute;
|
||||
struct global_attribute;
|
||||
struct geometry_type_attribute;
|
||||
struct function_call;
|
||||
struct unary_function_call;
|
||||
struct binary_function_call;
|
||||
|
||||
using expr_node = util::variant<
|
||||
value_null,
|
||||
|
@ -191,7 +192,8 @@ util::recursive_wrapper<binary_node<tags::logical_and> >,
|
|||
util::recursive_wrapper<binary_node<tags::logical_or> >,
|
||||
util::recursive_wrapper<regex_match_node>,
|
||||
util::recursive_wrapper<regex_replace_node>,
|
||||
util::recursive_wrapper<function_call>
|
||||
util::recursive_wrapper<unary_function_call>,
|
||||
util::recursive_wrapper<binary_function_call>
|
||||
>;
|
||||
|
||||
}
|
||||
|
|
|
@ -128,9 +128,13 @@ struct expression_string : util::static_visitor<void>
|
|||
str_ +="')";
|
||||
}
|
||||
|
||||
void operator() (function_call const& fun) const
|
||||
void operator() (unary_function_call const& call) const
|
||||
{
|
||||
str_ += "fun()";// FIXME
|
||||
str_ += "fun(arg)";// FIXME
|
||||
}
|
||||
void operator() (binary_function_call const& call) const
|
||||
{
|
||||
str_ += "fun(arg1,arg2)";// FIXME
|
||||
}
|
||||
private:
|
||||
std::string & str_;
|
||||
|
|
Loading…
Reference in a new issue