Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions intl.emu
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
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 _minFractionDigits_ be _validatedOpts_.[[MinimumFractionDigits]].
1. Let _maxFractionDigits_ be _validatedOpts_.[[MaximumFractionDigits]].
1. Let _minSignificantDigits_ be _validatedOpts_.[[MinimumSignificantDigits]].
1. Let _maxSignificantDigits_ be _validatedOpts_.[[MaximumSignificantDigits]].
Expand All @@ -90,9 +90,13 @@
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. If _minFractionDigits_ is not *undefined*, let _mnfd_ be ℝ(_minFractionDigits_); else let _mnfd_ be *undefined*.
1. If _maxFractionDigits_ is not *undefined*, let _mxfd_ be ℝ(_maxFractionDigits_); else let _mxfd_ be *undefined*.
1. If _minSignificantDigits_ is not *undefined*, let _mnsd_ be ℝ(_minSignificantDigits_); else let _mnsd_ be *undefined*.
1. If _maxSignificantDigits_ is not *undefined*, let _mxsd_ be ℝ(_maxSignificantDigits_); else let _mxsd_ be *undefined*.
1. Let _formatter_ be CreateFormatterObject(_roundingMode_, _mnfd_, _mxfd_, _mnsd_, _mxsd_, _roundingPriority_).
1. Let _formatted_ be FormatNumericToString(_formatter_, ℝ(_convertedValue_), 0).
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_.
Expand Down
96 changes: 74 additions & 22 deletions spec.emu
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,10 @@ location: https://github.com/tc39/proposal-amount/
1. If _fractionDigits_ is not *undefined*, then
1. If _significantDigits_ is not *undefined*, throw a *RangeError* exception.
1. If _fractionDigits_ is not an integral Number, throw a *RangeError* exception.
1. If _fractionDigits_ &lt; *-0*<sub>𝔽</sub> or _fractionDigits_ > *100*<sub>𝔽</sub>, throw a *RangeError* exception.
Comment on lines 94 to +95
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The operation header requires [[FractionDigits]] to be undefined or an integer, so let's convert it here and remove the awkward use of -0𝔽.

Suggested change
1. If _fractionDigits_ is not an integral Number, throw a *RangeError* exception.
1. If _fractionDigits_ &lt; *-0*<sub>𝔽</sub> or _fractionDigits_ > *100*<sub>𝔽</sub>, throw a *RangeError* exception.
1. If _fractionDigits_ is not an integral Number, throw a *RangeError* exception.
1. Set _fractionDigits_ to ℝ(_fractionDigits_).
1. If _fractionDigits_ is not in the inclusive interval from 0 to 100, throw a *RangeError* exception.

1. Else if _significantDigits_ is not *undefined*, then
1. If _significantDigits_ is not an integral Number, throw a *RangeError* exception.
1. If _significantDigits_ &lt; *1*<sub>𝔽</sub>, throw a *RangeError* exception.
1. If _significantDigits_ &lt; *1*<sub>𝔽</sub> or _significantDigits_ > *21*<sub>𝔽</sub>, throw a *RangeError* exception.
Comment on lines 97 to +98
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. If _significantDigits_ is not an integral Number, throw a *RangeError* exception.
1. If _significantDigits_ &lt; *1*<sub>𝔽</sub>, throw a *RangeError* exception.
1. If _significantDigits_ &lt; *1*<sub>𝔽</sub> or _significantDigits_ > *21*<sub>𝔽</sub>, throw a *RangeError* exception.
1. If _significantDigits_ is not an integral Number, throw a *RangeError* exception.
1. Set _significantDigits_ to ℝ(_significantDigits_).
1. If _significantDigits_ is not in the inclusive interval from 1 to 21, throw a *RangeError* exception.

1. If _unit_ is the empty String, throw a *RangeError* exception.
1. Return the Record { [[FractionDigits]]: _fractionDigits_, [[RoundingMode]]: _roundingMode_, [[SignificantDigits]]: _significantDigits_, [[Unit]]: _unit_ }.
</emu-alg>
Expand All @@ -103,34 +104,82 @@ location: https://github.com/tc39/proposal-amount/
<emu-clause id="sec-amount-getamountconverttooptions" type="abstract operation">
<h1>GetAmountConvertToOptions (
_opts_: an Object
): either a normal completion containing a Record with fields [[MinFractionDigits]] (a non-negative integer or *undefined*), [[MaxFractionDigits]] (a non-negative integer or *undefined*), [[RoundingMode]] (a <emu-xref href="#dfn-amount-rounding-mode">rounding mode</emu-xref>), [[RoundingPriority]] (a String), [[MinSignificantDigits]] (a positive integer or *undefined*), [[MaxSignificantDigits]] (a positive integer or *undefined*), [[Locale]] (a String or *undefined*), [[Usage]] (a String or *undefined*), and [[Unit]] (a String or *undefined*) or a throw completion
): either a normal completion containing a Record with fields [[MinimumFractionDigits]] (a non-negative integer or *undefined*), [[MaximumFractionDigits]] (a non-negative integer or *undefined*), [[RoundingMode]] (a <emu-xref href="#dfn-amount-rounding-mode">rounding mode</emu-xref>), [[RoundingPriority]] (a String), [[MinimumSignificantDigits]] (a positive integer or *undefined*), [[MaximumSignificantDigits]] (a positive integer or *undefined*), [[Locale]] (a String or *undefined*), [[Usage]] (a String or *undefined*), and [[Unit]] (a String or *undefined*) or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It validates the given _options_ (an ECMAScript object) for converting an Amount to another Amount and returns a Record with slots set to appropriate marthematical values (or *undefined*).</dd>
</dl>
<emu-alg>
1. Let _opts_ be ? GetOptionsObject(_opts_).
1. Let _minFractionDigits_ be ? GetOption(_opts_, *"minimumfractionDigits"*, ~number~, ~empty~, *undefined*).
1. Let _maxFractionDigits_ be ? GetOption(_opts_, *"maximumfractionDigits"*, ~number~, ~empty~, *undefined*).
1. Let _minFractionDigits_ be ? GetOption(_opts_, *"minimumFractionDigits"*, ~number~, ~empty~, *undefined*).
1. Let _maxFractionDigits_ be ? GetOption(_opts_, *"maximumFractionDigits"*, ~number~, ~empty~, *undefined*).
1. Let _roundingMode_ be ? GetOption(_opts_, *"roundingMode"*, ~string~, « *"ceil"*, *"floor"*, *"expand"*, *"trunc"*, *"halfCeil"*, *"halfFloor"*, *"halfExpand"*, *"halfTrunc"*, *"halfEven"* », *"halfEven"*).
1. Let _roundingPriority_ be ? GetOption(_opts_, *"roundingPriority"*, ~string~, ~empty~, *undefined*).
1. Let _minSignificantDigits_ be ? GetOption(_opts_, *"minimumSignificantDigits"*, ~number~, ~empty~, *undefined*).
1. Let _maxSignificantDigits_ be ? GetOption(_opts_, *"maximumSignificantDigits"*, ~number~, ~empty~, *undefined*).
1. Let _significantDigits_ be ? GetOption(_opts_, *"maximumSignificantDigits"*, ~number~, ~empty~, *undefined*).
1. Let _unit_ be ? GetOption(_opts_, *"unit"*, ~string~, ~empty~, *undefined*).
1. If _minFractionDigits_ is not *undefined* and not an integral Number, throw a *RangeError* exception.
1. If _maxFractionDigits_ is not *undefined* and not an integral Number, throw a *RangeError* exception.
1. If _minSignificantDigits_ is not *undefined* and not an integral Number, throw a *RangeError* exception.
1. If _maxSignificantDigits_ is not *undefined* and not an integral Number, throw a *RangeError* exception.
1. If _minFractionDigits_ is not *undefined*, then
1. If _minFractionDigits_ is not an integral Number, or _minFractionDigits_ &lt; *-0*<sub>𝔽</sub>, or _minFractionDigits_ > *100*<sub>𝔽</sub>, throw a *RangeError* exception.
1. If _maxFractionDigits_ is not *undefined*, then
1. If _maxFractionDigits_ is not an integral Number, or _maxFractionDigits_ &lt; *-0*<sub>𝔽</sub>, or _maxFractionDigits_ > *100*<sub>𝔽</sub>, throw a *RangeError* exception.
Comment on lines +122 to +125
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. If _minFractionDigits_ is not *undefined*, then
1. If _minFractionDigits_ is not an integral Number, or _minFractionDigits_ &lt; *-0*<sub>𝔽</sub>, or _minFractionDigits_ > *100*<sub>𝔽</sub>, throw a *RangeError* exception.
1. If _maxFractionDigits_ is not *undefined*, then
1. If _maxFractionDigits_ is not an integral Number, or _maxFractionDigits_ &lt; *-0*<sub>𝔽</sub>, or _maxFractionDigits_ > *100*<sub>𝔽</sub>, throw a *RangeError* exception.
1. If _minFractionDigits_ is not *undefined*, then
1. If _minFractionDigits_ is not an integral Number, throw a *RangeError* exception.
1. Set _minFractionDigits_ to ℝ(_minFractionDigits_).
1. If _minFractionDigits_ is not in the inclusive interval from 0 to 100, throw a *RangeError* exception.
1. If _maxFractionDigits_ is not *undefined*, then
1. If _maxFractionDigits_ is not an integral Number, throw a *RangeError* exception.
1. Set _maxFractionDigits_ to ℝ(_maxFractionDigits_).
1. If _maxFractionDigits_ is not in the inclusive interval from 0 to 100, throw a *RangeError* exception.

1. If _minFractionDigits_ is not *undefined* and _maxFractionDigits_ is not *undefined* and _minFractionDigits_ > _maxFractionDigits_, throw a *RangeError* exception.
1. If _minSignificantDigits_ is not *undefined*, then
1. If _minSignificantDigits_ is not an integral Number, or _minSignificantDigits_ &lt; *1*<sub>𝔽</sub>, or _minSignificantDigits_ > *21*<sub>𝔽</sub>, throw a *RangeError* exception.
1. If _maxSignificantDigits_ is not *undefined*, then
1. If _maxSignificantDigits_ is not an integral Number, or _maxSignificantDigits_ &lt; *1*<sub>𝔽</sub>, or _maxSignificantDigits_ > *21*<sub>𝔽</sub>, throw a *RangeError* exception.
Comment on lines +127 to +130
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. If _minSignificantDigits_ is not *undefined*, then
1. If _minSignificantDigits_ is not an integral Number, or _minSignificantDigits_ &lt; *1*<sub>𝔽</sub>, or _minSignificantDigits_ > *21*<sub>𝔽</sub>, throw a *RangeError* exception.
1. If _maxSignificantDigits_ is not *undefined*, then
1. If _maxSignificantDigits_ is not an integral Number, or _maxSignificantDigits_ &lt; *1*<sub>𝔽</sub>, or _maxSignificantDigits_ > *21*<sub>𝔽</sub>, throw a *RangeError* exception.
1. If _minSignificantDigits_ is not *undefined*, then
1. If _minSignificantDigits_ is not an integral Number, throw a *RangeError* exception.
1. Set _minSignificantDigits_ to ℝ(_minSignificantDigits_).
1. If _minSignificantDigits_ is not in the inclusive interval from 1 to 21, throw a *RangeError* exception.
1. If _maxSignificantDigits_ is not *undefined*, then
1. If _maxSignificantDigits_ is not an integral Number, throw a *RangeError* exception.
1. Set _maxSignificantDigits_ to ℝ(_maxSignificantDigits_).
1. If _maxSignificantDigits_ is not in the inclusive interval from 1 to 21, throw a *RangeError* exception.

1. If _minSignificantDigits_ is not *undefined* and _maxSignificantDigits_ is not *undefined* and _minSignificantDigits_ > _maxSignificantDigits_, throw a *RangeError* exception.
1. If _unit_ is the empty String, throw a *RangeError* exception.
1. Return the Record { [[MinimumFractionDigits]]: _minFractionDigits_, [[MaximumFractionDigits]]: _maxFractionDigits_, [[MinimumSignificantDigits]]: _minSignificantDigits_, [[MaximumSignificantDigits]]: _maxSignificantDigits_, [[RoundingMode]]: _roundingMode_, [[RoundingPriority]]: _roundingPriority_, [[SignificantDigits]]: _significantDigits_, [[Unit]]: _unit_ }.
1. Return the Record { [[MinimumFractionDigits]]: _minFractionDigits_, [[MaximumFractionDigits]]: _maxFractionDigits_, [[MinimumSignificantDigits]]: _minSignificantDigits_, [[MaximumSignificantDigits]]: _maxSignificantDigits_, [[RoundingMode]]: _roundingMode_, [[RoundingPriority]]: _roundingPriority_, [[Unit]]: _unit_ }.
</emu-alg>
</emu-clause>

<emu-clause id="sec-amount-createformatterobject" type="abstract operation">
<h1>CreateFormatterObject (
_roundingMode_: a String,
_minFractionDigits_: a non-negative integer or *undefined*,
_maxFractionDigits_: a non-negative integer or *undefined*,
_minSignificantDigits_: a positive integer or *undefined*,
_maxSignificantDigits_: a positive integer or *undefined*,
_roundingPriority_: a String or *undefined*
): an Object
</h1>
<dl class="header">
<dt>description</dt>
<dd>It creates an object with the internal slots required by <emu-xref href="#sec-formatnumerictostring">FormatNumericToString</emu-xref>, configured according to the given rounding and digit options.</dd>
</dl>
<emu-alg>
1. Let _formatter_ be OrdinaryObjectCreate(*null*).
1. Set _formatter_.[[RoundingMode]] to _roundingMode_.
1. Set _formatter_.[[MinimumIntegerDigits]] to 1.
1. Set _formatter_.[[RoundingIncrement]] to 1.
1. Set _formatter_.[[TrailingZeroDisplay]] to *"auto"*.
1. If _minSignificantDigits_ is not *undefined* or _maxSignificantDigits_ is not *undefined*, let _hasSD_ be *true*; else let _hasSD_ be *false*.
1. If _minFractionDigits_ is not *undefined* or _maxFractionDigits_ is not *undefined*, let _hasFD_ be *true*; else let _hasFD_ be *false*.
1. If _hasSD_ is *true*, then
1. If _minSignificantDigits_ is not *undefined*, let _resolvedMinSD_ be _minSignificantDigits_; else let _resolvedMinSD_ be 1.
1. If _maxSignificantDigits_ is not *undefined*, let _resolvedMaxSD_ be _maxSignificantDigits_; else let _resolvedMaxSD_ be 21.
1. Set _formatter_.[[MinimumSignificantDigits]] to _resolvedMinSD_.
1. Set _formatter_.[[MaximumSignificantDigits]] to _resolvedMaxSD_.
1. Else,
1. Set _formatter_.[[MinimumSignificantDigits]] to 1.
1. Set _formatter_.[[MaximumSignificantDigits]] to 21.
1. If _hasFD_ is *true*, then
1. If _minFractionDigits_ is not *undefined*, let _resolvedMinFD_ be _minFractionDigits_; else let _resolvedMinFD_ be 0.
1. If _maxFractionDigits_ is not *undefined*, let _resolvedMaxFD_ be _maxFractionDigits_; else let _resolvedMaxFD_ be 100.
1. Set _formatter_.[[MinimumFractionDigits]] to _resolvedMinFD_.
1. Set _formatter_.[[MaximumFractionDigits]] to _resolvedMaxFD_.
1. Else,
1. Set _formatter_.[[MinimumFractionDigits]] to 0.
1. Set _formatter_.[[MaximumFractionDigits]] to 100.
1. If _hasSD_ is *true* and _hasFD_ is *true*, then
1. If _roundingPriority_ is *"morePrecision"*, set _formatter_.[[RoundingType]] to ~more-precision~; else set _formatter_.[[RoundingType]] to ~less-precision~.
1. Else if _hasSD_ is *true*, then
1. Set _formatter_.[[RoundingType]] to ~significant-digits~.
1. Else,
1. Set _formatter_.[[RoundingType]] to ~fraction-digits~.
1. Return _formatter_.
</emu-alg>
<emu-note type="editor">
<p>
This abstract operation will need to be overridden in the 402 part because it will read additional Intl-specific properties beyond these.
</p>
</emu-note>
</emu-clause>

<emu-clause id="sec-amount-getunitconversionfactor" type="implementation-defined abstract operation">
Expand Down Expand Up @@ -209,9 +258,11 @@ location: https://github.com/tc39/proposal-amount/
1. Let _value_ be _x_.
1. Else,
1. Assert: _x_ is a String.
1. TODO Let _intlObject_ be an Object suitable as a first argument <emu-xref href="#sec-formatnumerictostring">FormatNumericToString</emu-xref>, using _fractionDigits_, _significantDigits_, and _roundingMode_.
1. If _fractionDigits_ is not *undefined*, let _fd_ be ℝ(_fractionDigits_); else let _fd_ be *undefined*.
1. If _significantDigits_ is not *undefined*, let _sd_ be ℝ(_significantDigits_); else let _sd_ be *undefined*.
1. Let _formatter_ be CreateFormatterObject(_roundingMode_, _fd_, _fd_, _sd_, _sd_, *undefined*).
1. Let _intlMV_ be ! ToIntlMathematicalValue(_x_).
1. Let _formatted_ be FormatNumericToString(_intlObject_, _intlMV_.[[Value]], _intlMV_.[[StringDigitCount]]).
1. Let _formatted_ be FormatNumericToString(_formatter_, _intlMV_.[[Value]], _intlMV_.[[StringDigitCount]]).
1. Let _value_ be _formatted_.[[FormattedString]].
1. Let _O_ be OrdinaryObjectCreate(%Amount.prototype%, « [[AmountValue]], [[Unit]] »).
1. Set _O_.[[AmountValue]] to _value_.
Expand Down Expand Up @@ -316,16 +367,17 @@ location: https://github.com/tc39/proposal-amount/
1. Assert: _v_ is a String.
1. Let _sourceValue_ be StringToNumber(_v_).
1. Let _convertedValue_ be ? ConvertUnitValue(_sourceValue_, _sourceUnit_, _targetUnit_).
1. TODO Let _intlObject_ be an Object suitable as the first argument of <emu-xref href="#sec-formatnumerictostring">FormatNumericToString</emu-xref>, using _minFractionDigits_, _maxFractionDigits_, _minSignificantDigits_, _maxSignificantDigits_, _roundingPriority_, and _roundingMode_.
1. Let _formatted_ be FormatNumericToString(_intlObject_, _convertedValue_, 0).
1. If _minFractionDigits_ is not *undefined*, let _mnfd_ be ℝ(_minFractionDigits_); else let _mnfd_ be *undefined*.
1. If _maxFractionDigits_ is not *undefined*, let _mxfd_ be ℝ(_maxFractionDigits_); else let _mxfd_ be *undefined*.
1. If _minSignificantDigits_ is not *undefined*, let _mnsd_ be ℝ(_minSignificantDigits_); else let _mnsd_ be *undefined*.
1. If _maxSignificantDigits_ is not *undefined*, let _mxsd_ be ℝ(_maxSignificantDigits_); else let _mxsd_ be *undefined*.
1. Let _formatter_ be CreateFormatterObject(_roundingMode_, _mnfd_, _mxfd_, _mnsd_, _mxsd_, _roundingPriority_).
1. Let _formatted_ be FormatNumericToString(_formatter_, ℝ(_convertedValue_), 0).
1. Let _result_ be OrdinaryObjectCreate(%Amount.prototype%, « [[AmountValue]], [[Unit]] »).
1. Set _result_.[[AmountValue]] to _formatted_.[[FormattedString]].
1. Set _result_.[[Unit]] to _targetUnit_.
1. Return _result_.
</emu-alg>
<emu-note>
<p>An ECMAScript implementation that includes the ECMA-402 Internationalization API supersedes this method to additionally support locale-based and usage-based unit conversion via CLDR unit preferences data. Without ECMA-402, only explicit unit-to-unit conversion (via the *"unit"* option) is supported.</p>
</emu-note>
</emu-clause>
</emu-clause>

Expand Down
Loading