Skip to content

Commit 1cb7340

Browse files
committed
Add eval function for value
1 parent 847bc40 commit 1cb7340

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

src/libasr/pass/intrinsic_function_registry.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,14 @@ namespace FlipSign {
13581358
x.base.base.loc, diagnostics);
13591359
}
13601360

1361+
static ASR::expr_t *eval_FlipSign(Allocator &al, const Location &loc,
1362+
ASR::ttype_t* t1, Vec<ASR::expr_t*> &args) {
1363+
int a = ASR::down_cast<ASR::IntegerConstant_t>(args[0])->m_n;
1364+
double b = ASR::down_cast<ASR::RealConstant_t>(args[1])->m_r;
1365+
if (a % 2 == 1) b = -b;
1366+
return make_ConstantWithType(make_RealConstant_t, b, t1, loc);
1367+
}
1368+
13611369
static inline ASR::asr_t* create_FlipSign(Allocator& al, const Location& loc,
13621370
Vec<ASR::expr_t*>& args,
13631371
const std::function<void (const std::string &, const Location &)> err) {
@@ -1371,6 +1379,12 @@ namespace FlipSign {
13711379
args[0]->base.loc);
13721380
}
13731381
ASR::expr_t *m_value = nullptr;
1382+
if (all_args_evaluated(args)) {
1383+
Vec<ASR::expr_t*> arg_values; arg_values.reserve(al, 2);
1384+
arg_values.push_back(al, expr_value(args[0]));
1385+
arg_values.push_back(al, expr_value(args[1]));
1386+
m_value = eval_FlipSign(al, loc, expr_type(args[1]), arg_values);
1387+
}
13741388
return ASR::make_IntrinsicScalarFunction_t(al, loc,
13751389
static_cast<int64_t>(IntrinsicScalarFunctions::FlipSign),
13761390
args.p, args.n, 0, ASRUtils::expr_type(args[1]), m_value);
@@ -1383,9 +1397,20 @@ namespace FlipSign {
13831397
fill_func_arg("signal", arg_types[0]);
13841398
fill_func_arg("variable", arg_types[1]);
13851399
auto result = declare(fn_name, return_type, ReturnVar);
1400+
/*
1401+
real(real32) function flipsigni32r32(signal, variable)
1402+
integer(int32), intent(in) :: signal
1403+
real(real32), intent(out) :: variable
1404+
integer(int32) :: q
1405+
q = signal/2
1406+
flipsigni32r32 = variable
1407+
if (signal - 2*q == 1 ) flipsigni32r32 = -variable
1408+
end subroutine
1409+
*/
1410+
13861411
ASR::expr_t *two = i(2, arg_types[0]);
13871412
ASR::expr_t *q = iDiv(args[0], two);
1388-
ASR::expr_t *cond = iMul(args[0], iMul(two, q));
1413+
ASR::expr_t *cond = iSub(args[0], iMul(two, q));
13891414
body.push_back(al, b.If(iEq(cond, i(1, arg_types[0])), {
13901415
b.Assignment(result, f32_neg(args[1], arg_types[1]))
13911416
}, {

0 commit comments

Comments
 (0)