remove all uses of condsyms symbols defined prior to bootstrap nim 0.20.0 (#16918)
* nimNoArrayToCstringConversion deadcode * nimbabel deadcode * nimHasalignOf deadcode * nimvarargstyped deadcode * nimhygiene deadcode * nimNewTypedesc deadcode * nimlocks deadcode * nimHasCppDefine deadcode * nimHasRunnableExamples deadcode * nimHasNilChecks deadcode * nimSymKind deadcode * minor macros refactoring * nimVmEqIdent deadcode * nimNoNil deadcode * nimNoZeroTerminator deadcode * nimHasSymOwnerInMacro deadcode * nimVmExportFixed deadcode * nimNewRuntime deadcode * nimAshr deadcode * nimUncheckedArrayTyp deadcode * nimHasTypeof deadcode * nimErrorProcCanHaveBody deadcode * nimHasHotCodeReloading deadcode * nimHasSignatureHashInMacro deadcode * nimHasDefault deadcode * nimMacrosSizealignof deadcode
This commit is contained in:
parent
e463a67c74
commit
b9994925f5
27 changed files with 555 additions and 734 deletions
|
|
@ -997,14 +997,9 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
if ty.kind in {tyRef, tyPtr}:
|
if ty.kind in {tyRef, tyPtr}:
|
||||||
ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check:
|
ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check:
|
||||||
if optBoundsCheck in p.options:
|
if optBoundsCheck in p.options:
|
||||||
if ty.kind == tyString and not defined(nimNoZeroTerminator):
|
linefmt(p, cpsStmts,
|
||||||
linefmt(p, cpsStmts,
|
"if ((NU)($1) >= (NU)$2){ #raiseIndexError2($1,$2-1); $3}$n",
|
||||||
"if ((NU)($1) > (NU)$2){ #raiseIndexError2($1,$2); $3}$n",
|
[rdLoc(b), lenExpr(p, a), raiseInstr(p)])
|
||||||
[rdLoc(b), lenExpr(p, a), raiseInstr(p)])
|
|
||||||
else:
|
|
||||||
linefmt(p, cpsStmts,
|
|
||||||
"if ((NU)($1) >= (NU)$2){ #raiseIndexError2($1,$2-1); $3}$n",
|
|
||||||
[rdLoc(b), lenExpr(p, a), raiseInstr(p)])
|
|
||||||
if d.k == locNone: d.storage = OnHeap
|
if d.k == locNone: d.storage = OnHeap
|
||||||
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
||||||
a.r = ropecg(p.module, "(*$1)", [a.r])
|
a.r = ropecg(p.module, "(*$1)", [a.r])
|
||||||
|
|
|
||||||
|
|
@ -218,9 +218,6 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) =
|
||||||
m.flags = cast[set[CodegenFlag]](decodeVInt(L.buf, L.bufpos) != 0)
|
m.flags = cast[set[CodegenFlag]](decodeVInt(L.buf, L.bufpos) != 0)
|
||||||
else: doAssert(false, "ccgmerge: unknown key: " & k)
|
else: doAssert(false, "ccgmerge: unknown key: " & k)
|
||||||
|
|
||||||
when not defined(nimhygiene):
|
|
||||||
{.pragma: inject.}
|
|
||||||
|
|
||||||
template withCFile(cfilename: AbsoluteFile, body: untyped) =
|
template withCFile(cfilename: AbsoluteFile, body: untyped) =
|
||||||
var s = llStreamOpen(cfilename, fmRead)
|
var s = llStreamOpen(cfilename, fmRead)
|
||||||
if s == nil: return
|
if s == nil: return
|
||||||
|
|
|
||||||
|
|
@ -34,55 +34,57 @@ proc countDefinedSymbols*(symbols: StringTableRef): int =
|
||||||
proc initDefines*(symbols: StringTableRef) =
|
proc initDefines*(symbols: StringTableRef) =
|
||||||
# for bootstrapping purposes and old code:
|
# for bootstrapping purposes and old code:
|
||||||
template defineSymbol(s) = symbols.defineSymbol(s)
|
template defineSymbol(s) = symbols.defineSymbol(s)
|
||||||
defineSymbol("nimhygiene")
|
defineSymbol("nimhygiene") # deadcode
|
||||||
defineSymbol("niminheritable")
|
defineSymbol("niminheritable") # deadcode
|
||||||
defineSymbol("nimmixin")
|
defineSymbol("nimmixin") # deadcode
|
||||||
defineSymbol("nimeffects")
|
defineSymbol("nimeffects") # deadcode
|
||||||
defineSymbol("nimbabel")
|
defineSymbol("nimbabel") # deadcode
|
||||||
defineSymbol("nimcomputedgoto")
|
defineSymbol("nimcomputedgoto") # deadcode
|
||||||
defineSymbol("nimunion")
|
defineSymbol("nimunion") # deadcode
|
||||||
defineSymbol("nimnewshared")
|
defineSymbol("nimnewshared") # deadcode
|
||||||
defineSymbol("nimNewTypedesc")
|
defineSymbol("nimNewTypedesc") # deadcode
|
||||||
defineSymbol("nimrequiresnimframe")
|
defineSymbol("nimrequiresnimframe") # deadcode
|
||||||
defineSymbol("nimparsebiggestfloatmagic")
|
defineSymbol("nimparsebiggestfloatmagic") # deadcode
|
||||||
defineSymbol("nimalias")
|
defineSymbol("nimalias") # deadcode
|
||||||
defineSymbol("nimlocks")
|
defineSymbol("nimlocks") # deadcode
|
||||||
defineSymbol("nimnode")
|
defineSymbol("nimnode") # deadcode pending tests/deps/opengl-1.1.0/opengl.nim
|
||||||
defineSymbol("nimvarargstyped")
|
defineSymbol("nimvarargstyped") # deadcode
|
||||||
defineSymbol("nimtypedescfixed")
|
defineSymbol("nimtypedescfixed") # deadcode
|
||||||
defineSymbol("nimKnowsNimvm")
|
defineSymbol("nimKnowsNimvm") # deadcode
|
||||||
defineSymbol("nimArrIdx")
|
defineSymbol("nimArrIdx") # deadcode
|
||||||
defineSymbol("nimHasalignOf")
|
defineSymbol("nimHasalignOf") # deadcode
|
||||||
defineSymbol("nimDistros")
|
defineSymbol("nimDistros") # deadcode
|
||||||
defineSymbol("nimHasCppDefine")
|
defineSymbol("nimHasCppDefine") # deadcode
|
||||||
defineSymbol("nimGenericInOutFlags")
|
defineSymbol("nimGenericInOutFlags") # deadcode
|
||||||
when false: defineSymbol("nimHasOpt")
|
when false: defineSymbol("nimHasOpt") # deadcode
|
||||||
defineSymbol("nimNoArrayToCstringConversion")
|
defineSymbol("nimNoArrayToCstringConversion") # deadcode
|
||||||
defineSymbol("nimHasRunnableExamples")
|
defineSymbol("nimHasRunnableExamples") # deadcode
|
||||||
defineSymbol("nimNewDot")
|
defineSymbol("nimNewDot") # deadcode
|
||||||
defineSymbol("nimHasNilChecks")
|
defineSymbol("nimHasNilChecks") # deadcode
|
||||||
defineSymbol("nimSymKind")
|
defineSymbol("nimSymKind") # deadcode
|
||||||
defineSymbol("nimVmEqIdent")
|
defineSymbol("nimVmEqIdent") # deadcode
|
||||||
defineSymbol("nimNoNil")
|
defineSymbol("nimNoNil") # deadcode
|
||||||
defineSymbol("nimNoZeroTerminator")
|
defineSymbol("nimNoZeroTerminator") # deadcode
|
||||||
defineSymbol("nimNotNil")
|
defineSymbol("nimNotNil") # deadcode
|
||||||
defineSymbol("nimVmExportFixed")
|
defineSymbol("nimVmExportFixed") # deadcode
|
||||||
defineSymbol("nimHasSymOwnerInMacro")
|
defineSymbol("nimHasSymOwnerInMacro") # deadcode
|
||||||
defineSymbol("nimNewRuntime")
|
defineSymbol("nimNewRuntime") # deadcode
|
||||||
defineSymbol("nimIncrSeqV3")
|
defineSymbol("nimIncrSeqV3") # xxx: turn this into deadcode
|
||||||
defineSymbol("nimAshr")
|
defineSymbol("nimAshr") # deadcode
|
||||||
defineSymbol("nimNoNilSeqs") # deadcode
|
defineSymbol("nimNoNilSeqs") # deadcode
|
||||||
defineSymbol("nimNoNilSeqs2") # deadcode
|
defineSymbol("nimNoNilSeqs2") # deadcode
|
||||||
defineSymbol("nimHasUserErrors") # deadcode
|
defineSymbol("nimHasUserErrors") # deadcode
|
||||||
defineSymbol("nimUncheckedArrayTyp")
|
defineSymbol("nimUncheckedArrayTyp") # deadcode
|
||||||
defineSymbol("nimHasTypeof")
|
defineSymbol("nimHasTypeof") # deadcode
|
||||||
defineSymbol("nimErrorProcCanHaveBody")
|
defineSymbol("nimErrorProcCanHaveBody") # deadcode
|
||||||
defineSymbol("nimHasInstantiationOfInMacro")
|
defineSymbol("nimHasInstantiationOfInMacro") # deadcode
|
||||||
defineSymbol("nimHasHotCodeReloading")
|
defineSymbol("nimHasHotCodeReloading") # deadcode
|
||||||
defineSymbol("nimHasNilSeqs")
|
defineSymbol("nimHasNilSeqs") # deadcode
|
||||||
defineSymbol("nimHasSignatureHashInMacro")
|
defineSymbol("nimHasSignatureHashInMacro") # deadcode
|
||||||
defineSymbol("nimHasDefault")
|
defineSymbol("nimHasDefault") # deadcode
|
||||||
defineSymbol("nimMacrosSizealignof")
|
defineSymbol("nimMacrosSizealignof") # deadcode
|
||||||
|
|
||||||
|
# > 0.20.0
|
||||||
defineSymbol("nimNoZeroExtendMagic")
|
defineSymbol("nimNoZeroExtendMagic")
|
||||||
defineSymbol("nimMacrosGetNodeId")
|
defineSymbol("nimMacrosGetNodeId")
|
||||||
for f in Feature:
|
for f in Feature:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# this config.nims also needs to exist to prevent future regressions, see #9990
|
# this config.nims also needs to exist to prevent future regressions, see #9990
|
||||||
|
|
||||||
when defined(nimHasCppDefine):
|
cppDefine "errno"
|
||||||
cppDefine "errno"
|
cppDefine "unix"
|
||||||
cppDefine "unix"
|
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,12 @@ path="$lib/arch"
|
||||||
path="$lib/core"
|
path="$lib/core"
|
||||||
path="$lib/pure"
|
path="$lib/pure"
|
||||||
|
|
||||||
@if nimbabel:
|
@if not windows:
|
||||||
@if not windows:
|
nimblepath="/opt/nimble/pkgs/"
|
||||||
nimblepath="/opt/nimble/pkgs/"
|
@else:
|
||||||
@else:
|
# TODO:
|
||||||
# TODO:
|
|
||||||
@end
|
|
||||||
nimblepath="$home/.nimble/pkgs/"
|
|
||||||
@end
|
@end
|
||||||
|
nimblepath="$home/.nimble/pkgs/"
|
||||||
|
|
||||||
@if danger or quick:
|
@if danger or quick:
|
||||||
obj_checks:off
|
obj_checks:off
|
||||||
|
|
@ -64,9 +62,7 @@ path="$lib/pure"
|
||||||
debugger:off
|
debugger:off
|
||||||
line_dir:off
|
line_dir:off
|
||||||
dead_code_elim:on
|
dead_code_elim:on
|
||||||
@if nimHasNilChecks:
|
nilchecks:off
|
||||||
nilchecks:off
|
|
||||||
@end
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@if release or danger:
|
@if release or danger:
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,17 @@ proc intVal*(n: NimNode): BiggestInt {.magic: "NIntVal", noSideEffect.}
|
||||||
proc floatVal*(n: NimNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.}
|
proc floatVal*(n: NimNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.}
|
||||||
## Returns a float from any floating point literal.
|
## Returns a float from any floating point literal.
|
||||||
|
|
||||||
{.push warnings: off.}
|
|
||||||
|
proc symKind*(symbol: NimNode): NimSymKind {.magic: "NSymKind", noSideEffect.}
|
||||||
|
proc getImpl*(symbol: NimNode): NimNode {.magic: "GetImpl", noSideEffect.}
|
||||||
|
## Returns a copy of the declaration of a symbol or `nil`.
|
||||||
|
proc strVal*(n: NimNode): string {.magic: "NStrVal", noSideEffect.}
|
||||||
|
## Returns the string value of an identifier, symbol, comment, or string literal.
|
||||||
|
##
|
||||||
|
## See also:
|
||||||
|
## * `strVal= proc<#strVal=,NimNode,string>`_ for setting the string value.
|
||||||
|
|
||||||
|
{.push warnings: off.} # silence `deprecated`
|
||||||
|
|
||||||
proc ident*(n: NimNode): NimIdent {.magic: "NIdent", noSideEffect, deprecated:
|
proc ident*(n: NimNode): NimIdent {.magic: "NIdent", noSideEffect, deprecated:
|
||||||
"Deprecated since version 0.18.1; All functionality is defined on 'NimNode'.".}
|
"Deprecated since version 0.18.1; All functionality is defined on 'NimNode'.".}
|
||||||
|
|
@ -239,41 +249,13 @@ proc symbol*(n: NimNode): NimSym {.magic: "NSymbol", noSideEffect, deprecated:
|
||||||
|
|
||||||
proc getImpl*(s: NimSym): NimNode {.magic: "GetImpl", noSideEffect, deprecated: "use `getImpl: NimNode -> NimNode` instead".}
|
proc getImpl*(s: NimSym): NimNode {.magic: "GetImpl", noSideEffect, deprecated: "use `getImpl: NimNode -> NimNode` instead".}
|
||||||
|
|
||||||
when defined(nimSymKind):
|
proc `$`*(i: NimIdent): string {.magic: "NStrVal", noSideEffect, deprecated:
|
||||||
proc symKind*(symbol: NimNode): NimSymKind {.magic: "NSymKind", noSideEffect.}
|
"Deprecated since version 0.18.1; Use 'strVal' instead.".}
|
||||||
proc getImpl*(symbol: NimNode): NimNode {.magic: "GetImpl", noSideEffect.}
|
## Converts a Nim identifier to a string.
|
||||||
## Returns a copy of the declaration of a symbol or `nil`.
|
|
||||||
proc strVal*(n: NimNode): string {.magic: "NStrVal", noSideEffect.}
|
|
||||||
## Returns the string value of an identifier, symbol, comment, or string literal.
|
|
||||||
##
|
|
||||||
## See also:
|
|
||||||
## * `strVal= proc<#strVal=,NimNode,string>`_ for setting the string value.
|
|
||||||
|
|
||||||
proc `$`*(i: NimIdent): string {.magic: "NStrVal", noSideEffect, deprecated:
|
proc `$`*(s: NimSym): string {.magic: "NStrVal", noSideEffect, deprecated:
|
||||||
"Deprecated since version 0.18.1; Use 'strVal' instead.".}
|
"Deprecated since version 0.18.1; Use 'strVal' instead.".}
|
||||||
## Converts a Nim identifier to a string.
|
## Converts a Nim symbol to a string.
|
||||||
|
|
||||||
proc `$`*(s: NimSym): string {.magic: "NStrVal", noSideEffect, deprecated:
|
|
||||||
"Deprecated since version 0.18.1; Use 'strVal' instead.".}
|
|
||||||
## Converts a Nim symbol to a string.
|
|
||||||
|
|
||||||
else: # bootstrapping substitute
|
|
||||||
proc getImpl*(symbol: NimNode): NimNode =
|
|
||||||
symbol.symbol.getImpl
|
|
||||||
|
|
||||||
proc strValOld(n: NimNode): string {.magic: "NStrVal", noSideEffect.}
|
|
||||||
|
|
||||||
proc `$`*(s: NimSym): string {.magic: "IdentToStr", noSideEffect.}
|
|
||||||
|
|
||||||
proc `$`*(i: NimIdent): string {.magic: "IdentToStr", noSideEffect.}
|
|
||||||
|
|
||||||
proc strVal*(n: NimNode): string =
|
|
||||||
if n.kind == nnkIdent:
|
|
||||||
$n.ident
|
|
||||||
elif n.kind == nnkSym:
|
|
||||||
$n.symbol
|
|
||||||
else:
|
|
||||||
n.strValOld
|
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
|
|
@ -284,23 +266,21 @@ when (NimMajor, NimMinor, NimPatch) >= (1, 3, 5) or defined(nimSymImplTransform)
|
||||||
## note that code transformations are implementation dependent and subject to change.
|
## note that code transformations are implementation dependent and subject to change.
|
||||||
## See an example in `tests/macros/tmacros_various.nim`.
|
## See an example in `tests/macros/tmacros_various.nim`.
|
||||||
|
|
||||||
when defined(nimHasSymOwnerInMacro):
|
proc owner*(sym: NimNode): NimNode {.magic: "SymOwner", noSideEffect.}
|
||||||
proc owner*(sym: NimNode): NimNode {.magic: "SymOwner", noSideEffect.}
|
## Accepts a node of kind `nnkSym` and returns its owner's symbol.
|
||||||
## Accepts a node of kind `nnkSym` and returns its owner's symbol.
|
## The meaning of 'owner' depends on `sym`'s `NimSymKind` and declaration
|
||||||
## The meaning of 'owner' depends on `sym`'s `NimSymKind` and declaration
|
## context. For top level declarations this is an `nskModule` symbol,
|
||||||
## context. For top level declarations this is an `nskModule` symbol,
|
## for proc local variables an `nskProc` symbol, for enum/object fields an
|
||||||
## for proc local variables an `nskProc` symbol, for enum/object fields an
|
## `nskType` symbol, etc. For symbols without an owner, `nil` is returned.
|
||||||
## `nskType` symbol, etc. For symbols without an owner, `nil` is returned.
|
##
|
||||||
##
|
## See also:
|
||||||
## See also:
|
## * `symKind proc<#symKind,NimNode>`_ to get the kind of a symbol
|
||||||
## * `symKind proc<#symKind,NimNode>`_ to get the kind of a symbol
|
## * `getImpl proc<#getImpl,NimNode>`_ to get the declaration of a symbol
|
||||||
## * `getImpl proc<#getImpl,NimNode>`_ to get the declaration of a symbol
|
|
||||||
|
|
||||||
when defined(nimHasInstantiationOfInMacro):
|
proc isInstantiationOf*(instanceProcSym, genProcSym: NimNode): bool {.magic: "SymIsInstantiationOf", noSideEffect.}
|
||||||
proc isInstantiationOf*(instanceProcSym, genProcSym: NimNode): bool {.magic: "SymIsInstantiationOf", noSideEffect.}
|
## Checks if a proc symbol is an instance of the generic proc symbol.
|
||||||
## Checks if a proc symbol is an instance of the generic proc symbol.
|
## Useful to check proc symbols against generic symbols
|
||||||
## Useful to check proc symbols against generic symbols
|
## returned by `bindSym`.
|
||||||
## returned by `bindSym`.
|
|
||||||
|
|
||||||
proc getType*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
|
proc getType*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
|
||||||
## With 'getType' you can access the node's `type`:idx:. A Nim type is
|
## With 'getType' you can access the node's `type`:idx:. A Nim type is
|
||||||
|
|
@ -362,12 +342,11 @@ object
|
||||||
doAssert(dumpTypeImpl(b) == t)
|
doAssert(dumpTypeImpl(b) == t)
|
||||||
doAssert(dumpTypeImpl(c) == t)
|
doAssert(dumpTypeImpl(c) == t)
|
||||||
|
|
||||||
when defined(nimHasSignatureHashInMacro):
|
proc signatureHash*(n: NimNode): string {.magic: "NSigHash", noSideEffect.}
|
||||||
proc signatureHash*(n: NimNode): string {.magic: "NSigHash", noSideEffect.}
|
## Returns a stable identifier derived from the signature of a symbol.
|
||||||
## Returns a stable identifier derived from the signature of a symbol.
|
## The signature combines many factors such as the type of the symbol,
|
||||||
## The signature combines many factors such as the type of the symbol,
|
## the owning module of the symbol and others. The same identifier is
|
||||||
## the owning module of the symbol and others. The same identifier is
|
## used in the back-end to produce the mangled symbol name.
|
||||||
## used in the back-end to produce the mangled symbol name.
|
|
||||||
|
|
||||||
proc symBodyHash*(s: NimNode): string {.noSideEffect.} =
|
proc symBodyHash*(s: NimNode): string {.noSideEffect.} =
|
||||||
## Returns a stable digest for symbols derived not only from type signature
|
## Returns a stable digest for symbols derived not only from type signature
|
||||||
|
|
@ -1414,45 +1393,26 @@ proc copy*(node: NimNode): NimNode {.compileTime.} =
|
||||||
## An alias for `copyNimTree<#copyNimTree,NimNode>`_.
|
## An alias for `copyNimTree<#copyNimTree,NimNode>`_.
|
||||||
return node.copyNimTree()
|
return node.copyNimTree()
|
||||||
|
|
||||||
when defined(nimVmEqIdent):
|
proc eqIdent*(a: string; b: string): bool {.magic: "EqIdent", noSideEffect.}
|
||||||
proc eqIdent*(a: string; b: string): bool {.magic: "EqIdent", noSideEffect.}
|
## Style insensitive comparison.
|
||||||
## Style insensitive comparison.
|
|
||||||
|
|
||||||
proc eqIdent*(a: NimNode; b: string): bool {.magic: "EqIdent", noSideEffect.}
|
proc eqIdent*(a: NimNode; b: string): bool {.magic: "EqIdent", noSideEffect.}
|
||||||
## Style insensitive comparison. ``a`` can be an identifier or a
|
## Style insensitive comparison. ``a`` can be an identifier or a
|
||||||
## symbol. ``a`` may be wrapped in an export marker
|
## symbol. ``a`` may be wrapped in an export marker
|
||||||
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
||||||
## these nodes will be unwrapped.
|
## these nodes will be unwrapped.
|
||||||
|
|
||||||
proc eqIdent*(a: string; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
|
proc eqIdent*(a: string; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
|
||||||
## Style insensitive comparison. ``b`` can be an identifier or a
|
## Style insensitive comparison. ``b`` can be an identifier or a
|
||||||
## symbol. ``b`` may be wrapped in an export marker
|
## symbol. ``b`` may be wrapped in an export marker
|
||||||
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
||||||
## these nodes will be unwrapped.
|
## these nodes will be unwrapped.
|
||||||
|
|
||||||
proc eqIdent*(a: NimNode; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
|
proc eqIdent*(a: NimNode; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
|
||||||
## Style insensitive comparison. ``a`` and ``b`` can be an
|
## Style insensitive comparison. ``a`` and ``b`` can be an
|
||||||
## identifier or a symbol. Both may be wrapped in an export marker
|
## identifier or a symbol. Both may be wrapped in an export marker
|
||||||
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
||||||
## these nodes will be unwrapped.
|
## these nodes will be unwrapped.
|
||||||
|
|
||||||
else:
|
|
||||||
from std/private/strimpl import cmpNimIdentifier
|
|
||||||
|
|
||||||
proc eqIdent*(a, b: string): bool = cmpNimIdentifier(a, b) == 0
|
|
||||||
## Check if two idents are equal.
|
|
||||||
|
|
||||||
proc eqIdent*(node: NimNode; s: string): bool {.compileTime.} =
|
|
||||||
## Check if node is some identifier node (``nnkIdent``, ``nnkSym``, etc.)
|
|
||||||
## is the same as ``s``. Note that this is the preferred way to check! Most
|
|
||||||
## other ways like ``node.ident`` are much more error-prone, unfortunately.
|
|
||||||
case node.kind
|
|
||||||
of nnkSym, nnkIdent:
|
|
||||||
result = eqIdent(node.strVal, s)
|
|
||||||
of nnkOpenSymChoice, nnkClosedSymChoice:
|
|
||||||
result = eqIdent($node[0], s)
|
|
||||||
else:
|
|
||||||
result = false
|
|
||||||
|
|
||||||
proc expectIdent*(n: NimNode, name: string) {.compileTime, since: (1,1).} =
|
proc expectIdent*(n: NimNode, name: string) {.compileTime, since: (1,1).} =
|
||||||
## Check that ``eqIdent(n,name)`` holds true. If this is not the
|
## Check that ``eqIdent(n,name)`` holds true. If this is not the
|
||||||
|
|
@ -1672,22 +1632,21 @@ proc getProjectPath*(): string = discard
|
||||||
## See also:
|
## See also:
|
||||||
## * `getCurrentDir proc <os.html#getCurrentDir>`_
|
## * `getCurrentDir proc <os.html#getCurrentDir>`_
|
||||||
|
|
||||||
when defined(nimMacrosSizealignof):
|
proc getSize*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||||
proc getSize*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
## Returns the same result as ``system.sizeof`` if the size is
|
||||||
## Returns the same result as ``system.sizeof`` if the size is
|
## known by the Nim compiler. Returns a negative value if the Nim
|
||||||
## known by the Nim compiler. Returns a negative value if the Nim
|
## compiler does not know the size.
|
||||||
## compiler does not know the size.
|
proc getAlign*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||||
proc getAlign*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
## Returns the same result as ``system.alignof`` if the alignment
|
||||||
## Returns the same result as ``system.alignof`` if the alignment
|
## is known by the Nim compiler. It works on ``NimNode`` for use
|
||||||
## is known by the Nim compiler. It works on ``NimNode`` for use
|
## in macro context. Returns a negative value if the Nim compiler
|
||||||
## in macro context. Returns a negative value if the Nim compiler
|
## does not know the alignment.
|
||||||
## does not know the alignment.
|
proc getOffset*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||||
proc getOffset*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
## Returns the same result as ``system.offsetof`` if the offset is
|
||||||
## Returns the same result as ``system.offsetof`` if the offset is
|
## known by the Nim compiler. It expects a resolved symbol node
|
||||||
## known by the Nim compiler. It expects a resolved symbol node
|
## from a field of a type. Therefore it only requires one argument
|
||||||
## from a field of a type. Therefore it only requires one argument
|
## instead of two. Returns a negative value if the Nim compiler
|
||||||
## instead of two. Returns a negative value if the Nim compiler
|
## does not know the offset.
|
||||||
## does not know the offset.
|
|
||||||
|
|
||||||
proc isExported*(n: NimNode): bool {.noSideEffect.} =
|
proc isExported*(n: NimNode): bool {.noSideEffect.} =
|
||||||
## Returns whether the symbol is exported or not.
|
## Returns whether the symbol is exported or not.
|
||||||
|
|
|
||||||
|
|
@ -386,9 +386,6 @@ proc findAll*(s: string, pattern: Regex, start = 0): seq[string] {.inline.} =
|
||||||
result = @[]
|
result = @[]
|
||||||
for x in findAll(s, pattern, start): result.add x
|
for x in findAll(s, pattern, start): result.add x
|
||||||
|
|
||||||
when not defined(nimhygiene):
|
|
||||||
{.pragma: inject.}
|
|
||||||
|
|
||||||
template `=~` *(s: string, pattern: Regex): untyped =
|
template `=~` *(s: string, pattern: Regex): untyped =
|
||||||
## This calls ``match`` with an implicit declared ``matches`` array that
|
## This calls ``match`` with an implicit declared ``matches`` array that
|
||||||
## can be used in the scope of the ``=~`` call:
|
## can be used in the scope of the ``=~`` call:
|
||||||
|
|
|
||||||
|
|
@ -87,301 +87,300 @@ template forwardImpl(impl, arg) {.dirty.} =
|
||||||
else:
|
else:
|
||||||
impl(x.uint64)
|
impl(x.uint64)
|
||||||
|
|
||||||
when defined(nimHasalignOf):
|
type BitsRange*[T] = range[0..sizeof(T)*8-1]
|
||||||
type BitsRange*[T] = range[0..sizeof(T)*8-1]
|
## A range with all bit positions for type `T`.
|
||||||
## A range with all bit positions for type `T`.
|
|
||||||
|
|
||||||
func bitsliced*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
func bitsliced*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
||||||
## Returns an extracted (and shifted) slice of bits from `v`.
|
## Returns an extracted (and shifted) slice of bits from `v`.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
doAssert 0b10111.bitsliced(2 .. 4) == 0b101
|
doAssert 0b10111.bitsliced(2 .. 4) == 0b101
|
||||||
doAssert 0b11100.bitsliced(0 .. 2) == 0b100
|
doAssert 0b11100.bitsliced(0 .. 2) == 0b100
|
||||||
doAssert 0b11100.bitsliced(0 ..< 3) == 0b100
|
doAssert 0b11100.bitsliced(0 ..< 3) == 0b100
|
||||||
|
|
||||||
let
|
let
|
||||||
upmost = sizeof(T) * 8 - 1
|
upmost = sizeof(T) * 8 - 1
|
||||||
uv = when v is SomeUnsignedInt: v else: v.toUnsigned
|
uv = when v is SomeUnsignedInt: v else: v.toUnsigned
|
||||||
(uv shl (upmost - slice.b) shr (upmost - slice.b + slice.a)).T
|
(uv shl (upmost - slice.b) shr (upmost - slice.b + slice.a)).T
|
||||||
|
|
||||||
proc bitslice*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
|
proc bitslice*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
|
||||||
## Mutates `v` into an extracted (and shifted) slice of bits from `v`.
|
## Mutates `v` into an extracted (and shifted) slice of bits from `v`.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var x = 0b101110
|
var x = 0b101110
|
||||||
x.bitslice(2 .. 4)
|
x.bitslice(2 .. 4)
|
||||||
doAssert x == 0b011
|
doAssert x == 0b011
|
||||||
|
|
||||||
let
|
let
|
||||||
upmost = sizeof(T) * 8 - 1
|
upmost = sizeof(T) * 8 - 1
|
||||||
uv = when v is SomeUnsignedInt: v else: v.toUnsigned
|
uv = when v is SomeUnsignedInt: v else: v.toUnsigned
|
||||||
v = (uv shl (upmost - slice.b) shr (upmost - slice.b + slice.a)).T
|
v = (uv shl (upmost - slice.b) shr (upmost - slice.b + slice.a)).T
|
||||||
|
|
||||||
func toMask*[T: SomeInteger](slice: Slice[int]): T {.inline, since: (1, 3).} =
|
func toMask*[T: SomeInteger](slice: Slice[int]): T {.inline, since: (1, 3).} =
|
||||||
## Creates a bitmask based on a slice of bits.
|
## Creates a bitmask based on a slice of bits.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
doAssert toMask[int32](1 .. 3) == 0b1110'i32
|
doAssert toMask[int32](1 .. 3) == 0b1110'i32
|
||||||
doAssert toMask[int32](0 .. 3) == 0b1111'i32
|
doAssert toMask[int32](0 .. 3) == 0b1111'i32
|
||||||
|
|
||||||
let
|
let
|
||||||
upmost = sizeof(T) * 8 - 1
|
upmost = sizeof(T) * 8 - 1
|
||||||
bitmask = when T is SomeUnsignedInt:
|
bitmask = when T is SomeUnsignedInt:
|
||||||
bitnot(0.T)
|
bitnot(0.T)
|
||||||
else:
|
else:
|
||||||
bitnot(0.T).toUnsigned
|
bitnot(0.T).toUnsigned
|
||||||
(bitmask shl (upmost - slice.b + slice.a) shr (upmost - slice.b)).T
|
(bitmask shl (upmost - slice.b + slice.a) shr (upmost - slice.b)).T
|
||||||
|
|
||||||
proc masked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
proc masked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
||||||
## Returns `v`, with only the `1` bits from `mask` matching those of
|
## Returns `v`, with only the `1` bits from `mask` matching those of
|
||||||
## `v` set to 1.
|
## `v` set to 1.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let v = 0b0000_0011'u8
|
let v = 0b0000_0011'u8
|
||||||
doAssert v.masked(0b0000_1010'u8) == 0b0000_0010'u8
|
doAssert v.masked(0b0000_1010'u8) == 0b0000_0010'u8
|
||||||
|
|
||||||
bitand(v, mask)
|
bitand(v, mask)
|
||||||
|
|
||||||
func masked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
func masked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
||||||
## Returns `v`, with only the `1` bits in the range of `slice`
|
## Returns `v`, with only the `1` bits in the range of `slice`
|
||||||
## matching those of `v` set to 1.
|
## matching those of `v` set to 1.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let v = 0b0000_1011'u8
|
let v = 0b0000_1011'u8
|
||||||
doAssert v.masked(1 .. 3) == 0b0000_1010'u8
|
doAssert v.masked(1 .. 3) == 0b0000_1010'u8
|
||||||
|
|
||||||
bitand(v, toMask[T](slice))
|
bitand(v, toMask[T](slice))
|
||||||
|
|
||||||
proc mask*[T: SomeInteger](v: var T; mask: T) {.inline, since: (1, 3).} =
|
proc mask*[T: SomeInteger](v: var T; mask: T) {.inline, since: (1, 3).} =
|
||||||
## Mutates `v`, with only the `1` bits from `mask` matching those of
|
## Mutates `v`, with only the `1` bits from `mask` matching those of
|
||||||
## `v` set to 1.
|
## `v` set to 1.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.mask(0b0000_1010'u8)
|
v.mask(0b0000_1010'u8)
|
||||||
doAssert v == 0b0000_0010'u8
|
doAssert v == 0b0000_0010'u8
|
||||||
|
|
||||||
v = bitand(v, mask)
|
v = bitand(v, mask)
|
||||||
|
|
||||||
proc mask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
|
proc mask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
|
||||||
## Mutates `v`, with only the `1` bits in the range of `slice`
|
## Mutates `v`, with only the `1` bits in the range of `slice`
|
||||||
## matching those of `v` set to 1.
|
## matching those of `v` set to 1.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_1011'u8
|
var v = 0b0000_1011'u8
|
||||||
v.mask(1 .. 3)
|
v.mask(1 .. 3)
|
||||||
doAssert v == 0b0000_1010'u8
|
doAssert v == 0b0000_1010'u8
|
||||||
|
|
||||||
v = bitand(v, toMask[T](slice))
|
v = bitand(v, toMask[T](slice))
|
||||||
|
|
||||||
func setMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
func setMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
||||||
## Returns `v`, with all the `1` bits from `mask` set to 1.
|
## Returns `v`, with all the `1` bits from `mask` set to 1.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let v = 0b0000_0011'u8
|
let v = 0b0000_0011'u8
|
||||||
doAssert v.setMasked(0b0000_1010'u8) == 0b0000_1011'u8
|
doAssert v.setMasked(0b0000_1010'u8) == 0b0000_1011'u8
|
||||||
|
|
||||||
bitor(v, mask)
|
bitor(v, mask)
|
||||||
|
|
||||||
func setMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
func setMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
||||||
## Returns `v`, with all the `1` bits in the range of `slice` set to 1.
|
## Returns `v`, with all the `1` bits in the range of `slice` set to 1.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let v = 0b0000_0011'u8
|
let v = 0b0000_0011'u8
|
||||||
doAssert v.setMasked(2 .. 3) == 0b0000_1111'u8
|
doAssert v.setMasked(2 .. 3) == 0b0000_1111'u8
|
||||||
|
|
||||||
bitor(v, toMask[T](slice))
|
bitor(v, toMask[T](slice))
|
||||||
|
|
||||||
proc setMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
|
proc setMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
|
||||||
## Mutates `v`, with all the `1` bits from `mask` set to 1.
|
## Mutates `v`, with all the `1` bits from `mask` set to 1.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.setMask(0b0000_1010'u8)
|
v.setMask(0b0000_1010'u8)
|
||||||
doAssert v == 0b0000_1011'u8
|
doAssert v == 0b0000_1011'u8
|
||||||
|
|
||||||
v = bitor(v, mask)
|
v = bitor(v, mask)
|
||||||
|
|
||||||
proc setMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
|
proc setMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
|
||||||
## Mutates `v`, with all the `1` bits in the range of `slice` set to 1.
|
## Mutates `v`, with all the `1` bits in the range of `slice` set to 1.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.setMask(2 .. 3)
|
v.setMask(2 .. 3)
|
||||||
doAssert v == 0b0000_1111'u8
|
doAssert v == 0b0000_1111'u8
|
||||||
|
|
||||||
v = bitor(v, toMask[T](slice))
|
v = bitor(v, toMask[T](slice))
|
||||||
|
|
||||||
func clearMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
func clearMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
||||||
## Returns `v`, with all the `1` bits from `mask` set to 0.
|
## Returns `v`, with all the `1` bits from `mask` set to 0.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
||||||
## with an *inverted mask*.
|
## with an *inverted mask*.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let v = 0b0000_0011'u8
|
let v = 0b0000_0011'u8
|
||||||
doAssert v.clearMasked(0b0000_1010'u8) == 0b0000_0001'u8
|
doAssert v.clearMasked(0b0000_1010'u8) == 0b0000_0001'u8
|
||||||
|
|
||||||
bitand(v, bitnot(mask))
|
bitand(v, bitnot(mask))
|
||||||
|
|
||||||
func clearMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
func clearMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
||||||
## Returns `v`, with all the `1` bits in the range of `slice` set to 0.
|
## Returns `v`, with all the `1` bits in the range of `slice` set to 0.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
||||||
## with an *inverted mask*.
|
## with an *inverted mask*.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let v = 0b0000_0011'u8
|
let v = 0b0000_0011'u8
|
||||||
doAssert v.clearMasked(1 .. 3) == 0b0000_0001'u8
|
doAssert v.clearMasked(1 .. 3) == 0b0000_0001'u8
|
||||||
|
|
||||||
bitand(v, bitnot(toMask[T](slice)))
|
bitand(v, bitnot(toMask[T](slice)))
|
||||||
|
|
||||||
proc clearMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
|
proc clearMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
|
||||||
## Mutates `v`, with all the `1` bits from `mask` set to 0.
|
## Mutates `v`, with all the `1` bits from `mask` set to 0.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
||||||
## with an *inverted mask*.
|
## with an *inverted mask*.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.clearMask(0b0000_1010'u8)
|
v.clearMask(0b0000_1010'u8)
|
||||||
doAssert v == 0b0000_0001'u8
|
doAssert v == 0b0000_0001'u8
|
||||||
|
|
||||||
v = bitand(v, bitnot(mask))
|
v = bitand(v, bitnot(mask))
|
||||||
|
|
||||||
proc clearMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
|
proc clearMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
|
||||||
## Mutates `v`, with all the `1` bits in the range of `slice` set to 0.
|
## Mutates `v`, with all the `1` bits in the range of `slice` set to 0.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
||||||
## with an *inverted mask*.
|
## with an *inverted mask*.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.clearMask(1 .. 3)
|
v.clearMask(1 .. 3)
|
||||||
doAssert v == 0b0000_0001'u8
|
doAssert v == 0b0000_0001'u8
|
||||||
|
|
||||||
v = bitand(v, bitnot(toMask[T](slice)))
|
v = bitand(v, bitnot(toMask[T](slice)))
|
||||||
|
|
||||||
func flipMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
func flipMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
||||||
## Returns `v`, with all the `1` bits from `mask` flipped.
|
## Returns `v`, with all the `1` bits from `mask` flipped.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let v = 0b0000_0011'u8
|
let v = 0b0000_0011'u8
|
||||||
doAssert v.flipMasked(0b0000_1010'u8) == 0b0000_1001'u8
|
doAssert v.flipMasked(0b0000_1010'u8) == 0b0000_1001'u8
|
||||||
|
|
||||||
bitxor(v, mask)
|
bitxor(v, mask)
|
||||||
|
|
||||||
func flipMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
func flipMasked*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
||||||
## Returns `v`, with all the `1` bits in the range of `slice` flipped.
|
## Returns `v`, with all the `1` bits in the range of `slice` flipped.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let v = 0b0000_0011'u8
|
let v = 0b0000_0011'u8
|
||||||
doAssert v.flipMasked(1 .. 3) == 0b0000_1101'u8
|
doAssert v.flipMasked(1 .. 3) == 0b0000_1101'u8
|
||||||
|
|
||||||
bitxor(v, toMask[T](slice))
|
bitxor(v, toMask[T](slice))
|
||||||
|
|
||||||
proc flipMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
|
proc flipMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
|
||||||
## Mutates `v`, with all the `1` bits from `mask` flipped.
|
## Mutates `v`, with all the `1` bits from `mask` flipped.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.flipMask(0b0000_1010'u8)
|
v.flipMask(0b0000_1010'u8)
|
||||||
doAssert v == 0b0000_1001'u8
|
doAssert v == 0b0000_1001'u8
|
||||||
|
|
||||||
v = bitxor(v, mask)
|
v = bitxor(v, mask)
|
||||||
|
|
||||||
proc flipMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
|
proc flipMask*[T: SomeInteger](v: var T; slice: Slice[int]) {.inline, since: (1, 3).} =
|
||||||
## Mutates `v`, with all the `1` bits in the range of `slice` flipped.
|
## Mutates `v`, with all the `1` bits in the range of `slice` flipped.
|
||||||
##
|
##
|
||||||
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.flipMask(1 .. 3)
|
v.flipMask(1 .. 3)
|
||||||
doAssert v == 0b0000_1101'u8
|
doAssert v == 0b0000_1101'u8
|
||||||
|
|
||||||
v = bitxor(v, toMask[T](slice))
|
v = bitxor(v, toMask[T](slice))
|
||||||
|
|
||||||
proc setBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
|
proc setBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
|
||||||
## Mutates `v`, with the bit at position `bit` set to 1.
|
## Mutates `v`, with the bit at position `bit` set to 1.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.setBit(5'u8)
|
v.setBit(5'u8)
|
||||||
doAssert v == 0b0010_0011'u8
|
doAssert v == 0b0010_0011'u8
|
||||||
|
|
||||||
v.setMask(1.T shl bit)
|
v.setMask(1.T shl bit)
|
||||||
|
|
||||||
proc clearBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
|
proc clearBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
|
||||||
## Mutates `v`, with the bit at position `bit` set to 0.
|
## Mutates `v`, with the bit at position `bit` set to 0.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.clearBit(1'u8)
|
v.clearBit(1'u8)
|
||||||
doAssert v == 0b0000_0001'u8
|
doAssert v == 0b0000_0001'u8
|
||||||
|
|
||||||
v.clearMask(1.T shl bit)
|
v.clearMask(1.T shl bit)
|
||||||
|
|
||||||
proc flipBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
|
proc flipBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
|
||||||
## Mutates `v`, with the bit at position `bit` flipped.
|
## Mutates `v`, with the bit at position `bit` flipped.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.flipBit(1'u8)
|
v.flipBit(1'u8)
|
||||||
doAssert v == 0b0000_0001'u8
|
doAssert v == 0b0000_0001'u8
|
||||||
|
|
||||||
v = 0b0000_0011'u8
|
v = 0b0000_0011'u8
|
||||||
v.flipBit(2'u8)
|
v.flipBit(2'u8)
|
||||||
doAssert v == 0b0000_0111'u8
|
doAssert v == 0b0000_0111'u8
|
||||||
|
|
||||||
v.flipMask(1.T shl bit)
|
v.flipMask(1.T shl bit)
|
||||||
|
|
||||||
macro setBits*(v: typed; bits: varargs[typed]): untyped =
|
macro setBits*(v: typed; bits: varargs[typed]): untyped =
|
||||||
## Mutates `v`, with the bits at positions `bits` set to 1.
|
## Mutates `v`, with the bits at positions `bits` set to 1.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_0011'u8
|
var v = 0b0000_0011'u8
|
||||||
v.setBits(3, 5, 7)
|
v.setBits(3, 5, 7)
|
||||||
doAssert v == 0b1010_1011'u8
|
doAssert v == 0b1010_1011'u8
|
||||||
|
|
||||||
bits.expectKind(nnkBracket)
|
bits.expectKind(nnkBracket)
|
||||||
result = newStmtList()
|
result = newStmtList()
|
||||||
for bit in bits:
|
for bit in bits:
|
||||||
result.add newCall("setBit", v, bit)
|
result.add newCall("setBit", v, bit)
|
||||||
|
|
||||||
macro clearBits*(v: typed; bits: varargs[typed]): untyped =
|
macro clearBits*(v: typed; bits: varargs[typed]): untyped =
|
||||||
## Mutates `v`, with the bits at positions `bits` set to 0.
|
## Mutates `v`, with the bits at positions `bits` set to 0.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b1111_1111'u8
|
var v = 0b1111_1111'u8
|
||||||
v.clearBits(1, 3, 5, 7)
|
v.clearBits(1, 3, 5, 7)
|
||||||
doAssert v == 0b0101_0101'u8
|
doAssert v == 0b0101_0101'u8
|
||||||
|
|
||||||
bits.expectKind(nnkBracket)
|
bits.expectKind(nnkBracket)
|
||||||
result = newStmtList()
|
result = newStmtList()
|
||||||
for bit in bits:
|
for bit in bits:
|
||||||
result.add newCall("clearBit", v, bit)
|
result.add newCall("clearBit", v, bit)
|
||||||
|
|
||||||
macro flipBits*(v: typed; bits: varargs[typed]): untyped =
|
macro flipBits*(v: typed; bits: varargs[typed]): untyped =
|
||||||
## Mutates `v`, with the bits at positions `bits` set to 0.
|
## Mutates `v`, with the bits at positions `bits` set to 0.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var v = 0b0000_1111'u8
|
var v = 0b0000_1111'u8
|
||||||
v.flipBits(1, 3, 5, 7)
|
v.flipBits(1, 3, 5, 7)
|
||||||
doAssert v == 0b1010_0101'u8
|
doAssert v == 0b1010_0101'u8
|
||||||
|
|
||||||
bits.expectKind(nnkBracket)
|
bits.expectKind(nnkBracket)
|
||||||
result = newStmtList()
|
result = newStmtList()
|
||||||
for bit in bits:
|
for bit in bits:
|
||||||
result.add newCall("flipBit", v, bit)
|
result.add newCall("flipBit", v, bit)
|
||||||
|
|
||||||
|
|
||||||
proc testBit*[T: SomeInteger](v: T; bit: BitsRange[T]): bool {.inline.} =
|
proc testBit*[T: SomeInteger](v: T; bit: BitsRange[T]): bool {.inline.} =
|
||||||
## Returns true if the bit in `v` at positions `bit` is set to 1.
|
## Returns true if the bit in `v` at positions `bit` is set to 1.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let v = 0b0000_1111'u8
|
let v = 0b0000_1111'u8
|
||||||
doAssert v.testBit(0)
|
doAssert v.testBit(0)
|
||||||
doAssert not v.testBit(7)
|
doAssert not v.testBit(7)
|
||||||
|
|
||||||
let mask = 1.T shl bit
|
let mask = 1.T shl bit
|
||||||
return (v and mask) == mask
|
return (v and mask) == mask
|
||||||
|
|
||||||
# #### Pure Nim version ####
|
# #### Pure Nim version ####
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,6 @@
|
||||||
const
|
const
|
||||||
growthFactor = 2
|
growthFactor = 2
|
||||||
|
|
||||||
when not defined(nimHasDefault):
|
|
||||||
template default[T](t: typedesc[T]): T =
|
|
||||||
var v: T
|
|
||||||
v
|
|
||||||
|
|
||||||
# hcode for real keys cannot be zero. hcode==0 signifies an empty slot. These
|
# hcode for real keys cannot be zero. hcode==0 signifies an empty slot. These
|
||||||
# two procs retain clarity of that encoding without the space cost of an enum.
|
# two procs retain clarity of that encoding without the space cost of an enum.
|
||||||
proc isEmpty(hcode: Hash): bool {.inline.} =
|
proc isEmpty(hcode: Hash): bool {.inline.} =
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,6 @@ runnableExamples:
|
||||||
|
|
||||||
import std/private/since
|
import std/private/since
|
||||||
|
|
||||||
when not defined(nimhygiene):
|
|
||||||
{.pragma: dirty.}
|
|
||||||
|
|
||||||
when not defined(nimHasCursor):
|
when not defined(nimHasCursor):
|
||||||
{.pragma: cursor.}
|
{.pragma: cursor.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,10 +84,6 @@ import std/private/since
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
when not defined(nimhygiene):
|
|
||||||
{.pragma: dirty.}
|
|
||||||
|
|
||||||
|
|
||||||
macro evalOnceAs(expAlias, exp: untyped,
|
macro evalOnceAs(expAlias, exp: untyped,
|
||||||
letAssigneable: static[bool]): untyped =
|
letAssigneable: static[bool]): untyped =
|
||||||
## Injects `expAlias` in caller scope, to avoid bugs involving multiple
|
## Injects `expAlias` in caller scope, to avoid bugs involving multiple
|
||||||
|
|
@ -956,16 +952,10 @@ template mapIt*(s: typed, op: untyped): untyped =
|
||||||
strings = nums.mapIt($(4 * it))
|
strings = nums.mapIt($(4 * it))
|
||||||
assert strings == @["4", "8", "12", "16"]
|
assert strings == @["4", "8", "12", "16"]
|
||||||
|
|
||||||
when defined(nimHasTypeof):
|
type OutType = typeof((
|
||||||
type OutType = typeof((
|
block:
|
||||||
block:
|
var it{.inject.}: typeof(items(s), typeOfIter);
|
||||||
var it{.inject.}: typeof(items(s), typeOfIter);
|
op), typeOfProc)
|
||||||
op), typeOfProc)
|
|
||||||
else:
|
|
||||||
type OutType = typeof((
|
|
||||||
block:
|
|
||||||
var it{.inject.}: typeof(items(s));
|
|
||||||
op))
|
|
||||||
when OutType is not (proc):
|
when OutType is not (proc):
|
||||||
# Here, we avoid to create closures in loops.
|
# Here, we avoid to create closures in loops.
|
||||||
# This avoids https://github.com/nim-lang/Nim/issues/12625
|
# This avoids https://github.com/nim-lang/Nim/issues/12625
|
||||||
|
|
@ -996,11 +986,7 @@ template mapIt*(s: typed, op: untyped): untyped =
|
||||||
# With this fallback, above code can be simplified to:
|
# With this fallback, above code can be simplified to:
|
||||||
# [1, 2].mapIt((x: int) => it + x)
|
# [1, 2].mapIt((x: int) => it + x)
|
||||||
# In this case, `mapIt` is just syntax sugar for `map`.
|
# In this case, `mapIt` is just syntax sugar for `map`.
|
||||||
|
type InType = typeof(items(s), typeOfIter)
|
||||||
when defined(nimHasTypeof):
|
|
||||||
type InType = typeof(items(s), typeOfIter)
|
|
||||||
else:
|
|
||||||
type InType = typeof(items(s))
|
|
||||||
# Use a help proc `f` to create closures for each element in `s`
|
# Use a help proc `f` to create closures for each element in `s`
|
||||||
let f = proc (x: InType): OutType =
|
let f = proc (x: InType): OutType =
|
||||||
let it {.inject.} = x
|
let it {.inject.} = x
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,6 @@ import
|
||||||
hashes, math
|
hashes, math
|
||||||
|
|
||||||
{.pragma: myShallow.}
|
{.pragma: myShallow.}
|
||||||
when not defined(nimhygiene):
|
|
||||||
{.pragma: dirty.}
|
|
||||||
|
|
||||||
# For "integer-like A" that are too big for intsets/bit-vectors to be practical,
|
# For "integer-like A" that are too big for intsets/bit-vectors to be practical,
|
||||||
# it would be best to shrink hcode to the same size as the integer. Larger
|
# it would be best to shrink hcode to the same size as the integer. Larger
|
||||||
# codes should never be needed, and this can pack more entries per cache-line.
|
# codes should never be needed, and this can pack more entries per cache-line.
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ elif defined(posix):
|
||||||
else:
|
else:
|
||||||
{.error: "OS module not ported to your operating system!".}
|
{.error: "OS module not ported to your operating system!".}
|
||||||
|
|
||||||
when weirdTarget and defined(nimErrorProcCanHaveBody):
|
when weirdTarget:
|
||||||
{.pragma: noWeirdTarget, error: "this proc is not available on the NimScript/js target".}
|
{.pragma: noWeirdTarget, error: "this proc is not available on the NimScript/js target".}
|
||||||
else:
|
else:
|
||||||
{.pragma: noWeirdTarget.}
|
{.pragma: noWeirdTarget.}
|
||||||
|
|
@ -2262,10 +2262,7 @@ iterator walkDir*(dir: string; relative = false, checkDir = false):
|
||||||
while true:
|
while true:
|
||||||
var x = readdir(d)
|
var x = readdir(d)
|
||||||
if x == nil: break
|
if x == nil: break
|
||||||
when defined(nimNoArrayToCstringConversion):
|
var y = $cstring(addr x.d_name)
|
||||||
var y = $cstring(addr x.d_name)
|
|
||||||
else:
|
|
||||||
var y = $x.d_name.cstring
|
|
||||||
if y != "." and y != "..":
|
if y != "." and y != "..":
|
||||||
var s: Stat
|
var s: Stat
|
||||||
let path = dir / y
|
let path = dir / y
|
||||||
|
|
|
||||||
|
|
@ -1158,9 +1158,6 @@ proc findAll*(s: string, pattern: Peg, start = 0): seq[string] {.
|
||||||
result = @[]
|
result = @[]
|
||||||
for it in findAll(s, pattern, start): result.add it
|
for it in findAll(s, pattern, start): result.add it
|
||||||
|
|
||||||
when not defined(nimhygiene):
|
|
||||||
{.pragma: inject.}
|
|
||||||
|
|
||||||
template `=~`*(s: string, pattern: Peg): bool =
|
template `=~`*(s: string, pattern: Peg): bool =
|
||||||
## This calls ``match`` with an implicit declared ``matches`` array that
|
## This calls ``match`` with an implicit declared ``matches`` array that
|
||||||
## can be used in the scope of the ``=~`` call:
|
## can be used in the scope of the ``=~`` call:
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,8 @@ from math import pow, floor, log10
|
||||||
from algorithm import reverse
|
from algorithm import reverse
|
||||||
import std/enumutils
|
import std/enumutils
|
||||||
|
|
||||||
when defined(nimVmExportFixed):
|
from unicode import toLower, toUpper
|
||||||
from unicode import toLower, toUpper
|
export toLower, toUpper
|
||||||
export toLower, toUpper
|
|
||||||
|
|
||||||
include "system/inclrtl"
|
include "system/inclrtl"
|
||||||
import std/private/since
|
import std/private/since
|
||||||
|
|
@ -2341,17 +2340,11 @@ func formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault,
|
||||||
frmtstr[3] = '*'
|
frmtstr[3] = '*'
|
||||||
frmtstr[4] = floatFormatToChar[format]
|
frmtstr[4] = floatFormatToChar[format]
|
||||||
frmtstr[5] = '\0'
|
frmtstr[5] = '\0'
|
||||||
when defined(nimNoArrayToCstringConversion):
|
L = c_sprintf(addr buf, addr frmtstr, precision, f)
|
||||||
L = c_sprintf(addr buf, addr frmtstr, precision, f)
|
|
||||||
else:
|
|
||||||
L = c_sprintf(buf, frmtstr, precision, f)
|
|
||||||
else:
|
else:
|
||||||
frmtstr[1] = floatFormatToChar[format]
|
frmtstr[1] = floatFormatToChar[format]
|
||||||
frmtstr[2] = '\0'
|
frmtstr[2] = '\0'
|
||||||
when defined(nimNoArrayToCstringConversion):
|
L = c_sprintf(addr buf, addr frmtstr, f)
|
||||||
L = c_sprintf(addr buf, addr frmtstr, f)
|
|
||||||
else:
|
|
||||||
L = c_sprintf(buf, frmtstr, f)
|
|
||||||
result = newString(L)
|
result = newString(L)
|
||||||
for i in 0 ..< L:
|
for i in 0 ..< L:
|
||||||
# Depending on the locale either dot or comma is produced,
|
# Depending on the locale either dot or comma is produced,
|
||||||
|
|
|
||||||
340
lib/system.nim
340
lib/system.nim
|
|
@ -135,39 +135,35 @@ else:
|
||||||
OrdinalImpl[T] {.magic: Ordinal.}
|
OrdinalImpl[T] {.magic: Ordinal.}
|
||||||
Ordinal* = OrdinalImpl | uint | uint64
|
Ordinal* = OrdinalImpl | uint | uint64
|
||||||
|
|
||||||
when defined(nimHasRunnableExamples):
|
proc runnableExamples*(rdoccmd = "", body: untyped) {.magic: "RunnableExamples".}
|
||||||
proc runnableExamples*(rdoccmd = "", body: untyped) {.magic: "RunnableExamples".}
|
## A section you should use to mark `runnable example`:idx: code with.
|
||||||
## A section you should use to mark `runnable example`:idx: code with.
|
##
|
||||||
##
|
## - In normal debug and release builds code within
|
||||||
## - In normal debug and release builds code within
|
## a `runnableExamples` section is ignored.
|
||||||
## a `runnableExamples` section is ignored.
|
## - The documentation generator is aware of these examples and considers them
|
||||||
## - The documentation generator is aware of these examples and considers them
|
## part of the `##` doc comment. As the last step of documentation
|
||||||
## part of the `##` doc comment. As the last step of documentation
|
## generation each runnableExample is put in its own file `$file_examples$i.nim`,
|
||||||
## generation each runnableExample is put in its own file `$file_examples$i.nim`,
|
## compiled and tested. The collected examples are
|
||||||
## compiled and tested. The collected examples are
|
## put into their own module to ensure the examples do not refer to
|
||||||
## put into their own module to ensure the examples do not refer to
|
## non-exported symbols.
|
||||||
## non-exported symbols.
|
##
|
||||||
##
|
## Usage:
|
||||||
## Usage:
|
##
|
||||||
##
|
## .. code-block:: Nim
|
||||||
## .. code-block:: Nim
|
## proc double*(x: int): int =
|
||||||
## proc double*(x: int): int =
|
## ## This proc doubles a number.
|
||||||
## ## This proc doubles a number.
|
## runnableExamples:
|
||||||
## runnableExamples:
|
## ## at module scope
|
||||||
## ## at module scope
|
## assert double(5) == 10
|
||||||
## assert double(5) == 10
|
## block: ## at block scope
|
||||||
## block: ## at block scope
|
## defer: echo "done"
|
||||||
## defer: echo "done"
|
## result = 2 * x
|
||||||
## result = 2 * x
|
## runnableExamples "-d:foo -b:cpp":
|
||||||
## runnableExamples "-d:foo -b:cpp":
|
## import std/compilesettings
|
||||||
## import std/compilesettings
|
## doAssert querySetting(backend) == "cpp"
|
||||||
## doAssert querySetting(backend) == "cpp"
|
## runnableExamples "-r:off": ## this one is only compiled
|
||||||
## runnableExamples "-r:off": ## this one is only compiled
|
## import std/browsers
|
||||||
## import std/browsers
|
## openDefaultBrowser "https://forum.nim-lang.org/"
|
||||||
## openDefaultBrowser "https://forum.nim-lang.org/"
|
|
||||||
else:
|
|
||||||
template runnableExamples*(doccmd = "", body: untyped) =
|
|
||||||
discard
|
|
||||||
|
|
||||||
when defined(nimHasDeclaredMagic):
|
when defined(nimHasDeclaredMagic):
|
||||||
proc declared*(x: untyped): bool {.magic: "Declared", noSideEffect, compileTime.}
|
proc declared*(x: untyped): bool {.magic: "Declared", noSideEffect, compileTime.}
|
||||||
|
|
@ -222,52 +218,45 @@ proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} =
|
||||||
## Cannot be overloaded.
|
## Cannot be overloaded.
|
||||||
discard
|
discard
|
||||||
|
|
||||||
when defined(nimNewTypedesc):
|
type
|
||||||
type
|
`static`*[T] {.magic: "Static".}
|
||||||
`static`*[T] {.magic: "Static".}
|
## Meta type representing all values that can be evaluated at compile-time.
|
||||||
## 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
|
||||||
## The type coercion `static(x)` can be used to force the compile-time
|
## evaluation of the given expression `x`.
|
||||||
## evaluation of the given expression `x`.
|
|
||||||
|
|
||||||
`type`*[T] {.magic: "Type".}
|
`type`*[T] {.magic: "Type".}
|
||||||
## Meta type representing the type of all type values.
|
## Meta type representing the type of all type values.
|
||||||
##
|
##
|
||||||
## The coercion `type(x)` can be used to obtain the type of the given
|
## The coercion `type(x)` can be used to obtain the type of the given
|
||||||
## expression `x`.
|
## expression `x`.
|
||||||
else:
|
|
||||||
proc `type`*(x: untyped): typedesc {.magic: "TypeOf", noSideEffect, compileTime.} =
|
|
||||||
## Builtin `type` operator for accessing the type of an expression.
|
|
||||||
## Cannot be overloaded.
|
|
||||||
discard
|
|
||||||
|
|
||||||
when defined(nimHasTypeof):
|
type
|
||||||
type
|
TypeOfMode* = enum ## Possible modes of `typeof`.
|
||||||
TypeOfMode* = enum ## Possible modes of `typeof`.
|
typeOfProc, ## Prefer the interpretation that means `x` is a proc call.
|
||||||
typeOfProc, ## Prefer the interpretation that means `x` is a proc call.
|
typeOfIter ## Prefer the interpretation that means `x` is an iterator call.
|
||||||
typeOfIter ## Prefer the interpretation that means `x` is an iterator call.
|
|
||||||
|
|
||||||
proc typeof*(x: untyped; mode = typeOfIter): typedesc {.
|
proc typeof*(x: untyped; mode = typeOfIter): typedesc {.
|
||||||
magic: "TypeOf", noSideEffect, compileTime.} =
|
magic: "TypeOf", noSideEffect, compileTime.} =
|
||||||
## Builtin `typeof` operation for accessing the type of an expression.
|
## Builtin `typeof` operation for accessing the type of an expression.
|
||||||
## Since version 0.20.0.
|
## Since version 0.20.0.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
proc myFoo(): float = 0.0
|
proc myFoo(): float = 0.0
|
||||||
iterator myFoo(): string = yield "abc"
|
iterator myFoo(): string = yield "abc"
|
||||||
iterator myFoo2(): string = yield "abc"
|
iterator myFoo2(): string = yield "abc"
|
||||||
iterator myFoo3(): string {.closure.} = yield "abc"
|
iterator myFoo3(): string {.closure.} = yield "abc"
|
||||||
doAssert type(myFoo()) is string
|
doAssert type(myFoo()) is string
|
||||||
doAssert typeof(myFoo()) is string
|
doAssert typeof(myFoo()) is string
|
||||||
doAssert typeof(myFoo(), typeOfIter) is string
|
doAssert typeof(myFoo(), typeOfIter) is string
|
||||||
doAssert typeof(myFoo3) is "iterator"
|
doAssert typeof(myFoo3) is "iterator"
|
||||||
|
|
||||||
doAssert typeof(myFoo(), typeOfProc) is float
|
doAssert typeof(myFoo(), typeOfProc) is float
|
||||||
doAssert typeof(0.0, typeOfProc) is float
|
doAssert typeof(0.0, typeOfProc) is float
|
||||||
doAssert typeof(myFoo3, typeOfProc) is "iterator"
|
doAssert typeof(myFoo3, typeOfProc) is "iterator"
|
||||||
doAssert not compiles(typeof(myFoo2(), typeOfProc))
|
doAssert not compiles(typeof(myFoo2(), typeOfProc))
|
||||||
# this would give: Error: attempting to call routine: 'myFoo2'
|
# this would give: Error: attempting to call routine: 'myFoo2'
|
||||||
# since `typeOfProc` expects a typed expression and `myFoo2()` can
|
# since `typeOfProc` expects a typed expression and `myFoo2()` can
|
||||||
# only be used in a `for` context.
|
# only be used in a `for` context.
|
||||||
|
|
||||||
const ThisIsSystem = true
|
const ThisIsSystem = true
|
||||||
|
|
||||||
|
|
@ -310,14 +299,9 @@ type
|
||||||
seq*[T]{.magic: "Seq".} ## Generic type to construct sequences.
|
seq*[T]{.magic: "Seq".} ## Generic type to construct sequences.
|
||||||
set*[T]{.magic: "Set".} ## Generic type to construct bit sets.
|
set*[T]{.magic: "Set".} ## Generic type to construct bit sets.
|
||||||
|
|
||||||
when defined(nimUncheckedArrayTyp):
|
type
|
||||||
type
|
UncheckedArray*[T]{.magic: "UncheckedArray".}
|
||||||
UncheckedArray*[T]{.magic: "UncheckedArray".}
|
## Array with no bounds checking.
|
||||||
## Array with no bounds checking.
|
|
||||||
else:
|
|
||||||
type
|
|
||||||
UncheckedArray*[T]{.unchecked.} = array[0,T]
|
|
||||||
## Array with no bounds checking.
|
|
||||||
|
|
||||||
type sink*[T]{.magic: "BuiltinType".}
|
type sink*[T]{.magic: "BuiltinType".}
|
||||||
type lent*[T]{.magic: "BuiltinType".}
|
type lent*[T]{.magic: "BuiltinType".}
|
||||||
|
|
@ -476,25 +460,24 @@ proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".}
|
||||||
## There is a reason why the default assignment does a deep copy of sequences
|
## There is a reason why the default assignment does a deep copy of sequences
|
||||||
## and strings.
|
## and strings.
|
||||||
|
|
||||||
when defined(nimArrIdx):
|
# :array|openArray|string|seq|cstring|tuple
|
||||||
# :array|openArray|string|seq|cstring|tuple
|
proc `[]`*[I: Ordinal;T](a: T; i: I): T {.
|
||||||
proc `[]`*[I: Ordinal;T](a: T; i: I): T {.
|
noSideEffect, magic: "ArrGet".}
|
||||||
noSideEffect, magic: "ArrGet".}
|
proc `[]=`*[I: Ordinal;T,S](a: T; i: I;
|
||||||
proc `[]=`*[I: Ordinal;T,S](a: T; i: I;
|
x: sink S) {.noSideEffect, magic: "ArrPut".}
|
||||||
x: sink S) {.noSideEffect, magic: "ArrPut".}
|
proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".}
|
||||||
proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".}
|
|
||||||
|
|
||||||
proc arrGet[I: Ordinal;T](a: T; i: I): T {.
|
proc arrGet[I: Ordinal;T](a: T; i: I): T {.
|
||||||
noSideEffect, magic: "ArrGet".}
|
noSideEffect, magic: "ArrGet".}
|
||||||
proc arrPut[I: Ordinal;T,S](a: T; i: I;
|
proc arrPut[I: Ordinal;T,S](a: T; i: I;
|
||||||
x: S) {.noSideEffect, magic: "ArrPut".}
|
x: S) {.noSideEffect, magic: "ArrPut".}
|
||||||
|
|
||||||
proc `=destroy`*[T](x: var T) {.inline, magic: "Destroy".} =
|
proc `=destroy`*[T](x: var T) {.inline, magic: "Destroy".} =
|
||||||
## Generic `destructor`:idx: implementation that can be overridden.
|
## Generic `destructor`:idx: implementation that can be overridden.
|
||||||
discard
|
discard
|
||||||
proc `=sink`*[T](x: var T; y: T) {.inline, magic: "Asgn".} =
|
proc `=sink`*[T](x: var T; y: T) {.inline, magic: "Asgn".} =
|
||||||
## Generic `sink`:idx: implementation that can be overridden.
|
## Generic `sink`:idx: implementation that can be overridden.
|
||||||
shallowCopy(x, y)
|
shallowCopy(x, y)
|
||||||
|
|
||||||
type
|
type
|
||||||
HSlice*[T, U] = object ## "Heterogeneous" slice type.
|
HSlice*[T, U] = object ## "Heterogeneous" slice type.
|
||||||
|
|
@ -522,12 +505,6 @@ proc `..`*[T](b: sink T): HSlice[int, T] {.noSideEffect, inline, magic: "DotDot"
|
||||||
## echo a[.. 2] # @[10, 20, 30]
|
## echo a[.. 2] # @[10, 20, 30]
|
||||||
result = HSlice[int, T](a: 0, b: b)
|
result = HSlice[int, T](a: 0, b: b)
|
||||||
|
|
||||||
when not defined(niminheritable):
|
|
||||||
{.pragma: inheritable.}
|
|
||||||
when not defined(nimunion):
|
|
||||||
{.pragma: unchecked.}
|
|
||||||
when not defined(nimHasHotCodeReloading):
|
|
||||||
{.pragma: nonReloadable.}
|
|
||||||
when defined(hotCodeReloading):
|
when defined(hotCodeReloading):
|
||||||
{.pragma: hcrInline, inline.}
|
{.pragma: hcrInline, inline.}
|
||||||
else:
|
else:
|
||||||
|
|
@ -631,23 +608,21 @@ proc sizeof*[T](x: T): int {.magic: "SizeOf", noSideEffect.}
|
||||||
## sizeof('A') # => 1
|
## sizeof('A') # => 1
|
||||||
## sizeof(2) # => 8
|
## sizeof(2) # => 8
|
||||||
|
|
||||||
when defined(nimHasalignOf):
|
proc alignof*[T](x: T): int {.magic: "AlignOf", noSideEffect.}
|
||||||
proc alignof*[T](x: T): int {.magic: "AlignOf", noSideEffect.}
|
proc alignof*(x: typedesc): int {.magic: "AlignOf", noSideEffect.}
|
||||||
proc alignof*(x: typedesc): int {.magic: "AlignOf", noSideEffect.}
|
|
||||||
|
|
||||||
proc offsetOfDotExpr(typeAccess: typed): int {.magic: "OffsetOf", noSideEffect, compileTime.}
|
proc offsetOfDotExpr(typeAccess: typed): int {.magic: "OffsetOf", noSideEffect, compileTime.}
|
||||||
|
|
||||||
template offsetOf*[T](t: typedesc[T]; member: untyped): int =
|
template offsetOf*[T](t: typedesc[T]; member: untyped): int =
|
||||||
var tmp {.noinit.}: ptr T
|
var tmp {.noinit.}: ptr T
|
||||||
offsetOfDotExpr(tmp[].member)
|
offsetOfDotExpr(tmp[].member)
|
||||||
|
|
||||||
template offsetOf*[T](value: T; member: untyped): int =
|
template offsetOf*[T](value: T; member: untyped): int =
|
||||||
offsetOfDotExpr(value.member)
|
offsetOfDotExpr(value.member)
|
||||||
|
|
||||||
#proc offsetOf*(memberaccess: typed): int {.magic: "OffsetOf", noSideEffect.}
|
#proc offsetOf*(memberaccess: typed): int {.magic: "OffsetOf", noSideEffect.}
|
||||||
|
|
||||||
when defined(nimtypedescfixed):
|
proc sizeof*(x: typedesc): int {.magic: "SizeOf", noSideEffect.}
|
||||||
proc sizeof*(x: typedesc): int {.magic: "SizeOf", noSideEffect.}
|
|
||||||
|
|
||||||
|
|
||||||
proc newSeq*[T](s: var seq[T], len: Natural) {.magic: "NewSeq", noSideEffect.}
|
proc newSeq*[T](s: var seq[T], len: Natural) {.magic: "NewSeq", noSideEffect.}
|
||||||
|
|
@ -969,52 +944,42 @@ proc cmp*(x, y: string): int {.noSideEffect.}
|
||||||
## **Note**: The precise result values depend on the used C runtime library and
|
## **Note**: The precise result values depend on the used C runtime library and
|
||||||
## can differ between operating systems!
|
## can differ between operating systems!
|
||||||
|
|
||||||
when defined(nimHasDefault):
|
proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.magic: "ArrToSeq", noSideEffect.}
|
||||||
proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.
|
## Turns an array into a sequence.
|
||||||
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
|
||||||
## This most often useful for constructing
|
## `seq[int]`, while `[1, 2, 3]` has the type `array[0..2, int]`.
|
||||||
## sequences with the array constructor: `@[1, 2, 3]` has the type
|
##
|
||||||
## `seq[int]`, while `[1, 2, 3]` has the type `array[0..2, int]`.
|
## .. code-block:: Nim
|
||||||
##
|
## let
|
||||||
## .. code-block:: Nim
|
## a = [1, 3, 5]
|
||||||
## let
|
## b = "foo"
|
||||||
## a = [1, 3, 5]
|
##
|
||||||
## b = "foo"
|
## echo @a # => @[1, 3, 5]
|
||||||
##
|
## echo @b # => @['f', 'o', 'o']
|
||||||
## echo @a # => @[1, 3, 5]
|
|
||||||
## echo @b # => @['f', 'o', 'o']
|
|
||||||
|
|
||||||
proc default*(T: typedesc): T {.magic: "Default", noSideEffect.} =
|
proc default*(T: typedesc): T {.magic: "Default", noSideEffect.} =
|
||||||
## returns the default value of the type `T`.
|
## returns the default value of the type `T`.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
assert (int, float).default == (0, 0.0)
|
assert (int, float).default == (0, 0.0)
|
||||||
# note: `var a = default(T)` is usually the same as `var a: T` and (currently) generates
|
# 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
|
# a value whose binary representation is all 0, regardless of whether this
|
||||||
# would violate type constraints such as `range`, `not nil`, etc. This
|
# would violate type constraints such as `range`, `not nil`, etc. This
|
||||||
# property is required to implement certain algorithms efficiently which
|
# property is required to implement certain algorithms efficiently which
|
||||||
# may require intermediate invalid states.
|
# may require intermediate invalid states.
|
||||||
type Foo = object
|
type Foo = object
|
||||||
a: range[2..6]
|
a: range[2..6]
|
||||||
var a1: range[2..6] # currently, this compiles
|
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 a2: Foo # currently, this errors: Error: The Foo type doesn't have a default value.
|
||||||
# var a3 = Foo() # ditto
|
# var a3 = Foo() # ditto
|
||||||
var a3 = Foo.default # this works, but generates a `UnsafeDefault` warning.
|
var a3 = Foo.default # this works, but generates a `UnsafeDefault` warning.
|
||||||
# note: the doc comment also explains why `default` can't be implemented
|
# note: the doc comment also explains why `default` can't be implemented
|
||||||
# via: `template default*[T](t: typedesc[T]): T = (var v: T; v)`
|
# via: `template default*[T](t: typedesc[T]): T = (var v: T; v)`
|
||||||
|
|
||||||
proc reset*[T](obj: var T) {.noSideEffect.} =
|
proc reset*[T](obj: var T) {.noSideEffect.} =
|
||||||
## Resets an object `obj` to its default value.
|
## Resets an object `obj` to its default value.
|
||||||
obj = default(typeof(obj))
|
obj = default(typeof(obj))
|
||||||
|
|
||||||
else:
|
|
||||||
proc `@`* [IDX, T](a: array[IDX, T]): seq[T] {.
|
|
||||||
magic: "ArrToSeq", noSideEffect.}
|
|
||||||
when defined(nimV2):
|
|
||||||
proc reset*[T](obj: var T) {.magic: "Destroy", noSideEffect.}
|
|
||||||
else:
|
|
||||||
proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.}
|
|
||||||
|
|
||||||
proc setLen*[T](s: var seq[T], newlen: Natural) {.
|
proc setLen*[T](s: var seq[T], newlen: Natural) {.
|
||||||
magic: "SetLengthSeq", noSideEffect.}
|
magic: "SetLengthSeq", noSideEffect.}
|
||||||
|
|
@ -2065,34 +2030,28 @@ elif hasAlloc:
|
||||||
inc(i)
|
inc(i)
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
when defined(nimvarargstyped):
|
proc echo*(x: varargs[typed, `$`]) {.magic: "Echo", tags: [WriteIOEffect],
|
||||||
proc echo*(x: varargs[typed, `$`]) {.magic: "Echo", tags: [WriteIOEffect],
|
benign, sideEffect.}
|
||||||
benign, sideEffect.}
|
## Writes and flushes the parameters to the standard output.
|
||||||
## Writes and flushes the parameters to the standard output.
|
##
|
||||||
##
|
## Special built-in that takes a variable number of arguments. Each argument
|
||||||
## Special built-in that takes a variable number of arguments. Each argument
|
## is converted to a string via `$`, so it works for user-defined
|
||||||
## is converted to a string via `$`, so it works for user-defined
|
## types that have an overloaded `$` operator.
|
||||||
## types that have an overloaded `$` operator.
|
## It is roughly equivalent to `writeLine(stdout, x); flushFile(stdout)`, but
|
||||||
## It is roughly equivalent to `writeLine(stdout, x); flushFile(stdout)`, but
|
## available for the JavaScript target too.
|
||||||
## available for the JavaScript target too.
|
##
|
||||||
##
|
## Unlike other IO operations this is guaranteed to be thread-safe as
|
||||||
## 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` is very often used for debugging convenience. If you want to use
|
## `echo` inside a `proc without side effects
|
||||||
## `echo` inside a `proc without side effects
|
## <manual.html#pragmas-nosideeffect-pragma>`_ you can use `debugEcho
|
||||||
## <manual.html#pragmas-nosideeffect-pragma>`_ you can use `debugEcho
|
## <#debugEcho,varargs[typed,]>`_ instead.
|
||||||
## <#debugEcho,varargs[typed,]>`_ instead.
|
|
||||||
|
|
||||||
proc debugEcho*(x: varargs[typed, `$`]) {.magic: "Echo", noSideEffect,
|
proc debugEcho*(x: varargs[typed, `$`]) {.magic: "Echo", noSideEffect,
|
||||||
tags: [], raises: [].}
|
tags: [], raises: [].}
|
||||||
## Same as `echo <#echo,varargs[typed,]>`_, but as a special semantic rule,
|
## 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
|
## `debugEcho` pretends to be free of side effects, so that it can be used
|
||||||
## for debugging routines marked as `noSideEffect
|
## for debugging routines marked as `noSideEffect
|
||||||
## <manual.html#pragmas-nosideeffect-pragma>`_.
|
## <manual.html#pragmas-nosideeffect-pragma>`_.
|
||||||
else:
|
|
||||||
proc echo*(x: varargs[untyped, `$`]) {.magic: "Echo", tags: [WriteIOEffect],
|
|
||||||
benign, sideEffect.}
|
|
||||||
proc debugEcho*(x: varargs[untyped, `$`]) {.magic: "Echo", noSideEffect,
|
|
||||||
tags: [], raises: [].}
|
|
||||||
|
|
||||||
template newException*(exceptn: typedesc, message: string;
|
template newException*(exceptn: typedesc, message: string;
|
||||||
parentException: ref Exception = nil): untyped =
|
parentException: ref Exception = nil): untyped =
|
||||||
|
|
@ -2796,9 +2755,6 @@ when compileOption("rangechecks"):
|
||||||
else:
|
else:
|
||||||
template rangeCheck*(cond) = discard
|
template rangeCheck*(cond) = discard
|
||||||
|
|
||||||
when not defined(nimhygiene):
|
|
||||||
{.pragma: inject.}
|
|
||||||
|
|
||||||
proc shallow*[T](s: var seq[T]) {.noSideEffect, inline.} =
|
proc shallow*[T](s: var seq[T]) {.noSideEffect, inline.} =
|
||||||
## Marks a sequence `s` as `shallow`:idx:. Subsequent assignments will not
|
## Marks a sequence `s` as `shallow`:idx:. Subsequent assignments will not
|
||||||
## perform deep copies of `s`.
|
## perform deep copies of `s`.
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@
|
||||||
# All symbols are prefixed with 'c_' to avoid ambiguities
|
# All symbols are prefixed with 'c_' to avoid ambiguities
|
||||||
|
|
||||||
{.push hints:off, stack_trace: off, profiler: off.}
|
{.push hints:off, stack_trace: off, profiler: off.}
|
||||||
when not defined(nimHasHotCodeReloading):
|
|
||||||
{.pragma: nonReloadable.}
|
|
||||||
|
|
||||||
proc c_memchr*(s: pointer, c: cint, n: csize_t): pointer {.
|
proc c_memchr*(s: pointer, c: cint, n: csize_t): pointer {.
|
||||||
importc: "memchr", header: "<string.h>".}
|
importc: "memchr", header: "<string.h>".}
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ proc `mod`*(x, y: int16): int16 {.magic: "ModI", noSideEffect.}
|
||||||
proc `mod`*(x, y: int32): int32 {.magic: "ModI", noSideEffect.}
|
proc `mod`*(x, y: int32): int32 {.magic: "ModI", noSideEffect.}
|
||||||
proc `mod`*(x, y: int64): int64 {.magic: "ModI", noSideEffect.}
|
proc `mod`*(x, y: int64): int64 {.magic: "ModI", noSideEffect.}
|
||||||
|
|
||||||
when defined(nimOldShiftRight) or not defined(nimAshr):
|
when defined(nimOldShiftRight):
|
||||||
const shrDepMessage = "`shr` will become sign preserving."
|
const shrDepMessage = "`shr` will become sign preserving."
|
||||||
proc `shr`*(x: int, y: SomeInteger): int {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
|
proc `shr`*(x: int, y: SomeInteger): int {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
|
||||||
proc `shr`*(x: int8, y: SomeInteger): int8 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
|
proc `shr`*(x: int8, y: SomeInteger): int8 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
|
||||||
|
|
@ -271,27 +271,23 @@ proc `shl`*(x: int16, y: SomeInteger): int16 {.magic: "ShlI", noSideEffect.}
|
||||||
proc `shl`*(x: int32, y: SomeInteger): int32 {.magic: "ShlI", noSideEffect.}
|
proc `shl`*(x: int32, y: SomeInteger): int32 {.magic: "ShlI", noSideEffect.}
|
||||||
proc `shl`*(x: int64, y: SomeInteger): int64 {.magic: "ShlI", noSideEffect.}
|
proc `shl`*(x: int64, y: SomeInteger): int64 {.magic: "ShlI", noSideEffect.}
|
||||||
|
|
||||||
when defined(nimAshr):
|
proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} =
|
||||||
proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} =
|
## Shifts right by pushing copies of the leftmost bit in from the left,
|
||||||
## Shifts right by pushing copies of the leftmost bit in from the left,
|
## and let the rightmost bits fall off.
|
||||||
## and let the rightmost bits fall off.
|
##
|
||||||
##
|
## Note that `ashr` is not an operator so use the normal function
|
||||||
## Note that `ashr` is not an operator so use the normal function
|
## call syntax for it.
|
||||||
## call syntax for it.
|
##
|
||||||
##
|
## See also:
|
||||||
## See also:
|
## * `shr func<#shr,int,SomeInteger>`_
|
||||||
## * `shr func<#shr,int,SomeInteger>`_
|
runnableExamples:
|
||||||
runnableExamples:
|
assert ashr(0b0001_0000'i8, 2) == 0b0000_0100'i8
|
||||||
assert ashr(0b0001_0000'i8, 2) == 0b0000_0100'i8
|
assert ashr(0b1000_0000'i8, 8) == 0b1111_1111'i8
|
||||||
assert ashr(0b1000_0000'i8, 8) == 0b1111_1111'i8
|
assert ashr(0b1000_0000'i8, 1) == 0b1100_0000'i8
|
||||||
assert ashr(0b1000_0000'i8, 1) == 0b1100_0000'i8
|
proc ashr*(x: int8, y: SomeInteger): int8 {.magic: "AshrI", noSideEffect.}
|
||||||
proc ashr*(x: int8, y: SomeInteger): int8 {.magic: "AshrI", noSideEffect.}
|
proc ashr*(x: int16, y: SomeInteger): int16 {.magic: "AshrI", noSideEffect.}
|
||||||
proc ashr*(x: int16, y: SomeInteger): int16 {.magic: "AshrI", noSideEffect.}
|
proc ashr*(x: int32, y: SomeInteger): int32 {.magic: "AshrI", noSideEffect.}
|
||||||
proc ashr*(x: int32, y: SomeInteger): int32 {.magic: "AshrI", noSideEffect.}
|
proc ashr*(x: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.}
|
||||||
proc ashr*(x: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.}
|
|
||||||
else:
|
|
||||||
# used for bootstrapping the compiler
|
|
||||||
proc ashr*[T](x: T, y: SomeInteger): T = discard
|
|
||||||
|
|
||||||
proc `and`*(x, y: int): int {.magic: "BitandI", noSideEffect.} =
|
proc `and`*(x, y: int): int {.magic: "BitandI", noSideEffect.} =
|
||||||
## Computes the `bitwise and` of numbers `x` and `y`.
|
## Computes the `bitwise and` of numbers `x` and `y`.
|
||||||
|
|
|
||||||
|
|
@ -282,12 +282,8 @@ proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} =
|
||||||
## Generic equals operator for sequences: relies on a equals operator for
|
## Generic equals operator for sequences: relies on a equals operator for
|
||||||
## the element type `T`.
|
## the element type `T`.
|
||||||
when nimvm:
|
when nimvm:
|
||||||
when not defined(nimNoNil):
|
if x.len == 0 and y.len == 0:
|
||||||
if x.isNil and y.isNil:
|
return true
|
||||||
return true
|
|
||||||
else:
|
|
||||||
if x.len == 0 and y.len == 0:
|
|
||||||
return true
|
|
||||||
else:
|
else:
|
||||||
when not defined(js):
|
when not defined(js):
|
||||||
proc seqToPtr[T](x: seq[T]): pointer {.inline, noSideEffect.} =
|
proc seqToPtr[T](x: seq[T]): pointer {.inline, noSideEffect.} =
|
||||||
|
|
@ -303,10 +299,6 @@ proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} =
|
||||||
asm """`sameObject` = `x` === `y`"""
|
asm """`sameObject` = `x` === `y`"""
|
||||||
if sameObject: return true
|
if sameObject: return true
|
||||||
|
|
||||||
when not defined(nimNoNil):
|
|
||||||
if x.isNil or y.isNil:
|
|
||||||
return false
|
|
||||||
|
|
||||||
if x.len != y.len:
|
if x.len != y.len:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,10 +161,7 @@ elif defined(windows) or defined(dos):
|
||||||
dec(m)
|
dec(m)
|
||||||
k = k div 10
|
k = k div 10
|
||||||
if k == 0: break
|
if k == 0: break
|
||||||
when defined(nimNoArrayToCstringConversion):
|
result = getProcAddress(cast[THINSTANCE](lib), addr decorated)
|
||||||
result = getProcAddress(cast[THINSTANCE](lib), addr decorated)
|
|
||||||
else:
|
|
||||||
result = getProcAddress(cast[THINSTANCE](lib), decorated)
|
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
procAddrError(name)
|
procAddrError(name)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -393,15 +393,10 @@ proc reportUnhandledErrorAux(e: ref Exception) {.nodestroy.} =
|
||||||
add(buf, " [")
|
add(buf, " [")
|
||||||
xadd(buf, e.name, e.name.len)
|
xadd(buf, e.name, e.name.len)
|
||||||
add(buf, "]\n")
|
add(buf, "]\n")
|
||||||
when defined(nimNoArrayToCstringConversion):
|
|
||||||
template tbuf(): untyped = addr buf
|
|
||||||
else:
|
|
||||||
template tbuf(): untyped = buf
|
|
||||||
|
|
||||||
if onUnhandledException != nil:
|
if onUnhandledException != nil:
|
||||||
onUnhandledException($tbuf())
|
onUnhandledException($buf.addr)
|
||||||
else:
|
else:
|
||||||
showErrorMessage(tbuf(), L)
|
showErrorMessage(buf.addr, L)
|
||||||
|
|
||||||
proc reportUnhandledError(e: ref Exception) {.nodestroy.} =
|
proc reportUnhandledError(e: ref Exception) {.nodestroy.} =
|
||||||
if unhandledExceptionHook != nil:
|
if unhandledExceptionHook != nil:
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,7 @@ else:
|
||||||
{.pragma: inl, inline.}
|
{.pragma: inl, inline.}
|
||||||
{.pragma: compilerRtl, compilerproc.}
|
{.pragma: compilerRtl, compilerproc.}
|
||||||
|
|
||||||
when defined(nimlocks):
|
{.pragma: benign, gcsafe, locks: 0.}
|
||||||
{.pragma: benign, gcsafe, locks: 0.}
|
|
||||||
else:
|
|
||||||
{.pragma: benign, gcsafe.}
|
|
||||||
|
|
||||||
when defined(nimHasSinkInference):
|
when defined(nimHasSinkInference):
|
||||||
{.push sinkInference: on.}
|
{.push sinkInference: on.}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
const useLibC = not defined(nimNoLibc)
|
const useLibC = not defined(nimNoLibc)
|
||||||
|
|
||||||
when not defined(nimHasHotCodeReloading):
|
|
||||||
{.pragma: nonReloadable.}
|
|
||||||
|
|
||||||
when useLibC:
|
when useLibC:
|
||||||
import ansi_c
|
import ansi_c
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,9 @@ proc reprInt(x: int64): string {.compilerproc.} = return $x
|
||||||
proc reprFloat(x: float): string {.compilerproc.} = return $x
|
proc reprFloat(x: float): string {.compilerproc.} = return $x
|
||||||
|
|
||||||
proc reprPointer(x: pointer): string {.compilerproc.} =
|
proc reprPointer(x: pointer): string {.compilerproc.} =
|
||||||
when defined(nimNoArrayToCstringConversion):
|
result = newString(60)
|
||||||
result = newString(60)
|
let n = c_sprintf(addr result[0], "%p", x)
|
||||||
let n = c_sprintf(addr result[0], "%p", x)
|
setLen(result, n)
|
||||||
setLen(result, n)
|
|
||||||
else:
|
|
||||||
var buf: array[0..59, char]
|
|
||||||
discard c_sprintf(buf, "%p", x)
|
|
||||||
return $buf
|
|
||||||
|
|
||||||
proc reprStrAux(result: var string, s: cstring; len: int) =
|
proc reprStrAux(result: var string, s: cstring; len: int) =
|
||||||
if cast[pointer](s) == nil:
|
if cast[pointer](s) == nil:
|
||||||
|
|
|
||||||
|
|
@ -329,11 +329,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
|
||||||
t[ti-2] = ('0'.ord + absExponent mod 10).char
|
t[ti-2] = ('0'.ord + absExponent mod 10).char
|
||||||
absExponent = absExponent div 10
|
absExponent = absExponent div 10
|
||||||
t[ti-3] = ('0'.ord + absExponent mod 10).char
|
t[ti-3] = ('0'.ord + absExponent mod 10).char
|
||||||
|
number = c_strtod(addr t, nil)
|
||||||
when defined(nimNoArrayToCstringConversion):
|
|
||||||
number = c_strtod(addr t, nil)
|
|
||||||
else:
|
|
||||||
number = c_strtod(t, nil)
|
|
||||||
|
|
||||||
when defined(nimHasInvariant):
|
when defined(nimHasInvariant):
|
||||||
{.pop.} # staticBoundChecks
|
{.pop.} # staticBoundChecks
|
||||||
|
|
|
||||||
|
|
@ -209,9 +209,6 @@ proc extractSpec(filename: string; spec: var TSpec): string =
|
||||||
#echo "warning: file does not contain spec: " & filename
|
#echo "warning: file does not contain spec: " & filename
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
when not defined(nimhygiene):
|
|
||||||
{.pragma: inject.}
|
|
||||||
|
|
||||||
proc parseTargets*(value: string): set[TTarget] =
|
proc parseTargets*(value: string): set[TTarget] =
|
||||||
for v in value.normalize.splitWhitespace:
|
for v in value.normalize.splitWhitespace:
|
||||||
case v
|
case v
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@ discard """
|
||||||
joinable: false
|
joinable: false
|
||||||
"""
|
"""
|
||||||
|
|
||||||
when not defined(nimNewRuntime):
|
# This bug could only be reproduced with --newruntime
|
||||||
{.error: "This bug could only be reproduced with --newruntime".}
|
|
||||||
|
|
||||||
type
|
type
|
||||||
Obj = object
|
Obj = object
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue