1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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
|
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 <nimc.html#compiler-usage-compileminustime-symbols>`_ 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 <manual.html#implementation-specific-pragmas-compileminustime-define-pragmas>`_
when defined(nimHasDeclaredMagic):
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>`_
else:
proc declared*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
when defined(nimHasDeclaredMagic):
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.
else:
proc declaredInScope*(x: untyped): bool {.magic: "DefinedInScope", noSideEffect, compileTime.}
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 <compilesettings.html>`_
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 <compilesettings.html>`_
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() <os.html#parentDir%2Cstring>`_ as `currentSourcePath.parentDir()`.
##
## The path returned by this template is set at compile time.
##
## See the docstring of `macros.getProjectPath() <macros.html#getProjectPath>`_
## for an example to see the distinction between the `currentSourcePath`
## and `getProjectPath`.
##
## See also:
## * `getCurrentDir proc <os.html#getCurrentDir>`_
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 <syncio.html#readFile,string>`_ 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 <manual.html#implementation-specific-pragmas-passc-pragma>`_ or
## `passl <manual.html#implementation-specific-pragmas-passl-pragma>`_.
##
## 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
|