12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795 |
- #
- #
- # Nim's Runtime Library
- # (c) Copyright 2015 Andreas Rumpf
- #
- # See the file "copying.txt", included in this
- # distribution, for details about the copyright.
- #
- ## The compiler depends on the System module to work properly and the System
- ## module depends on the compiler. Most of the routines listed here use
- ## special compiler magic.
- ##
- ## Each module implicitly imports the System module; it must not be listed
- ## explicitly. Because of this there cannot be a user-defined module named
- ## `system`.
- ##
- ## System module
- ## =============
- ##
- ## .. include:: ./system_overview.rst
- include "system/basic_types"
- func zeroDefault*[T](_: typedesc[T]): T {.magic: "ZeroDefault".} =
- ## returns the default value of the type `T`.
- include "system/compilation"
- {.push warning[GcMem]: off, warning[Uninit]: off.}
- # {.push hints: off.}
- type
- `static`*[T] {.magic: "Static".}
- ## Meta type representing all values that can be evaluated at compile-time.
- ##
- ## The type coercion `static(x)` can be used to force the compile-time
- ## evaluation of the given expression `x`.
- `type`*[T] {.magic: "Type".}
- ## Meta type representing the type of all type values.
- ##
- ## The coercion `type(x)` can be used to obtain the type of the given
- ## expression `x`.
- type
- TypeOfMode* = enum ## Possible modes of `typeof`.
- typeOfProc, ## Prefer the interpretation that means `x` is a proc call.
- typeOfIter ## Prefer the interpretation that means `x` is an iterator call.
- proc typeof*(x: untyped; mode = typeOfIter): typedesc {.
- magic: "TypeOf", noSideEffect, compileTime.} =
- ## Builtin `typeof` operation for accessing the type of an expression.
- ## Since version 0.20.0.
- runnableExamples:
- proc myFoo(): float = 0.0
- iterator myFoo(): string = yield "abc"
- iterator myFoo2(): string = yield "abc"
- iterator myFoo3(): string {.closure.} = yield "abc"
- doAssert type(myFoo()) is string
- doAssert typeof(myFoo()) is string
- doAssert typeof(myFoo(), typeOfIter) is string
- doAssert typeof(myFoo3) is "iterator"
- doAssert typeof(myFoo(), typeOfProc) is float
- doAssert typeof(0.0, typeOfProc) is float
- doAssert typeof(myFoo3, typeOfProc) is "iterator"
- doAssert not compiles(typeof(myFoo2(), typeOfProc))
- # this would give: Error: attempting to call routine: 'myFoo2'
- # since `typeOfProc` expects a typed expression and `myFoo2()` can
- # only be used in a `for` context.
- proc `or`*(a, b: typedesc): typedesc {.magic: "TypeTrait", noSideEffect.}
- ## Constructs an `or` meta class.
- proc `and`*(a, b: typedesc): typedesc {.magic: "TypeTrait", noSideEffect.}
- ## Constructs an `and` meta class.
- proc `not`*(a: typedesc): typedesc {.magic: "TypeTrait", noSideEffect.}
- ## Constructs an `not` meta class.
- when defined(nimHasIterable):
- type
- iterable*[T] {.magic: IterableType.} ## Represents an expression that yields `T`
- type
- Ordinal*[T] {.magic: Ordinal.} ## Generic ordinal type. Includes integer,
- ## bool, character, and enumeration types
- ## as well as their subtypes. See also
- ## `SomeOrdinal`.
- proc `addr`*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} =
- ## Builtin `addr` operator for taking the address of a memory location.
- ##
- ## .. note:: This works for `let` variables or parameters
- ## for better interop with C. When you use it to write a wrapper
- ## for a C library and take the address of `let` variables or parameters,
- ## you should always check that the original library
- ## does never write to data behind the pointer that is returned from
- ## this procedure.
- ##
- ## Cannot be overloaded.
- ##
- ## ```
- ## var
- ## buf: seq[char] = @['a','b','c']
- ## p = buf[1].addr
- ## echo p.repr # ref 0x7faa35c40059 --> 'b'
- ## echo p[] # b
- ## ```
- discard
- proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} =
- ## .. warning:: `unsafeAddr` is a deprecated alias for `addr`,
- ## use `addr` instead.
- discard
- const ThisIsSystem = true
- proc internalNew*[T](a: var ref T) {.magic: "New", noSideEffect.}
- ## Leaked implementation detail. Do not use.
- proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.
- magic: "NewFinalize", noSideEffect.}
- ## Creates a new object of type `T` and returns a safe (traced)
- ## reference to it in `a`.
- ##
- ## When the garbage collector frees the object, `finalizer` is called.
- ## The `finalizer` may not keep a reference to the
- ## object pointed to by `x`. The `finalizer` cannot prevent the GC from
- ## freeing the object.
- ##
- ## **Note**: The `finalizer` refers to the type `T`, not to the object!
- ## This means that for each object of type `T` the finalizer will be called!
- proc wasMoved*[T](obj: var T) {.magic: "WasMoved", noSideEffect.} =
- ## Resets an object `obj` to its initial (binary zero) value to signify
- ## it was "moved" and to signify its destructor should do nothing and
- ## ideally be optimized away.
- discard
- proc move*[T](x: var T): T {.magic: "Move", noSideEffect.} =
- result = x
- wasMoved(x)
- type
- range*[T]{.magic: "Range".} ## Generic type to construct range types.
- array*[I, T]{.magic: "Array".} ## Generic type to construct
- ## fixed-length arrays.
- openArray*[T]{.magic: "OpenArray".} ## Generic type to construct open arrays.
- ## Open arrays are implemented as a
- ## pointer to the array data and a
- ## length field.
- varargs*[T]{.magic: "Varargs".} ## Generic type to construct a varargs type.
- seq*[T]{.magic: "Seq".} ## Generic type to construct sequences.
- set*[T]{.magic: "Set".} ## Generic type to construct bit sets.
- type
- UncheckedArray*[T]{.magic: "UncheckedArray".}
- ## Array with no bounds checking.
- type sink*[T]{.magic: "BuiltinType".}
- type lent*[T]{.magic: "BuiltinType".}
- proc high*[T: Ordinal|enum|range](x: T): T {.magic: "High", noSideEffect,
- deprecated: "Deprecated since v1.4; there should not be `high(value)`. Use `high(type)`.".}
- ## Returns the highest possible value of an ordinal value `x`.
- ##
- ## As a special semantic rule, `x` may also be a type identifier.
- ##
- ## **This proc is deprecated**, use this one instead:
- ## * `high(typedesc) <#high,typedesc[T]>`_
- ##
- ## ```
- ## high(2) # => 9223372036854775807
- ## ```
- proc high*[T: Ordinal|enum|range](x: typedesc[T]): T {.magic: "High", noSideEffect.}
- ## Returns the highest possible value of an ordinal or enum type.
- ##
- ## `high(int)` is Nim's way of writing `INT_MAX`:idx: or `MAX_INT`:idx:.
- ## ```
- ## high(int) # => 9223372036854775807
- ## ```
- ##
- ## See also:
- ## * `low(typedesc) <#low,typedesc[T]>`_
- proc high*[T](x: openArray[T]): int {.magic: "High", noSideEffect.}
- ## Returns the highest possible index of a sequence `x`.
- ## ```
- ## var s = @[1, 2, 3, 4, 5, 6, 7]
- ## high(s) # => 6
- ## for i in low(s)..high(s):
- ## echo s[i]
- ## ```
- ##
- ## See also:
- ## * `low(openArray) <#low,openArray[T]>`_
- proc high*[I, T](x: array[I, T]): I {.magic: "High", noSideEffect.}
- ## Returns the highest possible index of an array `x`.
- ##
- ## For empty arrays, the return type is `int`.
- ## ```
- ## var arr = [1, 2, 3, 4, 5, 6, 7]
- ## high(arr) # => 6
- ## for i in low(arr)..high(arr):
- ## echo arr[i]
- ## ```
- ##
- ## See also:
- ## * `low(array) <#low,array[I,T]>`_
- proc high*[I, T](x: typedesc[array[I, T]]): I {.magic: "High", noSideEffect.}
- ## Returns the highest possible index of an array type.
- ##
- ## For empty arrays, the return type is `int`.
- ## ```
- ## high(array[7, int]) # => 6
- ## ```
- ##
- ## See also:
- ## * `low(typedesc[array]) <#low,typedesc[array[I,T]]>`_
- proc high*(x: cstring): int {.magic: "High", noSideEffect.}
- ## Returns the highest possible index of a compatible string `x`.
- ## This is sometimes an O(n) operation.
- ##
- ## See also:
- ## * `low(cstring) <#low,cstring>`_
- proc high*(x: string): int {.magic: "High", noSideEffect.}
- ## Returns the highest possible index of a string `x`.
- ## ```
- ## var str = "Hello world!"
- ## high(str) # => 11
- ## ```
- ##
- ## See also:
- ## * `low(string) <#low,string>`_
- proc low*[T: Ordinal|enum|range](x: T): T {.magic: "Low", noSideEffect,
- deprecated: "Deprecated since v1.4; there should not be `low(value)`. Use `low(type)`.".}
- ## Returns the lowest possible value of an ordinal value `x`. As a special
- ## semantic rule, `x` may also be a type identifier.
- ##
- ## **This proc is deprecated**, use this one instead:
- ## * `low(typedesc) <#low,typedesc[T]>`_
- ##
- ## ```
- ## low(2) # => -9223372036854775808
- ## ```
- proc low*[T: Ordinal|enum|range](x: typedesc[T]): T {.magic: "Low", noSideEffect.}
- ## Returns the lowest possible value of an ordinal or enum type.
- ##
- ## `low(int)` is Nim's way of writing `INT_MIN`:idx: or `MIN_INT`:idx:.
- ## ```
- ## low(int) # => -9223372036854775808
- ## ```
- ##
- ## See also:
- ## * `high(typedesc) <#high,typedesc[T]>`_
- proc low*[T](x: openArray[T]): int {.magic: "Low", noSideEffect.}
- ## Returns the lowest possible index of a sequence `x`.
- ## ```
- ## var s = @[1, 2, 3, 4, 5, 6, 7]
- ## low(s) # => 0
- ## for i in low(s)..high(s):
- ## echo s[i]
- ## ```
- ##
- ## See also:
- ## * `high(openArray) <#high,openArray[T]>`_
- proc low*[I, T](x: array[I, T]): I {.magic: "Low", noSideEffect.}
- ## Returns the lowest possible index of an array `x`.
- ##
- ## For empty arrays, the return type is `int`.
- ## ```
- ## var arr = [1, 2, 3, 4, 5, 6, 7]
- ## low(arr) # => 0
- ## for i in low(arr)..high(arr):
- ## echo arr[i]
- ## ```
- ##
- ## See also:
- ## * `high(array) <#high,array[I,T]>`_
- proc low*[I, T](x: typedesc[array[I, T]]): I {.magic: "Low", noSideEffect.}
- ## Returns the lowest possible index of an array type.
- ##
- ## For empty arrays, the return type is `int`.
- ## ```
- ## low(array[7, int]) # => 0
- ## ```
- ##
- ## See also:
- ## * `high(typedesc[array]) <#high,typedesc[array[I,T]]>`_
- proc low*(x: cstring): int {.magic: "Low", noSideEffect.}
- ## Returns the lowest possible index of a compatible string `x`.
- ##
- ## See also:
- ## * `high(cstring) <#high,cstring>`_
- proc low*(x: string): int {.magic: "Low", noSideEffect.}
- ## Returns the lowest possible index of a string `x`.
- ## ```
- ## var str = "Hello world!"
- ## low(str) # => 0
- ## ```
- ##
- ## See also:
- ## * `high(string) <#high,string>`_
- when not defined(gcArc) and not defined(gcOrc):
- proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".}
- ## Use this instead of `=` for a `shallow copy`:idx:.
- ##
- ## The shallow copy only changes the semantics for sequences and strings
- ## (and types which contain those).
- ##
- ## Be careful with the changed semantics though!
- ## There is a reason why the default assignment does a deep copy of sequences
- ## and strings.
- # :array|openArray|string|seq|cstring|tuple
- proc `[]`*[I: Ordinal;T](a: T; i: I): T {.
- noSideEffect, magic: "ArrGet".}
- proc `[]=`*[I: Ordinal;T,S](a: T; i: I;
- x: sink S) {.noSideEffect, magic: "ArrPut".}
- proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".}
- proc `=copy`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".}
- proc arrGet[I: Ordinal;T](a: T; i: I): T {.
- noSideEffect, magic: "ArrGet".}
- proc arrPut[I: Ordinal;T,S](a: T; i: I;
- x: S) {.noSideEffect, magic: "ArrPut".}
- proc `=destroy`*[T](x: var T) {.inline, magic: "Destroy".} =
- ## Generic `destructor`:idx: implementation that can be overridden.
- discard
- proc `=sink`*[T](x: var T; y: T) {.inline, nodestroy, magic: "Asgn".} =
- ## Generic `sink`:idx: implementation that can be overridden.
- when defined(gcArc) or defined(gcOrc):
- x = y
- else:
- shallowCopy(x, y)
- when defined(nimHasTrace):
- proc `=trace`*[T](x: var T; env: pointer) {.inline, magic: "Trace".} =
- ## Generic `trace`:idx: implementation that can be overridden.
- discard
- type
- HSlice*[T, U] = object ## "Heterogeneous" slice type.
- a*: T ## The lower bound (inclusive).
- b*: U ## The upper bound (inclusive).
- Slice*[T] = HSlice[T, T] ## An alias for `HSlice[T, T]`.
- proc `..`*[T, U](a: sink T, b: sink U): HSlice[T, U] {.noSideEffect, inline, magic: "DotDot".} =
- ## Binary `slice`:idx: operator that constructs an interval `[a, b]`, both `a`
- ## and `b` are inclusive.
- ##
- ## Slices can also be used in the set constructor and in ordinal case
- ## statements, but then they are special-cased by the compiler.
- ## ```
- ## let a = [10, 20, 30, 40, 50]
- ## echo a[2 .. 3] # @[30, 40]
- ## ```
- result = HSlice[T, U](a: a, b: b)
- proc `..`*[T](b: sink T): HSlice[int, T]
- {.noSideEffect, inline, magic: "DotDot", deprecated: "replace `..b` with `0..b`".} =
- ## Unary `slice`:idx: operator that constructs an interval `[default(int), b]`.
- ## ```
- ## let a = [10, 20, 30, 40, 50]
- ## echo a[.. 2] # @[10, 20, 30]
- ## ```
- result = HSlice[int, T](a: 0, b: b)
- when defined(hotCodeReloading):
- {.pragma: hcrInline, inline.}
- else:
- {.pragma: hcrInline.}
- include "system/arithmetics"
- include "system/comparisons"
- const
- appType* {.magic: "AppType".}: string = ""
- ## A string that describes the application type. Possible values:
- ## `"console"`, `"gui"`, `"lib"`.
- include "system/inclrtl"
- const NoFakeVars = defined(nimscript) ## `true` if the backend doesn't support \
- ## "fake variables" like `var EBADF {.importc.}: cint`.
- const notJSnotNims = not defined(js) and not defined(nimscript)
- when not defined(js) and not defined(nimSeqsV2):
- type
- TGenericSeq {.compilerproc, pure, inheritable.} = object
- len, reserved: int
- when defined(gogc):
- elemSize: int
- elemAlign: int
- PGenericSeq {.exportc.} = ptr TGenericSeq
- # len and space without counting the terminating zero:
- NimStringDesc {.compilerproc, final.} = object of TGenericSeq
- data: UncheckedArray[char]
- NimString = ptr NimStringDesc
- when notJSnotNims and not defined(nimSeqsV2):
- template space(s: PGenericSeq): int {.dirty.} =
- s.reserved and not (seqShallowFlag or strlitFlag)
- when notJSnotNims:
- include "system/hti"
- type
- byte* = uint8 ## This is an alias for `uint8`, that is an unsigned
- ## integer, 8 bits wide.
- Natural* = range[0..high(int)]
- ## is an `int` type ranging from zero to the maximum value
- ## of an `int`. This type is often useful for documentation and debugging.
- Positive* = range[1..high(int)]
- ## is an `int` type ranging from one to the maximum value
- ## of an `int`. This type is often useful for documentation and debugging.
- type
- RootObj* {.compilerproc, inheritable.} =
- object ## The root of Nim's object hierarchy.
- ##
- ## Objects should inherit from `RootObj` or one of its descendants.
- ## However, objects that have no ancestor are also allowed.
- RootRef* = ref RootObj ## Reference to `RootObj`.
- const NimStackTraceMsgs = compileOption("stacktraceMsgs")
- type
- RootEffect* {.compilerproc.} = object of RootObj ## \
- ## Base effect class.
- ##
- ## Each effect should inherit from `RootEffect` unless you know what
- ## you're doing.
- type
- StackTraceEntry* = object ## In debug mode exceptions store the stack trace that led
- ## to them. A `StackTraceEntry` is a single entry of the
- ## stack trace.
- procname*: cstring ## Name of the proc that is currently executing.
- line*: int ## Line number of the proc that is currently executing.
- filename*: cstring ## Filename of the proc that is currently executing.
- when NimStackTraceMsgs:
- frameMsg*: string ## When a stacktrace is generated in a given frame and
- ## rendered at a later time, we should ensure the stacktrace
- ## data isn't invalidated; any pointer into PFrame is
- ## subject to being invalidated so shouldn't be stored.
- when defined(nimStackTraceOverride):
- programCounter*: uint ## Program counter - will be used to get the rest of the info,
- ## when `$` is called on this type. We can't use
- ## "cuintptr_t" in here.
- procnameStr*, filenameStr*: string ## GC-ed alternatives to "procname" and "filename"
- Exception* {.compilerproc, magic: "Exception".} = object of RootObj ## \
- ## Base exception class.
- ##
- ## Each exception has to inherit from `Exception`. See the full `exception
- ## hierarchy <manual.html#exception-handling-exception-hierarchy>`_.
- parent*: ref Exception ## Parent exception (can be used as a stack).
- name*: cstring ## The exception's name is its Nim identifier.
- ## This field is filled automatically in the
- ## `raise` statement.
- msg* {.exportc: "message".}: string ## The exception's message. Not
- ## providing an exception message
- ## is bad style.
- when defined(js):
- trace*: string
- else:
- trace*: seq[StackTraceEntry]
- up: ref Exception # used for stacking exceptions. Not exported!
- Defect* = object of Exception ## \
- ## Abstract base class for all exceptions that Nim's runtime raises
- ## but that are strictly uncatchable as they can also be mapped to
- ## a `quit` / `trap` / `exit` operation.
- CatchableError* = object of Exception ## \
- ## Abstract class for all exceptions that are catchable.
- when defined(nimIcIntegrityChecks):
- include "system/exceptions"
- else:
- import system/exceptions
- export exceptions
- when defined(js) or defined(nimdoc):
- type
- JsRoot* = ref object of RootObj
- ## Root type of the JavaScript object hierarchy
- proc unsafeNew*[T](a: var ref T, size: Natural) {.magic: "New", noSideEffect.}
- ## Creates a new object of type `T` and returns a safe (traced)
- ## reference to it in `a`.
- ##
- ## This is **unsafe** as it allocates an object of the passed `size`.
- ## This should only be used for optimization purposes when you know
- ## what you're doing!
- ##
- ## See also:
- ## * `new <#new,ref.T,proc(ref.T)>`_
- proc sizeof*[T](x: T): int {.magic: "SizeOf", noSideEffect.}
- ## Returns the size of `x` in bytes.
- ##
- ## Since this is a low-level proc,
- ## its usage is discouraged - using `new <#new,ref.T,proc(ref.T)>`_ for
- ## the most cases suffices that one never needs to know `x`'s size.
- ##
- ## As a special semantic rule, `x` may also be a type identifier
- ## (`sizeof(int)` is valid).
- ##
- ## Limitations: If used for types that are imported from C or C++,
- ## sizeof should fallback to the `sizeof` in the C compiler. The
- ## result isn't available for the Nim compiler and therefore can't
- ## be used inside of macros.
- ## ```
- ## sizeof('A') # => 1
- ## sizeof(2) # => 8
- ## ```
- proc alignof*[T](x: T): int {.magic: "AlignOf", noSideEffect.}
- proc alignof*(x: typedesc): int {.magic: "AlignOf", noSideEffect.}
- proc offsetOfDotExpr(typeAccess: typed): int {.magic: "OffsetOf", noSideEffect, compileTime.}
- template offsetOf*[T](t: typedesc[T]; member: untyped): int =
- var tmp {.noinit.}: ptr T
- offsetOfDotExpr(tmp[].member)
- template offsetOf*[T](value: T; member: untyped): int =
- offsetOfDotExpr(value.member)
- #proc offsetOf*(memberaccess: typed): int {.magic: "OffsetOf", noSideEffect.}
- proc sizeof*(x: typedesc): int {.magic: "SizeOf", noSideEffect.}
- proc newSeq*[T](s: var seq[T], len: Natural) {.magic: "NewSeq", noSideEffect.}
- ## Creates a new sequence of type `seq[T]` with length `len`.
- ##
- ## This is equivalent to `s = @[]; setlen(s, len)`, but more
- ## efficient since no reallocation is needed.
- ##
- ## Note that the sequence will be filled with zeroed entries.
- ## After the creation of the sequence you should assign entries to
- ## the sequence instead of adding them. Example:
- ## ```
- ## var inputStrings: seq[string]
- ## newSeq(inputStrings, 3)
- ## assert len(inputStrings) == 3
- ## inputStrings[0] = "The fourth"
- ## inputStrings[1] = "assignment"
- ## inputStrings[2] = "would crash"
- ## #inputStrings[3] = "out of bounds"
- ## ```
- proc newSeq*[T](len = 0.Natural): seq[T] =
- ## Creates a new sequence of type `seq[T]` with length `len`.
- ##
- ## Note that the sequence will be filled with zeroed entries.
- ## After the creation of the sequence you should assign entries to
- ## the sequence instead of adding them.
- ## ```
- ## var inputStrings = newSeq[string](3)
- ## assert len(inputStrings) == 3
- ## inputStrings[0] = "The fourth"
- ## inputStrings[1] = "assignment"
- ## inputStrings[2] = "would crash"
- ## #inputStrings[3] = "out of bounds"
- ## ```
- ##
- ## See also:
- ## * `newSeqOfCap <#newSeqOfCap,Natural>`_
- ## * `newSeqUninitialized <#newSeqUninitialized,Natural>`_
- newSeq(result, len)
- proc newSeqOfCap*[T](cap: Natural): seq[T] {.
- magic: "NewSeqOfCap", noSideEffect.} =
- ## Creates a new sequence of type `seq[T]` with length zero and capacity
- ## `cap`. Example:
- ## ```
- ## var x = newSeqOfCap[int](5)
- ## assert len(x) == 0
- ## x.add(10)
- ## assert len(x) == 1
- ## ```
- discard
- when not defined(js):
- proc newSeqUninitialized*[T: SomeNumber](len: Natural): seq[T] =
- ## Creates a new sequence of type `seq[T]` with length `len`.
- ##
- ## Only available for numbers types. Note that the sequence will be
- ## uninitialized. After the creation of the sequence you should assign
- ## entries to the sequence instead of adding them.
- ## Example:
- ## ```
- ## var x = newSeqUninitialized[int](3)
- ## assert len(x) == 3
- ## x[0] = 10
- ## ```
- result = newSeqOfCap[T](len)
- when defined(nimSeqsV2):
- cast[ptr int](addr result)[] = len
- else:
- var s = cast[PGenericSeq](result)
- s.len = len
- func len*[TOpenArray: openArray|varargs](x: TOpenArray): int {.magic: "LengthOpenArray".} =
- ## Returns the length of an openArray.
- runnableExamples:
- proc bar[T](a: openArray[T]): int = len(a)
- assert bar([1,2]) == 2
- assert [1,2].len == 2
- func len*(x: string): int {.magic: "LengthStr".} =
- ## Returns the length of a string.
- runnableExamples:
- assert "abc".len == 3
- assert "".len == 0
- assert string.default.len == 0
- proc len*(x: cstring): int {.magic: "LengthStr", noSideEffect.} =
- ## Returns the length of a compatible string. This is an O(n) operation except
- ## in js at runtime.
- ##
- ## **Note:** On the JS backend this currently counts UTF-16 code points
- ## instead of bytes at runtime (not at compile time). For now, if you
- ## need the byte length of the UTF-8 encoding, convert to string with
- ## `$` first then call `len`.
- runnableExamples:
- doAssert len(cstring"abc") == 3
- doAssert len(cstring r"ab\0c") == 5 # \0 is escaped
- doAssert len(cstring"ab\0c") == 5 # ditto
- var a: cstring = "ab\0c"
- when defined(js): doAssert a.len == 4 # len ignores \0 for js
- else: doAssert a.len == 2 # \0 is a null terminator
- static:
- var a2: cstring = "ab\0c"
- doAssert a2.len == 2 # \0 is a null terminator, even in js vm
- func len*(x: (type array)|array): int {.magic: "LengthArray".} =
- ## Returns the length of an array or an array type.
- ## This is roughly the same as `high(T)-low(T)+1`.
- runnableExamples:
- var a = [1, 1, 1]
- assert a.len == 3
- assert array[0, float].len == 0
- static: assert array[-2..2, float].len == 5
- func len*[T](x: seq[T]): int {.magic: "LengthSeq".} =
- ## Returns the length of `x`.
- runnableExamples:
- assert @[0, 1].len == 2
- assert seq[int].default.len == 0
- assert newSeq[int](3).len == 3
- let s = newSeqOfCap[int](3)
- assert s.len == 0
- # xxx this gives cgen error: assert newSeqOfCap[int](3).len == 0
- func ord*[T: Ordinal|enum](x: T): int {.magic: "Ord".} =
- ## Returns the internal `int` value of `x`, including for enum with holes
- ## and distinct ordinal types.
- runnableExamples:
- assert ord('A') == 65
- type Foo = enum
- f0 = 0, f1 = 3
- assert f1.ord == 3
- type Bar = distinct int
- assert 3.Bar.ord == 3
- func chr*(u: range[0..255]): char {.magic: "Chr".} =
- ## Converts `u` to a `char`, same as `char(u)`.
- runnableExamples:
- doAssert chr(65) == 'A'
- doAssert chr(255) == '\255'
- doAssert chr(255) == char(255)
- doAssert not compiles chr(256)
- doAssert not compiles char(256)
- var x = 256
- doAssertRaises(RangeDefect): discard chr(x)
- doAssertRaises(RangeDefect): discard char(x)
- include "system/setops"
- proc contains*[U, V, W](s: HSlice[U, V], value: W): bool {.noSideEffect, inline.} =
- ## Checks if `value` is within the range of `s`; returns true if
- ## `value >= s.a and value <= s.b`.
- ## ```
- ## assert((1..3).contains(1) == true)
- ## assert((1..3).contains(2) == true)
- ## assert((1..3).contains(4) == false)
- ## ```
- result = s.a <= value and value <= s.b
- when not defined(nimHasCallsitePragma):
- {.pragma: callsite.}
- template `in`*(x, y: untyped): untyped {.dirty, callsite.} = contains(y, x)
- ## Sugar for `contains`.
- ## ```
- ## assert(1 in (1..3) == true)
- ## assert(5 in (1..3) == false)
- ## ```
- template `notin`*(x, y: untyped): untyped {.dirty, callsite.} = not contains(y, x)
- ## Sugar for `not contains`.
- ## ```
- ## assert(1 notin (1..3) == false)
- ## assert(5 notin (1..3) == true)
- ## ```
- proc `is`*[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.}
- ## Checks if `T` is of the same type as `S`.
- ##
- ## For a negated version, use `isnot <#isnot.t,untyped,untyped>`_.
- ##
- ## ```
- ## assert 42 is int
- ## assert @[1, 2] is seq
- ##
- ## proc test[T](a: T): int =
- ## when (T is int):
- ## return a
- ## else:
- ## return 0
- ##
- ## assert(test[int](3) == 3)
- ## assert(test[string]("xyz") == 0)
- ## ```
- template `isnot`*(x, y: untyped): untyped {.callsite.} = not (x is y)
- ## Negated version of `is <#is,T,S>`_. Equivalent to `not(x is y)`.
- ## ```
- ## assert 42 isnot float
- ## assert @[1, 2] isnot enum
- ## ```
- when (defined(nimOwnedEnabled) and not defined(nimscript)) or defined(nimFixedOwned):
- type owned*[T]{.magic: "BuiltinType".} ## type constructor to mark a ref/ptr or a closure as `owned`.
- else:
- template owned*(t: typedesc): typedesc = t
- when defined(nimOwnedEnabled) and not defined(nimscript):
- proc new*[T](a: var owned(ref T)) {.magic: "New", noSideEffect.}
- ## Creates a new object of type `T` and returns a safe (traced)
- ## reference to it in `a`.
- proc new*(t: typedesc): auto =
- ## Creates a new object of type `T` and returns a safe (traced)
- ## reference to it as result value.
- ##
- ## When `T` is a ref type then the resulting type will be `T`,
- ## otherwise it will be `ref T`.
- when (t is ref):
- var r: owned t
- else:
- var r: owned(ref t)
- new(r)
- return r
- proc unown*[T](x: T): T {.magic: "Unown", noSideEffect.}
- ## Use the expression `x` ignoring its ownership attribute.
- else:
- template unown*(x: typed): untyped = x
- proc new*[T](a: var ref T) {.magic: "New", noSideEffect.}
- ## Creates a new object of type `T` and returns a safe (traced)
- ## reference to it in `a`.
- proc new*(t: typedesc): auto =
- ## Creates a new object of type `T` and returns a safe (traced)
- ## reference to it as result value.
- ##
- ## When `T` is a ref type then the resulting type will be `T`,
- ## otherwise it will be `ref T`.
- when (t is ref):
- var r: t
- else:
- var r: ref t
- new(r)
- return r
- template disarm*(x: typed) =
- ## Useful for `disarming` dangling pointers explicitly for `--newruntime`.
- ## Regardless of whether `--newruntime` is used or not
- ## this sets the pointer or callback `x` to `nil`. This is an
- ## experimental API!
- x = nil
- proc `of`*[T, S](x: T, y: typedesc[S]): bool {.magic: "Of", noSideEffect.} =
- ## Checks if `x` is an instance of `y`.
- runnableExamples:
- type
- Base = ref object of RootObj
- Sub1 = ref object of Base
- Sub2 = ref object of Base
- Unrelated = ref object
- var base: Base = Sub1() # downcast
- doAssert base of Base # generates `CondTrue` (statically true)
- doAssert base of Sub1
- doAssert base isnot Sub1
- doAssert not (base of Sub2)
- base = Sub2() # re-assign
- doAssert base of Sub2
- doAssert Sub2(base) != nil # upcast
- doAssertRaises(ObjectConversionDefect): discard Sub1(base)
- var sub1 = Sub1()
- doAssert sub1 of Base
- doAssert sub1.Base of Sub1
- doAssert not compiles(base of Unrelated)
- proc cmp*[T](x, y: T): int =
- ## Generic compare proc.
- ##
- ## Returns:
- ## * a value less than zero, if `x < y`
- ## * a value greater than zero, if `x > y`
- ## * zero, if `x == y`
- ##
- ## This is useful for writing generic algorithms without performance loss.
- ## This generic implementation uses the `==` and `<` operators.
- ## ```
- ## import std/algorithm
- ## echo sorted(@[4, 2, 6, 5, 8, 7], cmp[int])
- ## ```
- if x == y: return 0
- if x < y: return -1
- return 1
- proc cmp*(x, y: string): int {.noSideEffect.}
- ## Compare proc for strings. More efficient than the generic version.
- ##
- ## **Note**: The precise result values depend on the used C runtime library and
- ## can differ between operating systems!
- proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.magic: "ArrToSeq", noSideEffect.}
- ## Turns an array into a sequence.
- ##
- ## This most often useful for constructing
- ## sequences with the array constructor: `@[1, 2, 3]` has the type
- ## `seq[int]`, while `[1, 2, 3]` has the type `array[0..2, int]`.
- ##
- ## ```
- ## let
- ## a = [1, 3, 5]
- ## b = "foo"
- ##
- ## echo @a # => @[1, 3, 5]
- ## echo @b # => @['f', 'o', 'o']
- ## ```
- proc default*[T](_: typedesc[T]): T {.magic: "Default", noSideEffect.} =
- ## returns the default value of the type `T`.
- runnableExamples:
- assert (int, float).default == (0, 0.0)
- # note: `var a = default(T)` is usually the same as `var a: T` and (currently) generates
- # a value whose binary representation is all 0, regardless of whether this
- # would violate type constraints such as `range`, `not nil`, etc. This
- # property is required to implement certain algorithms efficiently which
- # may require intermediate invalid states.
- type Foo = object
- a: range[2..6]
- var a1: range[2..6] # currently, this compiles
- # var a2: Foo # currently, this errors: Error: The Foo type doesn't have a default value.
- # var a3 = Foo() # ditto
- var a3 = Foo.default # this works, but generates a `UnsafeDefault` warning.
- # note: the doc comment also explains why `default` can't be implemented
- # via: `template default*[T](t: typedesc[T]): T = (var v: T; v)`
- proc reset*[T](obj: var T) {.noSideEffect.} =
- ## Resets an object `obj` to its default value.
- obj = default(typeof(obj))
- proc setLen*[T](s: var seq[T], newlen: Natural) {.
- magic: "SetLengthSeq", noSideEffect.}
- ## Sets the length of seq `s` to `newlen`. `T` may be any sequence type.
- ##
- ## If the current length is greater than the new length,
- ## `s` will be truncated.
- ## ```
- ## var x = @[10, 20]
- ## x.setLen(5)
- ## x[4] = 50
- ## assert x == @[10, 20, 0, 0, 50]
- ## x.setLen(1)
- ## assert x == @[10]
- ## ```
- proc setLen*(s: var string, newlen: Natural) {.
- magic: "SetLengthStr", noSideEffect.}
- ## Sets the length of string `s` to `newlen`.
- ##
- ## If the current length is greater than the new length,
- ## `s` will be truncated.
- ## ```
- ## var myS = "Nim is great!!"
- ## myS.setLen(3) # myS <- "Nim"
- ## echo myS, " is fantastic!!"
- ## ```
- proc newString*(len: Natural): string {.
- magic: "NewString", importc: "mnewString", noSideEffect.}
- ## Returns a new string of length `len` but with uninitialized
- ## content. One needs to fill the string character after character
- ## with the index operator `s[i]`.
- ##
- ## This procedure exists only for optimization purposes;
- ## the same effect can be achieved with the `&` operator or with `add`.
- proc newStringOfCap*(cap: Natural): string {.
- magic: "NewStringOfCap", importc: "rawNewString", noSideEffect.}
- ## Returns a new string of length `0` but with capacity `cap`.
- ##
- ## This procedure exists only for optimization purposes; the same effect can
- ## be achieved with the `&` operator or with `add`.
- proc `&`*(x: string, y: char): string {.
- magic: "ConStrStr", noSideEffect.}
- ## Concatenates `x` with `y`.
- ## ```
- ## assert("ab" & 'c' == "abc")
- ## ```
- proc `&`*(x, y: char): string {.
- magic: "ConStrStr", noSideEffect.}
- ## Concatenates characters `x` and `y` into a string.
- ## ```
- ## assert('a' & 'b' == "ab")
- ## ```
- proc `&`*(x, y: string): string {.
- magic: "ConStrStr", noSideEffect.}
- ## Concatenates strings `x` and `y`.
- ## ```
- ## assert("ab" & "cd" == "abcd")
- ## ```
- proc `&`*(x: char, y: string): string {.
- magic: "ConStrStr", noSideEffect.}
- ## Concatenates `x` with `y`.
- ## ```
- ## assert('a' & "bc" == "abc")
- ## ```
- # implementation note: These must all have the same magic value "ConStrStr" so
- # that the merge optimization works properly.
- proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.}
- ## Appends `y` to `x` in place.
- ## ```
- ## var tmp = ""
- ## tmp.add('a')
- ## tmp.add('b')
- ## assert(tmp == "ab")
- ## ```
- proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.} =
- ## Concatenates `x` and `y` in place.
- ##
- ## See also `strbasics.add`.
- runnableExamples:
- var tmp = ""
- tmp.add("ab")
- tmp.add("cd")
- assert tmp == "abcd"
- type
- Endianness* = enum ## Type describing the endianness of a processor.
- littleEndian, bigEndian
- const
- cpuEndian* {.magic: "CpuEndian".}: Endianness = littleEndian
- ## The endianness of the target CPU. This is a valuable piece of
- ## information for low-level code only. This works thanks to compiler
- ## magic.
- hostOS* {.magic: "HostOS".}: string = ""
- ## A string that describes the host operating system.
- ##
- ## Possible values:
- ## `"windows"`, `"macosx"`, `"linux"`, `"netbsd"`, `"freebsd"`,
- ## `"openbsd"`, `"solaris"`, `"aix"`, `"haiku"`, `"standalone"`.
- hostCPU* {.magic: "HostCPU".}: string = ""
- ## A string that describes the host CPU.
- ##
- ## Possible values:
- ## `"i386"`, `"alpha"`, `"powerpc"`, `"powerpc64"`, `"powerpc64el"`,
- ## `"sparc"`, `"amd64"`, `"mips"`, `"mipsel"`, `"arm"`, `"arm64"`,
- ## `"mips64"`, `"mips64el"`, `"riscv32"`, `"riscv64"`, '"loongarch64"'.
- seqShallowFlag = low(int)
- strlitFlag = 1 shl (sizeof(int)*8 - 2) # later versions of the codegen \
- # emit this flag
- # for string literals, it allows for some optimizations.
- const
- hasThreadSupport = compileOption("threads") and not defined(nimscript)
- hasSharedHeap = defined(boehmgc) or defined(gogc) # don't share heaps; every thread has its own
- when hasThreadSupport and defined(tcc) and not compileOption("tlsEmulation"):
- # tcc doesn't support TLS
- {.error: "`--tlsEmulation:on` must be used when using threads with tcc backend".}
- when defined(boehmgc):
- when defined(windows):
- when sizeof(int) == 8:
- const boehmLib = "boehmgc64.dll"
- else:
- const boehmLib = "boehmgc.dll"
- elif defined(macosx):
- const boehmLib = "libgc.dylib"
- elif defined(openbsd):
- const boehmLib = "libgc.so.(4|5).0"
- elif defined(freebsd):
- const boehmLib = "libgc-threaded.so.1"
- else:
- const boehmLib = "libgc.so.1"
- {.pragma: boehmGC, noconv, dynlib: boehmLib.}
- when not defined(nimPreviewSlimSystem):
- type TaintedString* {.deprecated: "Deprecated since 1.5".} = string
- when defined(profiler) and not defined(nimscript):
- proc nimProfile() {.compilerproc, noinline.}
- when hasThreadSupport:
- {.pragma: rtlThreadVar, threadvar.}
- else:
- {.pragma: rtlThreadVar.}
- const
- QuitSuccess* = 0
- ## is the value that should be passed to `quit <#quit,int>`_ to indicate
- ## success.
- QuitFailure* = 1
- ## is the value that should be passed to `quit <#quit,int>`_ to indicate
- ## failure.
- when not defined(js) and hostOS != "standalone":
- var programResult* {.compilerproc, exportc: "nim_program_result".}: int
- ## deprecated, prefer `quit` or `exitprocs.getProgramResult`, `exitprocs.setProgramResult`.
- import std/private/since
- import system/ctypes
- export ctypes
- proc align(address, alignment: int): int =
- if alignment == 0: # Actually, this is illegal. This branch exists to actively
- # hide problems.
- result = address
- else:
- result = (address + (alignment - 1)) and not (alignment - 1)
- when defined(nimNoQuit):
- proc rawQuit(errorcode: int = QuitSuccess) = discard "ignoring quit"
- elif defined(genode):
- import genode/env
- var systemEnv {.exportc: runtimeEnvSym.}: GenodeEnvPtr
- type GenodeEnv* = GenodeEnvPtr
- ## Opaque type representing Genode environment.
- proc rawQuit(env: GenodeEnv; errorcode: int) {.magic: "Exit", noreturn,
- importcpp: "#->parent().exit(@); Genode::sleep_forever()", header: "<base/sleep.h>".}
- proc rawQuit(errorcode: int = QuitSuccess) {.inline, noreturn.} =
- systemEnv.rawQuit(errorcode)
- elif defined(js) and defined(nodejs) and not defined(nimscript):
- proc rawQuit(errorcode: int = QuitSuccess) {.magic: "Exit",
- importc: "process.exit", noreturn.}
- else:
- proc rawQuit(errorcode: cint) {.
- magic: "Exit", importc: "exit", header: "<stdlib.h>", noreturn.}
- template sysAssert(cond: bool, msg: string) =
- when defined(useSysAssert):
- if not cond:
- cstderr.rawWrite "[SYSASSERT] "
- cstderr.rawWrite msg
- cstderr.rawWrite "\n"
- rawQuit 1
- const hasAlloc = (hostOS != "standalone" or not defined(nogc)) and not defined(nimscript)
- when notJSnotNims and hostOS != "standalone" and hostOS != "any":
- include "system/cgprocs"
- when notJSnotNims and hasAlloc and not defined(nimSeqsV2):
- proc addChar(s: NimString, c: char): NimString {.compilerproc, benign.}
- when defined(nimscript) or not defined(nimSeqsV2):
- proc add*[T](x: var seq[T], y: sink T) {.magic: "AppendSeqElem", noSideEffect.}
- ## Generic proc for adding a data item `y` to a container `x`.
- ##
- ## For containers that have an order, `add` means *append*. New generic
- ## containers should also call their adding proc `add` for consistency.
- ## Generic code becomes much easier to write if the Nim naming scheme is
- ## respected.
- when false: # defined(gcDestructors):
- proc add*[T](x: var seq[T], y: sink openArray[T]) {.noSideEffect.} =
- ## Generic proc for adding a container `y` to a container `x`.
- ##
- ## For containers that have an order, `add` means *append*. New generic
- ## containers should also call their adding proc `add` for consistency.
- ## Generic code becomes much easier to write if the Nim naming scheme is
- ## respected.
- ## ```
- ## var s: seq[string] = @["test2","test2"]
- ## s.add("test") # s <- @[test2, test2, test]
- ## ```
- ##
- ## See also:
- ## * `& proc <#&,seq[T],seq[T]>`_
- {.noSideEffect.}:
- let xl = x.len
- setLen(x, xl + y.len)
- for i in 0..high(y):
- when nimvm:
- # workaround the fact that the VM does not yet
- # handle sink parameters properly:
- x[xl+i] = y[i]
- else:
- x[xl+i] = move y[i]
- else:
- proc add*[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} =
- ## Generic proc for adding a container `y` to a container `x`.
- ##
- ## For containers that have an order, `add` means *append*. New generic
- ## containers should also call their adding proc `add` for consistency.
- ## Generic code becomes much easier to write if the Nim naming scheme is
- ## respected.
- ## ```
- ## var s: seq[string] = @["test2","test2"]
- ## s.add("test") # s <- @[test2, test2, test]
- ## ```
- ##
- ## See also:
- ## * `& proc <#&,seq[T],seq[T]>`_
- {.noSideEffect.}:
- let xl = x.len
- setLen(x, xl + y.len)
- for i in 0..high(y): x[xl+i] = y[i]
- when defined(nimSeqsV2):
- template movingCopy(a, b: typed) =
- a = move(b)
- else:
- template movingCopy(a, b: typed) =
- shallowCopy(a, b)
- proc del*[T](x: var seq[T], i: Natural) {.noSideEffect.} =
- ## Deletes the item at index `i` by putting `x[high(x)]` into position `i`.
- ##
- ## This is an `O(1)` operation.
- ##
- ## See also:
- ## * `delete <#delete,seq[T],Natural>`_ for preserving the order
- runnableExamples:
- var a = @[10, 11, 12, 13, 14]
- a.del(2)
- assert a == @[10, 11, 14, 13]
- let xl = x.len - 1
- movingCopy(x[i], x[xl])
- setLen(x, xl)
- proc insert*[T](x: var seq[T], item: sink T, i = 0.Natural) {.noSideEffect.} =
- ## Inserts `item` into `x` at position `i`.
- ## ```
- ## var i = @[1, 3, 5]
- ## i.insert(99, 0) # i <- @[99, 1, 3, 5]
- ## ```
- {.noSideEffect.}:
- template defaultImpl =
- let xl = x.len
- setLen(x, xl+1)
- var j = xl-1
- while j >= i:
- movingCopy(x[j+1], x[j])
- dec(j)
- when nimvm:
- defaultImpl()
- else:
- when defined(js):
- var it : T
- {.emit: "`x` = `x` || []; `x`.splice(`i`, 0, `it`);".}
- else:
- defaultImpl()
- x[i] = item
- when not defined(nimV2):
- proc repr*[T](x: T): string {.magic: "Repr", noSideEffect.}
- ## Takes any Nim variable and returns its string representation.
- ## No trailing newline is inserted (so `echo` won't add an empty newline).
- ## Use `-d:nimLegacyReprWithNewline` to revert to old behavior where newlines
- ## were added in some cases.
- ##
- ## It works even for complex data graphs with cycles. This is a great
- ## debugging tool.
- ## ```
- ## var s: seq[string] = @["test2", "test2"]
- ## var i = @[1, 2, 3, 4, 5]
- ## echo repr(s) # => 0x1055eb050[0x1055ec050"test2", 0x1055ec078"test2"]
- ## echo repr(i) # => 0x1055ed050[1, 2, 3, 4, 5]
- ## ```
- when not defined(nimPreviewSlimSystem):
- type
- csize* {.importc: "size_t", nodecl, deprecated: "use `csize_t` instead".} = int
- ## This isn't the same as `size_t` in *C*. Don't use it.
- const
- Inf* = 0x7FF0000000000000'f64
- ## Contains the IEEE floating point value of positive infinity.
- NegInf* = 0xFFF0000000000000'f64
- ## Contains the IEEE floating point value of negative infinity.
- NaN* = 0x7FF7FFFFFFFFFFFF'f64
- ## Contains an IEEE floating point value of *Not A Number*.
- ##
- ## Note that you cannot compare a floating point value to this value
- ## and expect a reasonable result - use the `isNaN` or `classify` procedure
- ## in the `math module <math.html>`_ for checking for NaN.
- proc high*(T: typedesc[SomeFloat]): T = Inf
- proc low*(T: typedesc[SomeFloat]): T = NegInf
- proc toFloat*(i: int): float {.noSideEffect, inline.} =
- ## Converts an integer `i` into a `float`. Same as `float(i)`.
- ##
- ## If the conversion fails, `ValueError` is raised.
- ## However, on most platforms the conversion cannot fail.
- ##
- ## ```
- ## let
- ## a = 2
- ## b = 3.7
- ##
- ## echo a.toFloat + b # => 5.7
- ## ```
- float(i)
- proc toBiggestFloat*(i: BiggestInt): BiggestFloat {.noSideEffect, inline.} =
- ## Same as `toFloat <#toFloat,int>`_ but for `BiggestInt` to `BiggestFloat`.
- BiggestFloat(i)
- proc toInt*(f: float): int {.noSideEffect.} =
- ## Converts a floating point number `f` into an `int`.
- ##
- ## Conversion rounds `f` half away from 0, see
- ## `Round half away from zero
- ## <https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero>`_,
- ## as opposed to a type conversion which rounds towards zero.
- ##
- ## Note that some floating point numbers (e.g. infinity or even 1e19)
- ## cannot be accurately converted.
- ## ```
- ## doAssert toInt(0.49) == 0
- ## doAssert toInt(0.5) == 1
- ## doAssert toInt(-0.5) == -1 # rounding is symmetrical
- ## ```
- if f >= 0: int(f+0.5) else: int(f-0.5)
- proc toBiggestInt*(f: BiggestFloat): BiggestInt {.noSideEffect.} =
- ## Same as `toInt <#toInt,float>`_ but for `BiggestFloat` to `BiggestInt`.
- if f >= 0: BiggestInt(f+0.5) else: BiggestInt(f-0.5)
- proc `/`*(x, y: int): float {.inline, noSideEffect.} =
- ## Division of integers that results in a float.
- ## ```
- ## echo 7 / 5 # => 1.4
- ## ```
- ##
- ## See also:
- ## * `div <system.html#div,int,int>`_
- ## * `mod <system.html#mod,int,int>`_
- result = toFloat(x) / toFloat(y)
- {.push stackTrace: off.}
- when defined(js):
- proc js_abs[T: SomeNumber](x: T): T {.importc: "Math.abs".}
- else:
- proc c_fabs(x: cdouble): cdouble {.importc: "fabs", header: "<math.h>".}
- proc c_fabsf(x: cfloat): cfloat {.importc: "fabsf", header: "<math.h>".}
- proc abs*[T: float64 | float32](x: T): T {.noSideEffect, inline.} =
- when nimvm:
- if x < 0.0: result = -x
- elif x == 0.0: result = 0.0 # handle 0.0, -0.0
- else: result = x # handle NaN, > 0
- else:
- when defined(js): result = js_abs(x)
- else:
- when T is float64:
- result = c_fabs(x)
- else:
- result = c_fabsf(x)
- func abs*(x: int): int {.magic: "AbsI", inline.} =
- if x < 0: -x else: x
- func abs*(x: int8): int8 {.magic: "AbsI", inline.} =
- if x < 0: -x else: x
- func abs*(x: int16): int16 {.magic: "AbsI", inline.} =
- if x < 0: -x else: x
- func abs*(x: int32): int32 {.magic: "AbsI", inline.} =
- if x < 0: -x else: x
- func abs*(x: int64): int64 {.magic: "AbsI", inline.} =
- ## Returns the absolute value of `x`.
- ##
- ## If `x` is `low(x)` (that is -MININT for its type),
- ## an overflow exception is thrown (if overflow checking is turned on).
- result = if x < 0: -x else: x
- {.pop.} # stackTrace: off
- when not defined(nimPreviewSlimSystem):
- proc addQuitProc*(quitProc: proc() {.noconv.}) {.
- importc: "atexit", header: "<stdlib.h>", deprecated: "use exitprocs.addExitProc".}
- ## Adds/registers a quit procedure.
- ##
- ## Each call to `addQuitProc` registers another quit procedure. Up to 30
- ## procedures can be registered. They are executed on a last-in, first-out
- ## basis (that is, the last function registered is the first to be executed).
- ## `addQuitProc` raises an EOutOfIndex exception if `quitProc` cannot be
- ## registered.
- # Support for addQuitProc() is done by Ansi C's facilities here.
- # In case of an unhandled exception the exit handlers should
- # not be called explicitly! The user may decide to do this manually though.
- proc swap*[T](a, b: var T) {.magic: "Swap", noSideEffect.}
- ## Swaps the values `a` and `b`.
- ##
- ## This is often more efficient than `tmp = a; a = b; b = tmp`.
- ## Particularly useful for sorting algorithms.
- ##
- ## ```
- ## var
- ## a = 5
- ## b = 9
- ##
- ## swap(a, b)
- ##
- ## assert a == 9
- ## assert b == 5
- ## ```
- when not defined(js) and not defined(booting) and defined(nimTrMacros):
- template swapRefsInArray*{swap(arr[a], arr[b])}(arr: openArray[ref], a, b: int) =
- # Optimize swapping of array elements if they are refs. Default swap
- # implementation will cause unsureAsgnRef to be emitted which causes
- # unnecessary slow down in this case.
- swap(cast[ptr pointer](addr arr[a])[], cast[ptr pointer](addr arr[b])[])
- when not defined(nimscript):
- {.push stackTrace: off, profiler: off.}
- when not defined(nimPreviewSlimSystem):
- import std/sysatomics
- export sysatomics
- else:
- import std/sysatomics
- {.pop.}
- include "system/memalloc"
- proc `|`*(a, b: typedesc): typedesc = discard
- include "system/iterators_1"
- proc len*[U: Ordinal; V: Ordinal](x: HSlice[U, V]): int {.noSideEffect, inline.} =
- ## Length of ordinal slice. When x.b < x.a returns zero length.
- ## ```
- ## assert((0..5).len == 6)
- ## assert((5..2).len == 0)
- ## ```
- result = max(0, ord(x.b) - ord(x.a) + 1)
- proc isNil*[T](x: ref T): bool {.noSideEffect, magic: "IsNil".}
- proc isNil*[T](x: ptr T): bool {.noSideEffect, magic: "IsNil".}
- proc isNil*(x: pointer): bool {.noSideEffect, magic: "IsNil".}
- proc isNil*(x: cstring): bool {.noSideEffect, magic: "IsNil".}
- proc isNil*[T: proc](x: T): bool {.noSideEffect, magic: "IsNil".}
- ## Fast check whether `x` is nil. This is sometimes more efficient than
- ## `== nil`.
- when defined(nimHasTopDownInference):
- # magic used for seq type inference
- proc `@`*[T](a: openArray[T]): seq[T] {.magic: "OpenArrayToSeq".} =
- ## Turns an *openArray* into a sequence.
- ##
- ## This is not as efficient as turning a fixed length array into a sequence
- ## as it always copies every element of `a`.
- newSeq(result, a.len)
- for i in 0..a.len-1: result[i] = a[i]
- else:
- proc `@`*[T](a: openArray[T]): seq[T] =
- ## Turns an *openArray* into a sequence.
- ##
- ## This is not as efficient as turning a fixed length array into a sequence
- ## as it always copies every element of `a`.
- newSeq(result, a.len)
- for i in 0..a.len-1: result[i] = a[i]
- when defined(nimSeqsV2):
- proc `&`*[T](x, y: sink seq[T]): seq[T] {.noSideEffect.} =
- ## Concatenates two sequences.
- ##
- ## Requires copying of the sequences.
- ## ```
- ## assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6])
- ## ```
- ##
- ## See also:
- ## * `add(var seq[T], openArray[T]) <#add,seq[T],openArray[T]>`_
- newSeq(result, x.len + y.len)
- for i in 0..x.len-1:
- result[i] = move(x[i])
- for i in 0..y.len-1:
- result[i+x.len] = move(y[i])
- proc `&`*[T](x: sink seq[T], y: sink T): seq[T] {.noSideEffect.} =
- ## Appends element y to the end of the sequence.
- ##
- ## Requires copying of the sequence.
- ## ```
- ## assert(@[1, 2, 3] & 4 == @[1, 2, 3, 4])
- ## ```
- ##
- ## See also:
- ## * `add(var seq[T], T) <#add,seq[T],sinkT>`_
- newSeq(result, x.len + 1)
- for i in 0..x.len-1:
- result[i] = move(x[i])
- result[x.len] = move(y)
- proc `&`*[T](x: sink T, y: sink seq[T]): seq[T] {.noSideEffect.} =
- ## Prepends the element x to the beginning of the sequence.
- ##
- ## Requires copying of the sequence.
- ## ```
- ## assert(1 & @[2, 3, 4] == @[1, 2, 3, 4])
- ## ```
- newSeq(result, y.len + 1)
- result[0] = move(x)
- for i in 0..y.len-1:
- result[i+1] = move(y[i])
- else:
- proc `&`*[T](x, y: seq[T]): seq[T] {.noSideEffect.} =
- ## Concatenates two sequences.
- ##
- ## Requires copying of the sequences.
- ## ```
- ## assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6])
- ## ```
- ##
- ## See also:
- ## * `add(var seq[T], openArray[T]) <#add,seq[T],openArray[T]>`_
- newSeq(result, x.len + y.len)
- for i in 0..x.len-1:
- result[i] = x[i]
- for i in 0..y.len-1:
- result[i+x.len] = y[i]
- proc `&`*[T](x: seq[T], y: T): seq[T] {.noSideEffect.} =
- ## Appends element y to the end of the sequence.
- ##
- ## Requires copying of the sequence.
- ## ```
- ## assert(@[1, 2, 3] & 4 == @[1, 2, 3, 4])
- ## ```
- ##
- ## See also:
- ## * `add(var seq[T], T) <#add,seq[T],sinkT>`_
- newSeq(result, x.len + 1)
- for i in 0..x.len-1:
- result[i] = x[i]
- result[x.len] = y
- proc `&`*[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} =
- ## Prepends the element x to the beginning of the sequence.
- ##
- ## Requires copying of the sequence.
- ## ```
- ## assert(1 & @[2, 3, 4] == @[1, 2, 3, 4])
- ## ```
- newSeq(result, y.len + 1)
- result[0] = x
- for i in 0..y.len-1:
- result[i+1] = y[i]
- proc instantiationInfo*(index = -1, fullPaths = false): tuple[
- filename: string, line: int, column: int] {.magic: "InstantiationInfo", noSideEffect.}
- ## Provides access to the compiler's instantiation stack line information
- ## of a template.
- ##
- ## While similar to the `caller info`:idx: of other languages, it is determined
- ## at compile time.
- ##
- ## This proc is mostly useful for meta programming (eg. `assert` template)
- ## to retrieve information about the current filename and line number.
- ## Example:
- ##
- ## ```
- ## import std/strutils
- ##
- ## template testException(exception, code: untyped): typed =
- ## try:
- ## let pos = instantiationInfo()
- ## discard(code)
- ## echo "Test failure at $1:$2 with '$3'" % [pos.filename,
- ## $pos.line, astToStr(code)]
- ## assert false, "A test expecting failure succeeded?"
- ## except exception:
- ## discard
- ##
- ## proc tester(pos: int): int =
- ## let
- ## a = @[1, 2, 3]
- ## result = a[pos]
- ##
- ## when isMainModule:
- ## testException(IndexDefect, tester(30))
- ## testException(IndexDefect, tester(1))
- ## # --> Test failure at example.nim:20 with 'tester(1)'
- ## ```
- when notJSnotNims:
- import system/ansi_c
- import system/memory
- {.push stackTrace: off.}
- when not defined(js) and hasThreadSupport and hostOS != "standalone":
- import std/private/syslocks
- include "system/threadlocalstorage"
- when not defined(js) and defined(nimV2):
- type
- DestructorProc = proc (p: pointer) {.nimcall, benign, raises: [].}
- TNimTypeV2 {.compilerproc.} = object
- destructor: pointer
- size: int
- align: int16
- depth: int16
- display: ptr UncheckedArray[uint32] # classToken
- when defined(nimTypeNames):
- name: cstring
- traceImpl: pointer
- typeInfoV1: pointer # for backwards compat, usually nil
- flags: int
- PNimTypeV2 = ptr TNimTypeV2
- when notJSnotNims and defined(nimSeqsV2):
- include "system/strs_v2"
- include "system/seqs_v2"
- {.pop.}
- when not defined(nimscript):
- proc writeStackTrace*() {.tags: [], gcsafe, raises: [].}
- ## Writes the current stack trace to `stderr`. This is only works
- ## for debug builds. Since it's usually used for debugging, this
- ## is proclaimed to have no IO effect!
- when not declared(sysFatal):
- include "system/fatal"
- when defined(nimV2):
- include system/arc
- template newException*(exceptn: typedesc, message: string;
- parentException: ref Exception = nil): untyped =
- ## Creates an exception object of type `exceptn` and sets its `msg` field
- ## to `message`. Returns the new exception object.
- (ref exceptn)(msg: message, parent: parentException)
- when not defined(nimPreviewSlimSystem):
- import std/assertions
- export assertions
- import system/iterators
- export iterators
- proc find*[T, S](a: T, item: S): int {.inline.}=
- ## Returns the first index of `item` in `a` or -1 if not found. This requires
- ## appropriate `items` and `==` operations to work.
- result = 0
- for i in items(a):
- if i == item: return
- inc(result)
- result = -1
- proc contains*[T](a: openArray[T], item: T): bool {.inline.}=
- ## Returns true if `item` is in `a` or false if not found. This is a shortcut
- ## for `find(a, item) >= 0`.
- ##
- ## This allows the `in` operator: `a.contains(item)` is the same as
- ## `item in a`.
- ## ```
- ## var a = @[1, 3, 5]
- ## assert a.contains(5)
- ## assert 3 in a
- ## assert 99 notin a
- ## ```
- return find(a, item) >= 0
- proc pop*[T](s: var seq[T]): T {.inline, noSideEffect.} =
- ## Returns the last item of `s` and decreases `s.len` by one. This treats
- ## `s` as a stack and implements the common *pop* operation.
- ##
- ## Raises `IndexDefect` if `s` is empty.
- runnableExamples:
- var a = @[1, 3, 5, 7]
- let b = pop(a)
- assert b == 7
- assert a == @[1, 3, 5]
- var L = s.len-1
- when defined(nimV2):
- result = move s[L]
- shrink(s, L)
- else:
- result = s[L]
- setLen(s, L)
- proc `==`*[T: tuple|object](x, y: T): bool =
- ## Generic `==` operator for tuples that is lifted from the components.
- ## of `x` and `y`.
- for a, b in fields(x, y):
- if a != b: return false
- return true
- proc `<=`*[T: tuple](x, y: T): bool =
- ## Generic lexicographic `<=` operator for tuples that is lifted from the
- ## components of `x` and `y`. This implementation uses `cmp`.
- for a, b in fields(x, y):
- var c = cmp(a, b)
- if c < 0: return true
- if c > 0: return false
- return true
- proc `<`*[T: tuple](x, y: T): bool =
- ## Generic lexicographic `<` operator for tuples that is lifted from the
- ## components of `x` and `y`. This implementation uses `cmp`.
- for a, b in fields(x, y):
- var c = cmp(a, b)
- if c < 0: return true
- if c > 0: return false
- return false
- include "system/gc_interface"
- # we have to compute this here before turning it off in except.nim anyway ...
- const NimStackTrace = compileOption("stacktrace")
- import system/coro_detection
- {.push checks: off.}
- # obviously we cannot generate checking operations here :-)
- # because it would yield into an endless recursion
- # however, stack-traces are available for most parts
- # of the code
- when notJSnotNims:
- var
- globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, benign.}
- ## With this hook you can influence exception handling on a global level.
- ## If not nil, every 'raise' statement ends up calling this hook.
- ##
- ## .. warning:: Ordinary application code should never set this hook! You better know what you do when setting this.
- ##
- ## If `globalRaiseHook` returns false, the exception is caught and does
- ## not propagate further through the call stack.
- localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, benign.}
- ## With this hook you can influence exception handling on a
- ## thread local level.
- ## If not nil, every 'raise' statement ends up calling this hook.
- ##
- ## .. warning:: Ordinary application code should never set this hook! You better know what you do when setting this.
- ##
- ## If `localRaiseHook` returns false, the exception
- ## is caught and does not propagate further through the call stack.
- outOfMemHook*: proc () {.nimcall, tags: [], benign, raises: [].}
- ## Set this variable to provide a procedure that should be called
- ## in case of an `out of memory`:idx: event. The standard handler
- ## writes an error message and terminates the program.
- ##
- ## `outOfMemHook` can be used to raise an exception in case of OOM like so:
- ##
- ## ```
- ## var gOutOfMem: ref EOutOfMemory
- ## new(gOutOfMem) # need to be allocated *before* OOM really happened!
- ## gOutOfMem.msg = "out of memory"
- ##
- ## proc handleOOM() =
- ## raise gOutOfMem
- ##
- ## system.outOfMemHook = handleOOM
- ## ```
- ##
- ## If the handler does not raise an exception, ordinary control flow
- ## continues and the program is terminated.
- unhandledExceptionHook*: proc (e: ref Exception) {.nimcall, tags: [], benign, raises: [].}
- ## Set this variable to provide a procedure that should be called
- ## in case of an `unhandle exception` event. The standard handler
- ## writes an error message and terminates the program, except when
- ## using `--os:any`
- type
- PFrame* = ptr TFrame ## Represents a runtime frame of the call stack;
- ## part of the debugger API.
- # keep in sync with nimbase.h `struct TFrame_`
- TFrame* {.importc, nodecl, final.} = object ## The frame itself.
- prev*: PFrame ## Previous frame; used for chaining the call stack.
- procname*: cstring ## Name of the proc that is currently executing.
- line*: int ## Line number of the proc that is currently executing.
- filename*: cstring ## Filename of the proc that is currently executing.
- len*: int16 ## Length of the inspectable slots.
- calldepth*: int16 ## Used for max call depth checking.
- when NimStackTraceMsgs:
- frameMsgLen*: int ## end position in frameMsgBuf for this frame.
- when defined(js) or defined(nimdoc):
- proc add*(x: var string, y: cstring) {.asmNoStackFrame.} =
- ## Appends `y` to `x` in place.
- runnableExamples:
- var tmp = ""
- tmp.add(cstring("ab"))
- tmp.add(cstring("cd"))
- doAssert tmp == "abcd"
- asm """
- if (`x` === null) { `x` = []; }
- var off = `x`.length;
- `x`.length += `y`.length;
- for (var i = 0; i < `y`.length; ++i) {
- `x`[off+i] = `y`.charCodeAt(i);
- }
- """
- proc add*(x: var cstring, y: cstring) {.magic: "AppendStrStr".} =
- ## Appends `y` to `x` in place.
- ## Only implemented for JS backend.
- runnableExamples:
- when defined(js):
- var tmp: cstring = ""
- tmp.add(cstring("ab"))
- tmp.add(cstring("cd"))
- doAssert tmp == cstring("abcd")
- elif hasAlloc:
- {.push stackTrace: off, profiler: off.}
- proc add*(x: var string, y: cstring) =
- var i = 0
- if y != nil:
- while y[i] != '\0':
- add(x, y[i])
- inc(i)
- {.pop.}
- proc echo*(x: varargs[typed, `$`]) {.magic: "Echo", benign, sideEffect.}
- ## Writes and flushes the parameters to the standard output.
- ##
- ## Special built-in that takes a variable number of arguments. Each argument
- ## is converted to a string via `$`, so it works for user-defined
- ## types that have an overloaded `$` operator.
- ## It is roughly equivalent to `writeLine(stdout, x); flushFile(stdout)`, but
- ## available for the JavaScript target too.
- ##
- ## Unlike other IO operations this is guaranteed to be thread-safe as
- ## `echo` is very often used for debugging convenience. If you want to use
- ## `echo` inside a `proc without side effects
- ## <manual.html#pragmas-nosideeffect-pragma>`_ you can use `debugEcho
- ## <#debugEcho,varargs[typed,]>`_ instead.
- proc debugEcho*(x: varargs[typed, `$`]) {.magic: "Echo", noSideEffect,
- tags: [], raises: [].}
- ## Same as `echo <#echo,varargs[typed,]>`_, but as a special semantic rule,
- ## `debugEcho` pretends to be free of side effects, so that it can be used
- ## for debugging routines marked as `noSideEffect
- ## <manual.html#pragmas-nosideeffect-pragma>`_.
- when hostOS == "standalone" and defined(nogc):
- proc nimToCStringConv(s: NimString): cstring {.compilerproc, inline.} =
- if s == nil or s.len == 0: result = cstring""
- else: result = cast[cstring](addr s.data)
- proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", benign.}
- ## Get type information for `x`.
- ##
- ## Ordinary code should not use this, but the `typeinfo module
- ## <typeinfo.html>`_ instead.
- when not defined(js):
- proc likelyProc(val: bool): bool {.importc: "NIM_LIKELY", nodecl, noSideEffect.}
- proc unlikelyProc(val: bool): bool {.importc: "NIM_UNLIKELY", nodecl, noSideEffect.}
- template likely*(val: bool): bool =
- ## Hints the optimizer that `val` is likely going to be true.
- ##
- ## You can use this template to decorate a branch condition. On certain
- ## platforms this can help the processor predict better which branch is
- ## going to be run. Example:
- ## ```
- ## for value in inputValues:
- ## if likely(value <= 100):
- ## process(value)
- ## else:
- ## echo "Value too big!"
- ## ```
- ##
- ## On backends without branch prediction (JS and the nimscript VM), this
- ## template will not affect code execution.
- when nimvm:
- val
- else:
- when defined(js):
- val
- else:
- likelyProc(val)
- template unlikely*(val: bool): bool =
- ## Hints the optimizer that `val` is likely going to be false.
- ##
- ## You can use this proc to decorate a branch condition. On certain
- ## platforms this can help the processor predict better which branch is
- ## going to be run. Example:
- ## ```
- ## for value in inputValues:
- ## if unlikely(value > 100):
- ## echo "Value too big!"
- ## else:
- ## process(value)
- ## ```
- ##
- ## On backends without branch prediction (JS and the nimscript VM), this
- ## template will not affect code execution.
- when nimvm:
- val
- else:
- when defined(js):
- val
- else:
- unlikelyProc(val)
- import system/dollars
- export dollars
- when defined(nimAuditDelete):
- {.pragma: auditDelete, deprecated: "review this call for out of bounds behavior".}
- else:
- {.pragma: auditDelete.}
- proc delete*[T](x: var seq[T], i: Natural) {.noSideEffect, auditDelete.} =
- ## Deletes the item at index `i` by moving all `x[i+1..^1]` items by one position.
- ##
- ## This is an `O(n)` operation.
- ##
- ## .. note:: With `-d:nimStrictDelete`, an index error is produced when the index passed
- ## to it was out of bounds. `-d:nimStrictDelete` will become the default
- ## in upcoming versions.
- ##
- ## See also:
- ## * `del <#del,seq[T],Natural>`_ for O(1) operation
- ##
- runnableExamples:
- var s = @[1, 2, 3, 4, 5]
- s.delete(2)
- doAssert s == @[1, 2, 4, 5]
- when defined(nimStrictDelete):
- if i > high(x):
- # xxx this should call `raiseIndexError2(i, high(x))` after some refactoring
- raise (ref IndexDefect)(msg: "index out of bounds: '" & $i & "' < '" & $x.len & "' failed")
- template defaultImpl =
- let xl = x.len
- for j in i.int..xl-2: movingCopy(x[j], x[j+1])
- setLen(x, xl-1)
- when nimvm:
- defaultImpl()
- else:
- when defined(js):
- {.emit: "`x`.splice(`i`, 1);".}
- else:
- defaultImpl()
- const
- NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch
- ## is the version of Nim as a string.
- when not defined(js):
- {.push stackTrace: off, profiler: off.}
- when hasAlloc:
- when not defined(gcRegions) and not usesDestructors:
- proc initGC() {.gcsafe, raises: [].}
- proc initStackBottom() {.inline, compilerproc.} =
- # WARNING: This is very fragile! An array size of 8 does not work on my
- # Linux 64bit system. -- That's because the stack direction is the other
- # way around.
- when declared(nimGC_setStackBottom):
- var locals {.volatile, noinit.}: pointer
- locals = addr(locals)
- nimGC_setStackBottom(locals)
- proc initStackBottomWith(locals: pointer) {.inline, compilerproc.} =
- # We need to keep initStackBottom around for now to avoid
- # bootstrapping problems.
- when declared(nimGC_setStackBottom):
- nimGC_setStackBottom(locals)
- when not usesDestructors:
- {.push profiler: off.}
- var
- strDesc = TNimType(size: sizeof(string), kind: tyString, flags: {ntfAcyclic})
- {.pop.}
- {.pop.}
- when not defined(js):
- # ugly hack, see the accompanying .pop for
- # the mysterious error message
- {.push stackTrace: off, profiler: off.}
- when notJSnotNims:
- proc zeroMem(p: pointer, size: Natural) =
- nimZeroMem(p, size)
- when declared(memTrackerOp):
- memTrackerOp("zeroMem", p, size)
- proc copyMem(dest, source: pointer, size: Natural) =
- nimCopyMem(dest, source, size)
- when declared(memTrackerOp):
- memTrackerOp("copyMem", dest, size)
- proc moveMem(dest, source: pointer, size: Natural) =
- c_memmove(dest, source, csize_t(size))
- when declared(memTrackerOp):
- memTrackerOp("moveMem", dest, size)
- proc equalMem(a, b: pointer, size: Natural): bool =
- nimCmpMem(a, b, size) == 0
- proc cmpMem(a, b: pointer, size: Natural): int =
- nimCmpMem(a, b, size).int
- when not defined(js):
- proc cmp(x, y: string): int =
- when nimvm:
- if x < y: result = -1
- elif x > y: result = 1
- else: result = 0
- else:
- when not defined(nimscript): # avoid semantic checking
- let minlen = min(x.len, y.len)
- result = int(nimCmpMem(x.cstring, y.cstring, cast[csize_t](minlen)))
- if result == 0:
- result = x.len - y.len
- when declared(newSeq):
- proc cstringArrayToSeq*(a: cstringArray, len: Natural): seq[string] =
- ## Converts a `cstringArray` to a `seq[string]`. `a` is supposed to be
- ## of length `len`.
- newSeq(result, len)
- for i in 0..len-1: result[i] = $a[i]
- proc cstringArrayToSeq*(a: cstringArray): seq[string] =
- ## Converts a `cstringArray` to a `seq[string]`. `a` is supposed to be
- ## terminated by `nil`.
- var L = 0
- while a[L] != nil: inc(L)
- result = cstringArrayToSeq(a, L)
- when not defined(js) and declared(alloc0) and declared(dealloc):
- proc allocCStringArray*(a: openArray[string]): cstringArray =
- ## Creates a NULL terminated cstringArray from `a`. The result has to
- ## be freed with `deallocCStringArray` after it's not needed anymore.
- result = cast[cstringArray](alloc0((a.len+1) * sizeof(cstring)))
- let x = cast[ptr UncheckedArray[string]](a)
- for i in 0 .. a.high:
- result[i] = cast[cstring](alloc0(x[i].len+1))
- copyMem(result[i], addr(x[i][0]), x[i].len)
- proc deallocCStringArray*(a: cstringArray) =
- ## Frees a NULL terminated cstringArray.
- var i = 0
- while a[i] != nil:
- dealloc(a[i])
- inc(i)
- dealloc(a)
- when notJSnotNims:
- type
- PSafePoint = ptr TSafePoint
- TSafePoint {.compilerproc, final.} = object
- prev: PSafePoint # points to next safe point ON THE STACK
- status: int
- context: C_JmpBuf
- SafePoint = TSafePoint
- when not defined(js):
- when declared(initAllocator):
- initAllocator()
- when hasThreadSupport:
- when hostOS != "standalone":
- include system/threadimpl
- when not defined(nimPreviewSlimSystem):
- import std/typedthreads
- export typedthreads
- elif not defined(nogc) and not defined(nimscript):
- when not defined(useNimRtl) and not defined(createNimRtl): initStackBottom()
- when declared(initGC): initGC()
- when notJSnotNims:
- proc setControlCHook*(hook: proc () {.noconv.})
- ## Allows you to override the behaviour of your application when CTRL+C
- ## is pressed. Only one such hook is supported.
- ## Example:
- ##
- ## ```
- ## proc ctrlc() {.noconv.} =
- ## echo "Ctrl+C fired!"
- ## # do clean up stuff
- ## quit()
- ##
- ## setControlCHook(ctrlc)
- ## ```
- when not defined(noSignalHandler) and not defined(useNimRtl):
- proc unsetControlCHook*()
- ## Reverts a call to setControlCHook.
- when hostOS != "standalone":
- proc getStackTrace*(): string {.gcsafe.}
- ## Gets the current stack trace. This only works for debug builds.
- proc getStackTrace*(e: ref Exception): string {.gcsafe.}
- ## Gets the stack trace associated with `e`, which is the stack that
- ## lead to the `raise` statement. This only works for debug builds.
- {.push stackTrace: off, profiler: off.}
- when defined(memtracker):
- include "system/memtracker"
- when hostOS == "standalone":
- include "system/embedded"
- else:
- include "system/excpt"
- include "system/chcks"
- # we cannot compile this with stack tracing on
- # as it would recurse endlessly!
- include "system/integerops"
- {.pop.}
- when not defined(js):
- # this is a hack: without this when statement, you would get:
- # Error: system module needs: nimGCvisit
- {.pop.} # stackTrace: off, profiler: off
- when notJSnotNims:
- when hostOS != "standalone" and hostOS != "any":
- include "system/dyncalls"
- import system/countbits_impl
- include "system/sets"
- when defined(gogc):
- const GenericSeqSize = (3 * sizeof(int))
- else:
- const GenericSeqSize = (2 * sizeof(int))
- proc getDiscriminant(aa: pointer, n: ptr TNimNode): uint =
- sysAssert(n.kind == nkCase, "getDiscriminant: node != nkCase")
- var d: uint
- var a = cast[uint](aa)
- case n.typ.size
- of 1: d = uint(cast[ptr uint8](a + uint(n.offset))[])
- of 2: d = uint(cast[ptr uint16](a + uint(n.offset))[])
- of 4: d = uint(cast[ptr uint32](a + uint(n.offset))[])
- of 8: d = uint(cast[ptr uint64](a + uint(n.offset))[])
- else:
- d = 0'u
- sysAssert(false, "getDiscriminant: invalid n.typ.size")
- return d
- proc selectBranch(aa: pointer, n: ptr TNimNode): ptr TNimNode =
- var discr = getDiscriminant(aa, n)
- if discr < cast[uint](n.len):
- result = n.sons[discr]
- if result == nil: result = n.sons[n.len]
- # n.sons[n.len] contains the `else` part (but may be nil)
- else:
- result = n.sons[n.len]
- when notJSnotNims and hasAlloc:
- {.push profiler: off.}
- include "system/mmdisp"
- {.pop.}
- {.push stackTrace: off, profiler: off.}
- when not defined(nimSeqsV2):
- include "system/sysstr"
- {.pop.}
- include "system/strmantle"
- include "system/assign"
- when not defined(nimV2):
- include "system/repr"
- when notJSnotNims and hasThreadSupport and hostOS != "standalone":
- when not defined(nimPreviewSlimSystem):
- include "system/channels_builtin"
- when notJSnotNims and hostOS != "standalone":
- proc getCurrentException*(): ref Exception {.compilerRtl, inl, benign.} =
- ## Retrieves the current exception; if there is none, `nil` is returned.
- result = currException
- proc nimBorrowCurrentException(): ref Exception {.compilerRtl, inl, benign, nodestroy.} =
- # .nodestroy here so that we do not produce a write barrier as the
- # C codegen only uses it in a borrowed way:
- result = currException
- proc getCurrentExceptionMsg*(): string {.inline, benign.} =
- ## Retrieves the error message that was attached to the current
- ## exception; if there is none, `""` is returned.
- return if currException == nil: "" else: currException.msg
- proc setCurrentException*(exc: ref Exception) {.inline, benign.} =
- ## Sets the current exception.
- ##
- ## .. warning:: Only use this if you know what you are doing.
- currException = exc
- elif defined(nimscript):
- proc getCurrentException*(): ref Exception {.compilerRtl.} = discard
- when notJSnotNims:
- {.push stackTrace: off, profiler: off.}
- when (defined(profiler) or defined(memProfiler)):
- include "system/profiler"
- {.pop.}
- proc rawProc*[T: proc](x: T): pointer {.noSideEffect, inline.} =
- ## Retrieves the raw proc pointer of the closure `x`. This is
- ## useful for interfacing closures with C/C++, hash compuations, etc.
- when T is "closure":
- #[
- The conversion from function pointer to `void*` is a tricky topic, but this
- should work at least for c++ >= c++11, e.g. for `dlsym` support.
- refs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57869,
- https://stackoverflow.com/questions/14125474/casts-between-pointer-to-function-and-pointer-to-object-in-c-and-c
- ]#
- {.emit: """
- `result` = (void*)`x`.ClP_0;
- """.}
- else:
- {.error: "Only closure function and iterator are allowed!".}
- proc rawEnv*[T: proc](x: T): pointer {.noSideEffect, inline.} =
- ## Retrieves the raw environment pointer of the closure `x`. See also `rawProc`.
- when T is "closure":
- {.emit: """
- `result` = `x`.ClE_0;
- """.}
- else:
- {.error: "Only closure function and iterator are allowed!".}
- proc finished*[T: proc](x: T): bool {.noSideEffect, inline, magic: "Finished".} =
- ## It can be used to determine if a first class iterator has finished.
- when T is "iterator":
- {.emit: """
- `result` = ((NI*) `x`.ClE_0)[1] < 0;
- """.}
- else:
- {.error: "Only closure iterator is allowed!".}
- from std/private/digitsutils import addInt
- export addInt
- when defined(js):
- include "system/jssys"
- include "system/reprjs"
- when defined(nimNoQuit):
- proc quit*(errorcode: int = QuitSuccess) = discard "ignoring quit"
- elif defined(nimdoc):
- proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn.}
- ## Stops the program immediately with an exit code.
- ##
- ## Before stopping the program the "exit procedures" are called in the
- ## opposite order they were added with `addExitProc <exitprocs.html#addExitProc,proc)>`_.
- ##
- ## The proc `quit(QuitSuccess)` is called implicitly when your nim
- ## program finishes without incident for platforms where this is the
- ## expected behavior. A raised unhandled exception is
- ## equivalent to calling `quit(QuitFailure)`.
- ##
- ## Note that this is a *runtime* call and using `quit` inside a macro won't
- ## have any compile time effect. If you need to stop the compiler inside a
- ## macro, use the `error <manual.html#pragmas-error-pragma>`_ or `fatal
- ## <manual.html#pragmas-fatal-pragma>`_ pragmas.
- ##
- ## .. warning:: `errorcode` gets saturated when it exceeds the valid range
- ## on the specific platform. On Posix, the valid range is `low(int8)..high(int8)`.
- ## On Windows, the valid range is `low(int32)..high(int32)`. For instance,
- ## `quit(int(0x100000000))` is equal to `quit(127)` on Linux.
- ##
- ## .. danger:: In almost all cases, in particular in library code, prefer
- ## alternatives, e.g. `doAssert false` or raise a `Defect`.
- ## `quit` bypasses regular control flow in particular `defer`,
- ## `try`, `catch`, `finally` and `destructors`, and exceptions that may have been
- ## raised by an `addExitProc` proc, as well as cleanup code in other threads.
- ## It does *not* call the garbage collector to free all the memory,
- ## unless an `addExitProc` proc calls `GC_fullCollect <#GC_fullCollect>`_.
- elif defined(genode):
- proc quit*(errorcode: int = QuitSuccess) {.inline, noreturn.} =
- rawQuit(errorcode)
- elif defined(js) and defined(nodejs) and not defined(nimscript):
- proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit",
- importc: "process.exit", noreturn.}
- else:
- proc quit*(errorcode: int = QuitSuccess) {.inline, noreturn.} =
- when defined(posix): # posix uses low 8 bits
- type ExitCodeRange = int8
- else: # win32 uses low 32 bits
- type ExitCodeRange = cint
- when sizeof(errorcode) > sizeof(ExitCodeRange):
- if errorcode < low(ExitCodeRange):
- rawQuit(low(ExitCodeRange).cint)
- elif errorcode > high(ExitCodeRange):
- rawQuit(high(ExitCodeRange).cint)
- else:
- rawQuit(errorcode.cint)
- else:
- rawQuit(errorcode.cint)
- proc quit*(errormsg: string, errorcode = QuitFailure) {.noreturn.} =
- ## A shorthand for `echo(errormsg); quit(errorcode)`.
- when defined(nimscript) or defined(js) or (hostOS == "standalone"):
- echo errormsg
- else:
- when nimvm:
- echo errormsg
- else:
- cstderr.rawWrite(errormsg)
- cstderr.rawWrite("\n")
- quit(errorcode)
- {.pop.} # checks: off
- # {.pop.} # hints: off
- include "system/indices"
- proc `&=`*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.}
- ## Appends in place to a string.
- ## ```
- ## var a = "abc"
- ## a &= "de" # a <- "abcde"
- ## ```
- template `&=`*(x, y: typed) =
- ## Generic 'sink' operator for Nim.
- ##
- ## If not specialized further, an alias for `add`.
- add(x, y)
- when compileOption("rangechecks"):
- template rangeCheck*(cond) =
- ## Helper for performing user-defined range checks.
- ## Such checks will be performed only when the `rangechecks`
- ## compile-time option is enabled.
- if not cond: sysFatal(RangeDefect, "range check failed")
- else:
- template rangeCheck*(cond) = discard
- when not defined(gcArc) and not defined(gcOrc):
- proc shallow*[T](s: var seq[T]) {.noSideEffect, inline.} =
- ## Marks a sequence `s` as `shallow`:idx:. Subsequent assignments will not
- ## perform deep copies of `s`.
- ##
- ## This is only useful for optimization purposes.
- if s.len == 0: return
- when not defined(js) and not defined(nimscript) and not defined(nimSeqsV2):
- var s = cast[PGenericSeq](s)
- {.noSideEffect.}:
- s.reserved = s.reserved or seqShallowFlag
- proc shallow*(s: var string) {.noSideEffect, inline.} =
- ## Marks a string `s` as `shallow`:idx:. Subsequent assignments will not
- ## perform deep copies of `s`.
- ##
- ## This is only useful for optimization purposes.
- when not defined(js) and not defined(nimscript) and not defined(nimSeqsV2):
- var s = cast[PGenericSeq](s)
- if s == nil:
- s = cast[PGenericSeq](newString(0))
- # string literals cannot become 'shallow':
- if (s.reserved and strlitFlag) == 0:
- {.noSideEffect.}:
- s.reserved = s.reserved or seqShallowFlag
- type
- NimNodeObj = object
- NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj
- ## Represents a Nim AST node. Macros operate on this type.
- type
- ForLoopStmt* {.compilerproc.} = object ## \
- ## A special type that marks a macro as a `for-loop macro`:idx:.
- ## See `"For Loop Macro" <manual.html#macros-for-loop-macro>`_.
- macro varargsLen*(x: varargs[untyped]): int {.since: (1, 1).} =
- ## returns number of variadic arguments in `x`
- proc varargsLenImpl(x: NimNode): NimNode {.magic: "LengthOpenArray", noSideEffect.}
- varargsLenImpl(x)
- when defined(nimV2):
- import system/repr_v2
- export repr_v2
- when hasAlloc or defined(nimscript):
- proc insert*(x: var string, item: string, i = 0.Natural) {.noSideEffect.} =
- ## Inserts `item` into `x` at position `i`.
- ## ```
- ## var a = "abc"
- ## a.insert("zz", 0) # a <- "zzabc"
- ## ```
- var xl = x.len
- setLen(x, xl+item.len)
- var j = xl-1
- while j >= i:
- when defined(gcArc) or defined(gcOrc):
- x[j+item.len] = move x[j]
- else:
- shallowCopy(x[j+item.len], x[j])
- dec(j)
- j = 0
- while j < item.len:
- x[j+i] = item[j]
- inc(j)
- when declared(initDebugger):
- initDebugger()
- proc addEscapedChar*(s: var string, c: char) {.noSideEffect, inline.} =
- ## Adds a char to string `s` and applies the following escaping:
- ##
- ## * replaces any ``\`` by `\\`
- ## * replaces any `'` by `\'`
- ## * replaces any `"` by `\"`
- ## * replaces any `\a` by `\\a`
- ## * replaces any `\b` by `\\b`
- ## * replaces any `\t` by `\\t`
- ## * replaces any `\n` by `\\n`
- ## * replaces any `\v` by `\\v`
- ## * replaces any `\f` by `\\f`
- ## * replaces any `\r` by `\\r`
- ## * replaces any `\e` by `\\e`
- ## * replaces any other character not in the set `{\21..\126}`
- ## by `\xHH` where `HH` is its hexadecimal value
- ##
- ## The procedure has been designed so that its output is usable for many
- ## different common syntaxes.
- ##
- ## .. warning:: This is **not correct** for producing ANSI C code!
- ##
- case c
- of '\a': s.add "\\a" # \x07
- of '\b': s.add "\\b" # \x08
- of '\t': s.add "\\t" # \x09
- of '\n': s.add "\\n" # \x0A
- of '\v': s.add "\\v" # \x0B
- of '\f': s.add "\\f" # \x0C
- of '\r': (when defined(nimLegacyAddEscapedCharx0D): s.add "\\c" else: s.add "\\r") # \x0D
- of '\e': s.add "\\e" # \x1B
- of '\\': s.add("\\\\")
- of '\'': s.add("\\'")
- of '\"': s.add("\\\"")
- of {'\32'..'\126'} - {'\\', '\'', '\"'}: s.add(c)
- else:
- s.add("\\x")
- const HexChars = "0123456789ABCDEF"
- let n = ord(c)
- s.add(HexChars[int((n and 0xF0) shr 4)])
- s.add(HexChars[int(n and 0xF)])
- proc addQuoted*[T](s: var string, x: T) =
- ## Appends `x` to string `s` in place, applying quoting and escaping
- ## if `x` is a string or char.
- ##
- ## See `addEscapedChar <#addEscapedChar,string,char>`_
- ## for the escaping scheme. When `x` is a string, characters in the
- ## range `{\128..\255}` are never escaped so that multibyte UTF-8
- ## characters are untouched (note that this behavior is different from
- ## `addEscapedChar`).
- ##
- ## The Nim standard library uses this function on the elements of
- ## collections when producing a string representation of a collection.
- ## It is recommended to use this function as well for user-side collections.
- ## Users may overload `addQuoted` for custom (string-like) types if
- ## they want to implement a customized element representation.
- ##
- ## ```
- ## var tmp = ""
- ## tmp.addQuoted(1)
- ## tmp.add(", ")
- ## tmp.addQuoted("string")
- ## tmp.add(", ")
- ## tmp.addQuoted('c')
- ## assert(tmp == """1, "string", 'c'""")
- ## ```
- when T is string or T is cstring:
- s.add("\"")
- for c in x:
- # Only ASCII chars are escaped to avoid butchering
- # multibyte UTF-8 characters.
- if c <= 127.char:
- s.addEscapedChar(c)
- else:
- s.add c
- s.add("\"")
- elif T is char:
- s.add("'")
- s.addEscapedChar(x)
- s.add("'")
- # prevent temporary string allocation
- elif T is SomeInteger:
- s.addInt(x)
- elif T is SomeFloat:
- s.addFloat(x)
- elif compiles(s.add(x)):
- s.add(x)
- else:
- s.add($x)
- proc locals*(): RootObj {.magic: "Plugin", noSideEffect.} =
- ## Generates a tuple constructor expression listing all the local variables
- ## in the current scope.
- ##
- ## This is quite fast as it does not rely
- ## on any debug or runtime information. Note that in contrast to what
- ## the official signature says, the return type is *not* `RootObj` but a
- ## tuple of a structure that depends on the current scope. Example:
- ##
- ## ```
- ## proc testLocals() =
- ## var
- ## a = "something"
- ## b = 4
- ## c = locals()
- ## d = "super!"
- ##
- ## b = 1
- ## for name, value in fieldPairs(c):
- ## echo "name ", name, " with value ", value
- ## echo "B is ", b
- ## # -> name a with value something
- ## # -> name b with value 4
- ## # -> B is 1
- ## ```
- discard
- when hasAlloc and notJSnotNims:
- # XXX how to implement 'deepCopy' is an open problem.
- proc deepCopy*[T](x: var T, y: T) {.noSideEffect, magic: "DeepCopy".} =
- ## Performs a deep copy of `y` and copies it into `x`.
- ##
- ## This is also used by the code generator
- ## for the implementation of `spawn`.
- ##
- ## For `--gc:arc` or `--gc:orc` deepcopy support has to be enabled
- ## via `--deepcopy:on`.
- discard
- proc deepCopy*[T](y: T): T =
- ## Convenience wrapper around `deepCopy` overload.
- deepCopy(result, y)
- include "system/deepcopy"
- proc procCall*(x: untyped) {.magic: "ProcCall", compileTime.} =
- ## Special magic to prohibit dynamic binding for `method`:idx: calls.
- ## This is similar to `super`:idx: in ordinary OO languages.
- ## ```
- ## # 'someMethod' will be resolved fully statically:
- ## procCall someMethod(a, b)
- ## ```
- discard
- proc `==`*(x, y: cstring): bool {.magic: "EqCString", noSideEffect,
- inline.} =
- ## Checks for equality between two `cstring` variables.
- proc strcmp(a, b: cstring): cint {.noSideEffect,
- importc, header: "<string.h>".}
- if pointer(x) == pointer(y): result = true
- elif x.isNil or y.isNil: result = false
- else: result = strcmp(x, y) == 0
- template closureScope*(body: untyped): untyped =
- ## Useful when creating a closure in a loop to capture local loop variables by
- ## their current iteration values.
- ##
- ## Note: This template may not work in some cases, use
- ## `capture <sugar.html#capture.m,varargs[typed],untyped>`_ instead.
- ##
- ## Example:
- ##
- ## ```
- ## var myClosure : proc()
- ## # without closureScope:
- ## for i in 0 .. 5:
- ## let j = i
- ## if j == 3:
- ## myClosure = proc() = echo j
- ## myClosure() # outputs 5. `j` is changed after closure creation
- ## # with closureScope:
- ## for i in 0 .. 5:
- ## closureScope: # Everything in this scope is locked after closure creation
- ## let j = i
- ## if j == 3:
- ## myClosure = proc() = echo j
- ## myClosure() # outputs 3
- ## ```
- (proc() = body)()
- template once*(body: untyped): untyped =
- ## Executes a block of code only once (the first time the block is reached).
- ## ```
- ## proc draw(t: Triangle) =
- ## once:
- ## graphicsInit()
- ## line(t.p1, t.p2)
- ## line(t.p2, t.p3)
- ## line(t.p3, t.p1)
- ## ```
- var alreadyExecuted {.global.} = false
- if not alreadyExecuted:
- alreadyExecuted = true
- body
- {.pop.} # warning[GcMem]: off, warning[Uninit]: off
- proc substr*(s: openArray[char]): string =
- ## Copies a slice of `s` into a new string and returns this new
- ## string.
- runnableExamples:
- let a = "abcdefgh"
- assert a.substr(2, 5) == "cdef"
- assert a.substr(2) == "cdefgh"
- assert a.substr(5, 99) == "fgh"
- result = newString(s.len)
- for i, ch in s:
- result[i] = ch
- proc substr*(s: string, first, last: int): string = # A bug with `magic: Slice` requires this to exist this way
- ## Copies a slice of `s` into a new string and returns this new
- ## string.
- ##
- ## The bounds `first` and `last` denote the indices of
- ## the first and last characters that shall be copied. If `last`
- ## is omitted, it is treated as `high(s)`. If `last >= s.len`, `s.len`
- ## is used instead: This means `substr` can also be used to `cut`:idx:
- ## or `limit`:idx: a string's length.
- runnableExamples:
- let a = "abcdefgh"
- assert a.substr(2, 5) == "cdef"
- assert a.substr(2) == "cdefgh"
- assert a.substr(5, 99) == "fgh"
- let first = max(first, 0)
- let L = max(min(last, high(s)) - first + 1, 0)
- result = newString(L)
- for i in 0 .. L-1:
- result[i] = s[i+first]
- proc substr*(s: string, first = 0): string =
- result = substr(s, first, high(s))
- when defined(nimconfig):
- include "system/nimscript"
- when not defined(js):
- proc toOpenArray*[T](x: ptr UncheckedArray[T]; first, last: int): openArray[T] {.
- magic: "Slice".}
- proc toOpenArray*(x: cstring; first, last: int): openArray[char] {.
- magic: "Slice".}
- proc toOpenArrayByte*(x: cstring; first, last: int): openArray[byte] {.
- magic: "Slice".}
- proc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {.
- magic: "Slice".}
- proc toOpenArray*[T](x: openArray[T]; first, last: int): openArray[T] {.
- magic: "Slice".}
- proc toOpenArray*[I, T](x: array[I, T]; first, last: I): openArray[T] {.
- magic: "Slice".}
- proc toOpenArray*(x: string; first, last: int): openArray[char] {.
- magic: "Slice".}
- proc toOpenArrayByte*(x: string; first, last: int): openArray[byte] {.
- magic: "Slice".}
- proc toOpenArrayByte*(x: openArray[char]; first, last: int): openArray[byte] {.
- magic: "Slice".}
- proc toOpenArrayByte*(x: seq[char]; first, last: int): openArray[byte] {.
- magic: "Slice".}
- when defined(genode):
- var componentConstructHook*: proc (env: GenodeEnv) {.nimcall.}
- ## Hook into the Genode component bootstrap process.
- ##
- ## This hook is called after all globals are initialized.
- ## When this hook is set the component will not automatically exit,
- ## call `quit` explicitly to do so. This is the only available method
- ## of accessing the initial Genode environment.
- proc nim_component_construct(env: GenodeEnv) {.exportc.} =
- ## Procedure called during `Component::construct` by the loader.
- if componentConstructHook.isNil:
- env.rawQuit(programResult)
- # No native Genode application initialization,
- # exit as would POSIX.
- else:
- componentConstructHook(env)
- # Perform application initialization
- # and return to thread entrypoint.
- when not defined(nimPreviewSlimSystem):
- import std/widestrs
- export widestrs
- when notJSnotNims:
- when defined(windows) and compileOption("threads"):
- when not declared(addSysExitProc):
- proc addSysExitProc(quitProc: proc() {.noconv.}) {.importc: "atexit", header: "<stdlib.h>".}
- var echoLock: SysLock
- initSysLock echoLock
- addSysExitProc(proc() {.noconv.} = deinitSys(echoLock))
- const stdOutLock = compileOption("threads") and
- not defined(windows) and
- not defined(android) and
- not defined(nintendoswitch) and
- not defined(freertos) and
- not defined(zephyr) and
- hostOS != "any"
- proc raiseEIO(msg: string) {.noinline, noreturn.} =
- sysFatal(IOError, msg)
- proc echoBinSafe(args: openArray[string]) {.compilerproc.} =
- when defined(androidNDK):
- # When running nim in android app, stdout goes nowhere, so echo gets ignored
- # To redirect echo to the android logcat, use -d:androidNDK
- const ANDROID_LOG_VERBOSE = 2.cint
- proc android_log_print(prio: cint, tag: cstring, fmt: cstring): cint
- {.importc: "__android_log_print", header: "<android/log.h>", varargs, discardable.}
- var s = ""
- for arg in args:
- s.add arg
- android_log_print(ANDROID_LOG_VERBOSE, "nim", s)
- else:
- # flockfile deadlocks some versions of Android 5.x.x
- when stdOutLock:
- proc flockfile(f: CFilePtr) {.importc, nodecl.}
- proc funlockfile(f: CFilePtr) {.importc, nodecl.}
- flockfile(cstdout)
- when defined(windows) and compileOption("threads"):
- acquireSys echoLock
- for s in args:
- when defined(windows):
- # equivalent to syncio.writeWindows
- proc writeWindows(f: CFilePtr; s: string; doRaise = false) =
- # Don't ask why but the 'printf' family of function is the only thing
- # that writes utf-8 strings reliably on Windows. At least on my Win 10
- # machine. We also enable `setConsoleOutputCP(65001)` now by default.
- # But we cannot call printf directly as the string might contain \0.
- # So we have to loop over all the sections separated by potential \0s.
- var i = c_fprintf(f, "%s", s)
- while i < s.len:
- if s[i] == '\0':
- let w = c_fputc('\0', f)
- if w != 0:
- if doRaise: raiseEIO("cannot write string to file")
- break
- inc i
- else:
- let w = c_fprintf(f, "%s", unsafeAddr s[i])
- if w <= 0:
- if doRaise: raiseEIO("cannot write string to file")
- break
- inc i, w
- writeWindows(cstdout, s)
- else:
- discard c_fwrite(s.cstring, cast[csize_t](s.len), 1, cstdout)
- const linefeed = "\n"
- discard c_fwrite(linefeed.cstring, linefeed.len, 1, cstdout)
- discard c_fflush(cstdout)
- when stdOutLock:
- funlockfile(cstdout)
- when defined(windows) and compileOption("threads"):
- releaseSys echoLock
- when not defined(nimPreviewSlimSystem):
- import std/syncio
- export syncio
- when not defined(createNimHcr) and not defined(nimscript):
- include nimhcr
- when notJSnotNims and not defined(nimSeqsV2):
- proc prepareMutation*(s: var string) {.inline.} =
- ## String literals (e.g. "abc", etc) in the ARC/ORC mode are "copy on write",
- ## therefore you should call `prepareMutation` before modifying the strings
- ## via `addr`.
- runnableExamples("--gc:arc"):
- var x = "abc"
- var y = "defgh"
- prepareMutation(y) # without this, you may get a `SIGBUS` or `SIGSEGV`
- moveMem(addr y[0], addr x[0], x.len)
- assert y == "abcgh"
- discard
- proc nimArrayWith[T](y: T, size: static int): array[size, T] {.compilerRtl, raises: [].} =
- ## Creates a new array filled with `y`.
- for i in 0..size-1:
- result[i] = y
|