LibJS: Add TokenType::TemplateLiteral

This is required for template literals - we're not quite there yet, but at
least the parser can now tell us when this token is encountered -
currently this yields "Unexpected token Invalid". Not really helpful.

The character is a "backtick", but as we already have
TokenType::{StringLiteral,RegexLiteral} this seemed like a fitting name.

This also enables syntax highlighting for template literals in the js
REPL and LibGUI's JSSyntaxHighlighter.
This commit is contained in:
Linus Groh 2020-04-24 00:20:02 +01:00 committed by Andreas Kling
parent 57caca3171
commit 95b51e857d
Notes: sideshowbarker 2024-07-19 07:20:50 +09:00
6 changed files with 13 additions and 3 deletions

View file

@ -42,6 +42,7 @@ static TextStyle style_for_token_type(Gfx::Palette palette, JS::TokenType type)
case JS::TokenType::NumericLiteral:
return { palette.syntax_number() };
case JS::TokenType::StringLiteral:
case JS::TokenType::TemplateLiteral:
case JS::TokenType::RegexLiteral:
case JS::TokenType::UnterminatedStringLiteral:
return { palette.syntax_string() };

View file

@ -337,7 +337,7 @@ Token Lexer::next()
}
}
token_type = TokenType::NumericLiteral;
} else if (m_current_char == '"' || m_current_char == '\'') {
} else if (m_current_char == '"' || m_current_char == '\'' || m_current_char == '`') {
char stop_char = m_current_char;
consume();
while (m_current_char != stop_char && m_current_char != '\n' && !is_eof()) {
@ -351,7 +351,10 @@ Token Lexer::next()
token_type = TokenType::UnterminatedStringLiteral;
} else {
consume();
token_type = TokenType::StringLiteral;
if (stop_char == '`')
token_type = TokenType::TemplateLiteral;
else
token_type = TokenType::StringLiteral;
}
} else if (m_current_char == EOF) {
token_type = TokenType::Eof;

View file

@ -1037,6 +1037,7 @@ bool Parser::match_expression() const
return type == TokenType::BoolLiteral
|| type == TokenType::NumericLiteral
|| type == TokenType::StringLiteral
|| type == TokenType::TemplateLiteral
|| type == TokenType::NullLiteral
|| type == TokenType::Identifier
|| type == TokenType::New

View file

@ -74,7 +74,7 @@ double Token::double_value() const
String Token::string_value() const
{
ASSERT(type() == TokenType::StringLiteral);
ASSERT(type() == TokenType::StringLiteral || type() == TokenType::TemplateLiteral);
StringBuilder builder;
for (size_t i = 1; i < m_value.length() - 1; ++i) {
if (m_value[i] == '\\' && i + 1 < m_value.length() - 1) {
@ -107,6 +107,9 @@ String Token::string_value() const
case '"':
builder.append('"');
break;
case '`':
builder.append('`');
break;
case '\\':
builder.append('\\');
break;

View file

@ -111,6 +111,7 @@ namespace JS {
__ENUMERATE_JS_TOKEN(SlashEquals) \
__ENUMERATE_JS_TOKEN(StringLiteral) \
__ENUMERATE_JS_TOKEN(Switch) \
__ENUMERATE_JS_TOKEN(TemplateLiteral) \
__ENUMERATE_JS_TOKEN(This) \
__ENUMERATE_JS_TOKEN(Throw) \
__ENUMERATE_JS_TOKEN(Tilde) \

View file

@ -453,6 +453,7 @@ int main(int argc, char** argv)
stylize({ start, end }, { Line::Style::Foreground(Line::Style::Color::Magenta) });
break;
case JS::TokenType::StringLiteral:
case JS::TokenType::TemplateLiteral:
case JS::TokenType::RegexLiteral:
case JS::TokenType::UnterminatedStringLiteral:
stylize({ start, end }, { Line::Style::Foreground(Line::Style::Color::Green), Line::Style::Bold });