New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generics, wrong sum #1823
Comments
The code shared above in the description of this issue does not seem to compile for me with LFortran. $ cat examples/expr2.f90
module template_add_m
implicit none
private
public :: add_t
requirement R(T)
type :: T; end type
end requirement
template add_t(T)
requires R(T)
private
public :: add_generic
contains
function add_generic(x, y, z) result(s)
type(T), intent(in) :: x, y, z
type(T) :: s
print*, "x, y, z, x+y+z =", x, y, z, x+y+z
s = x + y + z
print *, s
end function
end template
function add_integer2(x, y, z) result(s)
integer, intent(in) :: x, y, z
integer :: s
print*, "x, y, z, x+y+z =", x, y, z, x+y+z
s = x + y + z
print *, s
end function
contains
subroutine test_template()
real :: a
integer :: n
instantiate add_t(real), only: add_real => add_generic
a = add_real(5.1, 7.2, 10.0)
print*, "The result is ", a
instantiate add_t(integer), only: add_integer => add_generic
n = add_integer(5, 9, 10)
s = add_integer2(5, 9, 10)
print*, "The result is ", n, s
end subroutine
end module
program template_add
use template_add_m
implicit none
call test_template()
end program template_add
$ lfortran examples/expr2.f90
syntax error: Token 'function' is unexpected here
--> examples/expr2.f90:24:9
|
24 | function add_integer2(x, y, z) result(s)
| ^^^^^^^^
Note: if any of the above error or warning messages are not clear or are lacking
context please report it to us (we consider that a bug that must be fixed). |
Here is the code that works: module template_add_m
implicit none
private
public :: add_t
requirement R(T)
type :: T; end type
end requirement
template add_t(T)
requires R(T)
private
public :: add_generic
contains
function add_generic(x, y, z) result(s)
type(T), intent(in) :: x, y, z
type(T) :: s
print*, "x, y, z, x+y+z =", x, y, z, x+y+z
s = x + y + z
print *, s
end function
end template
contains
function add_integer2(x, y, z) result(s)
integer, intent(in) :: x, y, z
integer :: s
print*, "x, y, z, x+y+z =", x, y, z, x+y+z
s = x + y + z
print *, s
end function
subroutine test_template()
real :: a
integer :: n, s
instantiate add_t(real), only: add_real => add_generic
a = add_real(5.1, 7.2, 10.0)
print*, "The result is ", a
instantiate add_t(integer), only: add_integer => add_generic
n = add_integer(5, 9, 10)
s = add_integer2(5, 9, 10)
print*, "The result is ", n, s
end subroutine
end module
program template_add
use template_add_m
implicit none
call test_template()
end program template_add $ lfortran examples/expr2.f90
x, y, z, x+y+z = 5.09999990e+00 7.19999981e+00 1.00000000e+01 1.00000000e+01
1.00000000e+01
The result is 1.00000000e+01
x, y, z, x+y+z = 5 9 10 10
10
x, y, z, x+y+z = 5 9 10 24
24
The result is 10 24 |
Yup, I figured that. The
|
@ansharlubis do you have time to investigate what is going on here? |
@ansharlubis thanks. I think we don't want to have TemplateBinOp, because as you said, it might not be defined for all types. But I think we want to support "+". I think AST->ASR can verify that "+" is supported by the template type, and if so, implicitly create the proper function "plus" to represent "+". |
@certik let me consider it step-by-step. If we encounter In the end something like |
I see. Well, here are the operations to consider: BitNot, UnaryMinus, Compare, BinOp, Not, Len, Item, Section, Concat, Ord, Chr, etc. I think all the operations in expr must now be representable using templates. We used to have abstract BinOp, but we found it much easier to separate into individual types. Say string concat operation:
If |
Handled this in #1831. |
* Restored TemplateBinOp * Updated tests * Renamed tests * Forgot to update reference tests * Got the interface working in requirement * Converted binop in template into the corresponding functions during template construction, add various checks for requirement's parameters * Removed TemplateBinOp * Modified the template example with + operator --------- Co-authored-by: Ondřej Čertík <ondrej@certik.us>
This:
Gives:
The text was updated successfully, but these errors were encountered: