summary refs log tree commit diff stats
path: root/doc/nims.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/nims.md')
-rw-r--r--doc/nims.md352
1 files changed, 352 insertions, 0 deletions
diff --git a/doc/nims.md b/doc/nims.md
new file mode 100644
index 000000000..987cc2096
--- /dev/null
+++ b/doc/nims.md
@@ -0,0 +1,352 @@
+================================
+          NimScript
+================================
+
+.. default-role:: code
+.. include:: rstcommon.rst
+
+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`:cmd: 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`:option: 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`:option: command line option.
+3) ``$projectDir/config.nims`` where ``$projectDir`` stands for the
+   project's path. This file can be skipped with the `--skipProjCfg`:option:
+   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`:option: 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.
+
+
+Standard library modules
+========================
+
+At least the following standard library modules are available:
+
+* [algorithm](algorithm.html)
+* [base64](base64.html)
+* [bitops](bitops.html)
+* [chains](chains.html)
+* [colors](colors.html)
+* [complex](complex.html)
+* [distros](distros.html)
+* [std/editdistance](editdistance.html)
+* [htmlgen](htmlgen.html)
+* [htmlparser](htmlparser.html)
+* [httpcore](httpcore.html)
+* [json](json.html)
+* [lenientops](lenientops.html)
+* [macros](macros.html)
+* [math](math.html)
+* [options](options.html)
+* [os](os.html)
+* [parsecfg](parsecfg.html)
+* [parsecsv](parsecsv.html)
+* [parsejson](parsejson.html)
+* [parsesql](parsesql.html)
+* [parseutils](parseutils.html)
+* [punycode](punycode.html)
+* [random](random.html)
+* [ropes](ropes.html)
+* [std/setutils](setutils.html)
+* [stats](stats.html)
+* [strformat](strformat.html)
+* [strmisc](strmisc.html)
+* [strscans](strscans.html)
+* [strtabs](strtabs.html)
+* [strutils](strutils.html)
+* [sugar](sugar.html)
+* [unicode](unicode.html)
+* [unidecode](unidecode.html)
+* [uri](uri.html)
+* [std/wordwrap](wordwrap.html)
+* [xmlparser](xmlparser.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.
+
+See also:
+* [Check the tests for more information about modules compatible with NimScript](
+  https://github.com/nim-lang/Nim/blob/devel/tests/test_nimscript.nims)
+
+
+NimScript as a configuration file
+=================================
+
+A command-line switch `--FOO`:option: is written as `switch("FOO")` in
+NimScript. Similarly, command-line `--FOO:VAL`:option: translates to
+`switch("FOO", "VAL")`.
+
+Here are few examples of using the `switch` proc:
+
+  ```nim
+  # command-line: --opt:size
+  switch("opt", "size")
+  # command-line: --define:release or -d:release
+  switch("define", "release")
+  # command-line: --forceBuild
+  switch("forceBuild")
+  # command-line: --hint[Conf]:off or --hint:Conf:off
+  switch("hint", "[Conf]:off")
+  ```
+
+NimScripts also support `--`:option: templates for convenience, which look
+like command-line switches written as-is in the NimScript file. So the
+above example can be rewritten as:
+
+  ```nim
+  --opt:size
+  --define:release
+  --forceBuild
+  ```
+
+**Note**: In general, the *define* switches can also be set in
+NimScripts using `switch` or `--`, as shown in above examples. Few
+`define` switches such as `-d:strip`:option:, `-d:lto`:option: and
+`-d:lto_incremental`:option: 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`:option: command:
+
+  ```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`:option:, `cpp`:option: or `js`:option:).
+`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`:cmd: to run ``myscript.nims``. For example,
+installation of Nimble could be accomplished with this simple script:
+
+  ```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``:
+
+  ```nim
+  #!/usr/bin/env nim
+  mode = ScriptMode.Silent
+
+  echo "hello world"
+  ```
+
+Use `#!/usr/bin/env -S nim e --hints:off` to disable hints and relax the file extension constraint.
+
+
+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:
+
+  ```nim
+  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 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:
+
+  ```nim
+  import nimterlingua
+  nimterlingua("translations.cfg")
+  echo "cat"  # Run with -d:RU becomes "kot", -d:ES becomes "gato", ...
+  ```
+
+translations.cfg
+
+  ```none
+  [cat]
+  ES = gato
+  IT = gatto
+  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:
+
+  ```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?q=nimscript+is%3Amerged),
+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)