5 記法上の慣例

5.1 構文文法と字句文法

5.1.1 文脈自由文法

文脈自由文法は、いくつかの生成から構成されます。各生成は、その左辺として非終端記号と呼ばれる抽象記号を持ち、その右辺として0個以上の非終端記号および終端記号の列を持ちます。各文法について、終端記号は指定されたアルファベットから取られます。

chain productionとは、右辺にちょうど1つの非終端記号と0個以上の終端記号を持つ生成です。

goal symbolと呼ばれる単一の区別された非終端記号からなる文から始めて、与えられた文脈自由文法は言語、すなわち、列内の任意の非終端を、その非終端を左辺とする生成の右辺で繰り返し置き換えることによって得られる可能性のある終端記号列の(おそらく無限の)集合を指定します。

5.1.2 字句文法とRegExp文法

ECMAScriptの字句文法は、clause 12に示されます。この文法は、11.1で定義されるSourceCharacterの規則に適合するUnicode符号位置を終端記号として持ちます。これは、goal symbol InputElementDivInputElementTemplateTailInputElementRegExpInputElementRegExpOrTemplateTail、またはInputElementHashbangOrRegExpから始まる生成の集合を定義し、そのような符号位置の列がどのように入力要素の列へ変換されるかを記述します。

white spaceおよびcomments以外の入力要素は、ECMAScriptの構文文法の終端記号を形成し、ECMAScript tokensと呼ばれます。これらのtokensは、ECMAScript言語のreserved words、identifiers、literals、およびpunctuatorsです。さらに、line terminatorsは、tokensとは見なされないものの、入力要素のストリームの一部にもなり、自動セミコロン挿入(12.10)の過程を導きます。単純なwhite spaceおよびsingle-line commentsは破棄され、構文文法の入力要素のストリームには現れません。MultiLineComment(すなわち、複数行にまたがるかどうかにかかわらず、/**/という形式のcomment)も、line terminatorを含まない場合は同様に単に破棄されます。しかし、MultiLineCommentが1個以上のline terminatorsを含む場合、それは単一のline terminatorで置き換えられ、そのline terminatorが構文文法の入力要素のストリームの一部になります。

ECMAScriptのRegExp文法は、22.2.1に示されます。この文法も、SourceCharacterによって定義される符号位置を終端記号として持ちます。これは、goal symbol Patternから始まる生成の集合を定義し、符号位置の列がどのように正規表現パターンへ変換されるかを記述します。

字句文法およびRegExp文法の生成は、区切り句読点として2つのコロン“::”を持つことで区別されます。字句文法とRegExp文法はいくつかの生成を共有します。

5.1.3 数値文字列文法

数値文字列文法は、7.1.4.1に現れます。これはSourceCharacterを終端記号として持ち、goal symbol StringNumericLiteralから始めてStringsを数値へ変換するために使用されます(これは数値リテラルの字句文法に似ていますが、それとは別個です)。

数値文字列文法の生成は、句読点として3つのコロン“:::”を持つことで区別され、source textの解析には決して使用されません。

5.1.4 構文文法

ECMAScriptの構文文法は、clauses 13から16までに示されます。この文法は、字句文法によって定義されるECMAScript tokensを終端記号として持ちます(5.1.2)。これは、2つの代替goal symbols ScriptおよびModuleから始まる生成の集合を定義し、tokensの列がどのようにECMAScriptプログラムの構文的に正しい独立コンポーネントを形成するかを記述します。

符号位置のストリームをECMAScript ScriptまたはModuleとして解析するとき、それはまず字句文法の反復適用によって入力要素のストリームへ変換されます。この入力要素のストリームは、その後、構文文法の単一適用によって解析されます。入力要素のストリーム内のtokensが、tokensを残すことなく、goal nonterminal(ScriptまたはModule)の単一のインスタンスとして解析できない場合、入力ストリームは構文的にエラーです。

解析が成功すると、それはparse tree、すなわち各ノードがParse Nodeである根付き木構造を構築します。各Parse Nodeは文法内の記号のインスタンスです。それは、その記号から導出できるsource textの範囲を表します。source text全体を表すparse treeのルートノードは、解析のgoal symbolのインスタンスです。Parse Nodeが非終端のインスタンスである場合、それは、その非終端を左辺とする何らかの生成のインスタンスでもあります。さらに、それは0個以上のchildrenを持ち、生成の右辺上の各記号に対して1つずつあります。各childは、対応する記号のインスタンスであるParse Nodeです。

新しいParse Nodesは、parserの各呼び出しごとにインスタンス化され、同一のsource textの解析であっても、解析間で再利用されることはありません。Parse Nodesは、それらがsource textの同じ範囲を表し、同じ文法記号のインスタンスであり、同じparser呼び出しから得られた場合に限り、同じParse Nodeと見なされます。

Note 1

同じStringを複数回解析すると、異なるParse Nodesが生じます。たとえば、次を考えてください:

let str = "1 + 1;";
eval(str);
eval(str);

evalへの各呼び出しは、strの値をECMAScript source textへ変換し、それ自身の別個のParse Nodesの木を作成する独立した解析を実行します。各解析は同じString値から導出されたsource textに対して動作するものの、それらの木は別個です。

Note 2
Parse Nodesは仕様上の人工物であり、実装は類似のデータ構造を使用する必要はありません。

構文文法の生成は、句読点として1つのコロン“:”だけを持つことで区別されます。

clauses 13から16までに提示される構文文法は、どのtoken列が正しいECMAScript ScriptまたはModuleとして受理されるかについての完全な説明ではありません。特定の追加のtoken列も受理されます。すなわち、特定の場所(line terminator文字の前など)にセミコロンが追加されていれば文法によって記述されるであろうものです。さらに、文法によって記述される特定のtoken列は、line terminator文字が特定の“扱いにくい”場所に現れる場合、受理可能とは見なされません。

特定の場合には、曖昧さを避けるため、構文文法は有効なECMAScript ScriptまたはModuleを形成しないtoken列を許す一般化された生成を使用します。たとえば、この技法はオブジェクトリテラルおよびオブジェクト分割代入パターンに使用されます。そのような場合、受理可能なtoken列をさらに制限する、より制約の強い補足文法が提供されます。通常、early error ruleは、特定の文脈で“p must cover an n”と述べます。ここでpはParse Node(一般化された生成のインスタンス)であり、nは補足文法の非終端です。これは以下を意味します:

  1. もともとpに一致したtokensの列が、ngoal symbolとして再度解析されます。nが文法パラメーターを取る場合、それらはpがもともと解析されたときに使用されたものと同じ値に設定されます。
  2. tokensの列が、tokensを残すことなく、nの単一のインスタンスとして解析できる場合:
    1. そのnのインスタンス(与えられたpに対して一意なParse Node)を、“pによってcoveredされるn”と呼びます。
    2. nおよびその導出生成に対するすべてのEarly Error rulesも、pによってcoveredされるnに適用されます。
  3. それ以外(解析が失敗した場合)は、early Syntax Errorです。

5.1.5 文法記法

5.1.5.1 終端記号

ECMAScript文法において、一部の終端記号はfixed-widthフォントで示されます。これらはsource textに書かれたとおり正確に現れるものです。この方法で指定されるすべての終端記号符号位置は、他のUnicode範囲の似た見た目の符号位置ではなく、Basic Latinブロックからの適切なUnicode符号位置として理解されます。終端記号内の符号位置は、\ UnicodeEscapeSequenceによって表現することはできません。

終端記号が個々のUnicode符号位置である文法(すなわち、字句文法、RegExp文法、および数値文字列文法)では、生成内に現れる複数のfixed-width符号位置の連続した並びは、独立した終端記号として書かれた同じ符号位置列の単純な省略形です。

たとえば、生成:

HexIntegerLiteral :: 0x HexDigits

は、次の省略形です:

HexIntegerLiteral :: 0 x HexDigits

対照的に、構文文法では、fixed-width符号位置の連続した並びは単一の終端記号です。

終端記号には、他に2つの形式があります:

  • 字句文法およびRegExp文法では、慣用的な印字表現を持たないUnicode符号位置は、代わりに“<ABBREV>”という形式で示されます。ここで“ABBREV”は、その符号位置または符号位置集合のためのニーモニックです。これらの形式は、Unicode Format-Control CharactersWhite Space、およびLine Terminatorsで定義されます。
  • 構文文法では、特定の終端記号(例:IdentifierNameおよびRegularExpressionLiteral)はイタリック体で示されます。これは、それらが字句文法内の同名の非終端を参照するためです。

5.1.5.2 非終端記号と生成

非終端記号はitalic体で示されます。非終端の定義(“production”とも呼ばれます)は、定義される非終端の名前の後に1つ以上のコロンを続けることで導入されます。(コロンの数は、その生成がどの文法に属するかを示します。)その後、非終端に対する1つ以上の代替右辺が続く行に示されます。たとえば、構文上の定義:

WhileStatement : while ( Expression ) Statement

は、非終端WhileStatementが、token while、左括弧token、Expression、右括弧token、Statementの順で構成されることを述べています。ExpressionおよびStatementの出現は、それ自体が非終端です。別の例として、構文上の定義:

ArgumentList : AssignmentExpression ArgumentList , AssignmentExpression

は、ArgumentListが単一のAssignmentExpressionを表す場合も、ArgumentListに続いてカンマ、その後にAssignmentExpressionが続くものを表す場合もあることを述べています。このArgumentListの定義は再帰的です。つまり、それ自身を用いて定義されています。その結果、ArgumentListは、カンマで区切られた任意の正の個数のargumentsを含むことができ、各argument expressionはAssignmentExpressionです。このような非終端の再帰的定義は一般的です。

5.1.5.3 任意記号

終端または非終端の後に現れることがある下付き接尾辞“opt”は、任意記号を示します。任意記号を含む代替は、実際には、任意要素を省略するものとそれを含むものの2つの右辺を指定します。これは、次が:

VariableDeclaration : BindingIdentifier Initializeropt

次の便利な省略形であることを意味します:

VariableDeclaration : BindingIdentifier BindingIdentifier Initializer

また、次が:

ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

次の便利な省略形であることも意味します:

ForStatement : for ( LexicalDeclaration ; Expressionopt ) Statement for ( LexicalDeclaration Expression ; Expressionopt ) Statement

これはさらに次の省略形です:

ForStatement : for ( LexicalDeclaration ; ) Statement for ( LexicalDeclaration ; Expression ) Statement for ( LexicalDeclaration Expression ; ) Statement for ( LexicalDeclaration Expression ; Expression ) Statement

したがって、この例では、非終端ForStatementは実際には4つの代替右辺を持ちます。

5.1.5.4 文法パラメーター

生成は、その生成によって定義される非終端記号の接尾辞として現れることがある、“[parameters]”という形式の下付き注釈によってパラメーター化されても構いません。“parameters”は、単一の名前またはカンマ区切りの名前のリストのいずれかです。パラメーター化された生成は、パラメーター名のすべての組み合わせを定義する生成の集合の省略形であり、各パラメーター名にはアンダースコアが前置され、パラメーター化された非終端記号に追加されます。これは、次が:

StatementList[Return] : ReturnStatement ExpressionStatement

次の便利な省略形であることを意味します:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement

また、次が:

StatementList[Return, In] : ReturnStatement ExpressionStatement

次の省略形であることも意味します:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement StatementList_In : ReturnStatement ExpressionStatement StatementList_Return_In : ReturnStatement ExpressionStatement

複数のパラメーターは組み合わせ的な数の生成を生み出しますが、そのすべてが完全な文法内で必ずしも参照されるわけではありません。

生成の右辺上の非終端への参照もパラメーター化できます。たとえば:

StatementList : ReturnStatement ExpressionStatement[+In]

は、次のように言うことと等価です:

StatementList : ReturnStatement ExpressionStatement_In

また:

StatementList : ReturnStatement ExpressionStatement[~In]

は、次と等価です:

StatementList : ReturnStatement ExpressionStatement

非終端参照は、パラメーターリストと“opt”接尾辞の双方を持つことができます。たとえば:

VariableDeclaration : BindingIdentifier Initializer[+In]opt

は、次の省略形です:

VariableDeclaration : BindingIdentifier BindingIdentifier Initializer_In

右辺の非終端参照でパラメーター名に“?”を前置すると、そのパラメーター値は現在の生成の左辺記号への参照におけるそのパラメーター名の出現に依存します。たとえば:

VariableDeclaration[In] : BindingIdentifier Initializer[?In]

は、次の省略形です:

VariableDeclaration : BindingIdentifier Initializer VariableDeclaration_In : BindingIdentifier Initializer_In

右辺の代替が“[+parameter]”で前置されている場合、その代替は、生成の非終端記号を参照する際にその名前付きパラメーターが使用された場合にのみ利用可能です。右辺の代替が“[~parameter]”で前置されている場合、その代替は、生成の非終端記号を参照する際にその名前付きパラメーターが使用されなかった場合にのみ利用可能です。これは、次が:

StatementList[Return] : [+Return] ReturnStatement ExpressionStatement

次の省略形であることを意味します:

StatementList : ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement

また、次が:

StatementList[Return] : [~Return] ReturnStatement ExpressionStatement

次の省略形であることも意味します:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ExpressionStatement

5.1.5.5 one of

文法定義内でコロンの後に“one of”という語が続く場合、それは後続の行または複数行上の終端記号の各々が代替定義であることを意味します。たとえば、ECMAScriptの字句文法には次の生成が含まれます:

NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9

これは単に次の便利な省略形です:

NonZeroDigit :: 1 2 3 4 5 6 7 8 9

5.1.5.6 [empty]

“[empty]”という句が生成の右辺として現れる場合、それはその生成の右辺が終端も非終端も含まないことを示します。

5.1.5.7 先読み制約

“[lookahead = seq]”という句が生成の右辺に現れる場合、それは直後に続く入力token列のprefixがtoken列seqである場合にのみ、その生成を使用できることを示します。同様に、“[lookahead ∈ set]”は、setがtoken列の有限の非空集合である場合、直後に続くtoken列のprefixがsetのいずれかの要素である場合にのみ、その生成を使用できることを示します。便宜上、その集合は非終端として書くこともでき、その場合、それはその非終端が展開され得るすべてのtoken列の集合を表します。その非終端が無限に多くの異なるtoken列へ展開され得る場合、それは編集上の誤りと見なされます。

これらの条件は否定できます。“[lookahead ≠ seq]”は、含まれる生成が、seqが直後に続く入力token列のprefixでない場合にのみ使用できることを示し、“[lookahead ∉ set]”は、setいずれの要素も直後に続くtoken列のprefixでない場合にのみ、その生成を使用できることを示します。

例として、次の定義が与えられた場合:

DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 DecimalDigits :: DecimalDigit DecimalDigits DecimalDigit

この定義:

LookaheadExample :: n [lookahead ∉ { 1, 3, 5, 7, 9 }] DecimalDigits DecimalDigit [lookahead ∉ DecimalDigit]

は、文字nに続いて1個以上の10進数字があり、その最初のものが偶数であるもの、または、別の10進数字が後続しない10進数字のいずれかに一致します。

これらの句が構文文法で使用される場合、後続のtokensを決定するには後の位置でどの字句goal symbolを使用するかを知る必要があるため、直後に続くtoken列を曖昧さなく識別できない場合があることに注意してください。そのため、これらが構文文法で使用される場合、使用する字句goal symbolsの選択によってseqが結果のtoken列のprefixであるかどうかが変わり得るならば、token列seqが先読み制約内(列集合の一部としての場合を含む)に現れることは編集上の誤りと見なされます。

5.1.5.8 [no LineTerminator here]

“[no LineTerminator here]”という句が構文文法の生成の右辺に現れる場合、それはその生成が制限された生成であることを示します。すなわち、示された位置で入力ストリーム内にLineTerminatorが発生する場合、その生成を使用してはなりません。たとえば、生成:

ThrowStatement : throw [no LineTerminator here] Expression ;

は、script内でthrow tokenとExpressionの間にLineTerminatorが発生する場合、その生成を使用してはならないことを示します。

LineTerminatorの存在が制限された生成によって禁止されていない限り、入力要素のストリーム内で任意の2つの連続するtokensの間に任意の数のLineTerminatorが現れても、scriptの構文上の受理可能性には影響しません。

5.1.5.9 but not

生成の右辺は、“but not”という句を使用し、その後に除外される展開を示すことで、特定の展開が許可されないことを指定できます。たとえば、生成:

Identifier :: IdentifierName but not ReservedWord

は、非終端Identifierが、IdentifierNameを置き換え得る任意の符号位置列であって、同じ符号位置列がReservedWordを置き換え得ないものによって置き換えられることを意味します。

5.1.5.10 説明句

最後に、いくつかの非終端記号は、すべての代替を列挙することが非実用的である場合に、sans-serif体の説明句によって記述されます:

SourceCharacter :: any Unicode code point

5.2 アルゴリズムの慣例

この仕様は、アルゴリズムのステップを指定するために番号付きリストをよく使用します。これらのアルゴリズムは、ECMAScript言語構造の要求される意味論を正確に指定するために使用されます。これらのアルゴリズムは、特定の実装技法の使用を暗示することを意図していません。実際には、与えられた機能を実装するために、より効率的なアルゴリズムが利用可能である場合があります。

アルゴリズムは、順序付きのカンマ区切りのalias名の列によって明示的にパラメーター化されても構いません。これらのalias名は、アルゴリズムステップ内でその位置に渡されたargumentを参照するために使用できます。任意パラメーターは、周囲の角括弧([ , name ])で示され、アルゴリズムステップ内では必須パラメーターと何ら異なりません。restパラメーターは、leading ellipsis(, ...name)で示され、パラメーターリストの末尾に現れても構いません。restパラメーターは、必須および任意パラメーターの後に提供されたすべてのargumentsをListへ取り込みます。そのような追加のargumentsがない場合、そのListは空です。

アルゴリズムステップは、順次的なサブステップへ細分化されても構いません。サブステップはインデントされ、それ自体もさらにインデントされたサブステップへ分割されても構いません。サブステップを識別するためにアウトライン番号付けの慣例が使用され、第一レベルのサブステップは小文字のアルファベット文字で、第二レベルのサブステップは小文字のローマ数字でラベル付けされます。3レベルを超える必要がある場合、これらの規則は繰り返され、第4レベルでは数値ラベルが使用されます。たとえば:

  1. トップレベルステップ
    1. サブステップ。
    2. サブステップ。
      1. サブサブステップ。
        1. サブサブサブステップ
          1. サブサブサブサブステップ
            1. サブサブサブサブサブステップ

ステップまたはサブステップは、そのサブステップを条件付ける“if”述語として書かれることがあります。この場合、サブステップは述語がtrueである場合にのみ適用されます。ステップまたはサブステップが“else”という語で始まる場合、それは同じレベルの直前の“if”述語ステップの否定である述語です。

ステップは、そのサブステップの反復適用を指定するために“For each”または“Repeat”で始まることがあります。

Assert:”で始まるステップは、そのアルゴリズムの不変条件を表明します。そのような表明は、そうでなければ暗黙であるアルゴリズム上の不変条件を明示するために使用されます。同様に、“NOTE:”で始まるステップは、近くのステップに関する関連する文脈を提供します。Assertion stepsおよびnote stepsは厳密に情報提供であり、追加の意味的要件を加えないため、実装によってチェックされる必要はありません。

アルゴリズムステップは、“Let x be someValue”という形式を使用して任意の値に名前付きaliasを宣言できます。これらのaliasは、xsomeValueの双方が同じ基礎データを参照し、どちらに対する変更も双方から見えるという点で参照のようなものです。この参照のような振る舞いを避けたいアルゴリズムステップは、右辺のコピーを明示的に作成するべきです:“Let x be a copy of someValue”はsomeValueの浅いコピーを作成します。

一度宣言されると、aliasは後続の任意のステップで参照できますが、aliasの宣言より前のステップから参照してはなりません。aliasは、“Set x to someOtherValue”という形式を使用して変更できます。

5.2.1 評価順序

複雑な式がアルゴリズムステップ内に現れる場合、それらは左から右、内側から外側の順序で評価されるものと理解されます。たとえば、ステップ

  1. A(B(), C.[[D]]) + E(F())を返す。

は次と等価です

  1. tmp1 をB()とする。
  2. tmp2 をC.[[D]]とする。
  3. tmp3 をA(tmp1, tmp2)とする。
  4. tmp4 をF()とする。
  5. tmp5 をE(tmp4)とする。
  6. tmp6tmp3 + tmp5とする。
  7. tmp6 を返す。

ここで、さまざまなtmpN aliasesは一時的なものであり、これらのステップ内でのみ見えます。

5.2.2 抽象操作

この仕様の複数の部分での使用を容易にするため、abstract operationsと呼ばれる一部のアルゴリズムは、名前付きで、パラメーター化された関数形式で書かれ、他のアルゴリズム内から名前によって参照できるようにされています。抽象操作は通常、OperationName(arg1, arg2)のような関数適用スタイルを使用して参照されます。一部の抽象操作は、class風の仕様抽象化のpolymorphically dispatched methodsとして扱われます。そのようなmethod風の抽象操作は通常、someValue.OperationName(arg1, arg2)のようなメソッド適用スタイルを使用して参照されます。

5.2.3 Syntax-Directed Operations

syntax-directed operationとは、名前付き操作であり、その定義はアルゴリズムから構成され、それぞれがECMAScript文法のいずれかの1つ以上の生成に関連付けられます。複数の代替定義を持つ生成は通常、各代替について別個のアルゴリズムを持ちます。アルゴリズムが文法生成に関連付けられる場合、それはその生成代替の終端および非終端記号を、あたかもアルゴリズムのパラメーターであるかのように参照できます。この方法で使用される場合、非終端記号は、source textを解析する際に一致した実際の代替定義を指します。文法生成またはそれから導出されたParse Nodeによって一致されたsource textとは、その一致に参加した最初の終端の開始から始まり、その一致に参加した最後の終端の終了で終わるsource textの部分です。

アルゴリズムが生成代替に関連付けられる場合、その代替は通常、“[ ]”文法注釈なしで示されます。そのような注釈は、その代替の構文認識にのみ影響するべきであり、その代替に関連付けられた意味論には影響しません。

Syntax-directed operationsは、以下のアルゴリズム内のステップ13、および4上の慣例を使用して、parse nodeと、任意で他のパラメーターとともに呼び出されます:

  1. statusSomeNonTerminalのSyntaxDirectedOperationとする。
  2. someParseNode を何らかのsource textのparseとする。
  3. someParseNode のSyntaxDirectedOperationを実行する。
  4. argument "value" 付きでsomeParseNode のSyntaxDirectedOperationを実行する。

明示的に別途指定されない限り、すべてのchain productionsは、その生成の左辺非終端に適用され得るすべての操作について暗黙の定義を持ちます。暗黙の定義は、同じ操作を、同じパラメーターがあればそれらとともに、chain productionの唯一の右辺非終端へ再適用し、その後結果を返すだけです。たとえば、あるアルゴリズムに“Return Evaluation of Block”という形式のステップがあり、次の生成があると仮定します:

Block : { StatementList }

しかしEvaluation操作がその生成とアルゴリズムを関連付けていない場合、そのときEvaluation操作は暗黙に次の形式の関連付けを含みます:

Runtime Semantics: Evaluation

Block : { StatementList }
  1. StatementListEvaluationを返す。

5.2.4 Runtime Semantics

runtimeで呼び出されなければならない意味論を指定するアルゴリズムは、runtime semanticsと呼ばれます。Runtime semanticsは、abstract operationsまたはsyntax-directed operationsによって定義されます。

5.2.4.1 Completion ( completionRecord )

The abstract operation Completion takes argument completionRecord (a Completion Record) and returns a Completion Record. Completion Recordが返されていることを強調するために使用されます。 It performs the following steps when called:

  1. Assert: completionRecordCompletion Recordである。
  2. completionRecord を返す。

5.2.4.2 Throw

アルゴリズムステップにおいて、“throw”という語は、ThrowCompletionを呼び出した結果を返すことの省略形です。たとえば、

  1. result.[[Error]]noneでないなら、result.[[Error]]をthrowする。

は次と等価です

  1. result.[[Error]]noneでないなら、ThrowCompletion(result.[[Error]])を返す。

特定の型の例外をthrowすると述べるアルゴリズムステップは、throwされるその型の例外を構築します。たとえば、

  1. TypeError例外をthrowする。

は次と等価です

  1. ThrowCompletion(newly created TypeError object)を返す。

5.2.4.3 Completion Recordsをアンラップするための省略形

Prefix “?”および“!”は、Completion Recordsをアンラップする省略形として使用されます。“?”は、abrupt completionを呼び出し元へ伝播するか、そうでなければnormal completionをアンラップするために使用されます。“!”は、Completion Recordがnormalであることを表明し、それをアンラップするために使用されます。形式的には、ステップ

  1. result を ? record とする。

は次と等価です

  1. Assert: recordCompletion Recordである。
  2. recordabrupt completionなら、record を返す。
  3. resultrecord.[[Value]]とする。

同様に、ステップ

  1. result を ! record とする。

は次と等価です

  1. Assert: recordnormal completionである。
  2. resultrecord.[[Value]]とする。

“?”または“!”が他の任意の文脈で使用される場合、この規則が適用できるようになるまで、まず評価順序で与えられる書き換えを適用し、その後この規則を適用します。たとえば、ステップ

  1. AO(? Other())を実行する。

は次のように書き換えることができます

  1. tmp1 をOther()とする。
  2. tmp2 を ? tmp1 とする。
  3. AO(tmp2)を実行する。

これはさらに次のように展開されます

  1. tmp1 をOther()とする。
  2. Assert: tmp1Completion Recordである。
  3. tmp1abrupt completionなら、tmp1 を返す。
  4. tmp2tmp1.[[Value]]とする。
  5. AO(tmp2)を実行する。

5.2.4.4 暗黙のNormal Completion

Completion Recordを返すと宣言されているabstract operations内のアルゴリズム、およびすべてのbuilt-in functions内では、返された値はまずNormalCompletionへ渡され、その結果が代わりに使用されます。この規則は、Completionアルゴリズム内、または返される値がそのステップでCompletion Recordとして明確にマークされている場合には適用されません。これらの場合は以下です:

Completion Recordがそのようなabstract operationから他の手段で返される場合、それは編集上の誤りです。たとえば、これらのabstract operations内では、

  1. true を返す。

は次のいずれとも同じ意味です

  1. NormalCompletion(true)を返す。

または

  1. completionNormalCompletion(true)とする。
  2. Completion(completion)を返す。

または

  1. Completion Record { [[Type]]: normal, [[Value]]: true, [[Target]]: empty }を返す。

?省略形の展開を通じて、次の例は許可されることに注意してください。展開後のステップ内では、abruptの場合にCompletionを適用した結果が直接返され、normalの場合にアンラップ後に暗黙のNormalCompletion適用が発生するためです。

  1. completion を返す。

次の例は、Completion Recordがそのステップで注釈されずに返されているため、編集上の誤りになります。

  1. completionNormalCompletion(true)とする。
  2. completion を返す。

5.2.5 Static Semantics

文脈自由文法は、入力要素のストリームが、評価され得る有効なECMAScript ScriptまたはModuleを形成するかどうかを定義するすべての規則を表現するには十分に強力ではありません。状況によっては、ECMAScriptアルゴリズム慣例または散文要件のいずれかを使用して表現され得る追加の規則が必要です。そのような規則は常に文法の生成に関連付けられ、その生成のstatic semanticsと呼ばれます。

Static Semantic Rulesには名前があり、通常はアルゴリズムを使用して定義されます。名前付きStatic Semantic Rulesは文法生成に関連付けられ、複数の代替定義を持つ生成は通常、適用可能な各名前付きstatic semantic ruleについて、各代替に対して別個のアルゴリズムを持ちます。

static semantic ruleの特別な種類は、Early Error Ruleです。Early error rulesは、特定の文法生成に関連付けられたearly error conditions(clause 17を参照)を定義します。ほとんどのearly error rulesの評価は、この仕様のアルゴリズム内で明示的に呼び出されません。適合実装は、ScriptまたはModuleの最初の評価の前に、そのScriptまたはModuleを解析するために使用された生成のすべてのearly error rulesを検証しなければなりません。early error rulesのいずれかが違反された場合、そのScriptまたはModuleは無効であり、評価できません。

5.2.6 数学演算

この仕様は、以下の種類の数値を参照します:

  • Mathematical values: デフォルトの数値型として使用される任意の実数。
  • Extended mathematical values: Mathematical valuesに+∞および-∞を加えたもの。
  • Numbers: IEEE 754-2019 binary64(二倍精度浮動小数点)値。
  • BigInts: 任意の整数を一対一対応で表すECMAScript言語値

この仕様の言語では、数値は下付き接尾辞を使用して異なる数値種別の間で区別されます。下付き文字𝔽はNumbersを指し、下付き文字はBigIntsを指します。下付き接尾辞のない数値はmathematical valuesを指します。この仕様はほとんどの数値を10進法で表します。また、0xに続いて0-9またはA-Fの数字が続く形式の数値を16進値として使用します。

一般に、この仕様が“the length of y”や“the integer represented by the four hexadecimal digits ...”などの句で数値を参照し、数値種別を明示的に指定しない場合、その句はmathematical valueを指します。NumberまたはBigInt値を指す句は、そのように明示的に注釈されます。たとえば、“the Number value for the number of code points in …”または“the BigInt value for …”です。

この仕様でintegerという用語が使用される場合、別途述べられない限り、それは整数の集合に属するmathematical valueを指します。この仕様でintegral Numberという用語が使用される場合、それは、そのmathematical valueが整数の集合に属する有限のNumber値を指します。

+, ×, =, ≥などの数値演算子は、オペランドの型によって決定されるそれらの演算を指します。mathematical valuesに適用される場合、演算子は通常の数学演算を指します。extended mathematical valuesに適用される場合、演算子は拡張実数上の通常の数学演算を指します。不定形は定義されず、この仕様でそれらを使用することは編集上の誤りと見なされるべきです。Numbersに適用される場合、演算子はIEEE 754-2019内の関連する演算を指します。BigIntsに適用される場合、演算子はBigIntのmathematical valueに適用される通常の数学演算を指します。混合型のオペランド(Numberとmathematical valueなど)に適用される数値演算子は定義されず、この仕様では編集上の誤りと見なされるべきです。

mathematical valuesとNumbersまたはBigIntsの間の変換は、この文書では常に明示的です。mathematical valueまたはextended mathematical value x からNumberへの変換は、“the Number value for x”または𝔽(x)と表され、6.1.6.1で定義されます。integer x からBigIntへの変換は、“the BigInt value for x”またはℤ(x)と表されます。NumberまたはBigInt x からmathematical valueへの変換は、“the mathematical value of x”、またはℝ(x)と表されます。+0𝔽および-0𝔽mathematical valueは、mathematical value 0です。非有限値のmathematical valueは定義されません。xextended mathematical value ofは、有限値についてはxmathematical valueであり、+∞𝔽および-∞𝔽についてはそれぞれ+∞および-∞です。NaNについては定義されません。

数学関数abs(x)は、x の絶対値を生成します。これは、x < 0であれば-xであり、それ以外ではx 自身です。

数学関数ln(x)は、x の自然対数を生成します。数学関数log10(x)は、x の10を底とする対数を生成します。数学関数log2(x)は、x の2を底とする対数を生成します。

数学関数min(x1, x2, … , xN)は、x1からxNまでのうち数学的に最小のものを生成します。数学関数max(x1, x2, ..., xN)は、x1からxNまでのうち数学的に最大のものを生成します。これらの数学関数の定義域と値域はextended mathematical valuesです。

記法“x modulo y”(y は有限かつ非ゼロでなければなりません)は、y と同じ符号(またはゼロ)を持つ値k を計算します。ここでabs(k) < abs(y) and x - k = q × yが何らかのinteger q について成り立ちます。

“the result of clamping x between lower and upper”という句(ここでxextended mathematical valueであり、lower およびupperlowerupperを満たすmathematical valuesです)は、x < lowerならlower を生成し、x > upperならupper を生成し、それ以外ではx を生成します。

数学関数floor(x)は、x より大きくない最大のinteger(+∞に最も近いもの)を生成します。

Note

floor(x) = x - (x modulo 1)

数学関数truncate(x)は、ゼロ方向に丸めることでx の小数部分を取り除き、x < 0なら-floor(-x)を生成し、それ以外ではfloor(x)を生成します。

数学関数minmaxabsfloor、およびtruncateはNumbersおよびBigIntsについて定義されず、非mathematical value argumentsを持つそれらのメソッドの任意の使用は、この仕様では編集上の誤りとなります。

下限a から上限b までのintervalは、同じ数値型の数値の、無限であり得る、空であり得る集合です。各境界はinclusiveまたはexclusiveのいずれかとして記述されますが、両方ではありません。intervalには以下の4種類があります:

  • a(inclusive)からb(inclusive)までのinterval、別名inclusive interval from a to bは、同じ数値型のすべての値x であって axbを満たすものを含み、それ以外を含みません。
  • a(inclusive)からb(exclusive)までのintervalは、同じ数値型のすべての値x であって ax < bを満たすものを含み、それ以外を含みません。
  • a(exclusive)からb(inclusive)までのintervalは、同じ数値型のすべての値x であって a < xbを満たすものを含み、それ以外を含みません。
  • a(exclusive)からb(exclusive)までのintervalは、同じ数値型のすべての値x であって a < x < bを満たすものを含み、それ以外を含みません。

たとえば、1(inclusive)から2(exclusive)までのintervalは、1と2の間のすべてのmathematical valuesからなり、1を含み、2を含みません。intervalを定義する目的では、-0𝔽 < +0𝔽です。したがって、たとえば下限が+0𝔽であるinclusive interval+0𝔽を含みますが、-0𝔽は含みません。NaNintervalに決して含まれません。

5.2.7 値記法

この仕様では、ECMAScript言語値boldで表示されます。例にはnulltrue、または"hello"が含まれます。これらは、Function.prototype.applylet n = 42;などのECMAScript source textと区別されます。

5.2.8 同一性

この仕様では、仕様値とECMAScript言語値の双方が等価性について比較されます。等価性について比較する場合、値は2つのカテゴリのいずれかに分かれます。同一性を持たない値は、それらの生得的な特性がすべて同じである場合、他の同一性を持たない値と等しいです。特性とは、integerの大きさや列の長さなどです。同一性を持たない値は、その特性を完全に記述することで、事前の参照なしに明示できます。対照的に、各同一性を持つ値は一意であり、したがって自分自身にのみ等しいです。同一性を持つ値は、同一性を持たない値に似ていますが、同一性と呼ばれる追加の推測不能で変更不能で全世界的に一意な特性を持ちます。既存の同一性を持つ値への参照は、単にそれらを記述することでは明示できません。同一性そのものが記述不能であるためです。代わりに、これらの値への参照は、ある場所から別の場所へ明示的に渡されなければなりません。一部の同一性を持つ値はmutableであり、そのためその特性(同一性を除く)をin-placeで変更でき、その値を保持するすべてのものが新しい特性を観測することになります。同一性を持たない値は、同一性を持つ値と決して等しくありません。

この仕様の観点から、2つの値を等価性について比較するために、“If bool is true, then ...”のように“is”という語が使用され、等価性比較を使用してリスト内部の値を検索するために、“If list contains a Record r such that r.[[Foo]] is true, then ...”のように“contains”という語が使用されます。値のspecification identityはこれらの比較の結果を決定し、この仕様では公理的なものです。

ECMAScript言語の観点から、言語値はSameValue抽象操作およびそれが推移的に呼び出す抽象操作を使用して等価性について比較されます。これらの比較抽象操作のアルゴリズムは、ECMAScript言語値language identityを決定します。

仕様値について、specification identityを持たない値の例には、mathematical valuesおよびextended mathematical valuesECMAScript source textsurrogate pairsDirective Prologuesなど、UTF-16 code units、Unicode code points、enumsabstract operationssyntax-directed operationshost hooksなどを含む)、およびordered pairsが含まれますが、これらに限定されません。specification identityを持つ仕様値の例には、Property DescriptorsPrivateElementsなどを含む任意の種類のRecordsParse NodesListsSetsおよびRelationsAbstract ClosuresData BlocksPrivate Namesexecution contextsおよびexecution context stacksagent signifiers、ならびにWaiterList Recordsが含まれますが、これらに限定されません。

Specification identityは、Symbol.forによって生成されたSymbol valuesを除くすべてのECMAScript言語値についてlanguage identityと一致します。specification identityもlanguage identityも持たないECMAScript言語値は、undefinednullBooleansStringsNumbers、およびBigIntsです。specification identityとlanguage identityを持つECMAScript言語値は、SymbolsのうちSymbol.forによって生成されていないもの、およびObjectsです。Symbol.forによって生成されたSymbol valuesはspecification identityを持ちますが、language identityは持ちません。