diff --git a/integration_tests/symbolics_06.py b/integration_tests/symbolics_06.py index b9733cf763..5b603f6537 100644 --- a/integration_tests/symbolics_06.py +++ b/integration_tests/symbolics_06.py @@ -28,11 +28,18 @@ def test_elementary_functions(): # test composite functions a: S = exp(x) b: S = sin(a) + b1: bool = b.func == sin c: S = cos(b) d: S = log(c) d1: bool = d.func == log e: S = Abs(d) print(e) + assert(b1 == True) + if b.func == sin: + assert True + else: + assert False + assert(b.func == sin) assert(d1 == True) if d.func == log: assert True diff --git a/src/libasr/pass/intrinsic_function_registry.h b/src/libasr/pass/intrinsic_function_registry.h index 4cf8cf36b0..ff4c92548e 100644 --- a/src/libasr/pass/intrinsic_function_registry.h +++ b/src/libasr/pass/intrinsic_function_registry.h @@ -84,6 +84,7 @@ enum class IntrinsicScalarFunctions : int64_t { SymbolicMulQ, SymbolicPowQ, SymbolicLogQ, + SymbolicSinQ, // ... }; @@ -150,6 +151,7 @@ inline std::string get_intrinsic_name(int x) { INTRINSIC_NAME_CASE(SymbolicMulQ) INTRINSIC_NAME_CASE(SymbolicPowQ) INTRINSIC_NAME_CASE(SymbolicLogQ) + INTRINSIC_NAME_CASE(SymbolicSinQ) default : { throw LCompilersException("pickle: intrinsic_id not implemented"); } @@ -3155,6 +3157,7 @@ create_symbolic_query_macro(SymbolicAddQ) create_symbolic_query_macro(SymbolicMulQ) create_symbolic_query_macro(SymbolicPowQ) create_symbolic_query_macro(SymbolicLogQ) +create_symbolic_query_macro(SymbolicSinQ) #define create_symbolic_unary_macro(X) \ @@ -3320,6 +3323,8 @@ namespace IntrinsicScalarFunctionRegistry { {nullptr, &SymbolicPowQ::verify_args}}, {static_cast(IntrinsicScalarFunctions::SymbolicLogQ), {nullptr, &SymbolicLogQ::verify_args}}, + {static_cast(IntrinsicScalarFunctions::SymbolicSinQ), + {nullptr, &SymbolicSinQ::verify_args}}, }; static const std::map& intrinsic_function_id_to_name = { @@ -3434,6 +3439,8 @@ namespace IntrinsicScalarFunctionRegistry { "SymbolicPowQ"}, {static_cast(IntrinsicScalarFunctions::SymbolicLogQ), "SymbolicLogQ"}, + {static_cast(IntrinsicScalarFunctions::SymbolicSinQ), + "SymbolicSinQ"}, }; @@ -3494,6 +3501,7 @@ namespace IntrinsicScalarFunctionRegistry { {"MulQ", {&SymbolicMulQ::create_SymbolicMulQ, &SymbolicMulQ::eval_SymbolicMulQ}}, {"PowQ", {&SymbolicPowQ::create_SymbolicPowQ, &SymbolicPowQ::eval_SymbolicPowQ}}, {"LogQ", {&SymbolicLogQ::create_SymbolicLogQ, &SymbolicLogQ::eval_SymbolicLogQ}}, + {"SinQ", {&SymbolicSinQ::create_SymbolicSinQ, &SymbolicSinQ::eval_SymbolicSinQ}}, }; static inline bool is_intrinsic_function(const std::string& name) { diff --git a/src/libasr/pass/replace_symbolic.cpp b/src/libasr/pass/replace_symbolic.cpp index 3885b67667..3bae7436f8 100644 --- a/src/libasr/pass/replace_symbolic.cpp +++ b/src/libasr/pass/replace_symbolic.cpp @@ -951,6 +951,24 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitorm_args[0]); + Vec call_args; + call_args.reserve(al, 1); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = value1; + call_args.push_back(al, call_arg); + ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, + basic_get_type_sym, basic_get_type_sym, call_args.p, call_args.n, + ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), nullptr, nullptr)); + // Using 35 as the right value of the IntegerCompare node as it represents SYMENGINE_SIN through SYMENGINE_ENUM + return ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, function_call, ASR::cmpopType::Eq, + ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 35, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)))), + ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr)); + break; + } default: { throw LCompilersException("IntrinsicFunction: `" + ASRUtils::get_intrinsic_name(intrinsic_id) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 36873890ba..d1096a83ea 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -6055,6 +6055,9 @@ class BodyVisitor : public CommonVisitor { } else if (symbolic_type == "log") { tmp = attr_handler.eval_symbolic_is_log(se, al, x.base.base.loc, args, diag); return; + } else if (symbolic_type == "sin") { + tmp = attr_handler.eval_symbolic_is_sin(se, al, x.base.base.loc, args, diag); + return; } else { throw SemanticError(symbolic_type + " symbolic type not supported yet", x.base.base.loc); } diff --git a/src/lpython/semantics/python_attribute_eval.h b/src/lpython/semantics/python_attribute_eval.h index 2f70c308e8..580434bc4f 100644 --- a/src/lpython/semantics/python_attribute_eval.h +++ b/src/lpython/semantics/python_attribute_eval.h @@ -513,6 +513,20 @@ struct AttributeHandler { { throw SemanticError(msg, loc); }); } + static ASR::asr_t* eval_symbolic_is_sin(ASR::expr_t *s, Allocator &al, const Location &loc, + Vec &args, diag::Diagnostics &/*diag*/) { + Vec args_with_list; + args_with_list.reserve(al, args.size() + 1); + args_with_list.push_back(al, s); + for(size_t i = 0; i < args.size(); i++) { + args_with_list.push_back(al, args[i]); + } + ASRUtils::create_intrinsic_function create_function = + ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("SinQ"); + return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) + { throw SemanticError(msg, loc); }); + } + }; // AttributeHandler } // namespace LCompilers::LPython