Skip to content

Format string on parsing - #429

Merged
CohenArthur merged 3 commits into
jinko-core:feature/string-interpolationfrom
SanderJSA:parse-format-string
Dec 12, 2021
Merged

Format string on parsing#429
CohenArthur merged 3 commits into
jinko-core:feature/string-interpolationfrom
SanderJSA:parse-format-string

Conversation

@SanderJSA

Copy link
Copy Markdown
Collaborator

This PR formats string at parse time instead of eval time,
here's an example change in behavior caused by this PR:
before:

my_str = "{wont_fail}"
wont_fail = 10
println(my_str)

after:

my_str = "{will_fail}"
will_fail = 10
println(my_str)

The big difference it this string is now formatted in the context where it is built instead on where it is called.

I'm not sure if/what could I should remove to disable de eval time formatting though.

@SanderJSA
SanderJSA requested review from CohenArthur and removed request for CohenArthur December 11, 2021 18:21

@CohenArthur CohenArthur left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you also add a test with an interpolation right at the beginning of the string? I know you handle it properly in the parser, but just for later regressions. Something like "{world} hello" or whatever.

Also, we need to remove the expansion phase from the JkString struct but we should do that in a later PR.

Thanks a lot for this!!!

pub(crate) fn string_constant(input: &str) -> ParseResult<&str, Box<dyn Instruction>> {
let (input, string_value) = Token::string_constant(input)?;
let (input, inner) = preceded(Token::double_quote, ConstantConstruct::inner_string)(input)?;
let string = inner.unwrap_or_else(|| Box::new(JkString::from("")));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why unwrap here?

Comment on lines +38 to +39
if let Ok((input, _)) = Token::double_quote(input) {
Ok((input, None))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So if the first character we see is a double quote, we return None? Is that why we unwrap_or_else in the caller?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The elegant implementation here was to return an empty jkstring when we reach a double quote, that way we indiscriminately concat whatever we have afterwards instead of matching as you can see in the concat function, it would also avoid the unwrap_or_else in the function above.
However doing this cause EVERY string to call .concat("") when built, it also causes extra heap allocation in the AST to create this method call.
That's why instead i return an Option and handle it as a special case, thus avoiding unnecessary heap allocation and slightly better runtime performances.

@CohenArthur

Copy link
Copy Markdown
Member

Also @SanderJSA, could you change the target branch to feature/string-formatting?

@SanderJSA

SanderJSA commented Dec 12, 2021

Copy link
Copy Markdown
Collaborator Author

Could you also add a test with an interpolation right at the beginning of the string? I know you handle it properly in the parser, but just for later regressions. Something like "{world} hello" or whatever.

Done

@SanderJSA
SanderJSA changed the base branch from master to feature/string-interpolation December 12, 2021 15:37
@CohenArthur
CohenArthur merged commit 99ef287 into jinko-core:feature/string-interpolation Dec 12, 2021
@SanderJSA
SanderJSA deleted the parse-format-string branch December 12, 2021 18:44
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