Skip to content
Merged
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
2 changes: 1 addition & 1 deletion intl.emu
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
</dd>
</dl>
<emu-alg>
1. <ins>If _value_ has the [[Value]] and [[FractionDigits]] internal slots, let _primValue_ be RenderMVWithFractionDigits(_value_.[[Value]], _value_.[[FractionDigits]]) else</ins><del>Let</del> <ins>let</ins _primValue_ be ? ToPrimitive(_value_, ~number~).
1. <ins>If _value_ has the [[Value]] and [[FractionDigits]] internal slots, let _primValue_ be RenderAmountValueWithFractionDigits(_value_.[[Value]], _value_.[[FractionDigits]]) else</ins><del>Let</del> <ins>let</ins _primValue_ be ? ToPrimitive(_value_, ~number~).
1. If _primValue_ is a BigInt, return ℝ(_primValue_).
1. If _primValue_ is a String, then
1. Let _str_ be _primValue_.
Expand Down
216 changes: 123 additions & 93 deletions spec.emu
Original file line number Diff line number Diff line change
Expand Up @@ -71,27 +71,83 @@ location: https://github.com/tc39/proposal-measure/
</emu-clause>
</emu-clause>

<!-- This is copied directly from proposal-intl-keep-trailing-zeros -->
<!-- See http://tc39.es/proposal-intl-keep-trailing-zeros/ -->
<emu-clause id="sec-runtime-semantics-stringintlmv" type="sdo" number="15">
<h1>Runtime Semantics: StringIntlMV</h1>
<dl class="header">
</dl>
<emu-note>
<del class="block">
<p>The
conversion of a |StringNumericLiteral| to a Number value is similar overall to the determination of the NumericValue of a |NumericLiteral| (see <emu-xref href="#sec-literals-numeric-literals"></emu-xref>), but some of the details are different.</p>
</del>
<ins class="block">
<p>
The conversion of a |StringNumericLiteral| to a mathematical value and a precision is similar overall to the determination of the NumericValue of a |NumericLiteral| (see <emu-xref href="#sec-literals-numeric-literals"></emu-xref>), but some of the details are different.
The result of StringIntlMV is a List value with two elements, a mathematical value and the count of decimal digits in the source text.
</p>
</ins>
</emu-note>
<emu-grammar>StringNumericLiteral ::: StrWhiteSpace?</emu-grammar>
<emu-alg>
1. Return <del>0</del><ins>« 0, 0 »</ins>.
</emu-alg>
<emu-grammar>StringNumericLiteral ::: StrWhiteSpace? StrNumericLiteral StrWhiteSpace?</emu-grammar>
<emu-alg>
1. Return StringIntlMV of |StrNumericLiteral|.
</emu-alg>
<emu-grammar>StrNumericLiteral ::: NonDecimalIntegerLiteral</emu-grammar>
<emu-alg>
1. <del>Return MV of |NonDecimalIntegerLiteral|.</del>
1. <ins>Let _i_ be MV of |NonDecimalIntegerLiteral|.</ins>
1. <ins>Return « _i_, 0 ».</ins>
</emu-alg>
<emu-grammar>StrDecimalLiteral ::: `-` StrUnsignedDecimalLiteral</emu-grammar>
<emu-alg>
1. Let <del>_a_</del><ins>_x_</ins> be StringIntlMV of |StrUnsignedDecimalLiteral|.
1. <ins>Let _a_ be the first element of _x_.</ins>
1. <ins>Let _n_ be the second element of _x_.</ins>
1. If _a_ is 0, return <del>~negative-zero~</del><ins>« ~negative-zero~, _n_ »</ins>.
1. If _a_ is ~positive-infinity~, return <del>~negative-infinity~</del><ins>« ~negative-infinity~, 0 »</ins>.
1. Return <del>-_a_</del><ins>« -_a_, _n_ »</ins>.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: `Infinity`</emu-grammar>
<emu-alg>
1. Return <del>~positive-infinity~</del><ins>« ~positive-infinity~, 0 »</ins>.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: DecimalDigits `.` DecimalDigits? ExponentPart?</emu-grammar>
<emu-alg>
1. Let _a_ be MV of the first |DecimalDigits|.
1. <ins>Let _m_ be the number of code points in the first |DecimalDigits|.</ins>
1. If the second |DecimalDigits| is present, then
1. Let _b_ be MV of the second |DecimalDigits|.
1. Let _n_ be the number of code points in the second |DecimalDigits|.
1. Else,
1. Let _b_ be 0.
1. Let _n_ be 0.
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|. Otherwise, let _e_ be 0.
1. Return <ins>«</ins> (_a_ + (_b_ × 10<sup>-_n_</sup>)) × 10<sup>_e_</sup><ins>, _m_ + _n_ »</ins>.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: `.` DecimalDigits ExponentPart?</emu-grammar>
<emu-alg>
1. Let _b_ be MV of |DecimalDigits|.
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|. Otherwise, let _e_ be 0.
1. Let _n_ be the number of code points in |DecimalDigits|.
1. Return <ins>«</ins> _b_ × 10<sup>_e_ - _n_</sup><ins>, _n_ ».</ins>
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPart?</emu-grammar>
<emu-alg>
1. Let _a_ be MV of |DecimalDigits|.
1. <ins>Let _m_ be the number of code points in |DecimalDigits|.</ins>
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|. Otherwise, let _e_ be 0.
1. Return <ins>«</ins> _a_ × 10<sup>_e_</sup><ins>, _m_ »</ins>.
</emu-alg>
</emu-clause>

<emu-clause id="sec-amount-abstract-ops-decimal-digit-strings">
<h1>Operations on Decimal Digit Strings</h1>

<emu-clause id="sec-amount-countsignificantdigits" type="abstract operation">
<h1>CountSignificantDigits(
_s_: a decimal digit String
): a positive integer
</h1>
<dl class="header">
<dt>description</dt>
<dd>It computes the number of significant digits in a given <emu-xref href="#dfn-decimal-digit-string">decimal digit String</emu-xref>.</dd>
</dl>
<emu-alg>
1. Let _digitsToCount_ be _s_.
1. If _digitsToCount_ contains an *e* character, set _digitsToCount_ be the substring of _s_ before the first occurence of *"e"*.
1. If _digitsToCount_ contains a *"."* character, set _digitsToCount_ to the result of replacing all occurrences of *"."* in _digitsToCount_ by *""*.
1. Let _l_ be the length of _digitsToCount_.
1. Return _l_.
</emu-alg>
</emu-clause>

<emu-clause id="sec-amount-countfractiondigits" type="abstract operation">
<h1>CountFractionDigits(
_s_: a decimal digit String
Expand Down Expand Up @@ -142,7 +198,7 @@ location: https://github.com/tc39/proposal-measure/
</emu-clause>

<emu-clause id="sec-amount-roundtofractiondigits" type="abstract operation">
<h1>RoundToFractionDigits(
<h1>RoundAmountValueToFractionDigits(
_v_: a mathematical value,
_n_: a non-negative integer,
optional _roundingMode_: a rounding mode
Expand All @@ -161,7 +217,7 @@ location: https://github.com/tc39/proposal-measure/
1. If _roundingMode_ is *"ceil"*, set _reverseRoundingMode_ to *"floor"*.
1. If _roundingMode_ is *"halfCeil"*, set _reverseRoundingMode_ to *"halfFloor"*.
1. If _roundingMode_ is *"halfFloor"*, set _reverseRoundingMode_ to *"halfCeil"*.
1. Let _d_ be RoundToFractionDigits(–_v_, _n_, _reverseRoundingMode_).
1. Let _d_ be RoundAmountValueToFractionDigits(–_v_, _n_, _reverseRoundingMode_).
1. Return –_d_.
1. Let _e_ be the unique integer such that 10<sup>_e_</sup> ≤ _v_ < 10<sup>_e_+1</sup>.
1. Let _pow_ be _e_ + _n_.
Expand Down Expand Up @@ -203,17 +259,20 @@ location: https://github.com/tc39/proposal-measure/
</emu-clause>

<emu-clause id="sec-amount-rendermvwithfractiondigits" type="abstract operation">
<h1>RenderMVWithFractionDigits(
_v_: a mathematical value,
<h1>RenderAmountValueWithFractionDigits(
_v_: an Intl mathematical value,
_numDigits_: a non-negative integer,
optional _roundingMode_: a rounding mode
): a String
</h1>
<dl class="header">
<dt>description</dt>
<dd>It renders the given mathematical value with a given number of fractional digits, possibly rounding if necessary, using the given rounding mode, which, if missing, is *"halfEven"*.</dd>
<dd>It renders the given mathematical value or a suitable enum (~positive-infinity~, ~negative-infinity~, ~not-a-number~, or ~minus-zero~) with a given number of fractional digits, possibly rounding if necessary, using the given rounding mode, which, if missing, is *"halfEven"*.</dd>
</dl>
<emu-alg>
1. If _v_ is ~not-a-number~, return *"NaN"*.
1. If _v_ is ~negative-infinity~, return *"-Infinity"*.
1. If _v_ is ~positive-infinity~, return *"Infinity"*.
1. If _roundingMode_ is *undefined*, let _mode_ be *"halfEven"*, else let _mode_ be _roundingMode_.
1. If _v_ < 0, let _prefix_ be *"-"*, else let _prefix_ be "".
1. If _v_ < 0, set _v_ to -_v_.
Expand All @@ -222,10 +281,10 @@ location: https://github.com/tc39/proposal-measure/
1. Let _e_ be the smallest non-negative integer such that _v_ × 10<sup>-_numDigits_</sup> is an integer.
1. Let _s_ be the unique decimal string representation of _v_ without leading zeroes.
1. If _numDigits_ > _e_, then
1. If _v_ is an integer, return the string concatenation of _prefix, _s_, *"."*, and *"0"* repeated _numDigits_ times.
1. Otherwise, return the string concatenation of _prefix_, _s_ and *"0"* repeated _numDigits_ - _e_ times.
1. If _v_ is an integer, return the string-concatenation of _prefix, _s_, *"."*, and *"0"* repeated _numDigits_ times.
1. Otherwise, return the string-concatenation of _prefix_, _s_ and *"0"* repeated _numDigits_ - _e_ times.
1. Otherwise:
1. Return the string concatenation of _prefix, _s_ and *"0"* repeated _e_ - _numDigits_ times.
1. Return the string-concatenation of _prefix, _s_ and *"0"* repeated _e_ - _numDigits_ times.
</emu-alg>
</emu-clause>

Expand Down Expand Up @@ -275,80 +334,51 @@ location: https://github.com/tc39/proposal-measure/
1. Else if _x_ is a Number, set _toParse_ to Number::toString(_x_, 10).
1. Otherwise, if _x_ is a String, set _toParse_ to _x_.
1. If _toParse_ is not a String, throw a *TypeError* exception.
1. If _toParse_ is in « *"NaN"*, *"Infinity"*, *"-Infinity"* », throw a *RangeError* exception.
1. Let _parseResult_ be ParseText(_toParse_, |StrDecimalLiteral|).
1. Let _intlMV_ be the StringIntlMV of _toParse_.
1. Let _amountValue_ be _intlMV_[0].
1. Let _numDigits_ be _intlMV_[1].
1. Let _validatedOpts_ be ? GetAmountOptions(_opts_).
1. If _parseResult_ is a List of errors, throw a *SyntaxError* exception.
1. Let _amountValue_ be ? StringDecimalValue of _parseResult_.
1. Let _fractionDigits_ be _validatedOpts_.[[FractionDigits]].
1. Let _roundingMode_ be _validatedOpts_.[[RoundingMode]].
1. Let _significantDigits_ be _validatedOpts_.[[SignificantDigits]].
1. Let _unit_ be _validatedOpts_.[[Unit]].
1. Let _roundedValue_ be _amountValue_.
1. Assert: If _fractionDigits_ is not *undefined*, then _significantDigits_ is *undefined*.
1. Assert: If _significantDigits_ is not *undefined*, then _fractionDigits_ is *undefined*.
1. If both _significantDigits_ and _fractionDigits_ are *undefined*, then
1. Set _significantDigits_ to CountSignificantDigits(_toParse_).
1. Set _fractionDigits_ to CountFractionDigits(_toParse_).
1. Else if _significantDigits_ is *undefined*, then
1. Set _roundedValue_ be RoundToFractionDigits(_amountValue_, _fractionDigits_, _roundingMode_).
1. Let _digitStr_ be the unique decimal string representation of _roundedValue_ without leading zeroes.
1. Set _significantDigits_ to CountSignificantDigits(_digitStr_).
1. Otherwise:
1. Set _roundedValue_ be RoundToSignificantDigits(_amountValue_, _significantDigits_, _roundingMode_).
1. Let _digitStr_ be the unique decimal string representation of _roundedValue_ without leading zeroes.
1. Set _fractionDigits_ to CountFractionDigits(_digitStr_).
1. Let _O_ be OrdinaryObjectCreate(%Amount.prototype%, « [[FractionDigits]], [[SignificantDigits]], [[Unit]], [[Value]] »).
1. Set _O_.[[Value]] to _roundedValue_.
1. Set _O_.[[SignificantDigits]] to _significantDigits_.
1. Set _O_.[[FractionDigits]] to _fractionDigits_.
1. If _amountValue_ is a mathematical value, then
1. Let _roundedValue_ be _amountValue_.
1. If both _significantDigits_ and _fractionDigits_ are *undefined*, then
1. Set _significantDigits_ to _numDigits_.
1. Set _fractionDigits_ to CountFractionDigits(_toParse_).
1. Else if _significantDigits_ is *undefined*, then
1. Set _roundedValue_ be RoundAmountValueToFractionDigits(_amountValue_, _fractionDigits_, _roundingMode_).
1. Let _e_ be the smallest non-negative integer such that _roundedValue_ × 10<sup>-_e_</sup> is an integer.
1. Let _scaledRoundedValue_ be _roundedValue_ × 10<sup>-_e_</sup>.
1. If _scaledRoundedValue_ = 0, then
1. Set _significantDigits_ to 1.
1. Else,
1. Let _l_ be the log-10 of abs(_scaledRoundedValue_).
1. Set _significantDigits_ to floor(_l_) + 1.
1. Otherwise:
1. Set _roundedValue_ be RoundToSignificantDigits(_amountValue_, _significantDigits_, _roundingMode_).
1. Let _digitStr_ be the unique decimal string representation of _roundedValue_ without leading zeroes.
1. Set _fractionDigits_ to CountFractionDigits(_digitStr_).
1. Set _O_.[[Value]] to _roundedValue_.
1. Set _O_.[[SignificantDigits]] to _significantDigits_.
1. Set _O_.[[FractionDigits]] to _fractionDigits_.
1. Else if _amountValue_ is ~minus-zero~, then
1. Set _O_.[[Value]] to ~minus-zero~.
1. Set _O_.[[SignificantDigits]] to _numDigits_.
1. Assert: _numDigits_ ≥ 1.
1. Set _O_.[[FractionDigits]] to _numDigits_ - 1.
1. Otherwise:
1. Set _O_.[[Value]] to _amountValue_.
1. Set _O_.[[SignificantDigits]] to _numDigits_..
1. Set _O_.[[FractionDigits]] to 0.
1. If _unit_ is not *undefined*, set _O_.[[Unit]] to _unit_.
1. Return _O_.
</emu-alg>
<emu-note>
<p>Given a Number argument, the constructor converts it to a String using the <emu-xref href="#sec-number.prototype.tostring">toString</emu-xref> method (with no arguments). In some cases, this may not be desired; consider passing in a String form of a Number using the <emu-xref href="#sec-number.prototype.tofixed">toFixed</emu-xref> or <emu-xref href="#sec-number.prototype.toprecision">toPrecision</emu-xref> methods.</p>
</emu-note>
<emu-clause id="sec-runtime-semantics-stringdecimalvalue" type="sdo">
<h1>Runtime Semantics: StringDecimalValue ( ): either a normal completion containing a mathematical value or a throw completion</h1>
<dl class="header">
</dl>
<emu-grammar>StrDecimalLiteral ::: `-` StrUnsignedDecimalLiteral</emu-grammar>
<emu-alg>
1. Let _a_ be ? StringAmountValue of |StrUnsignedDecimalLiteral|.
1. Assert: _a_ is finite.
1. Return −_a_.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: `Infinity`</emu-grammar>
<emu-alg>
1. Throw a *RangeError* exception.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: DecimalDigits `.` DecimalDigits? ExponentPart?</emu-grammar>
<emu-alg>
1. Let _a_ be MV of the first |DecimalDigits|.
1. If the second |DecimalDigits| is present, then
1. Let _b_ be MV of the second |DecimalDigits|.
1. Let _n_ be the number of code points in the second |DecimalDigits|.
1. Else,
1. Let _b_ be 0.
1. Let _n_ be 0.
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|. Otherwise, let _e_ be 0.
1. Return (_a_ + (_b_ × 10<sup>−_n_</sup>)) × 10<sup>_e_</sup>.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: `.` DecimalDigits ExponentPart?</emu-grammar>
<emu-alg>
1. Let _b_ be MV of |DecimalDigits|.
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|. Otherwise, let _e_ be 0.
1. Let _n_ be the number of code points in |DecimalDigits|.
1. Let _newValue_ be _b_ × 10<sup>_e_ − _n_</sup>.
1. Return _newValue_.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPart?</emu-grammar>
<emu-alg>
1. Let _a_ be MV of |DecimalDigits|.
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|. Otherwise, let _e_ be 0.
1. Return _a_ × 10<sup>_e_</sup>.
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>
</emu-clause>
Expand All @@ -369,13 +399,13 @@ location: https://github.com/tc39/proposal-measure/
1. Let _u_ be _O_.[[Unit]].
1. Let _v_ be _O_.[[Value]].
1. Let _fractionDigits_ be _O_.[[FractionDigits]].
1. Let _s_ be RenderMVWithFractionDigits(_v_, _fractionDigits_).
1. Let _s_ be RenderAmountValueWithFractionDigits(_v_, _fractionDigits_).
1. If _displayUnit_ is *"never"*, return _s_.
1. If _u_ is *undefined*, then
1. If _displayUnit_ is *"always"*, return the string-concatenation of _s_ and *"[1]"*.
1. Else, return _s_.
1. Else,
1. Return the string concatenation of _s_, *"["*, _u_, and *"]"*.
1. Return the string-concatenation of _s_, *"["*, _u_, and *"]"*.
</emu-alg>
</emu-clause>

Expand All @@ -399,7 +429,7 @@ location: https://github.com/tc39/proposal-measure/
1. Let _fractionDigits_ be _processedOptions_.[[FractionDigits]].
1. Let _significantDigits_ be _processedOptions_.[[SignificantDigits]].
1. Let _value_ be _O_.[[Value]].
1. If _fractionDigits_ is not *undefined*, set _value_ to RoundToFractionDigits(_value_, _fractionDigits_).
1. If _fractionDigits_ is not *undefined*, set _value_ to RoundAmountValueToFractionDigits(_value_, _fractionDigits_).
1. Else if _significantDigits_ is not *undefined*, set _value_ to RoundToSignificantDigits(_value_, _significantDigits_).
1. Otherwise, throw a *TypeError* exception.
1. Let _N_ be OrdinaryObjectCreate(*"%Amount.prototype%"*, « [[FractionDigits]], [[SignificantDigits]], [[Unit]], [[Value]] »).
Expand Down Expand Up @@ -427,9 +457,9 @@ location: https://github.com/tc39/proposal-measure/
1. Let _mv_ be _O_.[[Value]].
1. If _hint_ is *"string"*, then
1. Let _fractionDigits_ be _O_.[[FractionDigits]].
1. Let _str_ be RenderMVWithFractionDigits(_mv_, _fractionDigits_).
1. Let _str_ be RenderAmountValueWithFractionDigits(_mv_, _fractionDigits_).
1. If _unit_ is *undefined*, return _str_.
1. Else, return the string concatenation of _str_, *"["*, _unit_, and *"]"*.
1. Else, return the string-concatenation of _str_, *"["*, _unit_, and *"]"*.
1. Else,
1. If _unit_ is not *undefined*, throw a *TypeError* exception.
1. Return the Number value for _mv_.
Expand Down