mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +00:00
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:
@@ -997,14 +997,9 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||
if ty.kind in {tyRef, tyPtr}:
|
||||
ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check:
|
||||
if optBoundsCheck in p.options:
|
||||
if ty.kind == tyString and not defined(nimNoZeroTerminator):
|
||||
linefmt(p, cpsStmts,
|
||||
"if ((NU)($1) > (NU)$2){ #raiseIndexError2($1,$2); $3}$n",
|
||||
[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)])
|
||||
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 skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
||||
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)
|
||||
else: doAssert(false, "ccgmerge: unknown key: " & k)
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: inject.}
|
||||
|
||||
template withCFile(cfilename: AbsoluteFile, body: untyped) =
|
||||
var s = llStreamOpen(cfilename, fmRead)
|
||||
if s == nil: return
|
||||
|
||||
@@ -34,55 +34,57 @@ proc countDefinedSymbols*(symbols: StringTableRef): int =
|
||||
proc initDefines*(symbols: StringTableRef) =
|
||||
# for bootstrapping purposes and old code:
|
||||
template defineSymbol(s) = symbols.defineSymbol(s)
|
||||
defineSymbol("nimhygiene")
|
||||
defineSymbol("niminheritable")
|
||||
defineSymbol("nimmixin")
|
||||
defineSymbol("nimeffects")
|
||||
defineSymbol("nimbabel")
|
||||
defineSymbol("nimcomputedgoto")
|
||||
defineSymbol("nimunion")
|
||||
defineSymbol("nimnewshared")
|
||||
defineSymbol("nimNewTypedesc")
|
||||
defineSymbol("nimrequiresnimframe")
|
||||
defineSymbol("nimparsebiggestfloatmagic")
|
||||
defineSymbol("nimalias")
|
||||
defineSymbol("nimlocks")
|
||||
defineSymbol("nimnode")
|
||||
defineSymbol("nimvarargstyped")
|
||||
defineSymbol("nimtypedescfixed")
|
||||
defineSymbol("nimKnowsNimvm")
|
||||
defineSymbol("nimArrIdx")
|
||||
defineSymbol("nimHasalignOf")
|
||||
defineSymbol("nimDistros")
|
||||
defineSymbol("nimHasCppDefine")
|
||||
defineSymbol("nimGenericInOutFlags")
|
||||
when false: defineSymbol("nimHasOpt")
|
||||
defineSymbol("nimNoArrayToCstringConversion")
|
||||
defineSymbol("nimHasRunnableExamples")
|
||||
defineSymbol("nimNewDot")
|
||||
defineSymbol("nimHasNilChecks")
|
||||
defineSymbol("nimSymKind")
|
||||
defineSymbol("nimVmEqIdent")
|
||||
defineSymbol("nimNoNil")
|
||||
defineSymbol("nimNoZeroTerminator")
|
||||
defineSymbol("nimNotNil")
|
||||
defineSymbol("nimVmExportFixed")
|
||||
defineSymbol("nimHasSymOwnerInMacro")
|
||||
defineSymbol("nimNewRuntime")
|
||||
defineSymbol("nimIncrSeqV3")
|
||||
defineSymbol("nimAshr")
|
||||
defineSymbol("nimhygiene") # deadcode
|
||||
defineSymbol("niminheritable") # deadcode
|
||||
defineSymbol("nimmixin") # deadcode
|
||||
defineSymbol("nimeffects") # deadcode
|
||||
defineSymbol("nimbabel") # deadcode
|
||||
defineSymbol("nimcomputedgoto") # deadcode
|
||||
defineSymbol("nimunion") # deadcode
|
||||
defineSymbol("nimnewshared") # deadcode
|
||||
defineSymbol("nimNewTypedesc") # deadcode
|
||||
defineSymbol("nimrequiresnimframe") # deadcode
|
||||
defineSymbol("nimparsebiggestfloatmagic") # deadcode
|
||||
defineSymbol("nimalias") # deadcode
|
||||
defineSymbol("nimlocks") # deadcode
|
||||
defineSymbol("nimnode") # deadcode pending tests/deps/opengl-1.1.0/opengl.nim
|
||||
defineSymbol("nimvarargstyped") # deadcode
|
||||
defineSymbol("nimtypedescfixed") # deadcode
|
||||
defineSymbol("nimKnowsNimvm") # deadcode
|
||||
defineSymbol("nimArrIdx") # deadcode
|
||||
defineSymbol("nimHasalignOf") # deadcode
|
||||
defineSymbol("nimDistros") # deadcode
|
||||
defineSymbol("nimHasCppDefine") # deadcode
|
||||
defineSymbol("nimGenericInOutFlags") # deadcode
|
||||
when false: defineSymbol("nimHasOpt") # deadcode
|
||||
defineSymbol("nimNoArrayToCstringConversion") # deadcode
|
||||
defineSymbol("nimHasRunnableExamples") # deadcode
|
||||
defineSymbol("nimNewDot") # deadcode
|
||||
defineSymbol("nimHasNilChecks") # deadcode
|
||||
defineSymbol("nimSymKind") # deadcode
|
||||
defineSymbol("nimVmEqIdent") # deadcode
|
||||
defineSymbol("nimNoNil") # deadcode
|
||||
defineSymbol("nimNoZeroTerminator") # deadcode
|
||||
defineSymbol("nimNotNil") # deadcode
|
||||
defineSymbol("nimVmExportFixed") # deadcode
|
||||
defineSymbol("nimHasSymOwnerInMacro") # deadcode
|
||||
defineSymbol("nimNewRuntime") # deadcode
|
||||
defineSymbol("nimIncrSeqV3") # xxx: turn this into deadcode
|
||||
defineSymbol("nimAshr") # deadcode
|
||||
defineSymbol("nimNoNilSeqs") # deadcode
|
||||
defineSymbol("nimNoNilSeqs2") # deadcode
|
||||
defineSymbol("nimHasUserErrors") # deadcode
|
||||
defineSymbol("nimUncheckedArrayTyp")
|
||||
defineSymbol("nimHasTypeof")
|
||||
defineSymbol("nimErrorProcCanHaveBody")
|
||||
defineSymbol("nimHasInstantiationOfInMacro")
|
||||
defineSymbol("nimHasHotCodeReloading")
|
||||
defineSymbol("nimHasNilSeqs")
|
||||
defineSymbol("nimHasSignatureHashInMacro")
|
||||
defineSymbol("nimHasDefault")
|
||||
defineSymbol("nimMacrosSizealignof")
|
||||
defineSymbol("nimUncheckedArrayTyp") # deadcode
|
||||
defineSymbol("nimHasTypeof") # deadcode
|
||||
defineSymbol("nimErrorProcCanHaveBody") # deadcode
|
||||
defineSymbol("nimHasInstantiationOfInMacro") # deadcode
|
||||
defineSymbol("nimHasHotCodeReloading") # deadcode
|
||||
defineSymbol("nimHasNilSeqs") # deadcode
|
||||
defineSymbol("nimHasSignatureHashInMacro") # deadcode
|
||||
defineSymbol("nimHasDefault") # deadcode
|
||||
defineSymbol("nimMacrosSizealignof") # deadcode
|
||||
|
||||
# > 0.20.0
|
||||
defineSymbol("nimNoZeroExtendMagic")
|
||||
defineSymbol("nimMacrosGetNodeId")
|
||||
for f in Feature:
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# this config.nims also needs to exist to prevent future regressions, see #9990
|
||||
|
||||
when defined(nimHasCppDefine):
|
||||
cppDefine "errno"
|
||||
cppDefine "unix"
|
||||
cppDefine "errno"
|
||||
cppDefine "unix"
|
||||
|
||||
@@ -43,14 +43,12 @@ path="$lib/arch"
|
||||
path="$lib/core"
|
||||
path="$lib/pure"
|
||||
|
||||
@if nimbabel:
|
||||
@if not windows:
|
||||
nimblepath="/opt/nimble/pkgs/"
|
||||
@else:
|
||||
# TODO:
|
||||
@end
|
||||
nimblepath="$home/.nimble/pkgs/"
|
||||
@if not windows:
|
||||
nimblepath="/opt/nimble/pkgs/"
|
||||
@else:
|
||||
# TODO:
|
||||
@end
|
||||
nimblepath="$home/.nimble/pkgs/"
|
||||
|
||||
@if danger or quick:
|
||||
obj_checks:off
|
||||
@@ -64,9 +62,7 @@ path="$lib/pure"
|
||||
debugger:off
|
||||
line_dir:off
|
||||
dead_code_elim:on
|
||||
@if nimHasNilChecks:
|
||||
nilchecks:off
|
||||
@end
|
||||
nilchecks:off
|
||||
@end
|
||||
|
||||
@if release or danger:
|
||||
|
||||
@@ -229,7 +229,17 @@ proc intVal*(n: NimNode): BiggestInt {.magic: "NIntVal", noSideEffect.}
|
||||
proc floatVal*(n: NimNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.}
|
||||
## 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:
|
||||
"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".}
|
||||
|
||||
when defined(nimSymKind):
|
||||
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.
|
||||
proc `$`*(i: NimIdent): string {.magic: "NStrVal", noSideEffect, deprecated:
|
||||
"Deprecated since version 0.18.1; Use 'strVal' instead.".}
|
||||
## Converts a Nim identifier to a string.
|
||||
|
||||
proc `$`*(i: NimIdent): string {.magic: "NStrVal", noSideEffect, deprecated:
|
||||
"Deprecated since version 0.18.1; Use 'strVal' instead.".}
|
||||
## Converts a Nim identifier 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
|
||||
proc `$`*(s: NimSym): string {.magic: "NStrVal", noSideEffect, deprecated:
|
||||
"Deprecated since version 0.18.1; Use 'strVal' instead.".}
|
||||
## Converts a Nim symbol to a string.
|
||||
|
||||
{.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.
|
||||
## See an example in `tests/macros/tmacros_various.nim`.
|
||||
|
||||
when defined(nimHasSymOwnerInMacro):
|
||||
proc owner*(sym: NimNode): NimNode {.magic: "SymOwner", noSideEffect.}
|
||||
## Accepts a node of kind `nnkSym` and returns its owner's symbol.
|
||||
## The meaning of 'owner' depends on `sym`'s `NimSymKind` and declaration
|
||||
## context. For top level declarations this is an `nskModule` symbol,
|
||||
## for proc local variables an `nskProc` symbol, for enum/object fields an
|
||||
## `nskType` symbol, etc. For symbols without an owner, `nil` is returned.
|
||||
##
|
||||
## See also:
|
||||
## * `symKind proc<#symKind,NimNode>`_ to get the kind of a symbol
|
||||
## * `getImpl proc<#getImpl,NimNode>`_ to get the declaration of a symbol
|
||||
proc owner*(sym: NimNode): NimNode {.magic: "SymOwner", noSideEffect.}
|
||||
## Accepts a node of kind `nnkSym` and returns its owner's symbol.
|
||||
## The meaning of 'owner' depends on `sym`'s `NimSymKind` and declaration
|
||||
## context. For top level declarations this is an `nskModule` symbol,
|
||||
## for proc local variables an `nskProc` symbol, for enum/object fields an
|
||||
## `nskType` symbol, etc. For symbols without an owner, `nil` is returned.
|
||||
##
|
||||
## See also:
|
||||
## * `symKind proc<#symKind,NimNode>`_ to get the kind 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.}
|
||||
## Checks if a proc symbol is an instance of the generic proc symbol.
|
||||
## Useful to check proc symbols against generic symbols
|
||||
## returned by `bindSym`.
|
||||
proc isInstantiationOf*(instanceProcSym, genProcSym: NimNode): bool {.magic: "SymIsInstantiationOf", noSideEffect.}
|
||||
## Checks if a proc symbol is an instance of the generic proc symbol.
|
||||
## Useful to check proc symbols against generic symbols
|
||||
## returned by `bindSym`.
|
||||
|
||||
proc getType*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
|
||||
## 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(c) == t)
|
||||
|
||||
when defined(nimHasSignatureHashInMacro):
|
||||
proc signatureHash*(n: NimNode): string {.magic: "NSigHash", noSideEffect.}
|
||||
## Returns a stable identifier derived from the signature of a 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
|
||||
## used in the back-end to produce the mangled symbol name.
|
||||
proc signatureHash*(n: NimNode): string {.magic: "NSigHash", noSideEffect.}
|
||||
## Returns a stable identifier derived from the signature of a 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
|
||||
## used in the back-end to produce the mangled symbol name.
|
||||
|
||||
proc symBodyHash*(s: NimNode): string {.noSideEffect.} =
|
||||
## 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>`_.
|
||||
return node.copyNimTree()
|
||||
|
||||
when defined(nimVmEqIdent):
|
||||
proc eqIdent*(a: string; b: string): bool {.magic: "EqIdent", noSideEffect.}
|
||||
## Style insensitive comparison.
|
||||
proc eqIdent*(a: string; b: string): bool {.magic: "EqIdent", noSideEffect.}
|
||||
## Style insensitive comparison.
|
||||
|
||||
proc eqIdent*(a: NimNode; b: string): bool {.magic: "EqIdent", noSideEffect.}
|
||||
## Style insensitive comparison. ``a`` can be an identifier or a
|
||||
## symbol. ``a`` may be wrapped in an export marker
|
||||
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
||||
## these nodes will be unwrapped.
|
||||
proc eqIdent*(a: NimNode; b: string): bool {.magic: "EqIdent", noSideEffect.}
|
||||
## Style insensitive comparison. ``a`` can be an identifier or a
|
||||
## symbol. ``a`` may be wrapped in an export marker
|
||||
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
||||
## these nodes will be unwrapped.
|
||||
|
||||
proc eqIdent*(a: string; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
|
||||
## Style insensitive comparison. ``b`` can be an identifier or a
|
||||
## symbol. ``b`` may be wrapped in an export marker
|
||||
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
||||
## these nodes will be unwrapped.
|
||||
proc eqIdent*(a: string; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
|
||||
## Style insensitive comparison. ``b`` can be an identifier or a
|
||||
## symbol. ``b`` may be wrapped in an export marker
|
||||
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
||||
## these nodes will be unwrapped.
|
||||
|
||||
proc eqIdent*(a: NimNode; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
|
||||
## Style insensitive comparison. ``a`` and ``b`` can be an
|
||||
## identifier or a symbol. Both may be wrapped in an export marker
|
||||
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
||||
## 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 eqIdent*(a: NimNode; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
|
||||
## Style insensitive comparison. ``a`` and ``b`` can be an
|
||||
## identifier or a symbol. Both may be wrapped in an export marker
|
||||
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
|
||||
## these nodes will be unwrapped.
|
||||
|
||||
proc expectIdent*(n: NimNode, name: string) {.compileTime, since: (1,1).} =
|
||||
## Check that ``eqIdent(n,name)`` holds true. If this is not the
|
||||
@@ -1672,22 +1632,21 @@ proc getProjectPath*(): string = discard
|
||||
## See also:
|
||||
## * `getCurrentDir proc <os.html#getCurrentDir>`_
|
||||
|
||||
when defined(nimMacrosSizealignof):
|
||||
proc getSize*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||
## Returns the same result as ``system.sizeof`` if the size is
|
||||
## known by the Nim compiler. Returns a negative value if the Nim
|
||||
## compiler does not know the size.
|
||||
proc getAlign*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||
## Returns the same result as ``system.alignof`` if the alignment
|
||||
## is known by the Nim compiler. It works on ``NimNode`` for use
|
||||
## in macro context. Returns a negative value if the Nim compiler
|
||||
## does not know the alignment.
|
||||
proc getOffset*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||
## Returns the same result as ``system.offsetof`` if the offset is
|
||||
## known by the Nim compiler. It expects a resolved symbol node
|
||||
## from a field of a type. Therefore it only requires one argument
|
||||
## instead of two. Returns a negative value if the Nim compiler
|
||||
## does not know the offset.
|
||||
proc getSize*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||
## Returns the same result as ``system.sizeof`` if the size is
|
||||
## known by the Nim compiler. Returns a negative value if the Nim
|
||||
## compiler does not know the size.
|
||||
proc getAlign*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||
## Returns the same result as ``system.alignof`` if the alignment
|
||||
## is known by the Nim compiler. It works on ``NimNode`` for use
|
||||
## in macro context. Returns a negative value if the Nim compiler
|
||||
## does not know the alignment.
|
||||
proc getOffset*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||
## Returns the same result as ``system.offsetof`` if the offset is
|
||||
## known by the Nim compiler. It expects a resolved symbol node
|
||||
## from a field of a type. Therefore it only requires one argument
|
||||
## instead of two. Returns a negative value if the Nim compiler
|
||||
## does not know the offset.
|
||||
|
||||
proc isExported*(n: NimNode): bool {.noSideEffect.} =
|
||||
## Returns whether the symbol is exported or not.
|
||||
|
||||
@@ -386,9 +386,6 @@ proc findAll*(s: string, pattern: Regex, start = 0): seq[string] {.inline.} =
|
||||
result = @[]
|
||||
for x in findAll(s, pattern, start): result.add x
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: inject.}
|
||||
|
||||
template `=~` *(s: string, pattern: Regex): untyped =
|
||||
## This calls ``match`` with an implicit declared ``matches`` array that
|
||||
## can be used in the scope of the ``=~`` call:
|
||||
|
||||
@@ -87,301 +87,300 @@ template forwardImpl(impl, arg) {.dirty.} =
|
||||
else:
|
||||
impl(x.uint64)
|
||||
|
||||
when defined(nimHasalignOf):
|
||||
type BitsRange*[T] = range[0..sizeof(T)*8-1]
|
||||
## A range with all bit positions for type `T`.
|
||||
type BitsRange*[T] = range[0..sizeof(T)*8-1]
|
||||
## A range with all bit positions for type `T`.
|
||||
|
||||
func bitsliced*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
||||
## Returns an extracted (and shifted) slice of bits from `v`.
|
||||
runnableExamples:
|
||||
doAssert 0b10111.bitsliced(2 .. 4) == 0b101
|
||||
doAssert 0b11100.bitsliced(0 .. 2) == 0b100
|
||||
doAssert 0b11100.bitsliced(0 ..< 3) == 0b100
|
||||
func bitsliced*[T: SomeInteger](v: T; slice: Slice[int]): T {.inline, since: (1, 3).} =
|
||||
## Returns an extracted (and shifted) slice of bits from `v`.
|
||||
runnableExamples:
|
||||
doAssert 0b10111.bitsliced(2 .. 4) == 0b101
|
||||
doAssert 0b11100.bitsliced(0 .. 2) == 0b100
|
||||
doAssert 0b11100.bitsliced(0 ..< 3) == 0b100
|
||||
|
||||
let
|
||||
upmost = sizeof(T) * 8 - 1
|
||||
uv = when v is SomeUnsignedInt: v else: v.toUnsigned
|
||||
(uv shl (upmost - slice.b) shr (upmost - slice.b + slice.a)).T
|
||||
let
|
||||
upmost = sizeof(T) * 8 - 1
|
||||
uv = when v is SomeUnsignedInt: v else: v.toUnsigned
|
||||
(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).} =
|
||||
## Mutates `v` into an extracted (and shifted) slice of bits from `v`.
|
||||
runnableExamples:
|
||||
var x = 0b101110
|
||||
x.bitslice(2 .. 4)
|
||||
doAssert x == 0b011
|
||||
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`.
|
||||
runnableExamples:
|
||||
var x = 0b101110
|
||||
x.bitslice(2 .. 4)
|
||||
doAssert x == 0b011
|
||||
|
||||
let
|
||||
upmost = sizeof(T) * 8 - 1
|
||||
uv = when v is SomeUnsignedInt: v else: v.toUnsigned
|
||||
v = (uv shl (upmost - slice.b) shr (upmost - slice.b + slice.a)).T
|
||||
let
|
||||
upmost = sizeof(T) * 8 - 1
|
||||
uv = when v is SomeUnsignedInt: v else: v.toUnsigned
|
||||
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).} =
|
||||
## Creates a bitmask based on a slice of bits.
|
||||
runnableExamples:
|
||||
doAssert toMask[int32](1 .. 3) == 0b1110'i32
|
||||
doAssert toMask[int32](0 .. 3) == 0b1111'i32
|
||||
func toMask*[T: SomeInteger](slice: Slice[int]): T {.inline, since: (1, 3).} =
|
||||
## Creates a bitmask based on a slice of bits.
|
||||
runnableExamples:
|
||||
doAssert toMask[int32](1 .. 3) == 0b1110'i32
|
||||
doAssert toMask[int32](0 .. 3) == 0b1111'i32
|
||||
|
||||
let
|
||||
upmost = sizeof(T) * 8 - 1
|
||||
bitmask = when T is SomeUnsignedInt:
|
||||
bitnot(0.T)
|
||||
else:
|
||||
bitnot(0.T).toUnsigned
|
||||
(bitmask shl (upmost - slice.b + slice.a) shr (upmost - slice.b)).T
|
||||
let
|
||||
upmost = sizeof(T) * 8 - 1
|
||||
bitmask = when T is SomeUnsignedInt:
|
||||
bitnot(0.T)
|
||||
else:
|
||||
bitnot(0.T).toUnsigned
|
||||
(bitmask shl (upmost - slice.b + slice.a) shr (upmost - slice.b)).T
|
||||
|
||||
proc masked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
||||
## Returns `v`, with only the `1` bits from `mask` matching those of
|
||||
## `v` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'u8
|
||||
doAssert v.masked(0b0000_1010'u8) == 0b0000_0010'u8
|
||||
proc masked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
||||
## Returns `v`, with only the `1` bits from `mask` matching those of
|
||||
## `v` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'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).} =
|
||||
## Returns `v`, with only the `1` bits in the range of `slice`
|
||||
## matching those of `v` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
let v = 0b0000_1011'u8
|
||||
doAssert v.masked(1 .. 3) == 0b0000_1010'u8
|
||||
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`
|
||||
## matching those of `v` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
let v = 0b0000_1011'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).} =
|
||||
## Mutates `v`, with only the `1` bits from `mask` matching those of
|
||||
## `v` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.mask(0b0000_1010'u8)
|
||||
doAssert v == 0b0000_0010'u8
|
||||
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
|
||||
## `v` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.mask(0b0000_1010'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).} =
|
||||
## Mutates `v`, with only the `1` bits in the range of `slice`
|
||||
## matching those of `v` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
var v = 0b0000_1011'u8
|
||||
v.mask(1 .. 3)
|
||||
doAssert v == 0b0000_1010'u8
|
||||
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`
|
||||
## matching those of `v` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
var v = 0b0000_1011'u8
|
||||
v.mask(1 .. 3)
|
||||
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).} =
|
||||
## Returns `v`, with all the `1` bits from `mask` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'u8
|
||||
doAssert v.setMasked(0b0000_1010'u8) == 0b0000_1011'u8
|
||||
func setMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
||||
## Returns `v`, with all the `1` bits from `mask` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'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).} =
|
||||
## 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.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'u8
|
||||
doAssert v.setMasked(2 .. 3) == 0b0000_1111'u8
|
||||
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.
|
||||
##
|
||||
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'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.} =
|
||||
## Mutates `v`, with all the `1` bits from `mask` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.setMask(0b0000_1010'u8)
|
||||
doAssert v == 0b0000_1011'u8
|
||||
proc setMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
|
||||
## Mutates `v`, with all the `1` bits from `mask` set to 1.
|
||||
##
|
||||
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.setMask(0b0000_1010'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).} =
|
||||
## 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.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.setMask(2 .. 3)
|
||||
doAssert v == 0b0000_1111'u8
|
||||
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.
|
||||
##
|
||||
## Effectively maps to a `bitor <#bitor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.setMask(2 .. 3)
|
||||
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).} =
|
||||
## Returns `v`, with all the `1` bits from `mask` set to 0.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
||||
## with an *inverted mask*.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'u8
|
||||
doAssert v.clearMasked(0b0000_1010'u8) == 0b0000_0001'u8
|
||||
func clearMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
||||
## Returns `v`, with all the `1` bits from `mask` set to 0.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
||||
## with an *inverted mask*.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'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).} =
|
||||
## 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
|
||||
## with an *inverted mask*.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'u8
|
||||
doAssert v.clearMasked(1 .. 3) == 0b0000_0001'u8
|
||||
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.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
||||
## with an *inverted mask*.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'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.} =
|
||||
## Mutates `v`, with all the `1` bits from `mask` set to 0.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
||||
## with an *inverted mask*.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.clearMask(0b0000_1010'u8)
|
||||
doAssert v == 0b0000_0001'u8
|
||||
proc clearMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
|
||||
## Mutates `v`, with all the `1` bits from `mask` set to 0.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
||||
## with an *inverted mask*.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.clearMask(0b0000_1010'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).} =
|
||||
## 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
|
||||
## with an *inverted mask*.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.clearMask(1 .. 3)
|
||||
doAssert v == 0b0000_0001'u8
|
||||
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.
|
||||
##
|
||||
## Effectively maps to a `bitand <#bitand.m,T,T,varargs[T]>`_ operation
|
||||
## with an *inverted mask*.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.clearMask(1 .. 3)
|
||||
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).} =
|
||||
## Returns `v`, with all the `1` bits from `mask` flipped.
|
||||
##
|
||||
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'u8
|
||||
doAssert v.flipMasked(0b0000_1010'u8) == 0b0000_1001'u8
|
||||
func flipMasked*[T: SomeInteger](v, mask :T): T {.inline, since: (1, 3).} =
|
||||
## Returns `v`, with all the `1` bits from `mask` flipped.
|
||||
##
|
||||
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'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).} =
|
||||
## 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.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'u8
|
||||
doAssert v.flipMasked(1 .. 3) == 0b0000_1101'u8
|
||||
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.
|
||||
##
|
||||
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
let v = 0b0000_0011'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.} =
|
||||
## Mutates `v`, with all the `1` bits from `mask` flipped.
|
||||
##
|
||||
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.flipMask(0b0000_1010'u8)
|
||||
doAssert v == 0b0000_1001'u8
|
||||
proc flipMask*[T: SomeInteger](v: var T; mask: T) {.inline.} =
|
||||
## Mutates `v`, with all the `1` bits from `mask` flipped.
|
||||
##
|
||||
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.flipMask(0b0000_1010'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).} =
|
||||
## 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.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.flipMask(1 .. 3)
|
||||
doAssert v == 0b0000_1101'u8
|
||||
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.
|
||||
##
|
||||
## Effectively maps to a `bitxor <#bitxor.m,T,T,varargs[T]>`_ operation.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.flipMask(1 .. 3)
|
||||
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.} =
|
||||
## Mutates `v`, with the bit at position `bit` set to 1.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.setBit(5'u8)
|
||||
doAssert v == 0b0010_0011'u8
|
||||
proc setBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
|
||||
## Mutates `v`, with the bit at position `bit` set to 1.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.setBit(5'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.} =
|
||||
## Mutates `v`, with the bit at position `bit` set to 0.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.clearBit(1'u8)
|
||||
doAssert v == 0b0000_0001'u8
|
||||
proc clearBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
|
||||
## Mutates `v`, with the bit at position `bit` set to 0.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.clearBit(1'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.} =
|
||||
## Mutates `v`, with the bit at position `bit` flipped.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.flipBit(1'u8)
|
||||
doAssert v == 0b0000_0001'u8
|
||||
proc flipBit*[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.} =
|
||||
## Mutates `v`, with the bit at position `bit` flipped.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.flipBit(1'u8)
|
||||
doAssert v == 0b0000_0001'u8
|
||||
|
||||
v = 0b0000_0011'u8
|
||||
v.flipBit(2'u8)
|
||||
doAssert v == 0b0000_0111'u8
|
||||
v = 0b0000_0011'u8
|
||||
v.flipBit(2'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 =
|
||||
## Mutates `v`, with the bits at positions `bits` set to 1.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.setBits(3, 5, 7)
|
||||
doAssert v == 0b1010_1011'u8
|
||||
macro setBits*(v: typed; bits: varargs[typed]): untyped =
|
||||
## Mutates `v`, with the bits at positions `bits` set to 1.
|
||||
runnableExamples:
|
||||
var v = 0b0000_0011'u8
|
||||
v.setBits(3, 5, 7)
|
||||
doAssert v == 0b1010_1011'u8
|
||||
|
||||
bits.expectKind(nnkBracket)
|
||||
result = newStmtList()
|
||||
for bit in bits:
|
||||
result.add newCall("setBit", v, bit)
|
||||
bits.expectKind(nnkBracket)
|
||||
result = newStmtList()
|
||||
for bit in bits:
|
||||
result.add newCall("setBit", v, bit)
|
||||
|
||||
macro clearBits*(v: typed; bits: varargs[typed]): untyped =
|
||||
## Mutates `v`, with the bits at positions `bits` set to 0.
|
||||
runnableExamples:
|
||||
var v = 0b1111_1111'u8
|
||||
v.clearBits(1, 3, 5, 7)
|
||||
doAssert v == 0b0101_0101'u8
|
||||
macro clearBits*(v: typed; bits: varargs[typed]): untyped =
|
||||
## Mutates `v`, with the bits at positions `bits` set to 0.
|
||||
runnableExamples:
|
||||
var v = 0b1111_1111'u8
|
||||
v.clearBits(1, 3, 5, 7)
|
||||
doAssert v == 0b0101_0101'u8
|
||||
|
||||
bits.expectKind(nnkBracket)
|
||||
result = newStmtList()
|
||||
for bit in bits:
|
||||
result.add newCall("clearBit", v, bit)
|
||||
bits.expectKind(nnkBracket)
|
||||
result = newStmtList()
|
||||
for bit in bits:
|
||||
result.add newCall("clearBit", v, bit)
|
||||
|
||||
macro flipBits*(v: typed; bits: varargs[typed]): untyped =
|
||||
## Mutates `v`, with the bits at positions `bits` set to 0.
|
||||
runnableExamples:
|
||||
var v = 0b0000_1111'u8
|
||||
v.flipBits(1, 3, 5, 7)
|
||||
doAssert v == 0b1010_0101'u8
|
||||
macro flipBits*(v: typed; bits: varargs[typed]): untyped =
|
||||
## Mutates `v`, with the bits at positions `bits` set to 0.
|
||||
runnableExamples:
|
||||
var v = 0b0000_1111'u8
|
||||
v.flipBits(1, 3, 5, 7)
|
||||
doAssert v == 0b1010_0101'u8
|
||||
|
||||
bits.expectKind(nnkBracket)
|
||||
result = newStmtList()
|
||||
for bit in bits:
|
||||
result.add newCall("flipBit", v, bit)
|
||||
bits.expectKind(nnkBracket)
|
||||
result = newStmtList()
|
||||
for bit in bits:
|
||||
result.add newCall("flipBit", v, bit)
|
||||
|
||||
|
||||
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.
|
||||
runnableExamples:
|
||||
let v = 0b0000_1111'u8
|
||||
doAssert v.testBit(0)
|
||||
doAssert not v.testBit(7)
|
||||
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.
|
||||
runnableExamples:
|
||||
let v = 0b0000_1111'u8
|
||||
doAssert v.testBit(0)
|
||||
doAssert not v.testBit(7)
|
||||
|
||||
let mask = 1.T shl bit
|
||||
return (v and mask) == mask
|
||||
let mask = 1.T shl bit
|
||||
return (v and mask) == mask
|
||||
|
||||
# #### Pure Nim version ####
|
||||
|
||||
|
||||
@@ -13,11 +13,6 @@
|
||||
const
|
||||
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
|
||||
# two procs retain clarity of that encoding without the space cost of an enum.
|
||||
proc isEmpty(hcode: Hash): bool {.inline.} =
|
||||
|
||||
@@ -60,9 +60,6 @@ runnableExamples:
|
||||
|
||||
import std/private/since
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: dirty.}
|
||||
|
||||
when not defined(nimHasCursor):
|
||||
{.pragma: cursor.}
|
||||
|
||||
|
||||
@@ -84,10 +84,6 @@ import std/private/since
|
||||
|
||||
import macros
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: dirty.}
|
||||
|
||||
|
||||
macro evalOnceAs(expAlias, exp: untyped,
|
||||
letAssigneable: static[bool]): untyped =
|
||||
## 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))
|
||||
assert strings == @["4", "8", "12", "16"]
|
||||
|
||||
when defined(nimHasTypeof):
|
||||
type OutType = typeof((
|
||||
block:
|
||||
var it{.inject.}: typeof(items(s), typeOfIter);
|
||||
op), typeOfProc)
|
||||
else:
|
||||
type OutType = typeof((
|
||||
block:
|
||||
var it{.inject.}: typeof(items(s));
|
||||
op))
|
||||
type OutType = typeof((
|
||||
block:
|
||||
var it{.inject.}: typeof(items(s), typeOfIter);
|
||||
op), typeOfProc)
|
||||
when OutType is not (proc):
|
||||
# Here, we avoid to create closures in loops.
|
||||
# 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:
|
||||
# [1, 2].mapIt((x: int) => it + x)
|
||||
# In this case, `mapIt` is just syntax sugar for `map`.
|
||||
|
||||
when defined(nimHasTypeof):
|
||||
type InType = typeof(items(s), typeOfIter)
|
||||
else:
|
||||
type InType = typeof(items(s))
|
||||
type InType = typeof(items(s), typeOfIter)
|
||||
# Use a help proc `f` to create closures for each element in `s`
|
||||
let f = proc (x: InType): OutType =
|
||||
let it {.inject.} = x
|
||||
|
||||
@@ -51,9 +51,6 @@ import
|
||||
hashes, math
|
||||
|
||||
{.pragma: myShallow.}
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: dirty.}
|
||||
|
||||
# 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
|
||||
# codes should never be needed, and this can pack more entries per cache-line.
|
||||
|
||||
@@ -74,7 +74,7 @@ elif defined(posix):
|
||||
else:
|
||||
{.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".}
|
||||
else:
|
||||
{.pragma: noWeirdTarget.}
|
||||
@@ -2262,10 +2262,7 @@ iterator walkDir*(dir: string; relative = false, checkDir = false):
|
||||
while true:
|
||||
var x = readdir(d)
|
||||
if x == nil: break
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
var y = $cstring(addr x.d_name)
|
||||
else:
|
||||
var y = $x.d_name.cstring
|
||||
var y = $cstring(addr x.d_name)
|
||||
if y != "." and y != "..":
|
||||
var s: Stat
|
||||
let path = dir / y
|
||||
|
||||
@@ -1158,9 +1158,6 @@ proc findAll*(s: string, pattern: Peg, start = 0): seq[string] {.
|
||||
result = @[]
|
||||
for it in findAll(s, pattern, start): result.add it
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: inject.}
|
||||
|
||||
template `=~`*(s: string, pattern: Peg): bool =
|
||||
## This calls ``match`` with an implicit declared ``matches`` array that
|
||||
## can be used in the scope of the ``=~`` call:
|
||||
|
||||
@@ -75,9 +75,8 @@ from math import pow, floor, log10
|
||||
from algorithm import reverse
|
||||
import std/enumutils
|
||||
|
||||
when defined(nimVmExportFixed):
|
||||
from unicode import toLower, toUpper
|
||||
export toLower, toUpper
|
||||
from unicode import toLower, toUpper
|
||||
export toLower, toUpper
|
||||
|
||||
include "system/inclrtl"
|
||||
import std/private/since
|
||||
@@ -2341,17 +2340,11 @@ func formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault,
|
||||
frmtstr[3] = '*'
|
||||
frmtstr[4] = floatFormatToChar[format]
|
||||
frmtstr[5] = '\0'
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
L = c_sprintf(addr buf, addr frmtstr, precision, f)
|
||||
else:
|
||||
L = c_sprintf(buf, frmtstr, precision, f)
|
||||
L = c_sprintf(addr buf, addr frmtstr, precision, f)
|
||||
else:
|
||||
frmtstr[1] = floatFormatToChar[format]
|
||||
frmtstr[2] = '\0'
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
L = c_sprintf(addr buf, addr frmtstr, f)
|
||||
else:
|
||||
L = c_sprintf(buf, frmtstr, f)
|
||||
L = c_sprintf(addr buf, addr frmtstr, f)
|
||||
result = newString(L)
|
||||
for i in 0 ..< L:
|
||||
# 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.}
|
||||
Ordinal* = OrdinalImpl | uint | uint64
|
||||
|
||||
when defined(nimHasRunnableExamples):
|
||||
proc runnableExamples*(rdoccmd = "", body: untyped) {.magic: "RunnableExamples".}
|
||||
## A section you should use to mark `runnable example`:idx: code with.
|
||||
##
|
||||
## - In normal debug and release builds code within
|
||||
## a `runnableExamples` section is ignored.
|
||||
## - The documentation generator is aware of these examples and considers them
|
||||
## part of the `##` doc comment. As the last step of documentation
|
||||
## generation each runnableExample is put in its own file `$file_examples$i.nim`,
|
||||
## compiled and tested. The collected examples are
|
||||
## put into their own module to ensure the examples do not refer to
|
||||
## non-exported symbols.
|
||||
##
|
||||
## Usage:
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## proc double*(x: int): int =
|
||||
## ## This proc doubles a number.
|
||||
## runnableExamples:
|
||||
## ## at module scope
|
||||
## assert double(5) == 10
|
||||
## block: ## at block scope
|
||||
## defer: echo "done"
|
||||
## result = 2 * x
|
||||
## runnableExamples "-d:foo -b:cpp":
|
||||
## import std/compilesettings
|
||||
## doAssert querySetting(backend) == "cpp"
|
||||
## runnableExamples "-r:off": ## this one is only compiled
|
||||
## import std/browsers
|
||||
## openDefaultBrowser "https://forum.nim-lang.org/"
|
||||
else:
|
||||
template runnableExamples*(doccmd = "", body: untyped) =
|
||||
discard
|
||||
proc runnableExamples*(rdoccmd = "", body: untyped) {.magic: "RunnableExamples".}
|
||||
## A section you should use to mark `runnable example`:idx: code with.
|
||||
##
|
||||
## - In normal debug and release builds code within
|
||||
## a `runnableExamples` section is ignored.
|
||||
## - The documentation generator is aware of these examples and considers them
|
||||
## part of the `##` doc comment. As the last step of documentation
|
||||
## generation each runnableExample is put in its own file `$file_examples$i.nim`,
|
||||
## compiled and tested. The collected examples are
|
||||
## put into their own module to ensure the examples do not refer to
|
||||
## non-exported symbols.
|
||||
##
|
||||
## Usage:
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## proc double*(x: int): int =
|
||||
## ## This proc doubles a number.
|
||||
## runnableExamples:
|
||||
## ## at module scope
|
||||
## assert double(5) == 10
|
||||
## block: ## at block scope
|
||||
## defer: echo "done"
|
||||
## result = 2 * x
|
||||
## runnableExamples "-d:foo -b:cpp":
|
||||
## import std/compilesettings
|
||||
## doAssert querySetting(backend) == "cpp"
|
||||
## runnableExamples "-r:off": ## this one is only compiled
|
||||
## import std/browsers
|
||||
## openDefaultBrowser "https://forum.nim-lang.org/"
|
||||
|
||||
when defined(nimHasDeclaredMagic):
|
||||
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.
|
||||
discard
|
||||
|
||||
when defined(nimNewTypedesc):
|
||||
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
|
||||
`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`.
|
||||
else:
|
||||
proc `type`*(x: untyped): typedesc {.magic: "TypeOf", noSideEffect, compileTime.} =
|
||||
## Builtin `type` operator for accessing the type of an expression.
|
||||
## Cannot be overloaded.
|
||||
discard
|
||||
`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`.
|
||||
|
||||
when defined(nimHasTypeof):
|
||||
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.
|
||||
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"
|
||||
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.
|
||||
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.
|
||||
|
||||
const ThisIsSystem = true
|
||||
|
||||
@@ -310,14 +299,9 @@ type
|
||||
seq*[T]{.magic: "Seq".} ## Generic type to construct sequences.
|
||||
set*[T]{.magic: "Set".} ## Generic type to construct bit sets.
|
||||
|
||||
when defined(nimUncheckedArrayTyp):
|
||||
type
|
||||
UncheckedArray*[T]{.magic: "UncheckedArray".}
|
||||
## Array with no bounds checking.
|
||||
else:
|
||||
type
|
||||
UncheckedArray*[T]{.unchecked.} = array[0,T]
|
||||
## Array with no bounds checking.
|
||||
type
|
||||
UncheckedArray*[T]{.magic: "UncheckedArray".}
|
||||
## Array with no bounds checking.
|
||||
|
||||
type sink*[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
|
||||
## and strings.
|
||||
|
||||
when defined(nimArrIdx):
|
||||
# :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".}
|
||||
# :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 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 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, magic: "Asgn".} =
|
||||
## Generic `sink`:idx: implementation that can be overridden.
|
||||
shallowCopy(x, y)
|
||||
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, magic: "Asgn".} =
|
||||
## Generic `sink`:idx: implementation that can be overridden.
|
||||
shallowCopy(x, y)
|
||||
|
||||
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]
|
||||
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):
|
||||
{.pragma: hcrInline, inline.}
|
||||
else:
|
||||
@@ -631,23 +608,21 @@ proc sizeof*[T](x: T): int {.magic: "SizeOf", noSideEffect.}
|
||||
## sizeof('A') # => 1
|
||||
## sizeof(2) # => 8
|
||||
|
||||
when defined(nimHasalignOf):
|
||||
proc alignof*[T](x: T): int {.magic: "AlignOf", noSideEffect.}
|
||||
proc alignof*(x: typedesc): int {.magic: "AlignOf", noSideEffect.}
|
||||
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.}
|
||||
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](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)
|
||||
template offsetOf*[T](value: T; member: untyped): int =
|
||||
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.}
|
||||
@@ -969,52 +944,42 @@ proc cmp*(x, y: string): int {.noSideEffect.}
|
||||
## **Note**: The precise result values depend on the used C runtime library and
|
||||
## can differ between operating systems!
|
||||
|
||||
when defined(nimHasDefault):
|
||||
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]`.
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## let
|
||||
## a = [1, 3, 5]
|
||||
## b = "foo"
|
||||
##
|
||||
## echo @a # => @[1, 3, 5]
|
||||
## echo @b # => @['f', 'o', 'o']
|
||||
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]`.
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## let
|
||||
## a = [1, 3, 5]
|
||||
## b = "foo"
|
||||
##
|
||||
## echo @a # => @[1, 3, 5]
|
||||
## echo @b # => @['f', 'o', 'o']
|
||||
|
||||
proc default*(T: typedesc): 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 default*(T: typedesc): 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))
|
||||
|
||||
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 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.}
|
||||
@@ -2065,34 +2030,28 @@ elif hasAlloc:
|
||||
inc(i)
|
||||
{.pop.}
|
||||
|
||||
when defined(nimvarargstyped):
|
||||
proc echo*(x: varargs[typed, `$`]) {.magic: "Echo", tags: [WriteIOEffect],
|
||||
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 echo*(x: varargs[typed, `$`]) {.magic: "Echo", tags: [WriteIOEffect],
|
||||
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>`_.
|
||||
else:
|
||||
proc echo*(x: varargs[untyped, `$`]) {.magic: "Echo", tags: [WriteIOEffect],
|
||||
benign, sideEffect.}
|
||||
proc debugEcho*(x: varargs[untyped, `$`]) {.magic: "Echo", noSideEffect,
|
||||
tags: [], raises: [].}
|
||||
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>`_.
|
||||
|
||||
template newException*(exceptn: typedesc, message: string;
|
||||
parentException: ref Exception = nil): untyped =
|
||||
@@ -2796,9 +2755,6 @@ when compileOption("rangechecks"):
|
||||
else:
|
||||
template rangeCheck*(cond) = discard
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: inject.}
|
||||
|
||||
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`.
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
# All symbols are prefixed with 'c_' to avoid ambiguities
|
||||
|
||||
{.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 {.
|
||||
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: int64): int64 {.magic: "ModI", noSideEffect.}
|
||||
|
||||
when defined(nimOldShiftRight) or not defined(nimAshr):
|
||||
when defined(nimOldShiftRight):
|
||||
const shrDepMessage = "`shr` will become sign preserving."
|
||||
proc `shr`*(x: int, y: SomeInteger): int {.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: int64, y: SomeInteger): int64 {.magic: "ShlI", noSideEffect.}
|
||||
|
||||
when defined(nimAshr):
|
||||
proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} =
|
||||
## Shifts right by pushing copies of the leftmost bit in from the left,
|
||||
## and let the rightmost bits fall off.
|
||||
##
|
||||
## Note that `ashr` is not an operator so use the normal function
|
||||
## call syntax for it.
|
||||
##
|
||||
## See also:
|
||||
## * `shr func<#shr,int,SomeInteger>`_
|
||||
runnableExamples:
|
||||
assert ashr(0b0001_0000'i8, 2) == 0b0000_0100'i8
|
||||
assert ashr(0b1000_0000'i8, 8) == 0b1111_1111'i8
|
||||
assert ashr(0b1000_0000'i8, 1) == 0b1100_0000'i8
|
||||
proc ashr*(x: int8, y: SomeInteger): int8 {.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: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.}
|
||||
else:
|
||||
# used for bootstrapping the compiler
|
||||
proc ashr*[T](x: T, y: SomeInteger): T = discard
|
||||
proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} =
|
||||
## Shifts right by pushing copies of the leftmost bit in from the left,
|
||||
## and let the rightmost bits fall off.
|
||||
##
|
||||
## Note that `ashr` is not an operator so use the normal function
|
||||
## call syntax for it.
|
||||
##
|
||||
## See also:
|
||||
## * `shr func<#shr,int,SomeInteger>`_
|
||||
runnableExamples:
|
||||
assert ashr(0b0001_0000'i8, 2) == 0b0000_0100'i8
|
||||
assert ashr(0b1000_0000'i8, 8) == 0b1111_1111'i8
|
||||
assert ashr(0b1000_0000'i8, 1) == 0b1100_0000'i8
|
||||
proc ashr*(x: int8, y: SomeInteger): int8 {.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: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.}
|
||||
|
||||
proc `and`*(x, y: int): int {.magic: "BitandI", noSideEffect.} =
|
||||
## 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
|
||||
## the element type `T`.
|
||||
when nimvm:
|
||||
when not defined(nimNoNil):
|
||||
if x.isNil and y.isNil:
|
||||
return true
|
||||
else:
|
||||
if x.len == 0 and y.len == 0:
|
||||
return true
|
||||
if x.len == 0 and y.len == 0:
|
||||
return true
|
||||
else:
|
||||
when not defined(js):
|
||||
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`"""
|
||||
if sameObject: return true
|
||||
|
||||
when not defined(nimNoNil):
|
||||
if x.isNil or y.isNil:
|
||||
return false
|
||||
|
||||
if x.len != y.len:
|
||||
return false
|
||||
|
||||
|
||||
@@ -161,10 +161,7 @@ elif defined(windows) or defined(dos):
|
||||
dec(m)
|
||||
k = k div 10
|
||||
if k == 0: break
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
result = getProcAddress(cast[THINSTANCE](lib), addr decorated)
|
||||
else:
|
||||
result = getProcAddress(cast[THINSTANCE](lib), decorated)
|
||||
result = getProcAddress(cast[THINSTANCE](lib), addr decorated)
|
||||
if result != nil: return
|
||||
procAddrError(name)
|
||||
|
||||
|
||||
@@ -393,15 +393,10 @@ proc reportUnhandledErrorAux(e: ref Exception) {.nodestroy.} =
|
||||
add(buf, " [")
|
||||
xadd(buf, e.name, e.name.len)
|
||||
add(buf, "]\n")
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
template tbuf(): untyped = addr buf
|
||||
else:
|
||||
template tbuf(): untyped = buf
|
||||
|
||||
if onUnhandledException != nil:
|
||||
onUnhandledException($tbuf())
|
||||
onUnhandledException($buf.addr)
|
||||
else:
|
||||
showErrorMessage(tbuf(), L)
|
||||
showErrorMessage(buf.addr, L)
|
||||
|
||||
proc reportUnhandledError(e: ref Exception) {.nodestroy.} =
|
||||
if unhandledExceptionHook != nil:
|
||||
|
||||
@@ -44,10 +44,7 @@ else:
|
||||
{.pragma: inl, inline.}
|
||||
{.pragma: compilerRtl, compilerproc.}
|
||||
|
||||
when defined(nimlocks):
|
||||
{.pragma: benign, gcsafe, locks: 0.}
|
||||
else:
|
||||
{.pragma: benign, gcsafe.}
|
||||
{.pragma: benign, gcsafe, locks: 0.}
|
||||
|
||||
when defined(nimHasSinkInference):
|
||||
{.push sinkInference: on.}
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
const useLibC = not defined(nimNoLibc)
|
||||
|
||||
when not defined(nimHasHotCodeReloading):
|
||||
{.pragma: nonReloadable.}
|
||||
|
||||
when useLibC:
|
||||
import ansi_c
|
||||
|
||||
|
||||
@@ -16,14 +16,9 @@ proc reprInt(x: int64): string {.compilerproc.} = return $x
|
||||
proc reprFloat(x: float): string {.compilerproc.} = return $x
|
||||
|
||||
proc reprPointer(x: pointer): string {.compilerproc.} =
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
result = newString(60)
|
||||
let n = c_sprintf(addr result[0], "%p", x)
|
||||
setLen(result, n)
|
||||
else:
|
||||
var buf: array[0..59, char]
|
||||
discard c_sprintf(buf, "%p", x)
|
||||
return $buf
|
||||
result = newString(60)
|
||||
let n = c_sprintf(addr result[0], "%p", x)
|
||||
setLen(result, n)
|
||||
|
||||
proc reprStrAux(result: var string, s: cstring; len: int) =
|
||||
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
|
||||
absExponent = absExponent div 10
|
||||
t[ti-3] = ('0'.ord + absExponent mod 10).char
|
||||
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
number = c_strtod(addr t, nil)
|
||||
else:
|
||||
number = c_strtod(t, nil)
|
||||
number = c_strtod(addr t, nil)
|
||||
|
||||
when defined(nimHasInvariant):
|
||||
{.pop.} # staticBoundChecks
|
||||
|
||||
@@ -209,9 +209,6 @@ proc extractSpec(filename: string; spec: var TSpec): string =
|
||||
#echo "warning: file does not contain spec: " & filename
|
||||
result = ""
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: inject.}
|
||||
|
||||
proc parseTargets*(value: string): set[TTarget] =
|
||||
for v in value.normalize.splitWhitespace:
|
||||
case v
|
||||
|
||||
@@ -2,8 +2,7 @@ discard """
|
||||
joinable: false
|
||||
"""
|
||||
|
||||
when not defined(nimNewRuntime):
|
||||
{.error: "This bug could only be reproduced with --newruntime".}
|
||||
# This bug could only be reproduced with --newruntime
|
||||
|
||||
type
|
||||
Obj = object
|
||||
|
||||
Reference in New Issue
Block a user