MikoScript 言語仕様

 各種組み込み処理

■標準入出力
 コンソール版の MikoScript の場合、通常、標準出力は、コンソール(ウィンドウ)
への出力で、標準入力は、キーボードからの入力になります。但し、標準入出力は、
起動時にリダイレクトされて、ファイル等になることがあります。
 一方、アプリケーション組み込みの MikoScript の場合、標準入出力は、基本的に、
そのアプリケーションに依存します。その場合、必ずしも、そのアプリケーション自身
の標準入出力にはなりません。
 例えば、Apsaly テキストエディタに組み込まれた MikoScript の場合、標準出力は、
-Script- というウィンドウへの出力になり、標準入力は、現状、ありません。

 print 文
書式: print <項目の並び> ;
概要: 指定項目の文字列を標準出力にプリントします。
説明: <項目の並び> は、空、または、1個以上のプリント対象の項目を指定します。
    プリント対象の項目が複数ある場合、
    各項目を、コンマ(,) または コロン(:) で区切ります。
    コンマ(,) で区切った場合、各項目自身のプリント内容の間には、
    「, 」(コンマ+半角空白)が無条件に挿入されます。
    コロン(:) で区切った場合、各項目は何の区切りもなしにそのまま連続して、
    プリントされます。
    本プリントの最後には、改行が付加されます。
    これを抑止するには、最後の項目をマイナス(-) に指定します。(用例参照)

    本プリントでは、プリント対象の項目のデータ型式が何であっても受け付けます。
    文字列の場合、そのままプリントします。
    数値の場合、適当な文字列に変換してプリントします。
    それ以外の場合、所定の形態の文字列に変換してプリントします。
    希望通りの厳密な書式でプリントするには、事前の処理が必要です。

注意: print 文は、あくまで「文」であって、関数ではありません。そのため、
    print の引数は、丸括弧で囲う必要がありません。また、print には、
    返値がありません。さらに、「print」という名前は、予約語になっている
    ので、他の関数名や変数名等には使えません。
    
補説: プリント対象の項目の区切りに、コンマとコロンの2種類があるのは、
    次の理由に依ります。複数の項目をプリントする時、各項目をコンマで
    区切ることはよくあります。特にデバッグ用のプリント等では頻繁にあります。
    しかし、そのようにプリントするには、若干面倒な書式指定が必要です。
    そのため、本 print 文では、各項目をコンマで区切るだけで、そのように
    プリントされるようになっています。勿論、コンマが勝手に付かないように
    プリントしたい場合もあるので、コロン区切りが用意されています。

用例: 以下の各 print 文では、そのコメントに示す内容がプリントされます。
            print "Hello";              // 「Hello」+改行
            print "Hello", -;           // 「Hello, 」(改行なし)
            print "Hello": -;           // 「Hello」のみ(改行なし)
            print ;                     //  改行のみ
            print "ABC", 123, 4.56;     // 「ABC, 123, 4.56」+改行
            print "ABC": 123: 4.56;     // 「ABC1234.56」+改行
            X = -987;
            Y = null;
            print "X=" : X, "Y=" : Y ;  // 「X=-987, Y=<null>」+改行
            print ##X=${X}, Y=${Y}## ;  // 「X=-987, Y=<null>」+改行
    次を実行すると、「0, 1, 2, 3, 4, 」+改行 がプリントされます。
            for( i = 0 ; i < 5 ; i++ )
                print i, -;
            print ;
    C言語で、例えば、
            printf( "a=%03d, b=%8.2f, c=%-15s\n", a, b, c );
    とするのは、本言語では、次のようにできます。
            print "a=%03d, b=%8.2f, c=%-15s"'fmt( a, b, c );
    なお、C言語でも本言語でも、%... で規定される書式のデータ型式と     それに対応する引数のデータ型式が整合していないといけません。     上例では、%03d に対応する a は整数値に、%8.2f の b は実数値に、     %-15s の c は文字列になっていないといけません。ちなみに、例えば、     b が整数値などの場合、プリント結果がおかしくなります。 puts 関数 書式: ::puts( <項目>,... ) 概要: 指定項目の文字列を標準出力します。 説明: 本関数は、指定された各項目を文字列にして標準出力します。     本関数が標準出力する各項目自身の内容は、print 文と同じですが、     print 文のように、各項目の間に「, 」を挿入したり、     最後に、改行を付加することはありません。また、本関数は、     あくまで関数なので、print 文のような特別な表記にはなりません。     本関数の返値は、特に意味はありません( null が返ります )。 用例: 
        ::puts( "Hello, Mr.", name, ".\n" );
gets 関数 書式: ::gets( <プロンプト> ) 概要: 標準入力から1行分の文字列を取得します。 説明: 本関数は、まず、<プロンプト> の指定があれば、その文字列を     標準出力します。その指定がなければ、出力しません。     次に、標準入力から1行分の文字列を取得して、それを返します。     本関数は、入力された文字列をそのまま返すので、     入力文字列の末尾が改行コードであっても除去しません。 補説: デフォールトでは、標準出力は、コンソールで、     標準入力は、キーボードになります。その場合、     本関数を実行すると、キーボードからの入力待ち状態になります。     この状態で、キー入力された文字は、コンソールにエコーバックされます。     Enter キーが押されると、入力が確定して、入力待ち状態は解除されます。     その時、本関数は、今までに入力された文字列を返します。     一方、標準入力がファイルの時には、コンソールへのエコーバックは     行なわれません。 注意: 本関数コールで入力可能な文字列は、1回あたり最大 256 バイトです。     エラーまたは EOF の場合、NULL が返ります。     本関数の実行で、入力待ち状態になっても、スクリプトのスレッドの     実行権の切り換えは、行なわれません。 用例: 
        answer = ::gets( "答えを入力して下さい: " );
■ダイアログ入出力 Confirm 関数 書式: ::Confirm( <メッセージ> ) 概要: 確認用のメッセージボックスを表示します。 説明: 本関数は、引数の <メッセージ> で指定された文字列を、     確認用のメッセージボックスに表示します。     ここには、「はい」と「いいえ」のボタンが2つあります。     このどちらかが押されると、このメッセージボックスが閉じます。     それが「はい」のボタンなら、本関数は、1 を返します。     「いいえ」なら、0 を返します。     万が一、メッセージボックスを表示できなかった場合、     本関数は、null を返します。 補説: メッセージボックスを表示したスクリプトのスレッドは、     待機状態になります。その時、他に実行可能なスレッドがあれば、     そのうちの最高優先順位のスレッドに実行権が譲渡されます。 注意: 本関数は、DLLのコールバック関数内では、実行できません。 用例: 
        if( ! ::Confirm( "この処理を行なってもよろしいですか?" ) )
            return;
Inform 関数 書式: ::Inform( <メッセージ> ) 概要: 通知用のメッセージボックスを表示します。 説明: 本関数は、引数の <メッセージ> で指定された文字列を、     通知用のメッセージボックスに表示します。     ここには、「OK」のボタンが1つあります。     このボタンが押されると、このメッセージボックスが閉じて、     本関数は、1 を返します。     万が一、メッセージボックスを表示できなかった場合、     本関数は、null を返します。 補説: メッセージボックスを表示したスクリプトのスレッドは、     待機状態になります。その時、他に実行可能なスレッドがあれば、     そのうちの最高優先順位のスレッドに実行権が譲渡されます。 注意: 本関数は、DLLのコールバック関数内では、実行できません。 用例: 
        ::Inform( "本処理は正常に終了しました!" );
Alert 関数 書式: ::Alert( <メッセージ> ) 概要: 警告用のメッセージボックスを表示します。 説明: 本関数は、引数の <メッセージ> で指定された文字列を、     警告用のメッセージボックスに表示します。     ここには、「OK」のボタンが1つあります。     このボタンが押されると、このメッセージボックスが閉じて、     本関数は、1 を返します。     万が一、メッセージボックスを表示できなかった場合、     本関数は、null を返します。 補説: メッセージボックスを表示したスクリプトのスレッドは、     待機状態になります。その時、他に実行可能なスレッドがあれば、     そのうちの最高優先順位のスレッドに実行権が譲渡されます。 注意: 本関数は、DLLのコールバック関数内では、実行できません。 用例: 
        ::Alert( "この操作は実行できません!" );
        ::Alert( ##ファイル ${ FileName } がありません!## );
Input 関数 書式: ::Input( <プロンプト>, <初期入力>, <入力リスト> ) 概要: 文字列入力用のダイアログボックスを表示します。 説明: このダイアログボックスは、次のように表示されます。       プロンプト        [文字列入力用コンボボックス]     ここで、      ・プロンプト欄には、<プロンプト> 引数で指定された       文字列が入ります。この指定がなければ、この欄は空です。      ・コンボボックスには、最初、<初期入力> 引数で指定された       文字列が入ります。この指定がなければ、ここは空になります。      ・コンボボックスの入力リストには、<入力リスト> 引数で       指定された内容が設定されます。この指定がなければ、       入力リストは空になります。       <入力リスト> は、任意個数の引数になります。この各引数は、       文字列、または、任意個数の文字列を要素に持つ連想配列で、       指定します。(用例参照)     本関数は、このダイアログボックスで入力された文字列を返します。     入力がキャンセルされた場合は、null を返します。     また、万が一、メッセージボックスを表示できなかった場合も、     null を返します。 補説: 本ダイアログボックスを表示したスクリプトのスレッドは、     待機状態になります。その時、他に実行可能なスレッドがあれば、     そのうちの最高優先順位のスレッドに実行権が譲渡されます。 注意: 本関数は、DLLのコールバック関数内では、実行できません。 例1: 
        ::Input( "好きな果物は:", "みかん", 
                 "りんご", "みかん", "桃", "柿", "ぶどう" );
例2:
        url_list =
        {
            "http://www.yahoo.co.jp",
            "http://www.google.co.jp",
            "http://ja.wikipedia.org/wiki",
        };
        ::Input( "URL:", "http://", url_list );
■システム関数 GetVersion 関数 書式: ::GetVersion() 説明: 本関数は、本スクリプト言語インタプリタの現バージョンを示す文字列を     返します。( 例: "1.24" ) GetTime 関数 書式: ::GetTime( 年, 月, 日, 曜, 時, 分, 秒, 千分秒 ) 説明: 本関数は、現在の時刻(ローカルタイム)を取得して、     引数の各変数に設定します。     その各内容は、引数の順番に応じて決まっています。     全部の引数を指定する必要はありません。     必要なものだけを指定して、不要なものは省略できます。     引数に指定する変数は、本関数が生成するわけではないので、     事前に生成しておく必要があります。     各引数には、次のような整数値が設定されます。       年: 4 桁の西暦年       月: 1 〜 12( 1月 〜 12月 )       日: 1 〜 31       曜: 0 〜 6 ( 日,月,火,...,土 )       時: 0 〜 23( 24 時間制 )       分: 0 〜 59       秒: 0 〜 59       千分秒: 0 〜 999( 1/1000 秒単位 ) 用例: (1) 全引数を指定する場合
            ::GetTime( 年'new!, 月'new!, 日'new!, 曜'new!,
                       時'new!, 分'new!, 秒'new!, 千分秒'new! );
            print 年, 月, 日, 曜, 時, 分, 秒, 千分秒;
     これを実行すると、例えば、次のようにプリントされます。       2007, 10, 24, 3, 10, 22, 34, 270     (2) 必要な引数だけを指定する場合
            ::GetTime( , month, day, , hour, minute );
     ここで、month, day, hour, minute の各変数が既存とします。      この場合は、月日と時分だけが取得されます。 SetOption 関数 書式: ::SetOption( <種別>, <データ> ) 説明: 本関数は、現状、将来のために予約されているだげで、特に有意義な処理は     行ないません。 SetIncludePath 関数 書式: ::SetIncludePath( <インクルードパス> ) 説明: 本関数は、#include マクロで指定されたファイルの検索パスの     追加分として、引数の <インクルードパス> を設定します。     複数のパスを指定する場合は、; で区切ります。この ; の前後に     空白等の隙間を入ることはできません。パス名の一部に扱われます。     相対パスを指定した場合、現時点のカレントパスが基準になります。     空または不正なパス名は、無視されます。     引数の <インクルードパス> が省略/不正、または、空文字列の場合、     当検索パスの追加分は、無しになります。     本関数の返値は、追加分として正常に設定されたパスの数になります。     設定に失敗した場合は、-1 が返ります。 用例: 
        ::SetIncludePath( $"D:\Script\Include;E:\Test\Include" );
SetLibraryPath 関数 書式: ::SetLibraryPath( <ライブラリーパス> ) 説明: 本関数は、モジュールファイルの検索パスの追加分として、     引数の <ライブラリーパス> を設定します。     複数のパスを指定する場合は、; で区切ります。この ; の前後に     空白等の隙間を入ることはできません。パス名の一部に扱われます。     相対パスを指定した場合、現時点のカレントパスが基準になります。     空または不正なパス名は、無視されます。     引数の <ライブラリーパス> が省略/不正、または、空文字列の場合、     当検索パスの追加分は、無しになります。     本関数の返値は、追加分として正常に設定されたパスの数になります。     設定に失敗した場合は、-1 が返ります。 用例: 
        ::SetLibraryPath( $"D:\Script\Library;E:\Test\Library" );
SetTitle 関数 書式: ::SetTitle( <タイトル> ) 説明: 本関数は、コンソールウィンドウのタイトルバーに、     引数の <タイトル> で指定された文字列を設定します。 注意: 本機能は、現状、アプリケーション組み込みの MikoScript でのみ、     実装されています。 ErrorMessage 関数 書式: ::ErrorMessage( <エラー識別番号>, <エラー付加情報> ) 説明: 本関数は、引数の <エラー識別番号> と <エラー付加情報> に対応する     エラーメッセージ文字列を返します。     この <エラー識別番号> と <エラー付加情報> は、エラー発生時に、     それぞれ、$err_code と $err_info という変数に、自動的に設定されます。     (「例外処理:エラー情報」参照 ) 用例: 
        print ::ErrorMessage( $err_code, $err_info );
Beep 関数 書式: ::Beep( <発音種別> ) 説明: 引数の <発音種別> で指定された音を発生します。     この音は、コントロールパネルの[サウンド]で設定されている音の     中から選びます。<発音種別> の値とその音との対応は次の通りです。       0: メッセージ (情報)       1: メッセージ (警告)       2: メッセージ (問い合わせ)       3: 一般の警告音       4: システムエラー     これらの音は、「なし」に設定されている場合もあります。     <発音種別> の指定音が、そのような音の場合、あるいは、     <発音種別> が、上記以外の値、または、省略の場合、     本関数は、所定のビープ音を発生します。     音の発生に成功すれば、本関数は、0 以外の整数値(通常 1 )を     返します。失敗した場合は、0 を返します。 注意: 本関数がコールされた時点で、引数の <発音種別> で指定された音が     既に発生中の場合、先の方が優先されて、後からの方は無効になります。 ■クリップボード操作  クリップボードを操作する関数は、::Clipboard 箱に入っています。但し、 現状、文字列関連の関数しかありません。これらについて、次に説明します。 GetText 関数 書式: ::Clipboard.GetText() 説明: 本関数は、現クリップボードの内容がテキストなら、その文字列を     返します。現クリップボードの内容がテキストでなければ、null を     返します。いずれの場合でも、現クリップボードの内容は変わりません。 用例: 次のスクリプトは、現クリップボードの内容をプリントします。
          print ::Clipboard.GetText();
SetText 関数 書式: ::Clipboard.SetText( <文字列> ) 説明: 本関数は、引数の <文字列> を、クリップボードに設定します。     この設定に成功した時、本関数は、その文字列のバイト数を返します。     引数が不正等で、設定ができなかった時は、null を返します。 用例: 次のスクリプトは、クリップボードに「Hello」という文字列を格納して、     それをプリントします。
          ::Clipboard.SetText( "Hello" );
          print ::Clipboard.GetText();   // → Hello
IsText 関数 書式: ::Clipboard.IsText() 説明: 本関数は、現クリップボードの内容がテキストなら、真値(1)を、     さもなければ、偽値(0)を返します。 用例: 次のスクリプトは、クリップボードの内容が文字列なら 1 を、     さもなければ 0 を、プリントします。
          print ::Clipboard.IsText();
■数学関数  数学関数には、以下の関数があります。これらはどれも、::Math 箱に入って います。そのため、各関数をコールするときは、例えば、::Math.sqrt( x ) の ようにする必要があります。但し、
        'AddScope( ::Math )  または scope ::Math { ... } 等
とすれば、関数名単独(例えば、sqrt( x ) など)で、使用することができます。 また、使用頻度の高い関数や、少しでも実行速度を上げたい関数等に対しては、 その関数への参照を使います。例えば、
        Round := ::Math.round;
としておけば、Round( x, n ) で、四捨五入関数がコールできます。  数学関数の引数は、浮動小数点型でも、整数型でも構いません。 但し、以下の n の引数は、整数型を期待しているので、浮動小数点型で 渡された場合、小数点以下は切り捨てられます。  数学関数の返値は、特に明記していなければ、浮動小数点型になります。
abs(x) x の絶対値( x が整数型なら返値も整数型 )
sqrt(x) x の平方根
sin(x) x の正弦値
cos(x) x の余弦値
tan(x) x の正接値
arctan(x,y) 平面座標系でX軸と原点から点(x,y)への線分の成す角度
-π/2 ≦ 返値 ≦ +π/2(単位:ラジアン、左回りが正)
exp(x) ex( e は自然対数の底)
log(x) x の自然対数値
log10(x)x の常用対数値
pow(x,y)xy( x の y 乗 )
ceil(x) x 以上の最小の整数の浮動小数点数値
floor(x)x 以下の最大の整数の浮動小数点数値
round(x,n) n > 0: 小数点以下第 n 桁未満の四捨五入値
n < 0: 小数点以上第 |n| 桁未満の四捨五入値
n = 0 or 省略: 小数点以下の四捨五入値
min(...) 引数(任意個数可)のうちの最小値
(全引数が整数なら返値も整数)
max(...) 引数(任意個数可)のうちの最大値
(全引数が整数なら返値も整数)
rand() 擬似乱数の整数値(全 32-bit 有効)⇒脚注
srand(n) 擬似乱数の種を設定(返値は無効) ⇒脚注
n 省略時は、システム時刻から適当に設定
■数値操作  ここでは、主に数値操作用の各種リレー型関数について、説明します。 'bool 関数 書式: <対象>'bool( a, b ) 説明: <対象> の「真偽判定」を行ない、その結果、<対象> が、       真なら a ( a 省略時は 1 )       偽なら b ( b 省略時は 0 )     を返します。     <対象> の真偽判定不能なら、null を返します。 'sign 関数 書式: <対象>'sign( a, b, c ) 説明: <対象> の数値の符号を調べて、その結果、<対象> が、       正なら a ( a 省略時は 1 )       0なら b ( b 省略時は 0 )       負なら c ( c 省略時は -1 )     を返します。     <対象> が数値以外なら、null を返します。 'abs 関数 書式: <対象>'abs 説明: <対象> の数値の絶対値を返します。     <対象> が数値以外なら、null を返します。 補説: 'abs と ::Math.abs() は、呼出形式が異なるだけで、機能的には同じです。 'int 関数 書式: <対象>'int 説明: <対象> を整数値に変換して返します。 ⇒詳細 'float 関数 書式: <対象>'float 説明: <対象> を浮動小数点値に変換して返します。 ⇒詳細 'cut 関数 書式: <対象>'cut( <最小値>, <最大値> ) 説明: <対象> の数値を、引数の <最小値> と <最大値> の範囲でカットした値を     返します。つまり、この返値は、       <対象> が <最小値> 以下の時、<最小値> に、       <対象> が <最大値> 以上の時、<最大値> に、       <対象> が <最小値> 〜 <最大値> 範囲内の時、<対象> の値そのままに、     なります。但し、       <最小値> が省略時、<最大値> だけでのカットが行われます。       <最大値> が省略時、<最小値> だけでのカットが行われます。       <最小値> と <最大値> の両方が省略時、<対象> 値がそのまま返ります。 補説: <対象>, <最小値>, <最大値> は、数値(整数または実数)に限ります。     この三者がどれも整数の時、返値は整数になります。     この三者のどれかが実数の時、返値は実数になります。     この三者のどれかが数値以外の時、返値は null になります。 用例: 次のスクリプトを実行すると、「0, 0, 0, 0, 1, 2, 2, 」とプリントされます。
          for( N = -3 ; N <= 3 ; N++ )
              print N'cut( 0, 2 ),-;
'in? 関数 書式: <対象>'in?( <最小値>, <最大値> ) 説明: <対象> の数値が、引数の <最小値> と <最大値> の範囲内なら真、さもなければ     偽を返します。但し、       <最小値> が省略時、<対象> が <最大値> 以下か否かの真偽値を返します。       <最大値> が省略時、<対象> が <最小値> 以上か否かの真偽値を返します。       <最小値> と <最大値> の両方が省略なら、null を返します。       <対象> が省略なら、null を返します。 補説: <対象>, <最小値>, <最大値> は、数値(整数または実数)に限ります。     この三者のどれかに非数値が指定された時、返値は null になります。 用例: 次のスクリプトを実行すると、「0, 0, 0, 1, 1, 1, 0, 」とプリントされます。
          for( N = -3 ; N <= 3 ; N++ )
              print N'in?( 0, 2 ),-;
'cbo 関数 書式: <対象>'cbo 説明: <対象> の整数値のバイト順を入れ替えた値を返します。     これは、いわゆる「Big Endian」と「Little Endian」の相互変換になります。     <対象> は整数値のみです。<対象> が整数値以外の時は、null を返します。     <対象> に、次の入出力形式が設定されていれば、そのデータ形式に準拠します。       'LONG, 'ULONG, 'SHORT, 'USHORT, 'BYTE, 'UBYTE 用例: 次のスクリプトを実行すると、各コメントに示すようにプリントされます。
          print 0x12345678'cbo'x(8);     // → 78563412
          print 0x1234'LONG'cbo'x(8);    // → 34120000
          print 0x1234'USHORT'cbo'x(8);  // → 00003412
'shift 関数 書式: <対象>'shift( n, s, e ) 説明: <対象> が整数値の時、その第 s ビットから第 e ビットまでを、符号なしで、      n ビットシフトした整数値を返します。ここで、       n > 0: 右シフト, n < 0: 左シフト       s, e = 0,1,2, ... ,31 ( s >= e のこと )       n 省略時、n=1、s 省略時、s=31、e 省略時、e=0 として扱われます。 補説: 符号ありのビットシフトは、>> と << の演算子で行ないます。     <対象> が文字列の時、⇒参照     エラー時、null を返します。 用例: 次のスクリプトを実行すると、各コメントに示すようにプリントされます。
          print 0x12345678'shift(+4)'x(8);        // → 01234567
          print 0x12345678'shift(-4)'x(8);        // → 23456780
          print 0x12345678'shift(+4,23,8)'x(8);   // → 12034578
          print 0x12345678'shift(-4,23,8)'x(8);   // → 12456078
          print 0x12345678'shift(+2,15,8)'x(8);   // → 12341578
          print 0x12345678'shift(-3,19,4)'x(8);   // → 1222B388
'rotate 関数 書式: <対象>'rotate( n, s, e ) 説明: <対象> が整数値の時、その第 s ビットから第 e ビットまでを、n ビット     回転した整数値を返します。ここで、       n > 0: 右回転, n < 0: 左回転       s, e = 0,1,2, ... ,31 ( s >= e のこと )       n 省略時、n=1、s 省略時、s=31、e 省略時、e=0 として扱われます。 補説: <対象> が文字列の時、⇒参照     <対象> が複合箱の時、⇒参照     エラー時、null を返します。 用例: 次のスクリプトを実行すると、各コメントに示すようにプリントされます。
          print 0x12345678'rotate(+4)'x(8);        // → 81234567
          print 0x12345678'rotate(-4)'x(8);        // → 23456781
          print 0x12345678'rotate(+4,23,8)'x(8);   // → 12634578
          print 0x12345678'rotate(-4,23,8)'x(8);   // → 12456378
          print 0x12345678'rotate(+2,15,8)'x(8);   // → 12349578
          print 0x12345678'rotate(-3,19,4)'x(8);   // → 1232B3A8
'reverse 関数 書式: <対象>'reverse( s, e ) 説明: <対象> が整数値の時、その第 s ビットから第 e ビットまでのビット列の     ビット順を逆にした整数値を返します。ここで、       s, e = 0,1,2, ... ,31 ( s >= e のこと )       s 省略時、s=31、e 省略時、e=0 として扱われます。 補説: <対象> が文字列の時、⇒参照     <対象> が複合箱の時、⇒参照     <対象> がメモリーブロックの時、⇒参照     エラー時、null を返します。 用例: 次のスクリプトを実行すると、各コメントに示すようにプリントされます。
          print 0x12345678'reverse'x(8);         // → 1E6A2C48
          print 0x12345678'reverse(23,8)'x(8);   // → 126A2C78
          print 0x12345678'reverse(15,8)'x(8);   // → 12346A78
          print 0x12345678'reverse(19,4)'x(8);   // → 123E6A28
'sfv 関数 書式: <対象>'sfv 説明: DLLの関数の引数や返値に、単精度実数型しか使えない場合が偶にあります。     ところが、このデータ型は、現状、本スクリプトの基本データ型には含まれて     いないので、この 'sfv 関数で対処します。この関数は次のように機能します。     <対象> が整数値の時:       その整数値(32-bit)を単精度実数(32-bit)のビット列と解釈して、       その値に相当する倍精度実数値を返します。     <対象> が倍精度実数値の時:       その値に相当する単精度実数値のビット列(32-bit)を整数値(32-bit)として       返します。 用例: 例えば、OpenGL の DLL の関数は、各種のデータ型が使えるようになっていますが、     なかには、単精度実数の引数しか使えない関数もあります。その場合、次のように     します。
            glClearColor( 0.0'sfv, 0.2'sfv, 0.5'sfv, 1.0'sfv );
■メモリー操作  ここでは、メモリー操作用の各種リレー型関数について、説明します。通常、これらは、 全く使う必要はありません。ただ、DLL関数の呼び出しなどで、どうしても必要になる 場合があるので、特別に用意されています。なお、これらの関数を使って誤ったメモリー アドレスにアクセスしてしまうと、プログラムが暴走しかねないので、くれぐれもご注意 ください。 'addr 関数 書式: <対象>'addr 説明: <対象> が格納されている内部メモリーの先頭アドレスを返します。     <対象> が箱なら、その中身は、数値、文字列、純粋配列Bufferクラスの       インスタンスのうちのどれかに限ります。     <対象> が実値なら、それは、数値、文字列に限ります。     <対象> が、Bufferクラスのインスタンスの場合、そのバッファの現入出力位置の       アドレスを返します。     <対象> が、これら以外の時は、0 を返します。 用例: 次のスクリプトは、箱 A 内の整数値のアドレスを 16進 8桁でプリントします。
          A = 1;
          print A'addr'x(8);
'pv 関数 書式: <アドレス>'pv       ・・・ 指定アドレスから数値を取得     <アドレス>'pv( <数値> )  ・・・ 指定アドレスへ数値を設定 説明: <アドレス> は、アクセス先の内部メモリーの先頭アドレスになります。     <アドレス> は、整数値で指定する必要があります。     <アドレス> に、次の入出力形式が設定されていれば、そのアクセス対象の数値の       データ形式が規定されます。        'BYTE, 'UBYTE 'SHORT, 'USHORT, 'LONG, 'ULONG, 'FLOAT, 'DOUBLE      例えば、<アドレス> に 'USHORT の形式が設定されていると、アクセス対象の      数値は、16 ビット整数(符号有り)になります。      なお、<アドレス> に入出力形式が設定されていなければ、'LONG になります。     <数値> の指定が無い場合:       <アドレス> から指定のデータ形式の数値を読み出して返します。     <数値> の指定が有る場合:       指定のデータ形式でその <数値> を <アドレス> へ設定します。       この場合の返値は、<数値> になります。 用例: 次のスクリプトは、箱 A 内の整数値のアドレスにある符号無し 16 ビット形式の     整数値を読み出して、16進 8桁でプリントします。
          A = 0x12345678;
          print A'addr'USHORT'pv'x(8);   // → 00005678
'ps 関数 書式: <アドレス>'ps        ・・・ 指定アドレスから文字列を取得     <アドレス>'ps( <文字列> )  ・・・ 指定アドレスへ文字列を設定 説明: <アドレス> は、アクセス先の内部メモリーの先頭アドレスになります。     <アドレス> は、整数値で指定する必要があります。     <文字列> の指定が無い場合:       <アドレス> から文字列を読み出して返します。     <文字列> の指定が有る場合:       その <文字列> を <アドレス> へ設定します。       この場合の返値は、実際にメモリーに書き込んだバイト数になります。 補説: 本関数では、0終端されている文字列しか扱いません。 用例: 次のスクリプトは、箱 A 内にある文字列のアドレスから文字列を取得して     プリントします。結局、箱 A をプリントするのと、同じ結果になります。
          A = "Hello";
          print A'addr'ps;   // → "Hello"
'MEMBLK 関数 書式:(1) 'MEMBLK( bp, bn, bs )    (2) <対象>'MEMBLK( bo, bn ) 説明: 書式(1)の場合:       引数 bp は、メモリーブロックの開始アドレス       引数 bn は、メモリーブロックのバイト数       引数 bs は、メモリのアクセス確認を行なうか否かの真偽値      を指定します。引数 bp, bn は必須です。bs は通常省略します(補注参照)。      返値は、正常終了時、そのメモリーブロックを示す値になります。        異常終了時、null になります。     書式(2)の場合:       <対象> は、バッファ(Bufferクラスのインスタンス)、純粋配列、文字列、         数値、or メモリーブロックの、箱または値       引数 bo は、<対象> のデータ領域内の特定部分のオフセット       引数 bn は、<対象> のデータ領域内の特定部分のバイト数      を指定します。引数 bo が省略時は 0、引数 bn が省略時は、そのデータ領域      内の bo から最後までのバイト数として扱います。従って、bo と bn が両方      省略された時は、そのデータ領域全体がその特定部分になります。      返値は、正常終了時、その特定部分のメモリーブロックを示す値になります。        異常終了時、null になります。 補説: ・<対象> が、バッファの場合、そのデータ領域は、現入出力位置から末尾までに       なります。     ・'MEMBLK が返すメモリーブロックを示す値は、箱に格納できます。また、関数       の引数や返値にもなれます。     ・'MEMBLK は、ファイルやバッファの入出力時にも使用できますが、特定の箱や       値に対して、入出力形式を設定するものではありません。 補注: 引数 bs を真値に指定すると、メモリー操作関数( 'pv, 'ps, 'memcpy, 'memcmp,     'fill のどれか)が、このメモリーブロック以外の範囲内をアクセスした時に、     例外を発生してくれます。 用例: 「メモリーブロックに対する入出力」参照。     'memcpy, 'memcmp, 'fill の用例参照。 'memcpy 関数 書式:(1) dp'memcpy( sp, sn )    (2) A'memcpy( sp, sn )    (3) A'memcpy( B ) 説明: 本関数は、メモリー領域をコピーします。     コピー先のメモリー領域は、次のように、本対象の dp または、A で指定します。       dp : その開始アドレス       A : そのメモリーブロック     コピー元のメモリー領域は、次のように、引数 sp, sn または、B で指定します。       sp : その開始アドレス       sn : そのバイト数       B : そのメモリーブロック 補説: 書式(2)と(3)の場合、コピー先とコピー元のメモリー領域のサイズが     異なれば、小さい方が採用されます。     コピー先とコピー元のメモリー領域が重なっていても、特に支障はありません。 返値: 正常時、コピーしたバイト数     異常時、null 補説: sp, sn, dp は、整数値で指定する必要があります。 用例: 次のスクリプトは、純粋配列 A へ純粋配列 B の全データをコピーします。
        A 'LONG( 100 );
        B 'LONG( 100 );
        A'MEMBLK'memcpy( B'MEMBLK );
'memcmp 関数 書式:(1) dp'memcmp( sp, sn )    (2) A'memcmp( sp, sn )    (3) A'memcmp( B ) 説明: 本関数は、2つのメモリー領域の内容を比較します。     1つ目のメモリー領域は、次のように、本対象の dp または、A で指定します。       dp : その開始アドレス       A : そのメモリーブロック     2つ目のメモリー領域は、次のように、引数 sp, sn または、B で指定します。       sp : その開始アドレス       sn : そのバイト数       B : そのメモリーブロック 補説: 書式(2)と(3)の場合、2つのメモリー領域のサイズが異なれば、      その内容は異なると判断します。 返値: 2つのメモリー領域の内容が同じなら、0 を返し、異なれば、0 以外の     整数値を返します。もし、エラーがあれば、null を返します。 補説: sp, sn, dp は、整数値で指定する必要があります。 用例: 次のスクリプトは、純粋配列 A と純粋配列 B の全データの内容を比較します。     この場合、両者の内容は同じなので、0 がプリントされます。
        A 'LONG( 200 );
        B 'LONG( 200 );
        print A'MEMBLK'memcmp( B'MEMBLK );
'fill 関数 書式: <対象>'fill( v ) 説明: <対象> のメモリーブロック内の全データを指定値 v で充満させます。     引数 v は、整数か実数で指定します。     引数 v に設定されている入出力形式で、充満要素が決定されます。      例えば、v が -34'SHORT の場合、充満要素は、値が -34 の 16-bit(2-byte)      整数値になります。<対象> のメモリーブロック内は、この値で充満されます。     引数 v の入出力形式が未設定なら、'LONG として扱われます。     引数 v が省略/不正時は、0'UBYTE として扱われます。 返値: 正常時、充満したバイト数     異常時、null 用例: 次のスクリプトは、純粋配列の全要素の値を設定します。
        A'SHORT( 500 );
        A'MEMBLK'fill( 123'SHORT );    // 全要素を 123 に設定
        A'MEMBLK'fill;                 // 全要素を 0 に設定
        B'DOUBLE( 100 );
        B'MEMBLK'fill( 1.0'DOUBLE );   // 全要素を 1.0 に設定
'reverse 関数 書式: <対象>'reverse( u ) 説明: <対象> のメモリーブロック内の全データの並びを逆順にします。     引数 u は、各要素のバイト数( =1,2,4,8 のみ )     引数 u が省略/不正時は、u=1 として扱われます。 返値: 正常時、<対象> のメモリーブロックを示す値     異常時、null 補説: <対象> が文字列の時、⇒参照     <対象> が整数値の時、⇒参照     <対象> が複合箱の時、⇒参照 用例: 次を実行すると、「9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 」とプリントされます。
        A'LONG( 10 );                   // 純粋配列( 32-bit整数 10 個 )
        for( i = 0 ; i < 10 ; i++ )     // 各要素に、0,1,...,9 の値を設定
            A(i) = i;
        A'MEMBLK'reverse( 4 );          // 各要素を逆順にする
        for( i = 0 ; i < 10 ; i++ )     // 各要素の値をプリント
            print A(i),-;
■レジストリー操作  レジストリーを操作するための各種関数やクラスが、::Registry 箱に入っています。 これらを使って、レジストリーキーの、開閉、読み出し、書き込み、削除、列挙などを 行なうことができます。なお、レジストリーには、Windows のシステム設定等の重要な 情報が保持されているので、その扱いには充分な注意が必要です。 レジストリーの定義済みキーのうち、本スクリプトで扱えるのは、次の4つです。    HKEY_CLASSES_ROOT    HKEY_CURRENT_USER    HKEY_LOCAL_MACHINE    HKEY_USERS レジストリーを操作する形態には、次の2通りがあります。  A.レジストリーキーを直接操作する場合:     この操作形態では、レジストリーキーの読み出しや書き込みなどを行なう際、     そのキーの開閉が、内部で自動的に行なわれるので、スクリプト言語レベル     での記述は必要ありません。この形態は、レジストリーキーを単発的に操作     するだけの時に便利です。ちなみに、この場合、対象のレジストリーキーは、     定義済みキーをルートとする「絶対キー経路」で指定します。  B.レジストリーキークラスのインスタンスで操作する場合:     この操作形態は、ファイルの入出力操作の場合とよく似ています。     まず、レジストリーキーを開いて、そのインスタンスを生成します。     次に、それを使って、読み出しや書き込みなどの操作を行ないます。     最後に、そのインスタンスを破棄して、そのレジストリーキーを閉じます。     ちなみに、この場合、対象のレジストリーキーは、そのインスタンスの     レジストリーキーを基点とした「相対キー経路」で指定します。 なお、以下の説明で、A〜 や B〜 という表記がありますが、それらは、上記の操作 形態の A と B に対応します。 ●レジストリーキーインスタンスの生成 A記法: ::Registry.OpenKey( <絶対キー経路>, <モード> ); B記法: regkey.OpenKey( <相対キー経路>, <モード> );      ( regkey は、基点となるレジストリーキーインスタンス ) A引数: <絶対キー経路> は、定義済キーから対象キーまでの絶対経路を指定します。       これは、省略不可です。 B引数: <相対キー経路> は、基点キーから対象キーまでの相対経路を指定します。       これが省略または空文字列の時、regkey 自身が対象になります。       つまり、同キーを再度(別途)開くことになります。  引数: <モード> は、以下の文字列でアクセスモードを指定します。        "r" 読み出し, "w" 書き込み, "a" 読み書き      これらのモードは既存経路が対象で、もし対象キーまでの経路が無ければ、      エラーになります。一方、これらに + をつけた        "r+", "w+", "a+"      の各モードでは、それぞれ、アクセス形態は同じですが、対象キーまでの      経路名が無い時には、その経路は新規に作成されます。      <モード> が省略/無効時は、"r" として扱われます。  返値: レジストリーキーインスタンス(正常時) or null(エラー時) A用例: 
        regkey1 = ::Registry.OpenKey( $"HKEY_LOCAL_MACHINE\SOFTWARE", "r" );
B用例: 
        regkey2 = regkey1.OpenKey( "Apsaly", "w+" );
●レジストリーキーインスタンスの破棄  レジストリーキーインスタンスは、delete 文で、明示的に破棄できます。また、それが 含まれているスコープが無くなる時に、自動的(暗黙的)に破棄されます。これは、他の インスタンスの場合と同様です。レジストリーキーインスタンスが破棄されると、その レジストリーキーがクローズされます。 ●レジストリーキー内の指定値の取得 A記法: ::Registry.GetValue( <絶対キー経路>, <値名> ); B記法: regkey.GetValue( <相対キー経路>, <値名> );      ( regkey は、基点となるレジストリーキーインスタンス ) A引数: <絶対キー経路> は、定義済キーから基準キーまでの絶対経路を指定します。       これは、省略不可です。 B引数: <相対キー経路> は、基点キーから基準キーまでの相対経路を指定します。       これが省略または空文字列の時、regkey 自身が基準になります。  引数: <値名> は、基準キー内の取得する値の名前を指定します。       これが省略または空文字列の時、基準キーのデフォールト値が取得されます。  返値: その取得値を返します。このデータ型は、元が、整数値なら整数値、文字列      なら文字列、バイナリー値なら純粋配列、になります。なお、元がこれ以外      のデータ型の場合には、null が返ります。また、エラー時にも、null が      返ります。 A用例: 
          ::Registry.GetValue( $"HKEY_LOCAL_MACHINE\SOFTWARE\Apsaly", "Location" )
B用例: 
          regkey = ::Registry.OpenKey( $"HKEY_LOCAL_MACHINE\SOFTWARE" );
          regkey.GetValue( "Apsaly", "Location" );
●レジストリーキー内の指定値の設定 A記法: ::Registry.SetValue( <絶対キー経路>, <値名>, <値>, <型> ); B記法: regkey.SetValue( <相対キー経路>, <値名>, <値>, <型> );      ( regkey は、基点となるレジストリーキーインスタンス ) A引数: <絶対キー経路> は、定義済キーから基準キーまでの絶対経路を指定します。       これは、省略不可です。 B引数: <相対キー経路> は、基点キーから基準キーまでの相対経路を指定します。       これが省略または空文字列の時、regkey 自身が基準になります。  引数: <値名> は、基準キー内の設定する値の名前を指定します。       この名前の値が存在しない時は、その名前の値が新規に生成されます。       この引数が省略/無効時、基準キーのデフォールト値が、設定対象です。  引数: <値> は、その設定値を指定します。       その設定先のデータの種類は、この <値> のデータ型が、         数値なら整数値(REG_DWORD)に、         文字列なら文字列値(REG_SZ)に、         純粋配列なら <型> で指定された種類に       なります。なお、これ以外のデータの種類は、設定できません。  引数: <型> は、<値> が純粋配列の場合に限り、設定先のデータの種類を、以下の       文字列で指定します。         "bin": バイナリー値(REG_BINARY)         "xsz": 展開可能な文字列(REG_EXPAND_SZ)         "msz": 複数文字列(REG_MULTI_SZ)         "qwd": 64ビット整数値(REG_QWORD)       なお、<型> が省略/無効時は、バイナリー値(REG_BINARY)になります。  返値: 設定したバイト数(正常時) or -1(エラー時)  補説: 基準キーまでの経路が存在しない時は、その経路が新規に生成されます。 A用例: 
        ::Registry.SetValue( $"HKEY_LOCAL_MACHINE\SOFTWARE\Apsaly",
               "Location", $"C:\Tools\Apsaly" );
B用例: 
        regkey = ::Registry.OpenKey( $"HKEY_LOCAL_MACHINE\SOFTWARE\Apsaly" );
        regkey.SetValue( "", "Location", $"C:\Tools\Apsaly" );
●レジストリーキー内のキー/値の削除 A記法: ::Registry.Delete( <絶対キー経路>, <キー名>, <値名> ); B記法: regkey.Delete( <相対キー経路>, <キー名>, <値名> );      ( regkey は、基点となるレジストリーキーインスタンス ) A引数: <絶対キー経路> は、定義済キーから基準キーまでの絶対経路を指定します。       これは、省略不可です。 B引数: <相対キー経路> は、基点キーから基準キーまでの相対経路を指定します。       これが省略または空文字列の時、regkey 自身が基準になります。  引数: <キー名> は、基準キー内の削除するキーの名前を指定します。       これが省略/無効時、キーの削除は行ないません。  引数: <値名> は、基準キー内の削除する値の名前を指定します。       これが空文字列の時、基準キーのデフォールト値を削除します。       これが省略/無効時、値の削除は行ないません。  返値: 削除したキー/値の個数(正常時) or -1(エラー時)  補説: キーを削除すると、その中のすべてのキーと値も削除されます。 A用例: 
        ::Registry.Delete( $"HKEY_LOCAL_MACHINE\SOFTWARE\Apsaly",
                 null, "Location" );
B用例: 
        regkey = ::Registry.OpenKey( $"HKEY_LOCAL_MACHINE\SOFTWARE\Apsaly" );
          regkey.Delete( null, null, "Location" );
●レジストリーキー内のキー名/値名の取得 B記法: regkey.Enum( <種類>, <順番> );      ( regkey は、基準となるレジストリーキーインスタンス )  引数: <種類> は、キー名と値名のどちらを取得するのかを、それぞれ、       "key" と "val" のどちらかの文字列で指定します。       この指定が省略/不正時は、"key" の指定として扱われます。  引数: <順番> は、基準キー内の何番目のキーまたは値の名前を取得するのかを示す       インデックス値を指定します。この値は、0, 1, 2, ... で、それぞれ、       第1番目、第2番目、第3番目、・・・ に対応します。      基準キー内にあるキーまたは値の総個数を取得したい場合は、<順番> の       指定を省略します。  返値: <種類> と <順番> に対応するキーまたは値がある場合、その名前を返します。      <順番> が省略/無効の時は、基準キー内にある <種類> のキーまたは値の       総個数を返します。      エラーの時は、null を返します。  用例: 
          regkey = ::Registry.OpenKey( $"HKEY_LOCAL_MACHINE\SOFTWARE\Apsaly" );
          regkey.Enum( "key", i );  // 基準キー内の i 番目のキーの名前を取得
          regkey.Enum( "val" );     // 基準キー内にある値の個数を取得
●レジストリー操作プログラム例 例1:   ファイルの拡張子 "mc" を、Apsaly テキストエディタに関連付けている場合、  次のスクリプトを実行すると、その内容がプリントされます。
    print ::Registry.GetValue( 
              $"HKEY_CLASSES_ROOT\Apsaly.mc\shell\open\command" );
    print ::Registry.GetValue( 
              $"HKEY_CLASSES_ROOT\Apsaly.mc\DefaultIcon" );
例2:   次のスクリプトは、HKEY_LOCAL_MACHINE\SOFTWARE 直下にある全てのキーを  列挙します。
    regkey = ::Registry.OpenKey( $"HKEY_LOCAL_MACHINE\SOFTWARE" );
    N = regkey.Enum( "key" );
    for( i = 0 ; i < N ; i++ )
        print regkey.Enum( "key", i );
    //delete regkey;    // ← これは実行しなくても、レジストリーキーは、
                        //    自動的に閉じる( ⇒ 参照
例3:   レジストリー操作関連のエラーが発生した時、OnError へエラーワープする例を、  次に示します。
    print ::Registry.GetValue( $"HKEY_CURRENT_USER\@@@Apsaly@@@" );
    print "この直前でエラーワープが発生するので、ここには来ない!";
    return;

  OnError:
    print "エラーワープ: " : ::ErrorMessage( $err_code, $err_info );
    return;

≪ 脚注 ≫  本スクリプト言語では、乱数発生アルゴリズムとして、 MT(メルセンヌ・ツイスタ)法を使用させて頂いています。 この著作権と使用条件の抜粋を、以下に示します。 This is a Mersenne Twister pseudorandom number generator with period 2^19937-1 with improved initialization scheme, modified on 2002/2/10 by Takuji Nishimura and Makoto Matsumoto. This is a faster version by taking Shawn Cokus's optimization, Matthe Bellew's simplification, Isaku Wada's real version. Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.