const NimMajor* {.intdefine.}: int = 1 ## is the major number of Nim's version. Example: ## ``` ## when (NimMajor, NimMinor, NimPatch) >= (1, 3, 1): discard ## ``` # see also std/private/since NimMinor* {.intdefine.}: int = 9 ## is the minor number of Nim's version. ## Odd for devel, even for releases. NimPatch* {.intdefine.}: int = 1 ## is the patch number of Nim's version. ## Odd for devel, even for releases. {.push profiler: off.} let nimvm* {.magic: "Nimvm", compileTime.}: bool = false ## May be used only in `when` expression. ## It is true in Nim VM context and false otherwise. {.pop.} const isMainModule* {.magic: "IsMainModule".}: bool = false ## True only when accessed in the main module. This works thanks to ## compiler magic. It is useful to embed testing code in a module. CompileDate* {.magic: "CompileDate".}: string = "0000-00-00" ## The date (in UTC) of compilation as a string of the form ## `YYYY-MM-DD`. This works thanks to compiler magic. CompileTime* {.magic: "CompileTime".}: string = "00:00:00" ## The time (in UTC) of compilation as a string of the form ## `HH:MM:SS`. This works thanks to compiler magic. proc defined*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.} ## Special compile-time procedure that checks whether `x` is ## defined. ## ## `x` is an external symbol introduced through the compiler's ## `-d:x switch `_ to enable ## build time conditionals: ## ``` ## when not defined(release): ## # Do here programmer friendly expensive sanity checks. ## # Put here the normal code ## ``` ## ## See also: ## * `compileOption <#compileOption,string>`_ for `on|off` options ## * `compileOption <#compileOption,string,string>`_ for enum options ## * `define pragmas `_ proc declared*(x: untyped): bool {.magic: "Declared", noSideEffect, compileTime.} ## Special compile-time procedure that checks whether `x` is ## declared. `x` has to be an identifier or a qualified identifier. ## ## This can be used to check whether a library provides a certain ## feature or not: ## ``` ## when not declared(strutils.toUpper): ## # provide our own toUpper proc here, because strutils is ## # missing it. ## ``` ## ## See also: ## * `declaredInScope <#declaredInScope,untyped>`_ proc declaredInScope*(x: untyped): bool {.magic: "DeclaredInScope", noSideEffect, compileTime.} ## Special compile-time procedure that checks whether `x` is ## declared in the current scope. `x` has to be an identifier. proc compiles*(x: untyped): bool {.magic: "Compiles", noSideEffect, compileTime.} = ## Special compile-time procedure that checks whether `x` can be compiled ## without any semantic error. ## This can be used to check whether a type supports some operation: ## ``` ## when compiles(3 + 4): ## echo "'+' for integers is available" ## ``` discard proc astToStr*[T](x: T): string {.magic: "AstToStr", noSideEffect.} ## Converts the AST of `x` into a string representation. This is very useful ## for debugging. proc runnableExamples*(rdoccmd = "", body: untyped) {.magic: "RunnableExamples".} = ## A section you should use to mark `runnable example`:idx: code with. ## ## - In normal debug and release builds code within ## a `runnableExamples` section is ignored. ## - The documentation generator is aware of these examples and considers them ## part of the `##` doc comment. As the last step of documentation ## generation each runnableExample is put in its own file `$file_examples$i.nim`, ## compiled and tested. The collected examples are ## put into their own module to ensure the examples do not refer to ## non-exported symbols. runnableExamples: proc timesTwo*(x: int): int = ## This proc doubles a number. runnableExamples: # at module scope const exported* = 123 assert timesTwo(5) == 10 block: # at block scope defer: echo "done" runnableExamples "-d:foo -b:cpp": import std/compilesettings assert querySetting(backend) == "cpp" assert defined(foo) runnableExamples "-r:off": ## this one is only compiled import std/browsers openDefaultBrowser "https://forum.nim-lang.org/" 2 * x proc compileOption*(option: string): bool {. magic: "CompileOption", noSideEffect.} = ## Can be used to determine an `on|off` compile-time option. ## ## See also: ## * `compileOption <#compileOption,string,string>`_ for enum options ## * `defined <#defined,untyped>`_ ## * `std/compilesettings module `_ runnableExamples("--floatChecks:off"): static: doAssert not compileOption("floatchecks") {.push floatChecks: on.} static: doAssert compileOption("floatchecks") # floating point NaN and Inf checks enabled in this scope {.pop.} proc compileOption*(option, arg: string): bool {. magic: "CompileOptionArg", noSideEffect.} = ## Can be used to determine an enum compile-time option. ## ## See also: ## * `compileOption <#compileOption,string>`_ for `on|off` options ## * `defined <#defined,untyped>`_ ## * `std/compilesettings module `_ runnableExamples: when compileOption("opt", "size") and compileOption("gc", "boehm"): discard "compiled with optimization for size and uses Boehm's GC" template currentSourcePath*: string = instantiationInfo(-1, true).filename ## Returns the full file-system path of the current source. ## ## To get the directory containing the current source, use it with ## `os.parentDir() `_ as `currentSourcePath.parentDir()`. ## ## The path returned by this template is set at compile time. ## ## See the docstring of `macros.getProjectPath() `_ ## for an example to see the distinction between the `currentSourcePath` ## and `getProjectPath`. ## ## See also: ## * `getCurrentDir proc `_ proc slurp*(filename: string): string {.magic: "Slurp".} ## This is an alias for `staticRead <#staticRead,string>`_. proc staticRead*(filename: string): string {.magic: "Slurp".} ## Compile-time `readFile `_ proc for easy ## `resource`:idx: embedding: ## ## The maximum file size limit that `staticRead` and `slurp` can read is ## near or equal to the *free* memory of the device you are using to compile. ## ``` ## const myResource = staticRead"mydatafile.bin" ## ``` ## ## `slurp <#slurp,string>`_ is an alias for `staticRead`. proc gorge*(command: string, input = "", cache = ""): string {. magic: "StaticExec".} = discard ## This is an alias for `staticExec <#staticExec,string,string,string>`_. proc staticExec*(command: string, input = "", cache = ""): string {. magic: "StaticExec".} = discard ## Executes an external process at compile-time and returns its text output ## (stdout + stderr). ## ## If `input` is not an empty string, it will be passed as a standard input ## to the executed program. ## ``` ## const buildInfo = "Revision " & staticExec("git rev-parse HEAD") & ## "\nCompiled on " & staticExec("uname -v") ## ``` ## ## `gorge <#gorge,string,string,string>`_ is an alias for `staticExec`. ## ## Note that you can use this proc inside a pragma like ## `passc `_ or ## `passl `_. ## ## If `cache` is not empty, the results of `staticExec` are cached within ## the `nimcache` directory. Use `--forceBuild` to get rid of this caching ## behaviour then. `command & input & cache` (the concatenated string) is ## used to determine whether the entry in the cache is still valid. You can ## use versioning information for `cache`: ## ``` ## const stateMachine = staticExec("dfaoptimizer", "input", "0.8.0") ## ``` proc gorgeEx*(command: string, input = "", cache = ""): tuple[output: string, exitCode: int] = ## Similar to `gorge <#gorge,string,string,string>`_ but also returns the ## precious exit code. discard