mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-01 21:19:03 +00:00
Merge branch 'devel' into pr_guten
This commit is contained in:
@@ -23,6 +23,8 @@ errors.
|
||||
|
||||
- With `-d:nimPreviewCStringComparisons`, comparsions (`<`, `>`, `<=`, `>=`) between cstrings switch from reference semantics to value semantics like `==` and `!=`.
|
||||
|
||||
- `std/parsesql` has been moved to a nimble package, use `nimble` or `atlas` to install it.
|
||||
|
||||
## Standard library additions and changes
|
||||
|
||||
[//]: # "Additions:"
|
||||
|
||||
@@ -819,6 +819,7 @@ type
|
||||
# nodes are compared by structure!
|
||||
counter*: int
|
||||
data*: TNodePairSeq
|
||||
ignoreTypes*: bool
|
||||
|
||||
TObjectSeq* = seq[RootRef]
|
||||
TObjectSet* = object
|
||||
@@ -1641,8 +1642,8 @@ proc initObjectSet*(): TObjectSet =
|
||||
result = TObjectSet(counter: 0)
|
||||
newSeq(result.data, StartSize)
|
||||
|
||||
proc initNodeTable*(): TNodeTable =
|
||||
result = TNodeTable(counter: 0)
|
||||
proc initNodeTable*(ignoreTypes=false): TNodeTable =
|
||||
result = TNodeTable(counter: 0, ignoreTypes: ignoreTypes)
|
||||
newSeq(result.data, StartSize)
|
||||
|
||||
proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType =
|
||||
|
||||
@@ -981,7 +981,11 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) =
|
||||
var a: TLoc = initLocExpr(p, e[0])
|
||||
if e[0].kind in {nkHiddenStdConv, nkHiddenSubConv, nkConv} and not ignoreConv(e[0]):
|
||||
# addr (conv x) introduces a temp because `conv x` is not a rvalue
|
||||
putIntoDest(p, d, e, addrLoc(p.config, expressionsNeedsTmp(p, a)), a.storage)
|
||||
# transform addr ( conv ( x ) ) -> conv ( addr ( x ) )
|
||||
var exprLoc: TLoc = initLocExpr(p, e[0][1])
|
||||
var tmp = getTemp(p, e.typ, needsInit=false)
|
||||
putIntoDest(p, tmp, e, cCast(getTypeDesc(p.module, e.typ), addrLoc(p.config, exprLoc)))
|
||||
putIntoDest(p, d, e, rdLoc(tmp))
|
||||
else:
|
||||
putIntoDest(p, d, e, addrLoc(p.config, a), a.storage)
|
||||
|
||||
|
||||
@@ -379,7 +379,9 @@ proc useVar(a: PEffects, n: PNode) =
|
||||
# If the variable is explicitly marked as .noinit. do not emit any error
|
||||
a.init.add s.id
|
||||
elif s.id notin a.init:
|
||||
if s.typ.requiresInit:
|
||||
if s.kind == skResult and tfRequiresInit in s.typ.flags:
|
||||
localError(a.config, n.info, "'result' requires explicit initialization")
|
||||
elif s.typ.requiresInit:
|
||||
message(a.config, n.info, warnProveInit, s.name.s)
|
||||
elif a.leftPartOfAsgn <= 0:
|
||||
if strictDefs in a.c.features:
|
||||
|
||||
@@ -725,7 +725,7 @@ template isLocalSym(sym: PSym): bool =
|
||||
sym.typ.kind == tyTypeDesc or
|
||||
sfCompileTime in sym.flags) or
|
||||
sym.kind in {skProc, skFunc, skIterator} and
|
||||
sfGlobal notin sym.flags
|
||||
sfGlobal notin sym.flags and sym.typ.callConv == ccClosure
|
||||
|
||||
proc usesLocalVar(n: PNode): bool =
|
||||
case n.kind
|
||||
|
||||
@@ -1147,7 +1147,9 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
|
||||
let t = newTypeS(tySink, c, result)
|
||||
result = t
|
||||
else: discard
|
||||
if result.kind == tyRef and c.config.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
|
||||
if result.kind == tyRef and
|
||||
c.config.selectedGC in {gcArc, gcOrc, gcAtomicArc} and
|
||||
tfTriggersCompileTime notin result.flags:
|
||||
result.flags.incl tfHasAsgn
|
||||
|
||||
proc findEnforcedStaticType(t: PType): PType =
|
||||
|
||||
@@ -259,7 +259,8 @@ proc transformBlock(c: PTransf, n: PNode): PNode =
|
||||
var labl: PSym
|
||||
if c.inlining > 0:
|
||||
labl = newLabel(c, n[0])
|
||||
c.transCon.mapping[n[0].sym.itemId] = newSymNode(labl)
|
||||
if n[0].kind != nkEmpty:
|
||||
c.transCon.mapping[n[0].sym.itemId] = newSymNode(labl)
|
||||
else:
|
||||
labl =
|
||||
if n[0].kind != nkEmpty:
|
||||
@@ -827,12 +828,20 @@ proc transformFor(c: PTransf, n: PNode): PNode =
|
||||
t = formal.ast.typ # better use the type that actually has a destructor.
|
||||
elif t.destructor == nil and arg.typ.destructor != nil:
|
||||
t = arg.typ
|
||||
# generate a temporary and produce an assignment statement:
|
||||
var temp = newTemp(c, t, formal.info)
|
||||
#incl(temp.sym.flags, sfCursor)
|
||||
addVar(v, temp)
|
||||
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg, true))
|
||||
newC.mapping[formal.itemId] = temp
|
||||
|
||||
if arg.kind in {nkDerefExpr, nkHiddenDeref}:
|
||||
# optimizes for `[]` # bug #24093
|
||||
var temp = newTemp(c, arg[0].typ, formal.info)
|
||||
addVar(v, temp)
|
||||
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg[0], true))
|
||||
newC.mapping[formal.itemId] = newDeref(temp)
|
||||
else:
|
||||
# generate a temporary and produce an assignment statement:
|
||||
var temp = newTemp(c, t, formal.info)
|
||||
#incl(temp.sym.flags, sfCursor)
|
||||
addVar(v, temp)
|
||||
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg, true))
|
||||
newC.mapping[formal.itemId] = temp
|
||||
of paVarAsgn:
|
||||
assert(skipTypes(formal.typ, abstractInst).kind in {tyVar, tyLent})
|
||||
newC.mapping[formal.itemId] = arg
|
||||
|
||||
@@ -42,32 +42,37 @@ proc hashTree*(n: PNode): Hash =
|
||||
#echo "hashTree ", result
|
||||
#echo n
|
||||
|
||||
proc treesEquivalent(a, b: PNode): bool =
|
||||
proc treesEquivalent(a, b: PNode; ignoreTypes: bool): bool =
|
||||
if a == b:
|
||||
result = true
|
||||
elif (a != nil) and (b != nil) and (a.kind == b.kind):
|
||||
case a.kind
|
||||
of nkEmpty, nkNilLit, nkType: result = true
|
||||
of nkEmpty: result = true
|
||||
of nkSym: result = a.sym.id == b.sym.id
|
||||
of nkIdent: result = a.ident.id == b.ident.id
|
||||
of nkCharLit..nkUInt64Lit: result = a.intVal == b.intVal
|
||||
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
|
||||
of nkFloatLit..nkFloat64Lit:
|
||||
result = cast[uint64](a.floatVal) == cast[uint64](b.floatVal)
|
||||
#result = a.floatVal == b.floatVal
|
||||
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
||||
of nkType, nkNilLit:
|
||||
result = a.typ == b.typ
|
||||
else:
|
||||
if a.len == b.len:
|
||||
for i in 0..<a.len:
|
||||
if not treesEquivalent(a[i], b[i]): return
|
||||
if not treesEquivalent(a[i], b[i], ignoreTypes): return
|
||||
result = true
|
||||
else:
|
||||
result = false
|
||||
if result: result = sameTypeOrNil(a.typ, b.typ)
|
||||
if result and not ignoreTypes:
|
||||
result = sameTypeOrNil(a.typ, b.typ)
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc nodeTableRawGet(t: TNodeTable, k: Hash, key: PNode): int =
|
||||
var h: Hash = k and high(t.data)
|
||||
while t.data[h].key != nil:
|
||||
if (t.data[h].h == k) and treesEquivalent(t.data[h].key, key):
|
||||
if (t.data[h].h == k) and treesEquivalent(t.data[h].key, key, t.ignoreTypes):
|
||||
return h
|
||||
h = nextTry(h, high(t.data))
|
||||
result = -1
|
||||
|
||||
@@ -249,6 +249,7 @@ type
|
||||
# to not slow down interpretation
|
||||
globals*: PNode #
|
||||
constants*: PNode # constant data
|
||||
contstantTab*: TNodeTable
|
||||
types*: seq[PType] # some instructions reference types (e.g. 'except')
|
||||
currentExceptionA*, currentExceptionB*: PNode
|
||||
exceptionInstr*: int # index of instruction that raised the exception
|
||||
@@ -298,7 +299,8 @@ proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph; idgen: IdGenerator
|
||||
prc: PProc(blocks: @[]), module: module, loopIterations: g.config.maxLoopIterationsVM,
|
||||
callDepth: g.config.maxCallDepthVM,
|
||||
comesFromHeuristic: unknownLineInfo, callbacks: @[], callbackIndex: initTable[string, int](), errorFlag: "",
|
||||
cache: cache, config: g.config, graph: g, idgen: idgen)
|
||||
cache: cache, config: g.config, graph: g, idgen: idgen,
|
||||
contstantTab: initNodeTable(true))
|
||||
|
||||
proc refresh*(c: PCtx, module: PSym; idgen: IdGenerator) =
|
||||
c.module = module
|
||||
|
||||
@@ -33,7 +33,8 @@ when defined(nimPreviewSlimSystem):
|
||||
|
||||
import
|
||||
ast, types, msgs, renderer, vmdef, trees,
|
||||
magicsys, options, lowerings, lineinfos, transf, astmsgs
|
||||
magicsys, options, lowerings, lineinfos, transf, astmsgs,
|
||||
treetab
|
||||
|
||||
from modulegraphs import getBody
|
||||
|
||||
@@ -478,10 +479,16 @@ proc sameConstant*(a, b: PNode): bool =
|
||||
result = true
|
||||
|
||||
proc genLiteral(c: PCtx; n: PNode): int =
|
||||
# types do not matter here:
|
||||
for i in 0..<c.constants.len:
|
||||
if sameConstant(c.constants[i], n): return i
|
||||
result = rawGenLiteral(c, n)
|
||||
result = nodeTableTestOrSet(c.contstantTab, n, c.constants.len)
|
||||
if result == c.constants.len:
|
||||
let lit = rawGenLiteral(c, n)
|
||||
assert lit == result
|
||||
|
||||
when false:
|
||||
# types do not matter here:
|
||||
for i in 0..<c.constants.len:
|
||||
if sameConstant(c.constants[i], n): return i
|
||||
result = rawGenLiteral(c, n)
|
||||
|
||||
proc unused(c: PCtx; n: PNode; x: TDest) {.inline.} =
|
||||
if x >= 0:
|
||||
@@ -1182,8 +1189,10 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}, m: TMag
|
||||
of mEqF64: genBinaryABC(c, n, dest, opcEqFloat)
|
||||
of mLeF64: genBinaryABC(c, n, dest, opcLeFloat)
|
||||
of mLtF64: genBinaryABC(c, n, dest, opcLtFloat)
|
||||
of mLePtr, mLeU: genBinaryABC(c, n, dest, opcLeu)
|
||||
of mLtPtr, mLtU: genBinaryABC(c, n, dest, opcLtu)
|
||||
of mLeU: genBinaryABC(c, n, dest, opcLeu)
|
||||
of mLtU: genBinaryABC(c, n, dest, opcLtu)
|
||||
of mLePtr, mLtPtr:
|
||||
globalError(c.config, n.info, "pointer comparisons are not available at compile-time")
|
||||
of mEqProc, mEqRef:
|
||||
genBinaryABC(c, n, dest, opcEqRef)
|
||||
of mXor: genBinaryABC(c, n, dest, opcXor)
|
||||
@@ -1547,8 +1556,7 @@ template cannotEval(c: PCtx; n: PNode) =
|
||||
if c.config.cmd == cmdCheck and c.config.m.errorOutputs != {}:
|
||||
# nim check command with no error outputs doesn't need to cascade here,
|
||||
# includes `tryConstExpr` case which should not continue generating code
|
||||
localError(c.config, n.info, "cannot evaluate at compile time: " &
|
||||
n.renderTree)
|
||||
localError(c.config, n.info, "cannot evaluate at compile time: " & n.renderTree)
|
||||
c.cannotEval = true
|
||||
return
|
||||
globalError(c.config, n.info, "cannot evaluate at compile time: " &
|
||||
@@ -1886,7 +1894,7 @@ proc genCheckedObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||
c.freeTemp(objR)
|
||||
|
||||
proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||
if n[0].typ == nil:
|
||||
if n[0].typ == nil:
|
||||
globalError(c.config, n.info, "cannot access array with nil type")
|
||||
return
|
||||
|
||||
|
||||
@@ -4062,7 +4062,7 @@ notation. (Thus an operator can have more than two parameters):
|
||||
# Multiply and add
|
||||
result = a * b + c
|
||||
|
||||
assert `*+`(3, 4, 6) == `+`(`*`(a, b), c)
|
||||
assert `*+`(3, 4, 6) == `+`(`*`(3, 4), 6)
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -224,6 +224,8 @@ directories (in this order; later files overwrite previous settings):
|
||||
command-line option.
|
||||
|
||||
|
||||
[NimScript files](nims.html) can also be used for configuration.
|
||||
|
||||
Command-line settings have priority over configuration file settings.
|
||||
|
||||
The default build of a project is a `debug build`:idx:. To compile a
|
||||
|
||||
2
koch.nim
2
koch.nim
@@ -13,7 +13,7 @@ const
|
||||
# examples of possible values for repos: Head, ea82b54
|
||||
NimbleStableCommit = "9207e8b2bbdf66b5a4d1020214cff44d2d30df92" # 0.20.1
|
||||
AtlasStableCommit = "26cecf4d0cc038d5422fc1aa737eec9c8803a82b" # 0.9
|
||||
ChecksumsStableCommit = "f8f6bd34bfa3fe12c64b919059ad856a96efcba0" # 2.0.1
|
||||
ChecksumsStableCommit = "0b8e46379c5bc1bf73d8b3011908389c60fb9b98" # 2.0.1
|
||||
SatStableCommit = "faf1617f44d7632ee9601ebc13887644925dcc01"
|
||||
|
||||
NimonyStableCommit = "1dbabac403ae32e185ee4c29f006d04e04b50c6d" # unversioned \
|
||||
|
||||
@@ -428,7 +428,7 @@ proc write*(f: AsyncFile, data: string): Future[void] =
|
||||
dealloc buffer
|
||||
buffer = nil
|
||||
)
|
||||
ol.offset = DWORD(f.offset and 0xffffffff)
|
||||
ol.offset = cast[DWORD](f.offset and 0xffffffff)
|
||||
ol.offsetHigh = DWORD(f.offset shr 32)
|
||||
f.offset.inc(data.len)
|
||||
|
||||
|
||||
@@ -116,6 +116,11 @@ macro evalOnceAs(expAlias, exp: untyped,
|
||||
newProc(name = genSym(nskTemplate, $expAlias), params = [getType(untyped)],
|
||||
body = val, procType = nnkTemplateDef))
|
||||
|
||||
template unCheckedInc(x) =
|
||||
{.push overflowChecks: off.}
|
||||
inc(x)
|
||||
{.pop.}
|
||||
|
||||
func concat*[T](seqs: varargs[seq[T]]): seq[T] =
|
||||
## Takes several sequences' items and returns them inside a new sequence.
|
||||
## All sequences must be of the same type.
|
||||
@@ -139,7 +144,7 @@ func concat*[T](seqs: varargs[seq[T]]): seq[T] =
|
||||
for s in items(seqs):
|
||||
for itm in items(s):
|
||||
result[i] = itm
|
||||
inc(i)
|
||||
unCheckedInc(i)
|
||||
|
||||
func addUnique*[T](s: var seq[T], x: sink T) =
|
||||
## Adds `x` to the container `s` if it is not already present.
|
||||
@@ -170,7 +175,7 @@ func count*[T](s: openArray[T], x: T): int =
|
||||
result = 0
|
||||
for itm in items(s):
|
||||
if itm == x:
|
||||
inc result
|
||||
unCheckedInc result
|
||||
|
||||
func cycle*[T](s: openArray[T], n: Natural): seq[T] =
|
||||
## Returns a new sequence with the items of the container `s` repeated
|
||||
@@ -188,7 +193,7 @@ func cycle*[T](s: openArray[T], n: Natural): seq[T] =
|
||||
for x in 0 ..< n:
|
||||
for e in s:
|
||||
result[o] = e
|
||||
inc o
|
||||
unCheckedInc o
|
||||
|
||||
proc repeat*[T](x: T, n: Natural): seq[T] =
|
||||
## Returns a new sequence with the item `x` repeated `n` times.
|
||||
@@ -321,6 +326,26 @@ func minmax*[T](x: openArray[T], cmp: proc(a, b: T): int): (T, T) {.effectsOf: c
|
||||
elif cmp(result[1], x[i]) < 0: result[1] = x[i]
|
||||
|
||||
|
||||
template findIt*(s, predicate: untyped): int =
|
||||
## Iterates through a container and returns the index of the first item that
|
||||
## fulfills the predicate, or -1
|
||||
##
|
||||
## Unlike the `find`, the predicate needs to be an expression using
|
||||
## the `it` variable for testing, like: `findIt([3, 2, 1], it == 2)`.
|
||||
var
|
||||
res = -1
|
||||
i = 0
|
||||
|
||||
# We must use items here since both `find` and `anyIt` are defined in terms
|
||||
# of `items`
|
||||
# (and not `pairs`)
|
||||
for it {.inject.} in items(s):
|
||||
if predicate:
|
||||
res = i
|
||||
break
|
||||
unCheckedInc(i)
|
||||
res
|
||||
|
||||
template zipImpl(s1, s2, retType: untyped): untyped =
|
||||
proc zip*[S, T](s1: openArray[S], s2: openArray[T]): retType =
|
||||
## Returns a new sequence with a combination of the two input containers.
|
||||
@@ -417,7 +442,7 @@ func distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] =
|
||||
|
||||
if extra == 0 or spread == false:
|
||||
# Use an algorithm which overcounts the stride and minimizes reading limits.
|
||||
if extra > 0: inc(stride)
|
||||
if extra > 0: unCheckedInc(stride)
|
||||
for i in 0 ..< num:
|
||||
result[i] = newSeq[T]()
|
||||
for g in first ..< min(s.len, first + stride):
|
||||
@@ -429,7 +454,7 @@ func distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] =
|
||||
last = first + stride
|
||||
if extra > 0:
|
||||
extra -= 1
|
||||
inc(last)
|
||||
unCheckedInc(last)
|
||||
result[i] = newSeq[T]()
|
||||
for g in first ..< last:
|
||||
result[i].add(s[g])
|
||||
@@ -586,7 +611,7 @@ proc keepIf*[T](s: var seq[T], pred: proc(x: T): bool {.closure.})
|
||||
s[pos] = move(s[i])
|
||||
else:
|
||||
shallowCopy(s[pos], s[i])
|
||||
inc(pos)
|
||||
unCheckedInc(pos)
|
||||
setLen(s, pos)
|
||||
|
||||
func delete*[T](s: var seq[T]; slice: Slice[int]) =
|
||||
@@ -617,8 +642,8 @@ func delete*[T](s: var seq[T]; slice: Slice[int]) =
|
||||
s[i] = move(s[j])
|
||||
else:
|
||||
s[i].shallowCopy(s[j])
|
||||
inc(i)
|
||||
inc(j)
|
||||
unCheckedInc(i)
|
||||
unCheckedInc(j)
|
||||
setLen(s, newLen)
|
||||
when nimvm: defaultImpl()
|
||||
else:
|
||||
@@ -649,8 +674,8 @@ func delete*[T](s: var seq[T]; first, last: Natural) {.deprecated: "use `delete(
|
||||
s[i] = move(s[j])
|
||||
else:
|
||||
s[i].shallowCopy(s[j])
|
||||
inc(i)
|
||||
inc(j)
|
||||
unCheckedInc(i)
|
||||
unCheckedInc(j)
|
||||
setLen(s, newLen)
|
||||
|
||||
func insert*[T](dest: var seq[T], src: openArray[T], pos = 0) =
|
||||
@@ -681,10 +706,10 @@ func insert*[T](dest: var seq[T], src: openArray[T], pos = 0) =
|
||||
dec(i)
|
||||
dec(j)
|
||||
# Insert items from `dest` into `dest` at `pos`
|
||||
inc(j)
|
||||
unCheckedInc(j)
|
||||
for item in src:
|
||||
dest[j] = item
|
||||
inc(j)
|
||||
unCheckedInc(j)
|
||||
|
||||
|
||||
template filterIt*(s, pred: untyped): untyped =
|
||||
@@ -715,7 +740,7 @@ template filterIt*(s, pred: untyped): untyped =
|
||||
var result = newSeq[typeof(s[0])]()
|
||||
for it {.inject.} in items(s):
|
||||
if pred: result.add(it)
|
||||
result
|
||||
move result
|
||||
|
||||
template keepItIf*(varSeq: seq, pred: untyped) =
|
||||
## Keeps the items in the passed sequence (must be declared as a `var`)
|
||||
@@ -743,7 +768,7 @@ template keepItIf*(varSeq: seq, pred: untyped) =
|
||||
varSeq[pos] = move(varSeq[i])
|
||||
else:
|
||||
shallowCopy(varSeq[pos], varSeq[i])
|
||||
inc(pos)
|
||||
unCheckedInc(pos)
|
||||
setLen(varSeq, pos)
|
||||
|
||||
since (1, 1):
|
||||
@@ -842,12 +867,7 @@ template anyIt*(s, pred: untyped): bool =
|
||||
assert numbers.anyIt(it > 8) == true
|
||||
assert numbers.anyIt(it > 9) == false
|
||||
|
||||
var result = false
|
||||
for it {.inject.} in items(s):
|
||||
if pred:
|
||||
result = true
|
||||
break
|
||||
result
|
||||
findIt(s, pred) != -1
|
||||
|
||||
template toSeq1(s: not iterator): untyped =
|
||||
# overload for typed but not iterator
|
||||
@@ -875,7 +895,7 @@ template toSeq2(iter: iterator): untyped =
|
||||
var result = newSeq[typeof(iter2)](iter2.len)
|
||||
for x in iter2:
|
||||
result[i] = x
|
||||
inc i
|
||||
unCheckedInc i
|
||||
result
|
||||
else:
|
||||
type OutType = typeof(iter2())
|
||||
@@ -920,7 +940,7 @@ template toSeq*(iter: untyped): untyped =
|
||||
var i = 0
|
||||
for x in iter2:
|
||||
result[i] = x
|
||||
inc i
|
||||
unCheckedInc i
|
||||
result
|
||||
else:
|
||||
var result: seq[typeof(iter)] = @[]
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
##
|
||||
## Unstable API.
|
||||
|
||||
{.deprecated: "use `nimble install parsesql` and import `pkg/parsesql` instead".}
|
||||
|
||||
import std/[strutils, lexbase]
|
||||
import std/private/decode_helpers
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ import std/parseutils
|
||||
from std/math import pow, floor, log10
|
||||
from std/algorithm import fill, reverse
|
||||
import std/enumutils
|
||||
from std/bitops import fastLog2
|
||||
|
||||
from std/unicode import toLower, toUpper
|
||||
export toLower, toUpper
|
||||
@@ -2639,37 +2640,35 @@ func formatSize*(bytes: int64,
|
||||
## * `strformat module<strformat.html>`_ for string interpolation and formatting
|
||||
runnableExamples:
|
||||
doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB"
|
||||
doAssert formatSize((2.234*1024*1024).int) == "2.234MiB"
|
||||
doAssert formatSize((2.234*1024*1024).int) == "2.233MiB"
|
||||
doAssert formatSize(4096, includeSpace = true) == "4 KiB"
|
||||
doAssert formatSize(4096, prefix = bpColloquial, includeSpace = true) == "4 kB"
|
||||
doAssert formatSize(4096) == "4KiB"
|
||||
doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,13MB"
|
||||
doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,129MB"
|
||||
|
||||
const iecPrefixes = ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"]
|
||||
const collPrefixes = ["", "k", "M", "G", "T", "P", "E", "Z", "Y"]
|
||||
var
|
||||
xb: int64 = bytes
|
||||
fbytes: float
|
||||
lastXb: int64 = bytes
|
||||
matchedIndex = 0
|
||||
prefixes: array[9, string]
|
||||
# It doesn't needs Zi and larger units until we use int72 or larger ints.
|
||||
const iecPrefixes = ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei"]
|
||||
const collPrefixes = ["", "k", "M", "G", "T", "P", "E"]
|
||||
|
||||
let lg2 = if bytes == 0:
|
||||
0
|
||||
else:
|
||||
when hasWorkingInt64:
|
||||
fastLog2(bytes)
|
||||
else:
|
||||
fastLog2(int32 bytes)
|
||||
let matchedIndex = lg2 div 10
|
||||
# Lower bits that are smaller than 0.001 when `bytes` is converted to a real number and added prefix, are discard.
|
||||
# Then it is converted to float with round down.
|
||||
let discardBits = (lg2 div 10 - 1) * 10
|
||||
|
||||
var prefixes: array[7, string]
|
||||
if prefix == bpColloquial:
|
||||
prefixes = collPrefixes
|
||||
else:
|
||||
prefixes = iecPrefixes
|
||||
|
||||
# Iterate through prefixes seeing if value will be greater than
|
||||
# 0 in each case
|
||||
for index in 1..<prefixes.len:
|
||||
lastXb = xb
|
||||
xb = bytes div (1'i64 shl (index*10))
|
||||
matchedIndex = index
|
||||
if xb == 0:
|
||||
xb = lastXb
|
||||
matchedIndex = index - 1
|
||||
break
|
||||
# xb has the integer number for the latest value; index should be correct
|
||||
fbytes = bytes.float / (1'i64 shl (matchedIndex*10)).float
|
||||
let fbytes = if lg2 < 10: bytes.float elif lg2 < 20: bytes.float / 1024.0 else: (bytes shr discardBits).float / 1024.0
|
||||
result = formatFloat(fbytes, format = ffDecimal, precision = 3,
|
||||
decimalSep = decimalSep)
|
||||
result.trimZeros(decimalSep)
|
||||
|
||||
@@ -1465,6 +1465,8 @@ proc isNil*[T: proc | iterator {.closure.}](x: T): bool {.noSideEffect, magic: "
|
||||
## Fast check whether `x` is nil. This is sometimes more efficient than
|
||||
## `== nil`.
|
||||
|
||||
proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".}
|
||||
|
||||
when defined(nimHasTopDownInference):
|
||||
# magic used for seq type inference
|
||||
proc `@`*[T](a: openArray[T]): seq[T] {.magic: "OpenArrayToSeq".} =
|
||||
@@ -1472,8 +1474,17 @@ when defined(nimHasTopDownInference):
|
||||
##
|
||||
## This is not as efficient as turning a fixed length array into a sequence
|
||||
## as it always copies every element of `a`.
|
||||
newSeq(result, a.len)
|
||||
for i in 0..a.len-1: result[i] = a[i]
|
||||
let sz = a.len
|
||||
when supportsCopyMem(T) and not defined(js):
|
||||
result = newSeqUninit[T](sz)
|
||||
when nimvm:
|
||||
for i in 0..sz-1: result[i] = a[i]
|
||||
else:
|
||||
if sz != 0:
|
||||
copyMem(addr result[0], addr a[0], sizeof(T) * sz)
|
||||
else:
|
||||
newSeq(result, sz)
|
||||
for i in 0..sz-1: result[i] = a[i]
|
||||
else:
|
||||
proc `@`*[T](a: openArray[T]): seq[T] =
|
||||
## Turns an *openArray* into a sequence.
|
||||
@@ -1644,8 +1655,6 @@ when not defined(js) and defined(nimV2):
|
||||
vTable: UncheckedArray[pointer] # vtable for types
|
||||
PNimTypeV2 = ptr TNimTypeV2
|
||||
|
||||
proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".}
|
||||
|
||||
when notJSnotNims and defined(nimSeqsV2):
|
||||
include "system/strs_v2"
|
||||
include "system/seqs_v2"
|
||||
|
||||
@@ -25,3 +25,23 @@ block:
|
||||
var m = uint64(12)
|
||||
foo(culonglong(m))
|
||||
main()
|
||||
|
||||
block: # bug #25109
|
||||
type T = culonglong
|
||||
proc r(c: var T) = c = 1
|
||||
proc h(a: var culonglong) = r(T(a))
|
||||
var a: culonglong
|
||||
h(a)
|
||||
doAssert a == 1
|
||||
|
||||
block: # bug #25111
|
||||
type T = culonglong
|
||||
proc r(c: var T) = c = 1
|
||||
|
||||
proc foo =
|
||||
var a: uint64
|
||||
r(T(a))
|
||||
doAssert a == 1
|
||||
|
||||
foo()
|
||||
|
||||
|
||||
@@ -53,11 +53,11 @@ proc nonStaticTests =
|
||||
block: # formatSize tests
|
||||
when not defined(js):
|
||||
doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB" # <=== bug #8231
|
||||
doAssert formatSize((2.234*1024*1024).int) == "2.234MiB"
|
||||
doAssert formatSize((2.234*1024*1024).int) == "2.233MiB"
|
||||
doAssert formatSize(4096) == "4KiB"
|
||||
doAssert formatSize(4096, prefix=bpColloquial, includeSpace=true) == "4 kB"
|
||||
doAssert formatSize(4096, includeSpace=true) == "4 KiB"
|
||||
doAssert formatSize(5_378_934, prefix=bpColloquial, decimalSep=',') == "5,13MB"
|
||||
doAssert formatSize(5_378_934, prefix=bpColloquial, decimalSep=',') == "5,129MB"
|
||||
|
||||
block: # formatEng tests
|
||||
doAssert formatEng(0, 2, trim=false) == "0.00"
|
||||
|
||||
13
tests/errmsgs/t25117.nim
Normal file
13
tests/errmsgs/t25117.nim
Normal file
@@ -0,0 +1,13 @@
|
||||
discard """
|
||||
errormsg: "'result' requires explicit initialization"
|
||||
"""
|
||||
|
||||
type RI {.requiresInit.} = object
|
||||
v: int
|
||||
|
||||
proc xxx(v: var RI) = discard
|
||||
|
||||
proc f(T: type): T =
|
||||
xxx(result) # Should fail
|
||||
|
||||
discard f(RI)
|
||||
6
tests/errmsgs/t25120.nim
Normal file
6
tests/errmsgs/t25120.nim
Normal file
@@ -0,0 +1,6 @@
|
||||
discard """
|
||||
errormsg: "request to generate code for .compileTime proc: riesig"
|
||||
"""
|
||||
|
||||
proc riesig(): NimNode = discard
|
||||
discard riesig()
|
||||
14
tests/global/tglobalclosure.nim
Normal file
14
tests/global/tglobalclosure.nim
Normal file
@@ -0,0 +1,14 @@
|
||||
discard """
|
||||
errormsg: "cannot assign local to global variable"
|
||||
line: 11
|
||||
"""
|
||||
|
||||
proc main() =
|
||||
var x = "hi"
|
||||
proc p() =
|
||||
echo x
|
||||
|
||||
let a {.global.} = p
|
||||
p()
|
||||
|
||||
main()
|
||||
17
tests/global/tglobalclosure2.nim
Normal file
17
tests/global/tglobalclosure2.nim
Normal file
@@ -0,0 +1,17 @@
|
||||
discard """
|
||||
errormsg: "cannot assign local to global variable"
|
||||
line: 14
|
||||
"""
|
||||
|
||||
type X = object
|
||||
p: proc() {.closure.}
|
||||
|
||||
proc main() =
|
||||
var x = "hi"
|
||||
proc p() =
|
||||
echo x
|
||||
|
||||
let a {.global.} = X(p: p)
|
||||
a.p()
|
||||
|
||||
main()
|
||||
17
tests/global/tglobalproc.nim
Normal file
17
tests/global/tglobalproc.nim
Normal file
@@ -0,0 +1,17 @@
|
||||
discard """
|
||||
output: "hi\nhi"
|
||||
"""
|
||||
|
||||
type X = object
|
||||
p: proc() {.nimcall.}
|
||||
|
||||
proc main() =
|
||||
proc p() =
|
||||
echo "hi"
|
||||
|
||||
let a {.global.} = p
|
||||
let b {.global.} = X(p: p)
|
||||
a()
|
||||
b.p()
|
||||
|
||||
main()
|
||||
@@ -412,3 +412,15 @@ block: # bug #24033
|
||||
collections.add (id, str, $num)
|
||||
|
||||
doAssert collections[1] == (1, "foo", "3.14")
|
||||
|
||||
|
||||
block: # bug #25121
|
||||
iterator k(): int =
|
||||
when nimvm:
|
||||
yield 0
|
||||
else:
|
||||
yield 0
|
||||
|
||||
for _ in k():
|
||||
(proc() = (; let _ = block: 0))()
|
||||
|
||||
|
||||
@@ -258,6 +258,17 @@ block: # any
|
||||
doAssert any(anumbers, proc (x: int): bool = return x > 8) == true
|
||||
doAssert any(anumbers, proc (x: int): bool = return x > 9) == false
|
||||
|
||||
block: # findIt
|
||||
let
|
||||
numbers = @[1, 4, 5, 8, 9, 7, 4]
|
||||
anumbers = [1, 4, 5, 8, 9, 7, 4]
|
||||
len0seq: seq[int] = @[]
|
||||
doAssert findIt(numbers, it == 4) == 1
|
||||
doAssert findIt(numbers, it > 9) == -1
|
||||
doAssert findIt(len0seq, true) == -1
|
||||
doAssert findIt(anumbers, it > 8) == 4
|
||||
doAssert findIt(anumbers, it > 9) == -1
|
||||
|
||||
block: # anyIt
|
||||
let
|
||||
numbers = @[1, 4, 5, 8, 9, 7, 4]
|
||||
|
||||
@@ -789,12 +789,71 @@ bar
|
||||
block: # formatSize
|
||||
disableVm:
|
||||
when hasWorkingInt64:
|
||||
doAssert formatSize(1024'i64 * 1024 * 1024 * 2 - 1) == "1.999GiB"
|
||||
doAssert formatSize(1024'i64 * 1024 * 1024 * 2) == "2GiB"
|
||||
doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB" # <=== bug #8231
|
||||
doAssert formatSize((2.234*1024*1024).int) == "2.234MiB"
|
||||
doAssert formatSize(int64.high) == "7.999EiB"
|
||||
doAssert formatSize(int64.high div 2 + 1) == "4EiB"
|
||||
doAssert formatSize(int64.high div 2) == "3.999EiB"
|
||||
doAssert formatSize(int64.high div 4 + 1) == "2EiB"
|
||||
doAssert formatSize(int64.high div 4) == "1.999EiB"
|
||||
doAssert formatSize(int64.high div 8 + 1) == "1EiB"
|
||||
doAssert formatSize(int64.high div 8) == "1023.999PiB"
|
||||
doAssert formatSize(int64.high div 16 + 1) == "512PiB"
|
||||
doAssert formatSize(int64.high div 16) == "511.999PiB"
|
||||
doAssert formatSize(0) == "0B"
|
||||
doAssert formatSize(0, includeSpace = true) == "0 B"
|
||||
doAssert formatSize(1) == "1B"
|
||||
doAssert formatSize(2) == "2B"
|
||||
doAssert formatSize(1022) == "1022B"
|
||||
doAssert formatSize(1023) == "1023B"
|
||||
doAssert formatSize(1024) == "1KiB"
|
||||
doAssert formatSize(1025) == "1.001KiB"
|
||||
doAssert formatSize(1026) == "1.002KiB"
|
||||
doAssert formatSize(1024 * 2 - 2) == "1.998KiB"
|
||||
doAssert formatSize(1024 * 2 - 1) == "1.999KiB"
|
||||
doAssert formatSize(1024 * 2) == "2KiB"
|
||||
doAssert formatSize(1024 * 2 + 1) == "2.001KiB"
|
||||
doAssert formatSize(1024 * 2 + 2) == "2.002KiB"
|
||||
doAssert formatSize(4096 - 1) == "3.999KiB"
|
||||
doAssert formatSize(4096) == "4KiB"
|
||||
doAssert formatSize(4096 + 1) == "4.001KiB"
|
||||
doAssert formatSize(1024 * 512 - 1) == "511.999KiB"
|
||||
doAssert formatSize(1024 * 512) == "512KiB"
|
||||
doAssert formatSize(1024 * 512 + 1) == "512.001KiB"
|
||||
doAssert formatSize(1024 * 1024 - 2) == "1023.998KiB"
|
||||
doAssert formatSize(1024 * 1024 - 1) == "1023.999KiB"
|
||||
doAssert formatSize(1024 * 1024) == "1MiB"
|
||||
doAssert formatSize(1024 * 1024 + 1) == "1MiB"
|
||||
doAssert formatSize(1024 * 1024 + 1023) == "1MiB"
|
||||
doAssert formatSize(1024 * 1024 + 1024) == "1.001MiB"
|
||||
doAssert formatSize(1024 * 1024 + 1024 * 2) == "1.002MiB"
|
||||
doAssert formatSize(1024 * 1024 * 2 - 1) == "1.999MiB"
|
||||
doAssert formatSize(1024 * 1024 * 2) == "2MiB"
|
||||
doAssert formatSize(1024 * 1024 * 2 + 1) == "2MiB"
|
||||
doAssert formatSize(1024 * 1024 * 2 + 1024) == "2.001MiB"
|
||||
doAssert formatSize(1024 * 1024 * 2 + 1024 * 2) == "2.002MiB"
|
||||
doAssert formatSize(1024 * 1024 * 4 - 1) == "3.999MiB"
|
||||
doAssert formatSize(1024 * 1024 * 4) == "4MiB"
|
||||
doAssert formatSize(1024 * (1024 * 4 + 1)) == "4.001MiB"
|
||||
doAssert formatSize(1024 * 1024 * 512 - 1025) == "511.998MiB"
|
||||
doAssert formatSize(1024 * 1024 * 512 - 1) == "511.999MiB"
|
||||
doAssert formatSize(1024 * 1024 * 512) == "512MiB"
|
||||
doAssert formatSize(1024 * 1024 * 512 + 1) == "512MiB"
|
||||
doAssert formatSize(1024 * 1024 * 512 + 1024) == "512.001MiB"
|
||||
doAssert formatSize(1024 * 1024 * 512 + 1024 * 2) == "512.002MiB"
|
||||
doAssert formatSize(1024 * 1024 * 1024 - 1) == "1023.999MiB"
|
||||
doAssert formatSize(1024 * 1024 * 1024) == "1GiB"
|
||||
doAssert formatSize(1024 * 1024 * 1024 + 1) == "1GiB"
|
||||
doAssert formatSize(1024 * 1024 * 1025) == "1.001GiB"
|
||||
doAssert formatSize(1024 * 1024 * 1026) == "1.002GiB"
|
||||
# != 2.234MiB as (2.234 * 1024 * 1024).int.float / (1024 * 1024) = 2.23399...
|
||||
# and formatSize round down the value
|
||||
doAssert formatSize((2.234*1024*1024).int) == "2.233MiB"
|
||||
doAssert formatSize(4096, prefix = bpColloquial, includeSpace = true) == "4 kB"
|
||||
doAssert formatSize(4096, includeSpace = true) == "4 KiB"
|
||||
doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,13MB"
|
||||
# (5378934).float / (1024 * 1024) = 5.12975...
|
||||
doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,129MB"
|
||||
|
||||
block: # formatEng
|
||||
disableVm:
|
||||
|
||||
@@ -4,6 +4,18 @@ import re
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
# Add compatibility for older GDB versions
|
||||
if not hasattr(gdb, 'SYMBOL_FUNCTION_DOMAIN'):
|
||||
gdb.SYMBOL_FUNCTION_DOMAIN = 0 # This is the value used in newer GDB versions
|
||||
|
||||
# Configure demangling for Itanium C++ ABI (which Nim uses)
|
||||
try:
|
||||
gdb.execute("set demangle-style gnu-v3") # GNU v3 style handles Itanium mangling
|
||||
gdb.execute("set print asm-demangle on")
|
||||
gdb.execute("set print demangle on")
|
||||
except Exception as e:
|
||||
gdb.write(f"Warning: Could not configure demangling: {str(e)}\n", gdb.STDERR)
|
||||
|
||||
# some feedback that the nim runtime support is loading, isn't a bad
|
||||
# thing at all.
|
||||
gdb.write("Loading Nim Runtime support.\n", gdb.STDERR)
|
||||
@@ -70,12 +82,12 @@ class NimTypeRecognizer:
|
||||
type_map_static = {
|
||||
'NI': 'system.int', 'NI8': 'int8', 'NI16': 'int16', 'NI32': 'int32',
|
||||
'NI64': 'int64',
|
||||
|
||||
|
||||
'NU': 'uint', 'NU8': 'uint8','NU16': 'uint16', 'NU32': 'uint32',
|
||||
'NU64': 'uint64',
|
||||
|
||||
|
||||
'NF': 'float', 'NF32': 'float32', 'NF64': 'float64',
|
||||
|
||||
|
||||
'NIM_BOOL': 'bool',
|
||||
|
||||
'NIM_CHAR': 'char', 'NCSTRING': 'cstring', 'NimStringDesc': 'string', 'NimStringV2': 'string'
|
||||
@@ -556,7 +568,7 @@ class NimSeqPrinter:
|
||||
except RuntimeError:
|
||||
inaccessible = True
|
||||
yield "data[{0}]".format(i), "inaccessible"
|
||||
|
||||
|
||||
################################################################################
|
||||
|
||||
class NimArrayPrinter:
|
||||
|
||||
Reference in New Issue
Block a user