/* @file pyexpression.cpp */ #include "pyexpression.hpp" #include "xo/pyreflect/pyreflect.hpp" #include "xo/expression/Expression.hpp" #include "xo/expression/ConstantInterface.hpp" #include "xo/expression/Constant.hpp" #include "xo/expression/PrimitiveInterface.hpp" #include "xo/expression/Primitive.hpp" #include "xo/pyutil/pyutil.hpp" #include namespace xo { namespace ast { using xo::ast::exprtype; using xo::ast::Expression; using xo::ast::ConstantInterface; using xo::ast::Constant; using xo::ast::PrimitiveInterface; using xo::ast::Primitive; using xo::ast::make_primitive; using xo::reflect::TaggedPtr; using xo::ref::rp; namespace py = pybind11; PYBIND11_MODULE(XO_PYEXPRESSION_MODULE_NAME(), m) { // e.g. for xo::reflect::TypeDescr PYREFLECT_IMPORT_MODULE(); // py::module_::import("pyreflect"); m.doc() = "pybind11 plugin for xo-expression"; py::enum_(m, "exprtype") .value("invalid", exprtype::invalid) .value("constant", exprtype::constant) .value("primitive", exprtype::primitive) .value("apply", exprtype::apply) .value("lambda", exprtype::lambda) .value("variable", exprtype::variable) ; py::class_>(m, "Expression") .def("extype", &Expression::extype) .def("__repr__", &Expression::display_string); ; // ----- Constants ----- py::class_>(m, "ConstantInterface") .def("value_td", &ConstantInterface::value_td, py::doc("type description for literal value represented by this Constant")) .def("value", [](const ConstantInterface & expr) { TaggedPtr tp = expr.value_tp(); auto * p = tp.recover_native(); /* TODO: promote to pyobject, so we can do polymorphism */ if (p) return *p; else return std::numeric_limits::quiet_NaN(); }, py::doc("recover constant expression's wrapped value [wip - only works for double]")) ; py::class_, ConstantInterface, rp>>(m, "Constant_double") ; m.def("make_constant", [](double x) { return make_constant(x); }, py::arg("x"), py::doc("make_constant(x) creates constant expression holding x [wip - only works for double")) ; // ----- Primitives ----- py::class_>(m, "PrimitiveInterface") .def("name", &PrimitiveInterface::name, py::doc("name of this primitive function; use this name to invoke the function")) .def("n_arg", &PrimitiveInterface::n_arg, py::doc("number of arguments to this function (not counting return value)")) ; using Fn_dbl_dbl_type = double (*)(double); m.def("make_sqrt_pm", []() { return make_primitive("sqrt", sqrt); }, py::doc("create primitive representing the ::sqrt() function")); m.def("make_sin_pm", []() { return make_primitive("sin", ::sin); }, py::doc("create primitive representing the ::sin() function")); m.def("make_cos_pm", []() { return make_primitive("cos", ::cos); }, py::doc("create primitive representing the ::cos() function")); py::class_, PrimitiveInterface, rp>>(m, "Primitive_double_double") ; } /*pyexpresion*/ } /*namespace ast*/ } /*namespace xo*/ /* end pyexpression.cpp */