MikoScript 言語仕様

 箱の操作

 本言語処理システムでは、箱の操作を行なう各種のリレー型関数が、予め組み込まれて
います。本章では、これらの関数について説明します。なお、箱の基本事項については、
「箱」の章で、説明しています。

基本操作
  'exist?  箱の存在確認
  'empty!  空箱化
  'new!   空箱の新規生成/既存箱の空箱化
  'name   箱名の取得/変更
  'size   箱/値のサイズを取得
  'type   箱/値のタイプを取得
  'attr   箱/値の属性を取得/設定
  'count   箱の中の箱の個数を取得
  'level   箱の(入れ子の)深さを取得
  'cbox!   「箱を入れる箱」を生成
  'cbox?   「箱を入れる箱」か?
  'same?   同一の箱か?
  'ref    対象の箱への参照値      ⇒参照
  'ref?   対象は参照箱または参照値か? ⇒参照
  'alias   対象の箱を参照する箱を取得  ⇒参照
  'val    実値への変換(参照の解消)

特定位置の箱の参照
  'up    上位箱
  'first   最初の箱
  'last   最後の箱
  'next   次の箱
  'prev   前の箱
  'after   後置箱
  'before  前置箱
  'fwd    先方箱
  'bwd    前方箱

出し入れ
  'queue!  双方向出し入れ用の箱を生成    ⇒参照
  'push   対象箱内に指定項目を先頭から追加 ⇒参照
  'post   対象箱内に指定項目を末尾から追加 ⇒参照
  'pop    対象箱内の最初の箱を取り出す   ⇒参照

箱内移動
  'move   対象箱内の指定箱を現順位に移動する
  'swap   対象箱と指定の箱の順序を入れ換える
  'sort   対象箱内の箱を並べ替える(1)
  'sort   対象箱内の箱を並べ替える(2)
  'rotate  対象箱内の箱の順番を回転する
  'reverse  対象箱内の箱の順番を逆にする

列挙
  'each   対象箱内の直属の箱を列挙する(フラット走査)
  'enum   対象箱内の直系の箱を列挙する(ツリー走査)


■基本操作
'exist? 関数
書式: <対象箱>'exist?
説明: <対象箱> の存在を確認します。
返値: <対象箱> が存在すれば 真値(1)、存在しなければ 偽値(0)
注意: 対象が値の場合、返値は、常に 真値(1) になります。
    但し、対象が null の場合、返値は、偽値(0) になります。
用例: 次のスクリプトを実行すると、「1,0」とプリントされます。
          A = 1;
          print A'exist?, B'exist?;
'empty! 関数 書式: <対象箱>'empty! 説明: <対象箱> の箱の中身を空にします。     <対象箱> が存在しない時は、例外が発生します。 返値: <対象箱> への参照値 or null(対象が箱でない場合) 'new! 関数 書式: <対象箱>'new! 説明: <対象箱> が存在しない時は、その名前の空箱を新規に生成します。     <対象箱> が存在する時は、その箱を空にします。 返値: <対象箱> への参照値 'name 関数 書式: <対象箱>'name       ・・・ 箱名の取得     <対象箱>'name( <箱名> )  ・・・ 箱名の変更 説明: <箱名> の引数が無ければ、<対象箱> の箱名を取得します。     <箱名> の引数が有れば、<対象箱> の箱名をそれに変更します。     なお、箱名の変更時、同じ箱名の箱が他にあれば、エラーになります。 返値: 取得/変更した箱名(正常時) or null(エラー時) 補説: 本関数の場合、エラーになっても例外は発生しません。 用例: 次のスクリプトは、「A, 春」と「春, B, <null>」をプリントします。
          A = "春";
          print A'name, [A]'new!'name;
          A'name( "B" );
          print B, B'name, C'name;
'size 関数 書式: <対象>'size 説明: <対象> は、箱か、または、値になります。     箱の場合は、その中身のデータサイズ(バイト数)を返します。     値の場合は、その値のデータサイズ(バイト数)を返します。     <対象> に「入出力形式」が設定されていれば、それに対応するサイズ、     つまり、実際に入出力されるサイズを返します。     なお、<対象> が不正な場合、-1 を返します。 用例: 次のスクリプトを実行すると、「4, 8, 12, 24」とプリントされます。
          A = 12.3;  B = "文字列データ";
          C ::= {  .Name'C(20);  .Age'LONG;  }
          print 123'size, A'size, B'size, C'size;
'type 関数 書式: <対象>'type( i ) 説明: 本関数は、<対象>(箱または値)のタイプを示す文字列を返します。     この主なものを下表に示します。
タイプ意味
 null  無効値
 empty  空箱
 integer  整数箱 or 値
 float  実数箱 or 値
 string  文字列箱 or 値
 array  純粋配列箱
 container  一般の「箱を入れる箱」
(クラス名) クラス(構造体)箱 ※
 class  クラス(構造体)箱 ※
 instance  インスタンス箱 ※
 usr-func  ユーザー定義関数箱
 sys-func  システム組込関数箱
 reference  参照
 bit-field  ビットフィールド箱
 sys-data  システムデータ箱
 dll-func  DLL関数箱
 dll-data  DLLデータ箱
 com-object COMオブジェクト箱
    ※ が付いてるタイプについて、以下に説明します。       なお、引数 i が関連するのは、このタイプだけです。     <対象> がクラス(構造体)の場合:       i が省略または 0 の時、<対象> のクラス名(箱名)を返します。       i > 0 の時、第 i 番目の直接の基底クラスの箱名(クラス名)を返します。        多重継承がなければ、i = 1 です。なお、ここでは、間接の基底クラスは、        対象外です。i に対応するクラスがない時は、それを意味する "[?]" と        いう文字列を返します。       i < 0 の時、"class" というタイプ名を返します。これは、<対象> が        クラス(構造体)かどうかだけ分かればよい時に使います。     <対象> がインスタンスの場合:       i が省略または 0 の時、<対象> を生成したクラスの名前(箱名)を返します。       i < 0 の時、"instance" というタイプ名を返します。これは、<対象> が        インスタンスかどうかだけ分かればよい時に使います。       i > 0 の時、対応クラスが無いことを示す "[?]" という文字列を返します。 補説: 純粋配列の場合、さらにどのデータ型かを調べるには、'attr を使います。     クラス(構造体)箱、または、インスタンス箱の場合、その基底クラスの名前     ではなく、参照を得するには、'base を使います。 注意: 特殊な箱では、この表以外のタイプになる場合もあります。     <対象> が参照箱の場合、その参照先の箱のタイプを返します(「例3」参考)。     <対象> がない場合は、null を返します。 例1: 次のスクリプトは、「integer, float, string, array」とプリントします。
          A = 12;  B = 34.5;  C = "xyz";  D'BYTE(100);
          print A'type, B'type, C'type, D'type;
例2: 対象がクラス(構造体)とインスタンスの例を示します。
          class A {}
          class B {}
          class C : A, B {}
          V = C();
          print A'type, B'type;
          print C'type, C'type(1), C'type(2), C'type(-1);
          print V'type, V'type(1), V'type(2), V'type(-1);
    このスクリプトを実行すると、次のようにプリントされます。       A, B       C, A, B, class       C, [?], [?], instance 例3: 次のスクリプトは、「integer, reference」とプリントします。
          A = 1;
          R := A;
          print R'type, A'ref'type;
'attr 関数 書式: <対象>'attr ・・・ 入出力形式または汎用属性値の取得     <対象>'attr( n ) ・・・ 汎用属性値の設定 説明: 本関数は、<対象>(箱または値)に設定されている属性値を取得/設定します。     ここでいう属性値とは、「入出力形式」または「汎用属性値」のことです。     <対象> に入出力形式が設定されている時に、この 'attr を引数なしで適用する     と、その形式を示す文字列(下表の「形式名」)を返します。また、数量を使用     する形式では、その数量(下表のnの値)も返します。
形式名意味
 C  文字n桁
 I  10進整数文字n桁
 X  16進整数文字n桁
 F  浮動小数点文字n桁
 LINE  改行区切り文字列
 CSV  コンマ区切り文字列
 SSV  空白区切り文字列
 KC  文字n字
 BIT_FIELD  n バイトのビットフィールド
 SBIT  n ビット整数値(符号有り)
 UBIT  n ビット整数値(符号無し)
 BYTE   8 ビット整数値(符号有り)
 UBYTE   8 ビット整数値(符号無し)
 SHORT  16ビット整数値(符号有り)
 USHORT  16ビット整数値(符号無し)
 LONG  32ビット整数値(符号有り)
 ULONG  32ビット整数値(符号無し)
 FLOAT  32ビット浮動小数点数値
 DOUBLE  64ビット浮動小数点数値
 STRUCT  構造体
 FILE  ファイル/バッファ
    <対象> に入出力形式が設定されていない時に、この 'attr を引数なしで     適用すると、その <対象> の汎用属性値を返します。     'attr では、入出力形式の設定はできません。     'attr で設定はできるのは、汎用属性値だけです。     <対象> に、引数 n を指定して、この 'attr を適用すると、その n の値の     汎用属性値が、<対象> に設定されます。この値の有効範囲は現状、0〜1023 に     限定されています。これ以外の値を指定しても、0 に設定されます。     汎用属性値の設定の際に、入出力形式は解除されます。     汎用属性値は、入出力形式を解除できない純粋配列やファイル/バッファなど     には設定できません。     汎用属性値の用途は、特に規定されていません。何に使っても構いません。 補説: 属性値の取得の際、<対象> の属性が未設定、または <対象> が不正/不在なら、     0 を返します。また、汎用属性値の設定に成功した時は、<対象> の参照、または、     値を返し、失敗した時は、null を返します。 例1: 次の実行では、「0, LINE, LONG, STRUCT, 0」とプリントされます。
          A = 0;  B'LINE;  C'LONG;  D ::= {  };
          print A'attr, B'attr, C'attr, D'attr, X'attr;
例2: 次の実行では、「C, 8」とプリントされます。
          Str'C(8);
          print Str'attr;
例3: 次の実行では、「123」とプリントされます。
          Tmp'new!'attr( 123 );
          print Tmp'attr;
'count 関数 書式: <対象箱>'count        ・・・ 「箱を入れる箱」内の箱数を取得     <純粋配列>'count( <次元> )  ・・・ 純粋配列の要素数を取得     <文字列>'count( s )      ・・・ サブ文字列の出現回数を取得 説明: 対象が「箱を入れる箱」の場合:       その箱の中にある直属の箱の個数を返します。     対象が純粋配列の場合:       <次元> の指定が無ければ、全要素数を返します。       <次元> の指定が有れば、その次元だけの要素数を返します。       なお、<次元> には、n 次元の配列の場合、1 〜 n の数値が指定できます。     対象が文字列の場合:       対象の文字列内に、引数 s の文字列が、何個あるかを返します。     対象が上記以外の場合:       -1 を返します。 用例: 次のスクリプトの実行では、「3, 200, 10, 20, 8」とプリントされます。
          A ::= { .X = .Y = .Z = 0; }
          B'SHORT( 10, 20 );
          C = "すもももももももものうち";
          print A'count, B'count, B'count(1), B'count(2), C'count("も");
'level 関数 書式: <対象箱>'level 説明: <対象箱> の入れ子の深さ、つまり、<対象箱> を含む最外の箱から、<対象箱>     までの、直属スコープの段数を返します。     なお、対象が不在または箱でない場合は、-1 を返します。 用例: 次のスクリプトの実行では、「1, 2, 3, -1」とプリントされます。
          A.B.C = 0;
          print A'level, A.B'level, A.B.C'level, X'level;
'cbox! 関数 書式: <対象箱>'cbox! 説明: <対象箱> が「箱を入れる箱」でなければ、強制的にそれを「箱を入れる箱」に       変えます。なお、その時点で、その箱の中には何の箱もありません。     <対象箱> が「箱を入れる箱」の場合は、そのままにしておきます。     <対象箱> が不在の時は、その箱を新規に生成します。     対象が値または無指定の場合は、エラーになります。 返値: <対象箱> への参照値 or null(エラー時) 用例: 次のスクリプトは、X という名前の「箱を入れる箱」をデフォールトスコープに     新規生成し、そのタイプ「container」をプリントします。
          X'cbox!;
          print X'type;
'cbox? 関数 書式: <対象>'cbox? 返値: <対象> が「箱を入れる箱」なら 真値(1)、さもなければ 偽値(0) 用例: 次のスクリプトを実行すると、「1,0」とプリントされます。
          A'cbox!;
          print A'cbox?, B'cbox?;
'same? 関数 書式: <対象>'same?( <箱名> ) 返値: <対象> の箱が <箱名> の箱と同一の箱なら 真値(1)、さもなければ 偽値(0) 説明: 本関数は、箱の中身ではなく、その箱自身が同一か否かを判定します。     <対象> や <箱名> の箱が、参照箱の場合、その参照先の箱が判定されます。 用例: 次のスクリプトを実行すると、「1, 1, 1, 0」とプリントされます。
          A = 123;
          B := A;
          C := B;
          X = 123;
          print A'same?( B ), B'same?( C ), C'same?( A ), A'same?( X );
'val 関数 書式: <対象>'val 説明: <対象> を実値に変換して(参照を解消して)返します。     <対象> が既に実値の時は、そのまま返します。     <対象> が実値に変換できない時は、null を返します。 補説: 'val は主に、関数の引数を「値渡し」にする時や、関数側で受け取った引数の     参照を解消する時に使います。⇒参照 ■特定位置の箱の参照 'up 関数 書式: <対象箱>'up( i ) 説明: <対象箱> よりも i 段上位の箱への参照を返します。     引数 i には、1, 2, ... を指定します。     i が省略時は、i = 1 として扱われます。     i = 0 の時は、<対象箱> 自身への参照を返します。     i に対応する箱が無い時や、対象が箱以外の時は、null を返します。 用例: 次のスクリプトを実行すると、「C, B, A」とプリントされます。
          T := A.B.C'new!;
          print T'name, T'up'name, T'up(2)'name;
'first 関数 書式: <対象箱>'first( i ) 説明: <対象箱> 内の最初の箱から順方向に i 個先の箱への参照を返します。     引数 i には、0, 1, 2, ... を指定します。これは、次のように対応します。       i = 0: 最初の箱       i = 1: 最初の箱から1つ次の箱       i = 2: 最初の箱から2つ次の箱        ・・・     i が省略時は、i = 0 として扱われます。     i に対応する箱が無い時や、対象が箱以外の時は、null を返します。 例1: 次の実行では、「1, A」と「3, C」と「A=1, B=2, C=3, 」がプリントされます。
          T ::= { .A = 1; .B = 2; .C = 3; }
          print T'first, T'first'name;
          print T'first(2), T'first(2)'name;
          for( p := T'first ; p'ref? ; p := T'next )
              print p'name : "=" : p, -;
例2: 次の実行では、「11, 22, 33」と「11, <null>, 33」がプリントされます。
          A = { 0, 0, 0 };
          A'first = 11;   A'first(1) = 22;   A'first(2) = 33;
          print A[0], A[1], A[2];
          delete [ A'first(1)'ref ];
          DefValue = null;
          print A[0], A[1], A[2];
補説: 正常終了時、<対象箱> 内の「現指示箱」が、返値の箱に更新されます。     これは、'next'prev の基準になります。 'last 関数 書式: <対象箱>'last( i ) 説明: <対象箱> 内の最後の箱から逆方向に i 個前の箱への参照を返します。     引数 i には、0, 1, 2, ... を指定します。これは、次のように対応します。       i = 0: 最後の箱       i = 1: 最後の箱から1つ前の箱       i = 2: 最後の箱から2つ前の箱        ・・・     i が省略時は、i = 0 として扱われます。     i に対応する箱が無い時や、対象が箱以外の時は、null を返します。 例1: 次の実行では、「3, C」と「1, A」と「C=3, B=2, A=1, 」がプリントされます。
          T ::= { .A = 1; .B = 2; .C = 3; }
          print T'last, T'last'name;
          print T'last(2), T'last(2)'name;
          for( p := T'last ; p'ref? ; p := T'prev )
              print p'name : "=" : p, -;
例2: 次の実行では、「11, 22, 33」と「11, <null>, 33」がプリントされます。
          A = { 0, 0, 0 };
          A'last = 33;   A'last(1) = 22;   A'last(2) = 11;
          print A[0], A[1], A[2];
          delete [ A'last(1)'ref ];
          DefValue = null;
          print A[0], A[1], A[2];
補説: 正常終了時、<対象箱> 内の「現指示箱」が、返値の箱に更新されます。     これは、'next'prev の基準になります。 'next 関数 書式: <対象箱>'next( i ) 説明: <対象箱> 内の「現指示箱」から i 個先の箱への参照を返します。     現指示箱に関しては、'first'last の「補説」参照。     引数 i は、0, ±1, ±2, ... を指定します。これは次のように対応します。       i = 0: 現指示箱       i = 1: 現指示箱から1つ次の箱       i = 2: 現指示箱から2つ次の箱        ・・・       i = -1: 現指示箱から1つ前の箱       i = -2: 現指示箱から2つ前の箱        ・・・     i が省略時は、i = 1 として扱われます。     i に対応する箱が無い時や、対象が箱以外の時は、null を返します。 補説: 本関数の正常終了時、現指示箱は、返値の箱に更新されます。 用例: 次のスクリプトは、「A, 1」,「B, 2」,「C, 3」とプリントします。
          T ::= { .A = 1; .B = 2; .C = 3; }
          for( p := T'first ; p'ref? ; p := T'next )
              print p'name, p;
'prev 関数 書式: <対象箱>'prev( i ) 説明: <対象箱> 内の「現指示箱」から i 個前の箱への参照を返します。     現指示箱に関しては、'first'last の「補説」参照。     引数 i は、0, ±1, ±2, ... を指定します。これは次のように対応します。       i = 0: 現指示箱       i = 1: 現指示箱から1つ前の箱       i = 2: 現指示箱から2つ前の箱        ・・・       i = -1: 現指示箱から1つ次の箱       i = -2: 現指示箱から2つ次の箱        ・・・     i が省略時は、i = 1 として扱われます。     i に対応する箱が無い時や、対象が箱以外の時は、null を返します。 補説: 本関数の正常終了時、現指示箱は、返値の箱に更新されます。 用例: 次のスクリプトは、「C, 3」,「B, 2」,「A, 1」とプリントします。
          T ::= { .A = 1; .B = 2; .C = 3; }
          for( p := T'last ; p'ref? ; p := T'prev )
              print p'name, p;
'after 関数 書式: <対象箱>'after( i ) 説明: <対象箱> から i 個先の箱への参照を返します。     引数 i は、0, ±1, ±2, ... を指定します。これは次のように対応します。       i = 0: <対象箱> 自身       i = 1: <対象箱> から1つ次の箱       i = 2: <対象箱> から2つ次の箱        ・・・       i = -1: <対象箱> から1つ前の箱       i = -2: <対象箱> から2つ前の箱        ・・・     i が省略時は、i = 1 として扱われます。     i に対応する箱が無い時や、対象が箱以外の時は、null を返します。 用例: 次のスクリプトは、「A」,「B」,「C」,「<null>」とプリントします。
          T ::= { .A = 1; .B = 2; .C = 3; }
          for( i = 0 ; i <= 3 ; i++ )
              print T.A'after(i)'name;
'before 関数 書式: <対象箱>'before( i ) 説明: <対象箱> から i 個前の箱への参照を返します。     引数 i は、0, ±1, ±2, ... を指定します。これは次のように対応します。       i = 0: <対象箱> 自身       i = 1: <対象箱> から1つ前の箱       i = 2: <対象箱> から2つ前の箱        ・・・       i = -1: <対象箱> から1つ次の箱       i = -2: <対象箱> から2つ次の箱        ・・・     i が省略時は、i = 1 として扱われます。     i に対応する箱が無い時や、対象が箱以外の時は、null を返します。 用例: 次のスクリプトは、「C」,「B」,「A」,「<null>」とプリントします。
          T ::= { .A = 1; .B = 2; .C = 3; }
          for( i = 0 ; i <= 3 ; i++ )
              print T.C'before(i)'name;
'fwd 関数 書式: <対象箱>'fwd( i ) 説明: <対象箱> から i 個先方(下記補説参照)の箱への参照を返します。     引数 i は、0, ±1, ±2, ... を指定します。これは次のように対応します。       i = 0: <対象箱> 自身       i = 1: <対象箱> から1つ先方の箱       i = 2: <対象箱> から2つ先方の箱        ・・・       i = -1: <対象箱> から1つ前方の箱       i = -2: <対象箱> から2つ前方の箱        ・・・     i が省略時は、i = 1 として扱われます。     i に対応する箱が無い時や、対象が箱以外の時は、null を返します。 補説: ここでの「先方」「前方」の意味は、次のとおりです。     階層構造を深さ優先で展開して各ノードを1行に表わすと、例えば、次のように     なります。       R       ├─A       │ ├─A1       │ └─A2       ├─B       │ └─B1       └─C     あるノードから1つ先方のノードというのは、上図のような展開において、その     ノードから1行下のノードになります。また、あるノードから1つ前方のノード     というのは、そのノードから1行上のノードになります。たとえば、ノードBの     1つ先方のノードはB1で、1つ前方のノードはA2になります。 用例: 次のようなスクリプトがあります。
          R ::= {
            .A ::= {  .A1 = 11;  .A2 = 12;  }
            .B ::= {  .B1 = 21;  }
            .C = 3;
          }
          for( p := R ; p'level > 0 ; p := p'fwd )
              print p'name;
 これを実行すると、次のようにプリントされます。      R      A      A1      A2      B      B1      C 'bwd 関数 書式: <対象箱>'bwd( i ) 説明: <対象箱> から i 個前方の箱への参照を返します。     引数 i は、0, ±1, ±2, ... を指定します。これは次のように対応します。       i = 0: <対象箱> 自身       i = 1: <対象箱> から1つ前方の箱       i = 2: <対象箱> から2つ前方の箱        ・・・       i = -1: <対象箱> から1つ先方の箱       i = -2: <対象箱> から2つ先方の箱        ・・・     i が省略時は、i = 1 として扱われます。     i に対応する箱が無い時や、対象が箱以外の時は、null を返します。     なお、「先方」「前方」の意味は、'fwd の補説参照。 用例: 次のようなスクリプトがあります。
          R ::= {
            .A ::= {  .A1 = 11;  .A2 = 12;  }
            .B ::= {  .B1 = 21;  }
            .C = 3;
          }
          for( p := R.C ; p'level >= 2 ; p := p'bwd )
              print p'name;
    これを実行すると、次のようにプリントされます。      C      B1      B      A2      A1      A ■箱内移動 'move 関数 書式: <対象箱>'move( A, "before", B )     <対象箱>'move( A, "after", B ) 説明: "before"の時、<対象箱> 内の箱Aを箱Bの前へ移動します。     "after" の時、<対象箱> 内の箱Aを箱Bの後へ移動します。 注意: 箱Aは、省略不可     箱Bの省略時は、現指示箱( 'first 等の「補説」参照)になります。     "before","after" の省略/不正時は、"before" として扱います。 返値: <対象箱> への参照( エラー時は、null ) 用例: 次のようなスクリプトがあります。
          T ::= { .A = 1; .B = 2; .C = 3; }
          T'move( T.A, "after", T.B );
          do T'each with p {  print p'name : "=" : p, -;  };
          print;
          T'move( T.C, "before", T.B );
          do T'each with p {  print p'name : "=" : p, -;  };
          print;
    これを実行すると、次のようにプリントされます。      B=2, A=1, C=3,      C=3, B=2, A=1, 'swap 関数 書式: 'swap( A, B )     A'swap( B ) 説明: 箱Aと箱Bの順序を入れ換えます。     なお、両箱の上位の箱は、同じでないといけません。 返値: 箱A への参照( エラー時は、null ) 用例: 次のスクリプトを実行すると、「C=3, B=2, A=1, 」とプリントされます。
          T ::= { .A = 1; .B = 2; .C = 3; }
          'swap( T.A, T.C );
          do T'each with p {  print p'name : "=" : p, -;  };
          print;
'sort 関数(1) 書式: <対象箱>'sort( <比較関数> ) 説明: <対象箱> の中の各箱を <比較関数> で比較した結果の順に並べ替えます。     <比較関数> の引数には、比較する2つの箱への参照が渡されます。     <比較関数> の返値は、比較する2つの箱をA,Bとすると、       = 0: AとBが等しい       < 0: AはBよりも先の順になる       > 0: AはBよりも後の順になる     となる数値を返す必要があります。 返値: <対象箱> への参照( エラー時は、null ) 補説: 箱の並べ替えは、特定の用途に限れば、'sort 関数(2)の方が高速です。 例1: 配列内の数値を昇順に並べ替える例を示します。ちなみに、次のスクリプトを     実行すると、「1, 2, 3, 4, 5, 」とプリントされます。
          T = {  5, 2, 1, 3, 4  };
          function Cmp( a, b )  {  return a - b;  }
          T'sort( Cmp );
          for( p := T'first ; p'ref? ; p := T'next )
              print p, -;
例2: do-with 式を使うと、例1のスクリプトは、次のように簡単に書けます。     比較関数が簡単な場合は、この方が便利です。
          T = {  5, 2, 1, 3, 4  };
          do T'sort with a, b { return a - b; };
          do T'each with p {  print p, -;  };
例3: 配列内の各箱をその名前の昇順に並べ替える例を示します。ちなみに、次の     スクリプトを実行すると、「A, B, C, D, E, 」とプリントされます。
          T ::= {  .C = .A = .D = .E = .B = 0;  };
          do T'sort with a, b { return a'name - b'name; };
          do T'each with p {  print p'name, -;  };
例4: 配列内の各箱の中の特定の変数(この例では X という変数)をキーとして、     その値の降順に並べ替える例を示します。このスクリプトを実行すると、     「C.X=3, B.X=2, A.X=1, 」とプリントされます。
          T ::= { .A.X = 1; .B.X = 2; .C.X = 3; }
          do T'sort with a, b { return b.X - a.X; };
          do T'each with p {  print p'name : ".X=" : p.X, -;  };
'sort 関数(2) 書式: <対象箱>'sort( mode, key ) 機能: <対象箱> の中の各箱を mode と key で指定された順に並べ替えます。 引数: mode には、並べ替え方を規定する以下の文字列を指定します。       "+n": <対象箱> の中の各箱の名前の昇順       "-n":     〃      名前の降順       "+v":     〃      値の昇順       "-v":     〃      値の降順       "+k":     〃      の中の「キー箱」の値の昇順       "-k":     〃      の中の「キー箱」の値の降順     これらの場合、英字の大小は区別されません。     英字の大小を区別して並べ替えるには、それぞれ、次の指定にします。       "+N", "-N", "+V", "-V", "+K", "-K"     mode が、"+k", "-k", "+K", "-K" の時、       key の引数で、その「キー箱」の名前を指定します。     mode が省略/不正時、"+n" として扱われます。 返値: <対象箱> への参照 ( エラー時は、null ) 補説: 値による並べ替えでの比較は、数値どうしか、文字列どうしに限られます。       それ以外の比較が必要な場合には、結果は保証されません。 補説: この 'sort 関数(2)の並べ替えは、比較関数が内部関数であるのと、     クイックソートを採用しているので、高速です。     ただ、比較関数を任意に指定できないので、用途は限られます。     一方、'sort 関数(1)は、汎用的ですが、'sort 関数(2)ほど速くは     ありません。 注意: <対象箱> は「箱を入れる箱」でないといけません。     キー箱は、参照箱であってはいけません。 例1: 次のスクリプトは、「キー箱」を使わない例です。
          T ::= { .A = 1; .B = 2; .C = 3; }
          T'sort( "-n" );
          do T'each with p {  print p'name : "=" : p, -;  };
          print;
          T'sort( "+v" );
          do T'each with p {  print p'name : "=" : p, -;  };
          print;
    このスクリプトを実行すると、次のようにプリントされます。      C=3, B=2, A=1,      A=1, B=2, C=3, 例2: 次のスクリプトは、「キー箱」を使う例です。この実行でも、例1と同じ     プリント結果になります。
          T ::= { .A.X = 1; .B.X = 2; .C.X = 3; }
          T'sort( "-k", "X" );
          do T'each with p {  print p'name : "=" : p.X, -;  };
          print;
          T'sort( "+k", "X" );
          do T'each with p {  print p'name : "=" : p.X, -;  };
          print;
'rotate 関数 書式: <対象箱>'rotate( n ) 説明: <対象箱> の中の各箱の順番を回転します。     引数 n は、その絶対値で回転回数を指定します。また、     n の正負で、回転方向を規定します:      n > 0 の時、順方向( 順番が上がる方へ移動、尚、先頭は末尾へ移動 )      n < 0 の時、逆方向( 順番が下がる方へ移動、尚、末尾は先頭へ移動 )     n が省略/不正時は、n = 1 として扱われます。 返値: <対象箱> への参照 ( エラー時は、null ) 補説: 'rotate は、対象が、文字列整数値の時も有効です。 用例: 次のスクリプトは、以下の各コメントに示すようにプリントします。
            T ::= { .A = 1, .B = 2, .C = 3, .D = 4, .E = 5; };
            call Print;       // →「A, B, C, D, E, 」
            T'rotate( 1 );
            call Print;       // →「B, C, D, E, A, 」
            T'rotate( -2 );
            call Print;       // →「E, A, B, C, D, 」
            return;
          Print:
            do T'each with p {  print p'name, -;  };
            print;
            back;
'reverse 関数 書式: <対象箱>'reverse 説明: <対象箱> の中の各箱の順番を逆にします。 返値: <対象箱> への参照 ( エラー時は、null ) 補説: 'reverse は、対象が、文字列整数値メモリーブロックの時も有効です。 用例: 次のスクリプトを実行すると、「E, D, C, B, A, 」とプリントされます。
          T ::= { .A = 1, .B = 2, .C = 3, .D = 4, .E = 5; };
          T'reverse;
          do T'each with p {  print p'name, -;  };
■列挙 'each 関数 書式: <対象箱>'each( <関数> ) 説明: <対象箱> の中にある直属の各箱を、その格納順に1つずつ、列挙します。     この列挙というのは、指定された <関数> のコールになります。その際、     引数として、各箱への参照が渡されます。     なお、<関数> の返値が、-1 であれば、それ以降の列挙は中止されます。 返値: <関数> をコールした回数     ( 列挙中止時は、それまでに <関数> をコールした回数を負にした値 ) 注意: 本関数は、<対象箱> の追加スコープ内にある箱は、列挙しません。 例1: 次のスクリプトは、「12, 34, 56, 78, 90, 」とプリントします。
          T = {  12, 34, 56, 78, 90  };
          function Dump( v )  {  print v, -;  }
          T'each( Dump );
例2: do-with 式を使うと、例1のスクリプトは、次のように書けます。
          T = {  12, 34, 56, 78, 90  };
          do T'each with v {  print v, -;  };
例3: 列挙を中断する例を示します。このスクリプトは、「12, 34, 56 」と     プリントします。
          T = {  12, 34, 56, 78, 90  };
          do T'each with v {
             print v, -;
             return v > 50 ? -1 : 0;  };
'enum 関数 書式: <対象箱>'enum( <関数> ) 説明: <対象箱> の中にある直系のすべての箱を、その格納順に1つずつ、列挙します。     その際、列挙した箱が「箱を入れる箱」の時は、その中の各箱に対しても、     (再帰的に)列挙します。     この列挙というのは、指定された <関数> のコールになります。その際、     引数として、各箱への参照が渡されます。     なお、<関数> の返値が、-1 であれば、それ以降の列挙は中止されます。 返値: <関数> をコールした回数     ( 列挙中止時は、それまでに <関数> をコールした回数を負にした値 ) 注意: 本関数は、<対象箱> の追加スコープ内にある箱は、列挙しません。 用例: 中が階層になっている箱内の全ての箱を列挙する例を示します。     このスクリプトを実行すると、「A, A1, A2, B, B1, C, 」とプリントされます。
          T ::= {
            .A ::= {  .A1 = 11;  .A2 = 12;  }
            .B ::= {  .B1 = 21;  }
            .C = 3;
          }
          do T'enum with p {  print p'name, -;  };