1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 14:07:42 +00:00

LibJS: Parse === and !== binary operators

This commit is contained in:
Conrad Pankoff 2020-03-12 23:11:33 +11:00 committed by Andreas Kling
parent 9d41aa4d5d
commit e88f2f15ee
4 changed files with 42 additions and 6 deletions

View file

@ -33,6 +33,7 @@
namespace JS { namespace JS {
HashMap<String, TokenType> Lexer::s_keywords; HashMap<String, TokenType> Lexer::s_keywords;
HashMap<String, TokenType> Lexer::s_three_char_tokens;
HashMap<String, TokenType> Lexer::s_two_char_tokens; HashMap<String, TokenType> Lexer::s_two_char_tokens;
HashMap<char, TokenType> Lexer::s_single_char_tokens; HashMap<char, TokenType> Lexer::s_single_char_tokens;
@ -62,6 +63,11 @@ Lexer::Lexer(StringView source)
s_keywords.set("while", TokenType::While); s_keywords.set("while", TokenType::While);
} }
if (s_three_char_tokens.is_empty()) {
s_three_char_tokens.set("===", TokenType::EqualsEqualsEquals);
s_three_char_tokens.set("!==", TokenType::ExclamationMarkEqualsEquals);
}
if (s_two_char_tokens.is_empty()) { if (s_two_char_tokens.is_empty()) {
s_two_char_tokens.set("+=", TokenType::PlusEquals); s_two_char_tokens.set("+=", TokenType::PlusEquals);
s_two_char_tokens.set("-=", TokenType::MinusEquals); s_two_char_tokens.set("-=", TokenType::MinusEquals);
@ -174,7 +180,7 @@ Token Lexer::next()
} }
size_t value_start = m_position; size_t value_start = m_position;
TokenType token_type; auto token_type = TokenType::Invalid;
if (is_identifier_start()) { if (is_identifier_start()) {
// identifier or keyword // identifier or keyword
@ -205,8 +211,23 @@ Token Lexer::next()
} else if (m_current_char == EOF) { } else if (m_current_char == EOF) {
token_type = TokenType::Eof; token_type = TokenType::Eof;
} else { } else {
bool found_three_char_token = false;
if (m_position+1 < m_source.length()) {
char secondChar = m_source[m_position];
char thirdChar = m_source[m_position+1];
char threeChars[] { (char)m_current_char, secondChar, thirdChar, 0 };
auto it = s_three_char_tokens.find(threeChars);
if (it != s_three_char_tokens.end()) {
found_three_char_token = true;
consume();
consume();
consume();
token_type = it->value;
}
}
bool found_two_char_token = false; bool found_two_char_token = false;
if (!is_eof()) { if (!found_three_char_token && !is_eof()) {
char secondChar = m_source[m_position]; char secondChar = m_source[m_position];
char twoChars[] { (char)m_current_char, secondChar, 0 }; char twoChars[] { (char)m_current_char, secondChar, 0 };
auto it = s_two_char_tokens.find(twoChars); auto it = s_two_char_tokens.find(twoChars);
@ -218,16 +239,20 @@ Token Lexer::next()
} }
} }
if (!found_two_char_token) { bool found_one_char_token = false;
if (!found_three_char_token && !found_two_char_token) {
auto it = s_single_char_tokens.find(m_current_char); auto it = s_single_char_tokens.find(m_current_char);
if (it != s_single_char_tokens.end()) { if (it != s_single_char_tokens.end()) {
found_one_char_token = true;
consume(); consume();
token_type = it->value; token_type = it->value;
} else {
consume();
token_type = TokenType::Invalid;
} }
} }
if (!found_three_char_token && !found_two_char_token && !found_one_char_token) {
consume();
token_type = TokenType::Invalid;
}
} }
m_current_token = Token( m_current_token = Token(

View file

@ -54,6 +54,7 @@ private:
int m_current_char; int m_current_char;
static HashMap<String, TokenType> s_keywords; static HashMap<String, TokenType> s_keywords;
static HashMap<String, TokenType> s_three_char_tokens;
static HashMap<String, TokenType> s_two_char_tokens; static HashMap<String, TokenType> s_two_char_tokens;
static HashMap<char, TokenType> s_single_char_tokens; static HashMap<char, TokenType> s_single_char_tokens;
}; };

View file

@ -157,6 +157,12 @@ NonnullOwnPtr<Expression> Parser::parse_secondary_expression(NonnullOwnPtr<Expre
case TokenType::LessThanEquals: case TokenType::LessThanEquals:
consume(); consume();
return make<BinaryExpression>(BinaryOp::LessThanEquals, move(lhs), parse_expression()); return make<BinaryExpression>(BinaryOp::LessThanEquals, move(lhs), parse_expression());
case TokenType::EqualsEqualsEquals:
consume();
return make<BinaryExpression>(BinaryOp::TypedEquals, move(lhs), parse_expression());
case TokenType::ExclamationMarkEqualsEquals:
consume();
return make<BinaryExpression>(BinaryOp::TypedInequals, move(lhs), parse_expression());
case TokenType::ParenOpen: case TokenType::ParenOpen:
return parse_call_expression(move(lhs)); return parse_call_expression(move(lhs));
case TokenType::Equals: case TokenType::Equals:
@ -276,6 +282,8 @@ bool Parser::match_secondary_expression() const
|| type == TokenType::Slash || type == TokenType::Slash
|| type == TokenType::SlashEquals || type == TokenType::SlashEquals
|| type == TokenType::Equals || type == TokenType::Equals
|| type == TokenType::EqualsEqualsEquals
|| type == TokenType::ExclamationMarkEqualsEquals
|| type == TokenType::GreaterThan || type == TokenType::GreaterThan
|| type == TokenType::GreaterThanEquals || type == TokenType::GreaterThanEquals
|| type == TokenType::LessThan || type == TokenType::LessThan

View file

@ -53,8 +53,10 @@ enum class TokenType {
Eof, Eof,
Equals, Equals,
EqualsEquals, EqualsEquals,
EqualsEqualsEquals,
ExclamationMark, ExclamationMark,
ExclamationMarkEquals, ExclamationMarkEquals,
ExclamationMarkEqualsEquals,
Finally, Finally,
Function, Function,
GreaterThan, GreaterThan,