構文リファレンス
NagiScript の構文全体を解説します。
このページは現行コンパイラーの正仕様に合わせてあります。実際に使えるキーワードは「fn,
val, var, if, else, for, while, match, struct, enum, impl,
unsafe, extern, export, return, in, as, break, continue,
true, false, print, println,
panic」と、for の増分指定 step
です(2026-08 の変更履歴 change.md で追加)。それ以外のキーワード(import
/ loop / async / await / type / const / class / interface /
trait / pub / and / or / not / null / void
など)は未実装であり、現行の
nagiscript コマンドではコンパイルできません。
プログラム構造
基本構造
// 出力は print / println(argc はちょうど 1 個)
fn main() {
println("Hello, World!")
println(42)
}
import
は未実装です。複数ファイルへの分割はできません。また
const(定数定義)や
void
の戻り値型も存在しません。戻り値のない関数は
-> を書きません。出力は組み込みの
print / println を使い、io.println
や std:io は利用できません。
変数宣言
不変変数
val x: i32 = 42
val name = "NagiScript" // 型推論
可変変数
var counter: i32 = 0
counter = 10 // OK
counter = counter + 1 // OK
変数宣言は val(不変)と
var(可変)の 2 種類です。定数キーワード
const は存在しません。文字列の型名は
string であり、str は unknown type
str エラーになります。
関数定義
基本構文
fn add(a: i32, b: i32) -> i32 {
return a + b
}
関数定義は
fn name(...) -> 型 { ... }
の形で、戻り値の型は
-> 構文で指定します。->
を省略した場合やブロック末尾の暗黙
return(式ブロック)は非対応です。戻り値を返す関数では必ず
return を明示してください。
ジェネリクス関数
fn first(list: List<i32>) -> i32 {
return list[0]
}
関数式(無名関数)の安定利用は未対応です。また
List<T> のジェネリクスは、LLVM
コード生成で
zext i64 to i64
エラーになりリンクに失敗する既知バグがあります。当面は構造体
+ 値渡しを推奨します。
出力
fn main() {
println("Hello, World!") // 改行付き
print("no newline") // 改行なし
print(42)
}
組み込みの出力は print(値) と
println(値) です。引数はちょうど 1
個で、文字列・数値・bool を表示できます。文字列の
+ による連結は使えません("Hello" + " World"
はコンパイルエラー)。
制御構文
if 文
if x > 5 {
println("大きい")
} else {
println("小さい")
}
関数のブロック末尾(} 直前)に置いた
if / match は、返り値の tail
式として扱われます。if / else
の両分岐が値を返せば、そのまま関数の戻り値になります
(return 不要)。else
が無い if x { return 1 }
のような、戻り値の欠ける経路はコンパイルエラーになります。通常の文としての
if
も従来どおり使えますが、ブロック途中の値は変数への代入で保持してください。
while ループ
var i = 0
while i < 5 {
println(i)
i = i + 1
}
for ループ(step 対応)
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
for i in 0..5 { println(i) } // 省略で 1 ずつ
for の範囲ループに任意の増分(ステップ値)を指定する
step 節が追加されました。省略時は従来どおり
1 ずつ増えます。負のステップは降順ループ
(10..0 step -1)で使えます。継続条件は
step * (end - i) > 0 で評価されるため、
0..10 step -1
のような「進まない向き」のループは即座に終了します。また、同じ変数名のループ変数を複数の
for で使い回す再宣言バグも修正されています
(while での書き換えも従来どおり可能)。
loop(未実装)
// loop は存在しない。while true を使う
while true {
println("回る")
break
}
無限ループ用の
loop キーワードは存在しません。while true { ... }
を使用してください。break /
continue は使用できます。
match 式
enum Status { Ok NotFound }
fn show(s: Status) {
val st = match s {
Ok => "200",
_ => "404",
}
println(st)
}
match のパターンは
裸の列挙バリアント名(Ok,
NotFound など)と
_ ワイルドカードを使用します。enum
のバリアント値を生成するときは
Status.Ok のように括弧は不要です(データを持つバリアントのみ括弧が必要、例: Some(42))。
型定義
構造体
struct Point { x: f32 y: f32 }
val p = Point { x: 3.0, y: 4.0 }
println(p.x)
impl ブロック(メソッド)
struct Point { x: f32 y: f32 }
impl Point {
fn show(self: Point) -> string {
return "point"
}
}
fn main() {
val p = Point { x: 1.0, y: 2.0 }
println(p.show())
}
メソッドは impl ブロックに定義します。fn Point.distance_to(self: Point, ...)
形式は動きません。また
self には型注釈が必須です。
self の渡し方は将来的に「常に暗黙の参照渡し」(Python
のオブジェクトモデルに近い)に統一する方針です。現在は値渡しですが、Rc
/ heap 系の型(List, Stack 等)は参照渡しに切り替える予定です。借用チェッカー(check_borrow)は未実装の方針であり、RC
ベースの所有権管理で運用する予定です(Rust
の借用チェックとは異なる設計)。
列挙型
enum Color {
Red
Green
Blue
}
ジェネリクス型
struct Vec2 {
x: f32
y: f32
}
Vec2<T> のようなジェネリクス構造体や
class / interface /
trait は未実装です。型パラメータは
List<i32> 以外では限定的です。実用法は
struct Vec2 { x: f32 y: f32 }
のような具体的な型で定義してください。
エラーハンドリング
Result 型(enum で自作)
enum Result { Ok Err }
fn divide(a: f64, b: f64) -> Result {
if b == 0.0 {
return Result.Err
}
return Result.Ok
}
組み込みの
Result<T, E> 型は存在せず、? 演算子(エラー伝播)も未実装です。エラーハンドリングが必要な場合は
enum で自分で定義し、if 文で分岐します。
ポインタ / unsafe
ポインタと unsafe ブロック
fn read(ptr: *i32) -> i32 {
unsafe { return *ptr }
}
var x = 42
val p = &x as *i32
println(read(p))
ポインタは *T 形式、アドレス取得は
&x as *T、参照外しは
unsafe { *ptr } を使います。ptr->
は未対応なので
*ptr と整数演算で代替してください。
Rc (参照カウント)
val data = Rc.new(Data { x: 10 })
val data2 = data // 参照の共有
Rc.new(値) /
.get() は存在しますが、.get()
の戻り値が意図と異なる場合がある既知の不具合があります。当面は構造体
+ 値渡しを推奨します。
モジュール
import(未実装)
// import は未実装(ロードマップ)
// 複数ファイルへの分割はできない
import は未実装です。"std:io"
などの標準モジュールも存在しないため、import "std:io"
のような書き方はできません。複数ファイルの分割は現行では行えません。
エクスポート(Wasm / C 向け)
export "C" fn add(a: i32, b: i32) -> i32 {
return a + b
}
export
は関数宣言の前置としてのみ使用できます(Wasm / C
向け)。正しい書き方は
export "C" fn add(...) -> i32 { ... }
の形です。export fn
という書き方は誤りです。Wasm 出力は
nagiscript wasm main.ngs [-o PATH]
でサポートされています。
extern(C 関数の宣言)
extern "C" fn strlen(s: *u8) -> i32
C 標準関数は
extern "C" fn で宣言して利用できます。std:math
/ std:fs / std:args /
std:async /
std:net
などのモジュールはすべて未実装(ロードマップ)です。
コメント
// 単一行コメント
/*
複数行コメント
*/
fn greet(name: string) -> string {
return name
}
演算子
算術演算子
| 演算子 | 説明 | 例 |
|---|---|---|
+ |
加算 | a + b |
- |
減算 | a - b |
* |
乗算 | a * b |
/ |
除算 | a / b |
% |
剰余 | a % b |
算術演算子(+ - *
/
%)は数値に対して正常に動作します。ただし文字列の
+
連結は使えません。詳細は「演算子リファレンス」を参照してください。
比較演算子
| 演算子 | 説明 | 例 |
|---|---|---|
== |
等しい | a == b |
!= |
等しくない | a != b |
< |
小さい | a < b |
> |
大きい | a > b |
<= |
以下 | a <= b |
>= |
以上 | a >= b |
論理演算子
| 演算子 | 説明 | 例 |
|---|---|---|
and |
論理AND | a and b |
or |
論理OR | a or b |
not |
論理NOT | not a |
論理演算は and or
not を使用します。&& / || /
! は使えません。
その他の演算子
| 演算子 | 説明 | 例 |
|---|---|---|
-> |
戻り値型の記法(関数定義) | fn f() -> i32 |
& |
アドレス取得 | &x as *i32 |
* |
参照外し(unsafe 内) | *ptr |
as |
型変換 | x as f64 |
->
は関数定義での戻り値型の記法としてのみ使用します(fn name(...) -> 型)。ptr->(ポインタ経由のメンバアクセス)は未対応です。?(エラー伝播)も未実装です。詳細は「演算子リファレンス」を参照してください。
