English

実践: マクロ活用

LuneScript のマクロ機能を使って、開発を効率化する具体的なサンプルを紹介します。

Step 1: デバッグプリント (_DBGP)

変数名とその値を一度に表示するデバッグ用マクロです。

macro _DBGP( val: __exp ) {
    print( "%s = %s" ( ,,,,val, ,,val ) );
}

let hoge = 100;
_DBGP( hoge ); // hoge = 100 と表示される

Step 2: カスタムアサーション (_Assert)

条件が満たされない場合にメッセージを表示して停止するマクロです。

macro _Assert( cond: __exp, msg: str ) {
    if not (,,cond) {
        print( "Assertion failed: %s" (,,msg) );
        // 必要に応じて処理を中断する記述を追加
    }
}

_Assert( 1 + 1 == 3, "Math is broken" );

Step 3: 処理時間の計測 (_Measure)

特定のコードブロックの実行時間を計測するマクロです。

macro _Measure( label: str, block: __block ) {
    {
        let startTime = os.clock();
        ,,block
        let endTime = os.clock();
        print( "%s: %f sec" (,,label, endTime - startTime) );
    }
}

_Measure( "Heavy Process", {
    let mut sum = 0;
    for i = 1, 1000000 {
        sum = sum + i;
    }
} );

Step 4: 外部ファイルの内容を定数としてロード

macro-statement を使用して、コンパイル時に外部設定ファイルなどを読み込み、コード内の定数として展開する例です。

macro _LoadConfig( path: str ) {
    {
        let mut list: List<str> = [];
        // コンパイル時にファイルを開く
        if! let mut file = io.open( path ) {
            let mut line = file.read( "*l" );
            while line {
                // 改行を取り除いてリストに追加
                list.insert( (unwrap line).gsub( "[\r\n]", "" ) );
                line = file.read( "*l" );
            }
            file.close();
        }
    }
    // const として展開
    pub const CONFIG_ITEMS = ,,list;
}

// config.txt の内容がコンパイル時に CONFIG_ITEMS に展開される
_LoadConfig( "config.txt" );

foreach item in CONFIG_ITEMS {
    print( item );
}
マクロの中で io.open を使うことで、外部リソースを直接プログラムの一部として組み込めます。これはデータの埋め込みなどに非常に有用です。

まとめ

LuneScript のマクロを活用することで、ボイラープレートの削減や、コンパイル時のみの複雑な処理を柔軟に実現できます。

さらに高度な機能については マクロ リファレンス を参照してください。