対応する構文
パーサは次を含む Lua 構文を受理します。goto/::label::- ビット演算子(
&|~<<>>) - 整数除算
// - ロングブラケット文字列・コメント(
[[ ]]、[=[ ]=]) - 可変長引数
... - 複数戻り値・複数代入
- ステップ付き数値 for、汎用 for(
ipairs/pairsなどとの組み合わせ) - クロージャ・アップバリュー
- 16 進数値・浮動小数点数・指数表記(16 進浮動小数点を含む)
setmetatable/getmetatable/coroutine.* のような呼び出しは、Lua の構文としては通常の関数呼び出しなので構文的には受理されます。ただし、これらの名前自体が Stormworks サンドボックスで利用できないため、意味検証の段階で警告またはエラーになります(後述)。
構文エラーと Stormworks 非対応 API の違い
- 構文エラー(
syntax-error): パーサ/レキサーの段階で検出される、Lua として不正な入力です。常にseverity: errorで、これがあるとコンパイルできません。 - Stormworks で利用できないグローバル(
sw-unavailable-global): 構文的には正しい Lua ですが、参照しているグローバル(標準 Lua のビルトインとして知られているが Stormworks には存在しない名前)が実行時に存在しないケースです。検出対象の名前は次の 20 個です。
require はコンパイル時に静的展開されるため、このリストには含まれません。analyze() では警告、compileProject()(minify 実行)ではエラーとして扱われます。自前で同名のグローバルを定義していれば対象外です。
error/assert は Stormworks 実機での可否が未確認のため、既知の非搭載ビルトインリストには含まれていません(検出対象外)。Stormworks で利用できるグローバルルート
resolver が標準で認識するグローバルルートは次の 16 個です。input.*/output.* は onTick コールバック(function onTick() ... end または onTick = function() ... end の本体、ネストした内側関数を含む)の中でのみ参照できます。それ以外の場所での参照は input-outside-ontick/output-outside-ontick として検出されます。関数呼び出しを経由した間接的な参照は現時点では検出されません。
意味保存モデル
StormMin はパース後に lexical binding を解決し、最適化の同値性判定には文字列名ではなく解決済みの binding identity を使います。そのためmath、screen、input、output、property などと同名のローカル変数や引数は、それらをシャドウしている限り builtin として扱われません。
主に次を解析した上で最適化を行います。
- binding の read/write
- ユーザー定義関数呼び出し/builtin 呼び出しの区別
- 順序付きの screen 副作用
- 例外が発生しうるかどうか
- コールバック内での安定性
screen.setColor/screen.draw* は順序付き副作用として扱われます。評価回数・評価順・例外発生位置を変える最適化は、必要な証明条件を満たさない限り採用されません。
pass ごとの ON/OFF(
passToggles)は通常のチューニングつまみではなく、問題が見つかった場合の一時的な回避手段として提供されています。壊れ得るコードのパターン
次のパターンを使うコードは、コンパイル結果に警告診断が付きます。これらは最適化の前提(クローズドワールドな静的解析)を崩す可能性があるためです。_ENV を介した動的なグローバルアクセスを行うコードは、StormMin がバインディングを静的に解決できないため、最適化の対象から除外されるか、意図しない結果になる可能性があります。rawget/rawset を使うテーブルはフィールド変換(キーの短縮など)の対象から除外されます。
数値モード
tolerant(既定):numericTolerance.abs/.relの範囲内の近似を許可します。exact: 近似やユニット再スケーリングなど、exact semantics を保証できない次の 12 pass を強制的に無効化します。
tolerant モードでも近似の対象になりません。