@@ -45,6 +45,8 @@ enum SpecialFunc {
45
45
AMax,
46
46
Sum,
47
47
Range,
48
+ Size,
49
+ Pow,
48
50
};
49
51
50
52
std::map<std::string, SpecialFunc> special_function_map = {
@@ -62,6 +64,8 @@ std::map<std::string, SpecialFunc> special_function_map = {
62
64
{" amax" , SpecialFunc::AMax},
63
65
{" sum" , SpecialFunc::Sum},
64
66
{" range" , SpecialFunc::Range},
67
+ {" size" , SpecialFunc::Size},
68
+ {" pow" , SpecialFunc::Pow},
65
69
};
66
70
67
71
class OneTimeUseString {
@@ -438,6 +442,9 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
438
442
intent_type = ASR::intentType::In;
439
443
type = ASRUtils::type_get_past_const (type);
440
444
}
445
+ if ( ASRUtils::is_allocatable (type) ) {
446
+ type = ASRUtils::type_get_past_allocatable (type);
447
+ }
441
448
if ( x->getType ()->getTypeClass () != clang::Type::LValueReference &&
442
449
ASRUtils::is_array (type) ) {
443
450
throw std::runtime_error (" Array objects should be passed by reference only." );
@@ -496,7 +503,8 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
496
503
TraverseStmt (callee);
497
504
ASR::expr_t * asr_callee = ASRUtils::EXPR (tmp.get ());
498
505
if ( !check_and_handle_special_function (x, asr_callee) ) {
499
- throw std::runtime_error (" Only xt::xtensor::shape, xt::xtensor::fill is supported." );
506
+ throw std::runtime_error (" Only xt::xtensor::shape, "
507
+ " xt::xtensor::fill, xt::xtensor::size is supported." );
500
508
}
501
509
502
510
return true ;
@@ -764,6 +772,14 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
764
772
tmp = ASR::make_ArraySize_t (al, Lloc (x), callee, dim,
765
773
ASRUtils::TYPE (ASR::make_Integer_t (al, Lloc (x), 4 )),
766
774
nullptr );
775
+ } else if (sf == SpecialFunc::Size) {
776
+ if ( args.size () != 0 ) {
777
+ throw std::runtime_error (" xt::xtensor::size should be called with only one argument." );
778
+ }
779
+
780
+ tmp = ASR::make_ArraySize_t (al, Lloc (x), callee, nullptr ,
781
+ ASRUtils::TYPE (ASR::make_Integer_t (al, Lloc (x), 4 )),
782
+ nullptr );
767
783
} else if (sf == SpecialFunc::Fill) {
768
784
if ( args.size () != 1 ) {
769
785
throw std::runtime_error (" xt::xtensor::fill should be called with only one argument." );
@@ -804,6 +820,12 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
804
820
tmp = ASRUtils::make_IntrinsicScalarFunction_t_util (al, Lloc (x),
805
821
static_cast <int64_t >(ASRUtils::IntrinsicScalarFunctions::Exp),
806
822
args.p , args.size (), 0 , ASRUtils::expr_type (args.p [0 ]), nullptr );
823
+ } else if ( sf == SpecialFunc::Pow ) {
824
+ if ( args.size () != 2 ) {
825
+ throw std::runtime_error (" Pow accepts exactly two arguments." );
826
+ }
827
+
828
+ CreateBinOp (args.p [0 ], args.p [1 ], ASR::binopType::Pow, Lloc (x));
807
829
} else if ( sf == SpecialFunc::Abs ) {
808
830
tmp = ASRUtils::make_IntrinsicScalarFunction_t_util (al, Lloc (x),
809
831
static_cast <int64_t >(ASRUtils::IntrinsicScalarFunctions::Abs),
@@ -1215,6 +1237,19 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
1215
1237
}
1216
1238
}
1217
1239
1240
+ void CreateUnaryMinus (ASR::expr_t * op, const Location& loc) {
1241
+ if ( ASRUtils::is_integer (*ASRUtils::expr_type (op)) ) {
1242
+ tmp = ASR::make_IntegerUnaryMinus_t (al, loc, op,
1243
+ ASRUtils::expr_type (op), nullptr );
1244
+ } else if ( ASRUtils::is_real (*ASRUtils::expr_type (op)) ) {
1245
+ tmp = ASR::make_RealUnaryMinus_t (al, loc, op,
1246
+ ASRUtils::expr_type (op), nullptr );
1247
+ } else {
1248
+ throw std::runtime_error (" Only integer and real types are supported so "
1249
+ " far for unary operator, found: " + ASRUtils::type_to_str (ASRUtils::expr_type (op)));
1250
+ }
1251
+ }
1252
+
1218
1253
bool TraverseBinaryOperator (clang::BinaryOperator *x) {
1219
1254
clang::BinaryOperatorKind op = x->getOpcode ();
1220
1255
TraverseStmt (x->getLHS ());
@@ -1311,7 +1346,7 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
1311
1346
name == " exit" || name == " printf" || name == " exp" ||
1312
1347
name == " sum" || name == " amax" || name == " abs" ||
1313
1348
name == " operator-" || name == " operator/" || name == " operator>" ||
1314
- name == " range" ) {
1349
+ name == " range" || name == " pow " ) {
1315
1350
if ( sym != nullptr && ASR::is_a<ASR::Function_t>(
1316
1351
*ASRUtils::symbol_get_past_external (sym)) ) {
1317
1352
throw std::runtime_error (" Special function " + name + " cannot be overshadowed yet." );
@@ -1431,11 +1466,11 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
1431
1466
1432
1467
bool TraverseUnaryOperator (clang::UnaryOperator* x) {
1433
1468
clang::UnaryOperatorKind op = x->getOpcode ();
1469
+ clang::Expr* expr = x->getSubExpr ();
1470
+ TraverseStmt (expr);
1471
+ ASR::expr_t * var = ASRUtils::EXPR (tmp.get ());
1434
1472
switch ( op ) {
1435
1473
case clang::UnaryOperatorKind::UO_PostInc: {
1436
- clang::Expr* expr = x->getSubExpr ();
1437
- TraverseStmt (expr);
1438
- ASR::expr_t * var = ASRUtils::EXPR (tmp.get ());
1439
1474
ASR::expr_t * incbyone = ASRUtils::EXPR (ASR::make_IntegerBinOp_t (
1440
1475
al, Lloc (x), var, ASR::binopType::Add,
1441
1476
ASRUtils::EXPR (ASR::make_IntegerConstant_t (
@@ -1445,8 +1480,12 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
1445
1480
is_stmt_created = true ;
1446
1481
break ;
1447
1482
}
1483
+ case clang::UnaryOperatorKind::UO_Minus: {
1484
+ CreateUnaryMinus (var, Lloc (x));
1485
+ break ;
1486
+ }
1448
1487
default : {
1449
- throw std::runtime_error (" Only postfix increment is supported so far" );
1488
+ throw std::runtime_error (" Only postfix increment and minus are supported so far. " );
1450
1489
}
1451
1490
}
1452
1491
return true ;
0 commit comments