Skip to content

[Parse] Implementation for SE-200 (raw strings) #17668

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

Merged
merged 15 commits into from
Sep 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ ERROR(lex_invalid_u_escape,none,
"\\u{...} escape sequence expects between 1 and 8 hex digits", ())
ERROR(lex_invalid_u_escape_rbrace,none,
"expected '}' in \\u{...} escape sequence", ())
ERROR(lex_invalid_escape_delimiter,none,
"too many '#' characters in delimited escape", ())
ERROR(lex_invalid_closing_delimiter,none,
"too many '#' characters in closing delimiter", ())

ERROR(lex_invalid_unicode_scalar,none,
"invalid unicode scalar", ())
Expand Down
23 changes: 14 additions & 9 deletions include/swift/Parse/Lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,19 +355,21 @@ class Lexer {
enum : char { Literal, Expr } Kind;
// Loc+Length for the segment inside the string literal, without quotes.
SourceLoc Loc;
unsigned Length, IndentToStrip;
unsigned Length, IndentToStrip, CustomDelimiterLen;
bool IsFirstSegment, IsLastSegment;

static StringSegment getLiteral(SourceLoc Loc, unsigned Length,
bool IsFirstSegment, bool IsLastSegment,
unsigned IndentToStrip) {
unsigned IndentToStrip,
unsigned CustomDelimiterLen) {
StringSegment Result;
Result.Kind = Literal;
Result.Loc = Loc;
Result.Length = Length;
Result.IsFirstSegment = IsFirstSegment;
Result.IsLastSegment = IsLastSegment;
Result.IndentToStrip = IndentToStrip;
Result.CustomDelimiterLen = CustomDelimiterLen;
return Result;
}

Expand All @@ -379,6 +381,7 @@ class Lexer {
Result.IsFirstSegment = false;
Result.IsLastSegment = false;
Result.IndentToStrip = 0;
Result.CustomDelimiterLen = 0;
return Result;
}

Expand All @@ -395,13 +398,14 @@ class Lexer {
SmallVectorImpl<char> &Buffer,
bool IsFirstSegment = false,
bool IsLastSegment = false,
unsigned IndentToStrip = 0);
unsigned IndentToStrip = 0,
unsigned CustomDelimiterLen = 0);
StringRef getEncodedStringSegment(StringSegment Segment,
SmallVectorImpl<char> &Buffer) const {
return getEncodedStringSegment(
StringRef(getBufferPtrForSourceLoc(Segment.Loc), Segment.Length),
Buffer, Segment.IsFirstSegment, Segment.IsLastSegment,
Segment.IndentToStrip);
Segment.IndentToStrip, Segment.CustomDelimiterLen);
}

/// \brief Given a string literal token, separate it into string/expr segments
Expand Down Expand Up @@ -465,7 +469,8 @@ class Lexer {
return diagnose(Loc, Diagnostic(DiagID, std::forward<ArgTypes>(Args)...));
}

void formToken(tok Kind, const char *TokStart, bool MultilineString = false);
void formToken(tok Kind, const char *TokStart, bool IsMultilineString = false,
unsigned CustomDelimiterLen = 0);
void formEscapedIdentifierToken(const char *TokStart);

/// Advance to the end of the line.
Expand All @@ -489,10 +494,10 @@ class Lexer {
void lexTrivia(syntax::Trivia &T, bool IsForTrailingTrivia);
static unsigned lexUnicodeEscape(const char *&CurPtr, Lexer *Diags);

unsigned lexCharacter(const char *&CurPtr,
char StopQuote, bool EmitDiagnostics,
bool MultilineString = false);
void lexStringLiteral();
unsigned lexCharacter(const char *&CurPtr, char StopQuote,
bool EmitDiagnostics, bool IsMultilineString = false,
unsigned CustomDelimiterLen = 0);
void lexStringLiteral(unsigned CustomDelimiterLen = 0);
void lexEscapedIdentifier();

void tryLexEditorPlaceholder();
Expand Down
22 changes: 16 additions & 6 deletions include/swift/Parse/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ class Token {
/// Modifiers for string literals
unsigned MultilineString : 1;

// Padding bits == 32 - sizeof(Kind) * 8 - 3;
/// Length of custom delimiter of "raw" string literals
unsigned CustomDelimiterLen : 8;

// Padding bits == 32 - 11;

/// \brief The length of the comment that precedes the token.
unsigned CommentLength;
Expand All @@ -62,8 +65,8 @@ class Token {
public:
Token(tok Kind, StringRef Text, unsigned CommentLength = 0)
: Kind(Kind), AtStartOfLine(false), EscapedIdentifier(false),
MultilineString(false), CommentLength(CommentLength),
Text(Text) {}
MultilineString(false), CustomDelimiterLen(0),
CommentLength(CommentLength), Text(Text) {}

Token() : Token(tok::NUM_TOKENS, {}, 0) {}

Expand Down Expand Up @@ -266,17 +269,24 @@ class Token {

/// \brief Set the token to the specified kind and source range.
void setToken(tok K, StringRef T, unsigned CommentLength = 0,
bool MultilineString = false) {
bool IsMultilineString = false, unsigned CustomDelimiterLen = 0) {
Kind = K;
Text = T;
this->CommentLength = CommentLength;
EscapedIdentifier = false;
this->MultilineString = MultilineString;
this->MultilineString = IsMultilineString;
this->CustomDelimiterLen = CustomDelimiterLen;
assert(this->CustomDelimiterLen == CustomDelimiterLen &&
"custom string delimiter length > 255");
}

bool IsMultilineString() const {
bool isMultilineString() const {
return MultilineString;
}

unsigned getCustomDelimiterLen() const {
return CustomDelimiterLen;
}
};

} // end namespace swift
Expand Down
Loading