PMunch / nimlsp

Language Server Protocol implementation for Nim
MIT License
415 stars 49 forks source link

nimlsp quit immediately opening nim-lang/Nim or .choosenim/toolchains/nim-1.4.8/lib #95

Closed MaskRay closed 2 years ago

MaskRay commented 2 years ago

I use neovim+coc.nvim and have tried nimlsp with several Nim projects.

choosenim update stable #  Info: Already up to date at version 1.4.8
nimble install nimlsp

For nim-lang/Nim, nvim compiler/lexer.nim works fine but nvim compiler/semexprs.nim fails immediately. coc.nvim says [coc.nvim] The "languageserver.nimlsp" server crashed 4 times in the last 3 minutes. The server will not be restarted. :CocInfo dump:

2021-10-09T22:20:39.110 INFO (pid:959357) [services] - registered service "languageserver.ccls"
2021-10-09T22:20:39.111 INFO (pid:959357) [services] - registered service "languageserver.lua-language-server"
2021-10-09T22:20:39.111 INFO (pid:959357) [services] - registered service "languageserver.nimlsp"
2021-10-09T22:20:39.114 INFO (pid:959357) [services] - nimlsp state change: stopped => starting
2021-10-09T22:20:39.116 INFO (pid:959357) [plugin] - coc.nvim 0.0.80-daab29410d initialized with node: v16.3.0 after 91ms
2021-10-09T22:20:39.121 INFO (pid:959357) [language-client-index] - Language server "languageserver.nimlsp" started with 959380
2021-10-09T22:20:39.129 INFO (pid:959357) [services] - nimlsp state change: starting => running
2021-10-09T22:20:39.132 INFO (pid:959357) [services] - service languageserver.nimlsp started
2021-10-09T22:20:39.820 INFO (pid:959357) [services] - nimlsp state change: running => stopped
2021-10-09T22:20:39.821 INFO (pid:959357) [services] - nimlsp state change: stopped => starting
2021-10-09T22:20:39.830 INFO (pid:959357) [language-client-index] - Language server "languageserver.nimlsp" started with 959386
2021-10-09T22:20:39.832 INFO (pid:959357) [services] - nimlsp state change: starting => running
2021-10-09T22:20:40.060 INFO (pid:959357) [services] - nimlsp state change: running => stopped
2021-10-09T22:20:40.060 INFO (pid:959357) [services] - nimlsp state change: stopped => starting
2021-10-09T22:20:40.064 INFO (pid:959357) [language-client-index] - Language server "languageserver.nimlsp" started with 959389
2021-10-09T22:20:40.065 INFO (pid:959357) [services] - nimlsp state change: starting => running
2021-10-09T22:20:40.298 INFO (pid:959357) [services] - nimlsp state change: running => stopped
2021-10-09T22:20:40.298 INFO (pid:959357) [services] - nimlsp state change: stopped => starting
2021-10-09T22:20:40.301 INFO (pid:959357) [language-client-index] - Language server "languageserver.nimlsp" started with 959392
2021-10-09T22:20:40.302 INFO (pid:959357) [services] - nimlsp state change: starting => running
2021-10-09T22:20:40.524 INFO (pid:959357) [services] - nimlsp state change: running => stopped
2021-10-09T22:20:43.916 INFO (pid:959357) [attach] - receive notification: showInfo []

I also get immediate quit if I try jumping to a standard library with (e.g. setLen) via textDocument/definitions:

;; From emacs lsp-mode
LSP :: Guessed project root is ~/.choosenim/toolchains/nim-1.4.8/lib/
LSP :: Connected to [nimls:956461/starting].
LSP :: nimls:956461 initialized successfully in folders: (/home/maskray/.choosenim/toolchains/nim-1.4.8/lib)
LSP :: nimls<1> has exited (exited abnormally with code 1)
Server nimls:956461 exited with status exit(check corresponding stderr buffer for details). Do you want to restart it? (y or n) n
Copied path to clipboard: ~/.choosenim/toolchains/nim-1.4.8/lib/system.nim [3 times]
Quit
Copied path to clipboard: ~/.choosenim/toolchains/nim-1.4.8/lib/system.nim

Nim related part in my neovim config:

  require('packer').startup(function()
    use 'wbthomason/packer.nvim'

    use 'neoclide/coc.nvim'
    use 'alaviss/nim.nvim'
  end)

~/.config/nvim/coc-settings.json:

{
  "languageserver": {
    "nimlsp": {
      "command": "nimlsp",
      "filetypes": ["nim"]
    }
  }
}
PMunch commented 2 years ago

Could you compile nimlsp yourself with debug logging and try again? This is likely to be a nimsuggest error, but if not this should help identify what it is.

PMunch commented 2 years ago

Just built one myself, it is simply a call to initNimsuggest that fails. Please report this in the nimsuggest error tracker

MaskRay commented 2 years ago

I filed nim-lang/Nim#18985 for nimsuggest. @xflywind noted that choosenim devel (nim 1.5.1) had fixed the nvim compiler/semexprs.nim problem and I confirm that.

However, with nim 1.5.1, nimlsp immediately quit for another file: nvim lib/system.nim. nimsuggest lib/system.nim doesn't crash. I am still learning the ecosystem and am quite puzzled on which component has an issue. I appreciate your debugging:)

(The title of this issue has .choosenim/toolchains/nim-1.4.8/lib. That was because I noticed that lib/system.nim does not work as well, though I did not mention it in the first comment.)

:CocCommand workspace.showOutput log (language server log)

Version: 0.3.2
explicitSourcePath: /home/maskray/.choosenim/toolchains/nim-#devel
Trying to read frame
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":1284548,"rootPath":"/home/maskray/Dev/Nim","rootUri":"file:///home/maskray/Dev/Nim","capabilities":{"workspace":{"applyEdit":true,"workspaceEdit":{"documentChanges":true,"resourceOperations":["create","rename","delete"],"failureHandling":"textOnlyTransactional"},"didChangeConfiguration":{"dynamicRegistration":true},"didChangeWatchedFiles":{"dynamicRegistration":true},"symbol":{"dynamicRegistration":true,"symbolKind":{"valueSet":[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]},"tagSupport":{"valueSet":[1]}},"codeLens":{"refreshSupport":true},"executeCommand":{"dynamicRegistration":true},"configuration":true,"semanticTokens":{"refreshSupport":true},"fileOperations":{"dynamicRegistration":true,"didCreate":true,"didRename":true,"didDelete":true,"willCreate":true,"willRename":true,"willDelete":true},"workspaceFolders":true},"textDocument":{"publishDiagnostics":{"relatedInformation":true,"versionSupport":false,"tagSupport":{"valueSet":[1,2]}},"synchronization":{"dynamicRegistration":true,"willSave":true,"willSaveWaitUntil":true,"didSave":true},"completion":{"dynamicRegistration":true,"contextSupport":true,"completionItem":{"snippetSupport":true,"commitCharactersSupport":true,"documentationFormat":["markdown","plaintext"],"deprecatedSupport":true,"preselectSupport":true,"insertReplaceSupport":true,"tagSupport":{"valueSet":[1]},"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"insertTextModeSupport":{"valueSet":[1,2]}},"completionItemKind":{"valueSet":[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]}},"hover":{"dynamicRegistration":true,"contentFormat":["markdown","plaintext"]},"signatureHelp":{"dynamicRegistration":true,"contextSupport":true,"signatureInformation":{"documentationFormat":["markdown","plaintext"],"activeParameterSupport":true,"parameterInformation":{"labelOffsetSupport":true}}},"definition":{"dynamicRegistration":true},"references":{"dynamicRegistration":true},"documentHighlight":{"dynamicRegistration":true},"documentSymbol":{"dynamicRegistration":true,"symbolKind":{"valueSet":[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]},"hierarchicalDocumentSymbolSupport":true,"tagSupport":{"valueSet":[1]}},"codeAction":{"dynamicRegistration":true,"isPreferredSupport":true,"disabledSupport":true,"dataSupport":true,"honorsChangeAnnotations":false,"resolveSupport":{"properties":["edit"]},"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}}},"codeLens":{"dynamicRegistration":true},"formatting":{"dynamicRegistration":true},"rangeFormatting":{"dynamicRegistration":true},"onTypeFormatting":{"dynamicRegistration":true},"rename":{"dynamicRegistration":true,"prepareSupport":true},"documentLink":{"dynamicRegistration":true,"tooltipSupport":true},"typeDefinition":{"dynamicRegistration":true},"implementation":{"dynamicRegistration":true},"declaration":{"dynamicRegistration":true},"colorProvider":{"dynamicRegistration":true},"foldingRange":{"dynamicRegistration":true,"rangeLimit":5000,"lineFoldingOnly":true},"selectionRange":{"dynamicRegistration":true},"callHierarchy":{"dynamicRegistration":true},"semanticTokens":{"dynamicRegistration":true,"tokenTypes":["namespace","type","class","enum","interface","struct","typeParameter","parameter","variable","property","enumMember","event","function","method","macro","keyword","modifier","comment","string","number","regexp","operator"],"tokenModifiers":["declaration","definition","readonly","static","deprecated","abstract","async","modification","documentation","defaultLibrary"],"formats":["relative"],"requests":{"range":true,"full":{"delta":true}},"multilineTokenSupport":false,"overlappingTokenSupport":false},"linkedEditingRange":{"dynamicRegistration":true}},"window":{"showMessage":{"messageActionItem":{"additionalPropertiesSupport":false}},"showDocument":{"support":false},"workDoneProgress":true},"general":{"regularExpressions":{"engine":"ECMAScript","version":"ES2020"},"markdown":{"parser":"marked","version":"1.1.0"}}},"initializationOptions":{},"trace":"off","workspaceFolders":[{"uri":"file:///home/maskray/Dev/Nim","name":"Nim"}],"locale":"en_US","clientInfo":{"name":"coc.nvim","version":"0.0.80"},"workDoneToken":"77b6fe0a-df0c-48a3-8aa5-1ec1c3c54ec4"}}
Got frame:
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":1284548,"rootPath":"/home/maskray/Dev/Nim","rootUri":"file:///home/maskray/Dev/Nim","capabilities":{"workspace":{"applyEdit":true,"workspaceEdit":{"documentChanges":true,"resourceOperations":["create","rename","delete"],"failureHandling":"textOnlyTransactional"},"didChangeConfiguration":{"dynamicRegistration":true},"didChangeWatchedFiles":{"dynamicRegistration":true},"symbol":{"dynamicRegistration":true,"symbolKind":{"valueSet":[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]},"tagSupport":{"valueSet":[1]}},"codeLens":{"refreshSupport":true},"executeCommand":{"dynamicRegistration":true},"configuration":true,"semanticTokens":{"refreshSupport":true},"fileOperations":{"dynamicRegistration":true,"didCreate":true,"didRename":true,"didDelete":true,"willCreate":true,"willRename":true,"willDelete":true},"workspaceFolders":true},"textDocument":{"publishDiagnostics":{"relatedInformation":true,"versionSupport":false,"tagSupport":{"valueSet":[1,2]}},"synchronization":{"dynamicRegistration":true,"willSave":true,"willSaveWaitUntil":true,"didSave":true},"completion":{"dynamicRegistration":true,"contextSupport":true,"completionItem":{"snippetSupport":true,"commitCharactersSupport":true,"documentationFormat":["markdown","plaintext"],"deprecatedSupport":true,"preselectSupport":true,"insertReplaceSupport":true,"tagSupport":{"valueSet":[1]},"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"insertTextModeSupport":{"valueSet":[1,2]}},"completionItemKind":{"valueSet":[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]}},"hover":{"dynamicRegistration":true,"contentFormat":["markdown","plaintext"]},"signatureHelp":{"dynamicRegistration":true,"contextSupport":true,"signatureInformation":{"documentationFormat":["markdown","plaintext"],"activeParameterSupport":true,"parameterInformation":{"labelOffsetSupport":true}}},"definition":{"dynamicRegistration":true},"references":{"dynamicRegistration":true},"documentHighlight":{"dynamicRegistration":true},"documentSymbol":{"dynamicRegistration":true,"symbolKind":{"valueSet":[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]},"hierarchicalDocumentSymbolSupport":true,"tagSupport":{"valueSet":[1]}},"codeAction":{"dynamicRegistration":true,"isPreferredSupport":true,"disabledSupport":true,"dataSupport":true,"honorsChangeAnnotations":false,"resolveSupport":{"properties":["edit"]},"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}}},"codeLens":{"dynamicRegistration":true},"formatting":{"dynamicRegistration":true},"rangeFormatting":{"dynamicRegistration":true},"onTypeFormatting":{"dynamicRegistration":true},"rename":{"dynamicRegistration":true,"prepareSupport":true},"documentLink":{"dynamicRegistration":true,"tooltipSupport":true},"typeDefinition":{"dynamicRegistration":true},"implementation":{"dynamicRegistration":true},"declaration":{"dynamicRegistration":true},"colorProvider":{"dynamicRegistration":true},"foldingRange":{"dynamicRegistration":true,"rangeLimit":5000,"lineFoldingOnly":true},"selectionRange":{"dynamicRegistration":true},"callHierarchy":{"dynamicRegistration":true},"semanticTokens":{"dynamicRegistration":true,"tokenTypes":["namespace","type","class","enum","interface","struct","typeParameter","parameter","variable","property","enumMember","event","function","method","macro","keyword","modifier","comment","string","number","regexp","operator"],"tokenModifiers":["declaration","definition","readonly","static","deprecated","abstract","async","modification","documentation","defaultLibrary"],"formats":["relative"],"requests":{"range":true,"full":{"delta":true}},"multilineTokenSupport":false,"overlappingTokenSupport":false},"linkedEditingRange":{"dynamicRegistration":true}},"window":{"showMessage":{"messageActionItem":{"additionalPropertiesSupport":false}},"showDocument":{"support":false},"workDoneProgress":true},"general":{"regularExpressions":{"engine":"ECMAScript","version":"ES2020"},"markdown":{"parser":"marked","version":"1.1.0"}}},"initializationOptions":{},"trace":"off","workspaceFolders":[{"uri":"file:///home/maskray/Dev/Nim","name":"Nim"}],"locale":"en_US","clientInfo":{"name":"coc.nvim","version":"0.0.80"},"workDoneToken":"77b6fe0a-df0c-48a3-8aa5-1ec1c3c54ec4"}}
Got valid Request message of type initialize
Got initialize request, answering
{"jsonrpc":"2.0","id":0,"result":{"capabilities":{"textDocumentSync":{"openClose":true,"change":1,"willSave":false,"willSaveWaitUntil":false,"save":{"includeText":true}},"hoverProvider":true,"completionProvider":{"resolveProvider":false,"triggerCharacters":["."," "]},"definitionProvider":true,"referencesProvider":true,"documentSymbolProvider":true,"renameProvider":true}}}
Trying to read frame
{"jsonrpc":"2.0","method":"initialized","params":{}}
Got frame:
{"jsonrpc":"2.0","method":"initialized","params":{}}
Unable to parse data as RequestMessage
Got valid Notification message of type initialized
Properly initialized
Trying to read frame
{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///home/maskray/Dev/Nim/lib/system.nim","languageId":"nim","version":1,"text":"#\n#\n#            Nim's Runtime Library\n#        (c) Copyright 2015 Andreas Rumpf\n#\n#    See the file \"copying.txt\", included in this\n#    distribution, for details about the copyright.\n#\n\n\n## The compiler depends on the System module to work properly and the System\n## module depends on the compiler. Most of the routines listed here use\n## special compiler magic.\n##\n## Each module implicitly imports the System module; it must not be listed\n## explicitly. Because of this there cannot be a user-defined module named\n## `system`.\n##\n## System module\n## =============\n##\n## .. include:: ./system_overview.rst\n\n\ntype\n  float* {.magic: Float.}     ## Default floating point type.\n  float32* {.magic: Float32.} ## 32 bit floating point type.\n  float64* {.magic: Float.}   ## 64 bit floating point type.\n\n# 'float64' is now an alias to 'float'; this solves many problems\n\ntype\n  char* {.magic: Char.}         ## Built-in 8 bit character type (unsigned).\n  string* {.magic: String.}     ## Built-in string type.\n  cstring* {.magic: Cstring.}   ## Built-in cstring (*compatible string*) type.\n  pointer* {.magic: Pointer.}   ## Built-in pointer type, use the `addr`\n                                ## operator to get a pointer to a variable.\n\n  typedesc* {.magic: TypeDesc.} ## Meta type to denote a type description.\n\ntype\n  `ptr`*[T] {.magic: Pointer.}   ## Built-in generic untraced pointer type.\n  `ref`*[T] {.magic: Pointer.}   ## Built-in generic traced pointer type.\n\n  `nil` {.magic: \"Nil\".}\n\n  void* {.magic: \"VoidType\".}    ## Meta type to denote the absence of any type.\n  auto* {.magic: Expr.}          ## Meta type for automatic type determination.\n  any* {.deprecated: \"Deprecated since v1.5; Use auto instead.\".} = distinct auto  ## Deprecated; Use `auto` instead. See https://github.com/nim-lang/RFCs/issues/281\n  untyped* {.magic: Expr.}       ## Meta type to denote an expression that\n                                 ## is not resolved (for templates).\n  typed* {.magic: Stmt.}         ## Meta type to denote an expression that\n                                 ## is resolved (for templates).\n\ninclude \"system/basic_types\"\n\n\nproc runnableExamples*(rdoccmd = \"\", body: untyped) {.magic: \"RunnableExamples\".} =\n  ## A section you should use to mark `runnable example`:idx: code with.\n  ##\n  ## - In normal debug and release builds code within\n  ##   a `runnableExamples` section is ignored.\n  ## - The documentation generator is aware of these examples and considers them\n  ##   part of the `##` doc comment. As the last step of documentation\n  ##   generation each runnableExample is put in its own file `$file_examples$i.nim`,\n  ##   compiled and tested. The collected examples are\n  ##   put into their own module to ensure the examples do not refer to\n  ##   non-exported symbols.\n  runnableExamples:\n    proc timesTwo*(x: int): int =\n      ## This proc doubles a number.\n      runnableExamples:\n        # at module scope\n        const exported* = 123\n        assert timesTwo(5) == 10\n        block: # at block scope\n          defer: echo \"done\"\n      runnableExamples \"-d:foo -b:cpp\":\n        import std/compilesettings\n        assert querySetting(backend) == \"cpp\"\n        assert defined(foo)\n      runnableExamples \"-r:off\": ## this one is only compiled\n         import std/browsers\n         openDefaultBrowser \"https://forum.nim-lang.org/\"\n      2 * x\n\nproc compileOption*(option: string): bool {.\n  magic: \"CompileOption\", noSideEffect.} =\n  ## Can be used to determine an `on|off` compile-time option.\n  ##\n  ## See also:\n  ## * `compileOption <#compileOption,string,string>`_ for enum options\n  ## * `defined <#defined,untyped>`_\n  ## * `std/compilesettings module <compilesettings.html>`_\n  runnableExamples(\"--floatChecks:off\"):\n    static: doAssert not compileOption(\"floatchecks\")\n    {.push floatChecks: on.}\n    static: doAssert compileOption(\"floatchecks\")\n    # floating point NaN and Inf checks enabled in this scope\n    {.pop.}\n\nproc compileOption*(option, arg: string): bool {.\n  magic: \"CompileOptionArg\", noSideEffect.} =\n  ## Can be used to determine an enum compile-time option.\n  ##\n  ## See also:\n  ## * `compileOption <#compileOption,string>`_ for `on|off` options\n  ## * `defined <#defined,untyped>`_\n  ## * `std/compilesettings module <compilesettings.html>`_\n  runnableExamples:\n    when compileOption(\"opt\", \"size\") and compileOption(\"gc\", \"boehm\"):\n      discard \"compiled with optimization for size and uses Boehm's GC\"\n\n{.push warning[GcMem]: off, warning[Uninit]: off.}\n# {.push hints: off.}\n\nproc `or`*(a, b: typedesc): typedesc {.magic: \"TypeTrait\", noSideEffect.}\n  ## Constructs an `or` meta class.\n\nproc `and`*(a, b: typedesc): typedesc {.magic: \"TypeTrait\", noSideEffect.}\n  ## Constructs an `and` meta class.\n\nproc `not`*(a: typedesc): typedesc {.magic: \"TypeTrait\", noSideEffect.}\n  ## Constructs an `not` meta class.\n\n\ntype\n  SomeFloat* = float|float32|float64\n    ## Type class matching all floating point number types.\n\n  SomeNumber* = SomeInteger|SomeFloat\n    ## Type class matching all number types.\n\nproc defined*(x: untyped): bool {.magic: \"Defined\", noSideEffect, compileTime.}\n  ## Special compile-time procedure that checks whether `x` is\n  ## defined.\n  ##\n  ## See also:\n  ## * `compileOption <#compileOption,string>`_ for `on|off` options\n  ## * `compileOption <#compileOption,string,string>`_ for enum options\n  ## * `define pragmas <manual.html#implementation-specific-pragmas-compileminustime-define-pragmas>`_\n  ##\n  ## `x` is an external symbol introduced through the compiler's\n  ## `-d:x switch <nimc.html#compiler-usage-compileminustime-symbols>`_ to enable\n  ## build time conditionals:\n  ##\n  ## .. code-block:: Nim\n  ##   when not defined(release):\n  ##     # Do here programmer friendly expensive sanity checks.\n  ##   # Put here the normal code\n\nwhen defined(nimHasIterable):\n  type\n    iterable*[T] {.magic: IterableType.}  ## Represents an expression that yields `T`\n\nwhen defined(nimHashOrdinalFixed):\n  type\n    Ordinal*[T] {.magic: Ordinal.} ## Generic ordinal type. Includes integer,\n                                   ## bool, character, and enumeration types\n                                   ## as well as their subtypes. See also\n                                   ## `SomeOrdinal`.\nelse:\n  # bootstrap < 1.2.0\n  type\n    OrdinalImpl[T] {.magic: Ordinal.}\n    Ordinal* = OrdinalImpl | uint | uint64\n\nwhen defined(nimHasDeclaredMagic):\n  proc declared*(x: untyped): bool {.magic: \"Declared\", noSideEffect, compileTime.}\n    ## Special compile-time procedure that checks whether `x` is\n    ## declared. `x` has to be an identifier or a qualified identifier.\n    ##\n    ## See also:\n    ## * `declaredInScope <#declaredInScope,untyped>`_\n    ##\n    ## This can be used to check whether a library provides a certain\n    ## feature or not:\n    ##\n    ## .. code-block:: Nim\n    ##   when not declared(strutils.toUpper):\n    ##     # provide our own toUpper proc here, because strutils is\n    ##     # missing it.\nelse:\n  proc declared*(x: untyped): bool {.magic: \"Defined\", noSideEffect, compileTime.}\n\nwhen defined(nimHasDeclaredMagic):\n  proc declaredInScope*(x: untyped): bool {.magic: \"DeclaredInScope\", noSideEffect, compileTime.}\n    ## Special compile-time procedure that checks whether `x` is\n    ## declared in the current scope. `x` has to be an identifier.\nelse:\n  proc declaredInScope*(x: untyped): bool {.magic: \"DefinedInScope\", noSideEffect, compileTime.}\n\nproc `addr`*[T](x: var T): ptr T {.magic: \"Addr\", noSideEffect.} =\n  ## Builtin `addr` operator for taking the address of a memory location.\n  ## Cannot be overloaded.\n  ##\n  ## See also:\n  ## * `unsafeAddr <#unsafeAddr,T>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var\n  ##    buf: seq[char] = @['a','b','c']\n  ##    p = buf[1].addr\n  ##  echo p.repr # ref 0x7faa35c40059 --> 'b'\n  ##  echo p[]    # b\n  discard\n\nproc unsafeAddr*[T](x: T): ptr T {.magic: \"Addr\", noSideEffect.} =\n  ## Builtin `addr` operator for taking the address of a memory\n  ## location. This works even for `let` variables or parameters\n  ## for better interop with C and so it is considered even more\n  ## unsafe than the ordinary `addr <#addr,T>`_.\n  ##\n  ## **Note**: When you use it to write a wrapper for a C library, you should\n  ## always check that the original library does never write to data behind the\n  ## pointer that is returned from this procedure.\n  ##\n  ## Cannot be overloaded.\n  discard\n\ntype\n  `static`*[T] {.magic: \"Static\".}\n    ## Meta type representing all values that can be evaluated at compile-time.\n    ##\n    ## The type coercion `static(x)` can be used to force the compile-time\n    ## evaluation of the given expression `x`.\n\n  `type`*[T] {.magic: \"Type\".}\n    ## Meta type representing the type of all type values.\n    ##\n    ## The coercion `type(x)` can be used to obtain the type of the given\n    ## expression `x`.\n\ntype\n  TypeOfMode* = enum ## Possible modes of `typeof`.\n    typeOfProc,      ## Prefer the interpretation that means `x` is a proc call.\n    typeOfIter       ## Prefer the interpretation that means `x` is an iterator call.\n\nproc typeof*(x: untyped; mode = typeOfIter): typedesc {.\n  magic: \"TypeOf\", noSideEffect, compileTime.} =\n  ## Builtin `typeof` operation for accessing the type of an expression.\n  ## Since version 0.20.0.\n  runnableExamples:\n    proc myFoo(): float = 0.0\n    iterator myFoo(): string = yield \"abc\"\n    iterator myFoo2(): string = yield \"abc\"\n    iterator myFoo3(): string {.closure.} = yield \"abc\"\n    doAssert type(myFoo()) is string\n    doAssert typeof(myFoo()) is string\n    doAssert typeof(myFoo(), typeOfIter) is string\n    doAssert typeof(myFoo3) is \"iterator\"\n\n    doAssert typeof(myFoo(), typeOfProc) is float\n    doAssert typeof(0.0, typeOfProc) is float\n    doAssert typeof(myFoo3, typeOfProc) is \"iterator\"\n    doAssert not compiles(typeof(myFoo2(), typeOfProc))\n      # this would give: Error: attempting to call routine: 'myFoo2'\n      # since `typeOfProc` expects a typed expression and `myFoo2()` can\n      # only be used in a `for` context.\n\nconst ThisIsSystem = true\n\nproc internalNew*[T](a: var ref T) {.magic: \"New\", noSideEffect.}\n  ## Leaked implementation detail. Do not use.\n\nwhen true:\n  proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.\n    magic: \"NewFinalize\", noSideEffect.}\n    ## Creates a new object of type `T` and returns a safe (traced)\n    ## reference to it in `a`.\n    ##\n    ## When the garbage collector frees the object, `finalizer` is called.\n    ## The `finalizer` may not keep a reference to the\n    ## object pointed to by `x`. The `finalizer` cannot prevent the GC from\n    ## freeing the object.\n    ##\n    ## **Note**: The `finalizer` refers to the type `T`, not to the object!\n    ## This means that for each object of type `T` the finalizer will be called!\n\nproc wasMoved*[T](obj: var T) {.magic: \"WasMoved\", noSideEffect.} =\n  ## Resets an object `obj` to its initial (binary zero) value to signify\n  ## it was \"moved\" and to signify its destructor should do nothing and\n  ## ideally be optimized away.\n  discard\n\nproc move*[T](x: var T): T {.magic: \"Move\", noSideEffect.} =\n  result = x\n  wasMoved(x)\n\ntype\n  range*[T]{.magic: \"Range\".}         ## Generic type to construct range types.\n  array*[I, T]{.magic: \"Array\".}      ## Generic type to construct\n                                      ## fixed-length arrays.\n  openArray*[T]{.magic: \"OpenArray\".} ## Generic type to construct open arrays.\n                                      ## Open arrays are implemented as a\n                                      ## pointer to the array data and a\n                                      ## length field.\n  varargs*[T]{.magic: \"Varargs\".}     ## Generic type to construct a varargs type.\n  seq*[T]{.magic: \"Seq\".}             ## Generic type to construct sequences.\n  set*[T]{.magic: \"Set\".}             ## Generic type to construct bit sets.\n\ntype\n  UncheckedArray*[T]{.magic: \"UncheckedArray\".}\n  ## Array with no bounds checking.\n\ntype sink*[T]{.magic: \"BuiltinType\".}\ntype lent*[T]{.magic: \"BuiltinType\".}\n\nproc high*[T: Ordinal|enum|range](x: T): T {.magic: \"High\", noSideEffect,\n  deprecated: \"Deprecated since v1.4; there should not be `high(value)`. Use `high(type)`.\".}\n  ## Returns the highest possible value of an ordinal value `x`.\n  ##\n  ## As a special semantic rule, `x` may also be a type identifier.\n  ##\n  ## **This proc is deprecated**, use this one instead:\n  ## * `high(typedesc) <#high,typedesc[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  high(2) # => 9223372036854775807\n\nproc high*[T: Ordinal|enum|range](x: typedesc[T]): T {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible value of an ordinal or enum type.\n  ##\n  ## `high(int)` is Nim's way of writing `INT_MAX`:idx: or `MAX_INT`:idx:.\n  ##\n  ## See also:\n  ## * `low(typedesc) <#low,typedesc[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  high(int) # => 9223372036854775807\n\nproc high*[T](x: openArray[T]): int {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible index of a sequence `x`.\n  ##\n  ## See also:\n  ## * `low(openArray) <#low,openArray[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var s = @[1, 2, 3, 4, 5, 6, 7]\n  ##  high(s) # => 6\n  ##  for i in low(s)..high(s):\n  ##    echo s[i]\n\nproc high*[I, T](x: array[I, T]): I {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible index of an array `x`.\n  ##\n  ## For empty arrays, the return type is `int`.\n  ##\n  ## See also:\n  ## * `low(array) <#low,array[I,T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var arr = [1, 2, 3, 4, 5, 6, 7]\n  ##  high(arr) # => 6\n  ##  for i in low(arr)..high(arr):\n  ##    echo arr[i]\n\nproc high*[I, T](x: typedesc[array[I, T]]): I {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible index of an array type.\n  ##\n  ## For empty arrays, the return type is `int`.\n  ##\n  ## See also:\n  ## * `low(typedesc[array]) <#low,typedesc[array[I,T]]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  high(array[7, int]) # => 6\n\nproc high*(x: cstring): int {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible index of a compatible string `x`.\n  ## This is sometimes an O(n) operation.\n  ##\n  ## See also:\n  ## * `low(cstring) <#low,cstring>`_\n\nproc high*(x: string): int {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible index of a string `x`.\n  ##\n  ## See also:\n  ## * `low(string) <#low,string>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var str = \"Hello world!\"\n  ##  high(str) # => 11\n\nproc low*[T: Ordinal|enum|range](x: T): T {.magic: \"Low\", noSideEffect,\n  deprecated: \"Deprecated since v1.4; there should not be `low(value)`. Use `low(type)`.\".}\n  ## Returns the lowest possible value of an ordinal value `x`. As a special\n  ## semantic rule, `x` may also be a type identifier.\n  ##\n  ## **This proc is deprecated**, use this one instead:\n  ## * `low(typedesc) <#low,typedesc[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  low(2) # => -9223372036854775808\n\nproc low*[T: Ordinal|enum|range](x: typedesc[T]): T {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible value of an ordinal or enum type.\n  ##\n  ## `low(int)` is Nim's way of writing `INT_MIN`:idx: or `MIN_INT`:idx:.\n  ##\n  ## See also:\n  ## * `high(typedesc) <#high,typedesc[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  low(int) # => -9223372036854775808\n\nproc low*[T](x: openArray[T]): int {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible index of a sequence `x`.\n  ##\n  ## See also:\n  ## * `high(openArray) <#high,openArray[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var s = @[1, 2, 3, 4, 5, 6, 7]\n  ##  low(s) # => 0\n  ##  for i in low(s)..high(s):\n  ##    echo s[i]\n\nproc low*[I, T](x: array[I, T]): I {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible index of an array `x`.\n  ##\n  ## For empty arrays, the return type is `int`.\n  ##\n  ## See also:\n  ## * `high(array) <#high,array[I,T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var arr = [1, 2, 3, 4, 5, 6, 7]\n  ##  low(arr) # => 0\n  ##  for i in low(arr)..high(arr):\n  ##    echo arr[i]\n\nproc low*[I, T](x: typedesc[array[I, T]]): I {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible index of an array type.\n  ##\n  ## For empty arrays, the return type is `int`.\n  ##\n  ## See also:\n  ## * `high(typedesc[array]) <#high,typedesc[array[I,T]]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  low(array[7, int]) # => 0\n\nproc low*(x: cstring): int {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible index of a compatible string `x`.\n  ##\n  ## See also:\n  ## * `high(cstring) <#high,cstring>`_\n\nproc low*(x: string): int {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible index of a string `x`.\n  ##\n  ## See also:\n  ## * `high(string) <#high,string>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var str = \"Hello world!\"\n  ##  low(str) # => 0\n\nproc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: \"ShallowCopy\".}\n  ## Use this instead of `=` for a `shallow copy`:idx:.\n  ##\n  ## The shallow copy only changes the semantics for sequences and strings\n  ## (and types which contain those).\n  ##\n  ## Be careful with the changed semantics though!\n  ## There is a reason why the default assignment does a deep copy of sequences\n  ## and strings.\n\n# :array|openArray|string|seq|cstring|tuple\nproc `[]`*[I: Ordinal;T](a: T; i: I): T {.\n  noSideEffect, magic: \"ArrGet\".}\nproc `[]=`*[I: Ordinal;T,S](a: T; i: I;\n  x: sink S) {.noSideEffect, magic: \"ArrPut\".}\nproc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: \"Asgn\".}\nproc `=copy`*[T](dest: var T; src: T) {.noSideEffect, magic: \"Asgn\".}\n\nproc arrGet[I: Ordinal;T](a: T; i: I): T {.\n  noSideEffect, magic: \"ArrGet\".}\nproc arrPut[I: Ordinal;T,S](a: T; i: I;\n  x: S) {.noSideEffect, magic: \"ArrPut\".}\n\nproc `=destroy`*[T](x: var T) {.inline, magic: \"Destroy\".} =\n  ## Generic `destructor`:idx: implementation that can be overridden.\n  discard\nproc `=sink`*[T](x: var T; y: T) {.inline, magic: \"Asgn\".} =\n  ## Generic `sink`:idx: implementation that can be overridden.\n  shallowCopy(x, y)\n\nwhen defined(nimHasTrace):\n  proc `=trace`*[T](x: var T; env: pointer) {.inline, magic: \"Trace\".} =\n    ## Generic `trace`:idx: implementation that can be overridden.\n    discard\n\ntype\n  HSlice*[T, U] = object   ## \"Heterogeneous\" slice type.\n    a*: T                  ## The lower bound (inclusive).\n    b*: U                  ## The upper bound (inclusive).\n  Slice*[T] = HSlice[T, T] ## An alias for `HSlice[T, T]`.\n\nproc `..`*[T, U](a: sink T, b: sink U): HSlice[T, U] {.noSideEffect, inline, magic: \"DotDot\".} =\n  ## Binary `slice`:idx: operator that constructs an interval `[a, b]`, both `a`\n  ## and `b` are inclusive.\n  ##\n  ## Slices can also be used in the set constructor and in ordinal case\n  ## statements, but then they are special-cased by the compiler.\n  ##\n  ## .. code-block:: Nim\n  ##   let a = [10, 20, 30, 40, 50]\n  ##   echo a[2 .. 3] # @[30, 40]\n  result = HSlice[T, U](a: a, b: b)\n\nproc `..`*[T](b: sink T): HSlice[int, T]\n  {.noSideEffect, inline, magic: \"DotDot\", deprecated: \"replace `..b` with `0..b`\".} =\n  ## Unary `slice`:idx: operator that constructs an interval `[default(int), b]`.\n  ##\n  ## .. code-block:: Nim\n  ##   let a = [10, 20, 30, 40, 50]\n  ##   echo a[.. 2] # @[10, 20, 30]\n  result = HSlice[int, T](a: 0, b: b)\n\nwhen defined(hotCodeReloading):\n  {.pragma: hcrInline, inline.}\nelse:\n  {.pragma: hcrInline.}\n\n{.push profiler: off.}\nlet nimvm* {.magic: \"Nimvm\", compileTime.}: bool = false\n  ## May be used only in `when` expression.\n  ## It is true in Nim VM context and false otherwise.\n{.pop.}\n\ninclude \"system/arithmetics\"\ninclude \"system/comparisons\"\n\nconst\n  appType* {.magic: \"AppType\".}: string = \"\"\n    ## A string that describes the application type. Possible values:\n    ## `\"console\"`, `\"gui\"`, `\"lib\"`.\n\ninclude \"system/inclrtl\"\n\nconst NoFakeVars = defined(nimscript) ## `true` if the backend doesn't support \\\n  ## \"fake variables\" like `var EBADF {.importc.}: cint`.\n\nconst notJSnotNims = not defined(js) and not defined(nimscript)\n\nwhen not defined(js) and not defined(nimSeqsV2):\n  type\n    TGenericSeq {.compilerproc, pure, inheritable.} = object\n      len, reserved: int\n      when defined(gogc):\n        elemSize: int\n        elemAlign: int\n    PGenericSeq {.exportc.} = ptr TGenericSeq\n    # len and space without counting the terminating zero:\n    NimStringDesc {.compilerproc, final.} = object of TGenericSeq\n      data: UncheckedArray[char]\n    NimString = ptr NimStringDesc\n\nwhen notJSnotNims and not defined(nimSeqsV2):\n  template space(s: PGenericSeq): int {.dirty.} =\n    s.reserved and not (seqShallowFlag or strlitFlag)\n\nwhen notJSnotNims:\n  include \"system/hti\"\n\ntype\n  byte* = uint8 ## This is an alias for `uint8`, that is an unsigned\n                ## integer, 8 bits wide.\n\n  Natural* = range[0..high(int)]\n    ## is an `int` type ranging from zero to the maximum value\n    ## of an `int`. This type is often useful for documentation and debugging.\n\n  Positive* = range[1..high(int)]\n    ## is an `int` type ranging from one to the maximum value\n    ## of an `int`. This type is often useful for documentation and debugging.\n\n  RootObj* {.compilerproc, inheritable.} =\n    object ## The root of Nim's object hierarchy.\n           ##\n           ## Objects should inherit from `RootObj` or one of its descendants.\n           ## However, objects that have no ancestor are also allowed.\n  RootRef* = ref RootObj ## Reference to `RootObj`.\n\n\ninclude \"system/exceptions\"\n\nwhen defined(js) or defined(nimdoc):\n  type\n    JsRoot* = ref object of RootObj\n      ## Root type of the JavaScript object hierarchy\n\nproc unsafeNew*[T](a: var ref T, size: Natural) {.magic: \"New\", noSideEffect.}\n  ## Creates a new object of type `T` and returns a safe (traced)\n  ## reference to it in `a`.\n  ##\n  ## This is **unsafe** as it allocates an object of the passed `size`.\n  ## This should only be used for optimization purposes when you know\n  ## what you're doing!\n  ##\n  ## See also:\n  ## * `new <#new,ref.T,proc(ref.T)>`_\n\nproc sizeof*[T](x: T): int {.magic: \"SizeOf\", noSideEffect.}\n  ## Returns the size of `x` in bytes.\n  ##\n  ## Since this is a low-level proc,\n  ## its usage is discouraged - using `new <#new,ref.T,proc(ref.T)>`_ for\n  ## the most cases suffices that one never needs to know `x`'s size.\n  ##\n  ## As a special semantic rule, `x` may also be a type identifier\n  ## (`sizeof(int)` is valid).\n  ##\n  ## Limitations: If used for types that are imported from C or C++,\n  ## sizeof should fallback to the `sizeof` in the C compiler. The\n  ## result isn't available for the Nim compiler and therefore can't\n  ## be used inside of macros.\n  ##\n  ## .. code-block:: Nim\n  ##  sizeof('A') # => 1\n  ##  sizeof(2) # => 8\n\nproc alignof*[T](x: T): int {.magic: \"AlignOf\", noSideEffect.}\nproc alignof*(x: typedesc): int {.magic: \"AlignOf\", noSideEffect.}\n\nproc offsetOfDotExpr(typeAccess: typed): int {.magic: \"OffsetOf\", noSideEffect, compileTime.}\n\ntemplate offsetOf*[T](t: typedesc[T]; member: untyped): int =\n  var tmp {.noinit.}: ptr T\n  offsetOfDotExpr(tmp[].member)\n\ntemplate offsetOf*[T](value: T; member: untyped): int =\n  offsetOfDotExpr(value.member)\n\n#proc offsetOf*(memberaccess: typed): int {.magic: \"OffsetOf\", noSideEffect.}\n\nproc sizeof*(x: typedesc): int {.magic: \"SizeOf\", noSideEffect.}\n\n\nproc newSeq*[T](s: var seq[T], len: Natural) {.magic: \"NewSeq\", noSideEffect.}\n  ## Creates a new sequence of type `seq[T]` with length `len`.\n  ##\n  ## This is equivalent to `s = @[]; setlen(s, len)`, but more\n  ## efficient since no reallocation is needed.\n  ##\n  ## Note that the sequence will be filled with zeroed entries.\n  ## After the creation of the sequence you should assign entries to\n  ## the sequence instead of adding them. Example:\n  ##\n  ## .. code-block:: Nim\n  ##   var inputStrings: seq[string]\n  ##   newSeq(inputStrings, 3)\n  ##   assert len(inputStrings) == 3\n  ##   inputStrings[0] = \"The fourth\"\n  ##   inputStrings[1] = \"assignment\"\n  ##   inputStrings[2] = \"would crash\"\n  ##   #inputStrings[3] = \"out of bounds\"\n\nproc newSeq*[T](len = 0.Natural): seq[T] =\n  ## Creates a new sequence of type `seq[T]` with length `len`.\n  ##\n  ## Note that the sequence will be filled with zeroed entries.\n  ## After the creation of the sequence you should assign entries to\n  ## the sequence instead of adding them.\n  ##\n  ## See also:\n  ## * `newSeqOfCap <#newSeqOfCap,Natural>`_\n  ## * `newSeqUninitialized <#newSeqUninitialized,Natural>`_\n  ##\n  ## .. code-block:: Nim\n  ##   var inputStrings = newSeq[string](3)\n  ##   assert len(inputStrings) == 3\n  ##   inputStrings[0] = \"The fourth\"\n  ##   inputStrings[1] = \"assignment\"\n  ##   inputStrings[2] = \"would crash\"\n  ##   #inputStrings[3] = \"out of bounds\"\n  newSeq(result, len)\n\nproc newSeqOfCap*[T](cap: Natural): seq[T] {.\n  magic: \"NewSeqOfCap\", noSideEffect.} =\n  ## Creates a new sequence of type `seq[T]` with length zero and capacity\n  ## `cap`.\n  ##\n  ## .. code-block:: Nim\n  ##   var x = newSeqOfCap[int](5)\n  ##   assert len(x) == 0\n  ##   x.add(10)\n  ##   assert len(x) == 1\n  discard\n\nwhen not defined(js):\n  proc newSeqUninitialized*[T: SomeNumber](len: Natural): seq[T] =\n    ## Creates a new sequence of type `seq[T]` with length `len`.\n    ##\n    ## Only available for numbers types. Note that the sequence will be\n    ## uninitialized. After the creation of the sequence you should assign\n    ## entries to the sequence instead of adding them.\n    ##\n    ## .. code-block:: Nim\n    ##   var x = newSeqUninitialized[int](3)\n    ##   assert len(x) == 3\n    ##   x[0] = 10\n    result = newSeqOfCap[T](len)\n    when defined(nimSeqsV2):\n      cast[ptr int](addr result)[] = len\n    else:\n      var s = cast[PGenericSeq](result)\n      s.len = len\n\nfunc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {.magic: \"LengthOpenArray\".} =\n  ## Returns the length of an openArray.\n  runnableExamples:\n    proc bar[T](a: openArray[T]): int = len(a)\n    assert bar([1,2]) == 2\n    assert [1,2].len == 2\n\nfunc len*(x: string): int {.magic: \"LengthStr\".} =\n  ## Returns the length of a string.\n  runnableExamples:\n    assert \"abc\".len == 3\n    assert \"\".len == 0\n    assert string.default.len == 0\n\nproc len*(x: cstring): int {.magic: \"LengthStr\", noSideEffect.} =\n  ## Returns the length of a compatible string. This is an O(n) operation except\n  ## in js at runtime.\n  ##\n  ## **Note:** On the JS backend this currently counts UTF-16 code points\n  ## instead of bytes at runtime (not at compile time). For now, if you\n  ## need the byte length of the UTF-8 encoding, convert to string with\n  ## `$` first then call `len`.\n  runnableExamples:\n    doAssert len(cstring\"abc\") == 3\n    doAssert len(cstring r\"ab\\0c\") == 5 # \\0 is escaped\n    doAssert len(cstring\"ab\\0c\") == 5 # ditto\n    var a: cstring = \"ab\\0c\"\n    when defined(js): doAssert a.len == 4 # len ignores \\0 for js\n    else: doAssert a.len == 2 # \\0 is a null terminator\n    static:\n      var a2: cstring = \"ab\\0c\"\n      doAssert a2.len == 2 # \\0 is a null terminator, even in js vm\n\nfunc len*(x: (type array)|array): int {.magic: \"LengthArray\".} =\n  ## Returns the length of an array or an array type.\n  ## This is roughly the same as `high(T)-low(T)+1`.\n  runnableExamples:\n    var a = [1, 1, 1]\n    assert a.len == 3\n    assert array[0, float].len == 0\n    static: assert array[-2..2, float].len == 5\n\nfunc len*[T](x: seq[T]): int {.magic: \"LengthSeq\".} =\n  ## Returns the length of `x`.\n  runnableExamples:\n    assert @[0, 1].len == 2\n    assert seq[int].default.len == 0\n    assert newSeq[int](3).len == 3\n    let s = newSeqOfCap[int](3)\n    assert s.len == 0\n  # xxx this gives cgen error: assert newSeqOfCap[int](3).len == 0\n\nfunc ord*[T: Ordinal|enum](x: T): int {.magic: \"Ord\".} =\n  ## Returns the internal `int` value of `x`, including for enum with holes\n  ## and distinct ordinal types.\n  runnableExamples:\n    assert ord('A') == 65\n    type Foo = enum\n      f0 = 0, f1 = 3\n    assert f1.ord == 3\n    type Bar = distinct int\n    assert 3.Bar.ord == 3\n\nfunc chr*(u: range[0..255]): char {.magic: \"Chr\".} =\n  ## Converts `u` to a `char`, same as `char(u)`.\n  runnableExamples:\n    doAssert chr(65) == 'A'\n    doAssert chr(255) == '\\255'\n    doAssert chr(255) == char(255)\n    doAssert not compiles chr(256)\n    doAssert not compiles char(256)\n    var x = 256\n    doAssertRaises(RangeDefect): discard chr(x)\n    doAssertRaises(RangeDefect): discard char(x)\n\n# floating point operations:\nproc `+`*(x: float32): float32 {.magic: \"UnaryPlusF64\", noSideEffect.}\nproc `-`*(x: float32): float32 {.magic: \"UnaryMinusF64\", noSideEffect.}\nproc `+`*(x, y: float32): float32 {.magic: \"AddF64\", noSideEffect.}\nproc `-`*(x, y: float32): float32 {.magic: \"SubF64\", noSideEffect.}\nproc `*`*(x, y: float32): float32 {.magic: \"MulF64\", noSideEffect.}\nproc `/`*(x, y: float32): float32 {.magic: \"DivF64\", noSideEffect.}\n\nproc `+`*(x: float): float {.magic: \"UnaryPlusF64\", noSideEffect.}\nproc `-`*(x: float): float {.magic: \"UnaryMinusF64\", noSideEffect.}\nproc `+`*(x, y: float): float {.magic: \"AddF64\", noSideEffect.}\nproc `-`*(x, y: float): float {.magic: \"SubF64\", noSideEffect.}\nproc `*`*(x, y: float): float {.magic: \"MulF64\", noSideEffect.}\nproc `/`*(x, y: float): float {.magic: \"DivF64\", noSideEffect.}\n\nproc `==`*(x, y: float32): bool {.magic: \"EqF64\", noSideEffect.}\nproc `<=`*(x, y: float32): bool {.magic: \"LeF64\", noSideEffect.}\nproc `<`  *(x, y: float32): bool {.magic: \"LtF64\", noSideEffect.}\n\nproc `==`*(x, y: float): bool {.magic: \"EqF64\", noSideEffect.}\nproc `<=`*(x, y: float): bool {.magic: \"LeF64\", noSideEffect.}\nproc `<`*(x, y: float): bool {.magic: \"LtF64\", noSideEffect.}\n\n\ninclude \"system/setops\"\n\n\nproc contains*[U, V, W](s: HSlice[U, V], value: W): bool {.noSideEffect, inline.} =\n  ## Checks if `value` is within the range of `s`; returns true if\n  ## `value >= s.a and value <= s.b`\n  ##\n  ## .. code-block:: Nim\n  ##   assert((1..3).contains(1) == true)\n  ##   assert((1..3).contains(2) == true)\n  ##   assert((1..3).contains(4) == false)\n  result = s.a <= value and value <= s.b\n\ntemplate `in`*(x, y: untyped): untyped {.dirty.} = contains(y, x)\n  ## Sugar for `contains`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert(1 in (1..3) == true)\n  ##   assert(5 in (1..3) == false)\ntemplate `notin`*(x, y: untyped): untyped {.dirty.} = not contains(y, x)\n  ## Sugar for `not contains`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert(1 notin (1..3) == false)\n  ##   assert(5 notin (1..3) == true)\n\nproc `is`*[T, S](x: T, y: S): bool {.magic: \"Is\", noSideEffect.}\n  ## Checks if `T` is of the same type as `S`.\n  ##\n  ## For a negated version, use `isnot <#isnot.t,untyped,untyped>`_.\n  ##\n  ## .. code-block:: Nim\n  ##   assert 42 is int\n  ##   assert @[1, 2] is seq\n  ##\n  ##   proc test[T](a: T): int =\n  ##     when (T is int):\n  ##       return a\n  ##     else:\n  ##       return 0\n  ##\n  ##   assert(test[int](3) == 3)\n  ##   assert(test[string](\"xyz\") == 0)\ntemplate `isnot`*(x, y: untyped): untyped = not (x is y)\n  ## Negated version of `is <#is,T,S>`_. Equivalent to `not(x is y)`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert 42 isnot float\n  ##   assert @[1, 2] isnot enum\n\nwhen (defined(nimOwnedEnabled) and not defined(nimscript)) or defined(nimFixedOwned):\n  type owned*[T]{.magic: \"BuiltinType\".} ## type constructor to mark a ref/ptr or a closure as `owned`.\nelse:\n  template owned*(t: typedesc): typedesc = t\n\nwhen defined(nimOwnedEnabled) and not defined(nimscript):\n  proc new*[T](a: var owned(ref T)) {.magic: \"New\", noSideEffect.}\n    ## Creates a new object of type `T` and returns a safe (traced)\n    ## reference to it in `a`.\n\n  proc new*(t: typedesc): auto =\n    ## Creates a new object of type `T` and returns a safe (traced)\n    ## reference to it as result value.\n    ##\n    ## When `T` is a ref type then the resulting type will be `T`,\n    ## otherwise it will be `ref T`.\n    when (t is ref):\n      var r: owned t\n    else:\n      var r: owned(ref t)\n    new(r)\n    return r\n\n  proc unown*[T](x: T): T {.magic: \"Unown\", noSideEffect.}\n    ## Use the expression `x` ignoring its ownership attribute.\n\n\nelse:\n  template unown*(x: typed): untyped = x\n\n  proc new*[T](a: var ref T) {.magic: \"New\", noSideEffect.}\n    ## Creates a new object of type `T` and returns a safe (traced)\n    ## reference to it in `a`.\n\n  proc new*(t: typedesc): auto =\n    ## Creates a new object of type `T` and returns a safe (traced)\n    ## reference to it as result value.\n    ##\n    ## When `T` is a ref type then the resulting type will be `T`,\n    ## otherwise it will be `ref T`.\n    when (t is ref):\n      var r: t\n    else:\n      var r: ref t\n    new(r)\n    return r\n\n\ntemplate disarm*(x: typed) =\n  ## Useful for `disarming` dangling pointers explicitly for `--newruntime`.\n  ## Regardless of whether `--newruntime` is used or not\n  ## this sets the pointer or callback `x` to `nil`. This is an\n  ## experimental API!\n  x = nil\n\nproc `of`*[T, S](x: T, y: typedesc[S]): bool {.magic: \"Of\", noSideEffect.} =\n  ## Checks if `x` is an instance of `y`.\n  runnableExamples:\n    type\n      Base = ref object of RootObj\n      Sub1 = ref object of Base\n      Sub2 = ref object of Base\n      Unrelated = ref object\n\n    var base: Base = Sub1() # downcast\n    doAssert base of Base # generates `CondTrue` (statically true)\n    doAssert base of Sub1\n    doAssert base isnot Sub1\n    doAssert not (base of Sub2)\n\n    base = Sub2() # re-assign\n    doAssert base of Sub2\n    doAssert Sub2(base) != nil # upcast\n    doAssertRaises(ObjectConversionDefect): discard Sub1(base)\n\n    var sub1 = Sub1()\n    doAssert sub1 of Base\n    doAssert sub1.Base of Sub1\n\n    doAssert not compiles(base of Unrelated)\n\nproc cmp*[T](x, y: T): int =\n  ## Generic compare proc.\n  ##\n  ## Returns:\n  ## * a value less than zero, if `x < y`\n  ## * a value greater than zero, if `x > y`\n  ## * zero, if `x == y`\n  ##\n  ## This is useful for writing generic algorithms without performance loss.\n  ## This generic implementation uses the `==` and `<` operators.\n  ##\n  ## .. code-block:: Nim\n  ##  import std/algorithm\n  ##  echo sorted(@[4, 2, 6, 5, 8, 7], cmp[int])\n  if x == y: return 0\n  if x < y: return -1\n  return 1\n\nproc cmp*(x, y: string): int {.noSideEffect.}\n  ## Compare proc for strings. More efficient than the generic version.\n  ##\n  ## **Note**: The precise result values depend on the used C runtime library and\n  ## can differ between operating systems!\n\nproc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.magic: \"ArrToSeq\", noSideEffect.}\n  ## Turns an array into a sequence.\n  ##\n  ## This most often useful for constructing\n  ## sequences with the array constructor: `@[1, 2, 3]` has the type\n  ## `seq[int]`, while `[1, 2, 3]` has the type `array[0..2, int]`.\n  ##\n  ## .. code-block:: Nim\n  ##   let\n  ##     a = [1, 3, 5]\n  ##     b = \"foo\"\n  ##\n  ##   echo @a # => @[1, 3, 5]\n  ##   echo @b # => @['f', 'o', 'o']\n\nproc default*[T](_: typedesc[T]): T {.magic: \"Default\", noSideEffect.} =\n  ## returns the default value of the type `T`.\n  runnableExamples:\n    assert (int, float).default == (0, 0.0)\n    # note: `var a = default(T)` is usually the same as `var a: T` and (currently) generates\n    # a value whose binary representation is all 0, regardless of whether this\n    # would violate type constraints such as `range`, `not nil`, etc. This\n    # property is required to implement certain algorithms efficiently which\n    # may require intermediate invalid states.\n    type Foo = object\n      a: range[2..6]\n    var a1: range[2..6] # currently, this compiles\n    # var a2: Foo # currently, this errors: Error: The Foo type doesn't have a default value.\n    # var a3 = Foo() # ditto\n    var a3 = Foo.default # this works, but generates a `UnsafeDefault` warning.\n  # note: the doc comment also explains why `default` can't be implemented\n  # via: `template default*[T](t: typedesc[T]): T = (var v: T; v)`\n\nproc reset*[T](obj: var T) {.noSideEffect.} =\n  ## Resets an object `obj` to its default value.\n  obj = default(typeof(obj))\n\nproc setLen*[T](s: var seq[T], newlen: Natural) {.\n  magic: \"SetLengthSeq\", noSideEffect.}\n  ## Sets the length of seq `s` to `newlen`. `T` may be any sequence type.\n  ##\n  ## If the current length is greater than the new length,\n  ## `s` will be truncated.\n  ##\n  ## .. code-block:: Nim\n  ##   var x = @[10, 20]\n  ##   x.setLen(5)\n  ##   x[4] = 50\n  ##   assert x == @[10, 20, 0, 0, 50]\n  ##   x.setLen(1)\n  ##   assert x == @[10]\n\nproc setLen*(s: var string, newlen: Natural) {.\n  magic: \"SetLengthStr\", noSideEffect.}\n  ## Sets the length of string `s` to `newlen`.\n  ##\n  ## If the current length is greater than the new length,\n  ## `s` will be truncated.\n  ##\n  ## .. code-block:: Nim\n  ##  var myS = \"Nim is great!!\"\n  ##  myS.setLen(3) # myS <- \"Nim\"\n  ##  echo myS, \" is fantastic!!\"\n\nproc newString*(len: Natural): string {.\n  magic: \"NewString\", importc: \"mnewString\", noSideEffect.}\n  ## Returns a new string of length `len` but with uninitialized\n  ## content. One needs to fill the string character after character\n  ## with the index operator `s[i]`.\n  ##\n  ## This procedure exists only for optimization purposes;\n  ## the same effect can be achieved with the `&` operator or with `add`.\n\nproc newStringOfCap*(cap: Natural): string {.\n  magic: \"NewStringOfCap\", importc: \"rawNewString\", noSideEffect.}\n  ## Returns a new string of length `0` but with capacity `cap`.\n  ##\n  ## This procedure exists only for optimization purposes; the same effect can\n  ## be achieved with the `&` operator or with `add`.\n\nproc `&`*(x: string, y: char): string {.\n  magic: \"ConStrStr\", noSideEffect, merge.}\n  ## Concatenates `x` with `y`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert(\"ab\" & 'c' == \"abc\")\nproc `&`*(x, y: char): string {.\n  magic: \"ConStrStr\", noSideEffect, merge.}\n  ## Concatenates characters `x` and `y` into a string.\n  ##\n  ## .. code-block:: Nim\n  ##   assert('a' & 'b' == \"ab\")\nproc `&`*(x, y: string): string {.\n  magic: \"ConStrStr\", noSideEffect, merge.}\n  ## Concatenates strings `x` and `y`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert(\"ab\" & \"cd\" == \"abcd\")\nproc `&`*(x: char, y: string): string {.\n  magic: \"ConStrStr\", noSideEffect, merge.}\n  ## Concatenates `x` with `y`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert('a' & \"bc\" == \"abc\")\n\n# implementation note: These must all have the same magic value \"ConStrStr\" so\n# that the merge optimization works properly.\n\nproc add*(x: var string, y: char) {.magic: \"AppendStrCh\", noSideEffect.}\n  ## Appends `y` to `x` in place.\n  ##\n  ## .. code-block:: Nim\n  ##   var tmp = \"\"\n  ##   tmp.add('a')\n  ##   tmp.add('b')\n  ##   assert(tmp == \"ab\")\n\nproc add*(x: var string, y: string) {.magic: \"AppendStrStr\", noSideEffect.} =\n  ## Concatenates `x` and `y` in place.\n  ##\n  ## See also `strbasics.add`.\n  runnableExamples:\n    var tmp = \"\"\n    tmp.add(\"ab\")\n    tmp.add(\"cd\")\n    assert tmp == \"abcd\"\n\ntype\n  Endianness* = enum ## Type describing the endianness of a processor.\n    littleEndian, bigEndian\n\nconst\n  isMainModule* {.magic: \"IsMainModule\".}: bool = false\n    ## True only when accessed in the main module. This works thanks to\n    ## compiler magic. It is useful to embed testing code in a module.\n\n  CompileDate* {.magic: \"CompileDate\".}: string = \"0000-00-00\"\n    ## The date (in UTC) of compilation as a string of the form\n    ## `YYYY-MM-DD`. This works thanks to compiler magic.\n\n  CompileTime* {.magic: \"CompileTime\".}: string = \"00:00:00\"\n    ## The time (in UTC) of compilation as a string of the form\n    ## `HH:MM:SS`. This works thanks to compiler magic.\n\n  cpuEndian* {.magic: \"CpuEndian\".}: Endianness = littleEndian\n    ## The endianness of the target CPU. This is a valuable piece of\n    ## information for low-level code only. This works thanks to compiler\n    ## magic.\n\n  hostOS* {.magic: \"HostOS\".}: string = \"\"\n    ## A string that describes the host operating system.\n    ##\n    ## Possible values:\n    ## `\"windows\"`, `\"macosx\"`, `\"linux\"`, `\"netbsd\"`, `\"freebsd\"`,\n    ## `\"openbsd\"`, `\"solaris\"`, `\"aix\"`, `\"haiku\"`, `\"standalone\"`.\n\n  hostCPU* {.magic: \"HostCPU\".}: string = \"\"\n    ## A string that describes the host CPU.\n    ##\n    ## Possible values:\n    ## `\"i386\"`, `\"alpha\"`, `\"powerpc\"`, `\"powerpc64\"`, `\"powerpc64el\"`,\n    ## `\"sparc\"`, `\"amd64\"`, `\"mips\"`, `\"mipsel\"`, `\"arm\"`, `\"arm64\"`,\n    ## `\"mips64\"`, `\"mips64el\"`, `\"riscv32\"`, `\"riscv64\"`.\n\n  seqShallowFlag = low(int)\n  strlitFlag = 1 shl (sizeof(int)*8 - 2) # later versions of the codegen \\\n  # emit this flag\n  # for string literals, it allows for some optimizations.\n\nconst\n  hasThreadSupport = compileOption(\"threads\") and not defined(nimscript)\n  hasSharedHeap = defined(boehmgc) or defined(gogc) # don't share heaps; every thread has its own\n\nwhen hasThreadSupport and defined(tcc) and not compileOption(\"tlsEmulation\"):\n  # tcc doesn't support TLS\n  {.error: \"`--tlsEmulation:on` must be used when using threads with tcc backend\".}\n\nwhen defined(boehmgc):\n  when defined(windows):\n    when sizeof(int) == 8:\n      const boehmLib = \"boehmgc64.dll\"\n    else:\n      const boehmLib = \"boehmgc.dll\"\n  elif defined(macosx):\n    const boehmLib = \"libgc.dylib\"\n  elif defined(openbsd):\n    const boehmLib = \"libgc.so.(4|5).0\"\n  elif defined(freebsd):\n    const boehmLib = \"libgc-threaded.so.1\"\n  else:\n    const boehmLib = \"libgc.so.1\"\n  {.pragma: boehmGC, noconv, dynlib: boehmLib.}\n\ntype TaintedString* {.deprecated: \"Deprecated since 1.5\".} = string\n\n\nwhen defined(profiler) and not defined(nimscript):\n  proc nimProfile() {.compilerproc, noinline.}\nwhen hasThreadSupport:\n  {.pragma: rtlThreadVar, threadvar.}\nelse:\n  {.pragma: rtlThreadVar.}\n\nconst\n  QuitSuccess* = 0\n    ## is the value that should be passed to `quit <#quit,int>`_ to indicate\n    ## success.\n\n  QuitFailure* = 1\n    ## is the value that should be passed to `quit <#quit,int>`_ to indicate\n    ## failure.\n\nwhen not defined(js) and hostOS != \"standalone\":\n  var programResult* {.compilerproc, exportc: \"nim_program_result\".}: int\n    ## deprecated, prefer `quit` or `exitprocs.getProgramResult`, `exitprocs.setProgramResult`.\n\nimport std/private/since\n\nproc align(address, alignment: int): int =\n  if alignment == 0: # Actually, this is illegal. This branch exists to actively\n                     # hide problems.\n    result = address\n  else:\n    result = (address + (alignment - 1)) and not (alignment - 1)\n\nwhen defined(nimdoc):\n  proc quit*(errorcode: int = QuitSuccess) {.magic: \"Exit\", noreturn.}\n    ## Stops the program immediately with an exit code.\n    ##\n    ## Before stopping the program the \"exit procedures\" are called in the\n    ## opposite order they were added with `addExitProc <exitprocs.html#addExitProc,proc)>`_.\n    ##\n    ## The proc `quit(QuitSuccess)` is called implicitly when your nim\n    ## program finishes without incident for platforms where this is the\n    ## expected behavior. A raised unhandled exception is\n    ## equivalent to calling `quit(QuitFailure)`.\n    ##\n    ## Note that this is a *runtime* call and using `quit` inside a macro won't\n    ## have any compile time effect. If you need to stop the compiler inside a\n    ## macro, use the `error <manual.html#pragmas-error-pragma>`_ or `fatal\n    ## <manual.html#pragmas-fatal-pragma>`_ pragmas.\n    ##\n    ## .. danger:: In almost all cases, in particular in library code, prefer\n    ##   alternatives, e.g. `doAssert false` or raise a `Defect`.\n    ##   `quit` bypasses regular control flow in particular `defer`,\n    ##   `try`, `catch`, `finally` and `destructors`, and exceptions that may have been\n    ##   raised by an `addExitProc` proc, as well as cleanup code in other threads.\n    ##   It does *not* call the garbage collector to free all the memory,\n    ##   unless an `addExitProc` proc calls `GC_fullCollect <#GC_fullCollect>`_.\n\nelif defined(genode):\n  include genode/env\n\n  var systemEnv {.exportc: runtimeEnvSym.}: GenodeEnvPtr\n\n  type GenodeEnv* = GenodeEnvPtr\n    ## Opaque type representing Genode environment.\n\n  proc quit*(env: GenodeEnv; errorcode: int) {.magic: \"Exit\", noreturn,\n    importcpp: \"#->parent().exit(@); Genode::sleep_forever()\", header: \"<base/sleep.h>\".}\n\n  proc quit*(errorcode: int = QuitSuccess) =\n    systemEnv.quit(errorcode)\n\nelif defined(js) and defined(nodejs) and not defined(nimscript):\n  proc quit*(errorcode: int = QuitSuccess) {.magic: \"Exit\",\n    importc: \"process.exit\", noreturn.}\n\nelse:\n  proc quit*(errorcode: int = QuitSuccess) {.\n    magic: \"Exit\", importc: \"exit\", header: \"<stdlib.h>\", noreturn.}\n\n\ntemplate sysAssert(cond: bool, msg: string) =\n  when defined(useSysAssert):\n    if not cond:\n      cstderr.rawWrite \"[SYSASSERT] \"\n      cstderr.rawWrite msg\n      cstderr.rawWrite \"\\n\"\n      quit 1\n\nconst hasAlloc = (hostOS != \"standalone\" or not defined(nogc)) and not defined(nimscript)\n\nwhen notJSnotNims and hostOS != \"standalone\" and hostOS != \"any\":\n  include \"system/cgprocs\"\nwhen notJSnotNims and hasAlloc and not defined(nimSeqsV2):\n  proc addChar(s: NimString, c: char): NimString {.compilerproc, benign.}\n\nwhen defined(nimscript) or not defined(nimSeqsV2):\n  proc add*[T](x: var seq[T], y: sink T) {.magic: \"AppendSeqElem\", noSideEffect.}\n    ## Generic proc for adding a data item `y` to a container `x`.\n    ##\n    ## For containers that have an order, `add` means *append*. New generic\n    ## containers should also call their adding proc `add` for consistency.\n    ## Generic code becomes much easier to write if the Nim naming scheme is\n    ## respected.\n\nwhen false: # defined(gcDestructors):\n  proc add*[T](x: var seq[T], y: sink openArray[T]) {.noSideEffect.} =\n    ## Generic proc for adding a container `y` to a container `x`.\n    ##\n    ## For containers that have an order, `add` means *append*. New generic\n    ## containers should also call their adding proc `add` for consistency.\n    ## Generic code becomes much easier to write if the Nim naming scheme is\n    ## respected.\n    ##\n    ## See also:\n    ## * `& proc <#&,seq[T],seq[T]>`_\n    ##\n    ## .. code-block:: Nim\n    ##   var s: seq[string] = @[\"test2\",\"test2\"]\n    ##   s.add(\"test\") # s <- @[test2, test2, test]\n    {.noSideEffect.}:\n      let xl = x.len\n      setLen(x, xl + y.len)\n      for i in 0..high(y):\n        when nimvm:\n          # workaround the fact that the VM does not yet\n          # handle sink parameters properly:\n          x[xl+i] = y[i]\n        else:\n          x[xl+i] = move y[i]\nelse:\n  proc add*[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} =\n    ## Generic proc for adding a container `y` to a container `x`.\n    ##\n    ## For containers that have an order, `add` means *append*. New generic\n    ## containers should also call their adding proc `add` for consistency.\n    ## Generic code becomes much easier to write if the Nim naming scheme is\n    ## respected.\n    ##\n    ## See also:\n    ## * `& proc <#&,seq[T],seq[T]>`_\n    ##\n    ## .. code-block:: Nim\n    ##   var s: seq[string] = @[\"test2\",\"test2\"]\n    ##   s.add(\"test\") # s <- @[test2, test2, test]\n    {.noSideEffect.}:\n      let xl = x.len\n      setLen(x, xl + y.len)\n      for i in 0..high(y): x[xl+i] = y[i]\n\n\nwhen defined(nimSeqsV2):\n  template movingCopy(a, b) =\n    a = move(b)\nelse:\n  template movingCopy(a, b) =\n    shallowCopy(a, b)\n\nproc del*[T](x: var seq[T], i: Natural) {.noSideEffect.} =\n  ## Deletes the item at index `i` by putting `x[high(x)]` into position `i`.\n  ##\n  ## This is an `O(1)` operation.\n  ##\n  ## See also:\n  ## * `delete <#delete,seq[T],Natural>`_ for preserving the order\n  runnableExamples:\n    var a = @[10, 11, 12, 13, 14]\n    a.del(2)\n    assert a == @[10, 11, 14, 13]\n  let xl = x.len - 1\n  movingCopy(x[i], x[xl])\n  setLen(x, xl)\n\nproc insert*[T](x: var seq[T], item: sink T, i = 0.Natural) {.noSideEffect.} =\n  ## Inserts `item` into `x` at position `i`.\n  ##\n  ## .. code-block:: Nim\n  ##  var i = @[1, 3, 5]\n  ##  i.insert(99, 0) # i <- @[99, 1, 3, 5]\n  {.noSideEffect.}:\n    template defaultImpl =\n      let xl = x.len\n      setLen(x, xl+1)\n      var j = xl-1\n      while j >= i:\n        movingCopy(x[j+1], x[j])\n        dec(j)\n    when nimvm:\n      defaultImpl()\n    else:\n      when defined(js):\n        var it : T\n        {.emit: \"`x` = `x` || []; `x`.splice(`i`, 0, `it`);\".}\n      else:\n        defaultImpl()\n    x[i] = item\n\nwhen not defined(nimV2):\n  proc repr*[T](x: T): string {.magic: \"Repr\", noSideEffect.}\n    ## Takes any Nim variable and returns its string representation.\n    ## No trailing newline is inserted (so `echo` won't add an empty newline).\n    ## Use `-d:nimLegacyReprWithNewline` to revert to old behavior where newlines\n    ## were added in some cases.\n    ##\n    ## It works even for complex data graphs with cycles. This is a great\n    ## debugging tool.\n    ##\n    ## .. code-block:: Nim\n    ##  var s: seq[string] = @[\"test2\", \"test2\"]\n    ##  var i = @[1, 2, 3, 4, 5]\n    ##  echo repr(s) # => 0x1055eb050[0x1055ec050\"test2\", 0x1055ec078\"test2\"]\n    ##  echo repr(i) # => 0x1055ed050[1, 2, 3, 4, 5]\n\ntype\n  ByteAddress* = int\n    ## is the signed integer type that should be used for converting\n    ## pointers to integer addresses for readability.\n\n  BiggestFloat* = float64\n    ## is an alias for the biggest floating point type the Nim\n    ## compiler supports. Currently this is `float64`, but it is\n    ## platform-dependent in general.\n\nwhen defined(js):\n  type BiggestUInt* = uint32\n    ## is an alias for the biggest unsigned integer type the Nim compiler\n    ## supports. Currently this is `uint32` for JS and `uint64` for other\n    ## targets.\nelse:\n  type BiggestUInt* = uint64\n    ## is an alias for the biggest unsigned integer type the Nim compiler\n    ## supports. Currently this is `uint32` for JS and `uint64` for other\n    ## targets.\n\nwhen defined(windows):\n  type\n    clong* {.importc: \"long\", nodecl.} = int32\n      ## This is the same as the type `long` in *C*.\n    culong* {.importc: \"unsigned long\", nodecl.} = uint32\n      ## This is the same as the type `unsigned long` in *C*.\nelse:\n  type\n    clong* {.importc: \"long\", nodecl.} = int\n      ## This is the same as the type `long` in *C*.\n    culong* {.importc: \"unsigned long\", nodecl.} = uint\n      ## This is the same as the type `unsigned long` in *C*.\n\ntype # these work for most platforms:\n  cchar* {.importc: \"char\", nodecl.} = char\n    ## This is the same as the type `char` in *C*.\n  cschar* {.importc: \"signed char\", nodecl.} = int8\n    ## This is the same as the type `signed char` in *C*.\n  cshort* {.importc: \"short\", nodecl.} = int16\n    ## This is the same as the type `short` in *C*.\n  cint* {.importc: \"int\", nodecl.} = int32\n    ## This is the same as the type `int` in *C*.\n  csize* {.importc: \"size_t\", nodecl, deprecated: \"use `csize_t` instead\".} = int\n    ## This isn't the same as `size_t` in *C*. Don't use it.\n  csize_t* {.importc: \"size_t\", nodecl.} = uint\n    ## This is the same as the type `size_t` in *C*.\n  clonglong* {.importc: \"long long\", nodecl.} = int64\n    ## This is the same as the type `long long` in *C*.\n  cfloat* {.importc: \"float\", nodecl.} = float32\n    ## This is the same as the type `float` in *C*.\n  cdouble* {.importc: \"double\", nodecl.} = float64\n    ## This is the same as the type `double` in *C*.\n  clongdouble* {.importc: \"long double\", nodecl.} = BiggestFloat\n    ## This is the same as the type `long double` in *C*.\n    ## This C type is not supported by Nim's code generator.\n\n  cuchar* {.importc: \"unsigned char\", nodecl, deprecated: \"use `char` or `uint8` instead\".} = char\n    ## Deprecated: Use `uint8` instead.\n  cushort* {.importc: \"unsigned short\", nodecl.} = uint16\n    ## This is the same as the type `unsigned short` in *C*.\n  cuint* {.importc: \"unsigned int\", nodecl.} = uint32\n    ## This is the same as the type `unsigned int` in *C*.\n  culonglong* {.importc: \"unsigned long long\", nodecl.} = uint64\n    ## This is the same as the type `unsigned long long` in *C*.\n\n  cstringArray* {.importc: \"char**\", nodecl.} = ptr UncheckedArray[cstring]\n    ## This is binary compatible to the type `char**` in *C*. The array's\n    ## high value is large enough to disable bounds checking in practice.\n    ## Use `cstringArrayToSeq proc <#cstringArrayToSeq,cstringArray,Natural>`_\n    ## to convert it into a `seq[string]`.\n\n  PFloat32* = ptr float32    ## An alias for `ptr float32`.\n  PFloat64* = ptr float64    ## An alias for `ptr float64`.\n  PInt64* = ptr int64        ## An alias for `ptr int64`.\n  PInt32* = ptr int32        ## An alias for `ptr int32`.\n\nproc toFloat*(i: int): float {.noSideEffect, inline.} =\n  ## Converts an integer `i` into a `float`. Same as `float(i)`.\n  ##\n  ## If the conversion fails, `ValueError` is raised.\n  ## However, on most platforms the conversion cannot fail.\n  ##\n  ## .. code-block:: Nim\n  ##   let\n  ##     a = 2\n  ##     b = 3.7\n  ##\n  ##   echo a.toFloat + b # => 5.7\n  float(i)\n\nproc toBiggestFloat*(i: BiggestInt): BiggestFloat {.noSideEffect, inline.} =\n  ## Same as `toFloat <#toFloat,int>`_ but for `BiggestInt` to `BiggestFloat`.\n  BiggestFloat(i)\n\nproc toInt*(f: float): int {.noSideEffect.} =\n  ## Converts a floating point number `f` into an `int`.\n  ##\n  ## Conversion rounds `f` half away from 0, see\n  ## `Round half away from zero\n  ## <https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero>`_,\n  ## as opposed to a type conversion which rounds towards zero.\n  ##\n  ## Note that some floating point numbers (e.g. infinity or even 1e19)\n  ## cannot be accurately converted.\n  ##\n  ## .. code-block:: Nim\n  ##   doAssert toInt(0.49) == 0\n  ##   doAssert toInt(0.5) == 1\n  ##   doAssert toInt(-0.5) == -1 # rounding is symmetrical\n  if f >= 0: int(f+0.5) else: int(f-0.5)\n\nproc toBiggestInt*(f: BiggestFloat): BiggestInt {.noSideEffect.} =\n  ## Same as `toInt <#toInt,float>`_ but for `BiggestFloat` to `BiggestInt`.\n  if f >= 0: BiggestInt(f+0.5) else: BiggestInt(f-0.5)\n\nproc addQuitProc*(quitProc: proc() {.noconv.}) {.\n  importc: \"atexit\", header: \"<stdlib.h>\", deprecated: \"use exitprocs.addExitProc\".}\n  ## Adds/registers a quit procedure.\n  ##\n  ## Each call to `addQuitProc` registers another quit procedure. Up to 30\n  ## procedures can be registered. They are executed on a last-in, first-out\n  ## basis (that is, the last function registered is the first to be executed).\n  ## `addQuitProc` raises an EOutOfIndex exception if `quitProc` cannot be\n  ## registered.\n  # Support for addQuitProc() is done by Ansi C's facilities here.\n  # In case of an unhandled exception the exit handlers should\n  # not be called explicitly! The user may decide to do this manually though.\n\nproc swap*[T](a, b: var T) {.magic: \"Swap\", noSideEffect.}\n  ## Swaps the values `a` and `b`.\n  ##\n  ## This is often more efficient than `tmp = a; a = b; b = tmp`.\n  ## Particularly useful for sorting algorithms.\n  ##\n  ## .. code-block:: Nim\n  ##   var\n  ##     a = 5\n  ##     b = 9\n  ##\n  ##   swap(a, b)\n  ##\n  ##   assert a == 9\n  ##   assert b == 5\n\nwhen not defined(js) and not defined(booting) and defined(nimTrMacros):\n  template swapRefsInArray*{swap(arr[a], arr[b])}(arr: openArray[ref], a, b: int) =\n    # Optimize swapping of array elements if they are refs. Default swap\n    # implementation will cause unsureAsgnRef to be emitted which causes\n    # unnecessary slow down in this case.\n    swap(cast[ptr pointer](addr arr[a])[], cast[ptr pointer](addr arr[b])[])\n\nconst\n  Inf* = 0x7FF0000000000000'f64\n    ## Contains the IEEE floating point value of positive infinity.\n  NegInf* = 0xFFF0000000000000'f64\n    ## Contains the IEEE floating point value of negative infinity.\n  NaN* = 0x7FF7FFFFFFFFFFFF'f64\n    ## Contains an IEEE floating point value of *Not A Number*.\n    ##\n    ## Note that you cannot compare a floating point value to this value\n    ## and expect a reasonable result - use the `isNaN` or `classify` procedure\n    ## in the `math module <math.html>`_ for checking for NaN.\n\n\ninclude \"system/memalloc\"\n\n\nproc `|`*(a, b: typedesc): typedesc = discard\n\ninclude \"system/iterators_1\"\n\n\n{.push stackTrace: off.}\n\n\nwhen defined(js):\n  proc js_abs[T: SomeNumber](x: T): T {.importc: \"Math.abs\".}\nelse:\n  proc c_fabs(x: cdouble): cdouble {.importc: \"fabs\", header: \"<math.h>\".}\n  proc c_fabsf(x: cfloat): cfloat {.importc: \"fabsf\", header: \"<math.h>\".}\n\nproc abs*[T: float64 | float32](x: T): T {.noSideEffect, inline.} =\n  when nimvm:\n    if x < 0.0: result = -x\n    elif x == 0.0: result = 0.0 # handle 0.0, -0.0\n    else: result = x # handle NaN, > 0\n  else:\n    when defined(js): result = js_abs(x)\n    else:\n      when T is float64:\n        result = c_fabs(x)\n      else:\n        result = c_fabsf(x)\n\nproc min*(x, y: float32): float32 {.noSideEffect, inline.} =\n  if x <= y or y != y: x else: y\nproc min*(x, y: float64): float64 {.noSideEffect, inline.} =\n  if x <= y or y != y: x else: y\nproc max*(x, y: float32): float32 {.noSideEffect, inline.} =\n  if y <= x or y != y: x else: y\nproc max*(x, y: float64): float64 {.noSideEffect, inline.} =\n  if y <= x or y != y: x else: y\nproc min*[T: not SomeFloat](x, y: T): T {.inline.} =\n  if x <= y: x else: y\nproc max*[T: not SomeFloat](x, y: T): T {.inline.} =\n  if y <= x: x else: y\n\n{.pop.} # stackTrace: off\n\n\nproc high*(T: typedesc[SomeFloat]): T = Inf\nproc low*(T: typedesc[SomeFloat]): T = NegInf\n\nproc len*[U: Ordinal; V: Ordinal](x: HSlice[U, V]): int {.noSideEffect, inline.} =\n  ## Length of ordinal slice. When x.b < x.a returns zero length.\n  ##\n  ## .. code-block:: Nim\n  ##   assert((0..5).len == 6)\n  ##   assert((5..2).len == 0)\n  result = max(0, ord(x.b) - ord(x.a) + 1)\n\nwhen true: # PRTEMP: remove?\n  proc isNil*[T](x: seq[T]): bool {.noSideEffect, magic: \"IsNil\", error.}\n    ## Seqs are no longer nil by default, but set and empty.\n    ## Check for zero length instead.\n    ##\n    ## See also:\n    ## * `isNil(string) <#isNil,string>`_\n\n  proc isNil*(x: string): bool {.noSideEffect, magic: \"IsNil\", error.}\n    ## See also:\n    ## * `isNil(seq[T]) <#isNil,seq[T]>`_\n\nproc isNil*[T](x: ref T): bool {.noSideEffect, magic: \"IsNil\".}\n\nproc isNil*[T](x: ptr T): bool {.noSideEffect, magic: \"IsNil\".}\nproc isNil*(x: pointer): bool {.noSideEffect, magic: \"IsNil\".}\nproc isNil*(x: cstring): bool {.noSideEffect, magic: \"IsNil\".}\nproc isNil*[T: proc](x: T): bool {.noSideEffect, magic: \"IsNil\".}\n  ## Fast check whether `x` is nil. This is sometimes more efficient than\n  ## `== nil`.\n\n\nproc `@`*[T](a: openArray[T]): seq[T] =\n  ## Turns an *openArray* into a sequence.\n  ##\n  ## This is not as efficient as turning a fixed length array into a sequence\n  ## as it always copies every element of `a`.\n  newSeq(result, a.len)\n  for i in 0..a.len-1: result[i] = a[i]\n\n\nwhen defined(nimSeqsV2):\n\n  proc `&`*[T](x, y: sink seq[T]): seq[T] {.noSideEffect.} =\n    ## Concatenates two sequences.\n    ##\n    ## Requires copying of the sequences.\n    ##\n    ## See also:\n    ## * `add(var seq[T], openArray[T]) <#add,seq[T],openArray[T]>`_\n    ##\n    ## .. code-block:: Nim\n    ##   assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6])\n    newSeq(result, x.len + y.len)\n    for i in 0..x.len-1:\n      result[i] = move(x[i])\n    for i in 0..y.len-1:\n      result[i+x.len] = move(y[i])\n\n  proc `&`*[T](x: sink seq[T], y: sink T): seq[T] {.noSideEffect.} =\n    ## Appends element y to the end of the sequence.\n    ##\n    ## Requires copying of the sequence.\n    ##\n    ## See also:\n    ## * `add(var seq[T], T) <#add,seq[T],sinkT>`_\n    ##\n    ## .. code-block:: Nim\n    ##   assert(@[1, 2, 3] & 4 == @[1, 2, 3, 4])\n    newSeq(result, x.len + 1)\n    for i in 0..x.len-1:\n      result[i] = move(x[i])\n    result[x.len] = move(y)\n\n  proc `&`*[T](x: sink T, y: sink seq[T]): seq[T] {.noSideEffect.} =\n    ## Prepends the element x to the beginning of the sequence.\n    ##\n    ## Requires copying of the sequence.\n    ##\n    ## .. code-block:: Nim\n    ##   assert(1 & @[2, 3, 4] == @[1, 2, 3, 4])\n    newSeq(result, y.len + 1)\n    result[0] = move(x)\n    for i in 0..y.len-1:\n      result[i+1] = move(y[i])\n\nelse:\n\n  proc `&`*[T](x, y: seq[T]): seq[T] {.noSideEffect.} =\n    ## Concatenates two sequences.\n    ##\n    ## Requires copying of the sequences.\n    ##\n    ## See also:\n    ## * `add(var seq[T], openArray[T]) <#add,seq[T],openArray[T]>`_\n    ##\n    ## .. code-block:: Nim\n    ##   assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6])\n    newSeq(result, x.len + y.len)\n    for i in 0..x.len-1:\n      result[i] = x[i]\n    for i in 0..y.len-1:\n      result[i+x.len] = y[i]\n\n  proc `&`*[T](x: seq[T], y: T): seq[T] {.noSideEffect.} =\n    ## Appends element y to the end of the sequence.\n    ##\n    ## Requires copying of the sequence.\n    ##\n    ## See also:\n    ## * `add(var seq[T], T) <#add,seq[T],sinkT>`_\n    ##\n    ## .. code-block:: Nim\n    ##   assert(@[1, 2, 3] & 4 == @[1, 2, 3, 4])\n    newSeq(result, x.len + 1)\n    for i in 0..x.len-1:\n      result[i] = x[i]\n    result[x.len] = y\n\n  proc `&`*[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} =\n    ## Prepends the element x to the beginning of the sequence.\n    ##\n    ## Requires copying of the sequence.\n    ##\n    ## .. code-block:: Nim\n    ##   assert(1 & @[2, 3, 4] == @[1, 2, 3, 4])\n    newSeq(result, y.len + 1)\n    result[0] = x\n    for i in 0..y.len-1:\n      result[i+1] = y[i]\n\n\nproc astToStr*[T](x: T): string {.magic: \"AstToStr\", noSideEffect.}\n  ## Converts the AST of `x` into a string representation. This is very useful\n  ## for debugging.\n\nproc instantiationInfo*(index = -1, fullPaths = false): tuple[\n  filename: string, line: int, column: int] {.magic: \"InstantiationInfo\", noSideEffect.}\n  ## Provides access to the compiler's instantiation stack line information\n  ## of a template.\n  ##\n  ## While similar to the `caller info`:idx: of other languages, it is determined\n  ## at compile time.\n  ##\n  ## This proc is mostly useful for meta programming (eg. `assert` template)\n  ## to retrieve information about the current filename and line number.\n  ## Example:\n  ##\n  ## .. code-block:: nim\n  ##   import std/strutils\n  ##\n  ##   template testException(exception, code: untyped): typed =\n  ##     try:\n  ##       let pos = instantiationInfo()\n  ##       discard(code)\n  ##       echo \"Test failure at $1:$2 with '$3'\" % [pos.filename,\n  ##         $pos.line, astToStr(code)]\n  ##       assert false, \"A test expecting failure succeeded?\"\n  ##     except exception:\n  ##       discard\n  ##\n  ##   proc tester(pos: int): int =\n  ##     let\n  ##       a = @[1, 2, 3]\n  ##     result = a[pos]\n  ##\n  ##   when isMainModule:\n  ##     testException(IndexDefect, tester(30))\n  ##     testException(IndexDefect, tester(1))\n  ##     # --> Test failure at example.nim:20 with 'tester(1)'\n\nproc compiles*(x: untyped): bool {.magic: \"Compiles\", noSideEffect, compileTime.} =\n  ## Special compile-time procedure that checks whether `x` can be compiled\n  ## without any semantic error.\n  ## This can be used to check whether a type supports some operation:\n  ##\n  ## .. code-block:: Nim\n  ##   when compiles(3 + 4):\n  ##     echo \"'+' for integers is available\"\n  discard\n\nwhen notJSnotNims:\n  import system/ansi_c\n  import system/memory\n\n\n{.push stackTrace: off.}\n\nwhen not defined(js) and hasThreadSupport and hostOS != \"standalone\":\n  const insideRLocksModule = false\n  include \"system/syslocks\"\n  include \"system/threadlocalstorage\"\n\nwhen not defined(js) and defined(nimV2):\n  type\n    DestructorProc = proc (p: pointer) {.nimcall, benign, raises: [].}\n    TNimTypeV2 {.compilerproc.} = object\n      destructor: pointer\n      size: int\n      align: int\n      name: cstring\n      traceImpl: pointer\n      typeInfoV1: pointer # for backwards compat, usually nil\n      flags: int\n    PNimTypeV2 = ptr TNimTypeV2\n\nwhen notJSnotNims and defined(nimSeqsV2):\n  include \"system/strs_v2\"\n  include \"system/seqs_v2\"\n\n{.pop.}\n\nwhen not defined(nimscript):\n  proc writeStackTrace*() {.tags: [], gcsafe, raises: [].}\n    ## Writes the current stack trace to `stderr`. This is only works\n    ## for debug builds. Since it's usually used for debugging, this\n    ## is proclaimed to have no IO effect!\n\nwhen not declared(sysFatal):\n  include \"system/fatal\"\n\nwhen not defined(nimscript):\n  {.push stackTrace: off, profiler: off.}\n\n  proc atomicInc*(memLoc: var int, x: int = 1): int {.inline,\n    discardable, benign.}\n    ## Atomic increment of `memLoc`. Returns the value after the operation.\n\n  proc atomicDec*(memLoc: var int, x: int = 1): int {.inline,\n    discardable, benign.}\n    ## Atomic decrement of `memLoc`. Returns the value after the operation.\n\n  include \"system/atomics\"\n\n  {.pop.}\n\n\nwhen defined(nimV2):\n  include system/arc\n\nimport system/assertions\nexport assertions\n\nimport system/iterators\nexport iterators\n\n\nproc find*[T, S](a: T, item: S): int {.inline.}=\n  ## Returns the first index of `item` in `a` or -1 if not found. This requires\n  ## appropriate `items` and `==` operations to work.\n  result = 0\n  for i in items(a):\n    if i == item: return\n    inc(result)\n  result = -1\n\nproc contains*[T](a: openArray[T], item: T): bool {.inline.}=\n  ## Returns true if `item` is in `a` or false if not found. This is a shortcut\n  ## for `find(a, item) >= 0`.\n  ##\n  ## This allows the `in` operator: `a.contains(item)` is the same as\n  ## `item in a`.\n  ##\n  ## .. code-block:: Nim\n  ##   var a = @[1, 3, 5]\n  ##   assert a.contains(5)\n  ##   assert 3 in a\n  ##   assert 99 notin a\n  return find(a, item) >= 0\n\nproc pop*[T](s: var seq[T]): T {.inline, noSideEffect.} =\n  ## Returns the last item of `s` and decreases `s.len` by one. This treats\n  ## `s` as a stack and implements the common *pop* operation.\n  runnableExamples:\n    var a = @[1, 3, 5, 7]\n    let b = pop(a)\n    assert b == 7\n    assert a == @[1, 3, 5]\n\n  var L = s.len-1\n  when defined(nimV2):\n    result = move s[L]\n    shrink(s, L)\n  else:\n    result = s[L]\n    setLen(s, L)\n\nproc `==`*[T: tuple|object](x, y: T): bool =\n  ## Generic `==` operator for tuples that is lifted from the components.\n  ## of `x` and `y`.\n  for a, b in fields(x, y):\n    if a != b: return false\n  return true\n\nproc `<=`*[T: tuple](x, y: T): bool =\n  ## Generic lexicographic `<=` operator for tuples that is lifted from the\n  ## components of `x` and `y`. This implementation uses `cmp`.\n  for a, b in fields(x, y):\n    var c = cmp(a, b)\n    if c < 0: return true\n    if c > 0: return false\n  return true\n\nproc `<`*[T: tuple](x, y: T): bool =\n  ## Generic lexicographic `<` operator for tuples that is lifted from the\n  ## components of `x` and `y`. This implementation uses `cmp`.\n  for a, b in fields(x, y):\n    var c = cmp(a, b)\n    if c < 0: return true\n    if c > 0: return false\n  return false\n\n\ninclude \"system/gc_interface\"\n\n# we have to compute this here before turning it off in except.nim anyway ...\nconst NimStackTrace = compileOption(\"stacktrace\")\n\nimport system/coro_detection\n\n{.push checks: off.}\n# obviously we cannot generate checking operations here :-)\n# because it would yield into an endless recursion\n# however, stack-traces are available for most parts\n# of the code\n\nwhen notJSnotNims:\n  var\n    globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, benign.}\n      ## With this hook you can influence exception handling on a global level.\n      ## If not nil, every 'raise' statement ends up calling this hook.\n      ##\n      ## .. warning:: Ordinary application code should never set this hook! You better know what you do when setting this.\n      ##\n      ## If `globalRaiseHook` returns false, the exception is caught and does\n      ## not propagate further through the call stack.\n\n    localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, benign.}\n      ## With this hook you can influence exception handling on a\n      ## thread local level.\n      ## If not nil, every 'raise' statement ends up calling this hook.\n      ##\n      ## .. warning:: Ordinary application code should never set this hook! You better know what you do when setting this.\n      ##\n      ## If `localRaiseHook` returns false, the exception\n      ## is caught and does not propagate further through the call stack.\n\n    outOfMemHook*: proc () {.nimcall, tags: [], benign, raises: [].}\n      ## Set this variable to provide a procedure that should be called\n      ## in case of an `out of memory`:idx: event. The standard handler\n      ## writes an error message and terminates the program.\n      ##\n      ## `outOfMemHook` can be used to raise an exception in case of OOM like so:\n      ##\n      ## .. code-block:: Nim\n      ##\n      ##   var gOutOfMem: ref EOutOfMemory\n      ##   new(gOutOfMem) # need to be allocated *before* OOM really happened!\n      ##   gOutOfMem.msg = \"out of memory\"\n      ##\n      ##   proc handleOOM() =\n      ##     raise gOutOfMem\n      ##\n      ##   system.outOfMemHook = handleOOM\n      ##\n      ## If the handler does not raise an exception, ordinary control flow\n      ## continues and the program is terminated.\n    unhandledExceptionHook*: proc (e: ref Exception) {.nimcall, tags: [], benign, raises: [].}\n      ## Set this variable to provide a procedure that should be called\n      ## in case of an `unhandle exception` event. The standard handler\n      ## writes an error message and terminates the program, except when\n      ## using `--os:any`\n\ntype\n  PFrame* = ptr TFrame  ## Represents a runtime frame of the call stack;\n                        ## part of the debugger API.\n  # keep in sync with nimbase.h `struct TFrame_`\n  TFrame* {.importc, nodecl, final.} = object ## The frame itself.\n    prev*: PFrame       ## Previous frame; used for chaining the call stack.\n    procname*: cstring  ## Name of the proc that is currently executing.\n    line*: int          ## Line number of the proc that is currently executing.\n    filename*: cstring  ## Filename of the proc that is currently executing.\n    len*: int16         ## Length of the inspectable slots.\n    calldepth*: int16   ## Used for max call depth checking.\n    when NimStackTraceMsgs:\n      frameMsgLen*: int   ## end position in frameMsgBuf for this frame.\n\nwhen defined(js) or defined(nimdoc):\n  proc add*(x: var string, y: cstring) {.asmNoStackFrame.} =\n    ## Appends `y` to `x` in place.\n    runnableExamples:\n      var tmp = \"\"\n      tmp.add(cstring(\"ab\"))\n      tmp.add(cstring(\"cd\"))\n      doAssert tmp == \"abcd\"\n    asm \"\"\"\n      if (`x` === null) { `x` = []; }\n      var off = `x`.length;\n      `x`.length += `y`.length;\n      for (var i = 0; i < `y`.length; ++i) {\n        `x`[off+i] = `y`.charCodeAt(i);\n      }\n    \"\"\"\n  proc add*(x: var cstring, y: cstring) {.magic: \"AppendStrStr\".} =\n    ## Appends `y` to `x` in place.\n    ## Only implemented for JS backend.\n    runnableExamples:\n      when defined(js):\n        var tmp: cstring = \"\"\n        tmp.add(cstring(\"ab\"))\n        tmp.add(cstring(\"cd\"))\n        doAssert tmp == cstring(\"abcd\")\n\nelif hasAlloc:\n  {.push stackTrace: off, profiler: off.}\n  proc add*(x: var string, y: cstring) =\n    var i = 0\n    if y != nil:\n      while y[i] != '\\0':\n        add(x, y[i])\n        inc(i)\n  {.pop.}\n\nproc echo*(x: varargs[typed, `$`]) {.magic: \"Echo\", benign, sideEffect.}\n  ## Writes and flushes the parameters to the standard output.\n  ##\n  ## Special built-in that takes a variable number of arguments. Each argument\n  ## is converted to a string via `$`, so it works for user-defined\n  ## types that have an overloaded `$` operator.\n  ## It is roughly equivalent to `writeLine(stdout, x); flushFile(stdout)`, but\n  ## available for the JavaScript target too.\n  ##\n  ## Unlike other IO operations this is guaranteed to be thread-safe as\n  ## `echo` is very often used for debugging convenience. If you want to use\n  ## `echo` inside a `proc without side effects\n  ## <manual.html#pragmas-nosideeffect-pragma>`_ you can use `debugEcho\n  ## <#debugEcho,varargs[typed,]>`_ instead.\n\nproc debugEcho*(x: varargs[typed, `$`]) {.magic: \"Echo\", noSideEffect,\n                                          tags: [], raises: [].}\n  ## Same as `echo <#echo,varargs[typed,]>`_, but as a special semantic rule,\n  ## `debugEcho` pretends to be free of side effects, so that it can be used\n  ## for debugging routines marked as `noSideEffect\n  ## <manual.html#pragmas-nosideeffect-pragma>`_.\n\ntemplate newException*(exceptn: typedesc, message: string;\n                       parentException: ref Exception = nil): untyped =\n  ## Creates an exception object of type `exceptn` and sets its `msg` field\n  ## to `message`. Returns the new exception object.\n  (ref exceptn)(msg: message, parent: parentException)\n\nwhen hostOS == \"standalone\" and defined(nogc):\n  proc nimToCStringConv(s: NimString): cstring {.compilerproc, inline.} =\n    if s == nil or s.len == 0: result = cstring\"\"\n    else: result = cstring(addr s.data)\n\nproc getTypeInfo*[T](x: T): pointer {.magic: \"GetTypeInfo\", benign.}\n  ## Get type information for `x`.\n  ##\n  ## Ordinary code should not use this, but the `typeinfo module\n  ## <typeinfo.html>`_ instead.\n\n{.push stackTrace: off.}\nfunc abs*(x: int): int {.magic: \"AbsI\", inline.} =\n  if x < 0: -x else: x\nfunc abs*(x: int8): int8 {.magic: \"AbsI\", inline.} =\n  if x < 0: -x else: x\nfunc abs*(x: int16): int16 {.magic: \"AbsI\", inline.} =\n  if x < 0: -x else: x\nfunc abs*(x: int32): int32 {.magic: \"AbsI\", inline.} =\n  if x < 0: -x else: x\nfunc abs*(x: int64): int64 {.magic: \"AbsI\", inline.} =\n  ## Returns the absolute value of `x`.\n  ##\n  ## If `x` is `low(x)` (that is -MININT for its type),\n  ## an overflow exception is thrown (if overflow checking is turned on).\n  result = if x < 0: -x else: x\n{.pop.}\n\nwhen not defined(js):\n\n  proc likelyProc(val: bool): bool {.importc: \"NIM_LIKELY\", nodecl, noSideEffect.}\n  proc unlikelyProc(val: bool): bool {.importc: \"NIM_UNLIKELY\", nodecl, noSideEffect.}\n\ntemplate likely*(val: bool): bool =\n  ## Hints the optimizer that `val` is likely going to be true.\n  ##\n  ## You can use this template to decorate a branch condition. On certain\n  ## platforms this can help the processor predict better which branch is\n  ## going to be run. Example:\n  ##\n  ## .. code-block:: Nim\n  ##   for value in inputValues:\n  ##     if likely(value <= 100):\n  ##       process(value)\n  ##     else:\n  ##       echo \"Value too big!\"\n  ##\n  ## On backends without branch prediction (JS and the nimscript VM), this\n  ## template will not affect code execution.\n  when nimvm:\n    val\n  else:\n    when defined(js):\n      val\n    else:\n      likelyProc(val)\n\ntemplate unlikely*(val: bool): bool =\n  ## Hints the optimizer that `val` is likely going to be false.\n  ##\n  ## You can use this proc to decorate a branch condition. On certain\n  ## platforms this can help the processor predict better which branch is\n  ## going to be run. Example:\n  ##\n  ## .. code-block:: Nim\n  ##   for value in inputValues:\n  ##     if unlikely(value > 100):\n  ##       echo \"Value too big!\"\n  ##     else:\n  ##       process(value)\n  ##\n  ## On backends without branch prediction (JS and the nimscript VM), this\n  ## template will not affect code execution.\n  when nimvm:\n    val\n  else:\n    when defined(js):\n      val\n    else:\n      unlikelyProc(val)\n\nconst\n  NimMajor* {.intdefine.}: int = 1\n    ## is the major number of Nim's version. Example:\n    ##\n    ## .. code-block:: Nim\n    ##   when (NimMajor, NimMinor, NimPatch) >= (1, 3, 1): discard\n    # see also std/private/since\n\n  NimMinor* {.intdefine.}: int = 5\n    ## is the minor number of Nim's version.\n    ## Odd for devel, even for releases.\n\n  NimPatch* {.intdefine.}: int = 1\n    ## is the patch number of Nim's version.\n    ## Odd for devel, even for releases.\n\nimport system/dollars\nexport dollars\n\nwhen defined(nimAuditDelete):\n  {.pragma: auditDelete, deprecated: \"review this call for out of bounds behavior\".}\nelse:\n  {.pragma: auditDelete.}\n\nproc delete*[T](x: var seq[T], i: Natural) {.noSideEffect, auditDelete.} =\n  ## Deletes the item at index `i` by moving all `x[i+1..^1]` items by one position.\n  ##\n  ## This is an `O(n)` operation.\n  ##\n  ## .. note:: With `-d:nimStrictDelete`, an index error is produced when the index passed\n  ##    to it was out of bounds. `-d:nimStrictDelete` will become the default\n  ##    in upcoming versions.\n  ##\n  ## See also:\n  ## * `del <#del,seq[T],Natural>`_ for O(1) operation\n  ##\n  runnableExamples:\n    var s = @[1, 2, 3, 4, 5]\n    s.delete(2)\n    doAssert s == @[1, 2, 4, 5]\n\n  when defined(nimStrictDelete):\n    if i > high(x):\n      # xxx this should call `raiseIndexError2(i, high(x))` after some refactoring\n      raise (ref IndexDefect)(msg: \"index out of bounds: '\" & $i & \"' < '\" & $x.len & \"' failed\")\n\n  template defaultImpl =\n    let xl = x.len\n    for j in i.int..xl-2: movingCopy(x[j], x[j+1])\n    setLen(x, xl-1)\n\n  when nimvm:\n    defaultImpl()\n  else:\n    when defined(js):\n      {.emit: \"`x`.splice(`i`, 1);\".}\n    else:\n      defaultImpl()\n\n\nconst\n  NimVersion*: string = $NimMajor & \".\" & $NimMinor & \".\" & $NimPatch\n    ## is the version of Nim as a string.\n\n\ntype\n  FileSeekPos* = enum ## Position relative to which seek should happen.\n                      # The values are ordered so that they match with stdio\n                      # SEEK_SET, SEEK_CUR and SEEK_END respectively.\n    fspSet            ## Seek to absolute value\n    fspCur            ## Seek relative to current position\n    fspEnd            ## Seek relative to end\n\n\nwhen not defined(js):\n  {.push stackTrace: off, profiler: off.}\n\n  when hasAlloc:\n    when not defined(gcRegions) and not usesDestructors:\n      proc initGC() {.gcsafe, raises: [].}\n\n    proc initStackBottom() {.inline, compilerproc.} =\n      # WARNING: This is very fragile! An array size of 8 does not work on my\n      # Linux 64bit system. -- That's because the stack direction is the other\n      # way around.\n      when declared(nimGC_setStackBottom):\n        var locals {.volatile, noinit.}: pointer\n        locals = addr(locals)\n        nimGC_setStackBottom(locals)\n\n    proc initStackBottomWith(locals: pointer) {.inline, compilerproc.} =\n      # We need to keep initStackBottom around for now to avoid\n      # bootstrapping problems.\n      when declared(nimGC_setStackBottom):\n        nimGC_setStackBottom(locals)\n\n    when not usesDestructors:\n      {.push profiler: off.}\n      var\n        strDesc = TNimType(size: sizeof(string), kind: tyString, flags: {ntfAcyclic})\n      {.pop.}\n\n  {.pop.}\n\n\nwhen not defined(js):\n  # ugly hack, see the accompanying .pop for\n  # the mysterious error message\n  {.push stackTrace: off, profiler: off.}\n\nwhen notJSnotNims:\n  proc zeroMem(p: pointer, size: Natural) =\n    nimZeroMem(p, size)\n    when declared(memTrackerOp):\n      memTrackerOp(\"zeroMem\", p, size)\n  proc copyMem(dest, source: pointer, size: Natural) =\n    nimCopyMem(dest, source, size)\n    when declared(memTrackerOp):\n      memTrackerOp(\"copyMem\", dest, size)\n  proc moveMem(dest, source: pointer, size: Natural) =\n    c_memmove(dest, source, csize_t(size))\n    when declared(memTrackerOp):\n      memTrackerOp(\"moveMem\", dest, size)\n  proc equalMem(a, b: pointer, size: Natural): bool =\n    nimCmpMem(a, b, size) == 0\n  proc cmpMem(a, b: pointer, size: Natural): int =\n    nimCmpMem(a, b, size)\n\nwhen not defined(js):\n  proc cmp(x, y: string): int =\n    when nimvm:\n      if x < y: result = -1\n      elif x > y: result = 1\n      else: result = 0\n    else:\n      when not defined(nimscript): # avoid semantic checking\n        let minlen = min(x.len, y.len)\n        result = int(nimCmpMem(x.cstring, y.cstring, cast[csize_t](minlen)))\n        if result == 0:\n          result = x.len - y.len\n\n  when declared(newSeq):\n    proc cstringArrayToSeq*(a: cstringArray, len: Natural): seq[string] =\n      ## Converts a `cstringArray` to a `seq[string]`. `a` is supposed to be\n      ## of length `len`.\n      newSeq(result, len)\n      for i in 0..len-1: result[i] = $a[i]\n\n    proc cstringArrayToSeq*(a: cstringArray): seq[string] =\n      ## Converts a `cstringArray` to a `seq[string]`. `a` is supposed to be\n      ## terminated by `nil`.\n      var L = 0\n      while a[L] != nil: inc(L)\n      result = cstringArrayToSeq(a, L)\n\n\nwhen not defined(js) and declared(alloc0) and declared(dealloc):\n  proc allocCStringArray*(a: openArray[string]): cstringArray =\n    ## Creates a NULL terminated cstringArray from `a`. The result has to\n    ## be freed with `deallocCStringArray` after it's not needed anymore.\n    result = cast[cstringArray](alloc0((a.len+1) * sizeof(cstring)))\n\n    let x = cast[ptr UncheckedArray[string]](a)\n    for i in 0 .. a.high:\n      result[i] = cast[cstring](alloc0(x[i].len+1))\n      copyMem(result[i], addr(x[i][0]), x[i].len)\n\n  proc deallocCStringArray*(a: cstringArray) =\n    ## Frees a NULL terminated cstringArray.\n    var i = 0\n    while a[i] != nil:\n      dealloc(a[i])\n      inc(i)\n    dealloc(a)\n\nwhen notJSnotNims:\n  type\n    PSafePoint = ptr TSafePoint\n    TSafePoint {.compilerproc, final.} = object\n      prev: PSafePoint # points to next safe point ON THE STACK\n      status: int\n      context: C_JmpBuf\n    SafePoint = TSafePoint\n\nwhen not defined(js):\n  when declared(initAllocator):\n    initAllocator()\n  when hasThreadSupport:\n    when hostOS != \"standalone\": include \"system/threads\"\n  elif not defined(nogc) and not defined(nimscript):\n    when not defined(useNimRtl) and not defined(createNimRtl): initStackBottom()\n    when declared(initGC): initGC()\n\nwhen notJSnotNims:\n  proc setControlCHook*(hook: proc () {.noconv.})\n    ## Allows you to override the behaviour of your application when CTRL+C\n    ## is pressed. Only one such hook is supported.\n\n  when not defined(noSignalHandler) and not defined(useNimRtl):\n    proc unsetControlCHook*()\n      ## Reverts a call to setControlCHook.\n\n  when hostOS != \"standalone\":\n    proc getStackTrace*(): string {.gcsafe.}\n      ## Gets the current stack trace. This only works for debug builds.\n\n    proc getStackTrace*(e: ref Exception): string {.gcsafe.}\n      ## Gets the stack trace associated with `e`, which is the stack that\n      ## lead to the `raise` statement. This only works for debug builds.\n\n  {.push stackTrace: off, profiler: off.}\n  when defined(memtracker):\n    include \"system/memtracker\"\n\n  when hostOS == \"standalone\":\n    include \"system/embedded\"\n  else:\n    include \"system/excpt\"\n  include \"system/chcks\"\n\n  # we cannot compile this with stack tracing on\n  # as it would recurse endlessly!\n  when defined(nimNewIntegerOps):\n    include \"system/integerops\"\n  else:\n    include \"system/arithm\"\n  {.pop.}\n\n\nwhen not defined(js):\n  # this is a hack: without this when statement, you would get:\n  # Error: system module needs: nimGCvisit\n  {.pop.} # stackTrace: off, profiler: off\n\n\n\nwhen notJSnotNims:\n  when hostOS != \"standalone\" and hostOS != \"any\":\n    include \"system/dyncalls\"\n\n  import system/countbits_impl\n  include \"system/sets\"\n\n  when defined(gogc):\n    const GenericSeqSize = (3 * sizeof(int))\n  else:\n    const GenericSeqSize = (2 * sizeof(int))\n\n  proc getDiscriminant(aa: pointer, n: ptr TNimNode): uint =\n    sysAssert(n.kind == nkCase, \"getDiscriminant: node != nkCase\")\n    var d: uint\n    var a = cast[uint](aa)\n    case n.typ.size\n    of 1: d = uint(cast[ptr uint8](a + uint(n.offset))[])\n    of 2: d = uint(cast[ptr uint16](a + uint(n.offset))[])\n    of 4: d = uint(cast[ptr uint32](a + uint(n.offset))[])\n    of 8: d = uint(cast[ptr uint64](a + uint(n.offset))[])\n    else:\n      d = 0'u\n      sysAssert(false, \"getDiscriminant: invalid n.typ.size\")\n    return d\n\n  proc selectBranch(aa: pointer, n: ptr TNimNode): ptr TNimNode =\n    var discr = getDiscriminant(aa, n)\n    if discr < cast[uint](n.len):\n      result = n.sons[discr]\n      if result == nil: result = n.sons[n.len]\n      # n.sons[n.len] contains the `else` part (but may be nil)\n    else:\n      result = n.sons[n.len]\n\nwhen notJSnotNims and hasAlloc:\n  {.push profiler: off.}\n  include \"system/mmdisp\"\n  {.pop.}\n  {.push stackTrace: off, profiler: off.}\n  when not defined(nimSeqsV2):\n    include \"system/sysstr\"\n  {.pop.}\n\n  include \"system/strmantle\"\n  include \"system/assign\"\n\n  when not defined(nimV2):\n    include \"system/repr\"\n\nwhen notJSnotNims and hasThreadSupport and hostOS != \"standalone\":\n  include \"system/channels_builtin\"\n\n\nwhen notJSnotNims and hostOS != \"standalone\":\n  proc getCurrentException*(): ref Exception {.compilerRtl, inl, benign.} =\n    ## Retrieves the current exception; if there is none, `nil` is returned.\n    result = currException\n\n  proc nimBorrowCurrentException(): ref Exception {.compilerRtl, inl, benign, nodestroy.} =\n    # .nodestroy here so that we do not produce a write barrier as the\n    # C codegen only uses it in a borrowed way:\n    result = currException\n\n  proc getCurrentExceptionMsg*(): string {.inline, benign.} =\n    ## Retrieves the error message that was attached to the current\n    ## exception; if there is none, `\"\"` is returned.\n    return if currException == nil: \"\" else: currException.msg\n\n  proc setCurrentException*(exc: ref Exception) {.inline, benign.} =\n    ## Sets the current exception.\n    ##\n    ## .. warning:: Only use this if you know what you are doing.\n    currException = exc\nelif defined(nimscript):\n  proc getCurrentException*(): ref Exception {.compilerRtl.} = discard\n\nwhen notJSnotNims:\n  {.push stackTrace: off, profiler: off.}\n  when (defined(profiler) or defined(memProfiler)):\n    include \"system/profiler\"\n  {.pop.}\n\n  proc rawProc*[T: proc](x: T): pointer {.noSideEffect, inline.} =\n    ## Retrieves the raw proc pointer of the closure `x`. This is\n    ## useful for interfacing closures with C/C++, hash compuations, etc.\n    when T is \"closure\":\n      #[\n      The conversion from function pointer to `void*` is a tricky topic, but this\n      should work at least for c++ >= c++11, e.g. for `dlsym` support.\n      refs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57869,\n      https://stackoverflow.com/questions/14125474/casts-between-pointer-to-function-and-pointer-to-object-in-c-and-c\n      ]#\n      {.emit: \"\"\"\n      `result` = (void*)`x`.ClP_0;\n      \"\"\".}\n    else:\n      {.error: \"Only closure function and iterator are allowed!\".}\n\n  proc rawEnv*[T: proc](x: T): pointer {.noSideEffect, inline.} =\n    ## Retrieves the raw environment pointer of the closure `x`. See also `rawProc`.\n    when T is \"closure\":\n      {.emit: \"\"\"\n      `result` = `x`.ClE_0;\n      \"\"\".}\n    else:\n      {.error: \"Only closure function and iterator are allowed!\".}\n\n  proc finished*[T: proc](x: T): bool {.noSideEffect, inline, magic: \"Finished\".} =\n    ## It can be used to determine if a first class iterator has finished.\n    when T is \"iterator\":\n      {.emit: \"\"\"\n      `result` = ((NI*) `x`.ClE_0)[1] < 0;\n      \"\"\".}\n    else:\n      {.error: \"Only closure iterator is allowed!\".}\n\nfrom std/private/digitsutils import addInt\nexport addInt\n\nwhen defined(js):\n  include \"system/jssys\"\n  include \"system/reprjs\"\n\nproc quit*(errormsg: string, errorcode = QuitFailure) {.noreturn.} =\n  ## A shorthand for `echo(errormsg); quit(errorcode)`.\n  when defined(nimscript) or defined(js) or (hostOS == \"standalone\"):\n    echo errormsg\n  else:\n    when nimvm:\n      echo errormsg\n    else:\n      cstderr.rawWrite(errormsg)\n      cstderr.rawWrite(\"\\n\")\n  quit(errorcode)\n\n{.pop.} # checks: off\n# {.pop.} # hints: off\n\nproc `/`*(x, y: int): float {.inline, noSideEffect.} =\n  ## Division of integers that results in a float.\n  ##\n  ## See also:\n  ## * `div <#div,int,int>`_\n  ## * `mod <#mod,int,int>`_\n  ##\n  ## .. code-block:: Nim\n  ##   echo 7 / 5 # => 1.4\n  result = toFloat(x) / toFloat(y)\n\ntype\n  BackwardsIndex* = distinct int ## Type that is constructed by `^` for\n                                 ## reversed array accesses.\n                                 ## (See `^ template <#^.t,int>`_)\n\ntemplate `^`*(x: int): BackwardsIndex = BackwardsIndex(x)\n  ## Builtin `roof`:idx: operator that can be used for convenient array access.\n  ## `a[^x]` is a shortcut for `a[a.len-x]`.\n  ##\n  ## .. code-block:: Nim\n  ##   let\n  ##     a = [1, 3, 5, 7, 9]\n  ##     b = \"abcdefgh\"\n  ##\n  ##   echo a[^1] # => 9\n  ##   echo b[^2] # => g\n\ntemplate `..^`*(a, b: untyped): untyped =\n  ## A shortcut for `.. ^` to avoid the common gotcha that a space between\n  ## '..' and '^' is required.\n  a .. ^b\n\ntemplate `..<`*(a, b: untyped): untyped =\n  ## A shortcut for `a .. pred(b)`.\n  ##\n  ## .. code-block:: Nim\n  ##   for i in 5 ..< 9:\n  ##     echo i # => 5; 6; 7; 8\n  a .. (when b is BackwardsIndex: succ(b) else: pred(b))\n\ntemplate spliceImpl(s, a, L, b: untyped): untyped =\n  # make room for additional elements or cut:\n  var shift = b.len - max(0,L)  # ignore negative slice size\n  var newLen = s.len + shift\n  if shift > 0:\n    # enlarge:\n    setLen(s, newLen)\n    for i in countdown(newLen-1, a+b.len): movingCopy(s[i], s[i-shift])\n  else:\n    for i in countup(a+b.len, newLen-1): movingCopy(s[i], s[i-shift])\n    # cut down:\n    setLen(s, newLen)\n  # fill the hole:\n  for i in 0 ..< b.len: s[a+i] = b[i]\n\ntemplate `^^`(s, i: untyped): untyped =\n  (when i is BackwardsIndex: s.len - int(i) else: int(i))\n\ntemplate `[]`*(s: string; i: int): char = arrGet(s, i)\ntemplate `[]=`*(s: string; i: int; val: char) = arrPut(s, i, val)\n\nproc `[]`*[T, U: Ordinal](s: string, x: HSlice[T, U]): string {.inline.} =\n  ## Slice operation for strings.\n  ## Returns the inclusive range `[s[x.a], s[x.b]]`:\n  ##\n  ## .. code-block:: Nim\n  ##    var s = \"abcdef\"\n  ##    assert s[1..3] == \"bcd\"\n  let a = s ^^ x.a\n  let L = (s ^^ x.b) - a + 1\n  result = newString(L)\n  for i in 0 ..< L: result[i] = s[i + a]\n\nproc `[]=`*[T, U: Ordinal](s: var string, x: HSlice[T, U], b: string) =\n  ## Slice assignment for strings.\n  ##\n  ## If `b.len` is not exactly the number of elements that are referred to\n  ## by `x`, a `splice`:idx: is performed:\n  ##\n  runnableExamples:\n    var s = \"abcdefgh\"\n    s[1 .. ^2] = \"xyz\"\n    assert s == \"axyzh\"\n\n  var a = s ^^ x.a\n  var L = (s ^^ x.b) - a + 1\n  if L == b.len:\n    for i in 0..<L: s[i+a] = b[i]\n  else:\n    spliceImpl(s, a, L, b)\n\nproc `[]`*[Idx, T; U, V: Ordinal](a: array[Idx, T], x: HSlice[U, V]): seq[T] =\n  ## Slice operation for arrays.\n  ## Returns the inclusive range `[a[x.a], a[x.b]]`:\n  ##\n  ## .. code-block:: Nim\n  ##    var a = [1, 2, 3, 4]\n  ##    assert a[0..2] == @[1, 2, 3]\n  let xa = a ^^ x.a\n  let L = (a ^^ x.b) - xa + 1\n  result = newSeq[T](L)\n  for i in 0..<L: result[i] = a[Idx(i + xa)]\n\nproc `[]=`*[Idx, T; U, V: Ordinal](a: var array[Idx, T], x: HSlice[U, V], b: openArray[T]) =\n  ## Slice assignment for arrays.\n  ##\n  ## .. code-block:: Nim\n  ##   var a = [10, 20, 30, 40, 50]\n  ##   a[1..2] = @[99, 88]\n  ##   assert a == [10, 99, 88, 40, 50]\n  let xa = a ^^ x.a\n  let L = (a ^^ x.b) - xa + 1\n  if L == b.len:\n    for i in 0..<L: a[Idx(i + xa)] = b[i]\n  else:\n    sysFatal(RangeDefect, \"different lengths for slice assignment\")\n\nproc `[]`*[T; U, V: Ordinal](s: openArray[T], x: HSlice[U, V]): seq[T] =\n  ## Slice operation for sequences.\n  ## Returns the inclusive range `[s[x.a], s[x.b]]`:\n  ##\n  ## .. code-block:: Nim\n  ##    var s = @[1, 2, 3, 4]\n  ##    assert s[0..2] == @[1, 2, 3]\n  let a = s ^^ x.a\n  let L = (s ^^ x.b) - a + 1\n  newSeq(result, L)\n  for i in 0 ..< L: result[i] = s[i + a]\n\nproc `[]=`*[T; U, V: Ordinal](s: var seq[T], x: HSlice[U, V], b: openArray[T]) =\n  ## Slice assignment for sequences.\n  ##\n  ## If `b.len` is not exactly the number of elements that are referred to\n  ## by `x`, a `splice`:idx: is performed.\n  runnableExamples:\n    var s = @\"abcdefgh\"\n    s[1 .. ^2] = @\"xyz\"\n    assert s == @\"axyzh\"\n\n  let a = s ^^ x.a\n  let L = (s ^^ x.b) - a + 1\n  if L == b.len:\n    for i in 0 ..< L: s[i+a] = b[i]\n  else:\n    spliceImpl(s, a, L, b)\n\nproc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline.} =\n  system.`[]`(s, s.len - int(i))\n\nproc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline.} =\n  a[Idx(a.len - int(i) + int low(a))]\nproc `[]`*(s: string; i: BackwardsIndex): char {.inline.} = s[s.len - int(i)]\n\nproc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline.} =\n  system.`[]`(s, s.len - int(i))\nproc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline.} =\n  a[Idx(a.len - int(i) + int low(a))]\nproc `[]`*(s: var string; i: BackwardsIndex): var char {.inline.} = s[s.len - int(i)]\n\nproc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline.} =\n  system.`[]=`(s, s.len - int(i), x)\nproc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline.} =\n  a[Idx(a.len - int(i) + int low(a))] = x\nproc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline.} =\n  s[s.len - int(i)] = x\n\nproc slurp*(filename: string): string {.magic: \"Slurp\".}\n  ## This is an alias for `staticRead <#staticRead,string>`_.\n\nproc staticRead*(filename: string): string {.magic: \"Slurp\".}\n  ## Compile-time `readFile <io.html#readFile,string>`_ proc for easy\n  ## `resource`:idx: embedding:\n  ##\n  ## The maximum file size limit that `staticRead` and `slurp` can read is\n  ## near or equal to the *free* memory of the device you are using to compile.\n  ##\n  ## .. code-block:: Nim\n  ##     const myResource = staticRead\"mydatafile.bin\"\n  ##\n  ## `slurp <#slurp,string>`_ is an alias for `staticRead`.\n\nproc gorge*(command: string, input = \"\", cache = \"\"): string {.\n  magic: \"StaticExec\".} = discard\n  ## This is an alias for `staticExec <#staticExec,string,string,string>`_.\n\nproc staticExec*(command: string, input = \"\", cache = \"\"): string {.\n  magic: \"StaticExec\".} = discard\n  ## Executes an external process at compile-time and returns its text output\n  ## (stdout + stderr).\n  ##\n  ## If `input` is not an empty string, it will be passed as a standard input\n  ## to the executed program.\n  ##\n  ## .. code-block:: Nim\n  ##     const buildInfo = \"Revision \" & staticExec(\"git rev-parse HEAD\") &\n  ##                       \"\\nCompiled on \" & staticExec(\"uname -v\")\n  ##\n  ## `gorge <#gorge,string,string,string>`_ is an alias for `staticExec`.\n  ##\n  ## Note that you can use this proc inside a pragma like\n  ## `passc <manual.html#implementation-specific-pragmas-passc-pragma>`_ or\n  ## `passl <manual.html#implementation-specific-pragmas-passl-pragma>`_.\n  ##\n  ## If `cache` is not empty, the results of `staticExec` are cached within\n  ## the `nimcache` directory. Use `--forceBuild` to get rid of this caching\n  ## behaviour then. `command & input & cache` (the concatenated string) is\n  ## used to determine whether the entry in the cache is still valid. You can\n  ## use versioning information for `cache`:\n  ##\n  ## .. code-block:: Nim\n  ##     const stateMachine = staticExec(\"dfaoptimizer\", \"input\", \"0.8.0\")\n\nproc gorgeEx*(command: string, input = \"\", cache = \"\"): tuple[output: string,\n                                                              exitCode: int] =\n  ## Similar to `gorge <#gorge,string,string,string>`_ but also returns the\n  ## precious exit code.\n  discard\n\n\nproc `+=`*[T: float|float32|float64] (x: var T, y: T) {.\n  inline, noSideEffect.} =\n  ## Increments in place a floating point number.\n  x = x + y\n\nproc `-=`*[T: float|float32|float64] (x: var T, y: T) {.\n  inline, noSideEffect.} =\n  ## Decrements in place a floating point number.\n  x = x - y\n\nproc `*=`*[T: float|float32|float64] (x: var T, y: T) {.\n  inline, noSideEffect.} =\n  ## Multiplies in place a floating point number.\n  x = x * y\n\nproc `/=`*(x: var float64, y: float64) {.inline, noSideEffect.} =\n  ## Divides in place a floating point number.\n  x = x / y\n\nproc `/=`*[T: float|float32](x: var T, y: T) {.inline, noSideEffect.} =\n  ## Divides in place a floating point number.\n  x = x / y\n\nproc `&=`*(x: var string, y: string) {.magic: \"AppendStrStr\", noSideEffect.}\n  ## Appends in place to a string.\n  ##\n  ## .. code-block:: Nim\n  ##   var a = \"abc\"\n  ##   a &= \"de\" # a <- \"abcde\"\n\ntemplate `&=`*(x, y: typed) =\n  ## Generic 'sink' operator for Nim.\n  ##\n  ## For files an alias for `write`.\n  ## If not specialized further, an alias for `add`.\n  add(x, y)\nwhen declared(File):\n  template `&=`*(f: File, x: typed) = write(f, x)\n\ntemplate currentSourcePath*: string = instantiationInfo(-1, true).filename\n  ## Returns the full file-system path of the current source.\n  ##\n  ## To get the directory containing the current source, use it with\n  ## `os.parentDir() <os.html#parentDir%2Cstring>`_ as `currentSourcePath.parentDir()`.\n  ##\n  ## The path returned by this template is set at compile time.\n  ##\n  ## See the docstring of `macros.getProjectPath() <macros.html#getProjectPath>`_\n  ## for an example to see the distinction between the `currentSourcePath`\n  ## and `getProjectPath`.\n  ##\n  ## See also:\n  ## * `getCurrentDir proc <os.html#getCurrentDir>`_\n\nwhen compileOption(\"rangechecks\"):\n  template rangeCheck*(cond) =\n    ## Helper for performing user-defined range checks.\n    ## Such checks will be performed only when the `rangechecks`\n    ## compile-time option is enabled.\n    if not cond: sysFatal(RangeDefect, \"range check failed\")\nelse:\n  template rangeCheck*(cond) = discard\n\nproc shallow*[T](s: var seq[T]) {.noSideEffect, inline.} =\n  ## Marks a sequence `s` as `shallow`:idx:. Subsequent assignments will not\n  ## perform deep copies of `s`.\n  ##\n  ## This is only useful for optimization purposes.\n  if s.len == 0: return\n  when not defined(js) and not defined(nimscript) and not defined(nimSeqsV2):\n    var s = cast[PGenericSeq](s)\n    s.reserved = s.reserved or seqShallowFlag\n\nproc shallow*(s: var string) {.noSideEffect, inline.} =\n  ## Marks a string `s` as `shallow`:idx:. Subsequent assignments will not\n  ## perform deep copies of `s`.\n  ##\n  ## This is only useful for optimization purposes.\n  when not defined(js) and not defined(nimscript) and not defined(nimSeqsV2):\n    var s = cast[PGenericSeq](s)\n    if s == nil:\n      s = cast[PGenericSeq](newString(0))\n    # string literals cannot become 'shallow':\n    if (s.reserved and strlitFlag) == 0:\n      s.reserved = s.reserved or seqShallowFlag\n\ntype\n  NimNodeObj = object\n\n  NimNode* {.magic: \"PNimrodNode\".} = ref NimNodeObj\n    ## Represents a Nim AST node. Macros operate on this type.\n\nwhen defined(nimV2):\n  import system/repr_v2\n  export repr_v2\n\nmacro varargsLen*(x: varargs[untyped]): int {.since: (1, 1).} =\n  ## returns number of variadic arguments in `x`\n  proc varargsLenImpl(x: NimNode): NimNode {.magic: \"LengthOpenArray\", noSideEffect.}\n  varargsLenImpl(x)\n\nwhen false:\n  template eval*(blk: typed): typed =\n    ## Executes a block of code at compile time just as if it was a macro.\n    ##\n    ## Optionally, the block can return an AST tree that will replace the\n    ## eval expression.\n    macro payload: typed {.gensym.} = blk\n    payload()\n\nwhen hasAlloc or defined(nimscript):\n  proc insert*(x: var string, item: string, i = 0.Natural) {.noSideEffect.} =\n    ## Inserts `item` into `x` at position `i`.\n    ##\n    ## .. code-block:: Nim\n    ##   var a = \"abc\"\n    ##   a.insert(\"zz\", 0) # a <- \"zzabc\"\n    var xl = x.len\n    setLen(x, xl+item.len)\n    var j = xl-1\n    while j >= i:\n      shallowCopy(x[j+item.len], x[j])\n      dec(j)\n    j = 0\n    while j < item.len:\n      x[j+i] = item[j]\n      inc(j)\n\nwhen declared(initDebugger):\n  initDebugger()\n\nproc addEscapedChar*(s: var string, c: char) {.noSideEffect, inline.} =\n  ## Adds a char to string `s` and applies the following escaping:\n  ##\n  ## * replaces any ``\\`` by `\\\\`\n  ## * replaces any `'` by `\\'`\n  ## * replaces any `\"` by `\\\"`\n  ## * replaces any `\\a` by `\\\\a`\n  ## * replaces any `\\b` by `\\\\b`\n  ## * replaces any `\\t` by `\\\\t`\n  ## * replaces any `\\n` by `\\\\n`\n  ## * replaces any `\\v` by `\\\\v`\n  ## * replaces any `\\f` by `\\\\f`\n  ## * replaces any `\\r` by `\\\\r`\n  ## * replaces any `\\e` by `\\\\e`\n  ## * replaces any other character not in the set `{\\21..\\126}`\n  ##   by `\\xHH` where `HH` is its hexadecimal value\n  ##\n  ## The procedure has been designed so that its output is usable for many\n  ## different common syntaxes.\n  ##\n  ## .. warning:: This is **not correct** for producing ANSI C code!\n  ##\n  case c\n  of '\\a': s.add \"\\\\a\" # \\x07\n  of '\\b': s.add \"\\\\b\" # \\x08\n  of '\\t': s.add \"\\\\t\" # \\x09\n  of '\\n': s.add \"\\\\n\" # \\x0A\n  of '\\v': s.add \"\\\\v\" # \\x0B\n  of '\\f': s.add \"\\\\f\" # \\x0C\n  of '\\r': (when defined(nimLegacyAddEscapedCharx0D): s.add \"\\\\c\" else: s.add \"\\\\r\") # \\x0D\n  of '\\e': s.add \"\\\\e\" # \\x1B\n  of '\\\\': s.add(\"\\\\\\\\\")\n  of '\\'': s.add(\"\\\\'\")\n  of '\\\"': s.add(\"\\\\\\\"\")\n  of {'\\32'..'\\126'} - {'\\\\', '\\'', '\\\"'}: s.add(c)\n  else:\n    s.add(\"\\\\x\")\n    const HexChars = \"0123456789ABCDEF\"\n    let n = ord(c)\n    s.add(HexChars[int((n and 0xF0) shr 4)])\n    s.add(HexChars[int(n and 0xF)])\n\nproc addQuoted*[T](s: var string, x: T) =\n  ## Appends `x` to string `s` in place, applying quoting and escaping\n  ## if `x` is a string or char.\n  ##\n  ## See `addEscapedChar <#addEscapedChar,string,char>`_\n  ## for the escaping scheme. When `x` is a string, characters in the\n  ## range `{\\128..\\255}` are never escaped so that multibyte UTF-8\n  ## characters are untouched (note that this behavior is different from\n  ## `addEscapedChar`).\n  ##\n  ## The Nim standard library uses this function on the elements of\n  ## collections when producing a string representation of a collection.\n  ## It is recommended to use this function as well for user-side collections.\n  ## Users may overload `addQuoted` for custom (string-like) types if\n  ## they want to implement a customized element representation.\n  ##\n  ## .. code-block:: Nim\n  ##   var tmp = \"\"\n  ##   tmp.addQuoted(1)\n  ##   tmp.add(\", \")\n  ##   tmp.addQuoted(\"string\")\n  ##   tmp.add(\", \")\n  ##   tmp.addQuoted('c')\n  ##   assert(tmp == \"\"\"1, \"string\", 'c'\"\"\")\n  when T is string or T is cstring:\n    s.add(\"\\\"\")\n    for c in x:\n      # Only ASCII chars are escaped to avoid butchering\n      # multibyte UTF-8 characters.\n      if c <= 127.char:\n        s.addEscapedChar(c)\n      else:\n        s.add c\n    s.add(\"\\\"\")\n  elif T is char:\n    s.add(\"'\")\n    s.addEscapedChar(x)\n    s.add(\"'\")\n  # prevent temporary string allocation\n  elif T is SomeInteger:\n    s.addInt(x)\n  elif T is SomeFloat:\n    s.addFloat(x)\n  elif compiles(s.add(x)):\n    s.add(x)\n  else:\n    s.add($x)\n\nproc locals*(): RootObj {.magic: \"Plugin\", noSideEffect.} =\n  ## Generates a tuple constructor expression listing all the local variables\n  ## in the current scope.\n  ##\n  ## This is quite fast as it does not rely\n  ## on any debug or runtime information. Note that in contrast to what\n  ## the official signature says, the return type is *not* `RootObj` but a\n  ## tuple of a structure that depends on the current scope. Example:\n  ##\n  ## .. code-block:: Nim\n  ##   proc testLocals() =\n  ##     var\n  ##       a = \"something\"\n  ##       b = 4\n  ##       c = locals()\n  ##       d = \"super!\"\n  ##\n  ##     b = 1\n  ##     for name, value in fieldPairs(c):\n  ##       echo \"name \", name, \" with value \", value\n  ##     echo \"B is \", b\n  ##   # -> name a with value something\n  ##   # -> name b with value 4\n  ##   # -> B is 1\n  discard\n\nwhen hasAlloc and notJSnotNims:\n  # XXX how to implement 'deepCopy' is an open problem.\n  proc deepCopy*[T](x: var T, y: T) {.noSideEffect, magic: \"DeepCopy\".} =\n    ## Performs a deep copy of `y` and copies it into `x`.\n    ##\n    ## This is also used by the code generator\n    ## for the implementation of `spawn`.\n    ##\n    ## For `--gc:arc` or `--gc:orc` deepcopy support has to be enabled\n    ## via `--deepcopy:on`.\n    discard\n\n  proc deepCopy*[T](y: T): T =\n    ## Convenience wrapper around `deepCopy` overload.\n    deepCopy(result, y)\n\n  include \"system/deepcopy\"\n\nproc procCall*(x: untyped) {.magic: \"ProcCall\", compileTime.} =\n  ## Special magic to prohibit dynamic binding for `method`:idx: calls.\n  ## This is similar to `super`:idx: in ordinary OO languages.\n  ##\n  ## .. code-block:: Nim\n  ##   # 'someMethod' will be resolved fully statically:\n  ##   procCall someMethod(a, b)\n  discard\n\n\nproc `==`*(x, y: cstring): bool {.magic: \"EqCString\", noSideEffect,\n                                   inline.} =\n  ## Checks for equality between two `cstring` variables.\n  proc strcmp(a, b: cstring): cint {.noSideEffect,\n    importc, header: \"<string.h>\".}\n  if pointer(x) == pointer(y): result = true\n  elif x.isNil or y.isNil: result = false\n  else: result = strcmp(x, y) == 0\n\nwhen true: # xxx PRTEMP remove\n  # bug #9149; ensure that 'typeof(nil)' does not match *too* well by using 'typeof(nil) | typeof(nil)',\n  # especially for converters, see tests/overload/tconverter_to_string.nim\n  # Eventually we will be able to remove this hack completely.\n  proc `==`*(x: string; y: typeof(nil) | typeof(nil)): bool {.\n      error: \"'nil' is now invalid for 'string'\".} =\n    discard\n  proc `==`*(x: typeof(nil) | typeof(nil); y: string): bool {.\n      error: \"'nil' is now invalid for 'string'\".} =\n    discard\n\ntemplate closureScope*(body: untyped): untyped =\n  ## Useful when creating a closure in a loop to capture local loop variables by\n  ## their current iteration values.\n  ##\n  ## Note: This template may not work in some cases, use\n  ## `capture <sugar.html#capture.m,varargs[typed],untyped>`_ instead.\n  ##\n  ## Example:\n  ##\n  ## .. code-block:: Nim\n  ##   var myClosure : proc()\n  ##   # without closureScope:\n  ##   for i in 0 .. 5:\n  ##     let j = i\n  ##     if j == 3:\n  ##       myClosure = proc() = echo j\n  ##   myClosure() # outputs 5. `j` is changed after closure creation\n  ##   # with closureScope:\n  ##   for i in 0 .. 5:\n  ##     closureScope: # Everything in this scope is locked after closure creation\n  ##       let j = i\n  ##       if j == 3:\n  ##         myClosure = proc() = echo j\n  ##   myClosure() # outputs 3\n  (proc() = body)()\n\ntemplate once*(body: untyped): untyped =\n  ## Executes a block of code only once (the first time the block is reached).\n  ##\n  ## .. code-block:: Nim\n  ##\n  ##  proc draw(t: Triangle) =\n  ##    once:\n  ##      graphicsInit()\n  ##    line(t.p1, t.p2)\n  ##    line(t.p2, t.p3)\n  ##    line(t.p3, t.p1)\n  ##\n  var alreadyExecuted {.global.} = false\n  if not alreadyExecuted:\n    alreadyExecuted = true\n    body\n\n{.pop.} # warning[GcMem]: off, warning[Uninit]: off\n\nproc substr*(s: string, first, last: int): string =\n  ## Copies a slice of `s` into a new string and returns this new\n  ## string.\n  ##\n  ## The bounds `first` and `last` denote the indices of\n  ## the first and last characters that shall be copied. If `last`\n  ## is omitted, it is treated as `high(s)`. If `last >= s.len`, `s.len`\n  ## is used instead: This means `substr` can also be used to `cut`:idx:\n  ## or `limit`:idx: a string's length.\n  runnableExamples:\n    let a = \"abcdefgh\"\n    assert a.substr(2, 5) == \"cdef\"\n    assert a.substr(2) == \"cdefgh\"\n    assert a.substr(5, 99) == \"fgh\"\n\n  let first = max(first, 0)\n  let L = max(min(last, high(s)) - first + 1, 0)\n  result = newString(L)\n  for i in 0 .. L-1:\n    result[i] = s[i+first]\n\nproc substr*(s: string, first = 0): string =\n  result = substr(s, first, high(s))\n\nwhen defined(nimconfig):\n  include \"system/nimscript\"\n\nwhen not defined(js):\n  proc toOpenArray*[T](x: ptr UncheckedArray[T]; first, last: int): openArray[T] {.\n    magic: \"Slice\".}\n  when defined(nimToOpenArrayCString):\n    proc toOpenArray*(x: cstring; first, last: int): openArray[char] {.\n      magic: \"Slice\".}\n    proc toOpenArrayByte*(x: cstring; first, last: int): openArray[byte] {.\n      magic: \"Slice\".}\n\nproc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {.\n  magic: \"Slice\".}\nproc toOpenArray*[T](x: openArray[T]; first, last: int): openArray[T] {.\n  magic: \"Slice\".}\nproc toOpenArray*[I, T](x: array[I, T]; first, last: I): openArray[T] {.\n  magic: \"Slice\".}\nproc toOpenArray*(x: string; first, last: int): openArray[char] {.\n  magic: \"Slice\".}\n\nproc toOpenArrayByte*(x: string; first, last: int): openArray[byte] {.\n  magic: \"Slice\".}\nproc toOpenArrayByte*(x: openArray[char]; first, last: int): openArray[byte] {.\n  magic: \"Slice\".}\nproc toOpenArrayByte*(x: seq[char]; first, last: int): openArray[byte] {.\n  magic: \"Slice\".}\n\ntype\n  ForLoopStmt* {.compilerproc.} = object ## \\\n    ## A special type that marks a macro as a `for-loop macro`:idx:.\n    ## See `\"For Loop Macro\" <manual.html#macros-for-loop-macro>`_.\n\nwhen defined(genode):\n  var componentConstructHook*: proc (env: GenodeEnv) {.nimcall.}\n    ## Hook into the Genode component bootstrap process.\n    ##\n    ## This hook is called after all globals are initialized.\n    ## When this hook is set the component will not automatically exit,\n    ## call `quit` explicitly to do so. This is the only available method\n    ## of accessing the initial Genode environment.\n\n  proc nim_component_construct(env: GenodeEnv) {.exportc.} =\n    ## Procedure called during `Component::construct` by the loader.\n    if componentConstructHook.isNil:\n      env.quit(programResult)\n        # No native Genode application initialization,\n        # exit as would POSIX.\n    else:\n      componentConstructHook(env)\n        # Perform application initialization\n        # and return to thread entrypoint.\n\n\nimport system/widestrs\nexport widestrs\n\nimport system/io\nexport io\n\nwhen not defined(createNimHcr) and not defined(nimscript):\n  include nimhcr\n\nwhen notJSnotNims and not defined(nimSeqsV2):\n  proc prepareMutation*(s: var string) {.inline.} =\n    ## String literals (e.g. \"abc\", etc) in the ARC/ORC mode are \"copy on write\",\n    ## therefore you should call `prepareMutation` before modifying the strings\n    ## via `addr`.\n    runnableExamples(\"--gc:arc\"):\n      var x = \"abc\"\n      var y = \"defgh\"\n      prepareMutation(y) # without this, you may get a `SIGBUS` or `SIGSEGV`\n      moveMem(addr y[0], addr x[0], x.len)\n      assert y == \"abcgh\"\n    discard\n"}}}
Got frame:
{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///home/maskray/Dev/Nim/lib/system.nim","languageId":"nim","version":1,"text":"#\n#\n#            Nim's Runtime Library\n#        (c) Copyright 2015 Andreas Rumpf\n#\n#    See the file \"copying.txt\", included in this\n#    distribution, for details about the copyright.\n#\n\n\n## The compiler depends on the System module to work properly and the System\n## module depends on the compiler. Most of the routines listed here use\n## special compiler magic.\n##\n## Each module implicitly imports the System module; it must not be listed\n## explicitly. Because of this there cannot be a user-defined module named\n## `system`.\n##\n## System module\n## =============\n##\n## .. include:: ./system_overview.rst\n\n\ntype\n  float* {.magic: Float.}     ## Default floating point type.\n  float32* {.magic: Float32.} ## 32 bit floating point type.\n  float64* {.magic: Float.}   ## 64 bit floating point type.\n\n# 'float64' is now an alias to 'float'; this solves many problems\n\ntype\n  char* {.magic: Char.}         ## Built-in 8 bit character type (unsigned).\n  string* {.magic: String.}     ## Built-in string type.\n  cstring* {.magic: Cstring.}   ## Built-in cstring (*compatible string*) type.\n  pointer* {.magic: Pointer.}   ## Built-in pointer type, use the `addr`\n                                ## operator to get a pointer to a variable.\n\n  typedesc* {.magic: TypeDesc.} ## Meta type to denote a type description.\n\ntype\n  `ptr`*[T] {.magic: Pointer.}   ## Built-in generic untraced pointer type.\n  `ref`*[T] {.magic: Pointer.}   ## Built-in generic traced pointer type.\n\n  `nil` {.magic: \"Nil\".}\n\n  void* {.magic: \"VoidType\".}    ## Meta type to denote the absence of any type.\n  auto* {.magic: Expr.}          ## Meta type for automatic type determination.\n  any* {.deprecated: \"Deprecated since v1.5; Use auto instead.\".} = distinct auto  ## Deprecated; Use `auto` instead. See https://github.com/nim-lang/RFCs/issues/281\n  untyped* {.magic: Expr.}       ## Meta type to denote an expression that\n                                 ## is not resolved (for templates).\n  typed* {.magic: Stmt.}         ## Meta type to denote an expression that\n                                 ## is resolved (for templates).\n\ninclude \"system/basic_types\"\n\n\nproc runnableExamples*(rdoccmd = \"\", body: untyped) {.magic: \"RunnableExamples\".} =\n  ## A section you should use to mark `runnable example`:idx: code with.\n  ##\n  ## - In normal debug and release builds code within\n  ##   a `runnableExamples` section is ignored.\n  ## - The documentation generator is aware of these examples and considers them\n  ##   part of the `##` doc comment. As the last step of documentation\n  ##   generation each runnableExample is put in its own file `$file_examples$i.nim`,\n  ##   compiled and tested. The collected examples are\n  ##   put into their own module to ensure the examples do not refer to\n  ##   non-exported symbols.\n  runnableExamples:\n    proc timesTwo*(x: int): int =\n      ## This proc doubles a number.\n      runnableExamples:\n        # at module scope\n        const exported* = 123\n        assert timesTwo(5) == 10\n        block: # at block scope\n          defer: echo \"done\"\n      runnableExamples \"-d:foo -b:cpp\":\n        import std/compilesettings\n        assert querySetting(backend) == \"cpp\"\n        assert defined(foo)\n      runnableExamples \"-r:off\": ## this one is only compiled\n         import std/browsers\n         openDefaultBrowser \"https://forum.nim-lang.org/\"\n      2 * x\n\nproc compileOption*(option: string): bool {.\n  magic: \"CompileOption\", noSideEffect.} =\n  ## Can be used to determine an `on|off` compile-time option.\n  ##\n  ## See also:\n  ## * `compileOption <#compileOption,string,string>`_ for enum options\n  ## * `defined <#defined,untyped>`_\n  ## * `std/compilesettings module <compilesettings.html>`_\n  runnableExamples(\"--floatChecks:off\"):\n    static: doAssert not compileOption(\"floatchecks\")\n    {.push floatChecks: on.}\n    static: doAssert compileOption(\"floatchecks\")\n    # floating point NaN and Inf checks enabled in this scope\n    {.pop.}\n\nproc compileOption*(option, arg: string): bool {.\n  magic: \"CompileOptionArg\", noSideEffect.} =\n  ## Can be used to determine an enum compile-time option.\n  ##\n  ## See also:\n  ## * `compileOption <#compileOption,string>`_ for `on|off` options\n  ## * `defined <#defined,untyped>`_\n  ## * `std/compilesettings module <compilesettings.html>`_\n  runnableExamples:\n    when compileOption(\"opt\", \"size\") and compileOption(\"gc\", \"boehm\"):\n      discard \"compiled with optimization for size and uses Boehm's GC\"\n\n{.push warning[GcMem]: off, warning[Uninit]: off.}\n# {.push hints: off.}\n\nproc `or`*(a, b: typedesc): typedesc {.magic: \"TypeTrait\", noSideEffect.}\n  ## Constructs an `or` meta class.\n\nproc `and`*(a, b: typedesc): typedesc {.magic: \"TypeTrait\", noSideEffect.}\n  ## Constructs an `and` meta class.\n\nproc `not`*(a: typedesc): typedesc {.magic: \"TypeTrait\", noSideEffect.}\n  ## Constructs an `not` meta class.\n\n\ntype\n  SomeFloat* = float|float32|float64\n    ## Type class matching all floating point number types.\n\n  SomeNumber* = SomeInteger|SomeFloat\n    ## Type class matching all number types.\n\nproc defined*(x: untyped): bool {.magic: \"Defined\", noSideEffect, compileTime.}\n  ## Special compile-time procedure that checks whether `x` is\n  ## defined.\n  ##\n  ## See also:\n  ## * `compileOption <#compileOption,string>`_ for `on|off` options\n  ## * `compileOption <#compileOption,string,string>`_ for enum options\n  ## * `define pragmas <manual.html#implementation-specific-pragmas-compileminustime-define-pragmas>`_\n  ##\n  ## `x` is an external symbol introduced through the compiler's\n  ## `-d:x switch <nimc.html#compiler-usage-compileminustime-symbols>`_ to enable\n  ## build time conditionals:\n  ##\n  ## .. code-block:: Nim\n  ##   when not defined(release):\n  ##     # Do here programmer friendly expensive sanity checks.\n  ##   # Put here the normal code\n\nwhen defined(nimHasIterable):\n  type\n    iterable*[T] {.magic: IterableType.}  ## Represents an expression that yields `T`\n\nwhen defined(nimHashOrdinalFixed):\n  type\n    Ordinal*[T] {.magic: Ordinal.} ## Generic ordinal type. Includes integer,\n                                   ## bool, character, and enumeration types\n                                   ## as well as their subtypes. See also\n                                   ## `SomeOrdinal`.\nelse:\n  # bootstrap < 1.2.0\n  type\n    OrdinalImpl[T] {.magic: Ordinal.}\n    Ordinal* = OrdinalImpl | uint | uint64\n\nwhen defined(nimHasDeclaredMagic):\n  proc declared*(x: untyped): bool {.magic: \"Declared\", noSideEffect, compileTime.}\n    ## Special compile-time procedure that checks whether `x` is\n    ## declared. `x` has to be an identifier or a qualified identifier.\n    ##\n    ## See also:\n    ## * `declaredInScope <#declaredInScope,untyped>`_\n    ##\n    ## This can be used to check whether a library provides a certain\n    ## feature or not:\n    ##\n    ## .. code-block:: Nim\n    ##   when not declared(strutils.toUpper):\n    ##     # provide our own toUpper proc here, because strutils is\n    ##     # missing it.\nelse:\n  proc declared*(x: untyped): bool {.magic: \"Defined\", noSideEffect, compileTime.}\n\nwhen defined(nimHasDeclaredMagic):\n  proc declaredInScope*(x: untyped): bool {.magic: \"DeclaredInScope\", noSideEffect, compileTime.}\n    ## Special compile-time procedure that checks whether `x` is\n    ## declared in the current scope. `x` has to be an identifier.\nelse:\n  proc declaredInScope*(x: untyped): bool {.magic: \"DefinedInScope\", noSideEffect, compileTime.}\n\nproc `addr`*[T](x: var T): ptr T {.magic: \"Addr\", noSideEffect.} =\n  ## Builtin `addr` operator for taking the address of a memory location.\n  ## Cannot be overloaded.\n  ##\n  ## See also:\n  ## * `unsafeAddr <#unsafeAddr,T>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var\n  ##    buf: seq[char] = @['a','b','c']\n  ##    p = buf[1].addr\n  ##  echo p.repr # ref 0x7faa35c40059 --> 'b'\n  ##  echo p[]    # b\n  discard\n\nproc unsafeAddr*[T](x: T): ptr T {.magic: \"Addr\", noSideEffect.} =\n  ## Builtin `addr` operator for taking the address of a memory\n  ## location. This works even for `let` variables or parameters\n  ## for better interop with C and so it is considered even more\n  ## unsafe than the ordinary `addr <#addr,T>`_.\n  ##\n  ## **Note**: When you use it to write a wrapper for a C library, you should\n  ## always check that the original library does never write to data behind the\n  ## pointer that is returned from this procedure.\n  ##\n  ## Cannot be overloaded.\n  discard\n\ntype\n  `static`*[T] {.magic: \"Static\".}\n    ## Meta type representing all values that can be evaluated at compile-time.\n    ##\n    ## The type coercion `static(x)` can be used to force the compile-time\n    ## evaluation of the given expression `x`.\n\n  `type`*[T] {.magic: \"Type\".}\n    ## Meta type representing the type of all type values.\n    ##\n    ## The coercion `type(x)` can be used to obtain the type of the given\n    ## expression `x`.\n\ntype\n  TypeOfMode* = enum ## Possible modes of `typeof`.\n    typeOfProc,      ## Prefer the interpretation that means `x` is a proc call.\n    typeOfIter       ## Prefer the interpretation that means `x` is an iterator call.\n\nproc typeof*(x: untyped; mode = typeOfIter): typedesc {.\n  magic: \"TypeOf\", noSideEffect, compileTime.} =\n  ## Builtin `typeof` operation for accessing the type of an expression.\n  ## Since version 0.20.0.\n  runnableExamples:\n    proc myFoo(): float = 0.0\n    iterator myFoo(): string = yield \"abc\"\n    iterator myFoo2(): string = yield \"abc\"\n    iterator myFoo3(): string {.closure.} = yield \"abc\"\n    doAssert type(myFoo()) is string\n    doAssert typeof(myFoo()) is string\n    doAssert typeof(myFoo(), typeOfIter) is string\n    doAssert typeof(myFoo3) is \"iterator\"\n\n    doAssert typeof(myFoo(), typeOfProc) is float\n    doAssert typeof(0.0, typeOfProc) is float\n    doAssert typeof(myFoo3, typeOfProc) is \"iterator\"\n    doAssert not compiles(typeof(myFoo2(), typeOfProc))\n      # this would give: Error: attempting to call routine: 'myFoo2'\n      # since `typeOfProc` expects a typed expression and `myFoo2()` can\n      # only be used in a `for` context.\n\nconst ThisIsSystem = true\n\nproc internalNew*[T](a: var ref T) {.magic: \"New\", noSideEffect.}\n  ## Leaked implementation detail. Do not use.\n\nwhen true:\n  proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.\n    magic: \"NewFinalize\", noSideEffect.}\n    ## Creates a new object of type `T` and returns a safe (traced)\n    ## reference to it in `a`.\n    ##\n    ## When the garbage collector frees the object, `finalizer` is called.\n    ## The `finalizer` may not keep a reference to the\n    ## object pointed to by `x`. The `finalizer` cannot prevent the GC from\n    ## freeing the object.\n    ##\n    ## **Note**: The `finalizer` refers to the type `T`, not to the object!\n    ## This means that for each object of type `T` the finalizer will be called!\n\nproc wasMoved*[T](obj: var T) {.magic: \"WasMoved\", noSideEffect.} =\n  ## Resets an object `obj` to its initial (binary zero) value to signify\n  ## it was \"moved\" and to signify its destructor should do nothing and\n  ## ideally be optimized away.\n  discard\n\nproc move*[T](x: var T): T {.magic: \"Move\", noSideEffect.} =\n  result = x\n  wasMoved(x)\n\ntype\n  range*[T]{.magic: \"Range\".}         ## Generic type to construct range types.\n  array*[I, T]{.magic: \"Array\".}      ## Generic type to construct\n                                      ## fixed-length arrays.\n  openArray*[T]{.magic: \"OpenArray\".} ## Generic type to construct open arrays.\n                                      ## Open arrays are implemented as a\n                                      ## pointer to the array data and a\n                                      ## length field.\n  varargs*[T]{.magic: \"Varargs\".}     ## Generic type to construct a varargs type.\n  seq*[T]{.magic: \"Seq\".}             ## Generic type to construct sequences.\n  set*[T]{.magic: \"Set\".}             ## Generic type to construct bit sets.\n\ntype\n  UncheckedArray*[T]{.magic: \"UncheckedArray\".}\n  ## Array with no bounds checking.\n\ntype sink*[T]{.magic: \"BuiltinType\".}\ntype lent*[T]{.magic: \"BuiltinType\".}\n\nproc high*[T: Ordinal|enum|range](x: T): T {.magic: \"High\", noSideEffect,\n  deprecated: \"Deprecated since v1.4; there should not be `high(value)`. Use `high(type)`.\".}\n  ## Returns the highest possible value of an ordinal value `x`.\n  ##\n  ## As a special semantic rule, `x` may also be a type identifier.\n  ##\n  ## **This proc is deprecated**, use this one instead:\n  ## * `high(typedesc) <#high,typedesc[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  high(2) # => 9223372036854775807\n\nproc high*[T: Ordinal|enum|range](x: typedesc[T]): T {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible value of an ordinal or enum type.\n  ##\n  ## `high(int)` is Nim's way of writing `INT_MAX`:idx: or `MAX_INT`:idx:.\n  ##\n  ## See also:\n  ## * `low(typedesc) <#low,typedesc[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  high(int) # => 9223372036854775807\n\nproc high*[T](x: openArray[T]): int {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible index of a sequence `x`.\n  ##\n  ## See also:\n  ## * `low(openArray) <#low,openArray[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var s = @[1, 2, 3, 4, 5, 6, 7]\n  ##  high(s) # => 6\n  ##  for i in low(s)..high(s):\n  ##    echo s[i]\n\nproc high*[I, T](x: array[I, T]): I {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible index of an array `x`.\n  ##\n  ## For empty arrays, the return type is `int`.\n  ##\n  ## See also:\n  ## * `low(array) <#low,array[I,T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var arr = [1, 2, 3, 4, 5, 6, 7]\n  ##  high(arr) # => 6\n  ##  for i in low(arr)..high(arr):\n  ##    echo arr[i]\n\nproc high*[I, T](x: typedesc[array[I, T]]): I {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible index of an array type.\n  ##\n  ## For empty arrays, the return type is `int`.\n  ##\n  ## See also:\n  ## * `low(typedesc[array]) <#low,typedesc[array[I,T]]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  high(array[7, int]) # => 6\n\nproc high*(x: cstring): int {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible index of a compatible string `x`.\n  ## This is sometimes an O(n) operation.\n  ##\n  ## See also:\n  ## * `low(cstring) <#low,cstring>`_\n\nproc high*(x: string): int {.magic: \"High\", noSideEffect.}\n  ## Returns the highest possible index of a string `x`.\n  ##\n  ## See also:\n  ## * `low(string) <#low,string>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var str = \"Hello world!\"\n  ##  high(str) # => 11\n\nproc low*[T: Ordinal|enum|range](x: T): T {.magic: \"Low\", noSideEffect,\n  deprecated: \"Deprecated since v1.4; there should not be `low(value)`. Use `low(type)`.\".}\n  ## Returns the lowest possible value of an ordinal value `x`. As a special\n  ## semantic rule, `x` may also be a type identifier.\n  ##\n  ## **This proc is deprecated**, use this one instead:\n  ## * `low(typedesc) <#low,typedesc[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  low(2) # => -9223372036854775808\n\nproc low*[T: Ordinal|enum|range](x: typedesc[T]): T {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible value of an ordinal or enum type.\n  ##\n  ## `low(int)` is Nim's way of writing `INT_MIN`:idx: or `MIN_INT`:idx:.\n  ##\n  ## See also:\n  ## * `high(typedesc) <#high,typedesc[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  low(int) # => -9223372036854775808\n\nproc low*[T](x: openArray[T]): int {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible index of a sequence `x`.\n  ##\n  ## See also:\n  ## * `high(openArray) <#high,openArray[T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var s = @[1, 2, 3, 4, 5, 6, 7]\n  ##  low(s) # => 0\n  ##  for i in low(s)..high(s):\n  ##    echo s[i]\n\nproc low*[I, T](x: array[I, T]): I {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible index of an array `x`.\n  ##\n  ## For empty arrays, the return type is `int`.\n  ##\n  ## See also:\n  ## * `high(array) <#high,array[I,T]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var arr = [1, 2, 3, 4, 5, 6, 7]\n  ##  low(arr) # => 0\n  ##  for i in low(arr)..high(arr):\n  ##    echo arr[i]\n\nproc low*[I, T](x: typedesc[array[I, T]]): I {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible index of an array type.\n  ##\n  ## For empty arrays, the return type is `int`.\n  ##\n  ## See also:\n  ## * `high(typedesc[array]) <#high,typedesc[array[I,T]]>`_\n  ##\n  ## .. code-block:: Nim\n  ##  low(array[7, int]) # => 0\n\nproc low*(x: cstring): int {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible index of a compatible string `x`.\n  ##\n  ## See also:\n  ## * `high(cstring) <#high,cstring>`_\n\nproc low*(x: string): int {.magic: \"Low\", noSideEffect.}\n  ## Returns the lowest possible index of a string `x`.\n  ##\n  ## See also:\n  ## * `high(string) <#high,string>`_\n  ##\n  ## .. code-block:: Nim\n  ##  var str = \"Hello world!\"\n  ##  low(str) # => 0\n\nproc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: \"ShallowCopy\".}\n  ## Use this instead of `=` for a `shallow copy`:idx:.\n  ##\n  ## The shallow copy only changes the semantics for sequences and strings\n  ## (and types which contain those).\n  ##\n  ## Be careful with the changed semantics though!\n  ## There is a reason why the default assignment does a deep copy of sequences\n  ## and strings.\n\n# :array|openArray|string|seq|cstring|tuple\nproc `[]`*[I: Ordinal;T](a: T; i: I): T {.\n  noSideEffect, magic: \"ArrGet\".}\nproc `[]=`*[I: Ordinal;T,S](a: T; i: I;\n  x: sink S) {.noSideEffect, magic: \"ArrPut\".}\nproc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: \"Asgn\".}\nproc `=copy`*[T](dest: var T; src: T) {.noSideEffect, magic: \"Asgn\".}\n\nproc arrGet[I: Ordinal;T](a: T; i: I): T {.\n  noSideEffect, magic: \"ArrGet\".}\nproc arrPut[I: Ordinal;T,S](a: T; i: I;\n  x: S) {.noSideEffect, magic: \"ArrPut\".}\n\nproc `=destroy`*[T](x: var T) {.inline, magic: \"Destroy\".} =\n  ## Generic `destructor`:idx: implementation that can be overridden.\n  discard\nproc `=sink`*[T](x: var T; y: T) {.inline, magic: \"Asgn\".} =\n  ## Generic `sink`:idx: implementation that can be overridden.\n  shallowCopy(x, y)\n\nwhen defined(nimHasTrace):\n  proc `=trace`*[T](x: var T; env: pointer) {.inline, magic: \"Trace\".} =\n    ## Generic `trace`:idx: implementation that can be overridden.\n    discard\n\ntype\n  HSlice*[T, U] = object   ## \"Heterogeneous\" slice type.\n    a*: T                  ## The lower bound (inclusive).\n    b*: U                  ## The upper bound (inclusive).\n  Slice*[T] = HSlice[T, T] ## An alias for `HSlice[T, T]`.\n\nproc `..`*[T, U](a: sink T, b: sink U): HSlice[T, U] {.noSideEffect, inline, magic: \"DotDot\".} =\n  ## Binary `slice`:idx: operator that constructs an interval `[a, b]`, both `a`\n  ## and `b` are inclusive.\n  ##\n  ## Slices can also be used in the set constructor and in ordinal case\n  ## statements, but then they are special-cased by the compiler.\n  ##\n  ## .. code-block:: Nim\n  ##   let a = [10, 20, 30, 40, 50]\n  ##   echo a[2 .. 3] # @[30, 40]\n  result = HSlice[T, U](a: a, b: b)\n\nproc `..`*[T](b: sink T): HSlice[int, T]\n  {.noSideEffect, inline, magic: \"DotDot\", deprecated: \"replace `..b` with `0..b`\".} =\n  ## Unary `slice`:idx: operator that constructs an interval `[default(int), b]`.\n  ##\n  ## .. code-block:: Nim\n  ##   let a = [10, 20, 30, 40, 50]\n  ##   echo a[.. 2] # @[10, 20, 30]\n  result = HSlice[int, T](a: 0, b: b)\n\nwhen defined(hotCodeReloading):\n  {.pragma: hcrInline, inline.}\nelse:\n  {.pragma: hcrInline.}\n\n{.push profiler: off.}\nlet nimvm* {.magic: \"Nimvm\", compileTime.}: bool = false\n  ## May be used only in `when` expression.\n  ## It is true in Nim VM context and false otherwise.\n{.pop.}\n\ninclude \"system/arithmetics\"\ninclude \"system/comparisons\"\n\nconst\n  appType* {.magic: \"AppType\".}: string = \"\"\n    ## A string that describes the application type. Possible values:\n    ## `\"console\"`, `\"gui\"`, `\"lib\"`.\n\ninclude \"system/inclrtl\"\n\nconst NoFakeVars = defined(nimscript) ## `true` if the backend doesn't support \\\n  ## \"fake variables\" like `var EBADF {.importc.}: cint`.\n\nconst notJSnotNims = not defined(js) and not defined(nimscript)\n\nwhen not defined(js) and not defined(nimSeqsV2):\n  type\n    TGenericSeq {.compilerproc, pure, inheritable.} = object\n      len, reserved: int\n      when defined(gogc):\n        elemSize: int\n        elemAlign: int\n    PGenericSeq {.exportc.} = ptr TGenericSeq\n    # len and space without counting the terminating zero:\n    NimStringDesc {.compilerproc, final.} = object of TGenericSeq\n      data: UncheckedArray[char]\n    NimString = ptr NimStringDesc\n\nwhen notJSnotNims and not defined(nimSeqsV2):\n  template space(s: PGenericSeq): int {.dirty.} =\n    s.reserved and not (seqShallowFlag or strlitFlag)\n\nwhen notJSnotNims:\n  include \"system/hti\"\n\ntype\n  byte* = uint8 ## This is an alias for `uint8`, that is an unsigned\n                ## integer, 8 bits wide.\n\n  Natural* = range[0..high(int)]\n    ## is an `int` type ranging from zero to the maximum value\n    ## of an `int`. This type is often useful for documentation and debugging.\n\n  Positive* = range[1..high(int)]\n    ## is an `int` type ranging from one to the maximum value\n    ## of an `int`. This type is often useful for documentation and debugging.\n\n  RootObj* {.compilerproc, inheritable.} =\n    object ## The root of Nim's object hierarchy.\n           ##\n           ## Objects should inherit from `RootObj` or one of its descendants.\n           ## However, objects that have no ancestor are also allowed.\n  RootRef* = ref RootObj ## Reference to `RootObj`.\n\n\ninclude \"system/exceptions\"\n\nwhen defined(js) or defined(nimdoc):\n  type\n    JsRoot* = ref object of RootObj\n      ## Root type of the JavaScript object hierarchy\n\nproc unsafeNew*[T](a: var ref T, size: Natural) {.magic: \"New\", noSideEffect.}\n  ## Creates a new object of type `T` and returns a safe (traced)\n  ## reference to it in `a`.\n  ##\n  ## This is **unsafe** as it allocates an object of the passed `size`.\n  ## This should only be used for optimization purposes when you know\n  ## what you're doing!\n  ##\n  ## See also:\n  ## * `new <#new,ref.T,proc(ref.T)>`_\n\nproc sizeof*[T](x: T): int {.magic: \"SizeOf\", noSideEffect.}\n  ## Returns the size of `x` in bytes.\n  ##\n  ## Since this is a low-level proc,\n  ## its usage is discouraged - using `new <#new,ref.T,proc(ref.T)>`_ for\n  ## the most cases suffices that one never needs to know `x`'s size.\n  ##\n  ## As a special semantic rule, `x` may also be a type identifier\n  ## (`sizeof(int)` is valid).\n  ##\n  ## Limitations: If used for types that are imported from C or C++,\n  ## sizeof should fallback to the `sizeof` in the C compiler. The\n  ## result isn't available for the Nim compiler and therefore can't\n  ## be used inside of macros.\n  ##\n  ## .. code-block:: Nim\n  ##  sizeof('A') # => 1\n  ##  sizeof(2) # => 8\n\nproc alignof*[T](x: T): int {.magic: \"AlignOf\", noSideEffect.}\nproc alignof*(x: typedesc): int {.magic: \"AlignOf\", noSideEffect.}\n\nproc offsetOfDotExpr(typeAccess: typed): int {.magic: \"OffsetOf\", noSideEffect, compileTime.}\n\ntemplate offsetOf*[T](t: typedesc[T]; member: untyped): int =\n  var tmp {.noinit.}: ptr T\n  offsetOfDotExpr(tmp[].member)\n\ntemplate offsetOf*[T](value: T; member: untyped): int =\n  offsetOfDotExpr(value.member)\n\n#proc offsetOf*(memberaccess: typed): int {.magic: \"OffsetOf\", noSideEffect.}\n\nproc sizeof*(x: typedesc): int {.magic: \"SizeOf\", noSideEffect.}\n\n\nproc newSeq*[T](s: var seq[T], len: Natural) {.magic: \"NewSeq\", noSideEffect.}\n  ## Creates a new sequence of type `seq[T]` with length `len`.\n  ##\n  ## This is equivalent to `s = @[]; setlen(s, len)`, but more\n  ## efficient since no reallocation is needed.\n  ##\n  ## Note that the sequence will be filled with zeroed entries.\n  ## After the creation of the sequence you should assign entries to\n  ## the sequence instead of adding them. Example:\n  ##\n  ## .. code-block:: Nim\n  ##   var inputStrings: seq[string]\n  ##   newSeq(inputStrings, 3)\n  ##   assert len(inputStrings) == 3\n  ##   inputStrings[0] = \"The fourth\"\n  ##   inputStrings[1] = \"assignment\"\n  ##   inputStrings[2] = \"would crash\"\n  ##   #inputStrings[3] = \"out of bounds\"\n\nproc newSeq*[T](len = 0.Natural): seq[T] =\n  ## Creates a new sequence of type `seq[T]` with length `len`.\n  ##\n  ## Note that the sequence will be filled with zeroed entries.\n  ## After the creation of the sequence you should assign entries to\n  ## the sequence instead of adding them.\n  ##\n  ## See also:\n  ## * `newSeqOfCap <#newSeqOfCap,Natural>`_\n  ## * `newSeqUninitialized <#newSeqUninitialized,Natural>`_\n  ##\n  ## .. code-block:: Nim\n  ##   var inputStrings = newSeq[string](3)\n  ##   assert len(inputStrings) == 3\n  ##   inputStrings[0] = \"The fourth\"\n  ##   inputStrings[1] = \"assignment\"\n  ##   inputStrings[2] = \"would crash\"\n  ##   #inputStrings[3] = \"out of bounds\"\n  newSeq(result, len)\n\nproc newSeqOfCap*[T](cap: Natural): seq[T] {.\n  magic: \"NewSeqOfCap\", noSideEffect.} =\n  ## Creates a new sequence of type `seq[T]` with length zero and capacity\n  ## `cap`.\n  ##\n  ## .. code-block:: Nim\n  ##   var x = newSeqOfCap[int](5)\n  ##   assert len(x) == 0\n  ##   x.add(10)\n  ##   assert len(x) == 1\n  discard\n\nwhen not defined(js):\n  proc newSeqUninitialized*[T: SomeNumber](len: Natural): seq[T] =\n    ## Creates a new sequence of type `seq[T]` with length `len`.\n    ##\n    ## Only available for numbers types. Note that the sequence will be\n    ## uninitialized. After the creation of the sequence you should assign\n    ## entries to the sequence instead of adding them.\n    ##\n    ## .. code-block:: Nim\n    ##   var x = newSeqUninitialized[int](3)\n    ##   assert len(x) == 3\n    ##   x[0] = 10\n    result = newSeqOfCap[T](len)\n    when defined(nimSeqsV2):\n      cast[ptr int](addr result)[] = len\n    else:\n      var s = cast[PGenericSeq](result)\n      s.len = len\n\nfunc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {.magic: \"LengthOpenArray\".} =\n  ## Returns the length of an openArray.\n  runnableExamples:\n    proc bar[T](a: openArray[T]): int = len(a)\n    assert bar([1,2]) == 2\n    assert [1,2].len == 2\n\nfunc len*(x: string): int {.magic: \"LengthStr\".} =\n  ## Returns the length of a string.\n  runnableExamples:\n    assert \"abc\".len == 3\n    assert \"\".len == 0\n    assert string.default.len == 0\n\nproc len*(x: cstring): int {.magic: \"LengthStr\", noSideEffect.} =\n  ## Returns the length of a compatible string. This is an O(n) operation except\n  ## in js at runtime.\n  ##\n  ## **Note:** On the JS backend this currently counts UTF-16 code points\n  ## instead of bytes at runtime (not at compile time). For now, if you\n  ## need the byte length of the UTF-8 encoding, convert to string with\n  ## `$` first then call `len`.\n  runnableExamples:\n    doAssert len(cstring\"abc\") == 3\n    doAssert len(cstring r\"ab\\0c\") == 5 # \\0 is escaped\n    doAssert len(cstring\"ab\\0c\") == 5 # ditto\n    var a: cstring = \"ab\\0c\"\n    when defined(js): doAssert a.len == 4 # len ignores \\0 for js\n    else: doAssert a.len == 2 # \\0 is a null terminator\n    static:\n      var a2: cstring = \"ab\\0c\"\n      doAssert a2.len == 2 # \\0 is a null terminator, even in js vm\n\nfunc len*(x: (type array)|array): int {.magic: \"LengthArray\".} =\n  ## Returns the length of an array or an array type.\n  ## This is roughly the same as `high(T)-low(T)+1`.\n  runnableExamples:\n    var a = [1, 1, 1]\n    assert a.len == 3\n    assert array[0, float].len == 0\n    static: assert array[-2..2, float].len == 5\n\nfunc len*[T](x: seq[T]): int {.magic: \"LengthSeq\".} =\n  ## Returns the length of `x`.\n  runnableExamples:\n    assert @[0, 1].len == 2\n    assert seq[int].default.len == 0\n    assert newSeq[int](3).len == 3\n    let s = newSeqOfCap[int](3)\n    assert s.len == 0\n  # xxx this gives cgen error: assert newSeqOfCap[int](3).len == 0\n\nfunc ord*[T: Ordinal|enum](x: T): int {.magic: \"Ord\".} =\n  ## Returns the internal `int` value of `x`, including for enum with holes\n  ## and distinct ordinal types.\n  runnableExamples:\n    assert ord('A') == 65\n    type Foo = enum\n      f0 = 0, f1 = 3\n    assert f1.ord == 3\n    type Bar = distinct int\n    assert 3.Bar.ord == 3\n\nfunc chr*(u: range[0..255]): char {.magic: \"Chr\".} =\n  ## Converts `u` to a `char`, same as `char(u)`.\n  runnableExamples:\n    doAssert chr(65) == 'A'\n    doAssert chr(255) == '\\255'\n    doAssert chr(255) == char(255)\n    doAssert not compiles chr(256)\n    doAssert not compiles char(256)\n    var x = 256\n    doAssertRaises(RangeDefect): discard chr(x)\n    doAssertRaises(RangeDefect): discard char(x)\n\n# floating point operations:\nproc `+`*(x: float32): float32 {.magic: \"UnaryPlusF64\", noSideEffect.}\nproc `-`*(x: float32): float32 {.magic: \"UnaryMinusF64\", noSideEffect.}\nproc `+`*(x, y: float32): float32 {.magic: \"AddF64\", noSideEffect.}\nproc `-`*(x, y: float32): float32 {.magic: \"SubF64\", noSideEffect.}\nproc `*`*(x, y: float32): float32 {.magic: \"MulF64\", noSideEffect.}\nproc `/`*(x, y: float32): float32 {.magic: \"DivF64\", noSideEffect.}\n\nproc `+`*(x: float): float {.magic: \"UnaryPlusF64\", noSideEffect.}\nproc `-`*(x: float): float {.magic: \"UnaryMinusF64\", noSideEffect.}\nproc `+`*(x, y: float): float {.magic: \"AddF64\", noSideEffect.}\nproc `-`*(x, y: float): float {.magic: \"SubF64\", noSideEffect.}\nproc `*`*(x, y: float): float {.magic: \"MulF64\", noSideEffect.}\nproc `/`*(x, y: float): float {.magic: \"DivF64\", noSideEffect.}\n\nproc `==`*(x, y: float32): bool {.magic: \"EqF64\", noSideEffect.}\nproc `<=`*(x, y: float32): bool {.magic: \"LeF64\", noSideEffect.}\nproc `<`  *(x, y: float32): bool {.magic: \"LtF64\", noSideEffect.}\n\nproc `==`*(x, y: float): bool {.magic: \"EqF64\", noSideEffect.}\nproc `<=`*(x, y: float): bool {.magic: \"LeF64\", noSideEffect.}\nproc `<`*(x, y: float): bool {.magic: \"LtF64\", noSideEffect.}\n\n\ninclude \"system/setops\"\n\n\nproc contains*[U, V, W](s: HSlice[U, V], value: W): bool {.noSideEffect, inline.} =\n  ## Checks if `value` is within the range of `s`; returns true if\n  ## `value >= s.a and value <= s.b`\n  ##\n  ## .. code-block:: Nim\n  ##   assert((1..3).contains(1) == true)\n  ##   assert((1..3).contains(2) == true)\n  ##   assert((1..3).contains(4) == false)\n  result = s.a <= value and value <= s.b\n\ntemplate `in`*(x, y: untyped): untyped {.dirty.} = contains(y, x)\n  ## Sugar for `contains`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert(1 in (1..3) == true)\n  ##   assert(5 in (1..3) == false)\ntemplate `notin`*(x, y: untyped): untyped {.dirty.} = not contains(y, x)\n  ## Sugar for `not contains`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert(1 notin (1..3) == false)\n  ##   assert(5 notin (1..3) == true)\n\nproc `is`*[T, S](x: T, y: S): bool {.magic: \"Is\", noSideEffect.}\n  ## Checks if `T` is of the same type as `S`.\n  ##\n  ## For a negated version, use `isnot <#isnot.t,untyped,untyped>`_.\n  ##\n  ## .. code-block:: Nim\n  ##   assert 42 is int\n  ##   assert @[1, 2] is seq\n  ##\n  ##   proc test[T](a: T): int =\n  ##     when (T is int):\n  ##       return a\n  ##     else:\n  ##       return 0\n  ##\n  ##   assert(test[int](3) == 3)\n  ##   assert(test[string](\"xyz\") == 0)\ntemplate `isnot`*(x, y: untyped): untyped = not (x is y)\n  ## Negated version of `is <#is,T,S>`_. Equivalent to `not(x is y)`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert 42 isnot float\n  ##   assert @[1, 2] isnot enum\n\nwhen (defined(nimOwnedEnabled) and not defined(nimscript)) or defined(nimFixedOwned):\n  type owned*[T]{.magic: \"BuiltinType\".} ## type constructor to mark a ref/ptr or a closure as `owned`.\nelse:\n  template owned*(t: typedesc): typedesc = t\n\nwhen defined(nimOwnedEnabled) and not defined(nimscript):\n  proc new*[T](a: var owned(ref T)) {.magic: \"New\", noSideEffect.}\n    ## Creates a new object of type `T` and returns a safe (traced)\n    ## reference to it in `a`.\n\n  proc new*(t: typedesc): auto =\n    ## Creates a new object of type `T` and returns a safe (traced)\n    ## reference to it as result value.\n    ##\n    ## When `T` is a ref type then the resulting type will be `T`,\n    ## otherwise it will be `ref T`.\n    when (t is ref):\n      var r: owned t\n    else:\n      var r: owned(ref t)\n    new(r)\n    return r\n\n  proc unown*[T](x: T): T {.magic: \"Unown\", noSideEffect.}\n    ## Use the expression `x` ignoring its ownership attribute.\n\n\nelse:\n  template unown*(x: typed): untyped = x\n\n  proc new*[T](a: var ref T) {.magic: \"New\", noSideEffect.}\n    ## Creates a new object of type `T` and returns a safe (traced)\n    ## reference to it in `a`.\n\n  proc new*(t: typedesc): auto =\n    ## Creates a new object of type `T` and returns a safe (traced)\n    ## reference to it as result value.\n    ##\n    ## When `T` is a ref type then the resulting type will be `T`,\n    ## otherwise it will be `ref T`.\n    when (t is ref):\n      var r: t\n    else:\n      var r: ref t\n    new(r)\n    return r\n\n\ntemplate disarm*(x: typed) =\n  ## Useful for `disarming` dangling pointers explicitly for `--newruntime`.\n  ## Regardless of whether `--newruntime` is used or not\n  ## this sets the pointer or callback `x` to `nil`. This is an\n  ## experimental API!\n  x = nil\n\nproc `of`*[T, S](x: T, y: typedesc[S]): bool {.magic: \"Of\", noSideEffect.} =\n  ## Checks if `x` is an instance of `y`.\n  runnableExamples:\n    type\n      Base = ref object of RootObj\n      Sub1 = ref object of Base\n      Sub2 = ref object of Base\n      Unrelated = ref object\n\n    var base: Base = Sub1() # downcast\n    doAssert base of Base # generates `CondTrue` (statically true)\n    doAssert base of Sub1\n    doAssert base isnot Sub1\n    doAssert not (base of Sub2)\n\n    base = Sub2() # re-assign\n    doAssert base of Sub2\n    doAssert Sub2(base) != nil # upcast\n    doAssertRaises(ObjectConversionDefect): discard Sub1(base)\n\n    var sub1 = Sub1()\n    doAssert sub1 of Base\n    doAssert sub1.Base of Sub1\n\n    doAssert not compiles(base of Unrelated)\n\nproc cmp*[T](x, y: T): int =\n  ## Generic compare proc.\n  ##\n  ## Returns:\n  ## * a value less than zero, if `x < y`\n  ## * a value greater than zero, if `x > y`\n  ## * zero, if `x == y`\n  ##\n  ## This is useful for writing generic algorithms without performance loss.\n  ## This generic implementation uses the `==` and `<` operators.\n  ##\n  ## .. code-block:: Nim\n  ##  import std/algorithm\n  ##  echo sorted(@[4, 2, 6, 5, 8, 7], cmp[int])\n  if x == y: return 0\n  if x < y: return -1\n  return 1\n\nproc cmp*(x, y: string): int {.noSideEffect.}\n  ## Compare proc for strings. More efficient than the generic version.\n  ##\n  ## **Note**: The precise result values depend on the used C runtime library and\n  ## can differ between operating systems!\n\nproc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.magic: \"ArrToSeq\", noSideEffect.}\n  ## Turns an array into a sequence.\n  ##\n  ## This most often useful for constructing\n  ## sequences with the array constructor: `@[1, 2, 3]` has the type\n  ## `seq[int]`, while `[1, 2, 3]` has the type `array[0..2, int]`.\n  ##\n  ## .. code-block:: Nim\n  ##   let\n  ##     a = [1, 3, 5]\n  ##     b = \"foo\"\n  ##\n  ##   echo @a # => @[1, 3, 5]\n  ##   echo @b # => @['f', 'o', 'o']\n\nproc default*[T](_: typedesc[T]): T {.magic: \"Default\", noSideEffect.} =\n  ## returns the default value of the type `T`.\n  runnableExamples:\n    assert (int, float).default == (0, 0.0)\n    # note: `var a = default(T)` is usually the same as `var a: T` and (currently) generates\n    # a value whose binary representation is all 0, regardless of whether this\n    # would violate type constraints such as `range`, `not nil`, etc. This\n    # property is required to implement certain algorithms efficiently which\n    # may require intermediate invalid states.\n    type Foo = object\n      a: range[2..6]\n    var a1: range[2..6] # currently, this compiles\n    # var a2: Foo # currently, this errors: Error: The Foo type doesn't have a default value.\n    # var a3 = Foo() # ditto\n    var a3 = Foo.default # this works, but generates a `UnsafeDefault` warning.\n  # note: the doc comment also explains why `default` can't be implemented\n  # via: `template default*[T](t: typedesc[T]): T = (var v: T; v)`\n\nproc reset*[T](obj: var T) {.noSideEffect.} =\n  ## Resets an object `obj` to its default value.\n  obj = default(typeof(obj))\n\nproc setLen*[T](s: var seq[T], newlen: Natural) {.\n  magic: \"SetLengthSeq\", noSideEffect.}\n  ## Sets the length of seq `s` to `newlen`. `T` may be any sequence type.\n  ##\n  ## If the current length is greater than the new length,\n  ## `s` will be truncated.\n  ##\n  ## .. code-block:: Nim\n  ##   var x = @[10, 20]\n  ##   x.setLen(5)\n  ##   x[4] = 50\n  ##   assert x == @[10, 20, 0, 0, 50]\n  ##   x.setLen(1)\n  ##   assert x == @[10]\n\nproc setLen*(s: var string, newlen: Natural) {.\n  magic: \"SetLengthStr\", noSideEffect.}\n  ## Sets the length of string `s` to `newlen`.\n  ##\n  ## If the current length is greater than the new length,\n  ## `s` will be truncated.\n  ##\n  ## .. code-block:: Nim\n  ##  var myS = \"Nim is great!!\"\n  ##  myS.setLen(3) # myS <- \"Nim\"\n  ##  echo myS, \" is fantastic!!\"\n\nproc newString*(len: Natural): string {.\n  magic: \"NewString\", importc: \"mnewString\", noSideEffect.}\n  ## Returns a new string of length `len` but with uninitialized\n  ## content. One needs to fill the string character after character\n  ## with the index operator `s[i]`.\n  ##\n  ## This procedure exists only for optimization purposes;\n  ## the same effect can be achieved with the `&` operator or with `add`.\n\nproc newStringOfCap*(cap: Natural): string {.\n  magic: \"NewStringOfCap\", importc: \"rawNewString\", noSideEffect.}\n  ## Returns a new string of length `0` but with capacity `cap`.\n  ##\n  ## This procedure exists only for optimization purposes; the same effect can\n  ## be achieved with the `&` operator or with `add`.\n\nproc `&`*(x: string, y: char): string {.\n  magic: \"ConStrStr\", noSideEffect, merge.}\n  ## Concatenates `x` with `y`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert(\"ab\" & 'c' == \"abc\")\nproc `&`*(x, y: char): string {.\n  magic: \"ConStrStr\", noSideEffect, merge.}\n  ## Concatenates characters `x` and `y` into a string.\n  ##\n  ## .. code-block:: Nim\n  ##   assert('a' & 'b' == \"ab\")\nproc `&`*(x, y: string): string {.\n  magic: \"ConStrStr\", noSideEffect, merge.}\n  ## Concatenates strings `x` and `y`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert(\"ab\" & \"cd\" == \"abcd\")\nproc `&`*(x: char, y: string): string {.\n  magic: \"ConStrStr\", noSideEffect, merge.}\n  ## Concatenates `x` with `y`.\n  ##\n  ## .. code-block:: Nim\n  ##   assert('a' & \"bc\" == \"abc\")\n\n# implementation note: These must all have the same magic value \"ConStrStr\" so\n# that the merge optimization works properly.\n\nproc add*(x: var string, y: char) {.magic: \"AppendStrCh\", noSideEffect.}\n  ## Appends `y` to `x` in place.\n  ##\n  ## .. code-block:: Nim\n  ##   var tmp = \"\"\n  ##   tmp.add('a')\n  ##   tmp.add('b')\n  ##   assert(tmp == \"ab\")\n\nproc add*(x: var string, y: string) {.magic: \"AppendStrStr\", noSideEffect.} =\n  ## Concatenates `x` and `y` in place.\n  ##\n  ## See also `strbasics.add`.\n  runnableExamples:\n    var tmp = \"\"\n    tmp.add(\"ab\")\n    tmp.add(\"cd\")\n    assert tmp == \"abcd\"\n\ntype\n  Endianness* = enum ## Type describing the endianness of a processor.\n    littleEndian, bigEndian\n\nconst\n  isMainModule* {.magic: \"IsMainModule\".}: bool = false\n    ## True only when accessed in the main module. This works thanks to\n    ## compiler magic. It is useful to embed testing code in a module.\n\n  CompileDate* {.magic: \"CompileDate\".}: string = \"0000-00-00\"\n    ## The date (in UTC) of compilation as a string of the form\n    ## `YYYY-MM-DD`. This works thanks to compiler magic.\n\n  CompileTime* {.magic: \"CompileTime\".}: string = \"00:00:00\"\n    ## The time (in UTC) of compilation as a string of the form\n    ## `HH:MM:SS`. This works thanks to compiler magic.\n\n  cpuEndian* {.magic: \"CpuEndian\".}: Endianness = littleEndian\n    ## The endianness of the target CPU. This is a valuable piece of\n    ## information for low-level code only. This works thanks to compiler\n    ## magic.\n\n  hostOS* {.magic: \"HostOS\".}: string = \"\"\n    ## A string that describes the host operating system.\n    ##\n    ## Possible values:\n    ## `\"windows\"`, `\"macosx\"`, `\"linux\"`, `\"netbsd\"`, `\"freebsd\"`,\n    ## `\"openbsd\"`, `\"solaris\"`, `\"aix\"`, `\"haiku\"`, `\"standalone\"`.\n\n  hostCPU* {.magic: \"HostCPU\".}: string = \"\"\n    ## A string that describes the host CPU.\n    ##\n    ## Possible values:\n    ## `\"i386\"`, `\"alpha\"`, `\"powerpc\"`, `\"powerpc64\"`, `\"powerpc64el\"`,\n    ## `\"sparc\"`, `\"amd64\"`, `\"mips\"`, `\"mipsel\"`, `\"arm\"`, `\"arm64\"`,\n    ## `\"mips64\"`, `\"mips64el\"`, `\"riscv32\"`, `\"riscv64\"`.\n\n  seqShallowFlag = low(int)\n  strlitFlag = 1 shl (sizeof(int)*8 - 2) # later versions of the codegen \\\n  # emit this flag\n  # for string literals, it allows for some optimizations.\n\nconst\n  hasThreadSupport = compileOption(\"threads\") and not defined(nimscript)\n  hasSharedHeap = defined(boehmgc) or defined(gogc) # don't share heaps; every thread has its own\n\nwhen hasThreadSupport and defined(tcc) and not compileOption(\"tlsEmulation\"):\n  # tcc doesn't support TLS\n  {.error: \"`--tlsEmulation:on` must be used when using threads with tcc backend\".}\n\nwhen defined(boehmgc):\n  when defined(windows):\n    when sizeof(int) == 8:\n      const boehmLib = \"boehmgc64.dll\"\n    else:\n      const boehmLib = \"boehmgc.dll\"\n  elif defined(macosx):\n    const boehmLib = \"libgc.dylib\"\n  elif defined(openbsd):\n    const boehmLib = \"libgc.so.(4|5).0\"\n  elif defined(freebsd):\n    const boehmLib = \"libgc-threaded.so.1\"\n  else:\n    const boehmLib = \"libgc.so.1\"\n  {.pragma: boehmGC, noconv, dynlib: boehmLib.}\n\ntype TaintedString* {.deprecated: \"Deprecated since 1.5\".} = string\n\n\nwhen defined(profiler) and not defined(nimscript):\n  proc nimProfile() {.compilerproc, noinline.}\nwhen hasThreadSupport:\n  {.pragma: rtlThreadVar, threadvar.}\nelse:\n  {.pragma: rtlThreadVar.}\n\nconst\n  QuitSuccess* = 0\n    ## is the value that should be passed to `quit <#quit,int>`_ to indicate\n    ## success.\n\n  QuitFailure* = 1\n    ## is the value that should be passed to `quit <#quit,int>`_ to indicate\n    ## failure.\n\nwhen not defined(js) and hostOS != \"standalone\":\n  var programResult* {.compilerproc, exportc: \"nim_program_result\".}: int\n    ## deprecated, prefer `quit` or `exitprocs.getProgramResult`, `exitprocs.setProgramResult`.\n\nimport std/private/since\n\nproc align(address, alignment: int): int =\n  if alignment == 0: # Actually, this is illegal. This branch exists to actively\n                     # hide problems.\n    result = address\n  else:\n    result = (address + (alignment - 1)) and not (alignment - 1)\n\nwhen defined(nimdoc):\n  proc quit*(errorcode: int = QuitSuccess) {.magic: \"Exit\", noreturn.}\n    ## Stops the program immediately with an exit code.\n    ##\n    ## Before stopping the program the \"exit procedures\" are called in the\n    ## opposite order they were added with `addExitProc <exitprocs.html#addExitProc,proc)>`_.\n    ##\n    ## The proc `quit(QuitSuccess)` is called implicitly when your nim\n    ## program finishes without incident for platforms where this is the\n    ## expected behavior. A raised unhandled exception is\n    ## equivalent to calling `quit(QuitFailure)`.\n    ##\n    ## Note that this is a *runtime* call and using `quit` inside a macro won't\n    ## have any compile time effect. If you need to stop the compiler inside a\n    ## macro, use the `error <manual.html#pragmas-error-pragma>`_ or `fatal\n    ## <manual.html#pragmas-fatal-pragma>`_ pragmas.\n    ##\n    ## .. danger:: In almost all cases, in particular in library code, prefer\n    ##   alternatives, e.g. `doAssert false` or raise a `Defect`.\n    ##   `quit` bypasses regular control flow in particular `defer`,\n    ##   `try`, `catch`, `finally` and `destructors`, and exceptions that may have been\n    ##   raised by an `addExitProc` proc, as well as cleanup code in other threads.\n    ##   It does *not* call the garbage collector to free all the memory,\n    ##   unless an `addExitProc` proc calls `GC_fullCollect <#GC_fullCollect>`_.\n\nelif defined(genode):\n  include genode/env\n\n  var systemEnv {.exportc: runtimeEnvSym.}: GenodeEnvPtr\n\n  type GenodeEnv* = GenodeEnvPtr\n    ## Opaque type representing Genode environment.\n\n  proc quit*(env: GenodeEnv; errorcode: int) {.magic: \"Exit\", noreturn,\n    importcpp: \"#->parent().exit(@); Genode::sleep_forever()\", header: \"<base/sleep.h>\".}\n\n  proc quit*(errorcode: int = QuitSuccess) =\n    systemEnv.quit(errorcode)\n\nelif defined(js) and defined(nodejs) and not defined(nimscript):\n  proc quit*(errorcode: int = QuitSuccess) {.magic: \"Exit\",\n    importc: \"process.exit\", noreturn.}\n\nelse:\n  proc quit*(errorcode: int = QuitSuccess) {.\n    magic: \"Exit\", importc: \"exit\", header: \"<stdlib.h>\", noreturn.}\n\n\ntemplate sysAssert(cond: bool, msg: string) =\n  when defined(useSysAssert):\n    if not cond:\n      cstderr.rawWrite \"[SYSASSERT] \"\n      cstderr.rawWrite msg\n      cstderr.rawWrite \"\\n\"\n      quit 1\n\nconst hasAlloc = (hostOS != \"standalone\" or not defined(nogc)) and not defined(nimscript)\n\nwhen notJSnotNims and hostOS != \"standalone\" and hostOS != \"any\":\n  include \"system/cgprocs\"\nwhen notJSnotNims and hasAlloc and not defined(nimSeqsV2):\n  proc addChar(s: NimString, c: char): NimString {.compilerproc, benign.}\n\nwhen defined(nimscript) or not defined(nimSeqsV2):\n  proc add*[T](x: var seq[T], y: sink T) {.magic: \"AppendSeqElem\", noSideEffect.}\n    ## Generic proc for adding a data item `y` to a container `x`.\n    ##\n    ## For containers that have an order, `add` means *append*. New generic\n    ## containers should also call their adding proc `add` for consistency.\n    ## Generic code becomes much easier to write if the Nim naming scheme is\n    ## respected.\n\nwhen false: # defined(gcDestructors):\n  proc add*[T](x: var seq[T], y: sink openArray[T]) {.noSideEffect.} =\n    ## Generic proc for adding a container `y` to a container `x`.\n    ##\n    ## For containers that have an order, `add` means *append*. New generic\n    ## containers should also call their adding proc `add` for consistency.\n    ## Generic code becomes much easier to write if the Nim naming scheme is\n    ## respected.\n    ##\n    ## See also:\n    ## * `& proc <#&,seq[T],seq[T]>`_\n    ##\n    ## .. code-block:: Nim\n    ##   var s: seq[string] = @[\"test2\",\"test2\"]\n    ##   s.add(\"test\") # s <- @[test2, test2, test]\n    {.noSideEffect.}:\n      let xl = x.len\n      setLen(x, xl + y.len)\n      for i in 0..high(y):\n        when nimvm:\n          # workaround the fact that the VM does not yet\n          # handle sink parameters properly:\n          x[xl+i] = y[i]\n        else:\n          x[xl+i] = move y[i]\nelse:\n  proc add*[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} =\n    ## Generic proc for adding a container `y` to a container `x`.\n    ##\n    ## For containers that have an order, `add` means *append*. New generic\n    ## containers should also call their adding proc `add` for consistency.\n    ## Generic code becomes much easier to write if the Nim naming scheme is\n    ## respected.\n    ##\n    ## See also:\n    ## * `& proc <#&,seq[T],seq[T]>`_\n    ##\n    ## .. code-block:: Nim\n    ##   var s: seq[string] = @[\"test2\",\"test2\"]\n    ##   s.add(\"test\") # s <- @[test2, test2, test]\n    {.noSideEffect.}:\n      let xl = x.len\n      setLen(x, xl + y.len)\n      for i in 0..high(y): x[xl+i] = y[i]\n\n\nwhen defined(nimSeqsV2):\n  template movingCopy(a, b) =\n    a = move(b)\nelse:\n  template movingCopy(a, b) =\n    shallowCopy(a, b)\n\nproc del*[T](x: var seq[T], i: Natural) {.noSideEffect.} =\n  ## Deletes the item at index `i` by putting `x[high(x)]` into position `i`.\n  ##\n  ## This is an `O(1)` operation.\n  ##\n  ## See also:\n  ## * `delete <#delete,seq[T],Natural>`_ for preserving the order\n  runnableExamples:\n    var a = @[10, 11, 12, 13, 14]\n    a.del(2)\n    assert a == @[10, 11, 14, 13]\n  let xl = x.len - 1\n  movingCopy(x[i], x[xl])\n  setLen(x, xl)\n\nproc insert*[T](x: var seq[T], item: sink T, i = 0.Natural) {.noSideEffect.} =\n  ## Inserts `item` into `x` at position `i`.\n  ##\n  ## .. code-block:: Nim\n  ##  var i = @[1, 3, 5]\n  ##  i.insert(99, 0) # i <- @[99, 1, 3, 5]\n  {.noSideEffect.}:\n    template defaultImpl =\n      let xl = x.len\n      setLen(x, xl+1)\n      var j = xl-1\n      while j >= i:\n        movingCopy(x[j+1], x[j])\n        dec(j)\n    when nimvm:\n      defaultImpl()\n    else:\n      when defined(js):\n        var it : T\n        {.emit: \"`x` = `x` || []; `x`.splice(`i`, 0, `it`);\".}\n      else:\n        defaultImpl()\n    x[i] = item\n\nwhen not defined(nimV2):\n  proc repr*[T](x: T): string {.magic: \"Repr\", noSideEffect.}\n    ## Takes any Nim variable and returns its string representation.\n    ## No trailing newline is inserted (so `echo` won't add an empty newline).\n    ## Use `-d:nimLegacyReprWithNewline` to revert to old behavior where newlines\n    ## were added in some cases.\n    ##\n    ## It works even for complex data graphs with cycles. This is a great\n    ## debugging tool.\n    ##\n    ## .. code-block:: Nim\n    ##  var s: seq[string] = @[\"test2\", \"test2\"]\n    ##  var i = @[1, 2, 3, 4, 5]\n    ##  echo repr(s) # => 0x1055eb050[0x1055ec050\"test2\", 0x1055ec078\"test2\"]\n    ##  echo repr(i) # => 0x1055ed050[1, 2, 3, 4, 5]\n\ntype\n  ByteAddress* = int\n    ## is the signed integer type that should be used for converting\n    ## pointers to integer addresses for readability.\n\n  BiggestFloat* = float64\n    ## is an alias for the biggest floating point type the Nim\n    ## compiler supports. Currently this is `float64`, but it is\n    ## platform-dependent in general.\n\nwhen defined(js):\n  type BiggestUInt* = uint32\n    ## is an alias for the biggest unsigned integer type the Nim compiler\n    ## supports. Currently this is `uint32` for JS and `uint64` for other\n    ## targets.\nelse:\n  type BiggestUInt* = uint64\n    ## is an alias for the biggest unsigned integer type the Nim compiler\n    ## supports. Currently this is `uint32` for JS and `uint64` for other\n    ## targets.\n\nwhen defined(windows):\n  type\n    clong* {.importc: \"long\", nodecl.} = int32\n      ## This is the same as the type `long` in *C*.\n    culong* {.importc: \"unsigned long\", nodecl.} = uint32\n      ## This is the same as the type `unsigned long` in *C*.\nelse:\n  type\n    clong* {.importc: \"long\", nodecl.} = int\n      ## This is the same as the type `long` in *C*.\n    culong* {.importc: \"unsigned long\", nodecl.} = uint\n      ## This is the same as the type `unsigned long` in *C*.\n\ntype # these work for most platforms:\n  cchar* {.importc: \"char\", nodecl.} = char\n    ## This is the same as the type `char` in *C*.\n  cschar* {.importc: \"signed char\", nodecl.} = int8\n    ## This is the same as the type `signed char` in *C*.\n  cshort* {.importc: \"short\", nodecl.} = int16\n    ## This is the same as the type `short` in *C*.\n  cint* {.importc: \"int\", nodecl.} = int32\n    ## This is the same as the type `int` in *C*.\n  csize* {.importc: \"size_t\", nodecl, deprecated: \"use `csize_t` instead\".} = int\n    ## This isn't the same as `size_t` in *C*. Don't use it.\n  csize_t* {.importc: \"size_t\", nodecl.} = uint\n    ## This is the same as the type `size_t` in *C*.\n  clonglong* {.importc: \"long long\", nodecl.} = int64\n    ## This is the same as the type `long long` in *C*.\n  cfloat* {.importc: \"float\", nodecl.} = float32\n    ## This is the same as the type `float` in *C*.\n  cdouble* {.importc: \"double\", nodecl.} = float64\n    ## This is the same as the type `double` in *C*.\n  clongdouble* {.importc: \"long double\", nodecl.} = BiggestFloat\n    ## This is the same as the type `long double` in *C*.\n    ## This C type is not supported by Nim's code generator.\n\n  cuchar* {.importc: \"unsigned char\", nodecl, deprecated: \"use `char` or `uint8` instead\".} = char\n    ## Deprecated: Use `uint8` instead.\n  cushort* {.importc: \"unsigned short\", nodecl.} = uint16\n    ## This is the same as the type `unsigned short` in *C*.\n  cuint* {.importc: \"unsigned int\", nodecl.} = uint32\n    ## This is the same as the type `unsigned int` in *C*.\n  culonglong* {.importc: \"unsigned long long\", nodecl.} = uint64\n    ## This is the same as the type `unsigned long long` in *C*.\n\n  cstringArray* {.importc: \"char**\", nodecl.} = ptr UncheckedArray[cstring]\n    ## This is binary compatible to the type `char**` in *C*. The array's\n    ## high value is large enough to disable bounds checking in practice.\n    ## Use `cstringArrayToSeq proc <#cstringArrayToSeq,cstringArray,Natural>`_\n    ## to convert it into a `seq[string]`.\n\n  PFloat32* = ptr float32    ## An alias for `ptr float32`.\n  PFloat64* = ptr float64    ## An alias for `ptr float64`.\n  PInt64* = ptr int64        ## An alias for `ptr int64`.\n  PInt32* = ptr int32        ## An alias for `ptr int32`.\n\nproc toFloat*(i: int): float {.noSideEffect, inline.} =\n  ## Converts an integer `i` into a `float`. Same as `float(i)`.\n  ##\n  ## If the conversion fails, `ValueError` is raised.\n  ## However, on most platforms the conversion cannot fail.\n  ##\n  ## .. code-block:: Nim\n  ##   let\n  ##     a = 2\n  ##     b = 3.7\n  ##\n  ##   echo a.toFloat + b # => 5.7\n  float(i)\n\nproc toBiggestFloat*(i: BiggestInt): BiggestFloat {.noSideEffect, inline.} =\n  ## Same as `toFloat <#toFloat,int>`_ but for `BiggestInt` to `BiggestFloat`.\n  BiggestFloat(i)\n\nproc toInt*(f: float): int {.noSideEffect.} =\n  ## Converts a floating point number `f` into an `int`.\n  ##\n  ## Conversion rounds `f` half away from 0, see\n  ## `Round half away from zero\n  ## <https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero>`_,\n  ## as opposed to a type conversion which rounds towards zero.\n  ##\n  ## Note that some floating point numbers (e.g. infinity or even 1e19)\n  ## cannot be accurately converted.\n  ##\n  ## .. code-block:: Nim\n  ##   doAssert toInt(0.49) == 0\n  ##   doAssert toInt(0.5) == 1\n  ##   doAssert toInt(-0.5) == -1 # rounding is symmetrical\n  if f >= 0: int(f+0.5) else: int(f-0.5)\n\nproc toBiggestInt*(f: BiggestFloat): BiggestInt {.noSideEffect.} =\n  ## Same as `toInt <#toInt,float>`_ but for `BiggestFloat` to `BiggestInt`.\n  if f >= 0: BiggestInt(f+0.5) else: BiggestInt(f-0.5)\n\nproc addQuitProc*(quitProc: proc() {.noconv.}) {.\n  importc: \"atexit\", header: \"<stdlib.h>\", deprecated: \"use exitprocs.addExitProc\".}\n  ## Adds/registers a quit procedure.\n  ##\n  ## Each call to `addQuitProc` registers another quit procedure. Up to 30\n  ## procedures can be registered. They are executed on a last-in, first-out\n  ## basis (that is, the last function registered is the first to be executed).\n  ## `addQuitProc` raises an EOutOfIndex exception if `quitProc` cannot be\n  ## registered.\n  # Support for addQuitProc() is done by Ansi C's facilities here.\n  # In case of an unhandled exception the exit handlers should\n  # not be called explicitly! The user may decide to do this manually though.\n\nproc swap*[T](a, b: var T) {.magic: \"Swap\", noSideEffect.}\n  ## Swaps the values `a` and `b`.\n  ##\n  ## This is often more efficient than `tmp = a; a = b; b = tmp`.\n  ## Particularly useful for sorting algorithms.\n  ##\n  ## .. code-block:: Nim\n  ##   var\n  ##     a = 5\n  ##     b = 9\n  ##\n  ##   swap(a, b)\n  ##\n  ##   assert a == 9\n  ##   assert b == 5\n\nwhen not defined(js) and not defined(booting) and defined(nimTrMacros):\n  template swapRefsInArray*{swap(arr[a], arr[b])}(arr: openArray[ref], a, b: int) =\n    # Optimize swapping of array elements if they are refs. Default swap\n    # implementation will cause unsureAsgnRef to be emitted which causes\n    # unnecessary slow down in this case.\n    swap(cast[ptr pointer](addr arr[a])[], cast[ptr pointer](addr arr[b])[])\n\nconst\n  Inf* = 0x7FF0000000000000'f64\n    ## Contains the IEEE floating point value of positive infinity.\n  NegInf* = 0xFFF0000000000000'f64\n    ## Contains the IEEE floating point value of negative infinity.\n  NaN* = 0x7FF7FFFFFFFFFFFF'f64\n    ## Contains an IEEE floating point value of *Not A Number*.\n    ##\n    ## Note that you cannot compare a floating point value to this value\n    ## and expect a reasonable result - use the `isNaN` or `classify` procedure\n    ## in the `math module <math.html>`_ for checking for NaN.\n\n\ninclude \"system/memalloc\"\n\n\nproc `|`*(a, b: typedesc): typedesc = discard\n\ninclude \"system/iterators_1\"\n\n\n{.push stackTrace: off.}\n\n\nwhen defined(js):\n  proc js_abs[T: SomeNumber](x: T): T {.importc: \"Math.abs\".}\nelse:\n  proc c_fabs(x: cdouble): cdouble {.importc: \"fabs\", header: \"<math.h>\".}\n  proc c_fabsf(x: cfloat): cfloat {.importc: \"fabsf\", header: \"<math.h>\".}\n\nproc abs*[T: float64 | float32](x: T): T {.noSideEffect, inline.} =\n  when nimvm:\n    if x < 0.0: result = -x\n    elif x == 0.0: result = 0.0 # handle 0.0, -0.0\n    else: result = x # handle NaN, > 0\n  else:\n    when defined(js): result = js_abs(x)\n    else:\n      when T is float64:\n        result = c_fabs(x)\n      else:\n        result = c_fabsf(x)\n\nproc min*(x, y: float32): float32 {.noSideEffect, inline.} =\n  if x <= y or y != y: x else: y\nproc min*(x, y: float64): float64 {.noSideEffect, inline.} =\n  if x <= y or y != y: x else: y\nproc max*(x, y: float32): float32 {.noSideEffect, inline.} =\n  if y <= x or y != y: x else: y\nproc max*(x, y: float64): float64 {.noSideEffect, inline.} =\n  if y <= x or y != y: x else: y\nproc min*[T: not SomeFloat](x, y: T): T {.inline.} =\n  if x <= y: x else: y\nproc max*[T: not SomeFloat](x, y: T): T {.inline.} =\n  if y <= x: x else: y\n\n{.pop.} # stackTrace: off\n\n\nproc high*(T: typedesc[SomeFloat]): T = Inf\nproc low*(T: typedesc[SomeFloat]): T = NegInf\n\nproc len*[U: Ordinal; V: Ordinal](x: HSlice[U, V]): int {.noSideEffect, inline.} =\n  ## Length of ordinal slice. When x.b < x.a returns zero length.\n  ##\n  ## .. code-block:: Nim\n  ##   assert((0..5).len == 6)\n  ##   assert((5..2).len == 0)\n  result = max(0, ord(x.b) - ord(x.a) + 1)\n\nwhen true: # PRTEMP: remove?\n  proc isNil*[T](x: seq[T]): bool {.noSideEffect, magic: \"IsNil\", error.}\n    ## Seqs are no longer nil by default, but set and empty.\n    ## Check for zero length instead.\n    ##\n    ## See also:\n    ## * `isNil(string) <#isNil,string>`_\n\n  proc isNil*(x: string): bool {.noSideEffect, magic: \"IsNil\", error.}\n    ## See also:\n    ## * `isNil(seq[T]) <#isNil,seq[T]>`_\n\nproc isNil*[T](x: ref T): bool {.noSideEffect, magic: \"IsNil\".}\n\nproc isNil*[T](x: ptr T): bool {.noSideEffect, magic: \"IsNil\".}\nproc isNil*(x: pointer): bool {.noSideEffect, magic: \"IsNil\".}\nproc isNil*(x: cstring): bool {.noSideEffect, magic: \"IsNil\".}\nproc isNil*[T: proc](x: T): bool {.noSideEffect, magic: \"IsNil\".}\n  ## Fast check whether `x` is nil. This is sometimes more efficient than\n  ## `== nil`.\n\n\nproc `@`*[T](a: openArray[T]): seq[T] =\n  ## Turns an *openArray* into a sequence.\n  ##\n  ## This is not as efficient as turning a fixed length array into a sequence\n  ## as it always copies every element of `a`.\n  newSeq(result, a.len)\n  for i in 0..a.len-1: result[i] = a[i]\n\n\nwhen defined(nimSeqsV2):\n\n  proc `&`*[T](x, y: sink seq[T]): seq[T] {.noSideEffect.} =\n    ## Concatenates two sequences.\n    ##\n    ## Requires copying of the sequences.\n    ##\n    ## See also:\n    ## * `add(var seq[T], openArray[T]) <#add,seq[T],openArray[T]>`_\n    ##\n    ## .. code-block:: Nim\n    ##   assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6])\n    newSeq(result, x.len + y.len)\n    for i in 0..x.len-1:\n      result[i] = move(x[i])\n    for i in 0..y.len-1:\n      result[i+x.len] = move(y[i])\n\n  proc `&`*[T](x: sink seq[T], y: sink T): seq[T] {.noSideEffect.} =\n    ## Appends element y to the end of the sequence.\n    ##\n    ## Requires copying of the sequence.\n    ##\n    ## See also:\n    ## * `add(var seq[T], T) <#add,seq[T],sinkT>`_\n    ##\n    ## .. code-block:: Nim\n    ##   assert(@[1, 2, 3] & 4 == @[1, 2, 3, 4])\n    newSeq(result, x.len + 1)\n    for i in 0..x.len-1:\n      result[i] = move(x[i])\n    result[x.len] = move(y)\n\n  proc `&`*[T](x: sink T, y: sink seq[T]): seq[T] {.noSideEffect.} =\n    ## Prepends the element x to the beginning of the sequence.\n    ##\n    ## Requires copying of the sequence.\n    ##\n    ## .. code-block:: Nim\n    ##   assert(1 & @[2, 3, 4] == @[1, 2, 3, 4])\n    newSeq(result, y.len + 1)\n    result[0] = move(x)\n    for i in 0..y.len-1:\n      result[i+1] = move(y[i])\n\nelse:\n\n  proc `&`*[T](x, y: seq[T]): seq[T] {.noSideEffect.} =\n    ## Concatenates two sequences.\n    ##\n    ## Requires copying of the sequences.\n    ##\n    ## See also:\n    ## * `add(var seq[T], openArray[T]) <#add,seq[T],openArray[T]>`_\n    ##\n    ## .. code-block:: Nim\n    ##   assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6])\n    newSeq(result, x.len + y.len)\n    for i in 0..x.len-1:\n      result[i] = x[i]\n    for i in 0..y.len-1:\n      result[i+x.len] = y[i]\n\n  proc `&`*[T](x: seq[T], y: T): seq[T] {.noSideEffect.} =\n    ## Appends element y to the end of the sequence.\n    ##\n    ## Requires copying of the sequence.\n    ##\n    ## See also:\n    ## * `add(var seq[T], T) <#add,seq[T],sinkT>`_\n    ##\n    ## .. code-block:: Nim\n    ##   assert(@[1, 2, 3] & 4 == @[1, 2, 3, 4])\n    newSeq(result, x.len + 1)\n    for i in 0..x.len-1:\n      result[i] = x[i]\n    result[x.len] = y\n\n  proc `&`*[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} =\n    ## Prepends the element x to the beginning of the sequence.\n    ##\n    ## Requires copying of the sequence.\n    ##\n    ## .. code-block:: Nim\n    ##   assert(1 & @[2, 3, 4] == @[1, 2, 3, 4])\n    newSeq(result, y.len + 1)\n    result[0] = x\n    for i in 0..y.len-1:\n      result[i+1] = y[i]\n\n\nproc astToStr*[T](x: T): string {.magic: \"AstToStr\", noSideEffect.}\n  ## Converts the AST of `x` into a string representation. This is very useful\n  ## for debugging.\n\nproc instantiationInfo*(index = -1, fullPaths = false): tuple[\n  filename: string, line: int, column: int] {.magic: \"InstantiationInfo\", noSideEffect.}\n  ## Provides access to the compiler's instantiation stack line information\n  ## of a template.\n  ##\n  ## While similar to the `caller info`:idx: of other languages, it is determined\n  ## at compile time.\n  ##\n  ## This proc is mostly useful for meta programming (eg. `assert` template)\n  ## to retrieve information about the current filename and line number.\n  ## Example:\n  ##\n  ## .. code-block:: nim\n  ##   import std/strutils\n  ##\n  ##   template testException(exception, code: untyped): typed =\n  ##     try:\n  ##       let pos = instantiationInfo()\n  ##       discard(code)\n  ##       echo \"Test failure at $1:$2 with '$3'\" % [pos.filename,\n  ##         $pos.line, astToStr(code)]\n  ##       assert false, \"A test expecting failure succeeded?\"\n  ##     except exception:\n  ##       discard\n  ##\n  ##   proc tester(pos: int): int =\n  ##     let\n  ##       a = @[1, 2, 3]\n  ##     result = a[pos]\n  ##\n  ##   when isMainModule:\n  ##     testException(IndexDefect, tester(30))\n  ##     testException(IndexDefect, tester(1))\n  ##     # --> Test failure at example.nim:20 with 'tester(1)'\n\nproc compiles*(x: untyped): bool {.magic: \"Compiles\", noSideEffect, compileTime.} =\n  ## Special compile-time procedure that checks whether `x` can be compiled\n  ## without any semantic error.\n  ## This can be used to check whether a type supports some operation:\n  ##\n  ## .. code-block:: Nim\n  ##   when compiles(3 + 4):\n  ##     echo \"'+' for integers is available\"\n  discard\n\nwhen notJSnotNims:\n  import system/ansi_c\n  import system/memory\n\n\n{.push stackTrace: off.}\n\nwhen not defined(js) and hasThreadSupport and hostOS != \"standalone\":\n  const insideRLocksModule = false\n  include \"system/syslocks\"\n  include \"system/threadlocalstorage\"\n\nwhen not defined(js) and defined(nimV2):\n  type\n    DestructorProc = proc (p: pointer) {.nimcall, benign, raises: [].}\n    TNimTypeV2 {.compilerproc.} = object\n      destructor: pointer\n      size: int\n      align: int\n      name: cstring\n      traceImpl: pointer\n      typeInfoV1: pointer # for backwards compat, usually nil\n      flags: int\n    PNimTypeV2 = ptr TNimTypeV2\n\nwhen notJSnotNims and defined(nimSeqsV2):\n  include \"system/strs_v2\"\n  include \"system/seqs_v2\"\n\n{.pop.}\n\nwhen not defined(nimscript):\n  proc writeStackTrace*() {.tags: [], gcsafe, raises: [].}\n    ## Writes the current stack trace to `stderr`. This is only works\n    ## for debug builds. Since it's usually used for debugging, this\n    ## is proclaimed to have no IO effect!\n\nwhen not declared(sysFatal):\n  include \"system/fatal\"\n\nwhen not defined(nimscript):\n  {.push stackTrace: off, profiler: off.}\n\n  proc atomicInc*(memLoc: var int, x: int = 1): int {.inline,\n    discardable, benign.}\n    ## Atomic increment of `memLoc`. Returns the value after the operation.\n\n  proc atomicDec*(memLoc: var int, x: int = 1): int {.inline,\n    discardable, benign.}\n    ## Atomic decrement of `memLoc`. Returns the value after the operation.\n\n  include \"system/atomics\"\n\n  {.pop.}\n\n\nwhen defined(nimV2):\n  include system/arc\n\nimport system/assertions\nexport assertions\n\nimport system/iterators\nexport iterators\n\n\nproc find*[T, S](a: T, item: S): int {.inline.}=\n  ## Returns the first index of `item` in `a` or -1 if not found. This requires\n  ## appropriate `items` and `==` operations to work.\n  result = 0\n  for i in items(a):\n    if i == item: return\n    inc(result)\n  result = -1\n\nproc contains*[T](a: openArray[T], item: T): bool {.inline.}=\n  ## Returns true if `item` is in `a` or false if not found. This is a shortcut\n  ## for `find(a, item) >= 0`.\n  ##\n  ## This allows the `in` operator: `a.contains(item)` is the same as\n  ## `item in a`.\n  ##\n  ## .. code-block:: Nim\n  ##   var a = @[1, 3, 5]\n  ##   assert a.contains(5)\n  ##   assert 3 in a\n  ##   assert 99 notin a\n  return find(a, item) >= 0\n\nproc pop*[T](s: var seq[T]): T {.inline, noSideEffect.} =\n  ## Returns the last item of `s` and decreases `s.len` by one. This treats\n  ## `s` as a stack and implements the common *pop* operation.\n  runnableExamples:\n    var a = @[1, 3, 5, 7]\n    let b = pop(a)\n    assert b == 7\n    assert a == @[1, 3, 5]\n\n  var L = s.len-1\n  when defined(nimV2):\n    result = move s[L]\n    shrink(s, L)\n  else:\n    result = s[L]\n    setLen(s, L)\n\nproc `==`*[T: tuple|object](x, y: T): bool =\n  ## Generic `==` operator for tuples that is lifted from the components.\n  ## of `x` and `y`.\n  for a, b in fields(x, y):\n    if a != b: return false\n  return true\n\nproc `<=`*[T: tuple](x, y: T): bool =\n  ## Generic lexicographic `<=` operator for tuples that is lifted from the\n  ## components of `x` and `y`. This implementation uses `cmp`.\n  for a, b in fields(x, y):\n    var c = cmp(a, b)\n    if c < 0: return true\n    if c > 0: return false\n  return true\n\nproc `<`*[T: tuple](x, y: T): bool =\n  ## Generic lexicographic `<` operator for tuples that is lifted from the\n  ## components of `x` and `y`. This implementation uses `cmp`.\n  for a, b in fields(x, y):\n    var c = cmp(a, b)\n    if c < 0: return true\n    if c > 0: return false\n  return false\n\n\ninclude \"system/gc_interface\"\n\n# we have to compute this here before turning it off in except.nim anyway ...\nconst NimStackTrace = compileOption(\"stacktrace\")\n\nimport system/coro_detection\n\n{.push checks: off.}\n# obviously we cannot generate checking operations here :-)\n# because it would yield into an endless recursion\n# however, stack-traces are available for most parts\n# of the code\n\nwhen notJSnotNims:\n  var\n    globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, benign.}\n      ## With this hook you can influence exception handling on a global level.\n      ## If not nil, every 'raise' statement ends up calling this hook.\n      ##\n      ## .. warning:: Ordinary application code should never set this hook! You better know what you do when setting this.\n      ##\n      ## If `globalRaiseHook` returns false, the exception is caught and does\n      ## not propagate further through the call stack.\n\n    localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, benign.}\n      ## With this hook you can influence exception handling on a\n      ## thread local level.\n      ## If not nil, every 'raise' statement ends up calling this hook.\n      ##\n      ## .. warning:: Ordinary application code should never set this hook! You better know what you do when setting this.\n      ##\n      ## If `localRaiseHook` returns false, the exception\n      ## is caught and does not propagate further through the call stack.\n\n    outOfMemHook*: proc () {.nimcall, tags: [], benign, raises: [].}\n      ## Set this variable to provide a procedure that should be called\n      ## in case of an `out of memory`:idx: event. The standard handler\n      ## writes an error message and terminates the program.\n      ##\n      ## `outOfMemHook` can be used to raise an exception in case of OOM like so:\n      ##\n      ## .. code-block:: Nim\n      ##\n      ##   var gOutOfMem: ref EOutOfMemory\n      ##   new(gOutOfMem) # need to be allocated *before* OOM really happened!\n      ##   gOutOfMem.msg = \"out of memory\"\n      ##\n      ##   proc handleOOM() =\n      ##     raise gOutOfMem\n      ##\n      ##   system.outOfMemHook = handleOOM\n      ##\n      ## If the handler does not raise an exception, ordinary control flow\n      ## continues and the program is terminated.\n    unhandledExceptionHook*: proc (e: ref Exception) {.nimcall, tags: [], benign, raises: [].}\n      ## Set this variable to provide a procedure that should be called\n      ## in case of an `unhandle exception` event. The standard handler\n      ## writes an error message and terminates the program, except when\n      ## using `--os:any`\n\ntype\n  PFrame* = ptr TFrame  ## Represents a runtime frame of the call stack;\n                        ## part of the debugger API.\n  # keep in sync with nimbase.h `struct TFrame_`\n  TFrame* {.importc, nodecl, final.} = object ## The frame itself.\n    prev*: PFrame       ## Previous frame; used for chaining the call stack.\n    procname*: cstring  ## Name of the proc that is currently executing.\n    line*: int          ## Line number of the proc that is currently executing.\n    filename*: cstring  ## Filename of the proc that is currently executing.\n    len*: int16         ## Length of the inspectable slots.\n    calldepth*: int16   ## Used for max call depth checking.\n    when NimStackTraceMsgs:\n      frameMsgLen*: int   ## end position in frameMsgBuf for this frame.\n\nwhen defined(js) or defined(nimdoc):\n  proc add*(x: var string, y: cstring) {.asmNoStackFrame.} =\n    ## Appends `y` to `x` in place.\n    runnableExamples:\n      var tmp = \"\"\n      tmp.add(cstring(\"ab\"))\n      tmp.add(cstring(\"cd\"))\n      doAssert tmp == \"abcd\"\n    asm \"\"\"\n      if (`x` === null) { `x` = []; }\n      var off = `x`.length;\n      `x`.length += `y`.length;\n      for (var i = 0; i < `y`.length; ++i) {\n        `x`[off+i] = `y`.charCodeAt(i);\n      }\n    \"\"\"\n  proc add*(x: var cstring, y: cstring) {.magic: \"AppendStrStr\".} =\n    ## Appends `y` to `x` in place.\n    ## Only implemented for JS backend.\n    runnableExamples:\n      when defined(js):\n        var tmp: cstring = \"\"\n        tmp.add(cstring(\"ab\"))\n        tmp.add(cstring(\"cd\"))\n        doAssert tmp == cstring(\"abcd\")\n\nelif hasAlloc:\n  {.push stackTrace: off, profiler: off.}\n  proc add*(x: var string, y: cstring) =\n    var i = 0\n    if y != nil:\n      while y[i] != '\\0':\n        add(x, y[i])\n        inc(i)\n  {.pop.}\n\nproc echo*(x: varargs[typed, `$`]) {.magic: \"Echo\", benign, sideEffect.}\n  ## Writes and flushes the parameters to the standard output.\n  ##\n  ## Special built-in that takes a variable number of arguments. Each argument\n  ## is converted to a string via `$`, so it works for user-defined\n  ## types that have an overloaded `$` operator.\n  ## It is roughly equivalent to `writeLine(stdout, x); flushFile(stdout)`, but\n  ## available for the JavaScript target too.\n  ##\n  ## Unlike other IO operations this is guaranteed to be thread-safe as\n  ## `echo` is very often used for debugging convenience. If you want to use\n  ## `echo` inside a `proc without side effects\n  ## <manual.html#pragmas-nosideeffect-pragma>`_ you can use `debugEcho\n  ## <#debugEcho,varargs[typed,]>`_ instead.\n\nproc debugEcho*(x: varargs[typed, `$`]) {.magic: \"Echo\", noSideEffect,\n                                          tags: [], raises: [].}\n  ## Same as `echo <#echo,varargs[typed,]>`_, but as a special semantic rule,\n  ## `debugEcho` pretends to be free of side effects, so that it can be used\n  ## for debugging routines marked as `noSideEffect\n  ## <manual.html#pragmas-nosideeffect-pragma>`_.\n\ntemplate newException*(exceptn: typedesc, message: string;\n                       parentException: ref Exception = nil): untyped =\n  ## Creates an exception object of type `exceptn` and sets its `msg` field\n  ## to `message`. Returns the new exception object.\n  (ref exceptn)(msg: message, parent: parentException)\n\nwhen hostOS == \"standalone\" and defined(nogc):\n  proc nimToCStringConv(s: NimString): cstring {.compilerproc, inline.} =\n    if s == nil or s.len == 0: result = cstring\"\"\n    else: result = cstring(addr s.data)\n\nproc getTypeInfo*[T](x: T): pointer {.magic: \"GetTypeInfo\", benign.}\n  ## Get type information for `x`.\n  ##\n  ## Ordinary code should not use this, but the `typeinfo module\n  ## <typeinfo.html>`_ instead.\n\n{.push stackTrace: off.}\nfunc abs*(x: int): int {.magic: \"AbsI\", inline.} =\n  if x < 0: -x else: x\nfunc abs*(x: int8): int8 {.magic: \"AbsI\", inline.} =\n  if x < 0: -x else: x\nfunc abs*(x: int16): int16 {.magic: \"AbsI\", inline.} =\n  if x < 0: -x else: x\nfunc abs*(x: int32): int32 {.magic: \"AbsI\", inline.} =\n  if x < 0: -x else: x\nfunc abs*(x: int64): int64 {.magic: \"AbsI\", inline.} =\n  ## Returns the absolute value of `x`.\n  ##\n  ## If `x` is `low(x)` (that is -MININT for its type),\n  ## an overflow exception is thrown (if overflow checking is turned on).\n  result = if x < 0: -x else: x\n{.pop.}\n\nwhen not defined(js):\n\n  proc likelyProc(val: bool): bool {.importc: \"NIM_LIKELY\", nodecl, noSideEffect.}\n  proc unlikelyProc(val: bool): bool {.importc: \"NIM_UNLIKELY\", nodecl, noSideEffect.}\n\ntemplate likely*(val: bool): bool =\n  ## Hints the optimizer that `val` is likely going to be true.\n  ##\n  ## You can use this template to decorate a branch condition. On certain\n  ## platforms this can help the processor predict better which branch is\n  ## going to be run. Example:\n  ##\n  ## .. code-block:: Nim\n  ##   for value in inputValues:\n  ##     if likely(value <= 100):\n  ##       process(value)\n  ##     else:\n  ##       echo \"Value too big!\"\n  ##\n  ## On backends without branch prediction (JS and the nimscript VM), this\n  ## template will not affect code execution.\n  when nimvm:\n    val\n  else:\n    when defined(js):\n      val\n    else:\n      likelyProc(val)\n\ntemplate unlikely*(val: bool): bool =\n  ## Hints the optimizer that `val` is likely going to be false.\n  ##\n  ## You can use this proc to decorate a branch condition. On certain\n  ## platforms this can help the processor predict better which branch is\n  ## going to be run. Example:\n  ##\n  ## .. code-block:: Nim\n  ##   for value in inputValues:\n  ##     if unlikely(value > 100):\n  ##       echo \"Value too big!\"\n  ##     else:\n  ##       process(value)\n  ##\n  ## On backends without branch prediction (JS and the nimscript VM), this\n  ## template will not affect code execution.\n  when nimvm:\n    val\n  else:\n    when defined(js):\n      val\n    else:\n      unlikelyProc(val)\n\nconst\n  NimMajor* {.intdefine.}: int = 1\n    ## is the major number of Nim's version. Example:\n    ##\n    ## .. code-block:: Nim\n    ##   when (NimMajor, NimMinor, NimPatch) >= (1, 3, 1): discard\n    # see also std/private/since\n\n  NimMinor* {.intdefine.}: int = 5\n    ## is the minor number of Nim's version.\n    ## Odd for devel, even for releases.\n\n  NimPatch* {.intdefine.}: int = 1\n    ## is the patch number of Nim's version.\n    ## Odd for devel, even for releases.\n\nimport system/dollars\nexport dollars\n\nwhen defined(nimAuditDelete):\n  {.pragma: auditDelete, deprecated: \"review this call for out of bounds behavior\".}\nelse:\n  {.pragma: auditDelete.}\n\nproc delete*[T](x: var seq[T], i: Natural) {.noSideEffect, auditDelete.} =\n  ## Deletes the item at index `i` by moving all `x[i+1..^1]` items by one position.\n  ##\n  ## This is an `O(n)` operation.\n  ##\n  ## .. note:: With `-d:nimStrictDelete`, an index error is produced when the index passed\n  ##    to it was out of bounds. `-d:nimStrictDelete` will become the default\n  ##    in upcoming versions.\n  ##\n  ## See also:\n  ## * `del <#del,seq[T],Natural>`_ for O(1) operation\n  ##\n  runnableExamples:\n    var s = @[1, 2, 3, 4, 5]\n    s.delete(2)\n    doAssert s == @[1, 2, 4, 5]\n\n  when defined(nimStrictDelete):\n    if i > high(x):\n      # xxx this should call `raiseIndexError2(i, high(x))` after some refactoring\n      raise (ref IndexDefect)(msg: \"index out of bounds: '\" & $i & \"' < '\" & $x.len & \"' failed\")\n\n  template defaultImpl =\n    let xl = x.len\n    for j in i.int..xl-2: movingCopy(x[j], x[j+1])\n    setLen(x, xl-1)\n\n  when nimvm:\n    defaultImpl()\n  else:\n    when defined(js):\n      {.emit: \"`x`.splice(`i`, 1);\".}\n    else:\n      defaultImpl()\n\n\nconst\n  NimVersion*: string = $NimMajor & \".\" & $NimMinor & \".\" & $NimPatch\n    ## is the version of Nim as a string.\n\n\ntype\n  FileSeekPos* = enum ## Position relative to which seek should happen.\n                      # The values are ordered so that they match with stdio\n                      # SEEK_SET, SEEK_CUR and SEEK_END respectively.\n    fspSet            ## Seek to absolute value\n    fspCur            ## Seek relative to current position\n    fspEnd            ## Seek relative to end\n\n\nwhen not defined(js):\n  {.push stackTrace: off, profiler: off.}\n\n  when hasAlloc:\n    when not defined(gcRegions) and not usesDestructors:\n      proc initGC() {.gcsafe, raises: [].}\n\n    proc initStackBottom() {.inline, compilerproc.} =\n      # WARNING: This is very fragile! An array size of 8 does not work on my\n      # Linux 64bit system. -- That's because the stack direction is the other\n      # way around.\n      when declared(nimGC_setStackBottom):\n        var locals {.volatile, noinit.}: pointer\n        locals = addr(locals)\n        nimGC_setStackBottom(locals)\n\n    proc initStackBottomWith(locals: pointer) {.inline, compilerproc.} =\n      # We need to keep initStackBottom around for now to avoid\n      # bootstrapping problems.\n      when declared(nimGC_setStackBottom):\n        nimGC_setStackBottom(locals)\n\n    when not usesDestructors:\n      {.push profiler: off.}\n      var\n        strDesc = TNimType(size: sizeof(string), kind: tyString, flags: {ntfAcyclic})\n      {.pop.}\n\n  {.pop.}\n\n\nwhen not defined(js):\n  # ugly hack, see the accompanying .pop for\n  # the mysterious error message\n  {.push stackTrace: off, profiler: off.}\n\nwhen notJSnotNims:\n  proc zeroMem(p: pointer, size: Natural) =\n    nimZeroMem(p, size)\n    when declared(memTrackerOp):\n      memTrackerOp(\"zeroMem\", p, size)\n  proc copyMem(dest, source: pointer, size: Natural) =\n    nimCopyMem(dest, source, size)\n    when declared(memTrackerOp):\n      memTrackerOp(\"copyMem\", dest, size)\n  proc moveMem(dest, source: pointer, size: Natural) =\n    c_memmove(dest, source, csize_t(size))\n    when declared(memTrackerOp):\n      memTrackerOp(\"moveMem\", dest, size)\n  proc equalMem(a, b: pointer, size: Natural): bool =\n    nimCmpMem(a, b, size) == 0\n  proc cmpMem(a, b: pointer, size: Natural): int =\n    nimCmpMem(a, b, size)\n\nwhen not defined(js):\n  proc cmp(x, y: string): int =\n    when nimvm:\n      if x < y: result = -1\n      elif x > y: result = 1\n      else: result = 0\n    else:\n      when not defined(nimscript): # avoid semantic checking\n        let minlen = min(x.len, y.len)\n        result = int(nimCmpMem(x.cstring, y.cstring, cast[csize_t](minlen)))\n        if result == 0:\n          result = x.len - y.len\n\n  when declared(newSeq):\n    proc cstringArrayToSeq*(a: cstringArray, len: Natural): seq[string] =\n      ## Converts a `cstringArray` to a `seq[string]`. `a` is supposed to be\n      ## of length `len`.\n      newSeq(result, len)\n      for i in 0..len-1: result[i] = $a[i]\n\n    proc cstringArrayToSeq*(a: cstringArray): seq[string] =\n      ## Converts a `cstringArray` to a `seq[string]`. `a` is supposed to be\n      ## terminated by `nil`.\n      var L = 0\n      while a[L] != nil: inc(L)\n      result = cstringArrayToSeq(a, L)\n\n\nwhen not defined(js) and declared(alloc0) and declared(dealloc):\n  proc allocCStringArray*(a: openArray[string]): cstringArray =\n    ## Creates a NULL terminated cstringArray from `a`. The result has to\n    ## be freed with `deallocCStringArray` after it's not needed anymore.\n    result = cast[cstringArray](alloc0((a.len+1) * sizeof(cstring)))\n\n    let x = cast[ptr UncheckedArray[string]](a)\n    for i in 0 .. a.high:\n      result[i] = cast[cstring](alloc0(x[i].len+1))\n      copyMem(result[i], addr(x[i][0]), x[i].len)\n\n  proc deallocCStringArray*(a: cstringArray) =\n    ## Frees a NULL terminated cstringArray.\n    var i = 0\n    while a[i] != nil:\n      dealloc(a[i])\n      inc(i)\n    dealloc(a)\n\nwhen notJSnotNims:\n  type\n    PSafePoint = ptr TSafePoint\n    TSafePoint {.compilerproc, final.} = object\n      prev: PSafePoint # points to next safe point ON THE STACK\n      status: int\n      context: C_JmpBuf\n    SafePoint = TSafePoint\n\nwhen not defined(js):\n  when declared(initAllocator):\n    initAllocator()\n  when hasThreadSupport:\n    when hostOS != \"standalone\": include \"system/threads\"\n  elif not defined(nogc) and not defined(nimscript):\n    when not defined(useNimRtl) and not defined(createNimRtl): initStackBottom()\n    when declared(initGC): initGC()\n\nwhen notJSnotNims:\n  proc setControlCHook*(hook: proc () {.noconv.})\n    ## Allows you to override the behaviour of your application when CTRL+C\n    ## is pressed. Only one such hook is supported.\n\n  when not defined(noSignalHandler) and not defined(useNimRtl):\n    proc unsetControlCHook*()\n      ## Reverts a call to setControlCHook.\n\n  when hostOS != \"standalone\":\n    proc getStackTrace*(): string {.gcsafe.}\n      ## Gets the current stack trace. This only works for debug builds.\n\n    proc getStackTrace*(e: ref Exception): string {.gcsafe.}\n      ## Gets the stack trace associated with `e`, which is the stack that\n      ## lead to the `raise` statement. This only works for debug builds.\n\n  {.push stackTrace: off, profiler: off.}\n  when defined(memtracker):\n    include \"system/memtracker\"\n\n  when hostOS == \"standalone\":\n    include \"system/embedded\"\n  else:\n    include \"system/excpt\"\n  include \"system/chcks\"\n\n  # we cannot compile this with stack tracing on\n  # as it would recurse endlessly!\n  when defined(nimNewIntegerOps):\n    include \"system/integerops\"\n  else:\n    include \"system/arithm\"\n  {.pop.}\n\n\nwhen not defined(js):\n  # this is a hack: without this when statement, you would get:\n  # Error: system module needs: nimGCvisit\n  {.pop.} # stackTrace: off, profiler: off\n\n\n\nwhen notJSnotNims:\n  when hostOS != \"standalone\" and hostOS != \"any\":\n    include \"system/dyncalls\"\n\n  import system/countbits_impl\n  include \"system/sets\"\n\n  when defined(gogc):\n    const GenericSeqSize = (3 * sizeof(int))\n  else:\n    const GenericSeqSize = (2 * sizeof(int))\n\n  proc getDiscriminant(aa: pointer, n: ptr TNimNode): uint =\n    sysAssert(n.kind == nkCase, \"getDiscriminant: node != nkCase\")\n    var d: uint\n    var a = cast[uint](aa)\n    case n.typ.size\n    of 1: d = uint(cast[ptr uint8](a + uint(n.offset))[])\n    of 2: d = uint(cast[ptr uint16](a + uint(n.offset))[])\n    of 4: d = uint(cast[ptr uint32](a + uint(n.offset))[])\n    of 8: d = uint(cast[ptr uint64](a + uint(n.offset))[])\n    else:\n      d = 0'u\n      sysAssert(false, \"getDiscriminant: invalid n.typ.size\")\n    return d\n\n  proc selectBranch(aa: pointer, n: ptr TNimNode): ptr TNimNode =\n    var discr = getDiscriminant(aa, n)\n    if discr < cast[uint](n.len):\n      result = n.sons[discr]\n      if result == nil: result = n.sons[n.len]\n      # n.sons[n.len] contains the `else` part (but may be nil)\n    else:\n      result = n.sons[n.len]\n\nwhen notJSnotNims and hasAlloc:\n  {.push profiler: off.}\n  include \"system/mmdisp\"\n  {.pop.}\n  {.push stackTrace: off, profiler: off.}\n  when not defined(nimSeqsV2):\n    include \"system/sysstr\"\n  {.pop.}\n\n  include \"system/strmantle\"\n  include \"system/assign\"\n\n  when not defined(nimV2):\n    include \"system/repr\"\n\nwhen notJSnotNims and hasThreadSupport and hostOS != \"standalone\":\n  include \"system/channels_builtin\"\n\n\nwhen notJSnotNims and hostOS != \"standalone\":\n  proc getCurrentException*(): ref Exception {.compilerRtl, inl, benign.} =\n    ## Retrieves the current exception; if there is none, `nil` is returned.\n    result = currException\n\n  proc nimBorrowCurrentException(): ref Exception {.compilerRtl, inl, benign, nodestroy.} =\n    # .nodestroy here so that we do not produce a write barrier as the\n    # C codegen only uses it in a borrowed way:\n    result = currException\n\n  proc getCurrentExceptionMsg*(): string {.inline, benign.} =\n    ## Retrieves the error message that was attached to the current\n    ## exception; if there is none, `\"\"` is returned.\n    return if currException == nil: \"\" else: currException.msg\n\n  proc setCurrentException*(exc: ref Exception) {.inline, benign.} =\n    ## Sets the current exception.\n    ##\n    ## .. warning:: Only use this if you know what you are doing.\n    currException = exc\nelif defined(nimscript):\n  proc getCurrentException*(): ref Exception {.compilerRtl.} = discard\n\nwhen notJSnotNims:\n  {.push stackTrace: off, profiler: off.}\n  when (defined(profiler) or defined(memProfiler)):\n    include \"system/profiler\"\n  {.pop.}\n\n  proc rawProc*[T: proc](x: T): pointer {.noSideEffect, inline.} =\n    ## Retrieves the raw proc pointer of the closure `x`. This is\n    ## useful for interfacing closures with C/C++, hash compuations, etc.\n    when T is \"closure\":\n      #[\n      The conversion from function pointer to `void*` is a tricky topic, but this\n      should work at least for c++ >= c++11, e.g. for `dlsym` support.\n      refs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57869,\n      https://stackoverflow.com/questions/14125474/casts-between-pointer-to-function-and-pointer-to-object-in-c-and-c\n      ]#\n      {.emit: \"\"\"\n      `result` = (void*)`x`.ClP_0;\n      \"\"\".}\n    else:\n      {.error: \"Only closure function and iterator are allowed!\".}\n\n  proc rawEnv*[T: proc](x: T): pointer {.noSideEffect, inline.} =\n    ## Retrieves the raw environment pointer of the closure `x`. See also `rawProc`.\n    when T is \"closure\":\n      {.emit: \"\"\"\n      `result` = `x`.ClE_0;\n      \"\"\".}\n    else:\n      {.error: \"Only closure function and iterator are allowed!\".}\n\n  proc finished*[T: proc](x: T): bool {.noSideEffect, inline, magic: \"Finished\".} =\n    ## It can be used to determine if a first class iterator has finished.\n    when T is \"iterator\":\n      {.emit: \"\"\"\n      `result` = ((NI*) `x`.ClE_0)[1] < 0;\n      \"\"\".}\n    else:\n      {.error: \"Only closure iterator is allowed!\".}\n\nfrom std/private/digitsutils import addInt\nexport addInt\n\nwhen defined(js):\n  include \"system/jssys\"\n  include \"system/reprjs\"\n\nproc quit*(errormsg: string, errorcode = QuitFailure) {.noreturn.} =\n  ## A shorthand for `echo(errormsg); quit(errorcode)`.\n  when defined(nimscript) or defined(js) or (hostOS == \"standalone\"):\n    echo errormsg\n  else:\n    when nimvm:\n      echo errormsg\n    else:\n      cstderr.rawWrite(errormsg)\n      cstderr.rawWrite(\"\\n\")\n  quit(errorcode)\n\n{.pop.} # checks: off\n# {.pop.} # hints: off\n\nproc `/`*(x, y: int): float {.inline, noSideEffect.} =\n  ## Division of integers that results in a float.\n  ##\n  ## See also:\n  ## * `div <#div,int,int>`_\n  ## * `mod <#mod,int,int>`_\n  ##\n  ## .. code-block:: Nim\n  ##   echo 7 / 5 # => 1.4\n  result = toFloat(x) / toFloat(y)\n\ntype\n  BackwardsIndex* = distinct int ## Type that is constructed by `^` for\n                                 ## reversed array accesses.\n                                 ## (See `^ template <#^.t,int>`_)\n\ntemplate `^`*(x: int): BackwardsIndex = BackwardsIndex(x)\n  ## Builtin `roof`:idx: operator that can be used for convenient array access.\n  ## `a[^x]` is a shortcut for `a[a.len-x]`.\n  ##\n  ## .. code-block:: Nim\n  ##   let\n  ##     a = [1, 3, 5, 7, 9]\n  ##     b = \"abcdefgh\"\n  ##\n  ##   echo a[^1] # => 9\n  ##   echo b[^2] # => g\n\ntemplate `..^`*(a, b: untyped): untyped =\n  ## A shortcut for `.. ^` to avoid the common gotcha that a space between\n  ## '..' and '^' is required.\n  a .. ^b\n\ntemplate `..<`*(a, b: untyped): untyped =\n  ## A shortcut for `a .. pred(b)`.\n  ##\n  ## .. code-block:: Nim\n  ##   for i in 5 ..< 9:\n  ##     echo i # => 5; 6; 7; 8\n  a .. (when b is BackwardsIndex: succ(b) else: pred(b))\n\ntemplate spliceImpl(s, a, L, b: untyped): untyped =\n  # make room for additional elements or cut:\n  var shift = b.len - max(0,L)  # ignore negative slice size\n  var newLen = s.len + shift\n  if shift > 0:\n    # enlarge:\n    setLen(s, newLen)\n    for i in countdown(newLen-1, a+b.len): movingCopy(s[i], s[i-shift])\n  else:\n    for i in countup(a+b.len, newLen-1): movingCopy(s[i], s[i-shift])\n    # cut down:\n    setLen(s, newLen)\n  # fill the hole:\n  for i in 0 ..< b.len: s[a+i] = b[i]\n\ntemplate `^^`(s, i: untyped): untyped =\n  (when i is BackwardsIndex: s.len - int(i) else: int(i))\n\ntemplate `[]`*(s: string; i: int): char = arrGet(s, i)\ntemplate `[]=`*(s: string; i: int; val: char) = arrPut(s, i, val)\n\nproc `[]`*[T, U: Ordinal](s: string, x: HSlice[T, U]): string {.inline.} =\n  ## Slice operation for strings.\n  ## Returns the inclusive range `[s[x.a], s[x.b]]`:\n  ##\n  ## .. code-block:: Nim\n  ##    var s = \"abcdef\"\n  ##    assert s[1..3] == \"bcd\"\n  let a = s ^^ x.a\n  let L = (s ^^ x.b) - a + 1\n  result = newString(L)\n  for i in 0 ..< L: result[i] = s[i + a]\n\nproc `[]=`*[T, U: Ordinal](s: var string, x: HSlice[T, U], b: string) =\n  ## Slice assignment for strings.\n  ##\n  ## If `b.len` is not exactly the number of elements that are referred to\n  ## by `x`, a `splice`:idx: is performed:\n  ##\n  runnableExamples:\n    var s = \"abcdefgh\"\n    s[1 .. ^2] = \"xyz\"\n    assert s == \"axyzh\"\n\n  var a = s ^^ x.a\n  var L = (s ^^ x.b) - a + 1\n  if L == b.len:\n    for i in 0..<L: s[i+a] = b[i]\n  else:\n    spliceImpl(s, a, L, b)\n\nproc `[]`*[Idx, T; U, V: Ordinal](a: array[Idx, T], x: HSlice[U, V]): seq[T] =\n  ## Slice operation for arrays.\n  ## Returns the inclusive range `[a[x.a], a[x.b]]`:\n  ##\n  ## .. code-block:: Nim\n  ##    var a = [1, 2, 3, 4]\n  ##    assert a[0..2] == @[1, 2, 3]\n  let xa = a ^^ x.a\n  let L = (a ^^ x.b) - xa + 1\n  result = newSeq[T](L)\n  for i in 0..<L: result[i] = a[Idx(i + xa)]\n\nproc `[]=`*[Idx, T; U, V: Ordinal](a: var array[Idx, T], x: HSlice[U, V], b: openArray[T]) =\n  ## Slice assignment for arrays.\n  ##\n  ## .. code-block:: Nim\n  ##   var a = [10, 20, 30, 40, 50]\n  ##   a[1..2] = @[99, 88]\n  ##   assert a == [10, 99, 88, 40, 50]\n  let xa = a ^^ x.a\n  let L = (a ^^ x.b) - xa + 1\n  if L == b.len:\n    for i in 0..<L: a[Idx(i + xa)] = b[i]\n  else:\n    sysFatal(RangeDefect, \"different lengths for slice assignment\")\n\nproc `[]`*[T; U, V: Ordinal](s: openArray[T], x: HSlice[U, V]): seq[T] =\n  ## Slice operation for sequences.\n  ## Returns the inclusive range `[s[x.a], s[x.b]]`:\n  ##\n  ## .. code-block:: Nim\n  ##    var s = @[1, 2, 3, 4]\n  ##    assert s[0..2] == @[1, 2, 3]\n  let a = s ^^ x.a\n  let L = (s ^^ x.b) - a + 1\n  newSeq(result, L)\n  for i in 0 ..< L: result[i] = s[i + a]\n\nproc `[]=`*[T; U, V: Ordinal](s: var seq[T], x: HSlice[U, V], b: openArray[T]) =\n  ## Slice assignment for sequences.\n  ##\n  ## If `b.len` is not exactly the number of elements that are referred to\n  ## by `x`, a `splice`:idx: is performed.\n  runnableExamples:\n    var s = @\"abcdefgh\"\n    s[1 .. ^2] = @\"xyz\"\n    assert s == @\"axyzh\"\n\n  let a = s ^^ x.a\n  let L = (s ^^ x.b) - a + 1\n  if L == b.len:\n    for i in 0 ..< L: s[i+a] = b[i]\n  else:\n    spliceImpl(s, a, L, b)\n\nproc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline.} =\n  system.`[]`(s, s.len - int(i))\n\nproc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline.} =\n  a[Idx(a.len - int(i) + int low(a))]\nproc `[]`*(s: string; i: BackwardsIndex): char {.inline.} = s[s.len - int(i)]\n\nproc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline.} =\n  system.`[]`(s, s.len - int(i))\nproc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline.} =\n  a[Idx(a.len - int(i) + int low(a))]\nproc `[]`*(s: var string; i: BackwardsIndex): var char {.inline.} = s[s.len - int(i)]\n\nproc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline.} =\n  system.`[]=`(s, s.len - int(i), x)\nproc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline.} =\n  a[Idx(a.len - int(i) + int low(a))] = x\nproc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline.} =\n  s[s.len - int(i)] = x\n\nproc slurp*(filename: string): string {.magic: \"Slurp\".}\n  ## This is an alias for `staticRead <#staticRead,string>`_.\n\nproc staticRead*(filename: string): string {.magic: \"Slurp\".}\n  ## Compile-time `readFile <io.html#readFile,string>`_ proc for easy\n  ## `resource`:idx: embedding:\n  ##\n  ## The maximum file size limit that `staticRead` and `slurp` can read is\n  ## near or equal to the *free* memory of the device you are using to compile.\n  ##\n  ## .. code-block:: Nim\n  ##     const myResource = staticRead\"mydatafile.bin\"\n  ##\n  ## `slurp <#slurp,string>`_ is an alias for `staticRead`.\n\nproc gorge*(command: string, input = \"\", cache = \"\"): string {.\n  magic: \"StaticExec\".} = discard\n  ## This is an alias for `staticExec <#staticExec,string,string,string>`_.\n\nproc staticExec*(command: string, input = \"\", cache = \"\"): string {.\n  magic: \"StaticExec\".} = discard\n  ## Executes an external process at compile-time and returns its text output\n  ## (stdout + stderr).\n  ##\n  ## If `input` is not an empty string, it will be passed as a standard input\n  ## to the executed program.\n  ##\n  ## .. code-block:: Nim\n  ##     const buildInfo = \"Revision \" & staticExec(\"git rev-parse HEAD\") &\n  ##                       \"\\nCompiled on \" & staticExec(\"uname -v\")\n  ##\n  ## `gorge <#gorge,string,string,string>`_ is an alias for `staticExec`.\n  ##\n  ## Note that you can use this proc inside a pragma like\n  ## `passc <manual.html#implementation-specific-pragmas-passc-pragma>`_ or\n  ## `passl <manual.html#implementation-specific-pragmas-passl-pragma>`_.\n  ##\n  ## If `cache` is not empty, the results of `staticExec` are cached within\n  ## the `nimcache` directory. Use `--forceBuild` to get rid of this caching\n  ## behaviour then. `command & input & cache` (the concatenated string) is\n  ## used to determine whether the entry in the cache is still valid. You can\n  ## use versioning information for `cache`:\n  ##\n  ## .. code-block:: Nim\n  ##     const stateMachine = staticExec(\"dfaoptimizer\", \"input\", \"0.8.0\")\n\nproc gorgeEx*(command: string, input = \"\", cache = \"\"): tuple[output: string,\n                                                              exitCode: int] =\n  ## Similar to `gorge <#gorge,string,string,string>`_ but also returns the\n  ## precious exit code.\n  discard\n\n\nproc `+=`*[T: float|float32|float64] (x: var T, y: T) {.\n  inline, noSideEffect.} =\n  ## Increments in place a floating point number.\n  x = x + y\n\nproc `-=`*[T: float|float32|float64] (x: var T, y: T) {.\n  inline, noSideEffect.} =\n  ## Decrements in place a floating point number.\n  x = x - y\n\nproc `*=`*[T: float|float32|float64] (x: var T, y: T) {.\n  inline, noSideEffect.} =\n  ## Multiplies in place a floating point number.\n  x = x * y\n\nproc `/=`*(x: var float64, y: float64) {.inline, noSideEffect.} =\n  ## Divides in place a floating point number.\n  x = x / y\n\nproc `/=`*[T: float|float32](x: var T, y: T) {.inline, noSideEffect.} =\n  ## Divides in place a floating point number.\n  x = x / y\n\nproc `&=`*(x: var string, y: string) {.magic: \"AppendStrStr\", noSideEffect.}\n  ## Appends in place to a string.\n  ##\n  ## .. code-block:: Nim\n  ##   var a = \"abc\"\n  ##   a &= \"de\" # a <- \"abcde\"\n\ntemplate `&=`*(x, y: typed) =\n  ## Generic 'sink' operator for Nim.\n  ##\n  ## For files an alias for `write`.\n  ## If not specialized further, an alias for `add`.\n  add(x, y)\nwhen declared(File):\n  template `&=`*(f: File, x: typed) = write(f, x)\n\ntemplate currentSourcePath*: string = instantiationInfo(-1, true).filename\n  ## Returns the full file-system path of the current source.\n  ##\n  ## To get the directory containing the current source, use it with\n  ## `os.parentDir() <os.html#parentDir%2Cstring>`_ as `currentSourcePath.parentDir()`.\n  ##\n  ## The path returned by this template is set at compile time.\n  ##\n  ## See the docstring of `macros.getProjectPath() <macros.html#getProjectPath>`_\n  ## for an example to see the distinction between the `currentSourcePath`\n  ## and `getProjectPath`.\n  ##\n  ## See also:\n  ## * `getCurrentDir proc <os.html#getCurrentDir>`_\n\nwhen compileOption(\"rangechecks\"):\n  template rangeCheck*(cond) =\n    ## Helper for performing user-defined range checks.\n    ## Such checks will be performed only when the `rangechecks`\n    ## compile-time option is enabled.\n    if not cond: sysFatal(RangeDefect, \"range check failed\")\nelse:\n  template rangeCheck*(cond) = discard\n\nproc shallow*[T](s: var seq[T]) {.noSideEffect, inline.} =\n  ## Marks a sequence `s` as `shallow`:idx:. Subsequent assignments will not\n  ## perform deep copies of `s`.\n  ##\n  ## This is only useful for optimization purposes.\n  if s.len == 0: return\n  when not defined(js) and not defined(nimscript) and not defined(nimSeqsV2):\n    var s = cast[PGenericSeq](s)\n    s.reserved = s.reserved or seqShallowFlag\n\nproc shallow*(s: var string) {.noSideEffect, inline.} =\n  ## Marks a string `s` as `shallow`:idx:. Subsequent assignments will not\n  ## perform deep copies of `s`.\n  ##\n  ## This is only useful for optimization purposes.\n  when not defined(js) and not defined(nimscript) and not defined(nimSeqsV2):\n    var s = cast[PGenericSeq](s)\n    if s == nil:\n      s = cast[PGenericSeq](newString(0))\n    # string literals cannot become 'shallow':\n    if (s.reserved and strlitFlag) == 0:\n      s.reserved = s.reserved or seqShallowFlag\n\ntype\n  NimNodeObj = object\n\n  NimNode* {.magic: \"PNimrodNode\".} = ref NimNodeObj\n    ## Represents a Nim AST node. Macros operate on this type.\n\nwhen defined(nimV2):\n  import system/repr_v2\n  export repr_v2\n\nmacro varargsLen*(x: varargs[untyped]): int {.since: (1, 1).} =\n  ## returns number of variadic arguments in `x`\n  proc varargsLenImpl(x: NimNode): NimNode {.magic: \"LengthOpenArray\", noSideEffect.}\n  varargsLenImpl(x)\n\nwhen false:\n  template eval*(blk: typed): typed =\n    ## Executes a block of code at compile time just as if it was a macro.\n    ##\n    ## Optionally, the block can return an AST tree that will replace the\n    ## eval expression.\n    macro payload: typed {.gensym.} = blk\n    payload()\n\nwhen hasAlloc or defined(nimscript):\n  proc insert*(x: var string, item: string, i = 0.Natural) {.noSideEffect.} =\n    ## Inserts `item` into `x` at position `i`.\n    ##\n    ## .. code-block:: Nim\n    ##   var a = \"abc\"\n    ##   a.insert(\"zz\", 0) # a <- \"zzabc\"\n    var xl = x.len\n    setLen(x, xl+item.len)\n    var j = xl-1\n    while j >= i:\n      shallowCopy(x[j+item.len], x[j])\n      dec(j)\n    j = 0\n    while j < item.len:\n      x[j+i] = item[j]\n      inc(j)\n\nwhen declared(initDebugger):\n  initDebugger()\n\nproc addEscapedChar*(s: var string, c: char) {.noSideEffect, inline.} =\n  ## Adds a char to string `s` and applies the following escaping:\n  ##\n  ## * replaces any ``\\`` by `\\\\`\n  ## * replaces any `'` by `\\'`\n  ## * replaces any `\"` by `\\\"`\n  ## * replaces any `\\a` by `\\\\a`\n  ## * replaces any `\\b` by `\\\\b`\n  ## * replaces any `\\t` by `\\\\t`\n  ## * replaces any `\\n` by `\\\\n`\n  ## * replaces any `\\v` by `\\\\v`\n  ## * replaces any `\\f` by `\\\\f`\n  ## * replaces any `\\r` by `\\\\r`\n  ## * replaces any `\\e` by `\\\\e`\n  ## * replaces any other character not in the set `{\\21..\\126}`\n  ##   by `\\xHH` where `HH` is its hexadecimal value\n  ##\n  ## The procedure has been designed so that its output is usable for many\n  ## different common syntaxes.\n  ##\n  ## .. warning:: This is **not correct** for producing ANSI C code!\n  ##\n  case c\n  of '\\a': s.add \"\\\\a\" # \\x07\n  of '\\b': s.add \"\\\\b\" # \\x08\n  of '\\t': s.add \"\\\\t\" # \\x09\n  of '\\n': s.add \"\\\\n\" # \\x0A\n  of '\\v': s.add \"\\\\v\" # \\x0B\n  of '\\f': s.add \"\\\\f\" # \\x0C\n  of '\\r': (when defined(nimLegacyAddEscapedCharx0D): s.add \"\\\\c\" else: s.add \"\\\\r\") # \\x0D\n  of '\\e': s.add \"\\\\e\" # \\x1B\n  of '\\\\': s.add(\"\\\\\\\\\")\n  of '\\'': s.add(\"\\\\'\")\n  of '\\\"': s.add(\"\\\\\\\"\")\n  of {'\\32'..'\\126'} - {'\\\\', '\\'', '\\\"'}: s.add(c)\n  else:\n    s.add(\"\\\\x\")\n    const HexChars = \"0123456789ABCDEF\"\n    let n = ord(c)\n    s.add(HexChars[int((n and 0xF0) shr 4)])\n    s.add(HexChars[int(n and 0xF)])\n\nproc addQuoted*[T](s: var string, x: T) =\n  ## Appends `x` to string `s` in place, applying quoting and escaping\n  ## if `x` is a string or char.\n  ##\n  ## See `addEscapedChar <#addEscapedChar,string,char>`_\n  ## for the escaping scheme. When `x` is a string, characters in the\n  ## range `{\\128..\\255}` are never escaped so that multibyte UTF-8\n  ## characters are untouched (note that this behavior is different from\n  ## `addEscapedChar`).\n  ##\n  ## The Nim standard library uses this function on the elements of\n  ## collections when producing a string representation of a collection.\n  ## It is recommended to use this function as well for user-side collections.\n  ## Users may overload `addQuoted` for custom (string-like) types if\n  ## they want to implement a customized element representation.\n  ##\n  ## .. code-block:: Nim\n  ##   var tmp = \"\"\n  ##   tmp.addQuoted(1)\n  ##   tmp.add(\", \")\n  ##   tmp.addQuoted(\"string\")\n  ##   tmp.add(\", \")\n  ##   tmp.addQuoted('c')\n  ##   assert(tmp == \"\"\"1, \"string\", 'c'\"\"\")\n  when T is string or T is cstring:\n    s.add(\"\\\"\")\n    for c in x:\n      # Only ASCII chars are escaped to avoid butchering\n      # multibyte UTF-8 characters.\n      if c <= 127.char:\n        s.addEscapedChar(c)\n      else:\n        s.add c\n    s.add(\"\\\"\")\n  elif T is char:\n    s.add(\"'\")\n    s.addEscapedChar(x)\n    s.add(\"'\")\n  # prevent temporary string allocation\n  elif T is SomeInteger:\n    s.addInt(x)\n  elif T is SomeFloat:\n    s.addFloat(x)\n  elif compiles(s.add(x)):\n    s.add(x)\n  else:\n    s.add($x)\n\nproc locals*(): RootObj {.magic: \"Plugin\", noSideEffect.} =\n  ## Generates a tuple constructor expression listing all the local variables\n  ## in the current scope.\n  ##\n  ## This is quite fast as it does not rely\n  ## on any debug or runtime information. Note that in contrast to what\n  ## the official signature says, the return type is *not* `RootObj` but a\n  ## tuple of a structure that depends on the current scope. Example:\n  ##\n  ## .. code-block:: Nim\n  ##   proc testLocals() =\n  ##     var\n  ##       a = \"something\"\n  ##       b = 4\n  ##       c = locals()\n  ##       d = \"super!\"\n  ##\n  ##     b = 1\n  ##     for name, value in fieldPairs(c):\n  ##       echo \"name \", name, \" with value \", value\n  ##     echo \"B is \", b\n  ##   # -> name a with value something\n  ##   # -> name b with value 4\n  ##   # -> B is 1\n  discard\n\nwhen hasAlloc and notJSnotNims:\n  # XXX how to implement 'deepCopy' is an open problem.\n  proc deepCopy*[T](x: var T, y: T) {.noSideEffect, magic: \"DeepCopy\".} =\n    ## Performs a deep copy of `y` and copies it into `x`.\n    ##\n    ## This is also used by the code generator\n    ## for the implementation of `spawn`.\n    ##\n    ## For `--gc:arc` or `--gc:orc` deepcopy support has to be enabled\n    ## via `--deepcopy:on`.\n    discard\n\n  proc deepCopy*[T](y: T): T =\n    ## Convenience wrapper around `deepCopy` overload.\n    deepCopy(result, y)\n\n  include \"system/deepcopy\"\n\nproc procCall*(x: untyped) {.magic: \"ProcCall\", compileTime.} =\n  ## Special magic to prohibit dynamic binding for `method`:idx: calls.\n  ## This is similar to `super`:idx: in ordinary OO languages.\n  ##\n  ## .. code-block:: Nim\n  ##   # 'someMethod' will be resolved fully statically:\n  ##   procCall someMethod(a, b)\n  discard\n\n\nproc `==`*(x, y: cstring): bool {.magic: \"EqCString\", noSideEffect,\n                                   inline.} =\n  ## Checks for equality between two `cstring` variables.\n  proc strcmp(a, b: cstring): cint {.noSideEffect,\n    importc, header: \"<string.h>\".}\n  if pointer(x) == pointer(y): result = true\n  elif x.isNil or y.isNil: result = false\n  else: result = strcmp(x, y) == 0\n\nwhen true: # xxx PRTEMP remove\n  # bug #9149; ensure that 'typeof(nil)' does not match *too* well by using 'typeof(nil) | typeof(nil)',\n  # especially for converters, see tests/overload/tconverter_to_string.nim\n  # Eventually we will be able to remove this hack completely.\n  proc `==`*(x: string; y: typeof(nil) | typeof(nil)): bool {.\n      error: \"'nil' is now invalid for 'string'\".} =\n    discard\n  proc `==`*(x: typeof(nil) | typeof(nil); y: string): bool {.\n      error: \"'nil' is now invalid for 'string'\".} =\n    discard\n\ntemplate closureScope*(body: untyped): untyped =\n  ## Useful when creating a closure in a loop to capture local loop variables by\n  ## their current iteration values.\n  ##\n  ## Note: This template may not work in some cases, use\n  ## `capture <sugar.html#capture.m,varargs[typed],untyped>`_ instead.\n  ##\n  ## Example:\n  ##\n  ## .. code-block:: Nim\n  ##   var myClosure : proc()\n  ##   # without closureScope:\n  ##   for i in 0 .. 5:\n  ##     let j = i\n  ##     if j == 3:\n  ##       myClosure = proc() = echo j\n  ##   myClosure() # outputs 5. `j` is changed after closure creation\n  ##   # with closureScope:\n  ##   for i in 0 .. 5:\n  ##     closureScope: # Everything in this scope is locked after closure creation\n  ##       let j = i\n  ##       if j == 3:\n  ##         myClosure = proc() = echo j\n  ##   myClosure() # outputs 3\n  (proc() = body)()\n\ntemplate once*(body: untyped): untyped =\n  ## Executes a block of code only once (the first time the block is reached).\n  ##\n  ## .. code-block:: Nim\n  ##\n  ##  proc draw(t: Triangle) =\n  ##    once:\n  ##      graphicsInit()\n  ##    line(t.p1, t.p2)\n  ##    line(t.p2, t.p3)\n  ##    line(t.p3, t.p1)\n  ##\n  var alreadyExecuted {.global.} = false\n  if not alreadyExecuted:\n    alreadyExecuted = true\n    body\n\n{.pop.} # warning[GcMem]: off, warning[Uninit]: off\n\nproc substr*(s: string, first, last: int): string =\n  ## Copies a slice of `s` into a new string and returns this new\n  ## string.\n  ##\n  ## The bounds `first` and `last` denote the indices of\n  ## the first and last characters that shall be copied. If `last`\n  ## is omitted, it is treated as `high(s)`. If `last >= s.len`, `s.len`\n  ## is used instead: This means `substr` can also be used to `cut`:idx:\n  ## or `limit`:idx: a string's length.\n  runnableExamples:\n    let a = \"abcdefgh\"\n    assert a.substr(2, 5) == \"cdef\"\n    assert a.substr(2) == \"cdefgh\"\n    assert a.substr(5, 99) == \"fgh\"\n\n  let first = max(first, 0)\n  let L = max(min(last, high(s)) - first + 1, 0)\n  result = newString(L)\n  for i in 0 .. L-1:\n    result[i] = s[i+first]\n\nproc substr*(s: string, first = 0): string =\n  result = substr(s, first, high(s))\n\nwhen defined(nimconfig):\n  include \"system/nimscript\"\n\nwhen not defined(js):\n  proc toOpenArray*[T](x: ptr UncheckedArray[T]; first, last: int): openArray[T] {.\n    magic: \"Slice\".}\n  when defined(nimToOpenArrayCString):\n    proc toOpenArray*(x: cstring; first, last: int): openArray[char] {.\n      magic: \"Slice\".}\n    proc toOpenArrayByte*(x: cstring; first, last: int): openArray[byte] {.\n      magic: \"Slice\".}\n\nproc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {.\n  magic: \"Slice\".}\nproc toOpenArray*[T](x: openArray[T]; first, last: int): openArray[T] {.\n  magic: \"Slice\".}\nproc toOpenArray*[I, T](x: array[I, T]; first, last: I): openArray[T] {.\n  magic: \"Slice\".}\nproc toOpenArray*(x: string; first, last: int): openArray[char] {.\n  magic: \"Slice\".}\n\nproc toOpenArrayByte*(x: string; first, last: int): openArray[byte] {.\n  magic: \"Slice\".}\nproc toOpenArrayByte*(x: openArray[char]; first, last: int): openArray[byte] {.\n  magic: \"Slice\".}\nproc toOpenArrayByte*(x: seq[char]; first, last: int): openArray[byte] {.\n  magic: \"Slice\".}\n\ntype\n  ForLoopStmt* {.compilerproc.} = object ## \\\n    ## A special type that marks a macro as a `for-loop macro`:idx:.\n    ## See `\"For Loop Macro\" <manual.html#macros-for-loop-macro>`_.\n\nwhen defined(genode):\n  var componentConstructHook*: proc (env: GenodeEnv) {.nimcall.}\n    ## Hook into the Genode component bootstrap process.\n    ##\n    ## This hook is called after all globals are initialized.\n    ## When this hook is set the component will not automatically exit,\n    ## call `quit` explicitly to do so. This is the only available method\n    ## of accessing the initial Genode environment.\n\n  proc nim_component_construct(env: GenodeEnv) {.exportc.} =\n    ## Procedure called during `Component::construct` by the loader.\n    if componentConstructHook.isNil:\n      env.quit(programResult)\n        # No native Genode application initialization,\n        # exit as would POSIX.\n    else:\n      componentConstructHook(env)\n        # Perform application initialization\n        # and return to thread entrypoint.\n\n\nimport system/widestrs\nexport widestrs\n\nimport system/io\nexport io\n\nwhen not defined(createNimHcr) and not defined(nimscript):\n  include nimhcr\n\nwhen notJSnotNims and not defined(nimSeqsV2):\n  proc prepareMutation*(s: var string) {.inline.} =\n    ## String literals (e.g. \"abc\", etc) in the ARC/ORC mode are \"copy on write\",\n    ## therefore you should call `prepareMutation` before modifying the strings\n    ## via `addr`.\n    runnableExamples(\"--gc:arc\"):\n      var x = \"abc\"\n      var y = \"defgh\"\n      prepareMutation(y) # without this, you may get a `SIGBUS` or `SIGSEGV`\n      moveMem(addr y[0], addr x[0], x.len)\n      assert y == \"abcgh\"\n    discard\n"}}}
Unable to parse data as RequestMessage
Got valid Notification message of type textDocument/didOpen
New document opened for URI: file:///home/maskray/Dev/Nim/lib/system.nim saving to /tmp/nimlsp/000000008B897647.nim
Initialising project with /home/maskray/Dev/Nim/lib/system.nim:/home/maskray/.choosenim/toolchains/nim-#devel
/home/maskray/Dev/nimlsp/src/nimlsp.nim(502) nimlsp
/home/maskray/.choosenim/toolchains/nim-#devel/nimsuggest/nimsuggest.nim(727) initNimSuggest
/home/maskray/.choosenim/toolchains/nim-#devel/nimsuggest/nimsuggest.nim(684) mockCommand
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/modules.nim(178) compileProject
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/modules.nim(98) compileModule
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/passes.nim(180) processModule
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/passes.nim(73) processTopLevelStmt
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/sem.nim(658) myProcess
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/sem.nim(621) semStmtAndGenerateGenerics
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/semstmts.nim(2363) semStmt
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/semexprs.nim(1065) semExprNoType
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/semexprs.nim(3001) semExpr
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/semstmts.nim(2305) semStmtList
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/semexprs.nim(3006) semExpr
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/semstmts.nim(1455) semTypeSection
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/semstmts.nim(1233) typeSectionRightSidePass
/home/maskray/.choosenim/toolchains/nim-#devel/compiler/semtypes.nim(2079) processMagicType
/home/maskray/.choosenim/toolchains/nim-#devel/lib/system/assertions.nim(38) failedAssertImpl
/home/maskray/.choosenim/toolchains/nim-#devel/lib/system/assertions.nim(28) raiseAssert
/home/maskray/.choosenim/toolchains/nim-#devel/lib/system/fatal.nim(53) sysFatal
Error: unhandled exception: /home/maskray/.choosenim/toolchains/nim-#devel/compiler/semtypes.nim(2079, 12) `c.graph.sysTypes[tySequence] == nil`  [AssertionDefect]
[Error  - 8:46:39 PM] /home/maskray/Dev/nimlsp/nimlsp exited with code: 1
[Info  - 8:46:39 PM] Connection to server got closed. Server will restart.
Version: 0.3.2
explicitSourcePath: /home/maskray/.choosenim/toolchains/nim-#devel
Trying to read frame
...
PMunch commented 2 years ago

Hmm, that log still points to initNimSuggest which is the initial call to the nimsuggest library. So this is another bug in nimsuggest unfortunately. Here is the stacktrace I managed to extract from my build of NimLSP:

/home/peter/Projects/nimlsp/src/nimlsp.nim(502) nimlsp
/home/peter/.choosenim/toolchains/nim-#devel/nimsuggest/nimsuggest.nim(727) initNimSuggest
/home/peter/.choosenim/toolchains/nim-#devel/nimsuggest/nimsuggest.nim(684) mockCommand
/home/peter/.choosenim/toolchains/nim-#devel/compiler/modules.nim(178) compileProject
/home/peter/.choosenim/toolchains/nim-#devel/compiler/modules.nim(98) compileModule
/home/peter/.choosenim/toolchains/nim-#devel/compiler/passes.nim(180) processModule
/home/peter/.choosenim/toolchains/nim-#devel/compiler/passes.nim(73) processTopLevelStmt
/home/peter/.choosenim/toolchains/nim-#devel/compiler/sem.nim(658) myProcess
/home/peter/.choosenim/toolchains/nim-#devel/compiler/sem.nim(621) semStmtAndGenerateGenerics
/home/peter/.choosenim/toolchains/nim-#devel/compiler/semstmts.nim(2363) semStmt
/home/peter/.choosenim/toolchains/nim-#devel/compiler/semexprs.nim(1065) semExprNoType
/home/peter/.choosenim/toolchains/nim-#devel/compiler/semexprs.nim(3001) semExpr
/home/peter/.choosenim/toolchains/nim-#devel/compiler/semstmts.nim(2305) semStmtList
/home/peter/.choosenim/toolchains/nim-#devel/compiler/semexprs.nim(3006) semExpr
/home/peter/.choosenim/toolchains/nim-#devel/compiler/semstmts.nim(1455) semTypeSection
/home/peter/.choosenim/toolchains/nim-#devel/compiler/semstmts.nim(1233) typeSectionRightSidePass
/home/peter/.choosenim/toolchains/nim-#devel/compiler/semtypes.nim(2079) processMagicType
/home/peter/.choosenim/toolchains/nim-#devel/lib/system/assertions.nim(38) failedAssertImpl
/home/peter/.choosenim/toolchains/nim-#devel/lib/system/assertions.nim(28) raiseAssert
/home/peter/.choosenim/toolchains/nim-#devel/lib/system/fatal.nim(53) sysFatal
Error: unhandled exception: /home/peter/.choosenim/toolchains/nim-#devel/compiler/semtypes.nim(2079, 12) `c.graph.sysTypes[tySequence] == nil`  [AssertionDefect]
ringabout commented 2 years ago

yeah, I can reproduce the issue with nim check

nim check lib/system.nim
Error: unhandled exception: semtypes.nim(2079, 12) `c.graph.sysTypes[tySequence] == nil`  [AssertionDefect]

Edit: It works with nim check --lib:lib lib/system.nim, maybe it is caused by incompatibilities between Nim compiler and system.nim.

PMunch commented 2 years ago

I pulled the latest Nim sources and built against that, then I chose it via choosenim and tried to open lib/system.nim. NimLSP doesn't immediately crash, but as soon as I try to get a definition I get the same error:

Running equivalent of: def /home/peter/Projects/Nim/lib/system.nim;/tmp/nimlsp/000000009388EA1A.nim:502:42
/home/peter/Projects/nimlsp/src/nimlsp.nim(410) nimlsp
/home/peter/Projects/nimlsp/src/nimlsppkg/suggestlib.nim(110) def
/home/peter/Projects/Nim/nimsuggest/nimsuggest.nim(760) runCmd
/home/peter/Projects/Nim/nimsuggest/nimsuggest.nim(194) executeNoHooks
/home/peter/Projects/Nim/compiler/modules.nim(175) compileProject
/home/peter/Projects/Nim/compiler/modules.nim(98) compileModule
/home/peter/Projects/Nim/compiler/passes.nim(180) processModule
/home/peter/Projects/Nim/compiler/passes.nim(73) processTopLevelStmt
/home/peter/Projects/Nim/compiler/sem.nim(658) myProcess
/home/peter/Projects/Nim/compiler/sem.nim(621) semStmtAndGenerateGenerics
/home/peter/Projects/Nim/compiler/semstmts.nim(2363) semStmt
/home/peter/Projects/Nim/compiler/semexprs.nim(1065) semExprNoType
/home/peter/Projects/Nim/compiler/semexprs.nim(3001) semExpr
/home/peter/Projects/Nim/compiler/semstmts.nim(2305) semStmtList
/home/peter/Projects/Nim/compiler/semexprs.nim(3006) semExpr
/home/peter/Projects/Nim/compiler/semstmts.nim(1455) semTypeSection
/home/peter/Projects/Nim/compiler/semstmts.nim(1233) typeSectionRightSidePass
/home/peter/Projects/Nim/compiler/semtypes.nim(2079) processMagicType
/home/peter/Projects/Nim/lib/system/assertions.nim(38) failedAssertImpl
/home/peter/Projects/Nim/lib/system/assertions.nim(28) raiseAssert
/home/peter/Projects/Nim/lib/system/fatal.nim(53) sysFatal
Error: unhandled exception: /home/peter/Projects/Nim/compiler/semtypes.nim(2079, 12) `c.graph.sysTypes[tySequence] == nil`  [AssertionDefect]
PMunch commented 2 years ago

Curiously starting nimsuggest from those same sources and running that "equivalent" command doesn't result in a crash..

PMunch commented 2 years ago

Aha, building nimsuggest withouth -d:danger (like the build_all.sh script does) made it produce the same error:

bin/nimsuggest lib/system.nim                         
usage: sug|con|def|use|dus|chk|mod|highlight|outline|known|project file.nim[;dirtyfile.nim]:line:col
type 'quit' to quit
type 'debug' to toggle debug mode on/off
type 'terse' to toggle terse mode on/off
> def /home/peter/Projects/Nim/lib/system.nim;/tmp/nimlsp/000000009388EA1A.nim:502:42
/home/peter/Projects/Nim/nimsuggest/nimsuggest.nim(651) nimsuggest
/home/peter/Projects/Nim/nimsuggest/nimsuggest.nim(648) handleCmdLine
/home/peter/Projects/Nim/nimsuggest/nimsuggest.nim(548) mainCommand
/home/peter/Projects/Nim/nimsuggest/nimsuggest.nim(497) mainThread
/home/peter/Projects/Nim/nimsuggest/nimsuggest.nim(463) execCmd
/home/peter/Projects/Nim/nimsuggest/nimsuggest.nim(210) execute
/home/peter/Projects/Nim/nimsuggest/nimsuggest.nim(194) executeNoHooks
/home/peter/Projects/Nim/compiler/modules.nim(175) compileProject
/home/peter/Projects/Nim/compiler/modules.nim(98) compileModule
/home/peter/Projects/Nim/compiler/passes.nim(180) processModule
/home/peter/Projects/Nim/compiler/passes.nim(73) processTopLevelStmt
/home/peter/Projects/Nim/compiler/sem.nim(658) myProcess
/home/peter/Projects/Nim/compiler/sem.nim(621) semStmtAndGenerateGenerics
/home/peter/Projects/Nim/compiler/semstmts.nim(2363) semStmt
/home/peter/Projects/Nim/compiler/semexprs.nim(1065) semExprNoType
/home/peter/Projects/Nim/compiler/semexprs.nim(3001) semExpr
/home/peter/Projects/Nim/compiler/semstmts.nim(2305) semStmtList
/home/peter/Projects/Nim/compiler/semexprs.nim(3006) semExpr
/home/peter/Projects/Nim/compiler/semstmts.nim(1455) semTypeSection
/home/peter/Projects/Nim/compiler/semstmts.nim(1233) typeSectionRightSidePass
/home/peter/Projects/Nim/compiler/semtypes.nim(2079) processMagicType
/home/peter/Projects/Nim/lib/system/assertions.nim(38) failedAssertImpl
/home/peter/Projects/Nim/lib/system/assertions.nim(28) raiseAssert
/home/peter/Projects/Nim/lib/system/fatal.nim(53) sysFatal
Error: unhandled exception: /home/peter/Projects/Nim/compiler/semtypes.nim(2079, 12) `c.graph.sysTypes[tySequence] == nil`  [AssertionDefect]

The NimLSP version I tested with was also built as a debug build to get better stracktraces.

EDIT: Commented out the assert and rebuilt NimLSP, seems to work better now. Any idea what that assert is supposed to do @xflywind?

ringabout commented 2 years ago

I'm not sure, but it was reported already:

https://github.com/nim-lang/Nim/issues/9718

header 2: https://github.com/nim-lang/Nim/issues/14545

ringabout commented 2 years ago

see https://github.com/nim-lang/Nim/pull/18988

MaskRay commented 2 years ago
choosenim update devel --latest
nimble install lsp  # overwrite
nvim lib/system.vim  # doesn't crash!

Thanks for the quick fix.

ringabout commented 2 years ago

Thanks for the quick fix.

@MaskRay You are welcome.

Btw, 我在知乎关注了大佬,希望大佬不要嫌弃这个小工坊制作的编程语言 ꒰๑• ̫•๑꒱ ♡

MaskRay commented 2 years ago

/ᐠ≗ᆽ≗๑ᐟ \ 嚇壞。。。 Nim 很好啊= = 正在緩慢學習

(I might use Fix assert failure in nimsuggest mode\n\nfix #18985 instead of fix #18985 (nimsuggest doesn't work well) which is less clear about the intention.)

ringabout commented 2 years ago

(I might use Fix assert failure in nimsuggest mode\n\nfix #18985 instead of fix #18985 (nimsuggest doesn't work well) which is less clear about the intention.)

haha, thanks for the suggestions!