-
Notifications
You must be signed in to change notification settings - Fork 171
Optional args #2851
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
base: main
Are you sure you want to change the base?
Optional args #2851
Conversation
Thanks for being patient with our new workflow. I checked it out locally, and got on updating the submodule:
But the following two commands fixed it:
|
@swamishiju help me understand the issue here. In LPython, the following code: def factorial_1(x: i32, y:i32 =1) ->i32 :
if x <= 1:
return y
return x * factorial_1(x-1)
def test_factorial_1():
test_00 : i32 = factorial_1(1)
print("test_00 is =>", test_00)
#assert test_00 == 1
test_01 : i32 = factorial_1(5,0)
print("test_01 is =>", test_01)
#assert test_01 == 120
test_02 : i32 = factorial_1(1,5555)
print("test_02 is =>", test_02)
#assert test_02 == 5555 Becomes after all ASR passes: integer(4) function factorial_1(x, y, is_y_present_) result(_lpython_return_variable)
logical(4), intent(in) :: is_y_present_
integer(4), intent(in) :: x
integer(4), intent(in) :: y
if (x <= 1) then
_lpython_return_variable = y
return
end if
_lpython_return_variable = x*factorial_1(x - 1, 1, .true.)
return
end function factorial_1
subroutine test_factorial_1()
integer(4) :: test_00
integer(4) :: test_01
integer(4) :: test_02
test_00 = factorial_1(1, 1, .true.)
print *, "test_00 is =>", test_00
test_01 = factorial_1(5, 0, .true.)
print *, "test_01 is =>", test_01
test_02 = factorial_1(1, 5555, .true.)
print *, "test_02 is =>", test_02
end subroutine test_factorial_1 So the --- a/src/libasr/pass/array_struct_temporary.cpp
+++ b/src/libasr/pass/array_struct_temporary.cpp
@@ -2240,8 +2240,9 @@ class TransformVariableInitialiser:
result_vec.push_back(al, ASRUtils::STMT(ASR::make_Associate_t(
al, loc, target, value)));
} else {
- result_vec.push_back(al, ASRUtils::STMT(make_Assignment_t_util(
- al, loc, target, value, nullptr, exprs_with_target)));
+ if (!(xx.m_intent == ASR::intentType::In && xx.m_presence == ASR::presenceType::Optional))
+ result_vec.push_back(al, ASRUtils::STMT(make_Assignment_t_util(
+ al, loc, target, value, nullptr, exprs_with_target)));
}
xx.m_symbolic_value = nullptr;
xx.m_value = nullptr; In here we skip pushing back into |
Previously we were transforming arguments also, and if they are intent(in), it becomes problematic. To solve optional arguments, we should assign their values at the call site, like LPython does. Towards lcompilers/lpython#2851.
How about this fix: lfortran/lfortran#7016. |
I merged that one, and updated LPython here: #2852. Once it's merged, then go ahead and update your PR against the latest main of LPython. |
@certik I found my fix while looking at C back end code if I remember correctly def foo(bar:i32 = 5):
pass would give error because of the intent check, if we commented that out the generated C code was
I figured that something similar happens on C and LLVM back ends since commenting out the intent check for testing always gives This code also failed asr_verify after the array_struct_temporary pass (this is the one that creates the assignment). The easiest way I thought was to simply not create an assignment for optional function arguments and use the symbolic value for simply book keeping and making the proper function calls. |
Yes I think that makes more sense, mine was based on thinking only optional function arguments will be both Optional and In ( it does feel a bit hand-wavey ) but yes your code is definitely better and also more readable. |
No worries I had read up on how sub-modules work so that was a plus |
@certik There is also an existing problem with optional args from pre sync def foo(bar:i32, baz:i32 = 2, raz:i32) Will not be a valid function defn in CP I dont think there is a check against that |
Fixed optional args for LP
Removed C test for
def_func_01
gives some error relating to_lfortran_strcpy
not being found