summary refs log tree commit diff stats
path: root/assets/tmpl
Commit message (Expand)AuthorAgeFilesLines
* fixed most example api calls with horizontal scrolling v0.2.1Ben Morrison2019-06-041-10/+10
* minor correction in landing page query output exampleBen Morrison2019-06-041-1/+1
* refactored landing page template and tweaked stylingBen Morrison2019-06-041-20/+37
* adding version to index template v0.2.0Ben Morrison2019-06-031-2/+2
* updated usage guide to reflect ?page=NBen Morrison2019-06-031-3/+5
* style changes for index.html templateBen Morrison2019-05-241-11/+13
* index page layout tweaksBen Morrison2019-05-231-4/+6
* updated index templateBen Morrison2019-05-221-5/+5
* updated template and adjusted stylingBen Morrison2019-05-191-7/+7
* template initialization addedBen Morrison2019-05-131-1/+52
* skeleton template for indexBen Morrison2019-05-131-0/+13
id='n141' href='#n141'>141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
================================
          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.

The ``nim`` executable processes the ``.nims`` configuration files in
the following directories (in this order; later files overwrite
previous settings):

1) If environment variable ``XDG_CONFIG_HOME`` is defined,
   ``$XDG_CONFIG_HOME/nim/config.nims`` or
   ``~/.config/nim/config.nims`` (POSIX) or
   ``%APPDATA%/nim/config.nims`` (Windows). This file can be skipped
   with the ``--skipUserCfg`` command line option.
2) ``$parentDir/config.nims`` where ``$parentDir`` stands for any
   parent directory of the project file's path. These files can be
   skipped with the ``--skipParentCfg`` command line option.
3) ``$projectDir/config.nims`` where ``$projectDir`` stands for the
   project's path. This file can be skipped with the ``--skipProjCfg``
   command line option.
4) A project can also have a project specific configuration file named
   ``$project.nims`` that resides in the same directory as
   ``$project.nim``. This file can be skipped with the same
   ``--skipProjCfg`` command line option.

For available procs and implementation details see `nimscript <nimscript.html>`_.


Limitations
===========

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

* Nim's FFI (foreign function interface) is not available in NimScript. This
  means that any stdlib module which relies on ``importc`` can not be used in
  the VM.

* ``ptr`` operations are are hard to emulate with the symbolic representation
  the VM uses. They are available and tested extensively but there are bugs left.

* ``var T`` function arguments rely on ``ptr`` operations internally and might
  also be problematic in some cases.

* More than one level of `ref` is generally not supported (for example, the type
  `ref ref int`).

* Multimethods are not available.

* ``random.randomize()`` requires an ``int64`` explicitly passed as argument, you *must* pass a Seed integer.

* ``unicode`` can be imported, but not ``unidecode``.


Standard library modules
========================

At least the following standard library modules are available:

* `macros <macros.html>`_
* `os <os.html>`_
* `strutils <strutils.html>`_
* `math <math.html>`_
* `distros <distros.html>`_
* `sugar <sugar.html>`_
* `algorithm <algorithm.html>`_
* `base64 <base64.html>`_
* `bitops <bitops.html>`_
* `chains <chains.html>`_
* `colors <colors.html>`_
* `complex <complex.html>`_
* `htmlgen <htmlgen.html>`_
* `httpcore <httpcore.html>`_
* `lenientops <lenientops.html>`_
* `mersenne <mersenne.html>`_
* `options <options.html>`_
* `parseutils <parseutils.html>`_
* `punycode <punycode.html>`_
* `random <punycode.html>`_
* `stats <stats.html>`_
* `strformat <strformat.html>`_
* `strmisc <strmisc.html>`_
* `strscans <strscans.html>`_
* `unicode <unicode.html>`_
* `uri <uri.html>`_
* `std/editdistance <editdistance.html>`_
* `std/wordwrap <wordwrap.html>`_
* `std/sums <sums.html>`_

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


NimScript as a configuration file
=================================

A command-line switch ``--FOO`` is written as ``switch("FOO")`` in
NimScript. Similarly, command-line ``--FOO:VAL`` translates to
``switch("FOO", "VAL")``.

Here are few examples of using the ``switch`` proc:

.. code-block:: nim
  # command-line: --opt:size
  switch("opt", "size")
  # command-line: --define:foo or -d:foo
  switch("define", "foo")
  # command-line: --forceBuild
  switch("forceBuild")

NimScripts also support ``--`` templates for convenience, which look
like command-line switches written as-is in the NimScript file. So the
above example can be rewritten as:

.. code-block:: nim
  --opt:size
  --define:foo
  --forceBuild

**Note**: In general, the *define* switches can also be set in
NimScripts using ``switch`` or ``--``, as shown in above
examples. Only the ``release`` define (``-d:release``) cannot be set
in NimScripts.


NimScript as a build tool
=========================

The ``task`` template that the ``system`` module defines allows a NimScript
file to be used as a build tool. The following example defines a
task ``build`` that is an alias for the ``c`` command:

.. code-block:: nim
  task build, "builds an example":
    setCommand "c"


In fact, as a convention the following tasks should be available:

=========     ===================================================
Task          Description
=========     ===================================================
``help``      List all the available NimScript tasks along with their docstrings.
``build``     Build the project with the required
              backend (``c``, ``cpp`` or ``js``).
``tests``     Runs the tests belonging to the project.
``bench``     Runs benchmarks belonging to the project.
=========     ===================================================


Look at the module `distros <distros.html>`_ for some support of the
OS's native package managers.


Nimble integration
==================

See the `Nimble readme <https://github.com/nim-lang/nimble#readme>`_
for more information.


Standalone NimScript
====================

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

.. code-block:: nim

  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

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

.. code-block:: nim

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

  echo "hello world"

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


Benefits
========

Cross-Platform
--------------

It is a cross-platform scripting language that can run where Nim 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:

.. code-block:: nim

  import 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 on compiled Nim and also on interpreted NimScript.

``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:

.. code-block:: nim

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

translations.cfg

.. code-block:: none

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


* `Nimterlingua <https://nimble.directory/pkg/nimterlingua>`_


Graceful Fallback
-----------------

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

See the following NimScript:

.. code-block:: nim

  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 Nim,
`occasionally new features might become available on NimScript <https://github.com/nim-lang/Nim/pulls?utf8=%E2%9C%93&q=nimscript>`_ ,
adapted from compiled Nim or added as new features on both.

Scripting Language with a Package Manager
-----------------------------------------

You can create your own modules to be compatible with NimScript,
and check `Nimble <https://nimble.directory>`_
to search for third party modules that may work on NimScript.

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.

* `An example of a third party NimScript that can be used as a project-agnostic tool. <https://github.com/kaushalmodi/nim_config#list-available-tasks>`_