Skip to content

Commit

Permalink
overload exp() for f64 arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffIrwin committed Oct 27, 2024
1 parent a7e149c commit 45adb3d
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 42 deletions.
100 changes: 58 additions & 42 deletions src/core.f90
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ module syntran__core_m
! + system: multiple out args? iostat and stdout
! * recursive user-defined fns
! * done:
! + exp (non-variadic)
! + exp
! + min, max, sum
! + size (non-variadic but polymorphic)
! + readln, writeln, println, open, close, str casting
Expand Down Expand Up @@ -219,14 +219,16 @@ subroutine declare_intrinsic_fns(fns)
i64_sca_fn, parse_i64_fn, i32_sca_fn, exit_fn, any_fn, all_fn, count_fn, &
min_i64_fn, max_i64_fn, i32_arr_fn, i64_arr_fn, sum_i32_fn, &
sum_f32_fn, sum_i64_fn, parse_f32_fn, min_f32_fn, max_f32_fn, &
char_fn, sum_f64_fn, parse_f64_fn, min_f64_fn, max_f64_fn, exp_f64_fn
char_fn, sum_f64_fn, parse_f64_fn, min_f64_fn, max_f64_fn, exp_f64_fn, &
exp_f64_arr_fn

! Increment index for each fn and then set num_fns
id_index = 0

!********

! Should exp be overloaded for ints?
! Should exp be overloaded for ints? No, fortran only allows exp on real or
! complex types

exp_f32_fn%type%type = f32_type
allocate(exp_f32_fn%params(1))
Expand All @@ -247,13 +249,26 @@ subroutine declare_intrinsic_fns(fns)
exp_f64_fn%params(1)%type = f64_type
exp_f64_fn%param_names%v(1)%s = "x"

! Insert the fn into the dict. These are global intrinsic fns, so there's no
! need to check iostat

call fns%insert("0exp_f64", exp_f64_fn, id_index)

!********

exp_f64_arr_fn%type%type = array_type
allocate(exp_f64_arr_fn%type%array)
exp_f64_arr_fn%type%array%type = f64_type
exp_f64_arr_fn%type%array%rank = -1

allocate(exp_f64_arr_fn%params(1))
allocate(exp_f64_arr_fn%param_names%v(1))

exp_f64_arr_fn%params(1)%type = any_type

exp_f64_arr_fn%param_names%v(1)%s = "x"

call fns%insert("0exp_f64_arr", exp_f64_arr_fn, id_index)

!********

! We could make max() and min() work with just 1 argument too. I'm not sure
! why you would want to be able to take the max of 1 number, but it seems
! like an arbitrary limitation. Anyway we follow the Fortran convention
Expand Down Expand Up @@ -783,42 +798,43 @@ subroutine declare_intrinsic_fns(fns)

fns%fns = &
[ &
exp_f32_fn , &
exp_f64_fn , &
min_i32_fn , &
min_i64_fn , &
min_f32_fn , &
min_f64_fn , &
max_i32_fn , &
max_i64_fn , &
max_f32_fn , &
max_f64_fn , &
println_fn , &
str_fn , &
len_fn , &
parse_i32_fn, &
parse_i64_fn, &
parse_f32_fn, &
parse_f64_fn, &
char_fn , &
i32_sca_fn , &
i32_arr_fn , &
i64_sca_fn , &
i64_arr_fn , &
open_fn , &
readln_fn , &
writeln_fn , &
eof_fn , &
close_fn , &
exit_fn , &
size_fn , &
count_fn , &
sum_i32_fn , &
sum_i64_fn , &
sum_f32_fn , &
sum_f64_fn , &
all_fn , &
any_fn &
exp_f32_fn , &
exp_f64_fn , &
exp_f64_arr_fn, &
min_i32_fn , &
min_i64_fn , &
min_f32_fn , &
min_f64_fn , &
max_i32_fn , &
max_i64_fn , &
max_f32_fn , &
max_f64_fn , &
println_fn , &
str_fn , &
len_fn , &
parse_i32_fn , &
parse_i64_fn , &
parse_f32_fn , &
parse_f64_fn , &
char_fn , &
i32_sca_fn , &
i32_arr_fn , &
i64_sca_fn , &
i64_arr_fn , &
open_fn , &
readln_fn , &
writeln_fn , &
eof_fn , &
close_fn , &
exit_fn , &
size_fn , &
count_fn , &
sum_i32_fn , &
sum_i64_fn , &
sum_f32_fn , &
sum_f64_fn , &
all_fn , &
any_fn &
]

end subroutine declare_intrinsic_fns
Expand Down
23 changes: 23 additions & 0 deletions src/eval.f90
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,29 @@ recursive subroutine eval_fn_call(node, state, res)
res%sca%f64 = exp(arg1%sca%f64)
state%returned = .true.

case ("0exp_f64_arr")

call syntax_eval(node%args(1), state, arg1)

! This requires an explicit call to mold() to copy array meta-data. The
! similar fn 0i32_arr already calls mold() via to_i32_array()

!res = arg1
res%array = mold(arg1%array, f64_type)
!allocate(res%array)
!res%array%rank = arg1%array%rank
!res%array%size = arg1%array%size
!res%type = array_type
!res%array%type = f64_type

!allocate(res%array)
!res%type = array_type
!res%array%type = f64_type

res%array%f64 = exp(arg1%array%f64)
!print *, "arr = ", res%array%f64
state%returned = .true.

case ("0min_i32")

call syntax_eval(node%args(1), state, arg)
Expand Down
15 changes: 15 additions & 0 deletions src/parse_fn.f90
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,21 @@ recursive module function parse_fn_call(parser) result(fn_call)
if (args%len_ >= 1) type_ = args%v(1)%val%type

select case (type_)
case (array_type)

! TODO: select array sub type

fn_call%identifier%text = "0exp_f64_arr"

if (args%len_ >= 1) then
allocate(fn_call%val%array)
fn_call%val%array%rank = args%v(1)%val%array%rank

!print *, "exp has_rank"
rank = fn_call%val%array%rank
has_rank = .true.
end if

case (f32_type)
fn_call%identifier%text = "0exp_f32"
case default
Expand Down
3 changes: 3 additions & 0 deletions src/tests/test.f90
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,9 @@ subroutine unit_test_intr_fns(npass, nfail)
abs(eval_f32('exp(1.0f);') - exp(1.0)) < tol, &
abs(eval_f64('exp(0.0);') - 1.0d0) < tol, &
abs(eval_f64('exp(1.0);') - exp(1.0d0)) < tol, &
abs(eval_f64('sum(exp([0.0, 1.0]));') - sum(exp([0.d0, 1.0d0]))) < tol, &
abs(eval_f64('sum(exp([0.5, 1.0]));') - sum(exp([0.5d0, 1.0d0]))) < tol, &
abs(eval_f64('sum(exp([2.0, 1.0]));') - sum(exp([2.d0, 1.0d0]))) < tol, &
eval_i32('min(3, 2);') == 2, &
eval_i32('min(2, 2);') == 2, &
eval_i32('min(2, 3, 4);') == 2, &
Expand Down

0 comments on commit 45adb3d

Please sign in to comment.