-
Notifications
You must be signed in to change notification settings - Fork 8
Add CreateFormatterObject AO #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jessealama
wants to merge
4
commits into
main
Choose a base branch
from
create-formatter-object
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+81
−25
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
db9b04b
Add CreateFormatterObject AO and wire up FormatNumericToString calls
jessealama 795bfdd
Update spec.emu
jessealama 1ffaa32
Ensure significant and fractional digits are in range
jessealama 7f2bad0
intl: Pass along significant/fraction digits to new formatter AO
jessealama File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -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_ < *-0*<sub>𝔽</sub> or _fractionDigits_ > *100*<sub>𝔽</sub>, 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_ < *1*<sub>𝔽</sub>, throw a *RangeError* exception. | ||||||||||||||||||||||||||
| 1. If _significantDigits_ < *1*<sub>𝔽</sub> or _significantDigits_ > *21*<sub>𝔽</sub>, throw a *RangeError* exception. | ||||||||||||||||||||||||||
|
Comment on lines
97
to
+98
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||
| 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> | ||||||||||||||||||||||||||
|
|
@@ -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_ < *-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_ < *-0*<sub>𝔽</sub>, or _maxFractionDigits_ > *100*<sub>𝔽</sub>, throw a *RangeError* exception. | ||||||||||||||||||||||||||
|
Comment on lines
+122
to
+125
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||
| 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_ < *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_ < *1*<sub>𝔽</sub>, or _maxSignificantDigits_ > *21*<sub>𝔽</sub>, throw a *RangeError* exception. | ||||||||||||||||||||||||||
|
Comment on lines
+127
to
+130
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||
| 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"> | ||||||||||||||||||||||||||
|
|
@@ -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_. | ||||||||||||||||||||||||||
|
|
@@ -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> | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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𝔽.