void IRGenerator::accept(UnaryExpr& expr) { FNTRACE(); static const std::unordered_map< int /*FlowVM::Opcode*/, Value* (IRGenerator::*)(Value*, const std::string&) > ops = { { FlowVM::Opcode::I2S, &IRGenerator::createI2S }, { FlowVM::Opcode::P2S, &IRGenerator::createP2S }, { FlowVM::Opcode::C2S, &IRGenerator::createC2S }, { FlowVM::Opcode::R2S, &IRGenerator::createR2S }, { FlowVM::Opcode::S2I, &IRGenerator::createS2I }, { FlowVM::Opcode::NNEG, &IRGenerator::createNeg }, }; Value* rhs = codegen(expr.subExpr()); auto i = ops.find(expr.op()); if (i != ops.end()) { result_ = (this->*i->second)(rhs, ""); } else { assert(!"Unsupported unary expression in IRGenerator."); result_ = nullptr; } }
// }}} // {{{ expressions void FlowCallVisitor::accept(UnaryExpr& expr) { visit(expr.subExpr()); }
void visit(const UnaryExpr& expr) { expr.get_expr()->walk(this); out << operators[expr.get_op()]; }
std::string process_impl(UnaryExpr const & e, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const { typedef op_unary<op_id<NumericType>, InterfaceType> OpId; typedef op_unary<op_exp<NumericType>, InterfaceType> OpExp; typedef op_unary<op_sin<NumericType>, InterfaceType> OpSin; typedef op_unary<op_cos<NumericType>, InterfaceType> OpCos; typedef op_unary<op_tan<NumericType>, InterfaceType> OpTan; typedef op_unary<op_fabs<NumericType>, InterfaceType> OpFabs; typedef op_unary<op_sqrt<NumericType>, InterfaceType> OpSqrt; typedef op_unary<op_log<NumericType>, InterfaceType> OpLog; typedef op_unary<op_log10<NumericType>, InterfaceType> OpLog10; // symbolic stuff: typedef op_unary<op_gradient<NumericType>, InterfaceType> OpGradient; typedef op_unary<op_divergence<NumericType>, InterfaceType> OpDivergence; typedef op_unary<op_partial_deriv<NumericType>, InterfaceType> OpPartialDeriv; typedef op_unary<op_rt_integral<InterfaceType>, InterfaceType> OpRuntimeIntegration; typedef op_unary<op_rt_symbolic_integral<InterfaceType>, InterfaceType> OpSymbolicIntegration; std::stringstream ss; viennamath::rt_expr<InterfaceType> lhs(e.lhs()->clone()); if (dynamic_cast< const OpId * >(e.op()) != NULL) ss << translator(lhs, use_parenthesis); else if (dynamic_cast< const OpExp * >(e.op()) != NULL) ss << " \\exp " << translator(lhs, true) << " "; else if (dynamic_cast< const OpSin * >(e.op()) != NULL) ss << " \\sin " << translator(lhs, true) << " "; else if (dynamic_cast< const OpCos * >(e.op()) != NULL) ss << " \\cos " << translator(lhs, true) << " "; else if (dynamic_cast< const OpTan * >(e.op()) != NULL) ss << " \\tan " << translator(lhs, true) << " "; else if (dynamic_cast< const OpFabs * >(e.op()) != NULL) ss << " \\left|" << translator(lhs) << "\\right| "; else if (dynamic_cast< const OpSqrt * >(e.op()) != NULL) ss << " \\sqrt{" << translator(lhs) << "} "; else if (dynamic_cast< const OpLog * >(e.op()) != NULL) ss << " \\ln " << translator(lhs, true) << " "; else if (dynamic_cast< const OpLog10 * >(e.op()) != NULL) ss << " \\log " << translator(lhs, true) << " "; else if (dynamic_cast< const OpGradient * >(e.op()) != NULL) ss << " \\nabla " << translator(lhs, true) << " "; else if (dynamic_cast< const OpDivergence * >(e.op()) != NULL) ss << " \\nabla \\cdot " << translator(lhs, true) << " "; else if (dynamic_cast< const OpPartialDeriv * >(e.op()) != NULL) { const OpPartialDeriv * tmp = dynamic_cast< const OpPartialDeriv * >(e.op()); viennamath::rt_variable<InterfaceType> var(tmp->op().id()); ss << " \\frac{\\partial " << translator(lhs, true) << "}{\\partial " << translator(var) << "} "; } else if (dynamic_cast< const OpRuntimeIntegration * >(e.op()) != NULL) { const OpRuntimeIntegration * op_integral = dynamic_cast< const OpRuntimeIntegration * >(e.op()); ss << " \\int_{ " << translator(op_integral->op().interval()) << " } "; ss << translator(lhs) << " "; ss << " \\: \\mathrm{d} " << translator(op_integral->op().variable()) << " "; } else if (dynamic_cast< const OpSymbolicIntegration * >(e.op()) != NULL) { const OpSymbolicIntegration * op_integral = dynamic_cast< const OpSymbolicIntegration * >(e.op()); // integral: ss << " \\int_{\\Omega_{" << op_integral->op().interval().id() << "}} "; ss << translator(lhs) << " "; ss << " \\: \\mathrm{d} \\Omega "; } else { std::cout << "Operator not supported: " << e.op()->str() << std::endl; throw "Not supported!"; } return ss.str(); }
void InstantiationVisitor::visit(UnaryExpr& u) { _expr.reset(new UnaryExpr(u.sloc(), u.op(), clone(u.expr()))); }