NimScript

厳密に言うと、 NimScript は Nim に組み込まれている仮想マシン (VM) で評価可能な Nim のサブセットです。この VM は Nim の compiletime 関数による評価機能を使用しています。

nim の実行可能ファイルは以下のディレクトリにあるコンフィギュレーション・ファイル .nims を処理をします (この順序にて。なお、後続のファイルは以前の設定を上書きします):

  1. 環境変数 XDG_CONFIG_HOME が定義されていれば、 $XDG_CONFIG_HOME/nim/config.nims~/.config/nim/config.nims (POSIX) を、あるいは %APPDATA%/nim/config.nims (Windows) となります。このファイルはコマンドラインオプション --skipUserCfg でスキップできます。
  2. または $parentDir/config.nims です。なお、 $parentDir はプロジェクトファイルのパスから見た親ディレクトリの場所を表します。このファイルはコマンドラインオプション --skipParentCfg でスキップできます。
  3. あるいは $projectDir/config.nims です。なお、 $projectDir はプロジェクトにおけるパスの場所を表します。このファイルはコマンドラインオプション --skipProjCfg でスキップできます。
  4. このほかにも、プロジェクト専用のコンフィギュレーション・ファイルとして $project.nims という名前のファイルをプロジェクトで扱えます。なお、 $project.nim はプロジェクトと同一ディレクトリに存在します。同じく、このファイルはコマンドラインオプション --skipProjCfg でスキップできます。

利用可能なプロシージャと実装の詳細は nimscript を参照してください。

機能制限

NimScript には VM (仮想マシン) の実装による一部制限があります。

標準ライブラリのモジュール

最低でも下記の標準的ライブラリのモジュールは利用できます:

通常の Nim シンタックス (system モジュール) に加えて、 NimScripts では nimscript モジュールで定義されているプロシージャ、テンプレートもサポートしています。

コンフィギュレーション・ファイルとしての NimScript

NimScript ではコマンドラインスイッチ --FOOswitch("FOO") として記述します。同じく、コマンドラインスイッチ --FOO:VALswitch("FOO", "VAL") として解釈します。

これは switch プロシージャの用例です:

# コマンドライン: --opt:size
switch("opt", "size")
# コマンドライン: --define:foo or -d:foo
switch("define", "foo")
# コマンドライン: --forceBuild
switch("forceBuild")

利便性の観点から NimScript では -- テンプレートをサポートしており、 NimScript ファイルからそのままの状態で記述されたコマンドラインスイッチのように見えます。つまり、上述の用例を書き直すと:

--opt:size
--define:foo
--forceBuild

備考: 一般に NimScripts でスイッチを定義 (define) するには、上述の用例で示したとおり switch または -- で設定します。release の定義 (-d:release) は NimScripts で設定できません。

ビルドツールとしての NimScript

system モジュールで定義されている task テンプレートはビルドツールとして NimScript ファイルを使用可能にします。この用例では c コマンドのエイリアスとして build タスクを定義しています:

task build, "builds an example":
  setCommand "c"

事実上、共通仕様として以下のタスクは利用可能にしてください。

タスク説明
helpdocstrings で利用可能な NimScript のタスクをすべてリストにて表示します。
build要求されたバックエンドでプロジェクトをビルドします(c, cpp または js)。
testsプロジェクトに関連するテストを行います。
benchプロジェクトに関連するベンチマークを行います。

オペレーティング・システム標準のパッケージマネージャに関するサポート状況は distros モジュールを参照してください。

Nimble との統合

詳しい情報は Nimble の readme をお読みください。

NimScript のスタンドアローン動作

NimScript は Bash スクリプトやバッチファイルの移植性がある代替物としてそのまま使えます。myscript.nims を実行するには nim myscript.nims を使います。例えば、このシンプルなスクリプトで Nimble のインストールが完了します:

mode = ScriptMode.Verbose

var id = 0
while dirExists("nimble" & $id):
  inc id

exec "git clone https://github.com/nim-lang/nimble.git nimble" & $id

withDir "nimble" & $id & "/src":
  exec "nim c nimble"

mvFile "nimble" & $id & "/src/nimble".toExe, "bin/nimble".toExe

Unix では、ファイルの拡張子が .nims であれば shebang 構文である #!/usr/bin/env nim を使えます:

#!/usr/bin/env nim
mode = ScriptMode.Silent

echo "hello world"

ヒントを無効にするには #!/usr/bin/env -S nim --hints:off を使います。

利点

クロスプラットフォーム

NimScript は Nim が実行できる環境であれば併せて実行できるクロス・プラットフォーム対応のスクリプト言語です。例えば、 Linux や Mac では バッチファイルや PowerShell スクリプトは動かず、 Macでは Linux 用の Bash スクリプトは動作しません。また、バッチファイルにはユニットテスト用のツールが無いなどの問題があります。

NimScript はプラットフォーム、オペレーティング・システム、アーキテクチャ、および実行中の Linux ディストリビューションを検出できるため、同じスクリプトで様々なシステムのサポートが可能です。

下記の用例を参照してください (半完成品):

import distros

# アーキテクチャ
if defined(amd64):
  echo "Architecture is x86 64Bits"
elif defined(i386):
  echo "Architecture is x86 32Bits"
elif defined(arm):
  echo "Architecture is ARM"

# オペレーティング・システム
if defined(linux):
  echo "Operating System is GNU Linux"
elif defined(windows):
  echo "Operating System is Microsoft Windows"
elif defined(macosx):
  echo "Operating System is Apple OS X"

# ディストリビューション
if detectOs(Ubuntu):
  echo "Distro is Ubuntu"
elif detectOs(ArchLinux):
  echo "Distro is ArchLinux"
elif detectOs(Debian):
  echo "Distro is Debian"

シンタックスの統一

シンタックス、スタイル、それ以外のエコシステムはコンパイラ版 Nim と同じです。つまり、開発者はコンテキストの切り替えは不要であり、新しいことを学ぶ必要は一切ありません。

強力なメタプログラミング

NimScript は Nim のテンプレート、マクロ、型、概念、エフェクト・トラッキングシステムなどの様々な機能を使えます。また、コンパイル版 Nim と同じく インタプリタ方式の NimScript で動作するモジュールの作成ができます。

func は副作用の検査を行い、 debugEcho は期待した通り動き、関数型スクリプトによるメタプログラミングでも満足のいくものです。

これはマクロとテンプレートを用いて未変更の NimScript にあるテキスト文字列を翻訳するサードパーティ製モジュールの用例です:

import nimterlingua
nimterlingua("translations.cfg")
echo "cat"  # 実行すると -d:RU では "kot" となり、-d:ES では "gato" となる...

translations.cfg

[cat]
ES = gato
PT = minino
RU = kot
FR = chat

優美なるフォールバック

コンパイル版 Nim の一部機能は NimScript では動作しません。その代わり、優美でスムーズなフォールバック・デグラデーション (無分断型降格処理機能) が使われます。

下記の NimScript 参照してください:

if likely(true):
  discard
elif unlikely(false):
  discard

proc foo() {.compiletime.} = echo NimVersion

static:
  echo CompileDate

likely(), unlikely(), static: および {.compiletime.} は NimScript での実行時にコードを一切生成しませんが、エラーと警告は一切発生することなくコードは動作します。

進化するスクリプト言語

NimScript は Nim と共に進化します。時折、コンパイル版 Nim からの転用、または同時に新機能として追加され NimScript で利用可能 になります。

パッケージマネージャのスクリプト言語として

NimScript と互換性のあるモジュールを自作できます。なお、 NimScript で動作する可能性のあるサードパティ製のモジュールをお探しでしたら Nimble をご確認ください。

DevOps スクリプティング

NimScript は製品のデプロイ、テストの実行、プロジェクトの構築、ベンチマーク、ドキュメンテーションの生成、そしてあらゆる種類の DevOps/SysAdmin に特化したタスクで使えます。