Merge branch 'devel' into new-ll

This commit is contained in:
Andreas Rumpf 2016-01-14 15:01:55 +01:00
commit 1124c61c49
13 changed files with 348 additions and 109 deletions

View file

@ -118,6 +118,14 @@ proc openArrayLoc(p: BProc, n: PNode): Rope =
result = "$1->data, $1->$2" % [a.rdLoc, lenField(p)] result = "$1->data, $1->$2" % [a.rdLoc, lenField(p)]
of tyArray, tyArrayConstr: of tyArray, tyArrayConstr:
result = "$1, $2" % [rdLoc(a), rope(lengthOrd(a.t))] result = "$1, $2" % [rdLoc(a), rope(lengthOrd(a.t))]
of tyPtr, tyRef:
case lastSon(a.t).kind
of tyString, tySequence:
result = "(*$1)->data, (*$1)->$2" % [a.rdLoc, lenField(p)]
of tyArray, tyArrayConstr:
result = "$1, $2" % [rdLoc(a), rope(lengthOrd(lastSon(a.t)))]
else:
internalError("openArrayLoc: " & typeToString(a.t))
else: internalError("openArrayLoc: " & typeToString(a.t)) else: internalError("openArrayLoc: " & typeToString(a.t))
proc genArgStringToCString(p: BProc, n: PNode): Rope {.inline.} = proc genArgStringToCString(p: BProc, n: PNode): Rope {.inline.} =

View file

@ -70,7 +70,7 @@ proc atomicTypeX(name: string; t: PType; info: TLineInfo): PNode =
proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode
proc mapTypeToBracket(name: string; t: PType; info: TLineInfo): PNode = proc mapTypeToBracket(name: string; t: PType; info: TLineInfo): PNode =
result = newNodeIT(nkBracketExpr, info, t) result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
result.add atomicTypeX(name, t, info) result.add atomicTypeX(name, t, info)
for i in 0 .. < t.len: for i in 0 .. < t.len:
if t.sons[i] == nil: if t.sons[i] == nil:
@ -92,19 +92,19 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
of tyStmt: result = atomicType("stmt") of tyStmt: result = atomicType("stmt")
of tyEmpty: result = atomicType"void" of tyEmpty: result = atomicType"void"
of tyArrayConstr, tyArray: of tyArrayConstr, tyArray:
result = newNodeIT(nkBracketExpr, info, t) result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
result.add atomicType("array") result.add atomicType("array")
result.add mapTypeToAst(t.sons[0], info) result.add mapTypeToAst(t.sons[0], info)
result.add mapTypeToAst(t.sons[1], info) result.add mapTypeToAst(t.sons[1], info)
of tyTypeDesc: of tyTypeDesc:
if t.base != nil: if t.base != nil:
result = newNodeIT(nkBracketExpr, info, t) result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
result.add atomicType("typeDesc") result.add atomicType("typeDesc")
result.add mapTypeToAst(t.base, info) result.add mapTypeToAst(t.base, info)
else: else:
result = atomicType"typeDesc" result = atomicType"typeDesc"
of tyGenericInvocation: of tyGenericInvocation:
result = newNodeIT(nkBracketExpr, info, t) result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
for i in 0 .. < t.len: for i in 0 .. < t.len:
result.add mapTypeToAst(t.sons[i], info) result.add mapTypeToAst(t.sons[i], info)
of tyGenericInst, tyGenericBody, tyOrdinal, tyUserTypeClassInst: of tyGenericInst, tyGenericBody, tyOrdinal, tyUserTypeClassInst:
@ -117,7 +117,7 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
of tyGenericParam, tyForward: result = atomicType(t.sym.name.s) of tyGenericParam, tyForward: result = atomicType(t.sym.name.s)
of tyObject: of tyObject:
if allowRecursion: if allowRecursion:
result = newNodeIT(nkObjectTy, info, t) result = newNodeIT(nkObjectTy, if t.n.isNil: info else: t.n.info, t)
if t.sons[0] == nil: if t.sons[0] == nil:
result.add ast.emptyNode result.add ast.emptyNode
else: else:
@ -126,7 +126,7 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
else: else:
result = atomicType(t.sym.name.s) result = atomicType(t.sym.name.s)
of tyEnum: of tyEnum:
result = newNodeIT(nkEnumTy, info, t) result = newNodeIT(nkEnumTy, if t.n.isNil: info else: t.n.info, t)
result.add copyTree(t.n) result.add copyTree(t.n)
of tyTuple: result = mapTypeToBracket("tuple", t, info) of tyTuple: result = mapTypeToBracket("tuple", t, info)
of tySet: result = mapTypeToBracket("set", t, info) of tySet: result = mapTypeToBracket("set", t, info)
@ -137,7 +137,7 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
of tyProc: result = mapTypeToBracket("proc", t, info) of tyProc: result = mapTypeToBracket("proc", t, info)
of tyOpenArray: result = mapTypeToBracket("openArray", t, info) of tyOpenArray: result = mapTypeToBracket("openArray", t, info)
of tyRange: of tyRange:
result = newNodeIT(nkBracketExpr, info, t) result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
result.add atomicType("range") result.add atomicType("range")
result.add t.n.sons[0].copyTree result.add t.n.sons[0].copyTree
result.add t.n.sons[1].copyTree result.add t.n.sons[1].copyTree
@ -174,7 +174,7 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
of tyNot: result = mapTypeToBracket("not", t, info) of tyNot: result = mapTypeToBracket("not", t, info)
of tyAnything: result = atomicType"anything" of tyAnything: result = atomicType"anything"
of tyStatic, tyFromExpr, tyFieldAccessor: of tyStatic, tyFromExpr, tyFieldAccessor:
result = newNodeIT(nkBracketExpr, info, t) result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
result.add atomicType("static") result.add atomicType("static")
if t.n != nil: if t.n != nil:
result.add t.n.copyTree result.add t.n.copyTree

View file

@ -102,8 +102,8 @@ doc.file = """<?xml version="1.0" encoding="utf-8" ?>
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/> <link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
<!-- Google fonts --> <!-- Google fonts -->
<link href='http://fonts.googleapis.com/css?family=Raleway:400,600,900' rel='stylesheet' type='text/css'> <link href='http://fonts.googleapis.com/css?family=Raleway:400,600,900' rel='stylesheet' type='text/css'/>
<link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'> <link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
<!-- CSS --> <!-- CSS -->
<title>$title</title> <title>$title</title>
@ -1246,7 +1246,7 @@ dt pre > span.Operator ~ span.Identifier, dt pre > span.Operator ~ span.Operator
<div class="row"> <div class="row">
<div class="twelve-columns footer"> <div class="twelve-columns footer">
<span class="nim-sprite"></span> <span class="nim-sprite"></span>
<br> <br/>
<small>Made with Nim. Generated: $date $time UTC</small> <small>Made with Nim. Generated: $date $time UTC</small>
</div> </div>
</div> </div>

View file

@ -1,4 +1,6 @@
import ospaths
mode = ScriptMode.Verbose mode = ScriptMode.Verbose
var id = 0 var id = 0
@ -10,4 +12,8 @@ exec "git clone https://github.com/nim-lang/nimble.git nimble" & $id
withDir "nimble" & $id & "/src": withDir "nimble" & $id & "/src":
exec "nim c nimble" exec "nim c nimble"
mkDir "bin/nimblepkg"
for file in listFiles("nimble" & $id & "/src/nimblepkg/"):
cpFile file, "bin/nimblepkg/" & file.extractFilename
mvFile "nimble" & $id & "/src/nimble".toExe, "bin/nimble".toExe mvFile "nimble" & $id & "/src/nimble".toExe, "bin/nimble".toExe

View file

@ -534,7 +534,7 @@ proc generateDocumentationJumps(docs: IndexedDocs): string =
for title in titles: for title in titles:
chunks.add("<a href=\"" & title.link & "\">" & title.keyword & "</a>") chunks.add("<a href=\"" & title.link & "\">" & title.keyword & "</a>")
result.add(chunks.join(", ") & ".<br>") result.add(chunks.join(", ") & ".<br/>")
proc generateModuleJumps(modules: seq[string]): string = proc generateModuleJumps(modules: seq[string]): string =
## Returns a plain list of hyperlinks to the list of modules. ## Returns a plain list of hyperlinks to the list of modules.
@ -544,7 +544,7 @@ proc generateModuleJumps(modules: seq[string]): string =
for name in modules: for name in modules:
chunks.add("<a href=\"" & name & ".html\">" & name & "</a>") chunks.add("<a href=\"" & name & ".html\">" & name & "</a>")
result.add(chunks.join(", ") & ".<br>") result.add(chunks.join(", ") & ".<br/>")
proc readIndexDir(dir: string): proc readIndexDir(dir: string):
tuple[modules: seq[string], symbols: seq[IndexEntry], docs: IndexedDocs] = tuple[modules: seq[string], symbols: seq[IndexEntry], docs: IndexedDocs] =

View file

@ -7,7 +7,9 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
## Common datatypes and definitions for all db_*.nim modules. ## Common datatypes and definitions for all ``db_*.nim`` (
## `db_mysql <db_mysql.html>`_, `db_postgres <db_postgres.html>`_,
## and `db_sqlite <db_sqlite.html>`_) modules.
type type
DbError* = object of IOError ## exception that is raised if a database error occurs DbError* = object of IOError ## exception that is raised if a database error occurs

View file

@ -28,7 +28,10 @@ type
BaseLexer* = object of RootObj ## the base lexer. Inherit your lexer from BaseLexer* = object of RootObj ## the base lexer. Inherit your lexer from
## this object. ## this object.
bufpos*: int ## the current position within the buffer bufpos*: int ## the current position within the buffer
buf*: cstring ## the buffer itself when defined(js): ## the buffer itself
buf*: string
else:
buf*: cstring
bufLen*: int ## length of buffer in characters bufLen*: int ## length of buffer in characters
input: Stream ## the input stream input: Stream ## the input stream
lineNumber*: int ## the current line number lineNumber*: int ## the current line number
@ -43,7 +46,8 @@ const
proc close*(L: var BaseLexer) = proc close*(L: var BaseLexer) =
## closes the base lexer. This closes `L`'s associated stream too. ## closes the base lexer. This closes `L`'s associated stream too.
dealloc(L.buf) when not defined(js):
dealloc(L.buf)
close(L.input) close(L.input)
proc fillBuffer(L: var BaseLexer) = proc fillBuffer(L: var BaseLexer) =
@ -58,8 +62,11 @@ proc fillBuffer(L: var BaseLexer) =
toCopy = L.bufLen - L.sentinel - 1 toCopy = L.bufLen - L.sentinel - 1
assert(toCopy >= 0) assert(toCopy >= 0)
if toCopy > 0: if toCopy > 0:
moveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize) when defined(js):
# "moveMem" handles overlapping regions for i in 0 ..< toCopy: L.buf[i] = L.buf[L.sentinel + 1 + i]
else:
# "moveMem" handles overlapping regions
moveMem(L.buf, addr L.buf[L.sentinel + 1], toCopy * chrSize)
charsRead = readData(L.input, addr(L.buf[toCopy]), charsRead = readData(L.input, addr(L.buf[toCopy]),
(L.sentinel + 1) * chrSize) div chrSize (L.sentinel + 1) * chrSize) div chrSize
s = toCopy + charsRead s = toCopy + charsRead
@ -81,7 +88,10 @@ proc fillBuffer(L: var BaseLexer) =
# double the buffer's size and try again: # double the buffer's size and try again:
oldBufLen = L.bufLen oldBufLen = L.bufLen
L.bufLen = L.bufLen * 2 L.bufLen = L.bufLen * 2
L.buf = cast[cstring](realloc(L.buf, L.bufLen * chrSize)) when defined(js):
L.buf.setLen(L.bufLen)
else:
L.buf = cast[cstring](realloc(L.buf, L.bufLen * chrSize))
assert(L.bufLen - oldBufLen == oldBufLen) assert(L.bufLen - oldBufLen == oldBufLen)
charsRead = readData(L.input, addr(L.buf[oldBufLen]), charsRead = readData(L.input, addr(L.buf[oldBufLen]),
oldBufLen * chrSize) div chrSize oldBufLen * chrSize) div chrSize
@ -139,7 +149,10 @@ proc open*(L: var BaseLexer, input: Stream, bufLen: int = 8192;
L.bufpos = 0 L.bufpos = 0
L.bufLen = bufLen L.bufLen = bufLen
L.refillChars = refillChars L.refillChars = refillChars
L.buf = cast[cstring](alloc(bufLen * chrSize)) when defined(js):
L.buf = newString(bufLen)
else:
L.buf = cast[cstring](alloc(bufLen * chrSize))
L.sentinel = bufLen - 1 L.sentinel = bufLen - 1
L.lineStart = 0 L.lineStart = 0
L.lineNumber = 1 # lines start at 1 L.lineNumber = 1 # lines start at 1

View file

@ -886,7 +886,7 @@ elif not defined(useNimRtl):
discard write(data.pErrorPipe[writeIdx], addr error, sizeof(error)) discard write(data.pErrorPipe[writeIdx], addr error, sizeof(error))
exitnow(1) exitnow(1)
when defined(macosx) or defined(freebsd) or defined(netbsd): when defined(macosx) or defined(freebsd) or defined(netbsd) or defined(android):
var environ {.importc.}: cstringArray var environ {.importc.}: cstringArray
proc startProcessAfterFork(data: ptr StartProcessData) = proc startProcessAfterFork(data: ptr StartProcessData) =
@ -916,7 +916,7 @@ elif not defined(useNimRtl):
discard fcntl(data.pErrorPipe[writeIdx], F_SETFD, FD_CLOEXEC) discard fcntl(data.pErrorPipe[writeIdx], F_SETFD, FD_CLOEXEC)
if data.optionPoUsePath: if data.optionPoUsePath:
when defined(macosx) or defined(freebsd) or defined(netbsd): when defined(macosx) or defined(freebsd) or defined(netbsd) or defined(android):
# MacOSX doesn't have execvpe, so we need workaround. # MacOSX doesn't have execvpe, so we need workaround.
# On MacOSX we can arrive here only from fork, so this is safe: # On MacOSX we can arrive here only from fork, so this is safe:
environ = data.sysEnv environ = data.sysEnv

View file

@ -29,7 +29,7 @@
## echo "epochTime() float value: ", epochTime() ## echo "epochTime() float value: ", epochTime()
## echo "getTime() float value: ", toSeconds(getTime()) ## echo "getTime() float value: ", toSeconds(getTime())
## echo "cpuTime() float value: ", cpuTime() ## echo "cpuTime() float value: ", cpuTime()
## echo "An hour from now : ", getLocalTime(getTime()) + initInterval(0,0,0,1) ## echo "An hour from now : ", getLocalTime(getTime()) + 1.hours
## echo "An hour from (UTC) now: ", getGmTime(getTime()) + initInterval(0,0,0,1) ## echo "An hour from (UTC) now: ", getGmTime(getTime()) + initInterval(0,0,0,1)
{.push debugger:off.} # the user does not want to trace a part {.push debugger:off.} # the user does not want to trace a part
@ -171,11 +171,6 @@ type
{.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time, {.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time,
TTimeInterval: TimeInterval, TTimeInfo: TimeInfo].} TTimeInterval: TimeInterval, TTimeInfo: TimeInfo].}
proc miliseconds*(t: TimeInterval): int {.deprecated.} = t.milliseconds
proc `miliseconds=`*(t:var TimeInterval, milliseconds: int) {.deprecated.} =
t.milliseconds = milliseconds
proc getTime*(): Time {.tags: [TimeEffect], benign.} proc getTime*(): Time {.tags: [TimeEffect], benign.}
## gets the current calendar time as a UNIX epoch value (number of seconds ## gets the current calendar time as a UNIX epoch value (number of seconds
## elapsed since 1970) with integer precission. Use epochTime for higher ## elapsed since 1970) with integer precission. Use epochTime for higher
@ -245,13 +240,59 @@ proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.}
proc initInterval*(milliseconds, seconds, minutes, hours, days, months, proc initInterval*(milliseconds, seconds, minutes, hours, days, months,
years: int = 0): TimeInterval = years: int = 0): TimeInterval =
## creates a new ``TimeInterval``. ## creates a new ``TimeInterval``.
result.milliseconds = milliseconds ##
result.seconds = seconds ## You can also use the convenience procedures called ``milliseconds``,
result.minutes = minutes ## ``seconds``, ``minutes``, ``hours``, ``days``, ``months``, and ``years``.
result.hours = hours ##
result.days = days ## Example:
result.months = months ##
result.years = years ## .. code-block:: nim
##
## let day = initInterval(hours=24)
## let tomorrow = getTime() + day
## echo(tomorrow)
var carryO = 0
result.milliseconds = `mod`(milliseconds, 1000)
carryO = `div`(milliseconds, 1000)
result.seconds = `mod`(carryO + seconds, 60)
carryO = `div`(seconds, 60)
result.minutes = `mod`(carryO + minutes, 60)
carryO = `div`(minutes, 60)
result.hours = `mod`(carryO + hours, 24)
carryO = `div`(hours, 24)
result.days = carryO + days
carryO = 0
result.months = `mod`(months, 12)
carryO = `div`(months, 12)
result.years = carryO + years
proc `+`*(ti1, ti2: TimeInterval): TimeInterval =
## Adds two ``TimeInterval`` objects together.
var carryO = 0
result.milliseconds = `mod`(ti1.milliseconds + ti2.milliseconds, 1000)
carryO = `div`(ti1.milliseconds + ti2.milliseconds, 1000)
result.seconds = `mod`(carryO + ti1.seconds + ti2.seconds, 60)
carryO = `div`(ti1.seconds + ti2.seconds, 60)
result.minutes = `mod`(carryO + ti1.minutes + ti2.minutes, 60)
carryO = `div`(ti1.minutes + ti2.minutes, 60)
result.hours = `mod`(carryO + ti1.hours + ti2.hours, 24)
carryO = `div`(ti1.hours + ti2.hours, 24)
result.days = carryO + ti1.days + ti2.days
carryO = 0
result.months = `mod`(ti1.months + ti2.months, 12)
carryO = `div`(ti1.months + ti2.months, 12)
result.years = carryO + ti1.years + ti2.years
proc `-`*(ti1, ti2: TimeInterval): TimeInterval =
## Subtracts TimeInterval ``ti1`` from ``ti2``.
result = ti1
result.milliseconds -= ti2.milliseconds
result.seconds -= ti2.seconds
result.minutes -= ti2.minutes
result.hours -= ti2.hours
result.days -= ti2.days
result.months -= ti2.months
result.years -= ti2.years
proc isLeapYear*(year: int): bool = proc isLeapYear*(year: int): bool =
## returns true if ``year`` is a leap year ## returns true if ``year`` is a leap year
@ -288,13 +329,22 @@ proc toSeconds(a: TimeInfo, interval: TimeInterval): float =
newinterv.months += interval.years * 12 newinterv.months += interval.years * 12
var curMonth = anew.month var curMonth = anew.month
for mth in 1 .. newinterv.months: if newinterv.months < 0: # subtracting
result += float(getDaysInMonth(curMonth, anew.year) * 24 * 60 * 60) for mth in countDown(-1 * newinterv.months, 1):
if curMonth == mDec: result -= float(getDaysInMonth(curMonth, anew.year) * 24 * 60 * 60)
curMonth = mJan if curMonth == mJan:
anew.year.inc() curMonth = mDec
else: anew.year.dec()
curMonth.inc() else:
curMonth.dec()
else: # adding
for mth in 1 .. newinterv.months:
result += float(getDaysInMonth(curMonth, anew.year) * 24 * 60 * 60)
if curMonth == mDec:
curMonth = mJan
anew.year.inc()
else:
curMonth.inc()
result += float(newinterv.days * 24 * 60 * 60) result += float(newinterv.days * 24 * 60 * 60)
result += float(newinterv.hours * 60 * 60) result += float(newinterv.hours * 60 * 60)
result += float(newinterv.minutes * 60) result += float(newinterv.minutes * 60)
@ -302,28 +352,39 @@ proc toSeconds(a: TimeInfo, interval: TimeInterval): float =
result += newinterv.milliseconds / 1000 result += newinterv.milliseconds / 1000
proc `+`*(a: TimeInfo, interval: TimeInterval): TimeInfo = proc `+`*(a: TimeInfo, interval: TimeInterval): TimeInfo =
## adds ``interval`` time. ## adds ``interval`` time from TimeInfo ``a``.
## ##
## **Note:** This has been only briefly tested and it may not be ## **Note:** This has been only briefly tested and it may not be
## very accurate. ## very accurate.
let t = toSeconds(timeInfoToTime(a)) let t = toSeconds(timeInfoToTime(a))
let secs = toSeconds(a, interval) let secs = toSeconds(a, interval)
#if a.tzname == "UTC":
# result = getGMTime(fromSeconds(t + secs))
#else:
result = getLocalTime(fromSeconds(t + secs)) result = getLocalTime(fromSeconds(t + secs))
proc `-`*(a: TimeInfo, interval: TimeInterval): TimeInfo = proc `-`*(a: TimeInfo, interval: TimeInterval): TimeInfo =
## subtracts ``interval`` time. ## subtracts ``interval`` time from TimeInfo ``a``.
## ##
## **Note:** This has been only briefly tested, it is inaccurate especially ## **Note:** This has been only briefly tested, it is inaccurate especially
## when you subtract so much that you reach the Julian calendar. ## when you subtract so much that you reach the Julian calendar.
let t = toSeconds(timeInfoToTime(a)) let t = toSeconds(timeInfoToTime(a))
let secs = toSeconds(a, interval) var intval: TimeInterval
#if a.tzname == "UTC": intval.milliseconds = - interval.milliseconds
# result = getGMTime(fromSeconds(t - secs)) intval.seconds = - interval.seconds
#else: intval.minutes = - interval.minutes
result = getLocalTime(fromSeconds(t - secs)) intval.hours = - interval.hours
intval.days = - interval.days
intval.months = - interval.months
intval.years = - interval.years
let secs = toSeconds(a, intval)
result = getLocalTime(fromSeconds(t + secs))
proc miliseconds*(t: TimeInterval): int {.deprecated.} = t.milliseconds
proc `miliseconds=`*(t: var TimeInterval, milliseconds: int) {.deprecated.} =
## An alias for a misspelled field in ``TimeInterval``.
##
## **Warning:** This should not be used! It will be removed in the next
## version.
t.milliseconds = milliseconds
when not defined(JS): when not defined(JS):
proc epochTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].} proc epochTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].}
@ -603,6 +664,69 @@ proc `$`*(m: Month): string =
"November", "December"] "November", "December"]
return lookup[m] return lookup[m]
proc milliseconds*(ms: int): TimeInterval {.inline.} =
## TimeInterval of `ms` milliseconds
##
## Note: not all time functions have millisecond resolution
initInterval(`mod`(ms,1000), `div`(ms,1000))
proc seconds*(s: int): TimeInterval {.inline.} =
## TimeInterval of `s` seconds
##
## ``echo getTime() + 5.second``
initInterval(0,`mod`(s,60), `div`(s,60))
proc minutes*(m: int): TimeInterval {.inline.} =
## TimeInterval of `m` minutes
##
## ``echo getTime() + 5.minutes``
initInterval(0,0,`mod`(m,60), `div`(m,60))
proc hours*(h: int): TimeInterval {.inline.} =
## TimeInterval of `h` hours
##
## ``echo getTime() + 2.hours``
initInterval(0,0,0,`mod`(h,24),`div`(h,24))
proc days*(d: int): TimeInterval {.inline.} =
## TimeInterval of `d` days
##
## ``echo getTime() + 2.days``
initInterval(0,0,0,0,d)
proc months*(m: int): TimeInterval {.inline.} =
## TimeInterval of `m` months
##
## ``echo getTime() + 2.months``
initInterval(0,0,0,0,0,`mod`(m,12),`div`(m,12))
proc years*(y: int): TimeInterval {.inline.} =
## TimeInterval of `y` years
##
## ``echo getTime() + 2.years``
initInterval(0,0,0,0,0,0,y)
proc `+=`*(t: var Time, ti: TimeInterval) =
## modifies `t` by adding the interval `ti`
t = timeInfoToTime(getLocalTime(t) + ti)
proc `+`*(t: Time, ti: TimeInterval): Time =
## adds the interval `ti` to Time `t`
## by converting to localTime, adding the interval, and converting back
##
## ``echo getTime() + 1.day``
result = timeInfoToTime(getLocalTime(t) + ti)
proc `-=`*(t: var Time, ti: TimeInterval) =
## modifies `t` by subtracting the interval `ti`
t = timeInfoToTime(getLocalTime(t) - ti)
proc `-`*(t: Time, ti: TimeInterval): Time =
## adds the interval `ti` to Time `t`
##
## ``echo getTime() - 1.day``
result = timeInfoToTime(getLocalTime(t) - ti)
proc formatToken(info: TimeInfo, token: string, buf: var string) = proc formatToken(info: TimeInfo, token: string, buf: var string) =
## Helper of the format proc to parse individual tokens. ## Helper of the format proc to parse individual tokens.
## ##

View file

@ -1,6 +1,14 @@
# Nim Compiler # Nim Compiler
[![Join the chat at https://gitter.im/nim-lang/Nim](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/nim-lang/Nim?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Join the Chat at irc.freenode.net#nim](https://img.shields.io/badge/IRC-join_chat_in_%23nim-blue.svg)](https://webchat.freenode.net/?channels=nim)
[![Get help](https://img.shields.io/badge/Forum-get%20help-4eb899.svg)](http://forum.nim-lang.org)
[![Stackoverflow](https://img.shields.io/badge/stackoverflow-use_%23nim_tag-yellow.svg)](http://stackoverflow.com/questions/tagged/nim?sort=newest&pageSize=15)
[![Follow @nim_lang!](https://img.shields.io/twitter/follow/nim_lang.svg?style=social)](https://twitter.com/nim_lang)
[![Travis](https://img.shields.io/travis/nim-lang/Nim.svg)](https://travis-ci.org/nim-lang/Nim)
[![Contribute to Nim via Gratipay!](https://img.shields.io/gratipay/team/nim.svg)](https://gratipay.com/nim/)
[![Bountysource](https://img.shields.io/bountysource/team/nim/activity.svg)](https://www.bountysource.com/teams/nim)
This repo contains the Nim compiler, Nim's stdlib, tools and This repo contains the Nim compiler, Nim's stdlib, tools and

View file

@ -0,0 +1,54 @@
discard """
file: "tptrarrayderef.nim"
output: "OK"
"""
var
arr = [1,2,3]
arrp = addr(arr)
sss = @[4,5,6,7]
sssp = addr(sss)
ra = new(array[3, int])
raa = [11,12,13]
#bug #3586
proc mutate[T](arr:openarray[T], brr: openArray[T]) =
for i in 0..arr.len-1:
doAssert(arr[i] == brr[i])
mutate(arr, arr)
#bug #2240
proc f(a: openarray[int], b: openArray[int]) =
for i in 0..a.len-1:
doAssert(a[i] == b[i])
var a = [7,8,9]
var p = addr a
f(p[], a)
f(sssp[], sss)
ra[0] = 11
ra[1] = 12
ra[2] = 13
f(ra[], raa)
#bug #2240b
proc fillBuffer(buf: var openarray[char]) =
for i in 0..buf.len-1:
buf[i] = chr(i)
proc fillSeqBuffer(b: ref seq[char]) =
fillBuffer(b[])
proc getFilledBuffer(sz: int): ref seq[char] =
let s : ref seq[char] = new(seq[char])
s[] = newSeq[char](sz)
fillBuffer(s[])
return s
let aa = getFilledBuffer(3)
for i in 0..aa[].len-1:
doAssert(aa[i] == chr(i))
echo "OK"

View file

@ -6,89 +6,88 @@ discard """
import import
times, strutils times, strutils
assert( $getTime() == getLocalTime(getTime()).format("ddd MMM dd HH:mm:ss yyyy"))
# $ date --date='@2147483647' # $ date --date='@2147483647'
# Tue 19 Jan 03:14:07 GMT 2038 # Tue 19 Jan 03:14:07 GMT 2038
var t = getGMTime(fromSeconds(2147483647)) var t = getGMTime(fromSeconds(2147483647))
assert t.format("ddd dd MMM hh:mm:ss ZZZ yyyy") == "Tue 19 Jan 03:14:07 UTC 2038" doAssert t.format("ddd dd MMM hh:mm:ss ZZZ yyyy") == "Tue 19 Jan 03:14:07 UTC 2038"
assert t.format("ddd ddMMMhh:mm:ssZZZyyyy") == "Tue 19Jan03:14:07UTC2038" doAssert t.format("ddd ddMMMhh:mm:ssZZZyyyy") == "Tue 19Jan03:14:07UTC2038"
assert t.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & doAssert t.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" &
" ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") ==
"19 19 Tue Tuesday 3 03 3 03 14 14 1 01 Jan January 7 07 A AM 8 38 038 2038 02038 0 00 00:00 UTC" "19 19 Tue Tuesday 3 03 3 03 14 14 1 01 Jan January 7 07 A AM 8 38 038 2038 02038 0 00 00:00 UTC"
assert t.format("yyyyMMddhhmmss") == "20380119031407" doAssert t.format("yyyyMMddhhmmss") == "20380119031407"
var t2 = getGMTime(fromSeconds(160070789)) # Mon 27 Jan 16:06:29 GMT 1975 var t2 = getGMTime(fromSeconds(160070789)) # Mon 27 Jan 16:06:29 GMT 1975
assert t2.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & doAssert t2.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" &
" ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") ==
"27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 0 00 00:00 UTC" "27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 0 00 00:00 UTC"
when not defined(JS): when not defined(JS):
when sizeof(Time) == 8: when sizeof(Time) == 8:
var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143
assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & doAssert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" &
" ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") ==
"7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC" "7 07 Fri Friday 6 06 18 18 20 20 6 06 Jun June 45 45 P PM 3 43 143 0143 30143 0 00 00:00 UTC"
assert t3.format(":,[]()-/") == ":,[]()-/" doAssert t3.format(":,[]()-/") == ":,[]()-/"
var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997 var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997
assert t4.format("M MM MMM MMMM") == "10 10 Oct October" doAssert t4.format("M MM MMM MMMM") == "10 10 Oct October"
# Interval tests # Interval tests
assert((t4 - initInterval(years = 2)).format("yyyy") == "1995") doAssert((t4 - initInterval(years = 2)).format("yyyy") == "1995")
assert((t4 - initInterval(years = 7, minutes = 34, seconds = 24)).format("yyyy mm ss") == "1990 24 10") doAssert((t4 - initInterval(years = 7, minutes = 34, seconds = 24)).format("yyyy mm ss") == "1990 24 10")
var s = "Tuesday at 09:04am on Dec 15, 2015" var s = "Tuesday at 09:04am on Dec 15, 2015"
var f = "dddd at hh:mmtt on MMM d, yyyy" var f = "dddd at hh:mmtt on MMM d, yyyy"
assert($s.parse(f) == "Tue Dec 15 09:04:00 2015") doAssert($s.parse(f) == "Tue Dec 15 09:04:00 2015")
# ANSIC = "Mon Jan _2 15:04:05 2006" # ANSIC = "Mon Jan _2 15:04:05 2006"
s = "Thu Jan 12 15:04:05 2006" s = "Thu Jan 12 15:04:05 2006"
f = "ddd MMM dd HH:mm:ss yyyy" f = "ddd MMM dd HH:mm:ss yyyy"
assert($s.parse(f) == "Thu Jan 12 15:04:05 2006") doAssert($s.parse(f) == "Thu Jan 12 15:04:05 2006")
# UnixDate = "Mon Jan _2 15:04:05 MST 2006" # UnixDate = "Mon Jan _2 15:04:05 MST 2006"
s = "Thu Jan 12 15:04:05 MST 2006" s = "Thu Jan 12 15:04:05 MST 2006"
f = "ddd MMM dd HH:mm:ss ZZZ yyyy" f = "ddd MMM dd HH:mm:ss ZZZ yyyy"
assert($s.parse(f) == "Thu Jan 12 15:04:05 2006") doAssert($s.parse(f) == "Thu Jan 12 15:04:05 2006")
# RubyDate = "Mon Jan 02 15:04:05 -0700 2006" # RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
s = "Thu Jan 12 15:04:05 -07:00 2006" s = "Thu Jan 12 15:04:05 -07:00 2006"
f = "ddd MMM dd HH:mm:ss zzz yyyy" f = "ddd MMM dd HH:mm:ss zzz yyyy"
assert($s.parse(f) == "Thu Jan 12 15:04:05 2006") doAssert($s.parse(f) == "Thu Jan 12 15:04:05 2006")
# RFC822 = "02 Jan 06 15:04 MST" # RFC822 = "02 Jan 06 15:04 MST"
s = "12 Jan 16 15:04 MST" s = "12 Jan 16 15:04 MST"
f = "dd MMM yy HH:mm ZZZ" f = "dd MMM yy HH:mm ZZZ"
assert($s.parse(f) == "Tue Jan 12 15:04:00 2016") doAssert($s.parse(f) == "Tue Jan 12 15:04:00 2016")
# RFC822Z = "02 Jan 06 15:04 -0700" # RFC822 with numeric zone # RFC822Z = "02 Jan 06 15:04 -0700" # RFC822 with numeric zone
s = "12 Jan 16 15:04 -07:00" s = "12 Jan 16 15:04 -07:00"
f = "dd MMM yy HH:mm zzz" f = "dd MMM yy HH:mm zzz"
assert($s.parse(f) == "Tue Jan 12 15:04:00 2016") doAssert($s.parse(f) == "Tue Jan 12 15:04:00 2016")
# RFC850 = "Monday, 02-Jan-06 15:04:05 MST" # RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
s = "Monday, 12-Jan-06 15:04:05 MST" s = "Monday, 12-Jan-06 15:04:05 MST"
f = "dddd, dd-MMM-yy HH:mm:ss ZZZ" f = "dddd, dd-MMM-yy HH:mm:ss ZZZ"
assert($s.parse(f) == "Thu Jan 12 15:04:05 2006") doAssert($s.parse(f) == "Thu Jan 12 15:04:05 2006")
# RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" # RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
s = "Thu, 12 Jan 2006 15:04:05 MST" s = "Thu, 12 Jan 2006 15:04:05 MST"
f = "ddd, dd MMM yyyy HH:mm:ss ZZZ" f = "ddd, dd MMM yyyy HH:mm:ss ZZZ"
assert($s.parse(f) == "Thu Jan 12 15:04:05 2006") doAssert($s.parse(f) == "Thu Jan 12 15:04:05 2006")
# RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" # RFC1123 with numeric zone # RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" # RFC1123 with numeric zone
s = "Thu, 12 Jan 2006 15:04:05 -07:00" s = "Thu, 12 Jan 2006 15:04:05 -07:00"
f = "ddd, dd MMM yyyy HH:mm:ss zzz" f = "ddd, dd MMM yyyy HH:mm:ss zzz"
assert($s.parse(f) == "Thu Jan 12 15:04:05 2006") doAssert($s.parse(f) == "Thu Jan 12 15:04:05 2006")
# RFC3339 = "2006-01-02T15:04:05Z07:00" # RFC3339 = "2006-01-02T15:04:05Z07:00"
s = "2006-01-12T15:04:05Z-07:00" s = "2006-01-12T15:04:05Z-07:00"
f = "yyyy-MM-ddTHH:mm:ssZzzz" f = "yyyy-MM-ddTHH:mm:ssZzzz"
assert($s.parse(f) == "Thu Jan 12 15:04:05 2006") doAssert($s.parse(f) == "Thu Jan 12 15:04:05 2006")
f = "yyyy-MM-dd'T'HH:mm:ss'Z'zzz" f = "yyyy-MM-dd'T'HH:mm:ss'Z'zzz"
assert($s.parse(f) == "Thu Jan 12 15:04:05 2006") doAssert($s.parse(f) == "Thu Jan 12 15:04:05 2006")
# RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" # RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
s = "2006-01-12T15:04:05.999999999Z-07:00" s = "2006-01-12T15:04:05.999999999Z-07:00"
f = "yyyy-MM-ddTHH:mm:ss.999999999Zzzz" f = "yyyy-MM-ddTHH:mm:ss.999999999Zzzz"
assert($s.parse(f) == "Thu Jan 12 15:04:05 2006") doAssert($s.parse(f) == "Thu Jan 12 15:04:05 2006")
# Kitchen = "3:04PM" # Kitchen = "3:04PM"
s = "3:04PM" s = "3:04PM"
f = "h:mmtt" f = "h:mmtt"
assert "15:04:00" in $s.parse(f) doAssert "15:04:00" in $s.parse(f)
#when not defined(testing): #when not defined(testing):
# echo "Kitchen: " & $s.parse(f) # echo "Kitchen: " & $s.parse(f)
# var ti = timeToTimeInfo(getTime()) # var ti = timeToTimeInfo(getTime())
@ -97,29 +96,54 @@ assert "15:04:00" in $s.parse(f)
# echo "Todays date after decoding to interval: ", tint # echo "Todays date after decoding to interval: ", tint
# checking dayOfWeek matches known days # checking dayOfWeek matches known days
assert getDayOfWeek(21, 9, 1900) == dFri doAssert getDayOfWeek(21, 9, 1900) == dFri
assert getDayOfWeek(1, 1, 1970) == dThu doAssert getDayOfWeek(1, 1, 1970) == dThu
assert getDayOfWeek(21, 9, 1970) == dMon doAssert getDayOfWeek(21, 9, 1970) == dMon
assert getDayOfWeek(1, 1, 2000) == dSat doAssert getDayOfWeek(1, 1, 2000) == dSat
assert getDayOfWeek(1, 1, 2021) == dFri doAssert getDayOfWeek(1, 1, 2021) == dFri
# Julian tests # Julian tests
assert getDayOfWeekJulian(21, 9, 1900) == dFri doAssert getDayOfWeekJulian(21, 9, 1900) == dFri
assert getDayOfWeekJulian(21, 9, 1970) == dMon doAssert getDayOfWeekJulian(21, 9, 1970) == dMon
assert getDayOfWeekJulian(1, 1, 2000) == dSat doAssert getDayOfWeekJulian(1, 1, 2000) == dSat
assert getDayOfWeekJulian(1, 1, 2021) == dFri doAssert getDayOfWeekJulian(1, 1, 2021) == dFri
# toSeconds tests with GM and Local timezones # toSeconds tests with GM and Local timezones
#var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997 #var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997
var t4L = getLocalTime(fromSeconds(876124714)) var t4L = getLocalTime(fromSeconds(876124714))
assert toSeconds(timeInfoToTime(t4L)) == 876124714 # fromSeconds is effectively "localTime" doAssert toSeconds(timeInfoToTime(t4L)) == 876124714 # fromSeconds is effectively "localTime"
assert toSeconds(timeInfoToTime(t4L)) + t4L.timezone.float == toSeconds(timeInfoToTime(t4)) doAssert toSeconds(timeInfoToTime(t4L)) + t4L.timezone.float == toSeconds(timeInfoToTime(t4))
# adding intervals # adding intervals
var var
a1L = toSeconds(timeInfoToTime(t4L + initInterval(hours = 1))) + t4L.timezone.float a1L = toSeconds(timeInfoToTime(t4L + initInterval(hours = 1))) + t4L.timezone.float
a1G = toSeconds(timeInfoToTime(t4)) + 60.0 * 60.0 a1G = toSeconds(timeInfoToTime(t4)) + 60.0 * 60.0
assert a1L == a1G doAssert a1L == a1G
# subtracting intervals # subtracting intervals
a1L = toSeconds(timeInfoToTime(t4L - initInterval(hours = 1))) + t4L.timezone.float a1L = toSeconds(timeInfoToTime(t4L - initInterval(hours = 1))) + t4L.timezone.float
a1G = toSeconds(timeInfoToTime(t4)) - (60.0 * 60.0) a1G = toSeconds(timeInfoToTime(t4)) - (60.0 * 60.0)
assert a1L == a1G doAssert a1L == a1G
# add/subtract TimeIntervals and Time/TimeInfo
doAssert getTime() - 1.seconds == getTime() - 3.seconds + 2.seconds
doAssert getTime() + 65.seconds == getTime() + 1.minutes + 5.seconds
doAssert getTime() + 60.minutes == getTime() + 1.hours
doAssert getTime() + 24.hours == getTime() + 1.days
doAssert getTime() + 13.months == getTime() + 1.years + 1.months
var
ti1 = getTime() + 1.years
ti1 -= 1.years
doAssert ti1 == getTime()
ti1 += 1.days
doAssert ti1 == getTime() + 1.days
# overflow of TimeIntervals on initalisation
doAssert initInterval(milliseconds = 25000) == initInterval(seconds = 25)
doAssert initInterval(seconds = 65) == initInterval(seconds = 5, minutes = 1)
doAssert initInterval(hours = 25) == initInterval(hours = 1, days = 1)
doAssert initInterval(months = 13) == initInterval(months = 1, years = 1)
# Bug with adding a day to a Time
let day = 24.hours
let tomorrow = getTime() + day
doAssert tomorrow - getTime() == 60*60*24

View file

@ -23,27 +23,27 @@ General FAQ
shared memory heap is also provided for the increased efficiency that results shared memory heap is also provided for the increased efficiency that results
from that model. from that model.
..
.. container:: standout
Why should I use Nim?
---------------------
It's a conservative language in a sense that we stick to features that have
proven themselves for larger scale programming. But it's revolutionary by
the features which have been laid on top.
One of Nim's goals is to increase developer productivity without sacrificing
the produced software's stability. The way that this is done is by providing
Depending on your use case.
Nim is one of the few programming languages in the world which allows you to
The language inventor describes it as the ultimate programming language .. .. container:: standout
with features which make it perfect for just about any problem.
.. Why should I use Nim?
.. ---------------------
.. It's a conservative language in a sense that we stick to features that have
.. proven themselves for larger scale programming. But it's revolutionary by
.. the features which have been laid on top.
.. One of Nim's goals is to increase developer productivity without sacrificing
.. the produced software's stability. The way that this is done is by providing
.. Depending on your use case.
.. Nim is one of the few programming languages in the world which allows you to
.. The language inventor describes it as the ultimate programming language
.. with features which make it perfect for just about any problem.
.. container:: standout .. container:: standout