@@ -83,6 +83,32 @@ struct CPPDeclarationOptions: public DeclarationOptions {
83
83
}
84
84
};
85
85
86
+ class SymEngineQueue {
87
+ public:
88
+ std::vector<std::string> queue;
89
+ int queue_front = -1 ;
90
+ std::string& symengine_src;
91
+
92
+ SymEngineQueue (std::string& symengine_src) : symengine_src(symengine_src) {}
93
+
94
+ std::string push () {
95
+ std::string indent (4 , ' ' );
96
+ std::string var;
97
+ if (queue_front == -1 || queue_front >= static_cast <int >(queue.size ())) {
98
+ var = " queue" + std::to_string (queue.size ());
99
+ queue.push_back (var);
100
+ symengine_src = indent + " basic " + var + " ;\n " ;
101
+ symengine_src += indent + " basic_new_stack(" + var + " );\n " ;
102
+ }
103
+ return queue[queue_front++];
104
+ }
105
+
106
+ void pop () {
107
+ LCOMPILERS_ASSERT (queue_front != -1 && queue_front < static_cast <int >(queue.size ()));
108
+ queue_front++;
109
+ }
110
+ };
111
+
86
112
template <class Struct >
87
113
class BaseCCPPVisitor : public ASR ::BaseVisitor<Struct>
88
114
{
@@ -115,6 +141,8 @@ class BaseCCPPVisitor : public ASR::BaseVisitor<Struct>
115
141
bool is_c;
116
142
std::set<std::string> headers, user_headers, user_defines;
117
143
std::vector<std::string> tmp_buffer_src;
144
+ std::string symengine_src;
145
+ SymEngineQueue symengine_queue{symengine_src};
118
146
119
147
SymbolTable* global_scope;
120
148
int64_t lower_bound;
@@ -1178,6 +1206,17 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
1178
1206
target = " &" + target;
1179
1207
}
1180
1208
}
1209
+ if ( ASR::is_a<ASR::SymbolicExpression_t>(*value_type) ) {
1210
+ if (ASR::is_a<ASR::Var_t>(*x.m_value )){
1211
+ src = indent + " basic_assign(" + target + " , " + value + " );\n " ;
1212
+ symengine_queue.pop ();
1213
+ symengine_queue.pop ();
1214
+ return ;
1215
+ }
1216
+ src = symengine_src;
1217
+ symengine_src = " " ;
1218
+ return ;
1219
+ }
1181
1220
if ( !from_std_vector_helper.empty () ) {
1182
1221
src = from_std_vector_helper;
1183
1222
} else {
@@ -1243,12 +1282,7 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
1243
1282
src += alloc + indent + c_ds_api->get_deepcopy (m_target_type, value, target) + " \n " ;
1244
1283
}
1245
1284
} else {
1246
- if (m_target_type->type == ASR::ttypeType::SymbolicExpression){
1247
- ASR::expr_t * m_value_expr = x.m_value ;
1248
- src += alloc + indent + c_ds_api->get_deepcopy_symbolic (m_value_expr, value, target) + " \n " ;
1249
- } else {
1250
- src += alloc + indent + c_ds_api->get_deepcopy (m_target_type, value, target) + " \n " ;
1251
- }
1285
+ src += alloc + indent + c_ds_api->get_deepcopy (m_target_type, value, target) + " \n " ;
1252
1286
}
1253
1287
} else {
1254
1288
src += indent + c_ds_api->get_deepcopy (m_target_type, value, target) + " \n " ;
@@ -1646,6 +1680,15 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
1646
1680
src = std::string (ASR::down_cast<ASR::Variable_t>(s)->m_name );
1647
1681
}
1648
1682
last_expr_precedence = 2 ;
1683
+ ASR::ttype_t * var_type = sv->m_type ;
1684
+ if ( ASR::is_a<ASR::SymbolicExpression_t>(*var_type)) {
1685
+ std::string var_name = std::string (ASR::down_cast<ASR::Variable_t>(s)->m_name );
1686
+ symengine_queue.queue .push_back (var_name);
1687
+ if (symengine_queue.queue_front == -1 ) {
1688
+ symengine_queue.queue_front = 0 ;
1689
+ }
1690
+ symengine_src = " " ;
1691
+ }
1649
1692
}
1650
1693
1651
1694
void visit_StructInstanceMember (const ASR::StructInstanceMember_t& x) {
@@ -1858,6 +1901,8 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
1858
1901
break ;
1859
1902
}
1860
1903
case (ASR::cast_kindType::IntegerToSymbolicExpression): {
1904
+ self ().visit_expr (*x.m_value );
1905
+ last_expr_precedence = 2 ;
1861
1906
break ;
1862
1907
}
1863
1908
default : throw CodeGenError (" Cast kind " + std::to_string (x.m_kind ) + " not implemented" ,
@@ -2591,8 +2636,34 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
2591
2636
out += func_name; break ; \
2592
2637
}
2593
2638
2639
+ std::string performSymbolicOperation (const std::string& functionName, const ASR::IntrinsicFunction_t& x) {
2640
+ headers.insert (" symengine/cwrapper.h" );
2641
+ std::string indent (4 , ' ' );
2642
+ LCOMPILERS_ASSERT (x.n_args == 2 );
2643
+ std::string target = symengine_queue.push ();
2644
+ std::string target_src = symengine_src;
2645
+ this ->visit_expr (*x.m_args [0 ]);
2646
+ std::string arg1 = src;
2647
+ std::string arg1_src = symengine_src;
2648
+ // Check if x.m_args[0] is a Var
2649
+ if (ASR::is_a<ASR::Var_t>(*x.m_args [0 ])) {
2650
+ symengine_queue.pop ();
2651
+ }
2652
+ this ->visit_expr (*x.m_args [1 ]);
2653
+ std::string arg2 = src;
2654
+ std::string arg2_src = symengine_src;
2655
+ // Check if x.m_args[0] is a Var
2656
+ if (ASR::is_a<ASR::Var_t>(*x.m_args [1 ])) {
2657
+ symengine_queue.pop ();
2658
+ }
2659
+ symengine_src = target_src + arg1_src + arg2_src;
2660
+ symengine_src += indent + functionName + " (" + target + " , " + arg1 + " , " + arg2 + " );\n " ;
2661
+ return target;
2662
+ }
2663
+
2594
2664
void visit_IntrinsicFunction (const ASR::IntrinsicFunction_t &x) {
2595
2665
std::string out;
2666
+ std::string indent (4 , ' ' );
2596
2667
switch (x.m_intrinsic_id ) {
2597
2668
SET_INTRINSIC_NAME (Sin, " sin" );
2598
2669
SET_INTRINSIC_NAME (Cos, " cos" );
@@ -2607,22 +2678,51 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
2607
2678
SET_INTRINSIC_NAME (Exp, " exp" );
2608
2679
SET_INTRINSIC_NAME (Exp2, " exp2" );
2609
2680
SET_INTRINSIC_NAME (Expm1, " expm1" );
2610
- SET_INTRINSIC_NAME (SymbolicSymbol, " Symbol" );
2611
- SET_INTRINSIC_NAME (SymbolicInteger, " Integer" );
2612
- SET_INTRINSIC_NAME (SymbolicPi, " pi" );
2613
- case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicAdd)):
2614
- case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicSub)):
2615
- case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicMul)):
2616
- case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicDiv)):
2681
+ case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicAdd)): {
2682
+ src = performSymbolicOperation (" basic_add" , x);
2683
+ return ;
2684
+ }
2685
+ case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicSub)): {
2686
+ src = performSymbolicOperation (" basic_sub" , x);
2687
+ return ;
2688
+ }
2689
+ case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicMul)): {
2690
+ src = performSymbolicOperation (" basic_mul" , x);
2691
+ return ;
2692
+ }
2693
+ case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicDiv)): {
2694
+ src = performSymbolicOperation (" basic_div" , x);
2695
+ return ;
2696
+ }
2617
2697
case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicPow)): {
2618
- LCOMPILERS_ASSERT (x.n_args == 2 );
2698
+ src = performSymbolicOperation (" basic_pow" , x);
2699
+ return ;
2700
+ }
2701
+ case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicPi)): {
2702
+ headers.insert (" symengine/cwrapper.h" );
2703
+ LCOMPILERS_ASSERT (x.n_args == 0 );
2704
+ std::string target = symengine_queue.push ();
2705
+ symengine_src += indent + " basic_const_pi(" + target + " );\n " ;
2706
+ src = target;
2707
+ return ;
2708
+ }
2709
+ case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicSymbol)): {
2710
+ headers.insert (" symengine/cwrapper.h" );
2711
+ LCOMPILERS_ASSERT (x.n_args == 1 );
2619
2712
this ->visit_expr (*x.m_args [0 ]);
2620
- std::string arg1 = src;
2621
- this ->visit_expr (*x.m_args [1 ]);
2622
- std::string arg2 = src;
2623
- out = arg1 + " ," + arg2;
2624
- src = out;
2625
- break ;
2713
+ std::string target = symengine_queue.push ();
2714
+ symengine_src += indent + " symbol_set(" + target + " , " + src + " );\n " ;
2715
+ src = target;
2716
+ return ;
2717
+ }
2718
+ case (static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicInteger)): {
2719
+ headers.insert (" symengine/cwrapper.h" );
2720
+ LCOMPILERS_ASSERT (x.n_args == 1 );
2721
+ this ->visit_expr (*x.m_args [0 ]);
2722
+ std::string target = symengine_queue.push ();
2723
+ symengine_src += indent + " integer_set_si(" + target + " , " + src + " );\n " ;
2724
+ src = target;
2725
+ return ;
2626
2726
}
2627
2727
default : {
2628
2728
throw LCompilersException (" IntrinsicFunction: `"
@@ -2631,16 +2731,9 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
2631
2731
}
2632
2732
}
2633
2733
headers.insert (" math.h" );
2634
- if (x.n_args == 0 ){
2635
- src = out;
2636
- } else if (x.n_args == 1 ) {
2637
- this ->visit_expr (*x.m_args [0 ]);
2638
- if ((x.m_intrinsic_id != static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicSymbol)) &&
2639
- (x.m_intrinsic_id != static_cast <int64_t >(ASRUtils::IntrinsicFunctions::SymbolicInteger))) {
2640
- out += " (" + src + " )" ;
2641
- src = out;
2642
- }
2643
- }
2734
+ this ->visit_expr (*x.m_args [0 ]);
2735
+ out += " (" + src + " )" ;
2736
+ src = out;
2644
2737
}
2645
2738
};
2646
2739
0 commit comments