Skip to content
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

Refactor FuncLexr to use iterator functions #39

Closed
wants to merge 4 commits into from
Closed

Refactor FuncLexr to use iterator functions #39

wants to merge 4 commits into from

Conversation

johnhuichen
Copy link

@johnhuichen johnhuichen commented Oct 23, 2023

I am making a minor change to crates/vimfuncs/build.rs.

It doesn't impact the functionality but use more idiomatic iterator. I also made some changes to keep abstraction level consistent. Please let me know if that's too many changes.

Changes:

  1. FuncLexer only has one field chars which is an iterator
  2. FuncToken has a new special token Skip
  3. FuncLexer::lex function delegates processing of characters to other struct methods
  4. Removed enum methods for FuncToken (string, number...) and instead use pattern matching to get enum values

Testing:

  1. cargo run test is green
  2. I used data/global_functions.txt to generate a list of tokens using the original script and the refactored script. They produced identifical content

None => break,
while let Some(ch) = self.chars.next() {
let tok = match ch {
'{' => self.process_left_brace(),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is any particular reason we need to make these all functions if they just return a value, i think it muddies the code

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true that these functions just return a value.

I did it for consistency and decoupling. If the logic of process_left_brace should change in the future, it's easier for another contributor to say with confidence that the logic is probably contained in the struct method.

Of course it's debatable that inlining the logic is also obvious that the logic is contained there.

I can revert back if you feel strongly about it

if !self.ch().is_whitespace() {
return;
}
fn skip_whitespaces(&mut self) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

skip_whitespace is a better name

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I will revert back

}
}

fn identifier(self) -> String {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't get why you removed these

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because these functions used on incorrect types (e.g. number on FuncToken::String) will throw an error, and it's not really unreachable

I replaced them with pattern matching the enum because I think it's more idiomatic.

Let me know what you think. I can revert back if needed

@tjdevries
Copy link
Owner

There's kind of a lot of extra changes in the PR. It's not a huge deal but in general it's nice if the changes can be made smaller so as to be more easily reviewed (for example, some of the name changes and things I don't really like as much as the names that were there before)

@johnhuichen
Copy link
Author

There's kind of a lot of extra changes in the PR. It's not a huge deal but in general it's nice if the changes can be made smaller so as to be more easily reviewed (for example, some of the name changes and things I don't really like as much as the names that were there before)

100% agreed. I started making too many changes as part of refactoring.

@johnhuichen
Copy link
Author

I cleaned the changes up by

  1. renaming skip_whitespaces to skip_whitespace
  2. revert deletion of FuncToken methods
  3. revert changes to anything outside FuncLexer

I made a new change so that now lex method iterates through characters by peek() instead of next(). See L64. I think this would make the design more flexible to change in the future. Let me know what you think

@tjdevries

let ch = self.chars.get(self.position).cloned();
self.position += 1;
fn process_left_brace(&mut self) -> FuncToken {
self.chars.next();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

making it explicit that the iterator advances by one step when creating a token

@johnhuichen johnhuichen closed this by deleting the head repository Jan 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants