/* * Copyright (c) 2022-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ #include #include namespace JS::Intl { GC_DEFINE_ALLOCATOR(PluralRules); // 17 PluralRules Objects, https://tc39.es/ecma402/#pluralrules-objects PluralRules::PluralRules(Object& prototype) : NumberFormatBase(prototype) { } // 17.5.2 ResolvePlural ( pluralRules, n ), https://tc39.es/ecma402/#sec-resolveplural Unicode::PluralCategory resolve_plural(PluralRules const& plural_rules, Value number) { // 1. If n is not a finite Number, then if (!number.is_finite_number()) { // a. Let s be ! ToString(n). // b. Return the Record { [[PluralCategory]]: "other", [[FormattedString]]: s }. return Unicode::PluralCategory::Other; } // 2. Let res be FormatNumericToString(pluralRules, ℝ(n)). // 3. Let s be res.[[FormattedString]]. // 4. Let locale be pluralRules.[[Locale]]. // 5. Let type be pluralRules.[[Type]]. // 6. Let p be PluralRuleSelect(locale, type, s). // 7. Return the Record { [[PluralCategory]]: p, [[FormattedString]]: s }. return plural_rules.formatter().select_plural(number.as_double()); } // 17.5.4 ResolvePluralRange ( pluralRules, x, y ), https://tc39.es/ecma402/#sec-resolveplural ThrowCompletionOr resolve_plural_range(VM& vm, PluralRules const& plural_rules, Value start, Value end) { // 1. If x is NaN or y is NaN, throw a RangeError exception. if (start.is_nan()) return vm.throw_completion(ErrorType::NumberIsNaN, "start"sv); if (end.is_nan()) return vm.throw_completion(ErrorType::NumberIsNaN, "end"sv); // 2. Let xp be ResolvePlural(pluralRules, x). // 3. Let yp be ResolvePlural(pluralRules, y). // 4. If xp.[[FormattedString]] is yp.[[FormattedString]], then // a. Return xp.[[PluralCategory]]. // 5. Let locale be pluralRules.[[Locale]]. // 6. Let type be pluralRules.[[Type]]. // 7. Return PluralRuleSelectRange(locale, type, xp.[[PluralCategory]], yp.[[PluralCategory]]). return plural_rules.formatter().select_plural_range(start.as_double(), end.as_double()); } }