LibJS: Fix ambiguity in FractionalPart grammar

This is a normative change in the Temporal spec.

See: https://github.com/tc39/proposal-temporal/commit/0f11bd6
This commit is contained in:
Linus Groh 2021-12-18 17:28:04 +00:00
parent bbfbd02c1b
commit 4b7f716f21
Notes: sideshowbarker 2024-07-17 22:38:56 +09:00
3 changed files with 12 additions and 25 deletions

View file

@ -1079,14 +1079,14 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(GlobalObject& global_object,
// 1. Assert: Type(isoString) is String. // 1. Assert: Type(isoString) is String.
// 2. Let year, month, day, hour, minute, second, fraction, and calendar be the parts of isoString produced respectively by the DateYear, DateMonth, DateDay, TimeHour, TimeMinute, TimeSecond, TimeFractionalPart, and CalendarName productions, or undefined if not present. // 2. Let year, month, day, hour, minute, second, fraction, and calendar be the parts of isoString produced respectively by the DateYear, DateMonth, DateDay, TimeHour, TimeMinute, TimeSecond, FractionalPart, and CalendarName productions, or undefined if not present.
auto year_part = parse_result.date_year; auto year_part = parse_result.date_year;
auto month_part = parse_result.date_month; auto month_part = parse_result.date_month;
auto day_part = parse_result.date_day; auto day_part = parse_result.date_day;
auto hour_part = parse_result.time_hour; auto hour_part = parse_result.time_hour;
auto minute_part = parse_result.time_minute; auto minute_part = parse_result.time_minute;
auto second_part = parse_result.time_second; auto second_part = parse_result.time_second;
auto fraction_part = parse_result.time_fractional_part; auto fraction_part = parse_result.fractional_part;
auto calendar_part = parse_result.calendar_name; auto calendar_part = parse_result.calendar_name;
// 3. If the first code unit of year is 0x2212 (MINUS SIGN), replace it with the code unit 0x002D (HYPHEN-MINUS). // 3. If the first code unit of year is 0x2212 (MINUS SIGN), replace it with the code unit 0x002D (HYPHEN-MINUS).
@ -1145,15 +1145,15 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(GlobalObject& global_object,
if (fraction_part.has_value()) { if (fraction_part.has_value()) {
// a. Set fraction to the string-concatenation of the previous value of fraction and the string "000000000". // a. Set fraction to the string-concatenation of the previous value of fraction and the string "000000000".
auto fraction = String::formatted("{}000000000", *fraction_part); auto fraction = String::formatted("{}000000000", *fraction_part);
// b. Let millisecond be the String value equal to the substring of fraction from 0 to 3. // b. Let millisecond be the String value equal to the substring of fraction from 1 to 4.
// c. Set millisecond to ! ToIntegerOrInfinity(millisecond). // c. Set millisecond to ! ToIntegerOrInfinity(millisecond).
millisecond = *fraction.substring(0, 3).to_uint<u16>(); millisecond = *fraction.substring(1, 3).to_uint<u16>();
// d. Let microsecond be the String value equal to the substring of fraction from 3 to 6. // d. Let microsecond be the String value equal to the substring of fraction from 4 to 7.
// e. Set microsecond to ! ToIntegerOrInfinity(microsecond). // e. Set microsecond to ! ToIntegerOrInfinity(microsecond).
microsecond = *fraction.substring(3, 3).to_uint<u16>(); microsecond = *fraction.substring(4, 3).to_uint<u16>();
// f. Let nanosecond be the String value equal to the substring of fraction from 6 to 9. // f. Let nanosecond be the String value equal to the substring of fraction from 7 to 10.
// g. Set nanosecond to ! ToIntegerOrInfinity(nanosecond). // g. Set nanosecond to ! ToIntegerOrInfinity(nanosecond).
nanosecond = *fraction.substring(6, 3).to_uint<u16>(); nanosecond = *fraction.substring(7, 3).to_uint<u16>();
} }
// 14. Else, // 14. Else,
else { else {

View file

@ -430,29 +430,17 @@ bool ISO8601Parser::parse_fractional_part()
return true; return true;
} }
// https://tc39.es/proposal-temporal/#prod-TimeFractionalPart
bool ISO8601Parser::parse_time_fractional_part()
{
// TimeFractionalPart :
// FractionalPart
StateTransaction transaction { *this };
if (!parse_fractional_part())
return false;
m_state.parse_result.time_fractional_part = transaction.parsed_string_view();
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-Fraction // https://tc39.es/proposal-temporal/#prod-Fraction
bool ISO8601Parser::parse_fraction() bool ISO8601Parser::parse_fraction()
{ {
// Fraction : // Fraction :
// DecimalSeparator TimeFractionalPart // DecimalSeparator FractionalPart
StateTransaction transaction { *this }; StateTransaction transaction { *this };
if (!parse_decimal_separator()) if (!parse_decimal_separator())
return false; return false;
if (!parse_time_fractional_part()) if (!parse_fractional_part())
return false; return false;
m_state.parse_result.fractional_part = transaction.parsed_string_view();
transaction.commit(); transaction.commit();
return true; return true;
} }

View file

@ -21,7 +21,7 @@ struct ParseResult {
Optional<StringView> time_hour; Optional<StringView> time_hour;
Optional<StringView> time_minute; Optional<StringView> time_minute;
Optional<StringView> time_second; Optional<StringView> time_second;
Optional<StringView> time_fractional_part; Optional<StringView> fractional_part;
Optional<StringView> calendar_name; Optional<StringView> calendar_name;
Optional<StringView> utc_designator; Optional<StringView> utc_designator;
Optional<StringView> time_zone_utc_offset_sign; Optional<StringView> time_zone_utc_offset_sign;
@ -104,7 +104,6 @@ public:
[[nodiscard]] bool parse_time_minute(); [[nodiscard]] bool parse_time_minute();
[[nodiscard]] bool parse_time_second(); [[nodiscard]] bool parse_time_second();
[[nodiscard]] bool parse_fractional_part(); [[nodiscard]] bool parse_fractional_part();
[[nodiscard]] bool parse_time_fractional_part();
[[nodiscard]] bool parse_fraction(); [[nodiscard]] bool parse_fraction();
[[nodiscard]] bool parse_time_fraction(); [[nodiscard]] bool parse_time_fraction();
[[nodiscard]] bool parse_time_zone_utc_offset_sign(); [[nodiscard]] bool parse_time_zone_utc_offset_sign();