MikoScript3 言語仕様

 スコープ

●スコープとは
 「スコープ」とは、本言語では、箱の名前(箱名)が通用する範囲を意味します。箱が
スコープ内にあるということは、その箱の名前が、そのスコープ内で通用するということ
です。そのため、スコープは「箱名空間」とも言えます。

 「箱を入れる箱」の中に入っている箱の名前は、その「箱を入れる箱」内で通用します。
つまり、「箱を入れる箱」は、スコープを持つということになります。本言語において、
スコープを持つのは「箱を入れる箱」だけです。従って、スコープも「箱の概念」に組み
込まれています。

 箱の名前が通用するということは、そのスコープが存在するということです。つまり、
その名前の箱が入っている「箱を入れる箱」が存在するということです。ということは、
一番外側の「箱を入れる箱」では、その名前が通用するスコープが存在しないということ
になります。通常、最外の箱には名前がありません。後述の「システムスコープ」がこれ
に相当します。一方、一般の箱には必ず名前があり、どこかのスコープ内にあります。

 「箱を入れる箱」の中に直接入っている箱は、「直属スコープ」にあると言います。
一方、その「箱を入れる箱」の中にさらに「箱を入れる箱」があって、その中に含まれて
いる箱や、それよりも深いところに含まれている箱は、「直属スコープ」にあるとは言い
ません。

 「箱を入れる箱」の中に実際に含まれている箱は、「直属スコープ」であってもなくても、
「直系スコープ」にあると言います。一方、その「箱を入れる箱」の中に実際に含まれて
いるのではなく、その箱に追加されたスコープ内に含まれている箱は、「追加スコープ」に
あると言います。なお、スコープの追加に関しては、後に詳しく述べます。

 スコープには、一般の「箱を入れる箱」内のスコープと、以下のような本言語システム
固有の「システムスコープ」があります。
    ・グローバルスコープ
    ・関数ローカルスコープ
    ・モジュールローカルスコープ
    ・スレッドローカルスコープ
    ・関数スタティックスコープ
    ・メンバースコープ
これらに関しては、本章の後節で詳説します。

●一般の「箱を入れる箱」内のスコープ
 一般に、「箱 A 内のスコープに 箱 B がある」という場合、箱 A と箱 B の関係は、
以下のうちのいずれかになります。
    ・箱 A 自身の「直属スコープ」内に箱 B がある
    ・箱 A 自身の「追加スコープ」内に箱 B がある
    ・箱 A の参照先の箱の「直属スコープ」内に箱 B がある
    ・箱 A の参照先の箱の「追加スコープ」内に箱 B がある

いずれの場合でも、「箱 A 内のスコープにある箱 B 」は、二項演算子 . または :: を
使って、以下のように表記します。
        A.B
        A::B
この演算子に関しては、「演算子」の章の「スコープ規定演算子」で説明しています。

●スコープの追加
 「箱を入れる箱」には、別の「箱を入れる箱」のスコープを追加することができます。
それには、システム組み込みのリレー型関数 'AddScope または、'inherit を使います。
例えば、
    X.A = 1;
    Y.B = 2;
とした場合、箱 X 内のスコープに箱 A があり、箱 Y 内のスコープに箱 B がありますが、
箱 X 内のスコープに、箱 B はありません。ここで、
    X'AddScope( Y );
    X'inherit( Y );
のどちらかを実行すると、箱 X 内のスコープに、箱 Y 内のスコープが追加されます。
これによって、箱 X 内のスコープから、箱 Y 内のスコープにある箱が見えるように
なります。この時、
    X.B
    X::B
は、どちらも、箱 X 内のスコープから見た、箱 Y の中にある箱 B です。本件の場合、
この値は、2 になります。このようになるのは、単にスコープの追加であって、決して
箱の実体が複製または移動されているわけではありません。また、箱 X が箱 B の直属
スコープになっているわけでもありません。

 基本的に、'AddScope も 'inherit もその用途は任意ですが、'AddScope は、関数の
ローカルスコープに別のスコープを追加する時などに使います。また、'inherit は主に、
動的な「クラスの継承」などに使います。これらの詳細は、関連各所で説明しています。

 さて、'AddScope で追加したスコープ内にある既存の箱へのアクセスは、読み出し
でも書き込み(代入など)でも、直属スコープ内の箱と同様に行なえます。例えば、
先ほどの続きで、
    X.B = -2;
とすると、実際には、Y.B に -2 が代入されます。

 一方、'inherit で追加したスコープ内にある既存の箱への読み出しのアクセスは、
直属スコープ内の箱と同様に行なえますが、代入などの書き込みアクセスは、直接的
には行なえません。例えば、先ほどと同様に、
    X.B = -2;
とすると、箱 X の直属スコープ内に箱 B が新規に生成されて、そこへ代入されます。
このとき、Y.B の箱は、そのまま存続しています。

 なお、書き込みアクセスを行なう演算子には、具体的には、以下があります。
  ・代入( =  :=  <- )
  ・算術代入演算 ( +=  -=  *=  /=  %=  &=  ^=  |=  <<=  >>= )
  ・単項増減演算 ( ++  -- )
  ・delete
これらの演算子を使って、通常の直接的な操作では、'inherit で追加したスコープ内
にある既存の箱を変更することはできません。 'AddScope で追加したスコープ内なら
できます。

 このような制約を設けているのは、'inherit の主用途である「クラスの継承」では、
基底クラスのメンバーを、その導出クラスやインスタンスのメンバー関数内の通常の
操作では変更できないようにするためです。

 ちなみに、'inherit で追加したスコープ内にある既存の箱へ、追加したスコープを
通して直接代入したい時は、例えば、次のようにすればできます。
    [ X.B'ref ] = -2;
あるいは、次のように、その箱への「参照」を介せばアクセスできます。
    R := X.B;
    R = -2;

 なお、Ver.2.00 未満では、'AddScope も 'inherit と同じ動作になっていたので、
ご注意ください。

 代入先の箱が、直属スコープ内にも、追加スコープ内にもない場合、その箱は、
直属スコープ内に新規生成されます。例えば、上記の続きで、
    X.New = 3;
とすると、箱 X 内に箱 New が新規に生成されて、そこへ 3 が代入されます。

 追加されたスコープの中に、直属スコープ内にある箱と同じ名前の箱がある場合、
直属スコープ内にある箱の方がが優先されます。例えば、先程の箱 Y の中に箱 A が
あった場合、
    X.A
    X::A
は、箱 Y の中の箱 A ではなく、箱 X の中の箱 A になります。

 追加するスコープの数には特に制限はありません。例えば、上記の箱 X に、さらに、
箱 Z のスコープを追加することができます。その場合も同様に、
    X'AddScope( Z );
を実行します。箱 Z の中に箱 C があったとすると、
    X.C
    X::C
は、箱 X から見た箱 Z の中の箱 C になります。

 追加されたスコープの中に同じ名前の箱があると、先に追加されたスコープのほうが、
後で追加されたスコープよりも優先されます。例えば、先程の箱 Z の中に箱 B があった
場合、
    X.B
    X::B
は、後で追加された箱 Z 内のスコープの箱 B ではなく、先に追加されている箱 Y 内の
スコープの箱 B になります。

 スコープの追加は、同時に複数可能です。例えば、箱 X に、箱 Y と箱 Z のスコープ
を追加する場合、
    X'AddScope( Y, Z );
とすることができます。

 リレー型関数 'AddScope の返値は、正常に追加したスコープの数になります。例えば、
上例の X'AddScope( Y ) の返値は 1 で、X'AddScope( Y, Z ) の返値は 2 になります。
もし、引数の数よりも、返値のほうが小さい場合、引数のうちのどれかが、スコープに追
加できていないことになります。例えば、リレー型関数 'AddScope の対象の箱(上例で
は箱 X )が、「箱を入れる箱」でない場合、スコープを追加できないので、返値は 0 に
なります。

 リレー型関数 'AddScope で、既に追加済みのスコープを再度追加しても、また、自分
自身のスコープを追加しても、無効です。但し、その場合のスコープは、返値のカウント
に含まれます。例えば、上例の続きで、
    X'AddScope( Y );
    X'AddScope( X );
を実行しても無効ですが、返値は 1 になります。

 スコープが追加されている箱のスコープが追加されると、その箱自身のスコープだけで
なく、その箱に追加されていたスコープも追加されます。たとえば、箱 X の中に箱 A が
あり、箱 Y の中に箱 B があり、箱 Z の中に箱 C があって、
    X'AddScope( Y, Z );
で、箱 X に箱 Y と箱 Z のスコープが追加されている状態で、箱 W に箱 X のスコープを
    W'AddScope( X );
として追加すると、箱 W から箱 X の中が見えるようになり、箱 X の中から、箱 Y と
箱 Z の中が見えるようになっているので、
    W.A,  W.B,  W.C
は、それぞれ、箱 W から見た、箱 X の中の箱 A、箱 Y の中の箱 B、箱 Z の中の箱 C
になります。

 このように、追加されたスコープに、さらに別のスコープが追加されている場合も、
スコープの優先度は、基本的には、前述の通りで、
    ・元の箱のスコープ(直属スコープ)が最優先
    ・追加されたスコープは、先に追加された方が優先
となります。ただし、先に追加されたスコープに追加されているスコープは、後で追加さ
れたスコープよりも優先されます。例えば、上記の例の続きで、
    W'AddScope( S );
として、箱 W に、さらに別の箱 S のスコープを追加した場合、箱 W のスコープの優先
度は、
    箱 W, 箱 X, 箱 Y, 箱 Z, 箱 S
のスコープの順になります。

 スコープの追加がリング状になる場合があります。例えば、箱 A, 箱 B, 箱 C が、
箱を入れる箱であるとして、
    A'AddScope( B );
    B'AddScope( C );
    C'AddScope( A );
を実行すると、各箱に追加されたスコープは、リング状になります。さらに、一般的には、
網状に、スコープを追加することもできます。しかし、追加された各スコープが、どのよ
うな構成であっても、同じスコープが2回以上対象になることはありません。

 追加されているスコープの箱が削除された場合、そのスコープは自動的に消滅します。
例えば、
    X'AddScope( Y );
で、箱 X に箱 Y のスコープが追加されている状態で、
    delete Y;
が実行されると、箱 X に追加されていた箱 Y のスコープは自動的に消滅します。

●スコープの削除
 リレー型関数 'AddScope または 'inherit で追加されたスコープは、リレー型関数 
'DelScope または 'disherit で削除できます。例えば、
    X'AddScope( A, B );
    X'inherit( A, B );
のどちらかで、箱 X に 箱 A と 箱 B のスコープが追加されますが、これらは、
    X'DelScope( A, B );
    X'disherit( A, B );
のどちらかで削除できます。これは、単に追加されていたスコープが削除されるだけで、
箱の実体が削除されるわけではありません。

 リレー型関数 'DelScope と 'disherit の返値はどちらも、正常に削除したスコープの
数になります。もし、引数の数よりも、返値のほうが小さい場合、引数のうちのどれかの
スコープが、正常に削除できていないことになります。

 なお、'AddScope と 'inherit の動作は、前述のように若干異なりますが、'DelScope 
と 'disherit の動作は、現状、まったく同じです。スコープの追加/削除を行なう際に、
'AddScope に対しては 'DelScope、また、'inherit に対しては 'disherit のペアで使う
のが意味的に整合しています。

●参照によるスコープの規定
 箱 A 内のスコープに箱 B がある場合、箱 R に箱 A への「参照」を設定すると、箱 R 
から、箱 A 内のスコープにアクセスできます。例えば、
    A.B = 1;        // 箱 A の中に箱 B を生成し、整数値 1 を代入
    R := A;         // 箱 R に箱 A への参照を設定
を実行すると、R::B と R.B は、どちらも、箱 A の中の箱 B を示します。

また、例えば、
    A.X = 1;        // 箱 A の中に箱 X を生成し、整数値 1 を代入
    B.Y = 2;        // 箱 A の中に箱 Y を生成し、整数値 2 を代入
    A'AddScope(B);  // 箱 A に箱 B のスコープを追加
    R := A;         // 箱 R に箱 A への参照を設定
を実行すると、
    R::X は、箱 A の中の箱 X を示し、
    R::Y は、箱 B の中の箱 Y を示します。
    R.X と R.Y も同様です。

 なお、慣習上、厳格な制限はありませんが、参照によってスコープを規定する場合には、
スコープ規定二項演算子として、. ではなく :: を使います。これに関しては、「演算子」
の章の「スコープ規定演算子」で説明しています。また、参照に関しては、「参照」の章
で詳しく説明します。


●システムスコープ
 本言語には、各種の「システムスコープ」があります。これらのシステムスコープ内に
ある箱は、その箱名の前に所定の前置演算子を付けることによって、特定できます。この
種の前置演算子が付かない場合、その箱のスコープは、デフォールトスコープになります。
この関係を以下に示します。
    ::箱名      グローバルスコープ
     .箱名      メンバースコープ
     ^箱名      モジュールローカルスコープ
     $箱名      スレッドローカルスコープ
     @箱名      関数スタティックスコープ
      箱名      デフォールトスコープ
例えば、::ABC は、グローバルスコープ内の ABC という名前の箱を示します。また、
.XYZ は、メンバースコープ内の XYZ という名前の箱を示します。

 システムスコープに関しては、以下で説明します。また、システムスコープを規定する
前置演算子に関しては、「演算子」の章の「スコープ規定演算子」で説明しています。

●グローバルスコープ
 グローバルスコープは、どのスレッドの、どの関数からでも、共通にアクセスできる広
域のスコープで、本言語システム内にただ1つだけ存在します。グローバルスコープは、
本言語システムの開始時に生成され、本言語システムが終了するまで存続します。グロー
バルスコープ内の箱は、その箱名の前に、:: 演算子を付けることによって、特定されま
す。例えば、グローバルスコープ内の A という名前の箱は、::A となります。

 グローバルスコープには、あらかじめ、本言語システムで共通に使用する各種の箱、た
とえば、File クラス箱、Buffer クラス箱、Math 数学関数箱、DLL クラス箱などが、格納
されています。(これらの詳細は、関連各所で述べています。)

 各関数、各モジュール、各スレッドで固有の箱は、できる限り、それぞれのローカルス
コープに格納するようにして、グローバルスコープには、共通に使用する箱だけを格納す
るようにします。また、グローバルスコープには、上述のように、あらかじめ本言語シス
テム共通の箱が組み込まれているので、箱の名前が、重複しないように注意する必要があ
ります。

●デフォールトスコープ
 システムスコープを規定する前置演算子が箱名に付かない場合(つまり箱名だけの場合)、
それはデフォールトスコープになります。デフォールトスコープの箱は、次の各スコープ
内から順に検索され、最初に見つかった箱が対象になります。
  (1)関数ローカルスコープ
  (2)モジュールローカルスコープ
  (3)グローバルスコープ

もし、この3つのどのスコープ内にも見つからなければ、次のようになります。
 ・対象の箱への読み出しアクセスの場合、例外が発生します。
 ・対象の箱への書き込み(代入)アクセスの場合、関数ローカルスコープに、その箱が、
   新規に生成されます。

 例えば、 A = B;  という代入では、箱 A と箱 B には、システムスコープを規定する
前置演算子が付いていないので、両者のスコープは、デフォールトスコープになります。
右辺の箱 B は、読み出しアクセスなので、上記の3つのスコープから順に検索されます。
まず、関数ローカルスコープが検索されて、そこに B という名前の箱があれば、その箱
が対象になります。もしなければ、次に、モジュールローカルスコープが検索されて、見
つかれば、その箱が対象になります。もしなければ、最後に、グローバルスコープが検索
されて、見つかれば、その箱が対象になります。もし、どのスコープにもなければ、例外
処理の対象になります。もし、B という名前の箱が、関数ローカルスコープとグローバル
スコープの両方にあれば、先に見つかる関数ローカルスコープ内の箱が対象になります。
一方、左辺の箱 A は、代入先なので、書き込みアクセスになります。この場合、同様に
3つのスコープから順に検索されて、最初に見つかった箱へ代入されます。もし、どの
スコープ内にも A という箱が見つからなければ、関数ローカルスコープ内に、箱 A が
新規生成されて、そこへ代入されます。

 以上が基本ですが、若干の例外があります。それは、前述のように、'inherit で追加
されたスコープ内の箱へは、書き込み(代入)アクセスができないからです。そのような
場合、関数ローカルスコープ内にその箱が新規に生成されて、そこへ代入されます。

 例えば、上記の  A = B;  という代入で、箱 A が 'inherit で追加されたスコープ内
で最初に見つかった場合、その箱には代入できないので、関数ローカルスコープ内に、
箱 A が新規生成されて、そこへ代入されます。

 なお、メンバースコープ、スレッドローカルスコープ、関数スタティックスコープは、
デフォールトスコープに含まれていません。そのため、これらのスコープにアクセスする
には、所定のスコープ規定前置演算子を、常に付ける必要があります。

●関数ローカルスコープ
 関数ローカルスコープは、現在実行中の関数内でのみ有効な局所的スコープで、関数が
コールされた時に自動的に生成され、その関数がリターンする時に、自動的に消滅します。
その消滅の際には、その中の箱が全て破棄されます。関数ローカルスコープ内の箱は、そ
の箱名の前に、スコープ規定演算子を付けずに、箱名だけで特定されます。関数に渡され
る引数は、関数ローカルスコープに格納されます。

例えば、以下の関数 F
    function F( P )
    {
        L = 1;
        ::M = 2;
        ・・・・・・
    }
の実行では、関数ローカルスコープに、引数の箱 P と、1 が代入された箱 L が、生成さ
れます。また、グローバルスコープに、箱 M が生成されます。この関数のリターンの際
に、その関数ローカルスコープが破棄されるので、その中の箱 P と箱 L も破棄されます。
一方、グローバルスコープは、依然存続するので、その中の箱 M は存続します。

 関数ローカルスコープは、各実行中の関数ごとに個別に割当てられているので、各関数
ローカルスコープ内の箱は、同じ名前であっても、実体は全く別々に存在し、相互の干渉
はありません。

例えば、上記の関数 F に加えて、以下の関数 G と関数 H があるとします。
    function G( P )
    {
        L = 2;
        F( "a" );
        ・・・・・・
    }
    function H( P )
    {
        L = 3;
        G( "b" );
        ・・・・・・
    }
ここで、
    H( "c" );
を実行すると、関数 H が引数 "c" でコールされます。関数 H は、箱 L に 3 を代入し
てから、関数 G を引数 "b" でコールします。関数 G は、箱 L に 2 を代入してから、
関数 F を引数 "a" でコールします。関数 F は、箱 L に 1 を代入します。さて、この
時点で、P という名前の箱と、L という名前の箱は、関数 F, G, H のそれぞれの関数
ローカルスコープに、個別に存在しています。ちなみに、各 P の箱には、それぞれ、"a",
 "b", "c" の文字列が入っていて、各 L の箱には、それぞれ、1, 2, 3 の整数値が入っ
ています。以降、関数 F からリターンした直後には、関数 F の箱 P と箱 L は消滅して
いますが、関数 G と関数 H のそれぞれの箱 P と箱 L は存続しています。また、関数 G
 からリターンした直後には、関数 G の箱 P と箱 L は消滅していますが、関数 H の箱 
P と箱 L が存続しています。その後、関数 H からリターンする時点で、関数 H の箱 P 
と箱 L が消滅します。

●モジュールローカルスコープ
 モジュールローカルスコープは、各「モジュール」ごとに割当てられるスコープで、
そのモジュール内で定義されている関数だけが、アクセスできます。モジュールローカル
スコープは、モジュールのロード時に生成され、そのモジュールがアンロードされる時に
破棄されます。その破棄の際には、その中の箱は全て破棄されます。モジュールローカル
スコープ内の箱は、その箱名の前に、^ 演算子を付けることによって、特定されます。
例えば、モジュールローカルスコープ内の A という名前の箱は、^A となります。

 モジュールローカルスコープは、そのモジュール内で定義されている各関数の間で共通
にアクセスする箱を格納するのに使います。また、その箱は、他のモジュール内で定義さ
れている関数からは見えないので、箱名の競合を気にする必要はありません。

●スレッドローカルスコープ
 スレッドローカルスコープは、各スレッドごとに割当てられるスコープで、そのスレッ
ドの関数だけが、アクセスできます。スレッドローカルスコープは、スレッドの起動時に
生成され、そのスレッドが終了する時に破棄されます。その破棄の際には、その中の箱も
全て破棄されます。スレッドローカルスコープ内の箱は、その箱名の前に、$ 演算子を付
けることによって、特定されます。たとえば、スレッドローカルスコープ内の A という
名前の箱は、$A となります。
 プログラム実行時のエラーコードやエラー情報は、このスレッドローカルスコープ内に
格納されます。

●関数スタティックスコープ
 関数スタティックスコープは、各関数ごとに割当てられるスコープで、その関数だけが、
アクセスできます。関数スタティックスコープは、その関数が定義されているモジュール
のロードに伴って、その関数が登録される時に、生成されます。また、関数スタティック
スコープは、その関数が定義されているモジュールのアンロードに伴って、その関数が抹
消される時に、破棄されます。その破棄の際には、その中の箱が全て破棄されます。

 関数スタティックスコープ内の箱は、その箱名の前に、@ 演算子を付けることによって、
特定されます。例えば、関数スタティックスコープ内の A という名前の箱は、@A となり
ます。

 関数スタティックスコープは、関数ローカルスコープとは違い、関数をリターンした時
も、存続します。そのため、その関数が再度コールされた時にも、前回のデータがそのま
ま残っています。

●メンバースコープ
 メンバースコープは、以下のどれかになります。
    ・現実行中の関数が見つかったスコープ
    ・構造体/クラスの設定対象になっている箱内のスコープ
    ・scope 構文で規定されている箱内のスコープ

 関数実行時のメンバースコープは、一般に、その関数が見つかったスコープになります。
オブジェクトのメンバー関数は、通常、そのオブジェクト内のスコープで見つかるので、
そのオブジェクト内がメンバースコープになります。グローバルスコープで見つかった
関数は、グローバルスコープがメンバースコープになります。また、モジュールローカル
スコープで見つかった関数は、そのモジュールローカルスコープが、メンバースコープに
なります。
 但し、構造体/クラスの設定ブロック内では、その対象の箱内が、メンバースコープに
なります。また、scope 構文のブロック内では、その対象の箱内が、メンバースコープに
なります。
 なお、構造体とクラスに関しては、「構造体」と「クラスとインスタンス」の各章で、
詳しく説明します。また、scope 構文に関しては、次節で説明します。

 メンバースコープ内の箱は、その箱名の前に、ピリオッド「.」演算子を付けることに
よって特定します。例えば、メンバースコープ内の A という名前の箱は、.A となります。
また、現メンバースコープを指す this という予約語を使って、this.A と表記すること
もできます。

●メンバースコープの scope 構文による規定
 メンバースコープを、特定のブロック内で、一時的に別のスコープに変更するには、
以下の scope 構文を使います。
    scope X
    {
        このブロックの中で、メンバースコープが、
        一時的に X のスコープに変更される
    }
ここで、X は、スコープを持つ既存の箱であれば、任意の箱が指定できます。

 scope 構文のブロック内で規定されるのは、メンバースコープだけです。つまり、箱名
の前に . 演算子が付いた箱が属するスコープだけです。デフォールトスコープやグロー
バルスコープ等には、影響しません。scope 構文のブロック内で、this は、そのメン
バースコープの箱(上記の X の箱)を指します。

以下に、scope 構文を使った例を示します。
    ::U.V1 = 1;     // グローバルスコープ内の箱 U の中の箱 V1 に 1 を代入
    scope ::U       // メンバースコープをグローバルスコープ内の箱 U に規定
    {
        A = .V1;    // デフォールトスコープ内の箱 A に先程の箱 V1 を代入
        .V2 = 2;    // 現メンバースコープ内、つまり、グローバルスコープ内の
    }               //   箱 U の中の、箱 V2 に 2 を代入
    B = ::U.V2;     // デフォールトスコープ内の箱 B に先程の箱 V2 を代入
を実行すると、箱 A と箱 B の中身はそれぞれ、整数値 1 と 2 になります。

 scope の構文は、何重にでも、ネスト(入れ子)にすることができます。例えば、上例
の続きで、
    E.F.G.H1 = -1;
    scope E.F           // メンバースコープを、デフォールトスコープ内の
    {                   //  箱 E の中の箱 F に規定
        scope .G        // メンバースコープを、現メンバースコープ内の
        {               //  箱 G に規定
            X = .H1;
            .H2 = -2;
        }               // メンバースコープは、前の E.F に戻る
        Y = .G.H2;
        scope ::U       // メンバースコープを、上例のグローバルスコープ内の
        {               //  箱 U に規定
            J = .V1;
            K = .V2;
        }               // メンバースコープは、前の E.F に戻る
        this.G.H3 = -3; // this は、現メンバースコープの箱( E.F )を指す
    }
    Z = E.F.G.H3;
を実行すると、箱 X, 箱 Y, 箱 Z の中身はそれぞれ、整数値 -1, -2, -3 になります。
また、箱 J, 箱 K の中身はそれぞれ、整数値 1, 2 になります。

 scope 文 の波括弧 { } のブロック内には、任意の実行文が記述できますが、ラベルは
設定できません。これについては、「制御の流れ(ジャンプ系)」の章の
   ・注意事項
の節で説明しています。
 また、同ブロック内で行なう関数コールやリターンに関しては、「関数」の章の
   ・関数のメンバースコープを規定したコール形態
の節で説明しています。

●関数ローカルスコープでのスコープの追加と削除
 リレー型関数 'AddScope または 'inherit で、スコープの追加対象の箱が省略された
場合、現実行中の関数のローカルスコープに、引数で指定された箱のスコープが追加され
ます。これによって、任意のスコープ内の箱に、箱名だけで、アクセスできるようになり
ます。例えば、
    ::G.A = 1;          // グローバルスコープ内の箱 G の中の箱 A に 1 を代入
    'AddScope( ::G );   // 関数ローカルスコープに、箱 ::G のスコープを追加
    print A;            // 関数ローカルスコープから、箱 ::G.A を、
                        //  単に A として、アクセスできる
を実行すると、1 がプリントされます。

 また、リレー型関数 'DelScope または 'disherit で、スコープの削除対象の箱が省略
された場合、現実行中の関数のローカルスコープから、引数で指定された箱のスコープが
削除されます。例えば、上例の続きで、
    'DelScope( ::G );   // 関数ローカルスコープから、箱 ::G のスコープを削除
    print A;            // 関数ローカルスコープから、箱 ::G.A は見えない
を実行すると、例外が発生します。

●メンバースコープでのスコープの追加と削除
 リレー型関数 'inherit または 'AddScope で、スコープの追加対象の箱に、this を
指定すると、現メンバースコープに、引数で指定された箱のスコープが追加されます。
例えば、あるメンバー関数の中で、
    ^L.M.N = 1;
    this'inherit( ^L.M );   // 現メンバースコープに、^L.M のスコープを追加(継承)
    print .N;               // 現メンバースコープから、^L.M.N を、
                            //  単に .N として、アクセスできる
を実行すると、1 がプリントされます。

 また、リレー型関数 'disherit または 'DelScope で、スコープの削除対象の箱に、
this を指定すると、現メンバースコープから、引数で指定された箱のスコープが削除
されます。例えば、上例の続きで、
    this'disherit( ^L.M );  // 現メンバースコープから、^L.M のスコープを削除
    print .N;               // 現メンバースコープから、^L.M.N は見えない
を実行すると、例外が発生します。