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

[Feature request] String interpolation (like Swift) #1

Closed
Bellisario opened this issue Jun 21, 2022 · 5 comments · Fixed by #2
Closed

[Feature request] String interpolation (like Swift) #1

Bellisario opened this issue Jun 21, 2022 · 5 comments · Fixed by #2
Labels

Comments

@Bellisario
Copy link
Contributor


About

Javascript string interpolation is not always clear:

  • it appears difficult to read it because could be "confused" with code brackets;
  • "$" and "{" char are difficult to read when a text is sticky to them (making strings hard also to "format");
  • you could find yourself in a string you used the (double)quote and just to add a string interpolation you need to replace (double)quotes to ticks first, then also add the string interpolation itself, loosing time.

More about Swift string interpolation here: https://www.hackingwithswift.com/sixty/1/5/string-interpolation


Here is how it will look like:

let me = "Tom"
let years = 25
let question = "Hello \(me), how old are you?"
let answer = "I'm \(years) year\(years > 1 ? "s" : "") old!"

console.log(question + "\n" + answer)
/* Will log:
 *    Hello Tom, how old are you?
 *    I'm 25 years old!
 * ----------------------------------------
 * Note if years was 1 it returned "year", not "years", as you could do within Javascript interpolation
*/

And here is how it looks in JavaScript:

let me = "Tom"
let years = 25
let question = `Hello ${me}, how old are you?`
let answer = `I'm ${years} year${years > 1 ? "s" : ""} old!`

console.log(question + "\n" + answer)
/* Will log:
 *    Hello Tom, how old are you?
 *    I'm 25 years old!
 * ----------------------------------------
 * Note if years was 1 it returned "year", not "years"
*/
@coderaiser
Copy link
Owner

That's interesting, such interpolation can be solved in two steps:

  1. String with \(me) converted to ${me}.
  2. StringLiteral should be converted to TemplateLiteral.

Do you have ideas how to solve 1?

@Bellisario
Copy link
Contributor Author

Yes, I was trying to solve this problem by looping every character and add some logic, but I found that the custom string literal, because will be parsed as a string, cannot contain the "\(" syntax because the char "(" will in a certain way escape the parenthesis, also if there isn't a reason.

Before continue, this should be solved...
I think fixing this could be really hard, so to make the solution as simple as possible we may instead of using this syntax "\(example)" use this "/(example)"...

@coderaiser
Copy link
Owner

Let's add it :)! Are you willing for a PR?

@Bellisario
Copy link
Contributor Author

Yes, of course!
I just am facing a small issue: my output is a "StringLiteral" and not a "TemplateLiteral" (so the literal is enclosed by double quotes, not ticks), and I tried parsing it with Acorn "parseTemplate", but it throws me this error: "Unterminated template literal"...

How can I solve? Could be "parseTemplate" is not the good one? (I am trying to learn with source code but could be the way I found is not appropriate)...

@coderaiser
Copy link
Owner

How can I solve? Could be "parseTemplate" is not the good one?

If you talking about parseTemplate it works in a different way. The thing is the whole parser moves over source code token by token, and saves current state in this object.

The simplest possible way would be to construct template expression and then just pass it to @babel/template in this case you do not need to bother about stuff like quasis and expressions of TemplateLiteral. You just receive ready to use part of an AST, which could be placed instead of StringLiteral.

Anyways the method to override should be parseLiteral, it should check whether it is Swift Template and if it is - template.ast(), if not call super.parseLiteral().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants