Merge branch 'devel' of github.com:nim-lang/Nim into devel

This commit is contained in:
Araq 2018-06-26 01:35:12 +02:00
commit c68d52b69d
15 changed files with 248 additions and 52 deletions

View file

@ -59,7 +59,7 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): Rope =
else: else:
result = rope("NIM_NIL") result = rope("NIM_NIL")
of nkStrLit..nkTripleStrLit: of nkStrLit..nkTripleStrLit:
case skipTypes(ty, abstractVarRange).kind case skipTypes(ty, abstractVarRange + {tyStatic}).kind
of tyNil: of tyNil:
result = genNilStringLiteral(p.module, n.info) result = genNilStringLiteral(p.module, n.info)
of tyString: of tyString:
@ -385,7 +385,7 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) =
else: else:
addrLoc(p.config, a) addrLoc(p.config, a)
var ty = skipTypes(dest.t, abstractVarRange) var ty = skipTypes(dest.t, abstractVarRange + {tyStatic})
case ty.kind case ty.kind
of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray: of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray:
# XXX optimize this # XXX optimize this

View file

@ -606,7 +606,10 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
incl(conf.globalOptions, optRun) incl(conf.globalOptions, optRun)
of "verbosity": of "verbosity":
expectArg(conf, switch, arg, pass, info) expectArg(conf, switch, arg, pass, info)
conf.verbosity = parseInt(arg) let verbosity = parseInt(arg)
if verbosity notin {0..3}:
localError(conf, info, "invalid verbosity level: '$1'" % arg)
conf.verbosity = verbosity
conf.notes = NotesVerbosity[conf.verbosity] conf.notes = NotesVerbosity[conf.verbosity]
incl(conf.notes, conf.enableNotes) incl(conf.notes, conf.enableNotes)
excl(conf.notes, conf.disableNotes) excl(conf.notes, conf.disableNotes)

View file

@ -271,7 +271,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
localError(c.config, n.info, errXExpectsTypeOrValue % opToStr[m]) localError(c.config, n.info, errXExpectsTypeOrValue % opToStr[m])
else: else:
n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType}) n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
var typ = skipTypes(n.sons[1].typ, abstractVarRange + {tyTypeDesc}) var typ = skipTypes(n.sons[1].typ, abstractVarRange + {tyTypeDesc, tyUserTypeClassInst})
case typ.kind case typ.kind
of tySequence, tyString, tyCString, tyOpenArray, tyVarargs: of tySequence, tyString, tyCString, tyOpenArray, tyVarargs:
n.typ = getSysType(c.graph, n.info, tyInt) n.typ = getSysType(c.graph, n.info, tyInt)
@ -1261,7 +1261,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
# make sure we don't evaluate generic macros/templates # make sure we don't evaluate generic macros/templates
n.sons[0] = semExprWithType(c, n.sons[0], n.sons[0] = semExprWithType(c, n.sons[0],
{efNoEvaluateGeneric}) {efNoEvaluateGeneric})
let arr = skipTypes(n.sons[0].typ, {tyGenericInst, let arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyUserTypeClassInst,
tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink}) tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
case arr.kind case arr.kind
of tyArray, tyOpenArray, tyVarargs, tySequence, tyString, of tyArray, tyOpenArray, tyVarargs, tySequence, tyString,

View file

@ -211,7 +211,12 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
of mUnaryMinusF64: result = newFloatNodeT(- getFloat(a), n, g) of mUnaryMinusF64: result = newFloatNodeT(- getFloat(a), n, g)
of mNot: result = newIntNodeT(1 - getInt(a), n, g) of mNot: result = newIntNodeT(1 - getInt(a), n, g)
of mCard: result = newIntNodeT(nimsets.cardSet(g.config, a), n, g) of mCard: result = newIntNodeT(nimsets.cardSet(g.config, a), n, g)
of mBitnotI: result = newIntNodeT(not getInt(a), n, g) of mBitnotI:
case skipTypes(n.typ, abstractRange).kind
of tyUInt..tyUInt64:
result = newIntNodeT((not getInt(a)) and lastOrd(g.config, a.typ, fixedUnsigned=true), n, g)
else:
result = newIntNodeT(not getInt(a), n, g)
of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, g) of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, g)
of mLengthSeq, mLengthOpenArray, mXLenSeq, mLengthStr, mXLenStr: of mLengthSeq, mLengthOpenArray, mXLenSeq, mLengthStr, mXLenStr:
if a.kind == nkNilLit: if a.kind == nkNilLit:
@ -250,8 +255,10 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
of tyInt8: result = newIntNodeT(int8(getInt(a)) shl int8(getInt(b)), n, g) of tyInt8: result = newIntNodeT(int8(getInt(a)) shl int8(getInt(b)), n, g)
of tyInt16: result = newIntNodeT(int16(getInt(a)) shl int16(getInt(b)), n, g) of tyInt16: result = newIntNodeT(int16(getInt(a)) shl int16(getInt(b)), n, g)
of tyInt32: result = newIntNodeT(int32(getInt(a)) shl int32(getInt(b)), n, g) of tyInt32: result = newIntNodeT(int32(getInt(a)) shl int32(getInt(b)), n, g)
of tyInt64, tyInt, tyUInt..tyUInt64: of tyInt64, tyInt:
result = newIntNodeT(`shl`(getInt(a), getInt(b)), n, g) result = newIntNodeT(`shl`(getInt(a), getInt(b)), n, g)
of tyUInt..tyUInt64:
result = newIntNodeT(`shl`(getInt(a), getInt(b)) and lastOrd(g.config, a.typ, fixedUnsigned=true), n, g)
else: internalError(g.config, n.info, "constant folding for shl") else: internalError(g.config, n.info, "constant folding for shl")
of mShrI: of mShrI:
case skipTypes(n.typ, abstractRange).kind case skipTypes(n.typ, abstractRange).kind
@ -612,7 +619,7 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
of mLow: of mLow:
result = newIntNodeT(firstOrd(g.config, n.sons[1].typ), n, g) result = newIntNodeT(firstOrd(g.config, n.sons[1].typ), n, g)
of mHigh: of mHigh:
if skipTypes(n.sons[1].typ, abstractVar).kind notin if skipTypes(n.sons[1].typ, abstractVar+{tyUserTypeClassInst}).kind notin
{tySequence, tyString, tyCString, tyOpenArray, tyVarargs}: {tySequence, tyString, tyCString, tyOpenArray, tyVarargs}:
result = newIntNodeT(lastOrd(g.config, skipTypes(n[1].typ, abstractVar)), n, g) result = newIntNodeT(lastOrd(g.config, skipTypes(n[1].typ, abstractVar)), n, g)
else: else:

View file

@ -519,7 +519,9 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
localError(c.config, a.info, errWrongNumberOfVariables) localError(c.config, a.info, errWrongNumberOfVariables)
b = newNodeI(nkVarTuple, a.info) b = newNodeI(nkVarTuple, a.info)
newSons(b, length) newSons(b, length)
b.sons[length-2] = a.sons[length-2] # keep type desc for doc generator # keep type desc for doc generator
# NOTE: at the moment this is always ast.emptyNode, see parser.nim
b.sons[length-2] = a.sons[length-2]
b.sons[length-1] = def b.sons[length-1] = def
addToVarSection(c, result, n, b) addToVarSection(c, result, n, b)
elif tup.kind == tyTuple and def.kind in {nkPar, nkTupleConstr} and elif tup.kind == tyTuple and def.kind in {nkPar, nkTupleConstr} and
@ -558,7 +560,12 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
# keep documentation information: # keep documentation information:
b.comment = a.comment b.comment = a.comment
addSon(b, newSymNode(v)) addSon(b, newSymNode(v))
addSon(b, a.sons[length-2]) # keep type desc for doc generator # keep type desc for doc generator, but only if the user explicitly
# added it
if a.sons[length-2].kind != nkEmpty:
addSon(b, newNodeIT(nkType, a.info, typ))
else:
addSon(b, a.sons[length-2])
addSon(b, copyTree(def)) addSon(b, copyTree(def))
addToVarSection(c, result, n, b) addToVarSection(c, result, n, b)
else: else:

View file

@ -189,18 +189,19 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
c.hashTypeSym(t.sym) c.hashTypeSym(t.sym)
else: else:
c.hashSym(t.sym) c.hashSym(t.sym)
if sfAnon in t.sym.flags: if {sfAnon, sfGenSym} * t.sym.flags != {}:
# generated object names can be identical, so we need to # generated object names can be identical, so we need to
# disambiguate furthermore by hashing the field types and names: # disambiguate furthermore by hashing the field types and names:
# mild hack to prevent endless recursions (makes nimforum compile again): # mild hack to prevent endless recursions (makes nimforum compile again):
excl t.sym.flags, sfAnon let oldFlags = t.sym.flags
t.sym.flags = t.sym.flags - {sfAnon, sfGenSym}
let n = t.n let n = t.n
for i in 0 ..< n.len: for i in 0 ..< n.len:
assert n[i].kind == nkSym assert n[i].kind == nkSym
let s = n[i].sym let s = n[i].sym
c.hashSym s c.hashSym s
c.hashType s.typ, flags c.hashType s.typ, flags
incl t.sym.flags, sfAnon t.sym.flags = oldFlags
else: else:
c &= t.id c &= t.id
if t.len > 0 and t.sons[0] != nil: if t.len > 0 and t.sons[0] != nil:

View file

@ -615,7 +615,7 @@ proc firstOrd*(conf: ConfigRef; t: PType): BiggestInt =
else: else:
assert(t.n.sons[0].kind == nkSym) assert(t.n.sons[0].kind == nkSym)
result = t.n.sons[0].sym.position result = t.n.sons[0].sym.position
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred: of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred, tyUserTypeClassInst:
result = firstOrd(conf, lastSon(t)) result = firstOrd(conf, lastSon(t))
of tyOrdinal: of tyOrdinal:
if t.len > 0: result = firstOrd(conf, lastSon(t)) if t.len > 0: result = firstOrd(conf, lastSon(t))

View file

@ -1184,7 +1184,7 @@ proc request*(client: HttpClient | AsyncHttpClient, url: string,
## Connects to the hostname specified by the URL and performs a request ## Connects to the hostname specified by the URL and performs a request
## using the custom method string specified by ``httpMethod``. ## using the custom method string specified by ``httpMethod``.
## ##
## Connection will kept alive. Further requests on the same ``client`` to ## Connection will be kept alive. Further requests on the same ``client`` to
## the same hostname will not require a new connection to be made. The ## the same hostname will not require a new connection to be made. The
## connection can be closed by using the ``close`` procedure. ## connection can be closed by using the ``close`` procedure.
## ##

View file

@ -542,7 +542,9 @@ type
fgBlue, ## blue fgBlue, ## blue
fgMagenta, ## magenta fgMagenta, ## magenta
fgCyan, ## cyan fgCyan, ## cyan
fgWhite ## white fgWhite, ## white
fg8Bit, ## 256-color (not supported, see ``enableTrueColors`` instead.)
fgDefault ## default terminal foreground color
BackgroundColor* = enum ## terminal's background colors BackgroundColor* = enum ## terminal's background colors
bgBlack = 40, ## black bgBlack = 40, ## black
@ -552,28 +554,40 @@ type
bgBlue, ## blue bgBlue, ## blue
bgMagenta, ## magenta bgMagenta, ## magenta
bgCyan, ## cyan bgCyan, ## cyan
bgWhite ## white bgWhite, ## white
bg8Bit, ## 256-color (not supported, see ``enableTrueColors`` instead.)
bgDefault ## default terminal background color
{.deprecated: [TForegroundColor: ForegroundColor, {.deprecated: [TForegroundColor: ForegroundColor,
TBackgroundColor: BackgroundColor].} TBackgroundColor: BackgroundColor].}
when defined(windows):
var defaultForegroundColor, defaultBackgroundColor: int16 = 0xFFFF'i16 # Default to an invalid value 0xFFFF
proc setForegroundColor*(f: File, fg: ForegroundColor, bright=false) = proc setForegroundColor*(f: File, fg: ForegroundColor, bright=false) =
## Sets the terminal's foreground color. ## Sets the terminal's foreground color.
when defined(windows): when defined(windows):
let h = conHandle(f) let h = conHandle(f)
var old = getAttributes(h) and not FOREGROUND_RGB var old = getAttributes(h) and not FOREGROUND_RGB
if defaultForegroundColor == 0xFFFF'i16:
defaultForegroundColor = old
old = if bright: old or FOREGROUND_INTENSITY old = if bright: old or FOREGROUND_INTENSITY
else: old and not(FOREGROUND_INTENSITY) else: old and not(FOREGROUND_INTENSITY)
const lookup: array[ForegroundColor, int] = [ const lookup: array[ForegroundColor, int] = [
0, 0, # ForegroundColor enum with ordinal 30
(FOREGROUND_RED), (FOREGROUND_RED),
(FOREGROUND_GREEN), (FOREGROUND_GREEN),
(FOREGROUND_RED or FOREGROUND_GREEN), (FOREGROUND_RED or FOREGROUND_GREEN),
(FOREGROUND_BLUE), (FOREGROUND_BLUE),
(FOREGROUND_RED or FOREGROUND_BLUE), (FOREGROUND_RED or FOREGROUND_BLUE),
(FOREGROUND_BLUE or FOREGROUND_GREEN), (FOREGROUND_BLUE or FOREGROUND_GREEN),
(FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_RED)] (FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_RED),
discard setConsoleTextAttribute(h, toU16(old or lookup[fg])) 0, # fg8Bit not supported, see ``enableTrueColors`` instead.
0] # unused
if fg == fgDefault:
discard setConsoleTextAttribute(h, toU16(old or defaultForegroundColor))
else:
discard setConsoleTextAttribute(h, toU16(old or lookup[fg]))
else: else:
gFG = ord(fg) gFG = ord(fg)
if bright: inc(gFG, 60) if bright: inc(gFG, 60)
@ -584,18 +598,25 @@ proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
when defined(windows): when defined(windows):
let h = conHandle(f) let h = conHandle(f)
var old = getAttributes(h) and not BACKGROUND_RGB var old = getAttributes(h) and not BACKGROUND_RGB
if defaultBackgroundColor == 0xFFFF'i16:
defaultBackgroundColor = old
old = if bright: old or BACKGROUND_INTENSITY old = if bright: old or BACKGROUND_INTENSITY
else: old and not(BACKGROUND_INTENSITY) else: old and not(BACKGROUND_INTENSITY)
const lookup: array[BackgroundColor, int] = [ const lookup: array[BackgroundColor, int] = [
0, 0, # BackgroundColor enum with ordinal 40
(BACKGROUND_RED), (BACKGROUND_RED),
(BACKGROUND_GREEN), (BACKGROUND_GREEN),
(BACKGROUND_RED or BACKGROUND_GREEN), (BACKGROUND_RED or BACKGROUND_GREEN),
(BACKGROUND_BLUE), (BACKGROUND_BLUE),
(BACKGROUND_RED or BACKGROUND_BLUE), (BACKGROUND_RED or BACKGROUND_BLUE),
(BACKGROUND_BLUE or BACKGROUND_GREEN), (BACKGROUND_BLUE or BACKGROUND_GREEN),
(BACKGROUND_BLUE or BACKGROUND_GREEN or BACKGROUND_RED)] (BACKGROUND_BLUE or BACKGROUND_GREEN or BACKGROUND_RED),
discard setConsoleTextAttribute(h, toU16(old or lookup[bg])) 0, # bg8Bit not supported, see ``enableTrueColors`` instead.
0] # unused
if bg == bgDefault:
discard setConsoleTextAttribute(h, toU16(old or defaultBackgroundColor))
else:
discard setConsoleTextAttribute(h, toU16(old or lookup[bg]))
else: else:
gBG = ord(bg) gBG = ord(bg)
if bright: inc(gBG, 60) if bright: inc(gBG, 60)
@ -935,3 +956,6 @@ when not defined(testing) and isMainModule:
stdout.styledWrite(fgGreen, "green text") stdout.styledWrite(fgGreen, "green text")
echo "" echo ""
echo "ordinary text" echo "ordinary text"
stdout.styledWriteLine(fgRed, "red text ", styleBright, "bold red", fgDefault, " bold text")
stdout.styledWriteLine(bgYellow, "text in yellow bg", styleBright, " bold text in yellow bg", bgDefault, " bold text")
echo "ordinary text"

View file

@ -238,11 +238,11 @@ proc utcZoneInfoFromUtc(time: Time): ZonedTime {.tags: [], raises: [], benign .}
proc utcZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .} proc utcZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .}
proc localZoneInfoFromUtc(time: Time): ZonedTime {.tags: [], raises: [], benign .} proc localZoneInfoFromUtc(time: Time): ZonedTime {.tags: [], raises: [], benign .}
proc localZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .} proc localZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .}
proc initTime*(unix: int64, nanosecond: NanosecondRange): Time proc initTime*(unix: int64, nanosecond: NanosecondRange): Time
{.tags: [], raises: [], benign noSideEffect.} {.tags: [], raises: [], benign noSideEffect.}
proc initDuration*(nanoseconds, microseconds, milliseconds, proc initDuration*(nanoseconds, microseconds, milliseconds,
seconds, minutes, hours, days, weeks: int64 = 0): Duration seconds, minutes, hours, days, weeks: int64 = 0): Duration
{.tags: [], raises: [], benign noSideEffect.} {.tags: [], raises: [], benign noSideEffect.}
proc nanosecond*(time: Time): NanosecondRange = proc nanosecond*(time: Time): NanosecondRange =
@ -531,7 +531,7 @@ proc `$`*(dur: Duration): string =
let quantity = numParts[unit] let quantity = numParts[unit]
if quantity != 0.int64: if quantity != 0.int64:
parts.add(stringifyUnit(quantity, $unit)) parts.add(stringifyUnit(quantity, $unit))
result = humanizeParts(parts) result = humanizeParts(parts)
proc `+`*(a, b: Duration): Duration {.operator.} = proc `+`*(a, b: Duration): Duration {.operator.} =
@ -1243,23 +1243,23 @@ proc evaluateStaticInterval(interval: TimeInterval): Duration =
minutes = interval.minutes, minutes = interval.minutes,
hours = interval.hours) hours = interval.hours)
proc between*(startDt, endDt:DateTime): TimeInterval = proc between*(startDt, endDt: DateTime): TimeInterval =
## Evaluate difference between two dates in ``TimeInterval`` format, so, it ## Evaluate difference between two dates in ``TimeInterval`` format, so, it
## will be relative. ## will be relative.
## ##
## **Warning:** It's not recommended to use ``between`` for ``DateTime's`` in ## **Warning:** It's not recommended to use ``between`` for ``DateTime's`` in
## different ``TimeZone's``. ## different ``TimeZone's``.
## ``a + between(a, b) == b`` is only guaranteed when ``a`` and ``b`` are in UTC. ## ``a + between(a, b) == b`` is only guaranteed when ``a`` and ``b`` are in UTC.
runnableExamples: runnableExamples:
var a = initDateTime(year = 2018, month = Month(3), monthday = 25, var a = initDateTime(year = 2018, month = Month(3), monthday = 25,
hour = 0, minute = 59, second = 59, nanosecond = 1, hour = 0, minute = 59, second = 59, nanosecond = 1,
zone = utc()).local zone = utc()).local
var b = initDateTime(year = 2018, month = Month(3), monthday = 25, var b = initDateTime(year = 2018, month = Month(3), monthday = 25,
hour = 1, minute = 1, second = 1, nanosecond = 0, hour = 1, minute = 1, second = 1, nanosecond = 0,
zone = utc()).local zone = utc()).local
doAssert between(a, b) == initTimeInterval( doAssert between(a, b) == initTimeInterval(
nanoseconds=999, milliseconds=999, microseconds=999, seconds=1, minutes=1) nanoseconds=999, milliseconds=999, microseconds=999, seconds=1, minutes=1)
a = parse("2018-01-09T00:00:00+00:00", "yyyy-MM-dd'T'HH:mm:sszzz", utc()) a = parse("2018-01-09T00:00:00+00:00", "yyyy-MM-dd'T'HH:mm:sszzz", utc())
b = parse("2018-01-10T23:00:00-02:00", "yyyy-MM-dd'T'HH:mm:sszzz") b = parse("2018-01-10T23:00:00-02:00", "yyyy-MM-dd'T'HH:mm:sszzz")
doAssert between(a, b) == initTimeInterval(hours=1, days=2) doAssert between(a, b) == initTimeInterval(hours=1, days=2)
@ -1526,7 +1526,6 @@ proc formatToken(dt: DateTime, token: string, buf: var string) =
else: else:
raise newException(ValueError, "Invalid format string: " & token) raise newException(ValueError, "Invalid format string: " & token)
proc format*(dt: DateTime, f: string): string {.tags: [].}= proc format*(dt: DateTime, f: string): string {.tags: [].}=
## This procedure formats `dt` as specified by `f`. The following format ## This procedure formats `dt` as specified by `f`. The following format
## specifiers are available: ## specifiers are available:
@ -1601,18 +1600,14 @@ proc format*(dt: DateTime, f: string): string {.tags: [].}=
inc(i) inc(i)
formatToken(dt, currentF, result) formatToken(dt, currentF, result)
proc format*(time: Time, f: string, zone_info: proc(t: Time): DateTime): string {.tags: [].} = proc format*(time: Time, f: string, zone: Timezone = local()): string {.tags: [].} =
## converts a `Time` value to a string representation. It will use format from ## Converts a `Time` value to a string representation. It will use format from
## ``format(dt: DateTime, f: string)``. ## ``format(dt: DateTime, f: string)``.
runnableExamples: runnableExamples:
var dt = initDateTime(01, mJan, 1970, 00, 00, 00, local()) var dt = initDateTime(01, mJan, 1970, 00, 00, 00, utc())
var tm = dt.toTime() var tm = dt.toTime()
doAssert format(tm, "yyyy-MM-dd'T'HH:mm:ss", local) == "1970-01-01T00:00:00" doAssert format(tm, "yyyy-MM-dd'T'HH:mm:ss", utc()) == "1970-01-01T00:00:00"
dt = initDateTime(01, mJan, 1970, 00, 00, 00, utc()) time.inZone(zone).format(f)
tm = dt.toTime()
doAssert format(tm, "yyyy-MM-dd'T'HH:mm:ss", utc) == "1970-01-01T00:00:00"
zone_info(time).format(f)
proc `$`*(dt: DateTime): string {.tags: [], raises: [], benign.} = proc `$`*(dt: DateTime): string {.tags: [], raises: [], benign.} =
## Converts a `DateTime` object to a string representation. ## Converts a `DateTime` object to a string representation.
@ -1984,16 +1979,12 @@ proc countYearsAndDays*(daySpan: int): tuple[years: int, days: int] =
proc toTimeInterval*(time: Time): TimeInterval = proc toTimeInterval*(time: Time): TimeInterval =
## Converts a Time to a TimeInterval. ## Converts a Time to a TimeInterval.
## ##
## To be used when diffing times. ## To be used when diffing times. Consider using `between` instead.
runnableExamples: runnableExamples:
let a = fromUnix(10) let a = fromUnix(10)
let dt = initDateTime(01, mJan, 1970, 00, 00, 00, local()) let b = fromUnix(1_500_000_000)
doAssert a.toTimeInterval() == initTimeInterval( let ti = b.toTimeInterval() - a.toTimeInterval()
years=1970, days=1, seconds=10, hours=convert( doAssert a + ti == b
Seconds, Hours, -dt.utcOffset
)
)
var dt = time.local var dt = time.local
initTimeInterval(dt.nanosecond, 0, 0, dt.second, dt.minute, dt.hour, initTimeInterval(dt.nanosecond, 0, 0, dt.second, dt.minute, dt.hour,
dt.monthday, 0, dt.month.ord - 1, dt.year) dt.monthday, 0, dt.month.ord - 1, dt.year)
@ -2150,7 +2141,7 @@ proc timeToTimeInterval*(t: Time): TimeInterval {.deprecated.} =
t.toTimeInterval() t.toTimeInterval()
proc getDayOfWeek*(day, month, year: int): WeekDay {.tags: [], raises: [], benign, deprecated.} = proc getDayOfWeek*(day, month, year: int): WeekDay {.tags: [], raises: [], benign, deprecated.} =
## **Deprecated since v0.18.0:** use ## **Deprecated since v0.18.0:** use
## ``getDayOfWeek(monthday: MonthdayRange; month: Month; year: int)`` instead. ## ``getDayOfWeek(monthday: MonthdayRange; month: Month; year: int)`` instead.
getDayOfWeek(day, month.Month, year) getDayOfWeek(day, month.Month, year)

View file

@ -19,7 +19,7 @@ proc readVu64*(z: openArray[byte]; pResult: var uint64): int =
return 1 return 1
if z[0] <= 248: if z[0] <= 248:
if z.len < 2: return 0 if z.len < 2: return 0
pResult = (uint64 z[0] - 241) * 256 + uint64 z[1] + 240 pResult = (uint64 z[0] - 241) * 256 + z[1].uint64 + 240
return 2 return 2
if z.len < int(z[0]-246): return 0 if z.len < int(z[0]-246): return 0
if z[0] == 249: if z[0] == 249:
@ -135,6 +135,13 @@ when isMainModule:
if encodeZigzag(decodeZigzag(test)) != test: if encodeZigzag(decodeZigzag(test)) != test:
echo "Failure for ", test, " ", encodeZigzag(decodeZigzag(test)), " ", decodeZigzag(test) echo "Failure for ", test, " ", encodeZigzag(decodeZigzag(test)), " ", decodeZigzag(test)
for test in 0u64..300u64:
let wrLen = writeVu64(dest, test)
let rdLen = readVu64(dest, got)
assert wrLen == rdLen
if got != test:
echo "BUG! expected: ", test, " got: ", got, " z0: ", dest[0]
# check this also works for floats: # check this also works for floats:
for test in [0.0, 0.1, 2.0, +Inf, Nan, NegInf]: for test in [0.0, 0.1, 2.0, +Inf, Nan, NegInf]:
let t = cast[uint64](test) let t = cast[uint64](test)

58
tests/arithm/tnot.nim Normal file
View file

@ -0,0 +1,58 @@
discard """
output: '''
-5
-5
-5
-5
4
4
4
4
251
65531
4294967291
18446744073709551611
4
4
4
4
'''
"""
# Signed types
block:
const t0: int8 = not 4
const t1: int16 = not 4
const t2: int32 = not 4
const t3: int64 = not 4
const t4: int8 = not -5
const t5: int16 = not -5
const t6: int32 = not -5
const t7: int64 = not -5
echo t0
echo t1
echo t2
echo t3
echo t4
echo t5
echo t6
echo t7
# Unsigned types
block:
const t0: uint8 = not 4'u8
const t1: uint16 = not 4'u16
const t2: uint32 = not 4'u32
const t3: uint64 = not 4'u64
const t4: uint8 = not 251'u8
const t5: uint16 = not 65531'u16
const t6: uint32 = not 4294967291'u32
const t7: uint64 = not 18446744073709551611'u64
echo t0
echo t1
echo t2
echo t3
echo t4
echo t5
echo t6
echo t7

34
tests/arithm/tshl.nim Normal file
View file

@ -0,0 +1,34 @@
discard """
output: '''
0
0
1
1
0
0
0
1
'''
"""
# Signed types
block:
const t0: int8 = 1'i8 shl 8
const t1: int16 = 1'i16 shl 16
const t2: int32 = 1'i32 shl 32
const t3: int64 = 1'i64 shl 64
echo t0
echo t1
echo t2
echo t3
# Unsigned types
block:
const t0: uint8 = 1'u8 shl 8
const t1: uint16 = 1'u16 shl 16
const t2: uint32 = 1'u32 shl 32
const t3: uint64 = 1'u64 shl 64
echo t0
echo t1
echo t2
echo t3

View file

@ -0,0 +1,31 @@
# issue 7705, 7703, 7702
discard """
output: '''
z
e
'''
"""
type
Reversable*[T] = concept a
a[int] is T
a.high is int
a.len is int
a.low is int
proc get[T](s: Reversable[T], n: int): T =
s[n]
proc hi[T](s: Reversable[T]): int =
s.high
proc lo[T](s: Reversable[T]): int =
s.low
iterator reverse*[T](s: Reversable[T]): T =
assert hi(s) - lo(s) == len(s) - 1
for z in hi(s).countdown(lo(s)):
yield s.get(z)
for s in @["e", "z"].reverse:
echo s

33
tests/types/t7905.nim Normal file
View file

@ -0,0 +1,33 @@
discard """
output: '''
(member: "hello world")
(member: 123.456)
(member: "hello world", x: ...)
(member: 123.456, x: ...)
'''
"""
template foobar(arg: typed): untyped =
type
MyType = object
member: type(arg)
var myVar: MyType
myVar.member = arg
echo myVar
foobar("hello world")
foobar(123.456'f64)
template foobarRec(arg: typed): untyped =
type
MyType = object
member: type(arg)
x: ref MyType
var myVar: MyType
myVar.member = arg
echo myVar
foobarRec("hello world")
foobarRec(123.456'f64)