日本語

Practical: Macro Usage

Here are concrete samples for streamlining development using LuneScript's macro features.

Step 1: Debug Print (_DBGP)

A debugging macro that displays a variable's name and its value simultaneously.

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

let hoge = 100;
_DBGP( hoge ); // Displays hoge = 100

Step 2: Custom Assertion (_Assert)

A macro that displays a message and halts if a condition is not met.

macro _Assert( cond: __exp, msg: str ) {
    if not (,,cond) {
        print( "Assertion failed: %s" (,,msg) );
        // Add logic to interrupt processing as needed
    }
}

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

Step 3: Measurement of Execution Time (_Measure)

A macro that measures the execution time of a specific code block.

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: Loading External File Content as Constants

An example using macro-statement to read external configuration files at compile time and expand them as constants within the code.

macro _LoadConfig( path: str ) {
    {
        let mut list: List<str> = [];
        // Open file at compile time
        if! let mut file = io.open( path ) {
            let mut line = file.read( "*l" );
            while line {
                // Remove newlines and add to list
                list.insert( (unwrap line).gsub( "[\r\n]", "" ) );
                line = file.read( "*l" );
            }
            file.close();
        }
    }
    // Expand as const
    pub const CONFIG_ITEMS = ,,list;
}

// Content of config.txt is expanded into CONFIG_ITEMS at compile time
_LoadConfig( "config.txt" );

foreach item in CONFIG_ITEMS {
    print( item );
}
By using io.open within a macro, you can incorporate external resources directly as part of your program. This is extremely useful for things like data embedding.

Summary

By leveraging LuneScript macros, you can flexibly achieve boilerplate reduction and complex compile-time-only logic.

Refer to the Macros Reference for more advanced features.