[swift-evolution] multi-line string literals.

L. Mihalkovic laurent.mihalkovic at gmail.com
Tue May 3 17:23:07 CDT 2016


(From mobile)

On May 2, 2016, at 2:23 PM, John Holdsworth <mac at johnholdsworth.com <mailto:mac at johnholdsworth.com>> wrote:

>> I'm having trouble getting the `e` modifier to work as advertised, at least for the sequence `\\`. For example, `print(e"\\\\")` prints two backslashes, and `print(e"\\\")` seems to try to escape the string literal. I'm currently envisioning `e` as disabling *all* backslash escapes, so these behaviors wouldn't be appropriate. It also looks like interpolation is still enabled in `e` strings.
>> Since other things like `print(e"\w+")` work just fine, I'm guessing this is a bug in the proposal's sketches (not being clear enough about the expected behavior), not your code.
>> I've written a gist with some tests to show how I expect things to work:
>> 	https://gist.github.com/brentdax/be3c032bc7e0c101d7ba8b72cd1a692e <https://gist.github.com/brentdax/be3c032bc7e0c101d7ba8b72cd1a692e>
> The problem here is that I’ve not implemented unescaped literals fully as it would require changes outside the lexer.
> This is because the string is first lexed and tokenised by one piece of code Lexer::lexStringLiteral but later
> on in the code generation phase it generates the actual literal in a function Lexer::getEncodedStringSegment.
> This is passed the same string from the source file but does not know what modifiers should be applied. As a result
> normal escapes are still processed. All the “e” flag does is silence the error for invalid escapes during tokenising.

Lexer just lays ropes around certain areas to tell what's where. sometimes this is not enough for extra semantics. this is the reason why i went down the path of a custom string_multiline_literal token. It looks like you might want to consider that path too. If you do, you might consider the merits of suggesting that half the work be put in place now, allowing both our experimentations (and other more sophisticated) to lean on it, as an alternative to just directly adding extra conditional code in the default lexer code.

> Having encountered this limitation I managed to persuade myself this is what you want anyway but perhaps few would agree,
> What has been implemented is more of an r”” than a e”” that solves the “picket fence” problem where you can also interpolate
> into convenient regex literals. This is all beyond the scope of this proposal anyway so I’ll leave that battle for another day.
> The changes to the compiler for anything else would be a step up in terms of disruption.

I found that by separating new from existing in Lexer using a new token, you can go further along without really disrupting the original flow. Having a custom token would give your a differentiation point to know how to treat the contents differently. As a concrete eg, this is my way to deal with 2 character prefix/postfix around multiline literals while keeping the existing interpolation logic in place:

void Lexer::getStringLiteralSegments(UNCHANGED SIG) {
  // normal initialization

  // drop double character marker of multiline literals
  if (Str.is(tok::string_multiline_literal)) {
    Bytes = Bytes.drop_front().drop_back();
  // normal segmenter below

Just thinking… another way to differentiation could be to seed the second lexer with a specific initial token to giving it a different context to interpret incoming chars from. Would probably give you the extra context you seem to be looking for (without widening the signature of the existing parse/lexer communication channel).

@dabrahams / @clattner
Might I ask if it would be possible to have even a very high level yup/nope answer regarding the feasibility of using the temporary lexer swapping facility to inline SIL contents as the body of multiline string literal expression? 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160504/88755ac3/attachment.html>

More information about the swift-evolution mailing list