構文拡張
このプラグインは、標準の Lua には無い簡易な記法をいくつか追加しています。キーボードで打ちやすく、 入力量と読み替えの手間を減らすための糖衣構文です。スクリプトは実行前に等価な標準 Lua へ変換されるため、 すべての実行エンジン(LuaJIT・MoonSharp・CPU カーネル)で同じように動きます。
? ! & | => ` や in < の並び)だけを入口にしているため、
通常の Lua スクリプトはそのまま動作します。
比較演算子
is と is not は、値どうしを比べる位置に書いたときだけ演算子として扱います。変数名としての is は変換しません。
| 書き方 | 意味 |
|---|---|
a is b | a == b |
a is not b | a ~= b |
a != b | a ~= b |
if frame is not 0 then
obj.x = 100
end
論理演算子
他言語でなじみのある記号を、Lua の and / or / not の別名として使えます。
| 書き方 | 意味 |
|---|---|
!a | not a |
a && b | a and b |
a || b | a or b |
if !hidden && frame != 0 then
obj.alpha = 255
end
複合代入
左辺の値を使って計算し、同じ場所へ書き戻す記法です。右辺は括弧で包んで展開するため、演算子の優先順位はそのまま保たれます。
| 書き方 | 展開後 |
|---|---|
x += 1 | x = x + (1) |
x -= 1 | x = x - (1) |
x *= 2 | x = x * (2) |
x /= 2 | x = x / (2) |
x %= 2 | x = x % (2) |
x ^= 2 | x = x ^ (2) |
s ..= "b" | s = s .. ("b")(文字列の連結) |
local total = 0
total += obj.track0
total *= 2
インクリメント
++ は行単位の文として使い、1 を加えて書き戻します。
count++
上の count++ は count = count + 1 に展開します。
nil 合体演算子
a ?? b は、a が nil のときだけ b を返します。
a and b or c と違い、a が false のときは false をそのまま返します。既定値を安全に書けます。
obj.x = obj.track0 ?? 100
a ?? b は左辺を 1 度だけ評価する無名関数に展開します。b は左辺が nil のときだけ評価されます。
代入をともなう演算子
変数が未設定・偽のときにまとめて代入する記法です。
| 書き方 | 意味 |
|---|---|
x ??= b | x が nil のときだけ b を代入 |
x ||= b | x = x or (b) |
x &&= b | x = x and (b) |
speed ??= 90
obj.rz = time * speed
範囲 for
数値 for を、範囲を視覚的に表す <開始..終了> で書けます。.. は終端を含み、
..< は終端を含みません。, のあとに増分を指定できます。
| 書き方 | 意味 |
|---|---|
for i in <0..10> do | for i = 0, 10 do(10 を含む) |
for i in <0..<10> do | for i = 0, (10) - 1 do(10 を含まない) |
for i in <0..10, 2> do | for i = 0, 10, 2 do(増分 2) |
local sum = 0
for i in <1..10> do
sum = sum + i
end
in < の並びは通常の Lua には現れないため、ipairs や pairs を使う汎用 for には影響しません。
三項演算子
条件 ? A : B は、条件が真のとき A を、偽のとき B を返します。
a and A or B と違い、A が false や nil のときも、その値をそのまま返します。
| 書き方 | 意味 |
|---|---|
c ? 1 : 2 | c が真なら 1、偽なら 2 |
obj.alpha = obj.frame == 0 ? 0 : 255
? : は条件を 1 度だけ評価する無名関数に展開します。: のあとにもう一度 ? : を書けば、else 側で分岐を続けられます。
nil 条件演算子
t?.name は、t が nil のときは nil を返し、そうでなければ t.name を返します。
nil の値へ添字アクセスして落ちるのを防ぎます。t?[k] と書けば添字でも同じことができます。
| 書き方 | 意味 |
|---|---|
t?.x | t が nil なら nil、そうでなければ t.x |
t?[k] | t が nil なら nil、そうでなければ t[k] |
local title = data?.title ?? "無題"
?. は対象を 1 度だけ評価する無名関数に展開します。a?.b?.c のように連ねれば、途中が nil でも安全にたどれます。
ラムダ式
(引数) => 式 は、その式を返す無名関数に展開します。引数が 1 つのときは括弧を省いて x => 式、
引数が無いときは () => 式 と書けます。本体には 1 つの式を書きます。
| 書き方 | 展開後 |
|---|---|
(a, b) => a + b | (function(a, b) return a + b end) |
x => x * 2 | (function(x) return x * 2 end) |
() => 1 | (function() return 1 end) |
local t = { 3, 1, 2 }
table.sort(t, (a, b) => a < b)
=> だけを入口にしているため、比較演算子の >= や <= には影響しません。
パイプ
x |> f は f(x) の形に展開し、左辺を関数の第 1 引数として渡します。
x |> f(a, b) のように引数を書いたときは、左辺が第 1 引数に入り、残りの引数は後ろへ続きます。
| 書き方 | 展開後 |
|---|---|
x |> f | f((x)) |
x |> clamp(0, 255) | clamp((x), 0, 255) |
local v = obj.track0 |> math.floor |> tostring
|> は左から右へ連ねられます。a |> f |> g は g(f(a)) と同じ順序で評価します。
補間文字列
バッククォート ` で囲んだ文字列の中に {式} を書くと、その値を tostring で文字列にして差し込みます。
{ } の中では拡張構文もそのまま使えます。
| 書き方 | 展開後 |
|---|---|
`x={a}` | ("x=" .. tostring(a)) |
`hello` | "hello" |
obj.text = `フレーム {obj.frame} / {obj.totalframe}`
` は変換しません。
範囲判定
x in <開始..終了> は、x がその範囲に入っているかどうかを判定します。
.. は終端を含み、..< は終端を含みません。
| 書き方 | 意味 |
|---|---|
x in <1..5> | 1 <= x and x <= 5 |
x in <1..<5> | 1 <= x and x < 5(5 を含まない) |
if obj.frame in <0..9> then
obj.alpha = 255
end
for i in <0..10> とは書く位置が異なるため、for のヘッダーには影響しません。
[fast] 高速化マーカー
obj.fill obj.convolve obj.resize は、処理量がしきい値以上で GPU の結果が CPU と一致すると確認できたとき、自動で GPU へ委譲します。[fast] を付けると、このしきい値を無視して強制的に GPU へ委譲します。YMM4 独自拡張です。
| 書き方 | 意味 |
|---|---|
[fast] の次の行に obj.convolve(k, 5) | しきい値を無視して GPU へ委譲を強制する |
obj.convolve(k, 5) | 処理量に応じて自動で GPU / CPU を判定する |
マーカーは単独の行に置いても、同じ行に続けて書いても構いません。GPU が使えない環境や GPU の結果が CPU と一致しない環境では、[fast] を付けても自動で CPU 実行に戻ります。
--track@size:Size,1,15,3,2
local n = math.floor(obj.track0)
if n % 2 == 0 then n = n + 1 end
local k = {}
for i = 1, n * n do k[i] = 1 end
[fast]
obj.convolve(k, n)
t[fast] のような添字アクセスは変換しません。[fast] を付けた対象が上記 3 関数以外のときはエラーを表示します。GPU 側の検証(ハードウェア対応と CPU との一致確認)は変わらず行われるため、結果が変わることはありません。従来エンジンと高速ランタイムの両方で動作します。処理量が小さいときは、GPU への委譲自体の往復コストが CPU 実行を上回ることがあり、[fast] を付けるとかえって遅くなる場合があります。