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
builtin: Add is_hex()
, is_int()
, is_bin()
, and is_oct()
by strings - Feature
#20540
Conversation
You'll need to format your changes. |
@JalonSolov Any suggestions on what I should do? |
Just run |
Note that you can install a git hook to check the files when you try to commit them by running |
@JalonSolov |
Still says |
@JalonSolov Sorry! I had forgotten! |
my only concern as always is performance, |
"I do too! In this case, the implementation meets this requirement, in my view, by eliminating any other invalid formats in the checks before the If I find a better way, I will submit a new pull request with the improvement! 😀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After a quick check on the code I'm suggesting to rewrite the functions in a more efficent way.
At my first sight I missed the string allocation in the function.
Allocate in the Heap for a check on a string it is truly not recommended IMHO.
Anyway I appreciate a lot the effort the @viniciusfdasilva put in this code 👍
Thanks a lot for your effort to contribute to V.
@@ -425,6 +425,109 @@ fn test_rsplit_once() ? { | |||
assert ext3 == '' | |||
} | |||
|
|||
fn test_is_bin() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think if the cases like +0b1001
or +0xFA3
must be managed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! I find the problem! kkkkk
I appreciate the recognition for the effort in my collaboration! I'm just starting with the language! I've only had 1 month of exposure to it, and I'm happy to contribute to the language's development! :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me it is ok!
Tnx for your work :)
for i < str.len { | ||
if str[i] < `0` || str[i] > `7` { | ||
return false | ||
} | ||
i++ | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More idiomatic (and slightly shorter) V would be
for i < str.len { | |
if str[i] < `0` || str[i] > `7` { | |
return false | |
} | |
i++ | |
} | |
for c in str[i..] { | |
if c < `0` || c > `7` { | |
return false | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
less performant I suppose due the str[i..]
-_-
We can increase speed further using pointers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for c in str[i..]
I agree with @penguindark. I think direct index access might be more performant by avoiding the cost of generating the slice in my opinion! I suggest sticking to the original implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this were the only change, true. However, you could move the entire function inside for c in str
and avoid using the index at all.
However, that can be done later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course! Thank you for the suggestion! I request approval for this PR! I plan to work on some other similar functions as well!
Let's analyze later which aspects can lead one approach to be better than another! :)
I appreciate both of you for the suggestions! 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the problem of the str[i..]
is that it generate a copy of the data,
at the actual compiler state it is very inefficient.
I think we can proceed with the merge of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me it is mergiable
// Check if a string is an octal value. Returns 'true' if it is, or 'false' if it is not | ||
@[direct_array_access] | ||
pub fn (str string) is_oct() bool { | ||
mut i := 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mut i := 0 | |
if str.len == 0 { | |
return false | |
} | |
mut i := 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise str[i]
on the next line will read the 0th byte that V requires for all V strings, for compatibility with C, which is ok, but not ideal (there are some situations where V strings may be generated inside unsafe{} blocks, for internal use, that will not have that 0th byte at the end, and it will be hard to track which string methods need modification for that case, and which do not).
// Check if a string is an binary value. Returns 'true' if it is, or 'false' if it is not | ||
@[direct_array_access] | ||
pub fn (str string) is_bin() bool { | ||
mut i := 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, if str.len == 0 { return false }
should be here as well.
// Check if a string is an hexadecimal value. Returns 'true' if it is, or 'false' if it is not | ||
@[direct_array_access] | ||
pub fn (str string) is_hex() bool { | ||
mut i := 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add if str.len == 0 { return false }
at the start.
// Check if a string is an integer value. Returns 'true' if it is, or 'false' if it is not | ||
@[direct_array_access] | ||
pub fn (str string) is_int() bool { | ||
mut i := 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add if str.len == 0 { return false }
at the start.
@@ -425,6 +425,168 @@ fn test_rsplit_once() ? { | |||
assert ext3 == '' | |||
} | |||
|
|||
fn test_is_bin() { | |||
assert '0b1'.is_bin() == true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also assert on the ''.is_bin()
etc cases too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work.
Code
Test code
Test output