# Module system

The compiler depends on the System module to work properly and the System module depends on the compiler. Most of the routines listed here use special compiler magic. Each module implicitly imports the System module; it must not be listed explicitly. Because of this there cannot be a user-defined module named `system`.

# Types

    int

  default integer type; bitwidth depends on architecture, but is always the same as a pointer

    int8

  signed 8 bit integer type

    int16

  signed 16 bit integer type

    int32

  signed 32 bit integer type

    int64

  signed 64 bit integer type

    uint

  unsigned default integer type

    uint8

  unsigned 8 bit integer type

    uint16

  unsigned 16 bit integer type

    uint32

  unsigned 32 bit integer type

    uint64

  unsigned 64 bit integer type

    float

  default floating point type

    float32

  32 bit floating point type

    float64

  64 bit floating point type

    bool = enum
      false = 0, true = 1

  built-in boolean type

    char

  built-in 8 bit character type (unsigned)

    string

  built-in string type

    cstring

  built-in cstring (compatible string) type

    pointer

  built-in pointer type, use the `addr` operator to get a pointer to a variable

    Ordinal[T]

    expr

  meta type to denote an expression (for templates)

    stmt

  meta type to denote a statement (for templates)

    typeDesc

  meta type to denote a type description

    void

  meta type to denote the absense of any type

    auto = expr

    any = distinct auto

    TSignedInt = int | int8 | int16 | int32 | int64

  type class matching all signed integer types

    TUnsignedInt = uint | uint8 | uint16 | uint32 | uint64

  type class matching all unsigned integer types

    TInteger = TSignedInt | TUnsignedInt

  type class matching all integer types

    TOrdinal = int | int8 | int16 | int32 | int64 | bool | enum | uint8 | uint16 |
        uint32

  type class matching all ordinal types; however this includes enums with holes.

    TReal = float | float32 | float64

  type class matching all floating point number types

    TNumber = TInteger | TReal

  type class matching all number types

    range[T]

  Generic type to construct range types.

    array[I, T]

  Generic type to construct fixed-length arrays.

    openarray[T]

  Generic type to construct open arrays. Open arrays are implemented as a pointer to the array data and a length field.

    varargs[T]

  Generic type to construct a varargs type.

    seq[T]

  Generic type to construct sequences.

    set[T]

  Generic type to construct bit sets.

    TSlice[T] = object
      a*, b*: T                   ## the bounds

  builtin slice type

    Byte = uint8

  this is an alias for `uint8`, that is an unsigned int 8 bits wide.

    Natural = range[0 .. high(int)]

  is an int type ranging from zero to the maximum value of an int. This type is often useful for documentation and debugging.

    Positive = range[1 .. high(int)]

  is an int type ranging from one to the maximum value of an int. This type is often useful for documentation and debugging.

    TObject = object

  the root of Nimrod's object hierarchy. Objects should inherit from TObject or one of its descendants. However, objects that have no ancestor are allowed.

    PObject = ref TObject

  reference to TObject

    TEffect = object of TObject

  base effect class; each effect should inherit from TEffect unless you know what you doing.

    FTime = object of TEffect

  Time effect.

    FIO = object of TEffect

  IO effect.

    FReadIO = object of FIO

  Effect describing a read IO operation.

    FWriteIO = object of FIO

  Effect describing a write IO operation.

    FExecIO = object of FIO

  Effect describing an executing IO operation.

    E_Base = object of TObject
      parent: ref E_Base          ## parent exception (can be used as a stack)
      name: cstring               ## The exception's name is its Nimrod identifier.
                                  ## This field is filled automatically in the
                                  ## ``raise`` statement.
      msg* {.exportc: "message".}: string ## the exception's message. Not
                                          ## providing an exception message
                                          ## is bad style.
      trace: string

  base exception class; each exception has to inherit from E_Base.

    EAsynch = object of E_Base

  Abstract exception class for asynchronous exceptions (interrupts). This is rarely needed: Most exception types inherit from ESynch

    ESynch = object of E_Base

  Abstract exception class for synchronous exceptions. Most exceptions should be inherited (directly or indirectly) from ESynch.

    ESystem = object of ESynch

  Abstract class for exceptions that the runtime system raises.

    EIO = object of ESystem

  raised if an IO error occured.

    EOS = object of ESystem

  raised if an operating system service failed.

    EInvalidLibrary = object of EOS

  raised if a dynamic library could not be loaded.

    EResourceExhausted = object of ESystem

  raised if a resource request could not be fullfilled.

    EArithmetic = object of ESynch

  raised if any kind of arithmetic error occured.

    EDivByZero = object of EArithmetic

  is the exception class for integer divide-by-zero errors.

    EOverflow = object of EArithmetic

  is the exception class for integer calculations whose results are too large to fit in the provided bits.

    EAccessViolation = object of ESynch

  the exception class for invalid memory access errors

    EAssertionFailed = object of ESynch

  is the exception class for Assert procedures that is raised if the assertion proves wrong

    EControlC = object of EAsynch

  is the exception class for Ctrl+C key presses in console applications.

    EInvalidValue = object of ESynch

  is the exception class for string and object conversion errors.

    EInvalidKey = object of EInvalidValue

  is the exception class if a key cannot be found in a table.

    EOutOfMemory = object of ESystem

  is the exception class for unsuccessful attempts to allocate memory.

    EInvalidIndex = object of ESynch

  is raised if an array index is out of bounds.

    EInvalidField = object of ESynch

  is raised if a record field is not accessible because its dicriminant's value does not fit.

    EOutOfRange = object of ESynch

  is raised if a range check error occured.

    EStackOverflow = object of ESystem

  is raised if the hardware stack used for subroutine calls overflowed.

    ENoExceptionToReraise = object of ESynch

  is raised if there is no exception to reraise.

    EInvalidObjectAssignment = object of ESynch

  is raised if an object gets assigned to its parent's object.

    EInvalidObjectConversion = object of ESynch

  is raised if an object is converted to an incompatible object type.

    EFloatingPoint = object of ESynch

  base class for floating point exceptions

    EFloatInvalidOp = object of EFloatingPoint

  Invalid operation according to IEEE: Raised by 0.0/0.0, for example.

    EFloatDivByZero = object of EFloatingPoint

  Division by zero. Divisor is zero and dividend is a finite nonzero number.

    EFloatOverflow = object of EFloatingPoint

  Overflow. Operation produces a result that exceeds the range of the exponent

    EFloatUnderflow = object of EFloatingPoint

  Underflow. Operation produces a result that is too small to be represented as a normal number

    EFloatInexact = object of EFloatingPoint

  Inexact. Operation produces a result that cannot be represented with infinite precision -- for example, 2.0 / 3.0, log(1.1) NOTE: Nimrod currently does not detect these!

    EDeadThread = object of ESynch

  is raised if it is attempted to send a message to a dead thread.

    TResult = enum
      Failure, Success

    TEndian = enum
      littleEndian, bigEndian

  is a type describing the endianness of a processor.

    TaintedString = string

  a distinct string type that is tainted. It is an alias for `string` if the taint mode is not turned on. Use the `-d:taintMode` command line switch to turn the taint mode on.

    TLibHandle = pointer

    TProcAddr = pointer

    TAddress = int

  is the signed integer type that should be used for converting pointers to integer addresses for readability.

    BiggestInt = int64

  is an alias for the biggest signed integer type the Nimrod compiler supports. Currently this is `int64`, but it is platform-dependant in general.

    BiggestFloat = float64

  is an alias for the biggest floating point type the Nimrod compiler supports. Currently this is `float64`, but it is platform-dependant in general.

    cchar = char

  This is the same as the type `char` in C.

    cschar = int8

  This is the same as the type `signed char` in C.

    cshort = int16

  This is the same as the type `short` in C.

    cint = int32

  This is the same as the type `int` in C.

    csize = int

  This is the same as the type `size_t` in C.

    clong = int

  This is the same as the type `long` in C.

    clonglong = int64

  This is the same as the type `long long` in C.

    cfloat = float32

  This is the same as the type `float` in C.

    cdouble = float64

  This is the same as the type `double` in C.

    clongdouble = BiggestFloat

  This is the same as the type `long double` in C. This C type is not supported by Nimrod's code generator

    cuchar = char

  This is the same as the type `unsigned char` in C.

    cushort = uint16

  This is the same as the type `unsigned short` in C.

    cuint = uint32

  This is the same as the type `unsigned int` in C.

    culong = uint

  This is the same as the type `unsigned long` in C.

    culonglong = uint64

  This is the same as the type `unsigned long long` in C.

    cstringArray = ptr array[0 .. 50000, cstring]

  This is binary compatible to the type `char**` in C. The array's high value is large enough to disable bounds checking in practice. Use cstringArrayToSeq to convert it into a `seq[string]`.

    PFloat32 = ptr float32

  an alias for `ptr float32`

    PFloat64 = ptr float64

  an alias for `ptr float64`

    PInt64 = ptr int64

  an alias for `ptr int64`

    PInt32 = ptr int32

  an alias for `ptr int32`

    TGC_Strategy = enum
      gcThroughput,               ## optimize for throughput
      gcResponsiveness,           ## optimize for responsiveness (default)
      gcOptimizeTime,             ## optimize for speed
      gcOptimizeSpace             ## optimize for memory footprint

  the strategy the GC should use for the application

    PFrame = ptr TFrame

  represents a runtime frame of the call stack; part of the debugger API.

    TFrame = object
      prev*: PFrame               ## previous frame; used for chaining the call stack
      procname*: cstring          ## name of the proc that is currently executing
      line*: int                  ## line number of the proc that is currently executing
      filename*: cstring          ## filename of the proc that is currently executing
      len*: int                   ## length of the inspectable slots

  the frame itself

    TFile = ptr CFile

  The type representing a file handle.

    TFileMode = enum
      fmRead,                     ## Open the file for read access only.
      fmWrite,                    ## Open the file for write access only.
      fmReadWrite,                ## Open the file for read and write access.
                                  ## If the file does not exist, it will be
                                  ## created.
      fmReadWriteExisting,        ## Open the file for read and write access.
                                  ## If the file does not exist, it will not be
                                  ## created.
      fmAppend                    ## Open the file for writing only; append data
                                  ## at the end.

  The file mode when opening a file.

    TFileHandle = cint

  type that represents an OS file handle; this is useful for low-level file access

    TAlignType = BiggestFloat

    TRefCount = int

    PNimrodNode = ref TNimrodNode

  represents a Nimrod AST node. Macros operate on this type.

# Vars

    programResult: int

  modify this varialbe to specify the exit code of the program under normal circumstances. When the program is terminated prematurelly using `quit`, this value is ignored.

    globalRaiseHook: proc (e: ref E_Base): bool {.nimcall.}

  with this hook you can influence exception handling on a global level. If not nil, every 'raise' statement ends up calling this hook. Ordinary application code should never set this hook! You better know what you do when setting this. If `globalRaiseHook` returns false, the exception is caught and does not propagate further through the call stack.

    localRaiseHook: proc (e: ref E_Base): bool {.nimcall.}

  with this hook you can influence exception handling on a thread local level. If not nil, every 'raise' statement ends up calling this hook. Ordinary application code should never set this hook! You better know what you do when setting this. If `localRaiseHook` returns false, the exception is caught and does not propagate further through the call stack.

    outOfMemHook: proc () {.nimcall, tags: [].}

  set this variable to provide a procedure that should be called in case of an out of memory event. The standard handler writes an error message and terminates the program. outOfMemHook can be used to raise an exception in case of OOM like so:

      var gOutOfMem: ref EOutOfMemory
      new(gOutOfMem) # need to be allocated *before* OOM really happened!
      gOutOfMem.msg = "out of memory"

      proc handleOOM() =
        raise gOutOfMem

      system.outOfMemHook = handleOOM

  If the handler does not raise an exception, ordinary control flow continues and the program is terminated.

    stdin: TFile

  The standard input stream.

    stdout: TFile

  The standard output stream.

    stderr: TFile

  The standard error stream.

  Note: In my opinion, this should not be used -- the concept of a separate error stream is a design flaw of UNIX. A separate message stream is a good idea, but since it is named `stderr` there are few programs out there that distinguish properly between `stdout` and `stderr`. So, that's what you get if you don't name your variables appropriately. It also annoys people if redirection via `>output.txt` does not work because the program writes to `stderr`.

    stackTraceNewLine: string

  undocumented feature; it is replaced by `<br>` for CGI applications

# Consts

    on = true

  alias for `true`

    off = false

  alias for `false`

    isMainModule = false

  is 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 = "0000-00-00"

  is the date of compilation as a string of the form `YYYY-MM-DD`. This works thanks to compiler magic.

    CompileTime = "00:00:00"

  is the time of compilation as a string of the form `HH:MM:SS`. This works thanks to compiler magic.

    NimrodVersion = "0.0.0"

  is the version of Nimrod as a string. This works thanks to compiler magic.

    NimrodMajor = 0

  is the major number of Nimrod's version. This works thanks to compiler magic.

    NimrodMinor = 0

  is the minor number of Nimrod's version. This works thanks to compiler magic.

    NimrodPatch = 0

  is the patch number of Nimrod's version. This works thanks to compiler magic.

    cpuEndian = littleEndian

  is the endianness of the target CPU. This is a valuable piece of information for low-level code only. This works thanks to compiler magic.

    hostOS = ""

  a string that describes the host operating system. Possible values: "windows", "macosx", "linux", "netbsd", "freebsd", "openbsd", "solaris", "aix".

    hostCPU = ""

  a string that describes the host CPU. Possible values: "i386", "alpha", "powerpc", "sparc", "amd64", "mips", "arm".

    appType = ""

  a string that describes the application type. Possible values: "console", "gui", "lib".

    QuitSuccess = 0

  is the value that should be passed to `quit` to indicate success.

    QuitFailure = 1

  is the value that should be passed to `quit` to indicate failure.

    inf = inf

  contains the IEEE floating point value of positive infinity.

    neginf = -inf

  contains the IEEE floating point value of negative infinity.

    nan = nan

  contains an IEEE floating point value of Not A Number. Note that you cannot compare a floating point value to this value and expect a reasonable result - use the classify procedure in the module `math` for checking for NaN.

# Procs

    proc defined[expr](x: expr): bool {.magic: "Defined", noSideEffect.}

  Special compile-time procedure that checks whether x is defined. 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 defined(strutils.toUpper):
        # provide our own toUpper proc here, because strutils is
        # missing it.

    proc definedInScope[expr](x: expr): bool {.magic: "DefinedInScope", noSideEffect.}

  Special compile-time procedure that checks whether x is defined in the current scope. x has to be an identifier.

    proc `not`(x: bool): bool {.magic: "Not", noSideEffect.}

  Boolean not; returns true iff `x == false`.

    proc `and`(x, y: bool): bool {.magic: "And", noSideEffect.}

  Boolean `and`; returns true iff `x == y == true`. Evaluation is lazy: if `x` is false, `y` will not even be evaluated.

    proc `or`(x, y: bool): bool {.magic: "Or", noSideEffect.}

  Boolean `or`; returns true iff `not (not x and not y)`. Evaluation is lazy: if `x` is true, `y` will not even be evaluated.

    proc `xor`(x, y: bool): bool {.magic: "Xor", noSideEffect.}

  Boolean exclusive or; returns true iff `x != y`.

    proc new[T](a: var ref T) {.magic: "New", noSideEffect.}

  creates a new object of type `T` and returns a safe (traced) reference to it in `a`.

    proc new[typeDesc](T: typeDesc): ref T

  creates a new object of type `T` and returns a safe (traced) reference to it as result value

    proc unsafeNew[T](a: var ref T; size: int) {.magic: "New", noSideEffect.}

  creates a new object of type `T` and returns a safe (traced) reference to it in `a`. This is unsafe as it allocates an object of the passed `size`. This should only be used for optimization purposes when you know what you're doing!

    proc internalNew[T](a: var ref T) {.magic: "New", noSideEffect.}

  leaked implementation detail. Do not use.

    proc new[T](a: var ref T; finalizer: proc (x: ref T) {.nimcall.}) {.
        magic: "NewFinalize", noSideEffect.}

  creates a new object of type `T` and returns a safe (traced) reference to it in `a`. When the garbage collector frees the object, finalizer is called. The finalizer may not keep a reference to the object pointed to by x. The finalizer cannot prevent the GC from freeing the object. Note: The finalizer refers to the type T, not to the object! This means that for each object of type T the finalizer will be called!

    proc reset[T](obj: var T) {.magic: "Reset", noSideEffect.}

  resets an object obj to its initial (binary zero) value. This needs to be called before any possible object branch transition.

    proc high[T](x: T): T {.magic: "High", noSideEffect.}

  returns the highest possible index of an array, a sequence, a string or the highest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.

    proc low[T](x: T): T {.magic: "Low", noSideEffect.}

  returns the lowest possible index of an array, a sequence, a string or the lowest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.

    proc `..`[T](a, b: T): TSlice[T] {.noSideEffect, inline.}

  slice operator that constructs an interval `[a, b]`, both a and b are inclusive. Slices can also be used in the set constructor and in ordinal case statements, but then they are special-cased by the compiler.

    proc `..`[T](b: T): TSlice[T] {.noSideEffect, inline.}

  slice operator that constructs an interval `[default(T), b]`

    proc sizeof[T](x: T): Natural {.magic: "SizeOf", noSideEffect.}

  returns the size of `x` in bytes. Since this is a low-level proc, its usage is discouraged - using `new` for the most cases suffices that one never needs to know `x`'s size. As a special semantic rule, `x` may also be a type identifier (`sizeof(int)` is valid).

    proc `<`[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect.}

  unary `<` that can be used for nice looking excluding ranges:

      for i in 0 .. <10: echo i

  Semantically this is the same as `pred`.

    proc succ[T](x: Ordinal[T]; y = 1): T {.magic: "Succ", noSideEffect.}

  returns the `y`-th successor of the value `x`. `T` has to be an ordinal type. If such a value does not exist, `EOutOfRange` is raised or a compile time error occurs.

    proc pred[T](x: Ordinal[T]; y = 1): T {.magic: "Pred", noSideEffect.}

  returns the `y`-th predecessor of the value `x`. `T` has to be an ordinal type. If such a value does not exist, `EOutOfRange` is raised or a compile time error occurs.

    proc inc[T](x: var Ordinal[T]; y = 1) {.magic: "Inc", noSideEffect.}

  increments the ordinal `x` by `y`. If such a value does not exist, `EOutOfRange` is raised or a compile time error occurs. This is a short notation for: `x = succ(x, y)`.

    proc dec[T](x: var Ordinal[T]; y = 1) {.magic: "Dec", noSideEffect.}

  decrements the ordinal `x` by `y`. If such a value does not exist, `EOutOfRange` is raised or a compile time error occurs. This is a short notation for: `x = pred(x, y)`.

    proc newSeq[T](s: var seq[T]; len: int) {.magic: "NewSeq", noSideEffect.}

  creates a new sequence of type `seq[T]` with length `len`. This is equivalent to `s = @[]; setlen(s, len)`, but more efficient since no reallocation is needed.

  Note that the sequence will be filled with uninitialized entries, which can be a problem for sequences containing strings. After the creation of the sequence you should assign entries to the sequence instead of adding them. Example:

      var inputStrings : seq[string]
      newSeq(inputStrings, 3)
      inputStrings[0] = "The fourth"
      inputStrings[1] = "assignment"
      inputStrings[2] = "would crash"
      #inputStrings[3] = "out of bounds"

    proc newSeq[T](len = 0): seq[T]

  creates a new sequence of type `seq[T]` with length `len`.

  Note that the sequence will be filled with uninitialized entries, which can be a problem for sequences containing strings. After the creation of the sequence you should assign entries to the sequence instead of adding them. Example:

      var inputStrings = newSeq[string](3)
      inputStrings[0] = "The fourth"
      inputStrings[1] = "assignment"
      inputStrings[2] = "would crash"
      #inputStrings[3] = "out of bounds"

    proc len[TOpenArray](x: TOpenArray): int {.magic: "LengthOpenArray",
        noSideEffect.}

    proc len(x: string): int {.magic: "LengthStr", noSideEffect.}

    proc len(x: cstring): int {.magic: "LengthStr", noSideEffect.}

    proc len[I, T](x: array[I, T]): int {.magic: "LengthArray", noSideEffect.}

    proc len[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}

  returns the length of an array, an openarray, a sequence or a string. This is rougly the same as `high(T)-low(T)+1`, but its resulting type is always an int.

    proc incl[T](x: var set[T]; y: T) {.magic: "Incl", noSideEffect.}

  includes element `y` to the set `x`. This is the same as `x = x + {y}`, but it might be more efficient.

    proc excl[T](x: var set[T]; y: T) {.magic: "Excl", noSideEffect.}

  excludes element `y` to the set `x`. This is the same as `x = x - {y}`, but it might be more efficient.

    proc card[T](x: set[T]): int {.magic: "Card", noSideEffect.}

  returns the cardinality of the set `x`, i.e. the number of elements in the set.

    proc ord[T](x: T): int {.magic: "Ord", noSideEffect.}

  returns the internal int value of an ordinal value `x`.

    proc chr(u: range[0 .. 255]): char {.magic: "Chr", noSideEffect.}

  converts an int in the range 0..255 to a character.

    proc ze(x: int8): int {.magic: "Ze8ToI", noSideEffect.}

  zero extends a smaller integer type to `int`. This treats x as unsigned.

    proc ze(x: int16): int {.magic: "Ze16ToI", noSideEffect.}

  zero extends a smaller integer type to `int`. This treats x as unsigned.

    proc ze64(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect.}

  zero extends a smaller integer type to `int64`. This treats x as unsigned.

    proc ze64(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect.}

  zero extends a smaller integer type to `int64`. This treats x as unsigned.

    proc ze64(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect.}

  zero extends a smaller integer type to `int64`. This treats x as unsigned.

    proc ze64(x: int): int64 {.magic: "ZeIToI64", noDecl, noSideEffect.}

  zero extends a smaller integer type to `int64`. This treats x as unsigned. Does nothing if the size of an `int` is the same as `int64`. (This is the case on 64 bit processors.)

    proc toU8(x: int): int8 {.magic: "ToU8", noSideEffect.}

  treats x as unsigned and converts it to a byte by taking the last 8 bits from x.

    proc toU16(x: int): int16 {.magic: "ToU16", noSideEffect.}

  treats x as unsigned and converts it to an `int16` by taking the last 16 bits from x.

    proc toU32(x: int64): int32 {.magic: "ToU32", noSideEffect.}

  treats x as unsigned and converts it to an `int32` by taking the last 32 bits from x.

    proc `+`(x: int): int {.magic: "UnaryPlusI", noSideEffect.}

    proc `+`(x: int8): int8 {.magic: "UnaryPlusI", noSideEffect.}

    proc `+`(x: int16): int16 {.magic: "UnaryPlusI", noSideEffect.}

    proc `+`(x: int32): int32 {.magic: "UnaryPlusI", noSideEffect.}

    proc `+`(x: int64): int64 {.magic: "UnaryPlusI64", noSideEffect.}

  Unary + operator for an integer. Has no effect.

    proc `-`(x: int): int {.magic: "UnaryMinusI", noSideEffect.}

    proc `-`(x: int8): int8 {.magic: "UnaryMinusI", noSideEffect.}

    proc `-`(x: int16): int16 {.magic: "UnaryMinusI", noSideEffect.}

    proc `-`(x: int32): int32 {.magic: "UnaryMinusI", noSideEffect.}

    proc `-`(x: int64): int64 {.magic: "UnaryMinusI64", noSideEffect.}

  Unary - operator for an integer. Negates x.

    proc `not`(x: int): int {.magic: "BitnotI", noSideEffect.}

    proc `not`(x: int8): int8 {.magic: "BitnotI", noSideEffect.}

    proc `not`(x: int16): int16 {.magic: "BitnotI", noSideEffect.}

    proc `not`(x: int32): int32 {.magic: "BitnotI", noSideEffect.}

    proc `not`(x: int64): int64 {.magic: "BitnotI64", noSideEffect.}

  computes the bitwise complement of the integer x.

    proc `+`(x, y: int): int {.magic: "AddI", noSideEffect.}

    proc `+`(x, y: int8): int8 {.magic: "AddI", noSideEffect.}

    proc `+`(x, y: int16): int16 {.magic: "AddI", noSideEffect.}

    proc `+`(x, y: int32): int32 {.magic: "AddI", noSideEffect.}

    proc `+`(x, y: int64): int64 {.magic: "AddI64", noSideEffect.}

  Binary + operator for an integer.

    proc `-`(x, y: int): int {.magic: "SubI", noSideEffect.}

    proc `-`(x, y: int8): int8 {.magic: "SubI", noSideEffect.}

    proc `-`(x, y: int16): int16 {.magic: "SubI", noSideEffect.}

    proc `-`(x, y: int32): int32 {.magic: "SubI", noSideEffect.}

    proc `-`(x, y: int64): int64 {.magic: "SubI64", noSideEffect.}

  Binary - operator for an integer.

    proc `*`(x, y: int): int {.magic: "MulI", noSideEffect.}

    proc `*`(x, y: int8): int8 {.magic: "MulI", noSideEffect.}

    proc `*`(x, y: int16): int16 {.magic: "MulI", noSideEffect.}

    proc `*`(x, y: int32): int32 {.magic: "MulI", noSideEffect.}

    proc `*`(x, y: int64): int64 {.magic: "MulI64", noSideEffect.}

  Binary * operator for an integer.

    proc `div`(x, y: int): int {.magic: "DivI", noSideEffect.}

    proc `div`(x, y: int8): int8 {.magic: "DivI", noSideEffect.}

    proc `div`(x, y: int16): int16 {.magic: "DivI", noSideEffect.}

    proc `div`(x, y: int32): int32 {.magic: "DivI", noSideEffect.}

    proc `div`(x, y: int64): int64 {.magic: "DivI64", noSideEffect.}

  computes the integer division. This is roughly the same as `floor(x/y)`.

    proc `mod`(x, y: int): int {.magic: "ModI", noSideEffect.}

    proc `mod`(x, y: int8): int8 {.magic: "ModI", noSideEffect.}

    proc `mod`(x, y: int16): int16 {.magic: "ModI", noSideEffect.}

    proc `mod`(x, y: int32): int32 {.magic: "ModI", noSideEffect.}

    proc `mod`(x, y: int64): int64 {.magic: "ModI64", noSideEffect.}

  computes the integer modulo operation. This is the same as `x - (x div y) * y`.

    proc `shr`(x, y: int): int {.magic: "ShrI", noSideEffect.}

    proc `shr`(x, y: int8): int8 {.magic: "ShrI", noSideEffect.}

    proc `shr`(x, y: int16): int16 {.magic: "ShrI", noSideEffect.}

    proc `shr`(x, y: int32): int32 {.magic: "ShrI", noSideEffect.}

    proc `shr`(x, y: int64): int64 {.magic: "ShrI64", noSideEffect.}

  computes the shift right operation of x and y.

    proc `shl`(x, y: int): int {.magic: "ShlI", noSideEffect.}

    proc `shl`(x, y: int8): int8 {.magic: "ShlI", noSideEffect.}

    proc `shl`(x, y: int16): int16 {.magic: "ShlI", noSideEffect.}

    proc `shl`(x, y: int32): int32 {.magic: "ShlI", noSideEffect.}

    proc `shl`(x, y: int64): int64 {.magic: "ShlI64", noSideEffect.}

  computes the shift left operation of x and y.

    proc `and`(x, y: int): int {.magic: "BitandI", noSideEffect.}

    proc `and`(x, y: int8): int8 {.magic: "BitandI", noSideEffect.}

    proc `and`(x, y: int16): int16 {.magic: "BitandI", noSideEffect.}

    proc `and`(x, y: int32): int32 {.magic: "BitandI", noSideEffect.}

    proc `and`(x, y: int64): int64 {.magic: "BitandI64", noSideEffect.}

  computes the bitwise and of numbers x and y.

    proc `or`(x, y: int): int {.magic: "BitorI", noSideEffect.}

    proc `or`(x, y: int8): int8 {.magic: "BitorI", noSideEffect.}

    proc `or`(x, y: int16): int16 {.magic: "BitorI", noSideEffect.}

    proc `or`(x, y: int32): int32 {.magic: "BitorI", noSideEffect.}

    proc `or`(x, y: int64): int64 {.magic: "BitorI64", noSideEffect.}

  computes the bitwise or of numbers x and y.

    proc `xor`(x, y: int): int {.magic: "BitxorI", noSideEffect.}

    proc `xor`(x, y: int8): int8 {.magic: "BitxorI", noSideEffect.}

    proc `xor`(x, y: int16): int16 {.magic: "BitxorI", noSideEffect.}

    proc `xor`(x, y: int32): int32 {.magic: "BitxorI", noSideEffect.}

    proc `xor`(x, y: int64): int64 {.magic: "BitxorI64", noSideEffect.}

  computes the bitwise xor of numbers x and y.

    proc `==`(x, y: int): bool {.magic: "EqI", noSideEffect.}

    proc `==`(x, y: int8): bool {.magic: "EqI", noSideEffect.}

    proc `==`(x, y: int16): bool {.magic: "EqI", noSideEffect.}

    proc `==`(x, y: int32): bool {.magic: "EqI", noSideEffect.}

    proc `==`(x, y: int64): bool {.magic: "EqI64", noSideEffect.}

  Compares two integers for equality.

    proc `<=`(x, y: int): bool {.magic: "LeI", noSideEffect.}

    proc `<=`(x, y: int8): bool {.magic: "LeI", noSideEffect.}

    proc `<=`(x, y: int16): bool {.magic: "LeI", noSideEffect.}

    proc `<=`(x, y: int32): bool {.magic: "LeI", noSideEffect.}

    proc `<=`(x, y: int64): bool {.magic: "LeI64", noSideEffect.}

  Returns true iff x is less than or equal to y.

    proc `<`(x, y: int): bool {.magic: "LtI", noSideEffect.}

    proc `<`(x, y: int8): bool {.magic: "LtI", noSideEffect.}

    proc `<`(x, y: int16): bool {.magic: "LtI", noSideEffect.}

    proc `<`(x, y: int32): bool {.magic: "LtI", noSideEffect.}

    proc `<`(x, y: int64): bool {.magic: "LtI64", noSideEffect.}

  Returns true iff x is less than y.

    proc abs(x: int): int {.magic: "AbsI", noSideEffect.}

    proc abs(x: int8): int8 {.magic: "AbsI", noSideEffect.}

    proc abs(x: int16): int16 {.magic: "AbsI", noSideEffect.}

    proc abs(x: int32): int32 {.magic: "AbsI", noSideEffect.}

    proc abs(x: int64): int64 {.magic: "AbsI64", noSideEffect.}

  returns the absolute value of x. If x is `low(x)` (that is -MININT for its type), an overflow exception is thrown (if overflow checking is turned on).

    proc `+%`[IntMax32](x, y: IntMax32): IntMax32 {.magic: "AddU", noSideEffect.}

    proc `+%`(x, y: int64): int64 {.magic: "AddU", noSideEffect.}

  treats x and y as unsigned and adds them. The result is truncated to fit into the result. This implements modulo arithmetic. No overflow errors are possible.

    proc `-%`[IntMax32](x, y: IntMax32): IntMax32 {.magic: "SubU", noSideEffect.}

    proc `-%`(x, y: int64): int64 {.magic: "SubU", noSideEffect.}

  treats x and y as unsigned and subtracts them. The result is truncated to fit into the result. This implements modulo arithmetic. No overflow errors are possible.

    proc `*%`[IntMax32](x, y: IntMax32): IntMax32 {.magic: "MulU", noSideEffect.}

    proc `*%`(x, y: int64): int64 {.magic: "MulU", noSideEffect.}

  treats x and y as unsigned and multiplies them. The result is truncated to fit into the result. This implements modulo arithmetic. No overflow errors are possible.

    proc `/%`[IntMax32](x, y: IntMax32): IntMax32 {.magic: "DivU", noSideEffect.}

    proc `/%`(x, y: int64): int64 {.magic: "DivU", noSideEffect.}

  treats x and y as unsigned and divides them. The result is truncated to fit into the result. This implements modulo arithmetic. No overflow errors are possible.

    proc `%%`[IntMax32](x, y: IntMax32): IntMax32 {.magic: "ModU", noSideEffect.}

    proc `%%`(x, y: int64): int64 {.magic: "ModU", noSideEffect.}

  treats x and y as unsigned and compute the modulo of x and y. The result is truncated to fit into the result. This implements modulo arithmetic. No overflow errors are possible.

    proc `<=%`[IntMax32](x, y: IntMax32): bool {.magic: "LeU", noSideEffect.}

    proc `<=%`(x, y: int64): bool {.magic: "LeU64", noSideEffect.}

  treats x and y as unsigned and compares them. Returns true iff `unsigned(x) <= unsigned(y)`.

    proc `<%`[IntMax32](x, y: IntMax32): bool {.magic: "LtU", noSideEffect.}

    proc `<%`(x, y: int64): bool {.magic: "LtU64", noSideEffect.}

  treats x and y as unsigned and compares them. Returns true iff `unsigned(x) < unsigned(y)`.

    proc `+`(x: float): float {.magic: "UnaryPlusF64", noSideEffect.}

    proc `-`(x: float): float {.magic: "UnaryMinusF64", noSideEffect.}

    proc `+`(x, y: float): float {.magic: "AddF64", noSideEffect.}

    proc `-`(x, y: float): float {.magic: "SubF64", noSideEffect.}

    proc `*`(x, y: float): float {.magic: "MulF64", noSideEffect.}

    proc `/`(x, y: float): float {.magic: "DivF64", noSideEffect.}

  computes the floating point division

    proc `==`(x, y: float): bool {.magic: "EqF64", noSideEffect.}

    proc `<=`(x, y: float): bool {.magic: "LeF64", noSideEffect.}

    proc `<`(x, y: float): bool {.magic: "LtF64", noSideEffect.}

    proc abs(x: float): float {.magic: "AbsF64", noSideEffect.}

    proc min(x, y: float): float {.magic: "MinF64", noSideEffect.}

    proc max(x, y: float): float {.magic: "MaxF64", noSideEffect.}

    proc `*`[T](x, y: set[T]): set[T] {.magic: "MulSet", noSideEffect.}

  This operator computes the intersection of two sets.

    proc `+`[T](x, y: set[T]): set[T] {.magic: "PlusSet", noSideEffect.}

  This operator computes the union of two sets.

    proc `-`[T](x, y: set[T]): set[T] {.magic: "MinusSet", noSideEffect.}

  This operator computes the difference of two sets.

    proc `-+-`[T](x, y: set[T]): set[T] {.magic: "SymDiffSet", noSideEffect.}

  computes the symmetric set difference. This is the same as `(A - B) + (B - A)`, but more efficient.

    proc `==`[TEnum](x, y: TEnum): bool {.magic: "EqEnum", noSideEffect.}

    proc `==`(x, y: pointer): bool {.magic: "EqRef", noSideEffect.}

    proc `==`(x, y: string): bool {.magic: "EqStr", noSideEffect.}

    proc `==`(x, y: cstring): bool {.magic: "EqCString", noSideEffect.}

    proc `==`(x, y: char): bool {.magic: "EqCh", noSideEffect.}

    proc `==`(x, y: bool): bool {.magic: "EqB", noSideEffect.}

    proc `==`[T](x, y: set[T]): bool {.magic: "EqSet", noSideEffect.}

    proc `==`[T](x, y: ref T): bool {.magic: "EqRef", noSideEffect.}

    proc `==`[T](x, y: ptr T): bool {.magic: "EqRef", noSideEffect.}

    proc `==`[T](x, y: T): bool {.magic: "EqProc", noSideEffect.}

    proc `<=`[TEnum](x, y: TEnum): bool {.magic: "LeEnum", noSideEffect.}

    proc `<=`(x, y: string): bool {.magic: "LeStr", noSideEffect.}

    proc `<=`(x, y: char): bool {.magic: "LeCh", noSideEffect.}

    proc `<=`[T](x, y: set[T]): bool {.magic: "LeSet", noSideEffect.}

    proc `<=`(x, y: bool): bool {.magic: "LeB", noSideEffect.}

    proc `<=`[T](x, y: ref T): bool {.magic: "LePtr", noSideEffect.}

    proc `<=`(x, y: pointer): bool {.magic: "LePtr", noSideEffect.}

    proc `<`[TEnum](x, y: TEnum): bool {.magic: "LtEnum", noSideEffect.}

    proc `<`(x, y: string): bool {.magic: "LtStr", noSideEffect.}

    proc `<`(x, y: char): bool {.magic: "LtCh", noSideEffect.}

    proc `<`[T](x, y: set[T]): bool {.magic: "LtSet", noSideEffect.}

    proc `<`(x, y: bool): bool {.magic: "LtB", noSideEffect.}

    proc `<`[T](x, y: ref T): bool {.magic: "LtPtr", noSideEffect.}

    proc `<`[T](x, y: ptr T): bool {.magic: "LtPtr", noSideEffect.}

    proc `<`(x, y: pointer): bool {.magic: "LtPtr", noSideEffect.}

    proc contains[T](x: set[T]; y: T): bool {.magic: "InSet", noSideEffect.}

  One should overload this proc if one wants to overload the `in` operator. The parameters are in reverse order! `a in b` is a template for `contains(b, a)`. This is because the unification algorithm that Nimrod uses for overload resolution works from left to right. But for the `in` operator that would be the wrong direction for this piece of code:

      var s: set[range['a'..'z']] = {'a'..'c'}
      writeln(stdout, 'b' in s)

  If `in` had been declared as `[T](elem: T, s: set[T])` then `T` would have been bound to `char`. But `s` is not compatible to type `set[char]`! The solution is to bind `T` to `range['a'..'z']`. This is achieved by reversing the parameters for `contains`; `in` then passes its arguments in reverse order.

    proc contains[T](s: TSlice[T]; value: T): bool {.noSideEffect, inline.}

    proc `is`[T, S](x: T; y: S): bool {.magic: "Is", noSideEffect.}

    proc `of`[T, S](x: T; y: S): bool {.magic: "Of", noSideEffect.}

    proc cmp[T](x, y: T): int {.procvar.}

  Generic compare proc. Returns a value < 0 iff x < y, a value > 0 iff x > y and 0 iff x == y. This is useful for writing generic algorithms without performance loss. This generic implementation uses the == and < operators.

    proc `@`[IDX, T](a: array[IDX, T]): seq[T] {.magic: "ArrToSeq", nosideeffect.}

  turns an array into a sequence. This most often useful for constructing sequences with the array constructor: `@[1, 2, 3]` has the type `seq[int]`, while `[1, 2, 3]` has the type `array[0..2, int]`.

    proc setLen[T](s: var seq[T]; newlen: int) {.magic: "SetLengthSeq", noSideEffect.}

  sets the length of s to newlen. `T` may be any sequence type. If the current length is greater than the new length, `s` will be truncated. s cannot be nil! To initialize a sequence with a size, use `newSeq` instead.

    proc setLen(s: var string; newlen: int) {.magic: "SetLengthStr", noSideEffect.}

  sets the length of s to newlen. If the current length is greater than the new length, `s` will be truncated. s cannot be nil! To initialize a string with a size, use `newString` instead.

    proc newString(len: int): string {.magic: "NewString", importc: "mnewString",
                                       noSideEffect.}

  returns a new string of length `len` but with uninitialized content. One needs to fill the string character after character with the index operator `s[i]`. This procedure exists only for optimization purposes; the same effect can be achieved with the `&` operator or with `add`.

    proc newStringOfCap(cap: int): string {.magic: "NewStringOfCap",
                                            importc: "rawNewString", noSideEffect.}

  returns a new string of length `0` but with capacity cap.This procedure exists only for optimization purposes; the same effect can be achieved with the `&` operator or with `add`.

    proc `&`(x: string; y: char): string {.magic: "ConStrStr", noSideEffect, merge.}

    proc `&`(x: char; y: char): string {.magic: "ConStrStr", noSideEffect, merge.}

    proc `&`(x, y: string): string {.magic: "ConStrStr", noSideEffect, merge.}

    proc `&`(x: char; y: string): string {.magic: "ConStrStr", noSideEffect, merge.}

  is the concatenation operator. It concatenates x and y.

    proc add(x: var string; y: char) {.magic: "AppendStrCh", noSideEffect.}

    proc add(x: var string; y: string) {.magic: "AppendStrStr", noSideEffect.}

    proc compileOption(option: string): bool {.magic: "CompileOption", noSideEffect.}

  can be used to determine an on|off compile-time option. Example:

      when compileOption("floatchecks"):
        echo "compiled with floating point NaN and Inf checks"

    proc compileOption(option, arg: string): bool {.magic: "CompileOptionArg",
        noSideEffect.}

  can be used to determine an enum compile-time option. Example:

      when compileOption("opt", "size") and compileOption("gc", "boehm"):
        echo "compiled with optimization for size and uses Boehm's GC"

    proc quit(errorcode: int = QuitSuccess) {.magic: "Exit", importc: "exit",
        noDecl, noReturn.}

  Stops the program immediately with an exit code.

  Before stopping the program the "quit procedures" are called in the opposite order they were added with `addQuitProc`. `quit` never returns and ignores any exception that may have been raised by the quit procedures. It does not call the garbage collector to free all the memory, unless a quit procedure calls `GC_collect`.

  The proc `quit(QuitSuccess)` is called implicitly when your nimrod program finishes without incident. A raised unhandled exception is equivalent to calling `quit(QuitFailure)`.

    proc add[T](x: var seq[T]; y: T) {.magic: "AppendSeqElem", noSideEffect.}

    proc add[T](x: var seq[T]; y: openarray[T]) {.noSideEffect.}

  Generic proc for adding a data item y to a container x. For containers that have an order, add means append. New generic containers should also call their adding proc add for consistency. Generic code becomes much easier to write if the Nimrod naming scheme is respected.

    proc shallowCopy[T](x: var T; y: T) {.noSideEffect, magic: "ShallowCopy".}

  use this instead of = for a shallow copy. The shallow copy only changes the semantics for sequences and strings (and types which contain those). Be careful with the changed semantics though! There is a reason why the default assignment does a deep copy of sequences and strings.

    proc del[T](x: var seq[T]; i: int) {.noSideEffect.}

  deletes the item at index i by putting `x[high(x)]` into position i. This is an O(1) operation.

    proc delete[T](x: var seq[T]; i: int) {.noSideEffect.}

  deletes the item at index i by moving `x[i+1..]` by one position. This is an O(n) operation.

    proc insert[T](x: var seq[T]; item: T; i = 0) {.noSideEffect.}

  inserts item into x at position i.

    proc repr[T](x: T): string {.magic: "Repr", noSideEffect.}

  takes any Nimrod variable and returns its string representation. It works even for complex data graphs with cycles. This is a great debugging tool.

    proc toFloat(i: int): float {.magic: "ToFloat", noSideEffect, importc: "toFloat".}

  converts an integer i into a `float`. If the conversion fails, EInvalidValue is raised. However, on most platforms the conversion cannot fail.

    proc toBiggestFloat(i: BiggestInt): BiggestFloat {.magic: "ToBiggestFloat",
        noSideEffect, importc: "toBiggestFloat".}

  converts an biggestint i into a `biggestfloat`. If the conversion fails, EInvalidValue is raised. However, on most platforms the conversion cannot fail.

    proc toInt(f: float): int {.magic: "ToInt", noSideEffect, importc: "toInt".}

  converts a floating point number f into an `int`. Conversion rounds f if it does not contain an integer value. If the conversion fails (because f is infinite for example), EInvalidValue is raised.

    proc toBiggestInt(f: BiggestFloat): BiggestInt {.magic: "ToBiggestInt",
        noSideEffect, importc: "toBiggestInt".}

  converts a biggestfloat f into a `biggestint`. Conversion rounds f if it does not contain an integer value. If the conversion fails (because f is infinite for example), EInvalidValue is raised.

    proc addQuitProc(QuitProc: proc () {.noconv.}) {.importc: "atexit", nodecl.}

  adds/registers a quit procedure. Each call to `addQuitProc` registers another quit procedure. Up to 30 procedures can be registered. They are executed on a last-in, first-out basis (that is, the last function registered is the first to be executed). `addQuitProc` raises an EOutOfIndex if `quitProc` cannot be registered.

    proc copy(s: string; first = 0): string {.magic: "CopyStr", importc: "copyStr",
        noSideEffect, deprecated.}

    proc copy(s: string; first, last: int): string {.magic: "CopyStrLast",
        importc: "copyStrLast", noSideEffect, deprecated.}

  copies a slice of s into a new string and returns this new string. The bounds first and last denote the indices of the first and last characters that shall be copied. If `last` is omitted, it is treated as `high(s)`. Deprecated since version 0.8.12: Use `substr` instead.

    proc substr(s: string; first = 0): string {.magic: "CopyStr",
        importc: "copyStr", noSideEffect.}

    proc substr(s: string; first, last: int): string {.magic: "CopyStrLast",
        importc: "copyStrLast", noSideEffect.}

  copies a slice of s into a new string and returns this new string. The bounds first and last denote the indices of the first and last characters that shall be copied. If `last` is omitted, it is treated as `high(s)`. If `last >= s.len`, `s.len` is used instead: This means `substr` can also be used to cut or limit a string's length.

    proc zeroMem(p: pointer; size: int) {.importc, noDecl.}

  overwrites the contents of the memory at `p` with the value 0. Exactly `size` bytes will be overwritten. Like any procedure dealing with raw memory this is unsafe.

    proc copyMem(dest, source: pointer; size: int) {.importc: "memcpy", noDecl.}

  copies the contents from the memory at `source` to the memory at `dest`. Exactly `size` bytes will be copied. The memory regions may not overlap. Like any procedure dealing with raw memory this is unsafe.

    proc moveMem(dest, source: pointer; size: int) {.importc: "memmove", noDecl.}

  copies the contents from the memory at `source` to the memory at `dest`. Exactly `size` bytes will be copied. The memory regions may overlap, `moveMem` handles this case appropriately and is thus somewhat more safe than `copyMem`. Like any procedure dealing with raw memory this is still unsafe, though.

    proc equalMem(a, b: pointer; size: int): bool {.importc: "equalMem", noDecl,
        noSideEffect.}

  compares the memory blocks `a` and `b`. `size` bytes will be compared. If the blocks are equal, true is returned, false otherwise. Like any procedure dealing with raw memory this is unsafe.

    proc swap[T](a, b: var T) {.magic: "Swap", noSideEffect.}

  swaps the values a and b. This is often more efficient than `tmp = a; a = b; b = tmp`. Particularly useful for sorting algorithms.

    proc `$`(x: int): string {.magic: "IntToStr", noSideEffect.}

  The stingify operator for an integer argument. Returns x converted to a decimal string.

    proc `$`(x: int64): string {.magic: "Int64ToStr", noSideEffect.}

  The stingify operator for an integer argument. Returns x converted to a decimal string.

    proc `$`(x: float): string {.magic: "FloatToStr", noSideEffect.}

  The stingify operator for a float argument. Returns x converted to a decimal string.

    proc `$`(x: bool): string {.magic: "BoolToStr", noSideEffect.}

  The stingify operator for a boolean argument. Returns x converted to the string "false" or "true".

    proc `$`(x: char): string {.magic: "CharToStr", noSideEffect.}

  The stingify operator for a character argument. Returns x converted to a string.

    proc `$`(x: cstring): string {.magic: "CStrToStr", noSideEffect.}

  The stingify operator for a CString argument. Returns x converted to a string.

    proc `$`(x: string): string {.magic: "StrToStr", noSideEffect.}

  The stingify operator for a string argument. Returns x as it is. This operator is useful for generic code, so that `$expr` also works if `expr` is already a string.

    proc `$`[TEnum](x: TEnum): string {.magic: "EnumToStr", noSideEffect.}

  The stingify operator for an enumeration argument. This works for any enumeration type thanks to compiler magic. If a `$` operator for a concrete enumeration is provided, this is used instead. (In other words: Overwriting is possible.)

    proc getRefcount[T](x: ref T): int {.importc: "getRefcount", noSideEffect.}

    proc getRefcount(x: string): int {.importc: "getRefcount", noSideEffect.}

    proc getRefcount[T](x: seq[T]): int {.importc: "getRefcount", noSideEffect.}

  retrieves the reference count of an heap-allocated object. The value is implementation-dependent.

    proc min(x, y: int): int {.magic: "MinI", noSideEffect.}

    proc min(x, y: int8): int8 {.magic: "MinI", noSideEffect.}

    proc min(x, y: int16): int16 {.magic: "MinI", noSideEffect.}

    proc min(x, y: int32): int32 {.magic: "MinI", noSideEffect.}

    proc min(x, y: int64): int64 {.magic: "MinI64", noSideEffect.}

  The minimum value of two integers.

    proc min[T](x: varargs[T]): T

  The minimum value of x. `T` needs to have a `<` operator.

    proc max(x, y: int): int {.magic: "MaxI", noSideEffect.}

    proc max(x, y: int8): int8 {.magic: "MaxI", noSideEffect.}

    proc max(x, y: int16): int16 {.magic: "MaxI", noSideEffect.}

    proc max(x, y: int32): int32 {.magic: "MaxI", noSideEffect.}

    proc max(x, y: int64): int64 {.magic: "MaxI64", noSideEffect.}

  The maximum value of two integers.

    proc max[T](x: varargs[T]): T

  The maximum value of x. `T` needs to have a `<` operator.

    proc clamp[T](x, a, b: T): T

  limits the value `x` within the interval [a, b]

    proc isNil[T](x: seq[T]): bool {.noSideEffect, magic: "IsNil".}

    proc isNil[T](x: ref T): bool {.noSideEffect, magic: "IsNil".}

    proc isNil(x: string): bool {.noSideEffect, magic: "IsNil".}

    proc isNil[T](x: ptr T): bool {.noSideEffect, magic: "IsNil".}

    proc isNil(x: pointer): bool {.noSideEffect, magic: "IsNil".}

    proc isNil(x: cstring): bool {.noSideEffect, magic: "IsNil".}

    proc isNil[T](x: T): bool {.noSideEffect, magic: "IsNil".}

  Fast check whether x is nil. This is sometimes more efficient than `== nil`.

    proc `@`[T](a: openarray[T]): seq[T]

  turns an openarray into a sequence. This is not as efficient as turning a fixed length array into a sequence as it always copies every element of a.

    proc `&`[T](x, y: seq[T]): seq[T] {.noSideEffect.}

    proc `&`[T](x: seq[T]; y: T): seq[T] {.noSideEffect.}

    proc `&`[T](x: T; y: seq[T]): seq[T] {.noSideEffect.}

    proc `==`[T](x, y: seq[T]): bool {.noSideEffect.}

  Generic equals operator for sequences: relies on a equals operator for the element type T.

    proc find[T, S](a: T; item: S): int {.inline.}

  Returns the first index of item in a or -1 if not found. This requires appropriate items and == operations to work.

    proc contains[T](a: openarray[T]; item: T): bool {.inline.}

  Returns true if item is in a or false if not found. This is a shortcut for `find(a, item) >= 0`.

    proc pop[T](s: var seq[T]): T {.inline, noSideEffect.}

  returns the last item of s and decreases `s.len` by one. This treats s as a stack and implements the common pop operation.

    proc each[T, S](data: openarray[T]; op: proc (x: T): S {.closure.}): seq[S] {.
        deprecated.}

  The well-known `map` operation from functional programming. Applies op to every item in data and returns the result as a sequence.

  Deprecated since version 0.9: Use the `map` proc instead.

    proc each[T](data: var openarray[T]; op: proc (x: var T) {.closure.}) {.
        deprecated.}

  The well-known `map` operation from functional programming. Applies op to every item in data modifying it directly.

  Deprecated since version 0.9: Use the `map` proc instead.

    proc map[T, S](data: openarray[T]; op: proc (x: T): S {.closure.}): seq[S]

  Returns a new sequence with the results of op applied to every item in data.

  Since the input is not modified you can use this version of `map` to transform the type of the elements in the input sequence. Example:

      let
        a = @[1, 2, 3, 4]
        b = map(a, proc(x: int): string = $x)
      assert b == @["1", "2", "3", "4"]

    proc map[T](data: var openarray[T]; op: proc (x: var T) {.closure.})

  Applies op to every item in data modifying it directly.

  Note that this version of `map` requires your input and output types to be the same, since they are modified in-place. Example:

      var a = @["1", "2", "3", "4"]
      echo repr(a)
      # --> ["1", "2", "3", "4"]
      map(a, proc(x: var string) = x &= "42")
      echo repr(a)
      # --> ["142", "242", "342", "442"]

    proc `==`[T](x, y: T): bool

  generic `==` operator for tuples that is lifted from the components of x and y.

    proc `<=`[T](x, y: T): bool

  generic `<=` operator for tuples that is lifted from the components of x and y. This implementation uses cmp.

    proc `<`[T](x, y: T): bool

  generic `<` operator for tuples that is lifted from the components of x and y. This implementation uses cmp.

    proc `$`[T](x: T): string

  generic `$` operator for tuples that is lifted from the components of x. Example:

      $(23, 45) == "(23, 45)"
      $() == "()"

    proc `$`[T](x: T): string

  generic `$` operator for sets that is lifted from the components of x. Example:

      ${23, 45} == "{23, 45}"

    proc GC_ref[T](x: ref T) {.magic: "GCref".}

    proc GC_ref[T](x: seq[T]) {.magic: "GCref".}

    proc GC_ref(x: string) {.magic: "GCref".}

  marks the object x as referenced, so that it will not be freed until it is unmarked via GC_unref. If called n-times for the same object x, n calls to GC_unref are needed to unmark x.

    proc GC_unref[T](x: ref T) {.magic: "GCunref".}

    proc GC_unref[T](x: seq[T]) {.magic: "GCunref".}

    proc GC_unref(x: string) {.magic: "GCunref".}

  see the documentation of GC_ref.

    proc add(x: var string; y: cstring) {.noStackFrame, raises: [], tags: [].}

    proc echo[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [FWriteIO].}

  special built-in that takes a variable number of arguments. Each argument is converted to a string via `$`, so it works for user-defined types that have an overloaded `$` operator. It is roughly equivalent to `writeln(stdout, x); flush(stdout)`, but available for the JavaScript target too. Unlike other IO operations this is guaranteed to be thread-safe as `echo` is very often used for debugging convenience.

    proc debugEcho[T](x: varargs[T, `$`]) {.magic: "Echo", noSideEffect, tags: [],
                                            raises: [].}

  Same as `echo`, but as a special semantic rule, `debugEcho` pretends to be free of side effects, so that it can be used for debugging routines marked as `noSideEffect`.

    proc getTypeInfo[T](x: T): pointer {.magic: "GetTypeInfo".}

  get type information for x. Ordinary code should not use this, but the typeinfo module instead.

    proc cmp(x, y: string): int {.noSideEffect, procvar, raises: [], tags: [].}

  Compare proc for strings. More efficient than the generic version.

    proc Open(f: var TFile; filename: string; mode: TFileMode = fmRead;
              bufSize: int = - 1): bool {.tags: [], raises: [EOutOfMemory].}

  Opens a file named filename with given mode.

  Default mode is readonly. Returns true iff the file could be opened. This throws no exception if the file could not be opened.

    proc Open(f: var TFile; filehandle: TFileHandle; mode: TFileMode = fmRead): bool {.
        tags: [], raises: [].}

  Creates a `TFile` from a filehandle with given mode.

  Default mode is readonly. Returns true iff the file could be opened.

    proc Open(filename: string; mode: TFileMode = fmRead; bufSize: int = - 1): TFile {.
        raises: [E_Base, EIO], tags: [].}

  Opens a file named filename with given mode.

  Default mode is readonly. Raises an `IO` exception if the file could not be opened.

    proc reopen(f: TFile; filename: string; mode: TFileMode = fmRead): bool {.
        tags: [], raises: [].}

  reopens the file f with given filename and mode. This is often used to redirect the stdin, stdout or stderr file variables.

  Default mode is readonly. Returns true iff the file could be reopened.

    proc Close(f: TFile) {.importc: "fclose", nodecl, tags: [].}

  Closes the file.

    proc EndOfFile(f: TFile): bool {.tags: [], raises: [].}

  Returns true iff f is at the end.

    proc readChar(f: TFile): char {.importc: "fgetc", nodecl, tags: [FReadIO].}

  Reads a single character from the stream f.

    proc FlushFile(f: TFile) {.importc: "fflush", noDecl, tags: [FWriteIO].}

  Flushes f's buffer.

    proc readAll(file: TFile): TaintedString {.tags: [FReadIO],
        raises: [E_Base, EIO].}

  Reads all data from the stream file. Raises an IO exception in case of an error

    proc readFile(filename: string): TaintedString {.tags: [FReadIO],
        raises: [E_Base, EIO, E_Base, EIO].}

  Opens a file named filename for reading. Then calls readAll and closes the file afterwards. Returns the string. Raises an IO exception in case of an error.

    proc writeFile(filename, content: string) {.tags: [FWriteIO],
        raises: [E_Base, EIO, E_Base].}

  Opens a file named filename for writing. Then writes the content completely to the file and closes the file afterwards. Raises an IO exception in case of an error.

    proc write(f: TFile; r: float) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; i: int) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; i: BiggestInt) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; r: BiggestFloat) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; s: string) {.tags: [FWriteIO], raises: [EIO].}

    proc write(f: TFile; b: bool) {.tags: [FWriteIO], raises: [E_Base].}

    proc write(f: TFile; c: char) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; c: cstring) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; a: varargs[string, `$`]) {.tags: [FWriteIO],
        raises: [E_Base].}

  Writes a value to the file f. May throw an IO exception.

    proc readLine(f: TFile): TaintedString {.tags: [FReadIO], raises: [EIO].}

  reads a line of text from the file f. May throw an IO exception. A line of text may be delimited by `CR`, `LF` or `CRLF`. The newline character(s) are not part of the returned string.

    proc readLine(f: TFile; line: var TaintedString): bool {.tags: [FReadIO],
        raises: [].}

  reads a line of text from the file f into line. line must not be `nil`! May throw an IO exception. A line of text may be delimited by `CR`, `LF` or `CRLF`. The newline character(s) are not part of the returned string. Returns `false` if the end of the file has been reached, `true` otherwise. If `false` is returned line contains no new data.

    proc writeln[Ty](f: TFile; x: varargs[Ty, `$`]) {.inline, tags: [FWriteIO].}

  writes the values x to f and then writes "n". May throw an IO exception.

    proc getFileSize(f: TFile): int64 {.tags: [FReadIO], raises: [EIO].}

  retrieves the file size (in bytes) of f.

    proc ReadBytes(f: TFile; a: var openarray[int8]; start, len: int): int {.
        tags: [FReadIO], raises: [].}

  reads len bytes into the buffer a starting at `a[start]`. Returns the actual number of bytes that have been read which may be less than len (if not as many bytes are remaining), but not greater.

    proc ReadChars(f: TFile; a: var openarray[char]; start, len: int): int {.
        tags: [FReadIO], raises: [].}

  reads len bytes into the buffer a starting at `a[start]`. Returns the actual number of bytes that have been read which may be less than len (if not as many bytes are remaining), but not greater.

    proc readBuffer(f: TFile; buffer: pointer; len: int): int {.tags: [FReadIO],
        raises: [].}

  reads len bytes into the buffer pointed to by buffer. Returns the actual number of bytes that have been read which may be less than len (if not as many bytes are remaining), but not greater.

    proc writeBytes(f: TFile; a: openarray[int8]; start, len: int): int {.
        tags: [FWriteIO], raises: [E_Base].}

  writes the bytes of `a[start..start+len-1]` to the file f. Returns the number of actual written bytes, which may be less than len in case of an error.

    proc writeChars(f: TFile; a: openarray[char]; start, len: int): int {.
        tags: [FWriteIO], raises: [E_Base].}

  writes the bytes of `a[start..start+len-1]` to the file f. Returns the number of actual written bytes, which may be less than len in case of an error.

    proc writeBuffer(f: TFile; buffer: pointer; len: int): int {.tags: [FWriteIO],
        raises: [].}

  writes the bytes of buffer pointed to by the parameter buffer to the file f. Returns the number of actual written bytes, which may be less than len in case of an error.

    proc setFilePos(f: TFile; pos: int64) {.raises: [EIO], tags: [].}

  sets the position of the file pointer that is used for read/write operations. The file's first byte has the index zero.

    proc getFilePos(f: TFile): int64 {.raises: [EIO], tags: [].}

  retrieves the current position of the file pointer that is used to read from the file f. The file's first byte has the index zero.

    proc fileHandle(f: TFile): TFileHandle {.importc: "fileno", header: "<stdio.h>".}

  returns the OS file handle of the file `f`. This is only useful for platform specific programming.

    proc cstringArrayToSeq(a: cstringArray; len: int): seq[string] {.raises: [],
        tags: [].}

  converts a `cstringArray` to a `seq[string]`. a is supposed to be of length `len`.

    proc cstringArrayToSeq(a: cstringArray): seq[string] {.raises: [], tags: [].}

  converts a `cstringArray` to a `seq[string]`. a is supposed to be terminated by `nil`.

    proc allocCStringArray(a: openarray[string]): cstringArray {.raises: [E_Base],
        tags: [].}

  creates a NULL terminated cstringArray from a. The result has to be freed with deallocCStringArray after it's not needed anymore.

    proc deallocCStringArray(a: cstringArray) {.raises: [E_Base], tags: [].}

  frees a NULL terminated cstringArray.

    proc atomicInc(memLoc: var int; x: int = 1): int {.inline, discardable,
        raises: [], tags: [].}

  atomic increment of memLoc. Returns the value after the operation.

    proc atomicDec(memLoc: var int; x: int = 1): int {.inline, discardable,
        raises: [], tags: [].}

  atomic decrement of memLoc. Returns the value after the operation.

    proc atomicInc(memLoc: var int; x: int = 1): int {.inline, discardable,
        raises: [], tags: [].}

  atomic increment of memLoc. Returns the value after the operation.

    proc atomicDec(memLoc: var int; x: int = 1): int {.inline, discardable,
        raises: [], tags: [].}

  atomic decrement of memLoc. Returns the value after the operation.

    proc compareAndSwap[T](mem: var T; expected: T; newValue: T): bool {.inline.}

  Returns true if successfully set value at mem to newValue when value at mem == expected

    proc setControlCHook(hook: proc () {.noconv.}) {.raises: [E_Base],
        tags: [TEffect].}

  allows you to override the behaviour of your application when CTRL+C is pressed. Only one such hook is supported.

    proc writeStackTrace() {.tags: [FWriteIO], raises: [E_Base].}

  writes the current stack trace to `stderr`. This is only works for debug builds.

    proc getStackTrace(): string {.raises: [], tags: [].}

  gets the current stack trace. This only works for debug builds.

    proc getStackTrace(e: ref E_Base): string {.raises: [], tags: [].}

  gets the stack trace associated with e, which is the stack that lead to the `raise` statement. This only works for debug builds.

    proc writeStackTrace() {.tags: [FWriteIO], raises: [E_Base].}

  writes the current stack trace to `stderr`. This is only works for debug builds.

    proc getStackTrace(): string {.raises: [], tags: [].}

  gets the current stack trace. This only works for debug builds.

    proc getStackTrace(e: ref E_Base): string {.raises: [], tags: [].}

  gets the stack trace associated with e, which is the stack that lead to the `raise` statement. This only works for debug builds.

    proc setControlCHook(hook: proc () {.noconv.}) {.raises: [E_Base],
        tags: [TEffect].}

  allows you to override the behaviour of your application when CTRL+C is pressed. Only one such hook is supported.

    proc alloc(size: int): pointer {.noconv, rtl, tags: [], raises: [E_Base].}

  allocates a new memory block with at least `size` bytes. The block has to be freed with `realloc(block, 0)` or `dealloc(block)`. The block is not initialized, so reading from it before writing to it is undefined behaviour! The allocated memory belongs to its allocating thread! Use allocShared to allocate from a shared heap.

    proc alloc0(size: int): pointer {.noconv, rtl, tags: [], raises: [E_Base].}

  allocates a new memory block with at least `size` bytes. The block has to be freed with `realloc(block, 0)` or `dealloc(block)`. The block is initialized with all bytes containing zero, so it is somewhat safer than `alloc`. The allocated memory belongs to its allocating thread! Use allocShared0 to allocate from a shared heap.

    proc dealloc(p: pointer) {.noconv, rtl, tags: [], raises: [E_Base].}

  frees the memory allocated with `alloc`, `alloc0` or `realloc`. This procedure is dangerous! If one forgets to free the memory a leak occurs; if one tries to access freed memory (or just freeing it twice!) a core dump may happen or other memory may be corrupted. The freed memory must belong to its allocating thread! Use deallocShared to deallocate from a shared heap.

    proc realloc(p: pointer; newsize: int): pointer {.noconv, rtl, tags: [],
        raises: [E_Base].}

  grows or shrinks a given memory block. If p is nil then a new memory block is returned. In either way the block has at least `newsize` bytes. If `newsize == 0` and p is not nil `realloc` calls `dealloc(p)`. In other cases the block has to be freed with `dealloc`. The allocated memory belongs to its allocating thread! Use reallocShared to reallocate from a shared heap.

    proc getFreeMem(): int {.rtl, raises: [], tags: [].}

  returns the number of bytes that are owned by the process, but do not hold any meaningful data.

    proc getTotalMem(): int {.rtl, raises: [], tags: [].}

  returns the number of bytes that are owned by the process.

    proc getOccupiedMem(): int {.rtl, raises: [], tags: [].}

  returns the number of bytes that are owned by the process and hold data.

    proc allocShared(size: int): pointer {.noconv, rtl, raises: [E_Base], tags: [].}

  allocates a new memory block on the shared heap with at least `size` bytes. The block has to be freed with `reallocShared(block, 0)` or `deallocShared(block)`. The block is not initialized, so reading from it before writing to it is undefined behaviour!

    proc allocShared0(size: int): pointer {.noconv, rtl, raises: [E_Base], tags: [].}

  allocates a new memory block on the shared heap with at least `size` bytes. The block has to be freed with `reallocShared(block, 0)` or `deallocShared(block)`. The block is initialized with all bytes containing zero, so it is somewhat safer than `allocShared`.

    proc deallocShared(p: pointer) {.noconv, rtl, raises: [E_Base], tags: [].}

  frees the memory allocated with `allocShared`, `allocShared0` or `reallocShared`. This procedure is dangerous! If one forgets to free the memory a leak occurs; if one tries to access freed memory (or just freeing it twice!) a core dump may happen or other memory may be corrupted.

    proc reallocShared(p: pointer; newsize: int): pointer {.noconv, rtl,
        raises: [E_Base], tags: [].}

  grows or shrinks a given memory block on the heap. If p is nil then a new memory block is returned. In either way the block has at least `newsize` bytes. If `newsize == 0` and p is not nil `reallocShared` calls `deallocShared(p)`. In other cases the block has to be freed with `deallocShared`.

    proc IsOnStack(p: pointer): bool {.noinline, raises: [], tags: [].}

    proc GC_addCycleRoot[T](p: ref T) {.inline.}

  adds 'p' to the cycle candidate set for the cycle collector. It is necessary if you used the 'acyclic' pragma for optimization purposes and need to break cycles manually.

    proc IsOnStack(p: pointer): bool {.noinline, raises: [], tags: [].}

    proc GC_disable() {.rtl, inl, raises: [], tags: [].}

  disables the GC. If called n-times, n calls to GC_enable are needed to reactivate the GC. Note that in most circumstances one should only disable the mark and sweep phase with GC_disableMarkAndSweep.

    proc GC_enable() {.rtl, inl, raises: [], tags: [].}

  enables the GC again.

    proc GC_setStrategy(strategy: TGC_Strategy) {.rtl, deprecated, raises: [],
        tags: [].}

  tells the GC the desired strategy for the application. Deprecated since version 0.8.14. This has always been a nop.

    proc GC_enableMarkAndSweep() {.rtl, raises: [], tags: [].}

    proc GC_disableMarkAndSweep() {.rtl, raises: [], tags: [].}

  the current implementation uses a reference counting garbage collector with a seldomly run mark and sweep phase to free cycles. The mark and sweep phase may take a long time and is not needed if the application does not create cycles. Thus the mark and sweep phase can be deactivated and activated separately from the rest of the GC.

    proc GC_fullCollect() {.rtl, raises: [E_Base], tags: [TEffect].}

  forces a full garbage collection pass. Ordinary code does not need to call this (and should not).

    proc GC_getStatistics(): string {.rtl, raises: [], tags: [].}

  returns an informative string about the GC's activity. This may be useful for tweaking.

    proc write(f: TFile; c: cstring) {.tags: [FWriteIO], raises: [].}

    proc readLine(f: TFile; line: var TaintedString): bool {.tags: [FReadIO],
        raises: [].}

  reads a line of text from the file f into line. line must not be `nil`! May throw an IO exception. A line of text may be delimited by `CR`, `LF` or `CRLF`. The newline character(s) are not part of the returned string. Returns `false` if the end of the file has been reached, `true` otherwise. If `false` is returned line contains no new data.

    proc readLine(f: TFile): TaintedString {.tags: [FReadIO], raises: [EIO].}

  reads a line of text from the file f. May throw an IO exception. A line of text may be delimited by `CR`, `LF` or `CRLF`. The newline character(s) are not part of the returned string.

    proc write(f: TFile; i: int) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; i: BiggestInt) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; b: bool) {.tags: [FWriteIO], raises: [E_Base].}

    proc write(f: TFile; r: float) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; r: BiggestFloat) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; c: char) {.tags: [FWriteIO], raises: [].}

    proc write(f: TFile; a: varargs[string, `$`]) {.tags: [FWriteIO],
        raises: [E_Base].}

  Writes a value to the file f. May throw an IO exception.

    proc readAll(file: TFile): TaintedString {.tags: [FReadIO],
        raises: [E_Base, EIO].}

  Reads all data from the stream file. Raises an IO exception in case of an error

    proc readFile(filename: string): TaintedString {.tags: [FReadIO],
        raises: [E_Base, EIO, E_Base, EIO].}

  Opens a file named filename for reading. Then calls readAll and closes the file afterwards. Returns the string. Raises an IO exception in case of an error.

    proc writeFile(filename, content: string) {.tags: [FWriteIO],
        raises: [E_Base, EIO, E_Base].}

  Opens a file named filename for writing. Then writes the content completely to the file and closes the file afterwards. Raises an IO exception in case of an error.

    proc EndOfFile(f: TFile): bool {.tags: [], raises: [].}

  Returns true iff f is at the end.

    proc writeln[Ty](f: TFile; x: varargs[Ty, `$`]) {.inline, tags: [FWriteIO].}

  writes the values x to f and then writes "n". May throw an IO exception.

    proc Open(f: var TFile; filename: string; mode: TFileMode = fmRead;
              bufSize: int = - 1): bool {.tags: [], raises: [EOutOfMemory].}

  Opens a file named filename with given mode.

  Default mode is readonly. Returns true iff the file could be opened. This throws no exception if the file could not be opened.

    proc reopen(f: TFile; filename: string; mode: TFileMode = fmRead): bool {.
        tags: [], raises: [].}

  reopens the file f with given filename and mode. This is often used to redirect the stdin, stdout or stderr file variables.

  Default mode is readonly. Returns true iff the file could be reopened.

    proc Open(f: var TFile; filehandle: TFileHandle; mode: TFileMode = fmRead): bool {.
        tags: [], raises: [].}

  Creates a `TFile` from a filehandle with given mode.

  Default mode is readonly. Returns true iff the file could be opened.

    proc readBuffer(f: TFile; buffer: pointer; len: int): int {.tags: [FReadIO],
        raises: [].}

  reads len bytes into the buffer pointed to by buffer. Returns the actual number of bytes that have been read which may be less than len (if not as many bytes are remaining), but not greater.

    proc ReadBytes(f: TFile; a: var openarray[int8]; start, len: int): int {.
        tags: [FReadIO], raises: [].}

  reads len bytes into the buffer a starting at `a[start]`. Returns the actual number of bytes that have been read which may be less than len (if not as many bytes are remaining), but not greater.

    proc ReadChars(f: TFile; a: var openarray[char]; start, len: int): int {.
        tags: [FReadIO], raises: [].}

  reads len bytes into the buffer a starting at `a[start]`. Returns the actual number of bytes that have been read which may be less than len (if not as many bytes are remaining), but not greater.

    proc writeBytes(f: TFile; a: openarray[int8]; start, len: int): int {.
        tags: [FWriteIO], raises: [E_Base].}

  writes the bytes of `a[start..start+len-1]` to the file f. Returns the number of actual written bytes, which may be less than len in case of an error.

    proc writeChars(f: TFile; a: openarray[char]; start, len: int): int {.
        tags: [FWriteIO], raises: [E_Base].}

  writes the bytes of `a[start..start+len-1]` to the file f. Returns the number of actual written bytes, which may be less than len in case of an error.

    proc writeBuffer(f: TFile; buffer: pointer; len: int): int {.tags: [FWriteIO],
        raises: [].}

  writes the bytes of buffer pointed to by the parameter buffer to the file f. Returns the number of actual written bytes, which may be less than len in case of an error.

    proc write(f: TFile; s: string) {.tags: [FWriteIO], raises: [EIO].}

    proc setFilePos(f: TFile; pos: int64) {.raises: [EIO], tags: [].}

  sets the position of the file pointer that is used for read/write operations. The file's first byte has the index zero.

    proc getFilePos(f: TFile): int64 {.raises: [EIO], tags: [].}

  retrieves the current position of the file pointer that is used to read from the file f. The file's first byte has the index zero.

    proc getFileSize(f: TFile): int64 {.tags: [FReadIO], raises: [EIO].}

  retrieves the file size (in bytes) of f.

    proc nimDestroyRange[T](r: T)

    proc `$`(x: uint64): string {.noSideEffect, raises: [], tags: [].}

  The stingify operator for an unsigned integer argument. Returns x converted to a decimal string.

    proc getCurrentException(): ref E_Base {.compilerRtl, inl, raises: [], tags: [].}

  retrieves the current exception; if there is none, nil is returned.

    proc getCurrentExceptionMsg(): string {.inline, raises: [], tags: [].}

  retrieves the error message that was attached to the current exception; if there is none, "" is returned.

    proc onRaise(action: proc (e: ref E_Base): bool {.closure.}) {.raises: [],
        tags: [].}

  can be used in a `try` statement to setup a Lisp-like condition system: This prevents the 'raise' statement to raise an exception but instead calls `action`. If `action` returns false, the exception has been handled and does not propagate further through the call stack.

    proc likely(val: bool): bool {.importc: "likely", nodecl, nosideeffect.}

  can be used to mark a condition to be likely. This is a hint for the optimizer.

    proc unlikely(val: bool): bool {.importc: "unlikely", nodecl, nosideeffect.}

  can be used to mark a condition to be unlikely. This is a hint for the optimizer.

    proc rawProc[T](x: T): pointer {.noSideEffect, inline.}

  retrieves the raw proc pointer of the closure x. This is useful for interfacing closures with C.

    proc rawEnv[T](x: T): pointer {.noSideEffect, inline.}

  retrieves the raw environment pointer of the closure x. This is useful for interfacing closures with C.

    proc finished[T](x: T): bool {.noSideEffect, inline.}

  can be used to determine if a first class iterator has finished.

    proc quit(errormsg: string; errorcode = QuitFailure) {.noReturn, raises: [],
        tags: [].}

  a shorthand for `echo(errormsg); quit(errorcode)`.

    proc `/`(x, y: int): float {.inline, noSideEffect, raises: [], tags: [].}

  integer division that results in a float.

    proc `[]`(s: string; x: TSlice[int]): string {.inline, raises: [], tags: [].}

  slice operation for strings. Negative indexes are supported.

    proc `[]=`(s: var string; x: TSlice[int]; b: string) {.raises: [], tags: [].}

  slice assignment for strings. Negative indexes are supported. If `b.len` is not exactly the number of elements that are referred to by x, a splice is performed:

      var s = "abcdef"
      s[1 .. -2] = "xyz"
      assert s == "axyzf"

    proc `[]`[Idx, T](a: array[Idx, T]; x: TSlice[int]): seq[T]

  slice operation for arrays. Negative indexes are not supported because the array might have negative bounds.

    proc `[]=`[Idx, T](a: var array[Idx, T]; x: TSlice[int]; b: openarray[T])

  slice assignment for arrays. Negative indexes are not supported because the array might have negative bounds.

    proc `[]`[Idx, T](a: array[Idx, T]; x: TSlice[Idx]): seq[T]

  slice operation for arrays. Negative indexes are not supported because the array might have negative bounds.

    proc `[]=`[Idx, T](a: var array[Idx, T]; x: TSlice[Idx]; b: openarray[T])

  slice assignment for arrays. Negative indexes are not supported because the array might have negative bounds.

    proc `[]`[T](s: seq[T]; x: TSlice[int]): seq[T]

  slice operation for sequences. Negative indexes are supported.

    proc `[]=`[T](s: var seq[T]; x: TSlice[int]; b: openarray[T])

  slice assignment for sequences. Negative indexes are supported. If `b.len` is not exactly the number of elements that are referred to by x, a splice is performed.

    proc slurp(filename: string): string {.magic: "Slurp".}

    proc staticRead(filename: string): string {.magic: "Slurp".}

  compile-time `readFile` proc for easy resource embedding:

      const myResource = staticRead"mydatafile.bin"

  `slurp` is an alias for `staticRead`.

    proc gorge(command: string; input = ""): string {.magic: "StaticExec",
        raises: [], tags: [].}

    proc staticExec(command: string; input = ""): string {.magic: "StaticExec",
        raises: [], tags: [].}

  executes an external process at compile-time. 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` is an alias for `staticExec`.

    proc `+=`[T](x: var T; y: T) {.magic: "Inc", noSideEffect.}

  Increments an ordinal

    proc `-=`[T](x: var T; y: T) {.magic: "Dec", noSideEffect.}

  Decrements an ordinal

    proc `*=`[T](x: var T; y: T) {.inline, noSideEffect.}

  Binary *= operator for ordinals

    proc `+=`[T](x: var T; y: T) {.inline, noSideEffect.}

  Increments in placee a floating point number

    proc `-=`[T](x: var T; y: T) {.inline, noSideEffect.}

  Decrements in place a floating point number

    proc `*=`[T](x: var T; y: T) {.inline, noSideEffect.}

  Multiplies in place a floating point number

    proc `/=`[T](x: var T; y: T) {.inline, noSideEffect.}

  Divides in place a floating point number

    proc `&=`(x: var string; y: string) {.magic: "AppendStrStr", noSideEffect.}

    proc rand(max: int): int {.magic: "Rand", sideEffect.}

  compile-time random function. Useful for debugging.

    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 InstantiationInfo(index = - 1; fullPaths = false): tuple[filename: string,
        line: int] {.magic: "InstantiationInfo", noSideEffect.}

  provides access to the compiler's instantiation stack line information.

  This proc is mostly useful for meta programming (eg. `assert` template) to retrieve information about the current filename and line number. Example:

      import strutils

      template testException(exception, code: expr): stmt =
        try:
          let pos = instantiationInfo()
          discard(code)
          echo "Test failure at $1:$2 with '$3'" % [pos.filename,
            $pos.line, astToStr(code)]
          assert false, "A test expecting failure succeeded?"
        except exception:
          nil

      proc tester(pos: int): int =
        let
          a = @[1, 2, 3]
        result = a[pos]

      when isMainModule:
        testException(EInvalidIndex, tester(30))
        testException(EInvalidIndex, tester(1))
        # --> Test failure at example.nim:20 with 'tester(1)'

    proc raiseAssert(msg: string) {.noinline, raises: [EAssertionFailed], tags: [].}

    proc shallow[T](s: var seq[T]) {.noSideEffect, inline.}

  marks a sequence s as shallow. Subsequent assignments will not perform deep copies of s. This is only useful for optimization purposes.

    proc shallow(s: var string) {.noSideEffect, inline, raises: [], tags: [].}

  marks a string s as shallow. Subsequent assignments will not perform deep copies of s. This is only useful for optimization purposes.

    proc insert(x: var string; item: string; i = 0) {.noSideEffect, raises: [],
        tags: [].}

  inserts item into x at position i.

    proc compiles[expr](x: expr): bool {.magic: "Compiles", noSideEffect.}

  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 not compiles(3 + 4):
        echo "'+' for integers is available"

    proc safeAdd[T](x: var seq[T]; y: T) {.noSideEffect.}

    proc safeAdd(x: var string; y: char) {.raises: [], tags: [].}

    proc safeAdd(x: var string; y: string) {.raises: [], tags: [].}

    proc locals(): TObject {.magic: "Locals", noSideEffect, raises: [], tags: [].}

  generates a tuple constructor expression listing all the local variables in the current scope. This is quite fast as it does not rely on any debug or runtime information. Note that in constrast to what the official signature says, the return type is not `TObject` but a tuple of a structure that depends on the current scope.

# Iterators

    iterator countdown[T](a, b: T; step = 1): T {.inline.}

  Counts from ordinal value a down to b with the given step count. T may be any ordinal type, step may only be positive.

    iterator countup[S, T](a: S; b: T; step = 1): T {.inline.}

  Counts from ordinal value a up to b with the given step count. S, T may be any ordinal type, step may only be positive.

    iterator `..`[S, T](a: S; b: T): T {.inline.}

  An alias for countup.

    iterator `||`[S, T](a: S; b: T; annotation = ""): T {.inline,
        magic: "OmpParFor", sideEffect.}

  parallel loop iterator. Same as .. but the loop may run in parallel. annotation is an additional annotation for the code generator to use. Note that the compiler maps that to the `#pragma omp parallel for` construct of OpenMP and as such isn't aware of the parallelism in your code! Be careful! Later versions of `||` will get proper support by Nimrod's code generator and GC.

    iterator items[T](a: openarray[T]): T {.inline.}

  iterates over each item of a.

    iterator items[IX, T](a: array[IX, T]): T {.inline.}

  iterates over each item of a.

    iterator items[T](a: seq[T]): T {.inline.}

  iterates over each item of a.

    iterator items(a: string): char {.inline, raises: [], tags: [].}

  iterates over each item of a.

    iterator items[T](a: set[T]): T {.inline.}

  iterates over each element of a. items iterates only over the elements that are really in the set (and not over the ones the set is able to hold).

    iterator items(a: cstring): char {.inline, raises: [], tags: [].}

  iterates over each item of a.

    iterator items[typeDesc, result:type](E: typeDesc[enum]): E

  iterates over the values of the enum `E`.

    iterator pairs[T](a: openarray[T]): tuple[key: int, val: T] {.inline.}

  iterates over each item of a. Yields `(index, a[index])` pairs.

    iterator pairs[IX, T](a: array[IX, T]): tuple[key: IX, val: T] {.inline.}

  iterates over each item of a. Yields `(index, a[index])` pairs.

    iterator pairs[T](a: seq[T]): tuple[key: int, val: T] {.inline.}

  iterates over each item of a. Yields `(index, a[index])` pairs.

    iterator pairs(a: string): tuple[key: int, val: char] {.inline, raises: [],
        tags: [].}

  iterates over each item of a. Yields `(index, a[index])` pairs.

    iterator fields[T](x: T): TObject {.magic: "Fields", noSideEffect.}

  iterates over every field of x. Warning: This really transforms the 'for' and unrolls the loop. The current implementation also has a bug that affects symbol binding in the loop body.

    iterator fields[S, T](x: S; y: T): tuple[a, b: expr] {.magic: "Fields",
        noSideEffect.}

  iterates over every field of x and y. Warning: This is really transforms the 'for' and unrolls the loop. The current implementation also has a bug that affects symbol binding in the loop body.

    iterator fieldPairs[T](x: T): TObject {.magic: "FieldPairs", noSideEffect.}

  iterates over every field of x. Warning: This really transforms the 'for' and unrolls the loop. The current implementation also has a bug that affects symbol binding in the loop body.

    iterator fieldPairs[S, T](x: S; y: T): tuple[a, b: expr] {.magic: "FieldPairs",
        noSideEffect.}

  iterates over every field of x and y. Warning: This really transforms the 'for' and unrolls the loop. The current implementation also has a bug that affects symbol binding in the loop body.

    iterator lines(filename: string): TaintedString {.tags: [FReadIO],
        raises: [E_Base, EIO].}

  Iterate over any line in the file named filename. If the file does not exist EIO is raised.

    iterator lines(f: TFile): TaintedString {.tags: [FReadIO], raises: [].}

  Iterate over any line in the file f.

# Templates

    template `!=`(x, y: expr): expr {.immediate.}

    template `>=`(x, y: expr): expr {.immediate.}

    template `>`(x, y: expr): expr {.immediate.}

    template `in`(x, y: expr): expr {.immediate.}

    template `not_in`(x, y: expr): expr {.immediate.}

    template `is_not`(x, y: expr): expr {.immediate.}

    template `>=%`(x, y: expr): expr {.immediate.}

  treats x and y as unsigned and compares them. Returns true iff `unsigned(x) >= unsigned(y)`.

    template `>%`(x, y: expr): expr {.immediate.}

  treats x and y as unsigned and compares them. Returns true iff `unsigned(x) > unsigned(y)`.

    template accumulateResult(iter: expr)

  helps to convert an iterator to a proc.

    template newException(exceptn: typeDesc; message: string): expr

  creates an exception object of type `exceptn` and sets its `msg` field to message. Returns the new exception object.

    template `-|`(b, s: expr): expr

    template CurrentSourcePath(): string

  returns the full file-system path of the current source

    template assert(cond: bool; msg = "")

  provides a means to implement programming by contracts in Nimrod. `assert` evaluates expression `cond` and if `cond` is false, it raises an `EAssertionFailure` exception. However, the compiler may not generate any code at all for `assert` if it is advised to do so. Use `assert` for debugging purposes only.

    template doAssert(cond: bool; msg = "")

  same as assert but is always turned on and not affected by the `--assertions` command line switch.

    template onFailedAssert(msg: expr; code: stmt): stmt

  Sets an assertion failure handler that will intercept any assert statements following onFailedAssert in the current lexical scope. Can be defined multiple times in a single function.

      proc example(x: int): TErrorCode =
        onFailedAssert(msg):
          log msg
          return E_FAIL

        assert(...)

        onFailedAssert(msg):
          raise newException(EMyException, msg)

        assert(...)

    template eval(blk: stmt): stmt

  executes a block of code at compile time just as if it was a macro optionally, the block can return an AST tree that will replace the eval expression

Generated: 2013-05-21 09:55:04 UTC