基本概念

変数、型、制御構文の基礎を学びます。


変数と定数

不変変数 (val)

filename.ngs
val x: i32 = 10
val name: string = "NagiScript"
val pi: f64 = 3.14159

val で宣言された変数は再代入できません。

可変変数 (var)

filename.ngs
var counter: i32 = 0
counter = 10  // OK
counter += 1  // OK

型推論

型を省略すると自動推論されます:

filename.ngs
val x = 10        // i32 と推論
val name = "Hello" // string と推論
val flag = true    // bool と推論

基本型

整数型

型 ビット幅 範囲
i8 8 -128 〜 127
i16 16 -32,768 〜 32,767
i32 32 約 ±21 億
i64 64 約 ±922京
u8 8 0 〜 255
u16 16 0 〜 65,535
u32 32 0 〜 約42億
u64 64 0 〜 約1844京
filename.ngs
val a: i32 = 42
val b: u8 = 255
val c: i64 = 999999999999

浮動小数点型

filename.ngs
val f1: f32 = 3.14
val f2: f64 = 2.71828182845

文字列型

現行仕様(v0.2.0)

型名は str ではなく string です。文字列の + による連結は未実装なので、"Hello, " + "World!" はコンパイルエラーになります。

filename.ngs
val s1: string = "Hello, World!"
val s2 = "型推論でもOK"

// 文字列同士は比較できる
val eq = s1 == s2  // false

文字列補間(f-string)

現行仕様

f"..." で変数を埋め込めます。式も { } 内に書けます。+ による文字列連結が未実装のため、文字列組み立ては f-string が主力になります。

filename.ngs
val name = "NagiScript"
val version = 42

// 変数の埋め込み
println(f"Hello, {name}!")           // Hello, NagiScript!

// 式も OK
println(f"version = {version + 1}") // version = 43

// 型名の埋め込み
val lang: string = "NGS"
println(f"lang = {lang}")           // lang = NGS

真偽値型

filename.ngs
val flag1: bool = true
val flag2 = false

// 論理演算は and / or / not(&& / || / ! は使えない)
if flag1 and not flag2 {
    println("ok")
}

Unit 型について

現行仕様(v0.2.0)

式としての単型 void(val x: void = void のような書き方)は現行では使用できません。戻り値のない関数は fn name() { ... } と書き、-> void は付けません。


制御構文

if 文

現行仕様(v0.2.0)

if は文として使うのが基本です。値を分岐させたい場合は var に代入してから if 文の中で代入します。なおブロック末尾 (} 直前)に置いた if / match は返り値の tail 式として扱われます (change.md, 2026-08)。通常位置での val x = if ... { } else { } のような代入は現行では対応していません。

filename.ngs
var result = ""
if x > 5 {
    result = "大きい"
} else {
    result = "小さい"
}

for ループ(step 対応)

現行仕様(change.md, 2026-08)

for i in 0..5 { } の範囲ループは使用できます。step 節で増分を指定でき(省略時は 1、負のステップは降順)、同じ変数名を複数の for で使い回す再宣言バグも修正されています。 while での書き換えも従来どおり可能です。

filename.ngs
for i in 0..5 { println(i) }           // 0 1 2 3 4
for i in 0..10 step 2 { println(i) }  // 0 2 4 6 8
for i in 10..0 step -3 { println(i) } // 10 7 4 1

while ループ

filename.ngs
var i = 0
while i < 5 {
    println(i)
    i = i + 1
}

// 無限ループ(loop キーワードは無い)
while true {
    // ...
}

match(パターンマッチング)

現行仕様(v0.2.0)

パターンは裸の列挙バリアント名(例 Ok, NotFound)と、ワイルドカード _ です。enum のバリアント値を生成するときは Status.Ok のように括弧は不要です(データを持つバリアントのみ括弧が必要、例: Some(42))。

filename.ngs
enum Status { Ok NotFound }

fn show(s: Status) {
    val st = match s {
        Ok => "200",
        _ => "404",
    }
    println(st)
}

fn main() {
    show(Status.Ok)
}

ブロック

現行仕様(v0.2.0)

ブロック末尾の式を値として返す「式ブロック」(val x = { ... a + b })はサポートされていません。ただし関数ブロック末尾の if / match は返り値の tail 式として扱われます(change.md, 2026-08)。それ以外は文としてのみ使用できます。

filename.ngs
// 文ブロック(スコープを区切る目的で使用)
{
    val a = 10
    val b = 20
    val c = a * b
}

型変換

隠示的変換 (i64 → i32)

filename.ngs
val a: i64 = 100
val b: i32 = a  // OK: i64 から i32 へ安全な縮小

型注釈による変換

filename.ngs
val x: i32 = 42
val y: f64 = x  // OK: i32 から f64 への拡張

文字列操作

現行仕様

文字列の連結 s + "..." は未実装です。文字列結合には f"..."(文字列補間)を使用してください。 s.len() のようなメソッドも現行では定義されていません。文字列は == / != での比較が可能です。

filename.ngs
val s = "Hello"

// 比較
val eq = s == "Hello"  // true
val ne = s != "World"  // true

// 文字列結合(+ は不可 → f-string を使う)
val joined = f"{s}, World!"  // "Hello, World!"

// 表示
println(joined)

コメント

filename.ngs
// これは単一行コメント

/*
   これは
   複数行コメント
*/

fn greet(name: string) {
    println(name)
}