関数

この章では、スクリプトにおける関数の呼出しの動作を定義する。

関数として呼出し可能なオブジェクト

スクリプトで扱われるオブジェクトには、関数として呼出し可能なものと そうでないものとがある。 両者の区別は、スクリプトプログラムから直接行うことはできない。

オブジェクトが関数として呼出し可能であるかどうかは、 そのオブジェクトについて不変である。また、関数として呼出し可能なオブジェクトが 関数として呼び出されたときの処理も、そのオブジェクトについて不変である。

関数オブジェクトとは、初期の Function のインスタンスであって、関数として呼出し可能なもの のことである。

arity プロパティの値が整数 x を表す Integer オブジェクトであるような関数オブジェクトを単にx-ary 関数オブジェクトという。メソッドについても、その値の関数オブジェクトの arity プロパティの値に関して同様にx-ary メソッドという。

関数生成式を評価すると、 新しい関数オブジェクトを生成する。しかし、必ずしも全ての関数オブジェクトが 関数生成式によって生成されたものであるとはいえない。 また、関数として呼出し可能なオブジェクトが全て関数オブジェクトである わけでもない。

関数の呼出し

関数として呼出し可能なオブジェクトが関数として呼出されるとき、 次のものが渡される:

@this 値
一つのオブジェクト
引数
任意の個数のオブジェクト (0 個でもよい)

関数が呼出されたときに行われる具体的な処理の内容は、 呼出された関数によって決まる。

関数の呼出しの結果は、必ず正常終了またはエラー終了のどちらか一方の結果である。 呼出しの結果が正常終了の場合は、結果の値はオブジェクトに限らない (すなわち、結果の値に参照が含まれていてもよい)。 呼出しの結果がエラー終了の場合は、結果の値は常にオブジェクトである。

関数の呼出しで渡される引数が複数のオブジェクトであるとき、 そのオブジェクトの順序は意味を持つ。

関数生成式によって生成される関数

関数生成式は、評価するたびに 新しい関数オブジェクトを生成し、それを値とする正常終了の結果を返す。 この関数オブジェクトは、次の内部メンバを持つ。

params
これは、0 個以上の識別子の原始リストである。関数生成式に IdentifierList が含まれる場合、params はそれらの識別子全てからなる原始リストである。 関数生成式に IdentifierList が含まれない場合、params は 0 個の識別子からなる原始リストである。
body
これは、関数生成式の Block 構成要素である。
context
これは、関数生成式が評価されるときの実行コンテクストである。

またこの関数オブジェクトは、次のプロパティを持つ。

arity
内部メンバ params に含まれる識別子の個数を表す Integer オブジェクト。その表す値は 0 以上である。

この関数オブジェクトが関数として呼出されると、次の処理を行う。ここで、p1, …, pn は関数オブジェクトの params 内部メンバに含まれる各識別子 (n は識別子の個数)、a1, …, am は関数の呼出しにおいて渡された各引数オブジェクト (m は引数オブジェクトの個数) である。

  1. 新しいオブジェクトを作成し、それを d とする。 この時点では、このオブジェクトは ($prototype 内部メンバを含めて) 一切メンバ・内部メンバを持たない。
  2. 新しい実行コンテクストを作成し、これを c とする。この実行コンテクストが持つ情報を以下のように設定する。
    変数領域
    オブジェクト d
    @this 値
    関数呼出しにおいて @this 値として渡されたオブジェクト
    デフォルトの精度
    現在の実行コンテクストに同じ
    親実行コンテクスト
    この関数オブジェクトの context 内部メンバの値
  3. オブジェクト d$callee という名前のメンバを作成し、値にこの関数オブジェクトを設定する。
  4. 初期の List.of を関数として呼出す。呼出しの際に渡す @this 値は初期の Void.void、引数は a1, …, am である。呼出しの結果が正常終了でなければ、その結果をそのまま返す。 呼出しの結果が正常終了ならば、d$args という名前のメンバを作成し、その値に呼出しの結果の値を設定する。
  5. i = 1, …, n について、i = 1 から i = n まで順番に次の処理を行う:
    1. オブジェクト d に、識別子 pi を名前とするメンバを作成し、そのメンバの値を以下のように設定する:
      im の場合
      ai
      i > m の場合
      初期の Void.void
  6. 現在の実行コンテクストを c に変更する。
  7. この関数オブジェクトの body 内部メンバである Block を実行し、その結果を r とする。
  8. 現在の実行コンテクストを、元に戻す。
  9. 以下の結果を関数呼出しの結果として返す。
    r が正常終了または復帰終了の場合
    r の値を値とする正常終了
    r がエラー終了の場合
    r
    r が break 終了または continue 終了の場合
    新しい SyntaxError のインスタンスを値とするエラー終了

文法エラーの早期発見

実行環境は、文法解析において、関数オブジェクトの body 内部メンバである Block を実行した結果が break 終了または continue 終了となりうるようなコードに遭遇した場合は、文法エラーとしてもよい。

© 2006-2007 Magicant