Docsの目次

HighとLow

Highは字下げでブロックを書く.nagi、Lowは波括弧と;で書く.lowです。どちらもNagiの言語です。普段はHighで書き、関数の実装を差し替えたいときにLowを使えます。

このページの目次

HighをLowへ変換する

次をapp.nagiに保存します。

def score(value: i64) -> i64:
    return value * 2

def main():
    print(score(7))
nagic run app.nagi
nagic lower app.nagi

実行結果は14です。lowerは型・所有権を検査し、build/app/generated.lowにLowを出力します。Lowでは関数をfnで宣言し、ブロックを{ }で囲みます。生成された変数にはletと推論した型が付きます。

手書きLowで関数を差し替える

次を同じディレクトリのnative.lowに保存します。

@replace generated::score
fn optimized_score(value: i64) -> i64 {
    return value * 6;
}
nagic check app.nagi --native native.low
nagic run app.nagi --native native.low

今度は42と表示されます。High側の呼び出しはscore(7)のままで、実行する本体がLowのoptimized_scoreに置き換わります。@replace generated::scoreが差し替える対象を指定しています。

差し替え先は、引数の数・型、戻り値の型、asyncかどうかが元の関数と一致する必要があります。対象が存在しない場合や、同じ関数を複数回差し替える場合はエラーです。変更できるのは関数全体です。

generated.lowはコマンドを実行すると再生成されます。変更を残すにはnative.lowへ書いてください。--nativeは差し替えに加えて通常のLow関数も追加でき、Highからその関数を呼べます。設定を保存する方法はプロジェクト設定にあります。

Lowの文法

型、所有権、借用、Resultの扱いはHighと共通です。次はResultを処理する関数の例です。

fn number_or(text: view[str], fallback: i64) -> i64 {
    match parse_i64(text) {
        case Ok(number) { return number; }
        case Err(_) { return fallback; }
    }
}

OkとErrの両方が必要です。詳しくはエラー処理を参照してください。

現在のLowは、型付きの変数、view、class(Lowではrecord)、関数、分岐、ループ、async、scopeに対応しています。生ポインター、メモリ配置の指定、手動の確保・解放、SIMD命令、unsafe構文、C ABIは未対応です。Rustの関数を呼ぶ方法はファイルのimportとRust連携にあります。

Nagi 0.1のドキュメントこのページのソース