nims.rst 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. ================================
  2. NimScript
  3. ================================
  4. .. default-role:: code
  5. .. include:: rstcommon.rst
  6. Strictly speaking, `NimScript` is the subset of Nim that can be evaluated
  7. by Nim's builtin virtual machine (VM). This VM is used for Nim's compiletime
  8. function evaluation features.
  9. The `nim`:cmd: executable processes the ``.nims`` configuration files in
  10. the following directories (in this order; later files overwrite
  11. previous settings):
  12. 1) If environment variable `XDG_CONFIG_HOME` is defined,
  13. ``$XDG_CONFIG_HOME/nim/config.nims`` or
  14. ``~/.config/nim/config.nims`` (POSIX) or
  15. ``%APPDATA%/nim/config.nims`` (Windows). This file can be skipped
  16. with the `--skipUserCfg`:option: command line option.
  17. 2) ``$parentDir/config.nims`` where ``$parentDir`` stands for any
  18. parent directory of the project file's path. These files can be
  19. skipped with the `--skipParentCfg`:option: command line option.
  20. 3) ``$projectDir/config.nims`` where ``$projectDir`` stands for the
  21. project's path. This file can be skipped with the `--skipProjCfg`:option:
  22. command line option.
  23. 4) A project can also have a project specific configuration file named
  24. ``$project.nims`` that resides in the same directory as
  25. ``$project.nim``. This file can be skipped with the same
  26. `--skipProjCfg`:option: command line option.
  27. For available procs and implementation details see `nimscript <nimscript.html>`_.
  28. Limitations
  29. ===========
  30. NimScript is subject to some limitations caused by the implementation of the VM
  31. (virtual machine):
  32. * Nim's FFI (foreign function interface) is not available in NimScript. This
  33. means that any stdlib module which relies on `importc` can not be used in
  34. the VM.
  35. * `ptr` operations are are hard to emulate with the symbolic representation
  36. the VM uses. They are available and tested extensively but there are bugs left.
  37. * `var T` function arguments rely on `ptr` operations internally and might
  38. also be problematic in some cases.
  39. * More than one level of `ref` is generally not supported (for example, the type
  40. `ref ref int`).
  41. * Multimethods are not available.
  42. * `random.randomize()` requires an `int64` explicitly passed as argument, you *must* pass a Seed integer.
  43. Standard library modules
  44. ========================
  45. At least the following standard library modules are available:
  46. * `macros <macros.html>`_
  47. * `os <os.html>`_
  48. * `strutils <strutils.html>`_
  49. * `math <math.html>`_
  50. * `distros <distros.html>`_
  51. * `sugar <sugar.html>`_
  52. * `algorithm <algorithm.html>`_
  53. * `base64 <base64.html>`_
  54. * `bitops <bitops.html>`_
  55. * `chains <chains.html>`_
  56. * `colors <colors.html>`_
  57. * `complex <complex.html>`_
  58. * `htmlgen <htmlgen.html>`_
  59. * `httpcore <httpcore.html>`_
  60. * `lenientops <lenientops.html>`_
  61. * `mersenne <mersenne.html>`_
  62. * `options <options.html>`_
  63. * `parseutils <parseutils.html>`_
  64. * `punycode <punycode.html>`_
  65. * `random <punycode.html>`_
  66. * `stats <stats.html>`_
  67. * `strformat <strformat.html>`_
  68. * `strmisc <strmisc.html>`_
  69. * `strscans <strscans.html>`_
  70. * `unicode <unicode.html>`_
  71. * `uri <uri.html>`_
  72. * `std/editdistance <editdistance.html>`_
  73. * `std/wordwrap <wordwrap.html>`_
  74. * `std/sums <sums.html>`_
  75. * `parsecsv <parsecsv.html>`_
  76. * `parsecfg <parsecfg.html>`_
  77. * `parsesql <parsesql.html>`_
  78. * `xmlparser <xmlparser.html>`_
  79. * `htmlparser <htmlparser.html>`_
  80. * `ropes <ropes.html>`_
  81. * `json <json.html>`_
  82. * `parsejson <parsejson.html>`_
  83. * `strtabs <strtabs.html>`_
  84. * `unidecode <unidecode.html>`_
  85. In addition to the standard Nim syntax (`system <system.html>`_ module),
  86. NimScripts support the procs and templates defined in the
  87. `nimscript <nimscript.html>`_ module too.
  88. See also:
  89. * `Check the tests for more information about modules compatible with NimScript. <https://github.com/nim-lang/Nim/blob/devel/tests/test_nimscript.nims>`_
  90. NimScript as a configuration file
  91. =================================
  92. A command-line switch `--FOO`:option: is written as `switch("FOO")` in
  93. NimScript. Similarly, command-line `--FOO:VAL`:option: translates to
  94. `switch("FOO", "VAL")`.
  95. Here are few examples of using the `switch` proc:
  96. .. code-block:: nim
  97. # command-line: --opt:size
  98. switch("opt", "size")
  99. # command-line: --define:release or -d:release
  100. switch("define", "release")
  101. # command-line: --forceBuild
  102. switch("forceBuild")
  103. NimScripts also support `--`:option: templates for convenience, which look
  104. like command-line switches written as-is in the NimScript file. So the
  105. above example can be rewritten as:
  106. .. code-block:: nim
  107. --opt:size
  108. --define:release
  109. --forceBuild
  110. **Note**: In general, the *define* switches can also be set in
  111. NimScripts using `switch` or `--`, as shown in above examples. Few
  112. `define` switches such as `-d:strip`:option:, `-d:lto`:option: and
  113. `-d:lto_incremental`:option: cannot be set in NimScripts.
  114. NimScript as a build tool
  115. =========================
  116. The `task` template that the `system` module defines allows a NimScript
  117. file to be used as a build tool. The following example defines a
  118. task `build` that is an alias for the `c`:option: command:
  119. .. code-block:: nim
  120. task build, "builds an example":
  121. setCommand "c"
  122. In fact, as a convention the following tasks should be available:
  123. ========= ===================================================
  124. Task Description
  125. ========= ===================================================
  126. `help` List all the available NimScript tasks along with their docstrings.
  127. `build` Build the project with the required
  128. backend (`c`:option:, `cpp`:option: or `js`:option:).
  129. `tests` Runs the tests belonging to the project.
  130. `bench` Runs benchmarks belonging to the project.
  131. ========= ===================================================
  132. Look at the module `distros <distros.html>`_ for some support of the
  133. OS's native package managers.
  134. Nimble integration
  135. ==================
  136. See the `Nimble readme <https://github.com/nim-lang/nimble#readme>`_
  137. for more information.
  138. Standalone NimScript
  139. ====================
  140. NimScript can also be used directly as a portable replacement for Bash and
  141. Batch files. Use `nim myscript.nims`:cmd: to run ``myscript.nims``. For example,
  142. installation of Nimble could be accomplished with this simple script:
  143. .. code-block:: nim
  144. mode = ScriptMode.Verbose
  145. var id = 0
  146. while dirExists("nimble" & $id):
  147. inc id
  148. exec "git clone https://github.com/nim-lang/nimble.git nimble" & $id
  149. withDir "nimble" & $id & "/src":
  150. exec "nim c nimble"
  151. mvFile "nimble" & $id & "/src/nimble".toExe, "bin/nimble".toExe
  152. On Unix, you can also use the shebang `#!/usr/bin/env nim`, as long as your filename
  153. ends with ``.nims``:
  154. .. code-block:: nim
  155. #!/usr/bin/env nim
  156. mode = ScriptMode.Silent
  157. echo "hello world"
  158. Use `#!/usr/bin/env -S nim --hints:off` to disable hints.
  159. Benefits
  160. ========
  161. Cross-Platform
  162. --------------
  163. It is a cross-platform scripting language that can run where Nim can run,
  164. e.g. you can not run Batch or PowerShell on Linux or Mac,
  165. the Bash for Linux might not run on Mac,
  166. there are no unit tests tools for Batch, etc.
  167. NimScript can detect on which platform, operating system,
  168. architecture, and even which Linux distribution is running on,
  169. allowing the same script to support a lot of systems.
  170. See the following (incomplete) example:
  171. .. code-block:: nim
  172. import std/distros
  173. # Architectures.
  174. if defined(amd64):
  175. echo "Architecture is x86 64Bits"
  176. elif defined(i386):
  177. echo "Architecture is x86 32Bits"
  178. elif defined(arm):
  179. echo "Architecture is ARM"
  180. # Operating Systems.
  181. if defined(linux):
  182. echo "Operating System is GNU Linux"
  183. elif defined(windows):
  184. echo "Operating System is Microsoft Windows"
  185. elif defined(macosx):
  186. echo "Operating System is Apple OS X"
  187. # Distros.
  188. if detectOs(Ubuntu):
  189. echo "Distro is Ubuntu"
  190. elif detectOs(ArchLinux):
  191. echo "Distro is ArchLinux"
  192. elif detectOs(Debian):
  193. echo "Distro is Debian"
  194. Uniform Syntax
  195. --------------
  196. The syntax, style, and rest of the ecosystem is the same as for compiled Nim,
  197. that means there is nothing new to learn, no context switch for developers.
  198. Powerful Metaprogramming
  199. ------------------------
  200. NimScript can use Nim's templates, macros, types, concepts, effect tracking system, and more,
  201. you can create modules that work on compiled Nim and also on interpreted NimScript.
  202. `func` will still check for side effects, `debugEcho` also works as expected,
  203. making it ideal for functional scripting metaprogramming.
  204. This is an example of a third party module that uses macros and templates to
  205. translate text strings on unmodified NimScript:
  206. .. code-block:: nim
  207. import nimterlingua
  208. nimterlingua("translations.cfg")
  209. echo "cat" # Run with -d:RU becomes "kot", -d:ES becomes "gato", ...
  210. translations.cfg
  211. .. code-block:: none
  212. [cat]
  213. ES = gato
  214. IT = gatto
  215. RU = kot
  216. FR = chat
  217. * `Nimterlingua <https://nimble.directory/pkg/nimterlingua>`_
  218. Graceful Fallback
  219. -----------------
  220. Some features of compiled Nim may not work on NimScript,
  221. but often a graceful and seamless fallback degradation is used.
  222. See the following NimScript:
  223. .. code-block:: nim
  224. if likely(true):
  225. discard
  226. elif unlikely(false):
  227. discard
  228. proc foo() {.compiletime.} = echo NimVersion
  229. static:
  230. echo CompileDate
  231. `likely()`, `unlikely()`, `static:` and `{.compiletime.}`
  232. will produce no code at all when run on NimScript,
  233. but still no error nor warning is produced and the code just works.
  234. Evolving Scripting language
  235. ---------------------------
  236. NimScript evolves together with Nim,
  237. `occasionally new features might become available on NimScript <https://github.com/nim-lang/Nim/pulls?utf8=%E2%9C%93&q=nimscript>`_ ,
  238. adapted from compiled Nim or added as new features on both.
  239. Scripting Language with a Package Manager
  240. -----------------------------------------
  241. You can create your own modules to be compatible with NimScript,
  242. and check `Nimble <https://nimble.directory>`_
  243. to search for third party modules that may work on NimScript.
  244. DevOps Scripting
  245. ----------------
  246. You can use NimScript to deploy to production, run tests, build projects, do benchmarks,
  247. generate documentation, and all kinds of DevOps/SysAdmin specific tasks.
  248. * `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>`_