diff options
author | Dominik Picheta <dominikpicheta@googlemail.com> | 2014-09-14 13:11:35 +0100 |
---|---|---|
committer | Dominik Picheta <dominikpicheta@googlemail.com> | 2014-09-14 13:11:35 +0100 |
commit | 59e5f3533bdb3f02d20a2b402fad92c2d56d50d8 (patch) | |
tree | b20773283e3a99eb3eb20f88247bfa3b15fdd1de | |
parent | 8b8841a6c1bbabebdfa8394f5fd3bd5f36202017 (diff) | |
parent | d330a72a4565353bd3ad54ade0580d53cd9d5a5d (diff) | |
download | Nim-59e5f3533bdb3f02d20a2b402fad92c2d56d50d8.tar.gz |
Merge branch 'bigbreak' of github.com:Araq/Nimrod into bigbreak
-rw-r--r-- | compiler/lambdalifting.nim | 2 | ||||
-rw-r--r-- | compiler/lowerings.nim | 1 | ||||
-rw-r--r-- | compiler/msgs.nim | 2 | ||||
-rw-r--r-- | compiler/options.nim | 5 | ||||
-rw-r--r-- | compiler/pretty.nim | 6 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 | ||||
-rw-r--r-- | compiler/vm.nim | 4 | ||||
-rw-r--r-- | compiler/vmdeps.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 1 | ||||
-rw-r--r-- | doc/basicopt.txt | 2 | ||||
-rw-r--r-- | doc/koch.txt | 7 | ||||
-rw-r--r-- | doc/manual.txt | 21 | ||||
-rw-r--r-- | examples/0mq/client.nim | 14 | ||||
-rw-r--r-- | examples/0mq/server.nim | 11 | ||||
-rw-r--r-- | lib/pure/cookies.nim | 20 | ||||
-rw-r--r-- | lib/pure/strutils.nim | 35 | ||||
-rw-r--r-- | lib/pure/times.nim | 2 | ||||
-rw-r--r-- | lib/pure/xmltree.nim | 4 | ||||
-rw-r--r-- | lib/system/sysio.nim | 14 | ||||
-rw-r--r-- | lib/system/threads.nim | 1 | ||||
-rw-r--r-- | tools/nimweb.nim | 57 |
21 files changed, 145 insertions, 68 deletions
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index b0595a7a7..194396ddd 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -949,7 +949,7 @@ proc liftLambdas*(fn: PSym, body: PNode): PNode = discard transformOuterProcBody(o, body, initIter(fn)) result = ex finishEnvironments(o) - #if fn.name.s == "cbOuter": + #if fn.name.s == "parseLong": # echo rendertree(result, {renderIds}) proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode = diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index e90ef9376..8e5ffd48a 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -56,6 +56,7 @@ proc lowerTupleUnpacking*(n: PNode; owner: PSym): PNode = result.add newAsgnStmt(newSymNode(temp), value) for i in 0 .. n.len-3: + if n.sons[i].kind == nkSym: v.addVar(n.sons[i]) result.add newAsgnStmt(n.sons[i], newTupleAccess(value, i)) proc createObj*(owner: PSym, info: TLineInfo): PType = diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 622c64359..da2fe122d 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -442,7 +442,7 @@ type TNoteKinds* = set[TNoteKind] TFileInfo*{.final.} = object - fullPath*: string # This is a canonical full filesystem path + fullPath: string # This is a canonical full filesystem path projPath*: string # This is relative to the project's root shortName*: string # short name of the module quotedName*: PRope # cached quoted short name for codegen diff --git a/compiler/options.nim b/compiler/options.nim index 69067b7c4..9d7df2f2b 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -188,8 +188,9 @@ proc getPrefixDir*(): string = result = splitPath(getAppDir()).head proc canonicalizePath*(path: string): string = - result = path.expandFilename - when not FileSystemCaseSensitive: result = result.toLower + #result = path.expandFilename + when not FileSystemCaseSensitive: result = path.toLower + else: result = path proc shortenDir*(dir: string): string = ## returns the interesting part of a dir diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 9f2074a0b..ec9322309 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -110,7 +110,7 @@ template styleCheckDef*(info: TLineInfo; s: PSym) = template styleCheckDef*(s: PSym) = styleCheckDef(s.info, s, s.kind) -proc styleCheckUse*(info: TLineInfo; s: PSym) = +proc styleCheckUseImpl(info: TLineInfo; s: PSym) = if info.fileIndex < 0: return # we simply convert it to what it looks like in the definition # for consistency @@ -138,3 +138,7 @@ proc styleCheckUse*(info: TLineInfo; s: PSym) = system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) gSourceFiles[info.fileIndex].dirty = true #if newName == "File": writeStackTrace() + +template styleCheckUse*(info: TLineInfo; s: PSym) = + when defined(nimfix): + if gStyleCheck != StyleCheck.None: styleCheckUseImpl(info, s) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index aaddc84d0..5cb2eabf8 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -354,7 +354,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) if typ != nil: if typ.isMetaType: - def = inferWithMetaType(c, typ, def) + def = inferWithMetatype(c, typ, def) typ = def.typ else: # BUGFIX: ``fitNode`` is needed here! diff --git a/compiler/vm.nim b/compiler/vm.nim index 5ef4576ec..f74f2e0d7 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1135,14 +1135,14 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcParseExprToAst: decodeB(rkNode) # c.debug[pc].line.int - countLines(regs[rb].strVal) ? - let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFilename, + let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath, c.debug[pc].line.int) if sonsLen(ast) != 1: globalError(c.debug[pc], errExprExpected, "multiple statements") regs[ra].node = ast.sons[0] of opcParseStmtToAst: decodeB(rkNode) - let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFilename, + let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath, c.debug[pc].line.int) regs[ra].node = ast of opcCallSite: diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index acf5277c6..6673d0bd2 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -12,11 +12,11 @@ import ast, types, msgs, osproc, streams, options proc readOutput(p: Process): string = result = "" var output = p.outputStream - discard p.waitForExit while not output.atEnd: result.add(output.readLine) result.add("\n") result.setLen(result.len - "\n".len) + discard p.waitForExit proc opGorge*(cmd, input: string): string = var p = startCmd(cmd) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 3921a69fe..e7f7ad742 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -46,7 +46,6 @@ proc debugInfo(info: TLineInfo): string = proc codeListing(c: PCtx, result: var string, start=0; last = -1) = # first iteration: compute all necessary labels: var jumpTargets = initIntSet() - let last = if last < 0: c.code.len-1 else: min(last, c.code.len-1) for i in start..last: let x = c.code[i] diff --git a/doc/basicopt.txt b/doc/basicopt.txt index 8080e380e..e8aaa2e4c 100644 --- a/doc/basicopt.txt +++ b/doc/basicopt.txt @@ -35,3 +35,5 @@ Options: -r, --run run the compiled program with given arguments --advanced show advanced command line switches -h, --help show this help + +Note: Even single letter options require the colon: -p:PATH. diff --git a/doc/koch.txt b/doc/koch.txt index a3b7f0df8..7da137458 100644 --- a/doc/koch.txt +++ b/doc/koch.txt @@ -138,6 +138,13 @@ from rst to HTML. It also repeats the same operation but places the result in the ``web/upload`` which can be used to update the website at http://nim-lang.org. +By default the documentation will be built in parallel using the number of +available CPU cores. If any documentation build sub commands fail, they will +be rerun in serial fashion so that meaninful error output can be gathered for +inspection. The ``--parallelBuild:n`` switch or configuration option can be +used to force a specific number of parallel jobs or run everything serially +from the start (``n == 1``). + zip command ----------- diff --git a/doc/manual.txt b/doc/manual.txt index f0f50e373..3d14ef488 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -596,7 +596,7 @@ Ordinal types Ordinal types have the following characteristics: - Ordinal types are countable and ordered. This property allows - the operation of functions as ``Inc``, ``Ord``, ``Dec`` on ordinal types to + the operation of functions as ``inc``, ``ord``, ``dec`` on ordinal types to be defined. - Ordinal values have a smallest possible value. Trying to count further down than the smallest value gives a checked runtime or static error. @@ -699,11 +699,11 @@ lowest and highest value of the type: .. code-block:: nim type - TSubrange = range[0..5] + Subrange = range[0..5] -``TSubrange`` is a subrange of an integer which can only hold the values 0 -to 5. Assigning any other value to a variable of type ``TSubrange`` is a +``Subrange`` is a subrange of an integer which can only hold the values 0 +to 5. Assigning any other value to a variable of type ``Subrange`` is a checked runtime error (or static error if it can be statically determined). Assignments from the base type to one of its subrange types (and vice versa) are allowed. @@ -791,6 +791,10 @@ turned off as default. The only operations that are affected by the ``floatChecks`` pragma are the ``+``, ``-``, ``*``, ``/`` operators for floating point types. +An implementation should always use the maximum precision available to evaluate +floating pointer values at compile time; this means expressions like +``0.09'f32 + 0.01'f32 == 0.09'f64 + 0.01'f64`` are true. + Boolean type ------------ @@ -3675,10 +3679,11 @@ Future versions of Nim may also support overloading based on the return type of the overloads. In such settings, the expected result type at call sites may also influence the inferred return type. -Likewise, if a type class is used in another position where Nim expects a -concrete type (e.g. a variable declaration or a type coercion), Nim will try to -infer the concrete type by applying the sane matching algorithm also used in -overload resolution. +.. + Likewise, if a type class is used in another position where Nim expects a + concrete type (e.g. a variable declaration or a type coercion), Nim will try + to infer the concrete type by applying the matching algorithm that also used + in overload resolution. Symbol lookup in generics diff --git a/examples/0mq/client.nim b/examples/0mq/client.nim deleted file mode 100644 index e75e5c7a2..000000000 --- a/examples/0mq/client.nim +++ /dev/null @@ -1,14 +0,0 @@ -import zmq - -var connection = zmq.open("tcp://localhost:5555", server=false) - -echo("Connecting...") - -for i in 0..10: - echo("Sending hello...", i) - send(connection, "Hello") - - var reply = receive(connection) - echo("Received ...", reply) - -close(connection) diff --git a/examples/0mq/server.nim b/examples/0mq/server.nim deleted file mode 100644 index 0fadf8b97..000000000 --- a/examples/0mq/server.nim +++ /dev/null @@ -1,11 +0,0 @@ -import zmq - -var connection = zmq.open("tcp://*:5555", server=true) - -while True: - var request = receive(connection) - echo("Received: ", request) - send(connection, "World") - -close(connection) - diff --git a/lib/pure/cookies.nim b/lib/pure/cookies.nim index c85f60915..6247efed2 100644 --- a/lib/pure/cookies.nim +++ b/lib/pure/cookies.nim @@ -28,8 +28,9 @@ proc parseCookies*(s: string): StringTableRef = if s[i] == '\0': break inc(i) # skip ';' -proc setCookie*(key, value: string, domain = "", path = "", - expires = "", noName = false): string = +proc setCookie*(key, value: string, domain = "", path = "", + expires = "", noName = false, + secure = false, httpOnly = false): string = ## Creates a command in the format of ## ``Set-Cookie: key=value; Domain=...; ...`` result = "" @@ -38,22 +39,23 @@ proc setCookie*(key, value: string, domain = "", path = "", if domain != "": result.add("; Domain=" & domain) if path != "": result.add("; Path=" & path) if expires != "": result.add("; Expires=" & expires) + if secure: result.add("; secure") + if httpOnly: result.add("; HttpOnly") proc setCookie*(key, value: string, expires: TimeInfo, - domain = "", path = "", noName = false): string = + domain = "", path = "", noName = false, + secure = false, httpOnly = false): string = ## Creates a command in the format of ## ``Set-Cookie: key=value; Domain=...; ...`` ## - ## **Note:** UTC is assumed as the timezone for ``expires``. - + ## **Note:** UTC is assumed as the timezone for ``expires``. return setCookie(key, value, domain, path, - format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'UTC'"), noName) - + format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'UTC'"), + noname, secure, httpOnly) + when isMainModule: var tim = Time(int(getTime()) + 76 * (60 * 60 * 24)) echo(setCookie("test", "value", tim.getGMTime())) echo parseCookies("uid=1; kp=2") - - diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 2fdf72011..55a204b4c 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -803,6 +803,36 @@ proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} = if result != -1: return return -1 +proc count*(s: string, sub: string, overlapping: bool = false): int {.noSideEffect, + rtl, extern: "nsuCountString".} = + ## Count the occurences of a substring `sub` in the string `s`. + ## Overlapping occurences of `sub` only count when `overlapping` + ## is set to true. + var i = 0 + while true: + i = s.find(sub, i) + if i < 0: + break + if overlapping: + inc i + else: + i += sub.len + inc result + +proc count*(s: string, sub: char): int {.noSideEffect, + rtl, extern: "nsuCountChar".} = + ## Count the occurences of the character `sub` in the string `s`. + for c in s: + if c == sub: + inc result + +proc count*(s: string, subs: set[char]): int {.noSideEffect, + rtl, extern: "nsuCountCharSet".} = + ## Count the occurences of the group of character `subs` in the string `s`. + for c in s: + if c in subs: + inc result + proc quoteIfContainsWhite*(s: string): string {.deprecated.} = ## Returns ``'"' & s & '"'`` if `s` contains a space and does not ## start with a quote, else returns `s`. @@ -1356,3 +1386,8 @@ when isMainModule: doAssert parseEnum[MyEnum]("enu_D") == enuD doAssert parseEnum("invalid enum value", enC) == enC + + doAssert count("foofoofoo", "foofoo") == 1 + doAssert count("foofoofoo", "foofoo", overlapping = true) == 2 + doAssert count("foofoofoo", 'f') == 3 + doAssert count("foofoofoobar", {'f','b'}) == 4 diff --git a/lib/pure/times.nim b/lib/pure/times.nim index dcc5617fd..1cabd381b 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -514,7 +514,7 @@ elif defined(JS): result.setFullYear(timeInfo.year) result.setDate(timeInfo.monthday) - proc `$`(timeInfo: TimeInfo): string = return $(TimeInfoToTIme(timeInfo)) + proc `$`(timeInfo: TimeInfo): string = return $(timeInfoToTime(timeInfo)) proc `$`(time: Time): string = return $time.toLocaleString() proc `-` (a, b: Time): int64 = diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim index 37f591f1e..b84da9586 100644 --- a/lib/pure/xmltree.nim +++ b/lib/pure/xmltree.nim @@ -154,6 +154,8 @@ proc addEscaped*(result: var string, s: string) = of '>': result.add(">") of '&': result.add("&") of '"': result.add(""") + of '\'': result.add("'") + of '/': result.add("/") else: result.add(c) proc escape*(s: string): string = @@ -167,6 +169,8 @@ proc escape*(s: string): string = ## ``>`` ``>`` ## ``&`` ``&`` ## ``"`` ``"`` + ## ``'`` ``'`` + ## ``/`` ``/`` ## ------------ ------------------- result = newStringOfCap(s.len) addEscaped(result, s) diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index 56de5e6e8..7908fbe4d 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -215,13 +215,13 @@ proc open(f: var File, filename: string, mode: FileMode = fmRead, bufSize: int = -1): bool = var p: pointer = fopen(filename, FormatOpen[mode]) - result = (p != nil) - f = cast[File](p) - if bufSize > 0 and bufSize <= high(cint).int: - if setvbuf(f, nil, IOFBF, bufSize.cint) != 0'i32: - sysFatal(OutOfMemError, "out of memory") - elif bufSize == 0: - discard setvbuf(f, nil, IONBF, 0) + if p != nil: + result = true + f = cast[File](p) + if bufSize > 0 and bufSize <= high(cint).int: + discard setvbuf(f, nil, IOFBF, bufSize.cint) + elif bufSize == 0: + discard setvbuf(f, nil, IONBF, 0) proc reopen(f: File, filename: string, mode: FileMode = fmRead): bool = var p: pointer = freopen(filename, FormatOpen[mode], f) diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 95fa353dd..7dac9d9aa 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -354,7 +354,6 @@ when hostOS == "windows": addr(t), 0'i32, dummyThreadId) if t.sys <= 0: raise newException(ResourceExhaustedError, "cannot create thread") - else: proc createThread*[TArg](t: var TThread[TArg], tp: proc (arg: TArg) {.thread.}, diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 1a5721075..c6602d884 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -21,6 +21,7 @@ type nimrodArgs: string gitCommit: string quotations: TTable[string, tuple[quote, author: string]] + numProcessors: int # Set by parallelBuild:n, only works for values > 0. TRssItem = object year, month, day, title: string @@ -42,6 +43,7 @@ proc initConfigData(c: var TConfigData) = c.ticker = "" c.vars = newStringTable(modeStyleInsensitive) c.gitCommit = "master" + c.numProcessors = countProcessors() # Attempts to obtain the git current commit. let (output, code) = execCmdEx("git log -n 1 --format=%H") if code == 0 and output.strip.len == 40: @@ -121,6 +123,12 @@ proc parseCmdLine(c: var TConfigData) = stdout.write(version & "\n") quit(0) of "o", "output": c.outdir = val + of "parallelbuild": + try: + let num = parseInt(val) + if num != 0: c.numProcessors = num + except EInvalidValue: + quit("invalid numeric value for --parallelBuild") of "var": var idx = val.find('=') if idx < 0: quit("invalid command line") @@ -187,6 +195,12 @@ proc parseIniFile(c: var TConfigData) = of "srcdoc": addFiles(c.srcdoc, "lib", ".nim", split(v, {';'})) of "srcdoc2": addFiles(c.srcdoc2, "lib", ".nim", split(v, {';'})) of "webdoc": addFiles(c.webdoc, "lib", ".nim", split(v, {';'})) + of "parallelbuild": + try: + let num = parseInt(v) + if num != 0: c.numProcessors = num + except EInvalidValue: + quit("invalid numeric value for --parallelBuild in config") else: quit(errorStr(p, "unknown variable: " & k.key)) of "quotations": let vSplit = v.split('-') @@ -215,6 +229,20 @@ proc exec(cmd: string) = echo(cmd) if os.execShellCmd(cmd) != 0: quit("external program failed") +proc sexec(cmds: openarray[string]) = + ## Serial queue wrapper around exec. + for cmd in cmds: exec(cmd) + +proc mexec(cmds: openarray[string], processors: int) = + ## Multiprocessor version of exec + if processors < 2: + sexec(cmds) + return + + if 0 != execProcesses(cmds, {poStdErrToStdOut, poParentStreams, poEchoCmd}): + echo "external program failed, retrying serial work queue for logs!" + sexec(cmds) + proc buildDocSamples(c: var TConfigData, destPath: string) = ## Special case documentation sample proc. ## @@ -229,18 +257,26 @@ proc buildDocSamples(c: var TConfigData, destPath: string) = proc buildDoc(c: var TConfigData, destPath: string) = # call nim for the documentation: + var + commands = newSeq[string](len(c.doc) + len(c.srcdoc) + len(c.srcdoc2)) + i = 0 for d in items(c.doc): - exec("nim rst2html $# --docSeeSrcUrl:$# -o:$# --index:on $#" % + commands[i] = "nim rst2html $# --docSeeSrcUrl:$# -o:$# --index:on $#" % [c.nimrodArgs, c.gitCommit, - destPath / changeFileExt(splitFile(d).name, "html"), d]) + destPath / changeFileExt(splitFile(d).name, "html"), d] + i.inc for d in items(c.srcdoc): - exec("nim doc $# --docSeeSrcUrl:$# -o:$# --index:on $#" % + commands[i] = "nim doc $# --docSeeSrcUrl:$# -o:$# --index:on $#" % [c.nimrodArgs, c.gitCommit, - destPath / changeFileExt(splitFile(d).name, "html"), d]) + destPath / changeFileExt(splitFile(d).name, "html"), d] + i.inc for d in items(c.srcdoc2): - exec("nim doc2 $# --docSeeSrcUrl:$# -o:$# --index:on $#" % + commands[i] = "nim doc2 $# --docSeeSrcUrl:$# -o:$# --index:on $#" % [c.nimrodArgs, c.gitCommit, - destPath / changeFileExt(splitFile(d).name, "html"), d]) + destPath / changeFileExt(splitFile(d).name, "html"), d] + i.inc + + mexec(commands, c.numProcessors) exec("nim buildIndex -o:$1/theindex.html $1" % [destPath]) proc buildPdfDoc(c: var TConfigData, destPath: string) = @@ -264,10 +300,17 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) = proc buildAddDoc(c: var TConfigData, destPath: string) = # build additional documentation (without the index): +<<<<<<< HEAD + var commands = newSeq[string](c.webdoc.len) + for i, doc in pairs(c.webdoc): + commands[i] = "nimrod doc $# --docSeeSrcUrl:$# -o:$# $#" % +======= for d in items(c.webdoc): exec("nim doc $# --docSeeSrcUrl:$# -o:$# $#" % +>>>>>>> 0047172274a73c681f619f5cd60aaad7109f694d [c.nimrodArgs, c.gitCommit, - destPath / changeFileExt(splitFile(d).name, "html"), d]) + destPath / changeFileExt(splitFile(doc).name, "html"), doc] + mexec(commands, c.numProcessors) proc parseNewsTitles(inputFilename: string): seq[TRssItem] = # parses the file for titles and returns them as TRssItem blocks. |