I would like to see something similar to C++'s constexpr functions. As Prog8's const is more similar to constexpr, I would suggest this be spelled as const sub. Due to the difference's between the languages and out of understanding that it is not something trivial to implement, I think restricting it to the same limitations constexpr functions had in C++11 would make sense: such a subroutine could only consist of a single return statement, which itself can be evaluated as a constant expression as long as all arguments are themselves constants.
If a const subroutine is called with constant arguments, the entire expression should be evaluated at compile time.
If a const subroutine is called with variable arguments, the return statement would instead be inlined to the call site. I believe this should avoid the issues inlining regular subroutines had in earlier versions of Prog8.
Examples:
; const sub that replicates the common BIT macro in C
const sub BIT(ubyte shift) -> uword {
return 1 << shift
}
const uword foo = BIT(3) ; at compile time the right hand size would evaluate to 0x08
ubyte shiftvar = 3
uword bar = BIT(shiftvar) ; the right hand side would be expanded to 1 << shiftvar
ubyte shiftvar = 3
const uword bar = BIT(shiftvar) ; compilation error
const ubyte shiftconst = 3
uword baz = BIT(shiftconst) ; at compile time the right hand size would evaluate to 0x08
If this is seen as something desirable, I can try implementing it myself when I have some time.
inline sub with the same restrictions but allowing for referencing variables in the return statement could also be useful.
I mainly see this as a way to make code more readable and reduce repetition, without incurring runtime costs or making the build require anything more than the prog8 compiler.
My 2 specific use cases that I really want this for are:
BIT so that I can define bitflags without 1 << or hex literals every time. This one mostly would just be compile-time evaluation.
- Long else if chains with conditions like:
(controller.buttons & controller.RIGHT) as bool. It would be really nice to be able to replace that with something like ButtonPressed(controller.RIGHT) with the guarantee that I'm not introducing a subroutine call. This would require the basic inlining I requested.
I would like to see something similar to C++'s
constexprfunctions. As Prog8'sconstis more similar toconstexpr, I would suggest this be spelled asconst sub. Due to the difference's between the languages and out of understanding that it is not something trivial to implement, I think restricting it to the same limitationsconstexprfunctions had in C++11 would make sense: such a subroutine could only consist of a single return statement, which itself can be evaluated as a constant expression as long as all arguments are themselves constants.If a const subroutine is called with constant arguments, the entire expression should be evaluated at compile time.
If a const subroutine is called with variable arguments, the return statement would instead be inlined to the call site. I believe this should avoid the issues inlining regular subroutines had in earlier versions of Prog8.
Examples:
If this is seen as something desirable, I can try implementing it myself when I have some time.
inline subwith the same restrictions but allowing for referencing variables in the return statement could also be useful.I mainly see this as a way to make code more readable and reduce repetition, without incurring runtime costs or making the build require anything more than the prog8 compiler.
My 2 specific use cases that I really want this for are:
BITso that I can define bitflags without1 <<or hex literals every time. This one mostly would just be compile-time evaluation.(controller.buttons & controller.RIGHT) as bool. It would be really nice to be able to replace that with something likeButtonPressed(controller.RIGHT)with the guarantee that I'm not introducing a subroutine call. This would require the basic inlining I requested.