1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 20:47:45 +00:00

LibJS: Use the new is_ascii_foo() helpers from AK

These constexpr helpers generate nicer code than the LibC ctype.h
variants, so let's make use of them. :^)
This commit is contained in:
Andreas Kling 2021-06-13 10:47:09 +02:00
parent d476144565
commit 39ad705c13
5 changed files with 30 additions and 31 deletions

View file

@ -6,9 +6,9 @@
*/ */
#include "Lexer.h" #include "Lexer.h"
#include <AK/CharacterTypes.h>
#include <AK/Debug.h> #include <AK/Debug.h>
#include <AK/HashMap.h> #include <AK/HashMap.h>
#include <ctype.h>
#include <stdio.h> #include <stdio.h>
namespace JS { namespace JS {
@ -199,10 +199,10 @@ bool Lexer::consume_exponent()
if (m_current_char == '-' || m_current_char == '+') if (m_current_char == '-' || m_current_char == '+')
consume(); consume();
if (!isdigit(m_current_char)) if (!is_ascii_digit(m_current_char))
return false; return false;
while (isdigit(m_current_char)) { while (is_ascii_digit(m_current_char)) {
consume(); consume();
} }
return true; return true;
@ -224,10 +224,10 @@ bool Lexer::consume_octal_number()
bool Lexer::consume_hexadecimal_number() bool Lexer::consume_hexadecimal_number()
{ {
consume(); consume();
if (!isxdigit(m_current_char)) if (!is_ascii_hex_digit(m_current_char))
return false; return false;
while (isxdigit(m_current_char)) while (is_ascii_hex_digit(m_current_char))
consume(); consume();
return true; return true;
@ -293,12 +293,12 @@ bool Lexer::is_line_terminator() const
bool Lexer::is_identifier_start() const bool Lexer::is_identifier_start() const
{ {
return isalpha(m_current_char) || m_current_char == '_' || m_current_char == '$'; return is_ascii_alpha(m_current_char) || m_current_char == '_' || m_current_char == '$';
} }
bool Lexer::is_identifier_middle() const bool Lexer::is_identifier_middle() const
{ {
return is_identifier_start() || isdigit(m_current_char); return is_identifier_start() || is_ascii_digit(m_current_char);
} }
bool Lexer::is_line_comment_start(bool line_has_token_yet) const bool Lexer::is_line_comment_start(bool line_has_token_yet) const
@ -323,7 +323,7 @@ bool Lexer::is_block_comment_end() const
bool Lexer::is_numeric_literal_start() const bool Lexer::is_numeric_literal_start() const
{ {
return isdigit(m_current_char) || (m_current_char == '.' && m_position < m_source.length() && isdigit(m_source[m_position])); return is_ascii_digit(m_current_char) || (m_current_char == '.' && m_position < m_source.length() && is_ascii_digit(m_source[m_position]));
} }
bool Lexer::slash_means_division() const bool Lexer::slash_means_division() const
@ -358,10 +358,10 @@ Token Lexer::next()
do { do {
consume(); consume();
} while (is_line_terminator()); } while (is_line_terminator());
} else if (isspace(m_current_char)) { } else if (is_ascii_space(m_current_char)) {
do { do {
consume(); consume();
} while (isspace(m_current_char)); } while (is_ascii_space(m_current_char));
} else if (is_line_comment_start(line_has_token_yet)) { } else if (is_line_comment_start(line_has_token_yet)) {
consume(); consume();
do { do {
@ -393,9 +393,9 @@ Token Lexer::next()
// bunch of Invalid* tokens (bad numeric literals, unterminated comments etc.) // bunch of Invalid* tokens (bad numeric literals, unterminated comments etc.)
String token_message; String token_message;
if (m_current_token.type() == TokenType::RegexLiteral && !is_eof() && isalpha(m_current_char)) { if (m_current_token.type() == TokenType::RegexLiteral && !is_eof() && is_ascii_alpha(m_current_char)) {
token_type = TokenType::RegexFlags; token_type = TokenType::RegexFlags;
while (!is_eof() && isalpha(m_current_char)) while (!is_eof() && is_ascii_alpha(m_current_char))
consume(); consume();
} else if (m_current_char == '`') { } else if (m_current_char == '`') {
consume(); consume();
@ -457,7 +457,7 @@ Token Lexer::next()
if (m_current_char == '.') { if (m_current_char == '.') {
// decimal // decimal
consume(); consume();
while (isdigit(m_current_char)) while (is_ascii_digit(m_current_char))
consume(); consume();
if (m_current_char == 'e' || m_current_char == 'E') if (m_current_char == 'e' || m_current_char == 'E')
is_invalid_numeric_literal = !consume_exponent(); is_invalid_numeric_literal = !consume_exponent();
@ -475,15 +475,15 @@ Token Lexer::next()
} else if (m_current_char == 'n') { } else if (m_current_char == 'n') {
consume(); consume();
token_type = TokenType::BigIntLiteral; token_type = TokenType::BigIntLiteral;
} else if (isdigit(m_current_char)) { } else if (is_ascii_digit(m_current_char)) {
// octal without '0o' prefix. Forbidden in 'strict mode' // octal without '0o' prefix. Forbidden in 'strict mode'
do { do {
consume(); consume();
} while (isdigit(m_current_char)); } while (is_ascii_digit(m_current_char));
} }
} else { } else {
// 1...9 or period // 1...9 or period
while (isdigit(m_current_char)) while (is_ascii_digit(m_current_char))
consume(); consume();
if (m_current_char == 'n') { if (m_current_char == 'n') {
consume(); consume();
@ -491,7 +491,7 @@ Token Lexer::next()
} else { } else {
if (m_current_char == '.') { if (m_current_char == '.') {
consume(); consume();
while (isdigit(m_current_char)) while (is_ascii_digit(m_current_char))
consume(); consume();
} }
if (m_current_char == 'e' || m_current_char == 'E') if (m_current_char == 'e' || m_current_char == 'E')
@ -579,7 +579,7 @@ Token Lexer::next()
auto it = s_two_char_tokens.find(two_chars_view.hash(), [&](auto& entry) { return entry.key == two_chars_view; }); auto it = s_two_char_tokens.find(two_chars_view.hash(), [&](auto& entry) { return entry.key == two_chars_view; });
if (it != s_two_char_tokens.end()) { if (it != s_two_char_tokens.end()) {
// OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit] // OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit]
if (!(it->value == TokenType::QuestionMarkPeriod && m_position + 1 < m_source.length() && isdigit(m_source[m_position + 1]))) { if (!(it->value == TokenType::QuestionMarkPeriod && m_position + 1 < m_source.length() && is_ascii_digit(m_source[m_position + 1]))) {
found_two_char_token = true; found_two_char_token = true;
consume(); consume();
consume(); consume();

View file

@ -6,11 +6,11 @@
*/ */
#include "Parser.h" #include "Parser.h"
#include <AK/CharacterTypes.h>
#include <AK/HashTable.h> #include <AK/HashTable.h>
#include <AK/ScopeGuard.h> #include <AK/ScopeGuard.h>
#include <AK/StdLibExtras.h> #include <AK/StdLibExtras.h>
#include <AK/TemporaryChange.h> #include <AK/TemporaryChange.h>
#include <ctype.h>
namespace JS { namespace JS {
@ -2213,7 +2213,7 @@ Token Parser::consume(TokenType expected_type)
Token Parser::consume_and_validate_numeric_literal() Token Parser::consume_and_validate_numeric_literal()
{ {
auto is_unprefixed_octal_number = [](const StringView& value) { auto is_unprefixed_octal_number = [](const StringView& value) {
return value.length() > 1 && value[0] == '0' && isdigit(value[1]); return value.length() > 1 && value[0] == '0' && is_ascii_digit(value[1]);
}; };
auto literal_start = position(); auto literal_start = position();
auto token = consume(TokenType::NumericLiteral); auto token = consume(TokenType::NumericLiteral);

View file

@ -6,13 +6,13 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <AK/CharacterTypes.h>
#include <AK/GenericLexer.h> #include <AK/GenericLexer.h>
#include <LibCore/DateTime.h> #include <LibCore/DateTime.h>
#include <LibJS/Runtime/Date.h> #include <LibJS/Runtime/Date.h>
#include <LibJS/Runtime/DateConstructor.h> #include <LibJS/Runtime/DateConstructor.h>
#include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/VM.h> #include <LibJS/Runtime/VM.h>
#include <ctype.h>
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
@ -30,7 +30,7 @@ static Value parse_simplified_iso8601(const String& iso_8601)
int r = 0; int r = 0;
for (size_t i = 0; i < n; ++i) { for (size_t i = 0; i < n; ++i) {
char ch = lexer.consume(); char ch = lexer.consume();
if (!isdigit(ch)) if (!is_ascii_digit(ch))
return false; return false;
r = 10 * r + ch - '0'; r = 10 * r + ch - '0';
} }

View file

@ -33,7 +33,6 @@
#include <LibJS/Runtime/Symbol.h> #include <LibJS/Runtime/Symbol.h>
#include <LibJS/Runtime/SymbolObject.h> #include <LibJS/Runtime/SymbolObject.h>
#include <LibJS/Runtime/Value.h> #include <LibJS/Runtime/Value.h>
#include <ctype.h>
#include <math.h> #include <math.h>
namespace JS { namespace JS {

View file

@ -7,9 +7,9 @@
#include "Token.h" #include "Token.h"
#include <AK/Assertions.h> #include <AK/Assertions.h>
#include <AK/CharacterTypes.h>
#include <AK/GenericLexer.h> #include <AK/GenericLexer.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <ctype.h>
namespace JS { namespace JS {
@ -64,7 +64,7 @@ double Token::double_value() const
} else if (value_string[1] == 'b' || value_string[1] == 'B') { } else if (value_string[1] == 'b' || value_string[1] == 'B') {
// binary // binary
return static_cast<double>(strtoul(value_string.characters() + 2, nullptr, 2)); return static_cast<double>(strtoul(value_string.characters() + 2, nullptr, 2));
} else if (isdigit(value_string[1])) { } else if (is_ascii_digit(value_string[1])) {
// also octal, but syntax error in strict mode // also octal, but syntax error in strict mode
if (!m_value.contains('8') && !m_value.contains('9')) if (!m_value.contains('8') && !m_value.contains('9'))
return static_cast<double>(strtoul(value_string.characters() + 1, nullptr, 8)); return static_cast<double>(strtoul(value_string.characters() + 1, nullptr, 8));
@ -75,10 +75,10 @@ double Token::double_value() const
static u32 hex2int(char x) static u32 hex2int(char x)
{ {
VERIFY(isxdigit(x)); VERIFY(is_ascii_hex_digit(x));
if (x >= '0' && x <= '9') if (x >= '0' && x <= '9')
return x - '0'; return x - '0';
return 10u + (tolower(x) - 'a'); return 10u + (to_ascii_lowercase(x) - 'a');
} }
String Token::string_value(StringValueStatus& status) const String Token::string_value(StringValueStatus& status) const
@ -115,7 +115,7 @@ String Token::string_value(StringValueStatus& status) const
continue; continue;
} }
// Null-byte escape // Null-byte escape
if (lexer.next_is('0') && !isdigit(lexer.peek(1))) { if (lexer.next_is('0') && !is_ascii_digit(lexer.peek(1))) {
lexer.ignore(); lexer.ignore();
builder.append('\0'); builder.append('\0');
continue; continue;
@ -123,7 +123,7 @@ String Token::string_value(StringValueStatus& status) const
// Hex escape // Hex escape
if (lexer.next_is('x')) { if (lexer.next_is('x')) {
lexer.ignore(); lexer.ignore();
if (!isxdigit(lexer.peek()) || !isxdigit(lexer.peek(1))) if (!is_ascii_hex_digit(lexer.peek()) || !is_ascii_hex_digit(lexer.peek(1)))
return encoding_failure(StringValueStatus::MalformedHexEscape); return encoding_failure(StringValueStatus::MalformedHexEscape);
auto code_point = hex2int(lexer.consume()) * 16 + hex2int(lexer.consume()); auto code_point = hex2int(lexer.consume()) * 16 + hex2int(lexer.consume());
VERIFY(code_point <= 255); VERIFY(code_point <= 255);
@ -137,7 +137,7 @@ String Token::string_value(StringValueStatus& status) const
if (lexer.next_is('{')) { if (lexer.next_is('{')) {
lexer.ignore(); lexer.ignore();
while (true) { while (true) {
if (!lexer.next_is(isxdigit)) if (!lexer.next_is(is_ascii_hex_digit))
return encoding_failure(StringValueStatus::MalformedUnicodeEscape); return encoding_failure(StringValueStatus::MalformedUnicodeEscape);
auto new_code_point = (code_point << 4u) | hex2int(lexer.consume()); auto new_code_point = (code_point << 4u) | hex2int(lexer.consume());
if (new_code_point < code_point) if (new_code_point < code_point)
@ -149,7 +149,7 @@ String Token::string_value(StringValueStatus& status) const
lexer.ignore(); lexer.ignore();
} else { } else {
for (int j = 0; j < 4; ++j) { for (int j = 0; j < 4; ++j) {
if (!lexer.next_is(isxdigit)) if (!lexer.next_is(is_ascii_hex_digit))
return encoding_failure(StringValueStatus::MalformedUnicodeEscape); return encoding_failure(StringValueStatus::MalformedUnicodeEscape);
code_point = (code_point << 4u) | hex2int(lexer.consume()); code_point = (code_point << 4u) | hex2int(lexer.consume());
} }