NimScript

Strictly speaking, NimScript is the subset of Nim that can be evaluated by Nim's builtin virtual machine (VM). This VM is used for Nim's compiletime function evaluation features.

Intro to Scripting

NimScript can be used directly as a portable replacement for Bash and Batch files. Use nim myscript.nims to run myscript.nims. For example, installation of a program could be accomplished with this simple script:

mode = ScriptMode.Verbose

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

exec "git clone https://github.com/bar/foo.git" & $id

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

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

On Unix, you can also use the shebang #!/usr/bin/env nim, as long as your filename ends with .nims:

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

echo "hello world"

Use #!/usr/bin/env -S nim --hints:off to disable hints.

Dry-Run and Debugging

Defining scriptmode on the command-line like so: nim -d:scriptmode foo.nims ensures that it's run in WhatIf mode, where effects such as shell execution, file IO, and so on are logged to the console and never ran. There are additional options, see nimscript for details.

Extensions & Limitations

Since the VM is limited in what it can do for security reasons, a set of procs allowing for file IO, shell execution, and so on are availabe in the nimscript module. There is also support for some OS native package managers in the distros module.

NimScript is subject to some limitations caused by the implementation of the VM (virtual machine):

Standard library modules

At least the following standard library modules are available:

In addition to the standard Nim syntax (system module), NimScripts support the procs and templates defined in the nimscript module too.

See also:

Benefits

Cross-Platform

It is a cross-platform scripting language that can run where NimSkull can run, e.g. you can not run Batch or PowerShell on Linux or Mac, the Bash for Linux might not run on Mac, there are no unit tests tools for Batch, etc.

NimScript can detect on which platform, operating system, architecture, and even which Linux distribution is running on, allowing the same script to support a lot of systems.

See the following (incomplete) example:

import std/distros

# Architectures.
if defined(amd64):
  echo "Architecture is x86 64Bits"
elif defined(i386):
  echo "Architecture is x86 32Bits"
elif defined(arm):
  echo "Architecture is ARM"

# Operating Systems.
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"

# Distros.
if detectOs(Ubuntu):
  echo "Distro is Ubuntu"
elif detectOs(ArchLinux):
  echo "Distro is ArchLinux"
elif detectOs(Debian):
  echo "Distro is Debian"

Uniform Syntax

The syntax, style, and rest of the ecosystem is the same as for compiled Nim, that means there is nothing new to learn, no context switch for developers.

Powerful Metaprogramming

NimScript can use Nim's templates, macros, types, concepts, effect tracking system, and more, you can create modules that work in both a compiled or scripting context.

func will still check for side effects, debugEcho also works as expected, making it ideal for functional scripting metaprogramming.

This is an example of a third party module that uses macros and templates to translate text strings on unmodified NimScript:

import nimterlingua
nimterlingua("translations.cfg")
echo "cat"  # Run with -d:RU becomes "kot", -d:ES becomes "gato", ...

translations.cfg

[cat]
ES = gato
IT = gatto
RU = kot
FR = chat

Graceful Fallback

Some features of compiled NimSkull may not work on NimScript, but often a graceful and seamless fallback degradation is used.

See the following NimScript:

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

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

static:
  echo CompileDate

likely(), unlikely(), static: and {.compiletime.} will produce no code at all when run on NimScript, but still no error nor warning is produced and the code just works.

Evolving Scripting language

NimScript evolves together with NimSkull, occasionally new features might become available on NimScript , adapted from compiled NimSkull or added as new features on both.

DevOps Scripting

You can use NimScript to deploy to production, run tests, build projects, do benchmarks, generate documentation, and all kinds of DevOps/SysAdmin specific tasks.