123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- ================================
- 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>`_
|