diff options
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 2 | ||||
-rw-r--r-- | compiler/condsyms.nim | 1 | ||||
-rw-r--r-- | compiler/jsgen.nim | 1 | ||||
-rw-r--r-- | compiler/lineinfos.nim | 6 | ||||
-rw-r--r-- | compiler/rodutils.nim | 21 | ||||
-rw-r--r-- | compiler/sem.nim | 3 | ||||
-rw-r--r-- | compiler/semfold.nim | 8 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 4 | ||||
-rw-r--r-- | compiler/vm.nim | 3 | ||||
-rw-r--r-- | compiler/vmdef.nim | 3 | ||||
-rw-r--r-- | compiler/vmgen.nim | 1 | ||||
-rw-r--r-- | lib/pure/collections/sequtils.nim | 33 | ||||
-rw-r--r-- | lib/pure/math.nim | 82 | ||||
-rw-r--r-- | lib/system.nim | 23 | ||||
-rw-r--r-- | lib/system/gc_common.nim | 22 | ||||
-rw-r--r-- | lib/windows/winlean.nim | 2 | ||||
-rw-r--r-- | tests/arithm/tashr.nim | 46 | ||||
-rw-r--r-- | tests/concepts/t3330.nim | 12 |
20 files changed, 224 insertions, 52 deletions
diff --git a/changelog.md b/changelog.md index 56830628a..9ab7a0b72 100644 --- a/changelog.md +++ b/changelog.md @@ -95,6 +95,7 @@ - Added the proc ``flush`` for memory mapped files. - Added the ``MemMapFileStream``. - Added ``macros.copyLineInfo`` to copy lineInfo from other node. +- Added ``system.ashr`` an arithmetic right shift for integers. ### Library changes diff --git a/compiler/ast.nim b/compiler/ast.nim index dbf1151a9..ef12e1184 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -591,7 +591,7 @@ type mAddI, mSubI, mMulI, mDivI, mModI, mSucc, mPred, mAddF64, mSubF64, mMulF64, mDivF64, - mShrI, mShlI, mBitandI, mBitorI, mBitxorI, + mShrI, mShlI, mAshrI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI, mMinF64, mMaxF64, mAddU, mSubU, mMulU, mDivU, mModU, diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 3bcf2c29b..6803a9478 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -552,9 +552,9 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = "(($4)($1) - ($4)($2))", # SubF64 "(($4)($1) * ($4)($2))", # MulF64 "(($4)($1) / ($4)($2))", # DivF64 - "($4)((NU$5)($1) >> (NU$3)($2))", # ShrI "($4)((NU$3)($1) << (NU$3)($2))", # ShlI + "($4)((NI$3)($1) >> (NU$3)($2))", # AshrI "($4)($1 & $2)", # BitandI "($4)($1 | $2)", # BitorI "($4)($1 ^ $2)", # BitxorI diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 9dfe69442..5a62b46ad 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -73,3 +73,4 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimNotNil") defineSymbol("nimVmExportFixed") defineSymbol("nimIncrSeqV3") + defineSymbol("nimAshr") diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index ef54841ae..63100a68d 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -379,6 +379,7 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["", "", "($1 / $2)", "($1 / $2)"], # DivF64 ["", "", "", ""], # ShrI ["", "", "($1 << $2)", "($1 << $2)"], # ShlI + ["", "", "($1 >> $2)", "($1 >> $2)"], # AshrI ["", "", "($1 & $2)", "($1 & $2)"], # BitandI ["", "", "($1 | $2)", "($1 | $2)"], # BitorI ["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index 261dcb44e..4f0c3a778 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -92,7 +92,7 @@ const warnResultShadowed: "Special variable 'result' is shadowed.", warnInconsistentSpacing: "Number of spaces around '$#' is not consistent", warnUser: "$1", - hintSuccess: "operation successful", + hintSuccess: "operation successful: $#", hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)", hintCC: "CC: \'$1\'", # unused hintLineTooLong: "line too long", @@ -169,8 +169,8 @@ proc computeNotesVerbosity(): array[0..3, TNoteKinds] = result[1] = result[2] - {warnShadowIdent, warnProveField, warnProveIndex, warnGcUnsafe, hintPath, hintDependency, hintCodeBegin, hintCodeEnd, hintSource, hintGlobalVar, hintGCStats} - result[0] = result[1] - {hintSuccessX, hintConf, hintProcessing, - hintPattern, hintExecuting, hintLinking} + result[0] = result[1] - {hintSuccessX, hintSuccess, hintConf, + hintProcessing, hintPattern, hintExecuting, hintLinking} const NotesVerbosity* = computeNotesVerbosity() diff --git a/compiler/rodutils.nim b/compiler/rodutils.nim index 66d7f63c2..a774cdba7 100644 --- a/compiler/rodutils.nim +++ b/compiler/rodutils.nim @@ -10,6 +10,27 @@ ## Serialization utilities for the compiler. import strutils, math +# MSVC prior to 2013 doesn't have C99 functions +when defined(windows) and (defined(vcc) or defined(bcc)): + {.emit: """#if defined(_MSC_VER) && _MSC_VER < 1900 + #include <stdarg.h> + static int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) { + int count = -1; + if (size != 0) count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + if (count == -1) count = _vscprintf(format, ap); + return count; + } + int snprintf(char *outBuf, size_t size, const char *format, ...) { + int count; + va_list ap; + va_start(ap, format); + count = c99_vsnprintf(outBuf, size, format, ap); + va_end(ap); + return count; + } + #endif + """.} + proc c_snprintf(s: cstring; n:uint; frmt: cstring): cint {.importc: "snprintf", header: "<stdio.h>", nodecl, varargs.} proc toStrMaxPrecision*(f: BiggestFloat, literalPostfix = ""): string = diff --git a/compiler/sem.nim b/compiler/sem.nim index 68a0a7094..427b44e04 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -621,7 +621,8 @@ proc testExamples(c: PContext) = if os.execShellCmd(os.getAppFilename() & " " & backend & " --nimcache:" & nimcache & " -r " & outp) != 0: quit "[Examples] failed: see " & outp else: - removeFile(outp) + # keep generated source file `outp` to allow inspection. + rawMessage(c.config, hintSuccess, ["runnableExamples: " & outp]) removeFile(outp.changeFileExt(ExeExt)) try: removeDir(nimcache) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index d2abfac13..a6c185fdc 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -268,6 +268,14 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = of tyInt64, tyInt, tyUInt..tyUInt64: result = newIntNodeT(`shr`(getInt(a), getInt(b)), n, g) else: internalError(g.config, n.info, "constant folding for shr") + of mAshrI: + case skipTypes(n.typ, abstractRange).kind + of tyInt8: result = newIntNodeT(ashr(int8(getInt(a)), int8(getInt(b))), n, g) + of tyInt16: result = newIntNodeT(ashr(int16(getInt(a)), int16(getInt(b))), n, g) + of tyInt32: result = newIntNodeT(ashr(int32(getInt(a)), int32(getInt(b))), n, g) + of tyInt64, tyInt: + result = newIntNodeT(ashr(getInt(a), getInt(b)), n, g) + else: internalError(g.config, n.info, "constant folding for ashr") of mDivI: result = foldDiv(getInt(a), getInt(b), n, g) of mModI: result = foldMod(getInt(a), getInt(b), n, g) of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n, g) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 29f16b808..5afa1b031 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -858,6 +858,10 @@ proc inferStaticParam*(c: var TCandidate, lhs: PNode, rhs: BiggestInt): bool = if lhs[2].kind == nkIntLit: return inferStaticParam(c, lhs[1], rhs shl lhs[2].intVal) + of mAshrI: + if lhs[2].kind == nkIntLit: + return inferStaticParam(c, lhs[1], ashr(rhs, lhs[2].intVal)) + of mUnaryMinusI: return inferStaticParam(c, lhs[1], -rhs) diff --git a/compiler/vm.nim b/compiler/vm.nim index d4b041dea..c49b66b82 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -752,6 +752,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcShlInt: decodeBC(rkInt) regs[ra].intVal = regs[rb].intVal shl regs[rc].intVal + of opcAshrInt: + decodeBC(rkInt) + regs[ra].intVal = ashr(regs[rb].intVal, regs[rc].intVal) of opcBitandInt: decodeBC(rkInt) regs[ra].intVal = regs[rb].intVal and regs[rc].intVal diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index a4489513a..50235c95f 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -57,7 +57,8 @@ type opcLenStr, opcIncl, opcInclRange, opcExcl, opcCard, opcMulInt, opcDivInt, opcModInt, - opcAddFloat, opcSubFloat, opcMulFloat, opcDivFloat, opcShrInt, opcShlInt, + opcAddFloat, opcSubFloat, opcMulFloat, opcDivFloat, + opcShrInt, opcShlInt, opcAshrInt, opcBitandInt, opcBitorInt, opcBitxorInt, opcAddu, opcSubu, opcMulu, opcDivu, opcModu, opcEqInt, opcLeInt, opcLtInt, opcEqFloat, opcLeFloat, opcLtFloat, opcLeu, opcLtu, diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 965c75485..a36f559ca 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -939,6 +939,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = c.freeTemp(tmp2) of mShlI: genBinaryABCnarrowU(c, n, dest, opcShlInt) + of mAshrI: genBinaryABCnarrow(c, n, dest, opcAshrInt) of mBitandI: genBinaryABCnarrowU(c, n, dest, opcBitandInt) of mBitorI: genBinaryABCnarrowU(c, n, dest, opcBitorInt) of mBitxorI: genBinaryABCnarrowU(c, n, dest, opcBitxorInt) diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index db33e41af..8f81fe4f5 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -635,6 +635,28 @@ template mapIt*(s, typ, op: untyped): untyped = result.add(op) result +# This is needed in order not to break the bootstrap, the fallback +# implementation is a "dumb" let that won't work in some cases (eg. when `exp` +# is an openArray) +when declared(macros.symKind): + macro evalOnce(v, exp: untyped): untyped = + expectKind(v, nnkIdent) + var val = exp + + result = newStmtList() + + # Not a parameter we can pass as-is, evaluate and store in a temporary + # variable + if exp.kind != nnkSym or exp.symKind != nskParam: + val = genSym() + result.add(newLetStmt(val, exp)) + + result.add( + newProc(name = genSym(nskTemplate, $v), params = [getType(untyped)], + body = val, procType = nnkTemplateDef)) +else: + macro evalOnce(v, exp: untyped): untyped = + result = newLetStmt(v, exp) template mapIt*(s, op: untyped): untyped = ## Convenience template around the ``map`` proc to reduce typing. @@ -654,8 +676,8 @@ template mapIt*(s, op: untyped): untyped = var it{.inject.}: type(items(s)); op)) var result: seq[outType] - when compiles(s.len): - let t = s + evalOnce(t, s) + when compiles(t.len): var i = 0 result = newSeq[outType](t.len) for it {.inject.} in t: @@ -663,7 +685,7 @@ template mapIt*(s, op: untyped): untyped = i += 1 else: result = @[] - for it {.inject.} in s: + for it {.inject.} in t: result.add(op) result @@ -1044,5 +1066,10 @@ when isMainModule: doAssert mapLiterals((1, ("abc"), 2), float, nested=false) == (float(1), "abc", float(2)) doAssert mapLiterals(([1], ("abc"), 2), `$`, nested=true) == (["1"], "abc", "2") + block: # mapIt with openArray + when declared(macros.symKind): + proc foo(x: openArray[int]): seq[int] = x.mapIt(it + 1) + doAssert foo([1,2,3]) == @[2,3,4] + when not defined(testing): echo "Finished doc tests" diff --git a/lib/pure/math.nim b/lib/pure/math.nim index b921b1841..eb09bf4a7 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -162,9 +162,6 @@ when not defined(JS): # C proc log10*(x: float32): float32 {.importc: "log10f", header: "<math.h>".} proc log10*(x: float64): float64 {.importc: "log10", header: "<math.h>".} ## Computes the common logarithm (base 10) of `x` - proc log2*(x: float32): float32 {.importc: "log2f", header: "<math.h>".} - proc log2*(x: float64): float64 {.importc: "log2", header: "<math.h>".} - ## Computes the binary logarithm (base 2) of `x` proc exp*(x: float32): float32 {.importc: "expf", header: "<math.h>".} proc exp*(x: float64): float64 {.importc: "exp", header: "<math.h>".} ## Computes the exponential function of `x` (pow(E, x)) @@ -268,6 +265,8 @@ proc arcsech*[T: float32|float64](x: T): T = arccosh(1.0 / x) proc arccsch*[T: float32|float64](x: T): T = arcsinh(1.0 / x) ## Computes the inverse hyperbolic cosecant of `x` +const windowsCC89 = defined(windows) and (defined(vcc) or defined(bcc)) + when not defined(JS): # C proc hypot*(x, y: float32): float32 {.importc: "hypotf", header: "<math.h>".} proc hypot*(x, y: float64): float64 {.importc: "hypot", header: "<math.h>".} @@ -280,25 +279,27 @@ when not defined(JS): # C ## ## To compute power between integers, use `^` e.g. 2 ^ 6 - proc erf*(x: float32): float32 {.importc: "erff", header: "<math.h>".} - proc erf*(x: float64): float64 {.importc: "erf", header: "<math.h>".} - ## The error function - proc erfc*(x: float32): float32 {.importc: "erfcf", header: "<math.h>".} - proc erfc*(x: float64): float64 {.importc: "erfc", header: "<math.h>".} - ## The complementary error function - - proc gamma*(x: float32): float32 {.importc: "tgammaf", header: "<math.h>".} - proc gamma*(x: float64): float64 {.importc: "tgamma", header: "<math.h>".} - ## The gamma function - proc tgamma*(x: float32): float32 - {.deprecated: "use gamma instead", importc: "tgammaf", header: "<math.h>".} - proc tgamma*(x: float64): float64 - {.deprecated: "use gamma instead", importc: "tgamma", header: "<math.h>".} - ## The gamma function - ## **Deprecated since version 0.19.0**: Use ``gamma`` instead. - proc lgamma*(x: float32): float32 {.importc: "lgammaf", header: "<math.h>".} - proc lgamma*(x: float64): float64 {.importc: "lgamma", header: "<math.h>".} - ## Natural log of the gamma function + # TODO: add C89 version on windows + when not windowsCC89: + proc erf*(x: float32): float32 {.importc: "erff", header: "<math.h>".} + proc erf*(x: float64): float64 {.importc: "erf", header: "<math.h>".} + ## The error function + proc erfc*(x: float32): float32 {.importc: "erfcf", header: "<math.h>".} + proc erfc*(x: float64): float64 {.importc: "erfc", header: "<math.h>".} + ## The complementary error function + + proc gamma*(x: float32): float32 {.importc: "tgammaf", header: "<math.h>".} + proc gamma*(x: float64): float64 {.importc: "tgamma", header: "<math.h>".} + ## The gamma function + proc tgamma*(x: float32): float32 + {.deprecated: "use gamma instead", importc: "tgammaf", header: "<math.h>".} + proc tgamma*(x: float64): float64 + {.deprecated: "use gamma instead", importc: "tgamma", header: "<math.h>".} + ## The gamma function + ## **Deprecated since version 0.19.0**: Use ``gamma`` instead. + proc lgamma*(x: float32): float32 {.importc: "lgammaf", header: "<math.h>".} + proc lgamma*(x: float64): float64 {.importc: "lgamma", header: "<math.h>".} + ## Natural log of the gamma function proc floor*(x: float32): float32 {.importc: "floorf", header: "<math.h>".} proc floor*(x: float64): float64 {.importc: "floor", header: "<math.h>".} @@ -314,7 +315,7 @@ when not defined(JS): # C ## .. code-block:: nim ## echo ceil(-2.1) ## -2.0 - when defined(windows) and (defined(vcc) or defined(bcc)): + when windowsCC89: # MSVC 2010 don't have trunc/truncf # this implementation was inspired by Go-lang Math.Trunc proc truncImpl(f: float64): float64 = @@ -452,6 +453,28 @@ when not defined(JS): var exp: int32 result = c_frexp(x, exp) exponent = exp + + when windowsCC89: + # taken from Go-lang Math.Log2 + const ln2 = 0.693147180559945309417232121458176568075500134360255254120680009 + template log2Impl[T](x: T): T = + var exp: int32 + var frac = frexp(x, exp) + # Make sure exact powers of two give an exact answer. + # Don't depend on Log(0.5)*(1/Ln2)+exp being exactly exp-1. + if frac == 0.5: return T(exp - 1) + log10(frac)*(1/ln2) + T(exp) + + proc log2*(x: float32): float32 = log2Impl(x) + proc log2*(x: float64): float64 = log2Impl(x) + ## Log2 returns the binary logarithm of x. + ## The special cases are the same as for Log. + + else: + proc log2*(x: float32): float32 {.importc: "log2f", header: "<math.h>".} + proc log2*(x: float64): float64 {.importc: "log2", header: "<math.h>".} + ## Computes the binary logarithm (base 2) of `x` + else: proc frexp*[T: float32|float64](x: T, exponent: var int): T = if x == 0.0: @@ -564,7 +587,7 @@ proc lcm*[T](x, y: T): T = ## Computes the least common multiple of ``x`` and ``y``. x div gcd(x, y) * y -when isMainModule and not defined(JS): +when isMainModule and not defined(JS) and not windowsCC89: # Check for no side effect annotation proc mySqrt(num: float): float {.noSideEffect.} = return sqrt(num) @@ -692,3 +715,14 @@ when isMainModule: block: # log doAssert log(4.0, 3.0) == ln(4.0) / ln(3.0) + doAssert log2(8.0'f64) == 3.0'f64 + doAssert log2(4.0'f64) == 2.0'f64 + doAssert log2(2.0'f64) == 1.0'f64 + doAssert log2(1.0'f64) == 0.0'f64 + doAssert classify(log2(0.0'f64)) == fcNegInf + + doAssert log2(8.0'f32) == 3.0'f32 + doAssert log2(4.0'f32) == 2.0'f32 + doAssert log2(2.0'f32) == 1.0'f32 + doAssert log2(1.0'f32) == 0.0'f32 + doAssert classify(log2(0.0'f32)) == fcNegInf diff --git a/lib/system.nim b/lib/system.nim index 0cfa39e19..53605f9fd 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -971,6 +971,23 @@ else: proc `shl`*(x, y: int32): int32 {.magic: "ShlI", noSideEffect.} proc `shl`*(x, y: int64): int64 {.magic: "ShlI", noSideEffect.} +when defined(nimAshr): + proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} + proc ashr*(x: int8, y: SomeInteger): int8 {.magic: "AshrI", noSideEffect.} + proc ashr*(x: int16, y: SomeInteger): int16 {.magic: "AshrI", noSideEffect.} + proc ashr*(x: int32, y: SomeInteger): int32 {.magic: "AshrI", noSideEffect.} + proc ashr*(x: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.} + ## Shifts right by pushing copies of the leftmost bit in from the left, + ## and let the rightmost bits fall off. + ## + ## .. code-block:: Nim + ## 0b0001_0000'i8 shr 2 == 0b0000_0100'i8 + ## 0b1000_0000'i8 shr 8 == 0b1111_1111'i8 + ## 0b1000_0000'i8 shr 1 == 0b1100_0000'i8 +else: + # used for bootstrapping the compiler + proc ashr*[T](x: T, y: SomeInteger): T = discard + proc `and`*(x, y: int): int {.magic: "BitandI", noSideEffect.} proc `and`*(x, y: int8): int8 {.magic: "BitandI", noSideEffect.} proc `and`*(x, y: int16): int16 {.magic: "BitandI", noSideEffect.} @@ -1978,7 +1995,7 @@ when sizeof(int) <= 2: else: type IntLikeForCount = int|int8|int16|int32|char|bool|uint8|uint16|enum -iterator countdown*[T](a, b: T, step = 1): T {.inline.} = +iterator countdown*[T](a, b: T, step: Positive = 1): T {.inline.} = ## Counts from ordinal value `a` down to `b` (inclusive) with the given ## step count. `T` may be any ordinal type, `step` may only ## be positive. **Note**: This fails to count to ``low(int)`` if T = int for @@ -2001,7 +2018,7 @@ iterator countdown*[T](a, b: T, step = 1): T {.inline.} = dec(res, step) when defined(nimNewRoof): - iterator countup*[T](a, b: T, step = 1): T {.inline.} = + iterator countup*[T](a, b: T, step: Positive = 1): T {.inline.} = ## Counts from ordinal value `a` up to `b` (inclusive) with the given ## step count. `S`, `T` may be any ordinal type, `step` may only ## be positive. **Note**: This fails to count to ``high(int)`` if T = int for @@ -2018,7 +2035,7 @@ when defined(nimNewRoof): inc(res, step) iterator `..`*[T](a, b: T): T {.inline.} = - ## An alias for `countup`. + ## An alias for `countup(a, b, 1)`. when T is IntLikeForCount: var res = int(a) while res <= int(b): diff --git a/lib/system/gc_common.nim b/lib/system/gc_common.nim index dcea0c4cc..88e150cd1 100644 --- a/lib/system/gc_common.nim +++ b/lib/system/gc_common.nim @@ -37,22 +37,28 @@ when defined(nimTypeNames): a[j] = v if h == 1: break - proc dumpNumberOfInstances* = - # also add the allocated strings to the list of known types: + iterator dumpHeapInstances*(): tuple[name: cstring; count: int; sizes: int] = + ## Iterate over summaries of types on heaps. + ## This data may be inaccurate if allocations + ## are made by the iterator body. if strDesc.nextType == nil: strDesc.nextType = nimTypeRoot strDesc.name = "string" nimTypeRoot = addr strDesc + var it = nimTypeRoot + while it != nil: + if (it.instances > 0 or it.sizes != 0): + yield (it.name, it.instances, it.sizes) + it = it.nextType + + proc dumpNumberOfInstances* = var a: InstancesInfo var n = 0 - var it = nimTypeRoot var totalAllocated = 0 - while it != nil: - if (it.instances > 0 or it.sizes != 0) and n < a.len: - a[n] = (it.name, it.instances, it.sizes) - inc n + for it in dumpHeapInstances(): + a[n] = it + inc n inc totalAllocated, it.sizes - it = it.nextType sortInstances(a, n) for i in 0 .. n-1: c_fprintf(stdout, "[Heap] %s: #%ld; bytes: %ld\n", a[i][0], a[i][1], a[i][2]) diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 3263f1d37..60a6e5d9b 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -396,7 +396,7 @@ else: proc moveFileA*(lpExistingFileName, lpNewFileName: cstring): WINBOOL {. importc: "MoveFileA", stdcall, dynlib: "kernel32".} - proc moveFileExA*(lpExistingFileName, lpNewFileName: WideCString, + proc moveFileExA*(lpExistingFileName, lpNewFileName: cstring, flags: DWORD): WINBOOL {. importc: "MoveFileExA", stdcall, dynlib: "kernel32".} diff --git a/tests/arithm/tashr.nim b/tests/arithm/tashr.nim new file mode 100644 index 000000000..aeb3b6843 --- /dev/null +++ b/tests/arithm/tashr.nim @@ -0,0 +1,46 @@ +discard """ + output: '''''' + targets: '''c js''' +""" + +# issue #6255, feature request +# arithmetic right shift + +var x1 = -123'i8 +var x2 = -123'i16 +var x3 = -123'i32 +var x4 = -123'i64 +var x5 = -123 + +block codegen_test: + doAssert ashr(x1, 1) == -62 + doAssert ashr(x2, 1) == -62 + doAssert ashr(x3, 1) == -62 + doAssert ashr(x4, 1) == -62 + doAssert ashr(x5, 1) == -62 + +block semfold_test: + doAssert ashr(-123'i8 , 1) == -62 + doAssert ashr(-123'i16, 1) == -62 + doAssert ashr(-123'i32, 1) == -62 + doAssert ashr(-123'i64, 1) == -62 + doAssert ashr(-123 , 1) == -62 + +static: # VM test + doAssert ashr(-123'i8 , 1) == -62 + doAssert ashr(-123'i16, 1) == -62 + doAssert ashr(-123'i32, 1) == -62 + doAssert ashr(-123'i64, 1) == -62 + doAssert ashr(-123 , 1) == -62 + + var y1 = -123'i8 + var y2 = -123'i16 + var y3 = -123'i32 + var y4 = -123'i64 + var y5 = -123 + + doAssert ashr(y1, 1) == -62 + doAssert ashr(y2, 1) == -62 + doAssert ashr(y3, 1) == -62 + doAssert ashr(y4, 1) == -62 + doAssert ashr(y5, 1) == -62 diff --git a/tests/concepts/t3330.nim b/tests/concepts/t3330.nim index 78dd876e2..8021db827 100644 --- a/tests/concepts/t3330.nim +++ b/tests/concepts/t3330.nim @@ -13,15 +13,11 @@ proc add(result: var string; x: float) first type mismatch at position: 1 required type: var string but expression 'k' is of type: Alias -proc add(x: var string; y: cstring) - first type mismatch at position: 1 - required type: var string - but expression 'k' is of type: Alias -proc add(x: var string; y: char) +proc add(x: var string; y: string) first type mismatch at position: 1 required type: var string but expression 'k' is of type: Alias -proc add(x: var string; y: string) +proc add(x: var string; y: cstring) first type mismatch at position: 1 required type: var string but expression 'k' is of type: Alias @@ -33,6 +29,10 @@ proc add(result: var string; x: int64) first type mismatch at position: 1 required type: var string but expression 'k' is of type: Alias +proc add(x: var string; y: char) + first type mismatch at position: 1 + required type: var string + but expression 'k' is of type: Alias t3330.nim(48, 8) template/generic instantiation from here t3330.nim(55, 6) Foo: 'bar.value' cannot be assigned to |