temporal-parser.h 6.66 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_TEMPORAL_TEMPORAL_PARSER_H_
#define V8_TEMPORAL_TEMPORAL_PARSER_H_

8
#include "src/base/optional.h"
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
#include "src/execution/isolate.h"

namespace v8 {
namespace internal {

/**
 * ParsedISO8601Result contains the parsed result of ISO 8601 grammar
 * documented in #sec-temporal-iso8601grammar
 * for TemporalInstantString, TemporalZonedDateTimeString,
 * TemporalCalendarString, TemporalDateString, TemporalDateTimeString,
 * TemporalMonthDayString, TemporalRelativeToString, TemporalTimeString,
 * TemporalTimeZoneString, and TemporalYearMonthString. For all the fields
 * represented by int32_t, a special value kMinInt31 is used to represent the
 * field is "undefined" after parsing.
 */
struct ParsedISO8601Result {
  int32_t date_year;    // DateYear production
  int32_t date_month;   // DateMonth production
  int32_t date_day;     // DateDay production
  int32_t time_hour;    // TimeHour production
  int32_t time_minute;  // TimeMinute production
  int32_t time_second;  // TimeSecond production
  int32_t
      time_nanosecond;  // TimeFractionalPart production stored in nanosecond
  int32_t tzuo_sign;    // TimeZoneUTCOffsetSign production
  int32_t tzuo_hour;    // TimeZoneUTCOffsetHour production
  int32_t tzuo_minute;  // TimeZoneUTCOffsetMinute production
  int32_t tzuo_second;  // TimeZoneUTCOffsetSecond production
  int32_t
      tzuo_nanosecond;  // TimeZoneUTCOffsetFractionalPart stored in nanosecond
  bool utc_designator;  // UTCDesignator is presented
  int32_t tzi_name_start;   // Starting offset of TimeZoneIANAName in the input
                            // string.
  int32_t tzi_name_length;  // Length of TimeZoneIANAName production
  int32_t calendar_name_start;  // Starting offset of CalendarName production in
                                // the input string.
  int32_t calendar_name_length;  // Length of CalendarName production.
46 47 48 49
  int32_t offset_string_start;   // Starting offset of TimeZoneNumericUTCOffset
                                 // in the input string.
  int32_t
      offset_string_length;  // Length of TimeZoneNumericUTCOffset production
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

  ParsedISO8601Result()
      : date_year(kMinInt31),
        date_month(kMinInt31),
        date_day(kMinInt31),
        time_hour(kMinInt31),
        time_minute(kMinInt31),
        time_second(kMinInt31),
        time_nanosecond(kMinInt31),
        tzuo_sign(kMinInt31),
        tzuo_hour(kMinInt31),
        tzuo_minute(kMinInt31),
        tzuo_second(kMinInt31),
        tzuo_nanosecond(kMinInt31),
        utc_designator(false),
        tzi_name_start(0),
        tzi_name_length(0),
        calendar_name_start(0),
68 69 70
        calendar_name_length(0),
        offset_string_start(0),
        offset_string_length(0) {}
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

  bool date_year_is_undefined() const { return date_year == kMinInt31; }
  bool date_month_is_undefined() const { return date_month == kMinInt31; }
  bool date_day_is_undefined() const { return date_day == kMinInt31; }
  bool time_hour_is_undefined() const { return time_hour == kMinInt31; }
  bool time_minute_is_undefined() const { return time_minute == kMinInt31; }
  bool time_second_is_undefined() const { return time_second == kMinInt31; }
  bool time_nanosecond_is_undefined() const {
    return time_nanosecond == kMinInt31;
  }
  bool tzuo_hour_is_undefined() const { return tzuo_hour == kMinInt31; }
  bool tzuo_minute_is_undefined() const { return tzuo_minute == kMinInt31; }
  bool tzuo_second_is_undefined() const { return tzuo_second == kMinInt31; }
  bool tzuo_sign_is_undefined() const { return tzuo_sign == kMinInt31; }
  bool tzuo_nanosecond_is_undefined() const {
    return tzuo_nanosecond == kMinInt31;
  }
};

/**
 * ParsedISO8601Duration contains the parsed result of ISO 8601 grammar
 * documented in #prod-TemporalDurationString
 * for TemporalDurationString.
94 95
 * A special value kEmpty is used to represent the
 * field is "undefined" after parsing for all fields except sign.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
 */
struct ParsedISO8601Duration {
  int64_t sign;              // Sign production
  int64_t years;             // DurationYears production
  int64_t months;            // DurationMonths production
  int64_t weeks;             // DurationWeeks production
  int64_t days;              // DurationDays production
  int64_t whole_hours;       // DurationWholeHours production
  int64_t hours_fraction;    // DurationHoursFraction, in unit of 1e-9 hours
  int64_t whole_minutes;     // DurationWholeMinutes production
  int64_t minutes_fraction;  // DurationMinuteFraction, in unit of 1e-9 minutes
  int64_t whole_seconds;     // DurationWholeSeconds production
  int64_t seconds_fraction;  // DurationSecondFraction, in unit of nanosecond (
                             // 1e-9 seconds).

111
  static constexpr int64_t kEmpty = -1;
112 113
  ParsedISO8601Duration()
      : sign(1),
114 115 116 117 118 119 120 121 122 123
        years(kEmpty),
        months(kEmpty),
        weeks(kEmpty),
        days(kEmpty),
        whole_hours(kEmpty),
        hours_fraction(kEmpty),
        whole_minutes(kEmpty),
        minutes_fraction(kEmpty),
        whole_seconds(kEmpty),
        seconds_fraction(kEmpty) {}
124 125 126 127 128 129 130 131 132 133 134 135
};

/**
 * TemporalParser is low level parsing functions to support the implementation
 * of various ParseTemporal*String Abstract Operations listed after
 * #sec-temporal-parsetemporalinstantstring.
 * All the methods take an Isolate, a Handle<String> as input, and also a
 * pointer to a bool to answer the "satisfy the syntax of a Temporal*String"
 * question and return the parsed result.
 */
class V8_EXPORT_PRIVATE TemporalParser {
 public:
136 137 138
#define DEFINE_PARSE_METHOD(R, NAME)                          \
  V8_WARN_UNUSED_RESULT static base::Optional<R> Parse##NAME( \
      Isolate* isolate, Handle<String> iso_string)
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalDateString);
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalDateTimeString);
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalTimeString);
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalYearMonthString);
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalMonthDayString);
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalInstantString);
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalZonedDateTimeString);
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalTimeZoneString);
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalRelativeToString);
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalCalendarString);
  DEFINE_PARSE_METHOD(ParsedISO8601Duration, TemporalDurationString);
  DEFINE_PARSE_METHOD(ParsedISO8601Result, TimeZoneNumericUTCOffset);
};
#undef DEFINE_PARSE_METHOD

}  // namespace internal
}  // namespace v8

#endif  // V8_TEMPORAL_TEMPORAL_PARSER_H_