Пример #1
0
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_ = insert(new VmInstr(expr.op(), {rhs}));
    }
}
Пример #2
0
      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())));
}