Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
commit
c68d52b69d
15 changed files with 248 additions and 52 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -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,27 +554,39 @@ 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),
|
||||||
|
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]))
|
discard setConsoleTextAttribute(h, toU16(old or lookup[fg]))
|
||||||
else:
|
else:
|
||||||
gFG = ord(fg)
|
gFG = ord(fg)
|
||||||
|
|
@ -584,17 +598,24 @@ 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),
|
||||||
|
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]))
|
discard setConsoleTextAttribute(h, toU16(old or lookup[bg]))
|
||||||
else:
|
else:
|
||||||
gBG = ord(bg)
|
gBG = ord(bg)
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -1243,7 +1243,7 @@ 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.
|
||||||
##
|
##
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
58
tests/arithm/tnot.nim
Normal 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
34
tests/arithm/tshl.nim
Normal 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
|
||||||
31
tests/concepts/treversable.nim
Normal file
31
tests/concepts/treversable.nim
Normal 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
33
tests/types/t7905.nim
Normal 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)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue