generated from tc39/template-for-proposals
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathintl.emu
More file actions
285 lines (271 loc) · 16 KB
/
intl.emu
File metadata and controls
285 lines (271 loc) · 16 KB
1
2
3
4
5
6
7
8
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
<!DOCTYPE html>
<emu-clause id="sec-decimal-intl">
<h1>Amendments to the ECMAScript® 2024 Internationalization API Specification</h1>
<emu-note type="editor">
<p>
This section lists amendments which must be made to <a href="https://tc39.es/ecma402/">ECMA-402, the ECMAScript® 2024 Internationalization API Specification</a>.
Text to be added is marked <ins>like this</ins>, and text to be deleted is marked <del>like this</del>.
Blocks of unmodified text between modified sections are marked by [...].
</p>
</emu-note>
<emu-clause id="sup-properties-of-the-amount-prototype-object">
<h1>Properties of the Amount Prototype Object</h1>
<emu-clause id="sup-amount.prototype.tolocalestring">
<h1>Amount.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )</h1>
<p>This definition supersedes the definition provided in es2025, <emu-xref href="#sec-amount.prototype.tolocalestring"></emu-xref>.</p>
<p>This function performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[AmountValue]]).
1. Let _v_ be _O_.[[AmountValue]].
1. If _v_ is a String, then
1. Let _numValue_ be _v_.
1. Else if _v_ is a BigInt, then
1. Let _numValue_ be BigInt::toString(_v_, 10).
1. Else,
1. Assert: _v_ is a Number.
1. Let _numValue_ be _v_.
1. Let _unit_ be _O_.[[Unit]].
1. Let _mergedOptions_ be OrdinaryObjectCreate(*null*).
1. If _options_ is not *undefined*, then
1. Let _optionsObj_ be ? GetOptionsObject(_options_).
1. Perform ? CopyDataProperties(_mergedOptions_, _optionsObj_, « »).
1. If _unit_ is not *undefined*, then
1. If ? HasProperty(_mergedOptions_, *"style"*) is *false*, then
1. If IsWellFormedCurrencyCode(_unit_) is *true*, then
1. Perform ! CreateDataPropertyOrThrow(_mergedOptions_, *"style"*, *"currency"*).
1. If ? HasProperty(_mergedOptions_, *"currency"*) is *false*, then
1. Perform ! CreateDataPropertyOrThrow(_mergedOptions_, *"currency"*, _unit_).
1. Else,
1. Perform ! CreateDataPropertyOrThrow(_mergedOptions_, *"style"*, *"unit"*).
1. If ? HasProperty(_mergedOptions_, *"unit"*) is *false*, then
1. Perform ! CreateDataPropertyOrThrow(_mergedOptions_, *"unit"*, _unit_).
1. Let _numberFormat_ be ? Construct(%Intl.NumberFormat%, « _locales_, _mergedOptions_ »).
1. Return FormatNumeric(_numberFormat_, _numValue_).
</emu-alg>
</emu-clause>
<emu-clause id="sup-amount.prototype.convertto">
<h1>Amount.prototype.convertTo ( _options_ )</h1>
<p>This definition supersedes the definition provided in es2025, <emu-xref href="#sec-amount.prototype.convertto"></emu-xref>.</p>
<p>This function performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[AmountValue]]).
1. Let _sourceUnit_ be _O_.[[Unit]].
1. If _sourceUnit_ is *undefined*, throw a *TypeError* exception.
1. Let _validatedOpts_ be ? GetAmountConvertToOptions(_options_).
1. Let _targetUnit_ be _validatedOpts_.[[Unit]].
1. Let _roundingMode_ be _validatedOpts_.[[RoundingMode]].
1. Let _roundingPriority_ be _validatedOpts_.[[RoundingPriority]].
1. Let _minFractionDigits_ be _validatedOpts_.[[MiniumumFractionDigits]].
1. Let _maxFractionDigits_ be _validatedOpts_.[[MaximumFractionDigits]].
1. Let _minSignificantDigits_ be _validatedOpts_.[[MinimumSignificantDigits]].
1. Let _maxSignificantDigits_ be _validatedOpts_.[[MaximumSignificantDigits]].
1. Let _locale_ be _validatedOpts_.[[Locale]].
1. Let _usage_ be _validatedOpts_.[[Usage]].
1. If _targetUnit_ is *undefined* and _locale_ is *undefined* and _usage_ is *undefined*, throw a *TypeError* exception.
1. Let _v_ be _O_.[[AmountValue]].
1. If _v_ is a Number, then
1. Let _sourceValue_ be _v_.
1. Else if _v_ is a BigInt, then
1. Let _sourceValue_ be 𝔽(ℝ(_v_)).
1. Else,
1. Assert: _v_ is a String.
1. Let _sourceValue_ be StringToNumber(_v_).
1. If _targetUnit_ is not *undefined*, then
1. If _locale_ is not *undefined* or _usage_ is not *undefined*, throw a *TypeError* exception.
1. Else,
1. Let _matcher_ be ? GetOption(_validatedOpts_, *"localeMatcher"*, ~string~, « *"lookup"*, *"best fit"* », *"best fit"*).
1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locale_).
1. If _usage_ is *undefined*, set _usage_ to *"default"*.
1. Set _targetUnit_ to ? ResolveUnitPreference(_sourceUnit_, _sourceValue_, _requestedLocales_, _usage_, _matcher_).
1. Let _convertedValue_ be ? ConvertUnitValue(_sourceValue_, _sourceUnit_, _targetUnit_).
1. Let _result_ be OrdinaryObjectCreate(%Amount.prototype%, « [[AmountValue]], [[Unit]] »).
1. TODO Let _intlObject_ be an Object suitable for use as the first argument of a call to <emu-xref href="#sec-formatnumerictostring">FormatNumericToString</emu-xref> that uses _minSignificantDigits_, _maxSignificantDigits_, _minFractionDigits_, _maxFractionDigits_, _roundingPriority_, and _roundingMode_.
1. Let _formatted_ be FormatNumericToString(_intlObject_, _convertedValue_, 0).
1. Set _result_.[[AmountValue]] to _formatted_.[[FormattedString]].
1. Set _result_.[[Unit]] to _targetUnit_.
1. Return _result_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-resolveunitpreference" type="implementation-defined abstract operation">
<h1>ResolveUnitPreference (
_sourceUnit_: a String,
_sourceValue_: a Number,
_requestedLocales_: a Language Priority List,
_usage_: a String,
_localeMatcher_: a String,
): either a normal completion containing a String or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It determines the preferred target unit for _sourceUnit_ in the locale best matching _requestedLocales_ and _usage_ context, based on CLDR unit preferences data.</dd>
</dl>
<emu-alg>
1. Let _sourceConv_ be ? GetUnitConversionFactor(_sourceUnit_).
1. Let _category_ be _sourceConv_.[[Category]].
1. Let _availableLocales_ be the Available Locales List for locales for which the <code><unitPreferences></code> element data of <a href="https://unicode.org/reports/tr35/tr35-info.html#Unit_Preferences">UTS #35 Part 6 Supplemental, Unit Preferences</a> includes data.
1. Let _localeData_ be a Record whose field names are the elements of _availableLocales_ and whose values are Records.
1. Let _r_ be ResolveLocale(_availableLocales_, _requestedLocales_, the Record { [[localeMatcher]]: _localeMatcher_ }, « », _localeData_).
1. Let _locale_ be _r_.[[Locale]].
1. Let _preferredUnit_ be the preferred unit for _category_, _locale_, _usage_, and _sourceValue_ as specified by the <code><unitPreferences></code> element data of <a href="https://unicode.org/reports/tr35/tr35-info.html#Unit_Preferences">UTS #35 Part 6 Supplemental, Unit Preferences</a>.
1. If _preferredUnit_ is *undefined*, throw a *RangeError* exception.
1. Return _preferredUnit_.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-amount-intl-normative-references">
<h1>Amendment to the Normative References of ECMA-402</h1>
<emu-note type="editor">
<p>The following entry is to be added to ECMA-402's list of referenced parts of Unicode Technical Standard #35.</p>
</emu-note>
<ul>
<li>
<a href="https://unicode.org/reports/tr35/tr35-info.html#Unit_Preferences">Part 6 Supplemental, Unit Preferences</a>
</li>
</ul>
</emu-clause>
</emu-clause>
<emu-clause id="numberformat-objects">
<h1>NumberFormat Objects</h1>
<emu-clause id="sec-numberformat-abstracts">
<h1>Abstract Operations for NumberFormat Objects</h1>
<emu-clause id="sec-getnumberformatpattern" type="abstract operation">
<h1>
GetNumberFormatPattern (
_numberFormat_: an Intl.NumberFormat,
_x_: an Intl mathematical value,
): either a normal completion containing a String or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>
It considers the resolved unit-related options in the number format object along with the final scaled and rounded number being formatted (an Intl mathematical value) and returns a pattern, a String value as described in <emu-xref href="#sec-intl.numberformat-internal-slots"></emu-xref>.
</dd>
</dl>
<emu-alg>
1. Let _resolvedLocaleData_ be _numberFormat_.[[LocaleData]].
1. Let _patterns_ be _resolvedLocaleData_.[[patterns]].
1. Assert: _patterns_ is a Record (see <emu-xref href="#sec-intl.numberformat-internal-slots"></emu-xref>).
1. Let _style_ be _numberFormat_.[[Style]].
1. If _style_ is *"percent"*, then
1. Set _patterns_ to _patterns_.[[percent]].
1. Else if _style_ is *"unit"*, then
1. Let _unit_ be _numberFormat_.[[Unit]].
1. <ins>Let _fmtUnit_ be _x_.[[Unit]].</ins>
1. <ins>If _fmtUnit_ is not *undefined* and SameValueNonNumber(_unit_, _fmtUnit_) is *false*, then</ins>
1. <ins>If _unit_ is not *undefined*, throw a *TypeError* exception.</ins>
1. <ins>Set _unit_ to _fmtUnit_.</ins>
1. <ins>Else if _unit_ is *undefined*, then</ins>
1. <ins>Throw a *TypeError* exception.</ins>
1. Let _unitDisplay_ be _numberFormat_.[[UnitDisplay]].
1. Set _patterns_ to _patterns_.[[unit]].
1. If _patterns_ doesn't have a field [[<_unit_>]], then
1. Set _unit_ to *"fallback"*.
1. Set _patterns_ to _patterns_.[[<_unit_>]].
1. Set _patterns_ to _patterns_.[[<_unitDisplay_>]].
1. Else if _style_ is *"currency"*, then
1. Let _currency_ be _numberFormat_.[[Currency]].
1. <ins>Let _fmtCurrency_ be _x_.[[Currency]].</ins>
1. <ins>If _fmtCurrency_ is not *undefined* and SameValueNonNumber(_currency_, _fmtCurrency_) is *false*, then</ins>
1. <ins>If _currency_ is not *undefined*, throw a *TypeError* exception.</ins>
1. <ins>Set _currency_ to _fmtCurrency_.</ins>
1. <ins>Else if _currency_ is *undefined*, then</ins>
1. <ins>Throw a *TypeError* exception.</ins>
1. Let _currencyDisplay_ be _numberFormat_.[[CurrencyDisplay]].
1. Let _currencySign_ be _numberFormat_.[[CurrencySign]].
1. Set _patterns_ to _patterns_.[[currency]].
1. If _patterns_ doesn't have a field [[<_currency_>]], then
1. Set _currency_ to *"fallback"*.
1. Set _patterns_ to _patterns_.[[<_currency_>]].
1. Set _patterns_ to _patterns_.[[<_currencyDisplay_>]].
1. Set _patterns_ to _patterns_.[[<_currencySign_>]].
1. Else,
1. Assert: _style_ is *"decimal"*.
1. Set _patterns_ to _patterns_.[[decimal]].
1. If _x_ is ~negative-infinity~, then
1. Let _category_ be ~negative-non-zero~.
1. Else if _x_ is ~negative-zero~, then
1. Let _category_ be ~negative-zero~.
1. Else if _x_ is ~not-a-number~, then
1. Let _category_ be ~positive-zero~.
1. Else if _x_ is ~positive-infinity~, then
1. Let _category_ be ~positive-non-zero~.
1. Else,
1. Assert: _x_ is a mathematical value.
1. If _x_ < 0, then
1. Let _category_ be ~negative-non-zero~.
1. Else if _x_ > 0, then
1. Let _category_ be ~positive-non-zero~.
1. Else,
1. Let _category_ be ~positive-zero~.
1. Let _signDisplay_ be _numberFormat_.[[SignDisplay]].
1. If _signDisplay_ is *"never"*, then
1. Let _pattern_ be _patterns_.[[zeroPattern]].
1. Else if _signDisplay_ is *"auto"*, then
1. If _category_ is ~positive-non-zero~ or ~positive-zero~, then
1. Let _pattern_ be _patterns_.[[zeroPattern]].
1. Else,
1. Let _pattern_ be _patterns_.[[negativePattern]].
1. Else if _signDisplay_ is *"always"*, then
1. If _category_ is ~positive-non-zero~ or ~positive-zero~, then
1. Let _pattern_ be _patterns_.[[positivePattern]].
1. Else,
1. Let _pattern_ be _patterns_.[[negativePattern]].
1. Else if _signDisplay_ is *"exceptZero"*, then
1. If _category_ is ~positive-zero~ or ~negative-zero~, then
1. Let _pattern_ be _patterns_.[[zeroPattern]].
1. Else if _category_ is ~positive-non-zero~, then
1. Let _pattern_ be _patterns_.[[positivePattern]].
1. Else,
1. Let _pattern_ be _patterns_.[[negativePattern]].
1. Else,
1. Assert: _signDisplay_ is *"negative"*.
1. If _category_ is ~negative-non-zero~, then
1. Let _pattern_ be _patterns_.[[negativePattern]].
1. Else,
1. Let _pattern_ be _patterns_.[[zeroPattern]].
1. Return _pattern_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-setnumberformatunitoptions" type="abstract operation">
<h1>
SetNumberFormatUnitOptions (
_intlObj_: an Intl.NumberFormat,
_options_: an Object,
): either a normal completion containing ~unused~ or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It resolves the user-specified options relating to units onto _intlObj_.</dd>
</dl>
<emu-alg>
1. Let _style_ be ? GetOption(_options_, *"style"*, ~string~, « *"decimal"*, *"percent"*, *"currency"*, *"unit"* », *"decimal"*).
1. Set _intlObj_.[[Style]] to _style_.
1. Let _currency_ be ? GetOption(_options_, *"currency"*, ~string~, ~empty~, *undefined*).
1. <del>If _currency_ is *undefined*, then</del>
1. <del>If _style_ is *"currency"*, throw a *TypeError* exception.</del>
1. <del>Else,</del>
1. <del>If IsWellFormedCurrencyCode(_currency_) is *false*, throw a *RangeError* exception.</del>
1. <ins>If _currency_ is not *undefined* and IsWellFormedCurrencyCode(_currency_) is *false*, throw a *RangeError* exception.</ins>
1. Let _currencyDisplay_ be ? GetOption(_options_, *"currencyDisplay"*, ~string~, « *"code"*, *"symbol"*, *"narrowSymbol"*, *"name"* », *"symbol"*).
1. Let _currencySign_ be ? GetOption(_options_, *"currencySign"*, ~string~, « *"standard"*, *"accounting"* », *"standard"*).
1. Let _unit_ be ? GetOption(_options_, *"unit"*, ~string~, ~empty~, *undefined*).
1. <del>If _unit_ is *undefined*, then</del>
1. <del>If _style_ is *"unit"*, throw a *TypeError* exception.</del>
1. <del>Else,</del>
1. <del>If IsWellFormedUnitIdentifier(_unit_) is *false*, throw a *RangeError* exception.</del>
1. <ins>If _unit_ is not *undefined* and IsWellFormedUnitIdentifier(_unit_) is *false*, throw a *RangeError* exception.</ins>
1. Let _unitDisplay_ be ? GetOption(_options_, *"unitDisplay"*, ~string~, « *"short"*, *"narrow"*, *"long"* », *"short"*).
1. If _style_ is *"currency"*, then
1. <ins>If _currency_ is not *undefined*, set</ins> <del>Set</del> _intlObj_.[[Currency]] to the ASCII-uppercase of _currency_.
1. Set _intlObj_.[[CurrencyDisplay]] to _currencyDisplay_.
1. Set _intlObj_.[[CurrencySign]] to _currencySign_.
1. If _style_ is *"unit"*, then
1. <ins>If _unit_ is not *undefined*, </ins> <del>Set</del> <ins>set</ins> _intlObj_.[[Unit]] to _unit_.
1. Set _intlObj_.[[UnitDisplay]] to _unitDisplay_.
1. Return ~unused~.
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>