From b6df42a32adf80651384b91453a239a4cf5bb2b7 Mon Sep 17 00:00:00 2001 From: Michael Ficarra Date: Sat, 10 Jul 2021 13:51:03 -0700 Subject: [PATCH] Editorial: refactor runtime MV and add/use RoundStringMVResult (#2435) reword some things that read like initialisms fix linting error accept some changes extract StringNumericValue from MV on the string grammar use StringNumericValue further describe "the mathematical value denoted by" address review comments don't round NonDecimalIntegerLiteral --- spec.html | 131 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/spec.html b/spec.html index 5826608e398..7b8625713eb 100644 --- a/spec.html +++ b/spec.html @@ -4458,53 +4458,68 @@

Syntax

- -

Runtime Semantics: MV

-

The conversion of a String to a Number value is similar overall to the determination of the Number value for a numeric literal (see ), but some of the details are different, so the process for converting a String numeric literal to a value of Number type is given here. This value is determined in two steps: first, a mathematical value (MV) is derived from the String numeric literal; second, this mathematical value is rounded as described below. The MV on any grammar symbol, not provided below, is the MV for that symbol defined in .

- -

Once the exact MV for a String numeric literal has been determined, it is then rounded to a value of the Number type. If the MV is 0, then the rounded value is *+0*𝔽 unless the first non white space code point in the String numeric literal is `-`, in which case the rounded value is *-0*𝔽. Otherwise, the rounded value must be the Number value for the MV (in the sense defined in ), unless the literal includes a |StrUnsignedDecimalLiteral| and the literal has more than 20 significant digits, in which case the Number value may be either the Number value for the MV of a literal produced by replacing each significant digit after the 20th with a 0 digit or the Number value for the MV of a literal produced by replacing each significant digit after the 20th with a 0 digit and then incrementing the literal at the 20th digit position. A digit is significant if it is not part of an |ExponentPart| and

- + +

Runtime Semantics: StringNumericValue

+

The conversion of a String to a Number value is similar overall to the determination of the Number value for a numeric literal (see ), but some of the details are different, so the process for converting a String numeric literal to a value of the Number type is given here.

+ StringNumericLiteral ::: StrWhiteSpace? + + 1. Return *+0*𝔽. + + StringNumericLiteral ::: StrWhiteSpace? StrNumericLiteral StrWhiteSpace? + + 1. Return StringNumericValue of |StrNumericLiteral|. + + StrNumericLiteral ::: NonDecimalIntegerLiteral + + 1. Return 𝔽(MV of |NonDecimalIntegerLiteral|). + + StrDecimalLiteral ::: `-` StrUnsignedDecimalLiteral + + 1. Let _a_ be StringNumericValue of |StrUnsignedDecimalLiteral|. + 1. If _a_ is *+0*𝔽, return *-0*𝔽. + 1. Return -_a_. + + StrUnsignedDecimalLiteral ::: `Infinity` + + 1. Return *+∞*𝔽. + + StrUnsignedDecimalLiteral ::: DecimalDigits `.` DecimalDigits? ExponentPart? + + 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 RoundMVResult((_a_ + (_b_ × 10-_n_)) × 10_e_). + + StrUnsignedDecimalLiteral ::: `.` DecimalDigits ExponentPart? + + 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 RoundMVResult(_b_ × 10_e_ - _n_). + + StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPart? + + 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 RoundMVResult(_a_ × 10_e_). + +
+ + +

RoundMVResult ( _n_ )

+

The abstract operation RoundMVResult takes argument _n_ (a mathematical value). It converts _n_ to a Number in an implementation-defined manner. For the purposes of this abstract operation, a digit is significant if it is not zero or there is a non-zero digit to its left and there is a non-zero digit to its right. For the purposes of this abstract operation, "the mathematical value denoted by" a representation of a mathematical value is the inverse of "the decimal representation of" a mathematical value. It performs the following steps when called:

+ + 1. If the decimal representation of _n_ has 20 or fewer significant digits, return 𝔽(_n_). + 1. Let _option1_ be the mathematical value denoted by the result of replacing each significant digit in the decimal representation of _n_ after the 20th with a 0 digit. + 1. Let _option2_ be the mathematical value denoted by the result of replacing each significant digit in the decimal representation of _n_ after the 20th with a 0 digit and then incrementing it at the 20th position (with carrying as necessary). + 1. Let _chosen_ be an implementation-defined choice of either _option1_ or _option2_. + 1. Return 𝔽(_chosen_). +
@@ -14183,22 +14198,12 @@

Static Semantics: MV

Static Semantics: NumericValue

NumericLiteral :: DecimalLiteral - 1. Return the Number value that results from rounding the MV of |DecimalLiteral| as described below. + 1. Return RoundMVResult(MV of |DecimalLiteral|). NumericLiteral :: NonDecimalIntegerLiteral - 1. Return the Number value that results from rounding the MV of |NonDecimalIntegerLiteral| as described below. + 1. Return 𝔽(MV of |NonDecimalIntegerLiteral|). -

Once the exact MV for a numeric literal has been determined, it is then rounded to a value of the Number type. If the MV is 0, then the rounded value is *+0*𝔽; otherwise, the rounded value must be the Number value for the MV (as specified in ), unless the literal is a |DecimalLiteral| and the literal has more than 20 significant digits, in which case the Number value may be either the Number value for the MV of a literal produced by replacing each significant digit after the 20th with a `0` digit or the Number value for the MV of a literal produced by replacing each significant digit after the 20th with a `0` digit and then incrementing the literal at the 20th significant digit position. A digit is significant if it is not part of an |ExponentPart| and

- - NumericLiteral :: NonDecimalIntegerLiteral BigIntLiteralSuffix 1. Return the BigInt value that represents the MV of |NonDecimalIntegerLiteral|. @@ -24689,11 +24694,9 @@

parseFloat ( _string_ )

1. Let _trimmedString_ be ! TrimString(_inputString_, ~start~). 1. If neither _trimmedString_ nor any prefix of _trimmedString_ satisfies the syntax of a |StrDecimalLiteral| (see ), return *NaN*. 1. Let _numberString_ be the longest prefix of _trimmedString_, which might be _trimmedString_ itself, that satisfies the syntax of a |StrDecimalLiteral|. - 1. Let _mathFloat_ be MV of _numberString_. - 1. If _mathFloat_ = 0, then - 1. If the first code unit of _trimmedString_ is the code unit 0x002D (HYPHEN-MINUS), return *-0*𝔽. - 1. Return *+0*𝔽. - 1. Return 𝔽(_mathFloat_). + 1. Let _parsedNumber_ be ParseText(! StringToCodePoints(_numberString_), |StrDecimalLiteral|). + 1. Assert: _parsedNumber_ is a Parse Node. + 1. Return StringNumericValue of _parsedNumber_.

`parseFloat` may interpret only a leading portion of _string_ as a Number value; it ignores any code units that cannot be interpreted as part of the notation of a decimal literal, and no indication is given that any such code units were ignored.