English

基本構文

LuneScript の基本的な構文について説明します。Lua の文法をベースにしつつ、静的型付けによる安全性を高めるための拡張が行われています。

コメント

LuneScript では C++ スタイルのコメントが使用できます。

// これは1行コメントです
let val = 1; // 行の途中からでも書けます

/*
  これは
  複数行の
  コメントです
*/
Lua 5.3 の // (切り捨て除算) は、LuneScript ではコメントとして扱われます。 切り捨て除算を行いたい場合は、int 同士の除算を行うか、明示的なキャストや関数を使用してください。

変数宣言

変数は let キーワードを使用して宣言します。LuneScript は静的型付け言語であるため、変数は型を持ちます。

基本的な宣言

let val: int = 1;

変数名の後に :型名 を記述します。宣言と同時に初期化を行うことが一般的です。

初期値の型が宣言された型と異なる場合、コンパイルエラーとなります。

// Error: int 型の変数に real 型の値は代入できません
let param: int = 1.5; 

型推論

初期値が与えられている場合、型宣言を省略することができます。コンパイラが右辺の値から型を推論します。

let val1 = 10;      // int として推論
let val2 = 1.5;     // real として推論
let val3 = "test";  // str として推論
let val4 = true;    // bool として推論

型を明示する必要があるのは、主に以下のようなケースです。

可変 (Mutable) と 不変 (Immutable)

let で宣言された変数は、デフォルトで 不変 (Immutable) です。再代入はできません。

再代入可能な変数を宣言するには、mut キーワードを使用します。

let mut count = 0;
count = count + 1; // OK

let fixed = 10;
// fixed = 20; // Error: Immutable variable cannot be modified

フロー解析による初期化 (変数初期化漏れ検知)

LuneScript では、変数の宣言時に初期化を行わなくても構いませんが、変数を参照する前には必ず初期化されている必要があります。

コンパイラはフロー解析を行い、すべての実行パスで変数が初期化されているかをチェックします(変数初期化漏れ検知)。

fn check( flag: bool ) {
    let val: int;

    if flag {
        val = 10;
    } else {
        val = 20;
    }
    
    // すべてのパスで初期化されているため OK
    print( val ); 
}

もし初期化されていないパスが存在する場合、コンパイルエラーとなります。

fn errorCase( flag: bool ) {
    let val: int;
    if flag {
        val = 10;
    }
    // else 節がないため、flag が false の場合に初期化されない
    // print( val ); // Error: variable 'val' may be uninitialized
}

このフロー解析による初期化は「遅延初期化」であり、mut 宣言は不要です(一度だけ代入されるため)。

スコープブロック

波括弧 { ... } で囲まれた部分はスコープブロックとなります。ブロック内で宣言された変数は、そのブロックの外からはアクセスできません。

let outer = 1;
{
    let inner = 2;
    print( outer, inner ); // 1 2
}
// print( inner ); // Error: 'inner' is undefined
シャドーイングの禁止:
LuneScript では、外側のスコープで既に定義されている変数と同名の変数を内側のスコープで定義すること(シャドーイング)はできません。
意図しない変数の参照ミスを防ぐための制約です。
let val = 1;
{
    // Error: shadowing symbol of val
    // let val = 2; 
}