diff options
-rw-r--r-- | compiler/jsgen.nim | 4 | ||||
-rw-r--r-- | compiler/main.nim | 2 | ||||
-rw-r--r-- | compiler/modules.nim | 29 | ||||
-rw-r--r-- | compiler/nim.nim | 9 | ||||
-rw-r--r-- | compiler/nimsuggest/nimsuggest.nim | 8 | ||||
-rw-r--r-- | compiler/options.nim | 1 | ||||
-rw-r--r-- | compiler/passes.nim | 6 | ||||
-rw-r--r-- | compiler/vm.nim | 4 | ||||
-rw-r--r-- | config/nim.cfg | 1 | ||||
-rw-r--r-- | doc/astspec.txt | 2 | ||||
-rw-r--r-- | doc/lib.txt | 4 | ||||
-rw-r--r-- | doc/manual/threads.txt | 2 | ||||
-rw-r--r-- | doc/spawn.txt | 2 | ||||
-rw-r--r-- | doc/tut1.txt | 2 | ||||
-rw-r--r-- | lib/core/macros.nim | 6 | ||||
-rw-r--r-- | lib/pure/algorithm.nim | 11 | ||||
-rw-r--r-- | lib/pure/asyncdispatch.nim | 4 | ||||
-rw-r--r-- | lib/pure/httpclient.nim | 16 | ||||
-rw-r--r-- | lib/pure/json.nim | 65 | ||||
-rw-r--r-- | lib/pure/net.nim | 10 | ||||
-rw-r--r-- | lib/pure/osproc.nim | 2 | ||||
-rw-r--r-- | lib/pure/rawsockets.nim | 4 | ||||
-rw-r--r-- | lib/pure/scgi.nim | 2 | ||||
-rw-r--r-- | lib/pure/sockets.nim | 18 | ||||
-rw-r--r-- | lib/pure/times.nim | 17 | ||||
-rw-r--r-- | tests/macros/tgettype.nim | 20 | ||||
-rw-r--r-- | web/news.txt | 5 |
27 files changed, 177 insertions, 79 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 704713243..5c7071498 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1052,11 +1052,13 @@ proc genArg(p: PProc, n: PNode, r: var TCompRes) = proc genArgs(p: PProc, n: PNode, r: var TCompRes) = add(r.res, "(") + var hasArgs = false for i in countup(1, sonsLen(n) - 1): let it = n.sons[i] if it.typ.isCompileTimeOnly: continue - if i > 1: add(r.res, ", ") + if hasArgs: add(r.res, ", ") genArg(p, it, r) + hasArgs = true add(r.res, ")") r.kind = resExpr diff --git a/compiler/main.nim b/compiler/main.nim index 0c80c19b7..a01b6fe4f 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -63,7 +63,7 @@ proc commandCompileToC = compileProject() cgenWriteModules() if gCmd != cmdRun: - extccomp.callCCompiler(if gProjectName == "-": "stdinfile" else: changeFileExt(gProjectFull, "")) + extccomp.callCCompiler(changeFileExt(gProjectFull, "")) if isServing: # caas will keep track only of the compilation commands diff --git a/compiler/modules.nim b/compiler/modules.nim index a2b739efc..2fa46f356 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -10,8 +10,8 @@ ## implements the module handling import - ast, astalgo, magicsys, crc, rodread, msgs, cgendata, sigmatch, options, - idents, os, lexer, idgen, passes, syntaxes + ast, astalgo, magicsys, crc, rodread, msgs, cgendata, sigmatch, options, + idents, os, lexer, idgen, passes, syntaxes, llstream type TNeedRecompile* = enum Maybe, No, Yes, Probing, Recompiled @@ -39,12 +39,12 @@ template crc(x: PSym): expr = proc crcChanged(fileIdx: int32): bool = internalAssert fileIdx >= 0 and fileIdx < gMemCacheData.len - + template updateStatus = gMemCacheData[fileIdx].crcStatus = if result: crcHasChanged else: crcNotChanged # echo "TESTING CRC: ", fileIdx.toFilename, " ", result - + case gMemCacheData[fileIdx].crcStatus: of crcHasChanged: result = true @@ -96,7 +96,7 @@ proc checkDepMem(fileIdx: int32): TNeedRecompile = if optForceFullMake in gGlobalOptions or crcChanged(fileIdx): markDirty - + if gMemCacheData[fileIdx].deps != nil: gMemCacheData[fileIdx].needsRecompile = Probing for dep in gMemCacheData[fileIdx].deps: @@ -104,30 +104,30 @@ proc checkDepMem(fileIdx: int32): TNeedRecompile = if d in {Yes, Recompiled}: # echo fileIdx.toFilename, " depends on ", dep.toFilename, " ", d markDirty - + gMemCacheData[fileIdx].needsRecompile = No return No proc newModule(fileIdx: int32): PSym = # We cannot call ``newSym`` here, because we have to circumvent the ID - # mechanism, which we do in order to assign each module a persistent ID. + # mechanism, which we do in order to assign each module a persistent ID. new(result) result.id = - 1 # for better error checking result.kind = skModule let filename = fileIdx.toFullPath result.name = getIdent(splitFile(filename).name) - if result.name.s != "-" and not isNimIdentifier(result.name.s): + if not isNimIdentifier(result.name.s): rawMessage(errInvalidModuleName, result.name.s) - + result.info = newLineInfo(fileIdx, 1, 1) result.owner = newSym(skPackage, getIdent(getPackageName(filename)), nil, result.info) result.position = fileIdx - + growCache gMemCacheData, fileIdx growCache gCompiledModules, fileIdx gCompiledModules[result.position] = result - + incl(result.flags, sfUsed) initStrTable(result.tab) strTableAdd(result.tab, result) # a module knows itself @@ -143,12 +143,15 @@ proc compileModule*(fileIdx: int32, flags: TSymFlags): PSym = result.flags = result.flags + flags if gCmd in {cmdCompileToC, cmdCompileToCpp, cmdCheck, cmdIdeTools}: rd = handleSymbolFile(result) - if result.id < 0: + if result.id < 0: internalError("handleSymbolFile should have set the module\'s ID") return else: result.id = getID() - processModule(result, nil, rd) + if sfMainModule in flags and gProjectIsStdin: + processModule(result, llStreamOpen(stdin), rd) + else: + processModule(result, nil, rd) if optCaasEnabled in gGlobalOptions: gMemCacheData[fileIdx].compiledAt = gLastCmdTime gMemCacheData[fileIdx].needsRecompile = Recompiled diff --git a/compiler/nim.nim b/compiler/nim.nim index b8ba2c6da..89db22e8f 100644 --- a/compiler/nim.nim +++ b/compiler/nim.nim @@ -38,7 +38,12 @@ proc handleCmdLine() = else: # Process command line arguments: processCmdLine(passCmd1, "") - if gProjectName != "": + if gProjectName == "-": + gProjectName = "stdinfile" + gProjectFull = "stdinfile" + gProjectPath = getCurrentDir() + gProjectIsStdin = true + elif gProjectName != "": try: gProjectFull = canonicalizePath(gProjectName) except OSError: @@ -61,8 +66,6 @@ proc handleCmdLine() = if gCmd == cmdRun: tccgen.run(commands.arguments) if optRun in gGlobalOptions: - if gProjectName == "-": - gProjectFull = "stdinfile" if gCmd == cmdCompileToJS: var ex: string if options.outFile.len > 0: diff --git a/compiler/nimsuggest/nimsuggest.nim b/compiler/nimsuggest/nimsuggest.nim index 3b4aa658d..2c785d118 100644 --- a/compiler/nimsuggest/nimsuggest.nim +++ b/compiler/nimsuggest/nimsuggest.nim @@ -119,9 +119,8 @@ proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int) = gTrackPos = newLineInfo(dirtyIdx, line, col) gErrorCounter = 0 if not isKnownFile: - compileProject(dirtyIdx) - else: compileProject() + compileProject(dirtyIdx) proc executeEPC(cmd: IdeCmd, args: SexpNode) = let @@ -192,8 +191,6 @@ proc parseCmdLine(cmd: string) = execute(gIdeCmd, orig, dirtyfile, line, col-1) proc serve() = - # do not stop after the first error: - msgs.gErrorMax = high(int) case gMode: of mstdin: echo Help @@ -278,6 +275,9 @@ proc mainCommand = # current path is always looked first for modules prependStr(searchPaths, gProjectPath) + # do not stop after the first error: + msgs.gErrorMax = high(int) + compileProject() serve() proc processCmdLine*(pass: TCmdLinePass, cmd: string) = diff --git a/compiler/options.nim b/compiler/options.nim index d07342fce..b3060a180 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -149,6 +149,7 @@ var gProjectName* = "" # holds a name like 'nimrod' gProjectPath* = "" # holds a path like /home/alice/projects/nimrod/compiler/ gProjectFull* = "" # projectPath/projectName + gProjectIsStdin* = false # whether we're compiling from stdin gProjectMainIdx*: int32 # the canonical path id of the main module nimcacheDir* = "" command* = "" # the main command (e.g. cc, check, scan, etc) diff --git a/compiler/passes.nim b/compiler/passes.nim index 129d8ad47..e031dae10 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -170,11 +170,7 @@ proc processModule(module: PSym, stream: PLLStream, rd: PRodReader) = openPasses(a, module) if stream == nil: let filename = fileIdx.toFullPathConsiderDirty - if module.name.s == "-": - module.name.s = "stdinfile" - s = llStreamOpen(stdin) - else: - s = llStreamOpen(filename, fmRead) + s = llStreamOpen(filename, fmRead) if s == nil: rawMessage(errCannotOpenFile, filename) return diff --git a/compiler/vm.nim b/compiler/vm.nim index 1c6c9a30b..e49bed522 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1121,7 +1121,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = decodeB(rkInt) let a = regs[rb].node case a.kind - of nkCharLit..nkInt64Lit: regs[ra].intVal = a.intVal + of nkCharLit..nkUInt64Lit: regs[ra].intVal = a.intVal else: stackTrace(c, tos, pc, errFieldXNotFound, "intVal") of opcNFloatVal: decodeB(rkFloat) @@ -1276,7 +1276,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcNSetIntVal: decodeB(rkNode) var dest = regs[ra].node - if dest.kind in {nkCharLit..nkInt64Lit} and + if dest.kind in {nkCharLit..nkUInt64Lit} and regs[rb].kind in {rkInt}: dest.intVal = regs[rb].intVal else: diff --git a/config/nim.cfg b/config/nim.cfg index fef7df79e..0c3ffef4e 100644 --- a/config/nim.cfg +++ b/config/nim.cfg @@ -78,6 +78,7 @@ path="$lib/pure/unidecode" gcc.options.linker = "-ldl" gcc.cpp.options.linker = "-ldl" clang.options.linker = "-ldl" + clang.cpp.options.linker = "-ldl" tcc.options.linker = "-ldl" @end @if bsd or haiku: diff --git a/doc/astspec.txt b/doc/astspec.txt index 4c27272e2..68bb9f1cd 100644 --- a/doc/astspec.txt +++ b/doc/astspec.txt @@ -23,7 +23,7 @@ contains: case kind: NimNodeKind ## the node's kind of nnkNone, nnkEmpty, nnkNilLit: discard ## node contains no additional fields - of nnkCharLit..nnkInt64Lit: + of nnkCharLit..nnkUInt64Lit: intVal: biggestInt ## the int literal of nnkFloatLit..nnkFloat64Lit: floatVal: biggestFloat ## the float literal diff --git a/doc/lib.txt b/doc/lib.txt index 1c0278068..f43228151 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -325,6 +325,10 @@ Parsers * `rstgen <rstgen.html>`_ This module implements a generator of HTML/Latex from reStructuredText. +* `sexp <sexp.html>`_ + High performance sexp parser and generator, mainly for communication + with emacs. + XML Processing -------------- diff --git a/doc/manual/threads.txt b/doc/manual/threads.txt index 11380f757..f2b79a34f 100644 --- a/doc/manual/threads.txt +++ b/doc/manual/threads.txt @@ -146,7 +146,7 @@ wait on multiple flow variables at the same time: # wait until 2 out of 3 servers received the update: proc main = - var responses = newSeq[RawFlowVar](3) + var responses = newSeq[FlowVarBase](3) for i in 0..2: responses[i] = spawn tellServer(Update, "key", "value") var index = awaitAny(responses) diff --git a/doc/spawn.txt b/doc/spawn.txt index fb2f851c7..36bd02e96 100644 --- a/doc/spawn.txt +++ b/doc/spawn.txt @@ -33,7 +33,7 @@ variables at the same time: # wait until 2 out of 3 servers received the update: proc main = - var responses = newSeq[RawFlowVar](3) + var responses = newSeq[FlowVarBase](3) for i in 0..2: responses[i] = spawn tellServer(Update, "key", "value") var index = awaitAny(responses) diff --git a/doc/tut1.txt b/doc/tut1.txt index cf27ac788..1fa495054 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -1303,7 +1303,7 @@ type conversions in this context: myWriteln(stdout, 123, "abc", 4.0) # is transformed by the compiler to: - myWriteln(stdout, [$123, $"def", $4.0]) + myWriteln(stdout, [$123, $"abc", $4.0]) In this example `$ <system.html#$>`_ is applied to any argument that is passed to the parameter ``a``. Note that `$ <system.html#$>`_ applied to strings is a diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 35f0f61c1..7e6e4ccc9 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -177,6 +177,12 @@ proc getType*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.} ## resolve recursive types, you have to call 'getType' again. To see what ## kind of type it is, call `typeKind` on getType's result. +proc getType*(n: typedesc): NimNode {.magic: "NGetType", noSideEffect.} + ## Returns the Nim type node for given type. This can be used to turn macro + ## typedesc parameter into proper NimNode representing type, since typedesc + ## are an exception in macro calls - they are not mapped implicitly to + ## NimNode like any other arguments. + proc typeKind*(n: NimNode): NimTypeKind {.magic: "NGetType", noSideEffect.} ## Returns the type kind of the node 'n' that should represent a type, that ## means the node should have been obtained via `getType`. diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 352b177e2..0eafb316a 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -24,6 +24,17 @@ proc `*`*(x: int, order: SortOrder): int {.inline.} = var y = order.ord - 1 result = (x xor y) - y +proc fill*[T](a: var openArray[T], first, last: Natural, value: T) = + ## fills the array ``a[first..last]`` with `value`. + var x = first + while x <= last: + a[x] = value + inc(x) + +proc fill*[T](a: var openArray[T], value: T) = + ## fills the array `a` with `value`. + fill(a, 0, a.high, value) + proc reverse*[T](a: var openArray[T], first, last: Natural) = ## reverses the array ``a[first..last]``. var x = first diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index a4d7a1632..8010e9ebc 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -1154,7 +1154,7 @@ else: proc sleepAsync*(ms: int): Future[void] = ## Suspends the execution of the current async procedure for the next - ## ``ms`` miliseconds. + ## ``ms`` milliseconds. var retFuture = newFuture[void]("sleepAsync") let p = getGlobalDispatcher() p.timers.add((epochTime() + (ms / 1000), retFuture)) @@ -1328,7 +1328,7 @@ proc processBody(node, retFutureSym: NimNode, else: discard of nnkDiscardStmt: # discard await x - if node[0].kind != nnkEmpty and node[0][0].kind == nnkIdent and + if node[0].kind == nnkCommand and node[0][0].kind == nnkIdent and node[0][0].ident == !"await": var newDiscard = node result.createVar("futureDiscard_" & $toStrLit(node[0][1]), node[0][1], diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 9c27ecdab..e083d44ea 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -64,7 +64,7 @@ ## ======== ## Currently all functions support an optional timeout, by default the timeout is set to ## `-1` which means that the function will never time out. The timeout is -## measured in miliseconds, once it is set any call on a socket which may +## measured in milliseconds, once it is set any call on a socket which may ## block will be susceptible to this timeout, however please remember that the ## function as a whole can take longer than the specified timeout, only ## individual internal calls on the socket are affected. In practice this means @@ -386,7 +386,7 @@ proc request*(url: string, httpMethod: string, extraHeaders = "", ## | Requests ``url`` with the custom method string specified by the ## | ``httpMethod`` parameter. ## | Extra headers can be specified and must be separated by ``\c\L`` - ## | An optional timeout can be specified in miliseconds, if reading from the + ## | An optional timeout can be specified in milliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. var r = if proxy == nil: parseUri(url) else: proxy.url var headers = substr(httpMethod, len("http")) @@ -440,7 +440,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", userAgent = defUserAgent, proxy: Proxy = nil): Response = ## | Requests ``url`` with the specified ``httpMethod``. ## | Extra headers can be specified and must be separated by ``\c\L`` - ## | An optional timeout can be specified in miliseconds, if reading from the + ## | An optional timeout can be specified in milliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. result = request(url, $httpMethod, extraHeaders, body, sslContext, timeout, userAgent, proxy) @@ -467,7 +467,7 @@ proc get*(url: string, extraHeaders = "", maxRedirects = 5, ## | GETs the ``url`` and returns a ``Response`` object ## | This proc also handles redirection ## | Extra headers can be specified and must be separated by ``\c\L``. - ## | An optional timeout can be specified in miliseconds, if reading from the + ## | An optional timeout can be specified in milliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. result = request(url, httpGET, extraHeaders, "", sslContext, timeout, userAgent, proxy) @@ -486,7 +486,7 @@ proc getContent*(url: string, extraHeaders = "", maxRedirects = 5, ## | GETs the body and returns it as a string. ## | Raises exceptions for the status codes ``4xx`` and ``5xx`` ## | Extra headers can be specified and must be separated by ``\c\L``. - ## | An optional timeout can be specified in miliseconds, if reading from the + ## | An optional timeout can be specified in milliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. var r = get(url, extraHeaders, maxRedirects, sslContext, timeout, userAgent, proxy) @@ -505,7 +505,7 @@ proc post*(url: string, extraHeaders = "", body = "", ## | This proc adds the necessary Content-Length header. ## | This proc also handles redirection. ## | Extra headers can be specified and must be separated by ``\c\L``. - ## | An optional timeout can be specified in miliseconds, if reading from the + ## | An optional timeout can be specified in milliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. ## | The optional ``multipart`` parameter can be used to create ## ``multipart/form-data`` POSTs comfortably. @@ -542,7 +542,7 @@ proc postContent*(url: string, extraHeaders = "", body = "", ## | POSTs ``body`` to ``url`` and returns the response's body as a string ## | Raises exceptions for the status codes ``4xx`` and ``5xx`` ## | Extra headers can be specified and must be separated by ``\c\L``. - ## | An optional timeout can be specified in miliseconds, if reading from the + ## | An optional timeout can be specified in milliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. ## | The optional ``multipart`` parameter can be used to create ## ``multipart/form-data`` POSTs comfortably. @@ -558,7 +558,7 @@ proc downloadFile*(url: string, outputFilename: string, timeout = -1, userAgent = defUserAgent, proxy: Proxy = nil) = ## | Downloads ``url`` and saves it to ``outputFilename`` - ## | An optional timeout can be specified in miliseconds, if reading from the + ## | An optional timeout can be specified in milliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. var f: File if open(f, outputFilename, fmWrite): diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 5d824d6f8..518572be3 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -761,7 +761,7 @@ proc len*(n: JsonNode): int = of JObject: result = n.fields.len else: discard -proc `[]`*(node: JsonNode, name: string): JsonNode = +proc `[]`*(node: JsonNode, name: string): JsonNode {.inline.} = ## Gets a field from a `JObject`, which must not be nil. ## If the value at `name` does not exist, returns nil assert(not isNil(node)) @@ -771,7 +771,7 @@ proc `[]`*(node: JsonNode, name: string): JsonNode = return item return nil -proc `[]`*(node: JsonNode, index: int): JsonNode = +proc `[]`*(node: JsonNode, index: int): JsonNode {.inline.} = ## Gets the node at `index` in an Array. Result is undefined if `index` ## is out of bounds assert(not isNil(node)) @@ -799,7 +799,7 @@ proc add*(obj: JsonNode, key: string, val: JsonNode) = assert obj.kind == JObject obj.fields.add((key, val)) -proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) = +proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) {.inline.} = ## Sets a field from a `JObject`. Performs a check for duplicate keys. assert(obj.kind == JObject) for i in 0..obj.fields.len-1: @@ -815,7 +815,7 @@ proc `{}`*(node: JsonNode, keys: varargs[string]): JsonNode = result = node for key in keys: if isNil(result) or result.kind!=JObject: - return nil + return nil result=result[key] proc `{}=`*(node: JsonNode, keys: varargs[string], value: JsonNode) = @@ -949,10 +949,46 @@ proc pretty*(node: JsonNode, indent = 2): string = result = "" toPretty(result, node, indent) +proc toUgly*(result: var string, node: JsonNode) = + ## Converts `node` to its JSON Representation, without + ## regard for human readability. Meant to improve ``$`` string + ## conversion performance. + ## + ## This provides higher efficiency than the ``toPretty`` procedure as it + ## does **not** attempt to format the resulting JSON to make it human readable. + var comma = false + case node.kind: + of JArray: + result.add "[" + for child in node.elems: + if comma: result.add "," + else: comma = true + result.toUgly child + result.add "]" + of JObject: + result.add "{" + for key, value in items(node.fields): + if comma: result.add "," + else: comma = true + result.add key.escapeJson() + result.add ":" + result.toUgly value + result.add "}" + of JString: + result.add node.str.escapeJson() + of JInt: + result.add($node.num) + of JFloat: + result.add($node.fnum) + of JBool: + result.add(if node.bval: "true" else: "false") + of JNull: + result.add "null" + proc `$`*(node: JsonNode): string = ## Converts `node` to its JSON Representation on one line. - result = "" - toPretty(result, node, 0, false) + result = newStringOfCap(node.len shl 1) + toUgly(result, node) iterator items*(node: JsonNode): JsonNode = ## Iterator for the items of `node`. `node` has to be a JArray. @@ -1153,7 +1189,7 @@ when false: when isMainModule: #var node = parse("{ \"test\": null }") #echo(node.existsKey("test56")) - + var parsed = parseFile("tests/testdata/jsontest.json") var parsed2 = parseFile("tests/testdata/jsontest2.json") @@ -1176,6 +1212,11 @@ when isMainModule: testJson{["c", "d"]} = %true assert(testJson["c"]["d"].bval) + # test `$` + let stringified = $testJson + let parsedAgain = parseJson(stringified) + assert(parsedAgain["b"].str == "asd") + # Bounds checking try: let a = testJson["a"][9] @@ -1192,17 +1233,17 @@ when isMainModule: except: assert(false, "EInvalidIndex thrown for valid index") - assert(testJson{"b"}.str=="asd", "Couldn't fetch a singly nested key with {}") - assert(isNil(testJson{"nonexistent"}), "Non-existent keys should return nil") + assert(testJson{"b"}.str=="asd", "Couldn't fetch a singly nested key with {}") + assert(isNil(testJson{"nonexistent"}), "Non-existent keys should return nil") assert(parsed2{"repository", "description"}.str=="IRC Library for Haskell", "Couldn't fetch via multiply nested key using {}") assert(isNil(testJson{"a", "b"}), "Indexing through a list should return nil") assert(isNil(testJson{"a", "b"}), "Indexing through a list should return nil") assert(testJson{"a"}==parseJson"[1, 2, 3, 4]", "Didn't return a non-JObject when there was one to be found") assert(isNil(parseJson("[1, 2, 3]"){"foo"}), "Indexing directly into a list should return nil") - + # Generator: var j = %* [{"name": "John", "age": 30}, {"name": "Susan", "age": 31}] - assert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}] + assert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}] var j2 = %* [ @@ -1230,7 +1271,7 @@ when isMainModule: } ] assert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}] - + when not defined(testing): discard """ while true: diff --git a/lib/pure/net.nim b/lib/pure/net.nim index ffbc6e320..cf37c271e 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -704,7 +704,7 @@ proc waitFor(socket: Socket, waited: var float, timeout, size: int, proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {. tags: [ReadIOEffect, TimeEffect].} = - ## overload with a ``timeout`` parameter in miliseconds. + ## overload with a ``timeout`` parameter in milliseconds. var waited = 0.0 # number of seconds already waited var read = 0 @@ -729,7 +729,7 @@ proc recv*(socket: Socket, data: var string, size: int, timeout = -1, ## This function will throw an EOS exception when an error occurs. A value ## lower than 0 is never returned. ## - ## A timeout may be specified in miliseconds, if enough data is not received + ## A timeout may be specified in milliseconds, if enough data is not received ## within the time specified an ETimeout exception will be raised. ## ## **Note**: ``data`` must be initialised. @@ -777,7 +777,7 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1, ## ## An EOS exception will be raised in the case of a socket error. ## - ## A timeout can be specified in miliseconds, if data is not received within + ## A timeout can be specified in milliseconds, if data is not received within ## the specified time an ETimeout exception will be raised. ## ## **Warning**: Only the ``SafeDisconn`` flag is currently supported. @@ -844,7 +844,7 @@ proc recvFrom*(socket: Socket, data: var string, length: int, proc skip*(socket: Socket, size: int, timeout = -1) = ## Skips ``size`` amount of bytes. ## - ## An optional timeout can be specified in miliseconds, if skipping the + ## An optional timeout can be specified in milliseconds, if skipping the ## bytes takes longer than specified an ETimeout exception will be raised. ## ## Returns the number of skipped bytes. @@ -967,7 +967,7 @@ proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, af: Domain = AF_INET) {.tags: [ReadIOEffect, WriteIOEffect].} = ## Connects to server as specified by ``address`` on port specified by ``port``. ## - ## The ``timeout`` paremeter specifies the time in miliseconds to allow for + ## The ``timeout`` paremeter specifies the time in milliseconds to allow for ## the connection to the server to be made. socket.fd.setBlocking(false) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 8150f902a..dc6f21174 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -303,7 +303,7 @@ proc execProcesses*(cmds: openArray[string], close(p) proc select*(readfds: var seq[Process], timeout = 500): int - ## `select` with a sensible Nim interface. `timeout` is in miliseconds. + ## `select` with a sensible Nim interface. `timeout` is in milliseconds. ## Specify -1 for no timeout. Returns the number of processes that are ## ready to read from. The processes that are ready to be read from are ## removed from `readfds`. diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim index a30c23ada..d08c5b769 100644 --- a/lib/pure/rawsockets.nim +++ b/lib/pure/rawsockets.nim @@ -392,7 +392,7 @@ proc select*(readfds: var seq[SocketHandle], timeout = 500): int = ## Traditional select function. This function will return the number of ## sockets that are ready to be read from, written to, or which have errors. ## If there are none; 0 is returned. - ## ``Timeout`` is in miliseconds and -1 can be specified for no timeout. + ## ``Timeout`` is in milliseconds and -1 can be specified for no timeout. ## ## A socket is removed from the specific ``seq`` when it has data waiting to ## be read/written to or has errors (``exceptfds``). @@ -416,7 +416,7 @@ proc selectWrite*(writefds: var seq[SocketHandle], ## written to. The sockets which can be written to will also be removed ## from ``writefds``. ## - ## ``timeout`` is specified in miliseconds and ``-1`` can be specified for + ## ``timeout`` is specified in milliseconds and ``-1`` can be specified for ## an unlimited time. var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) diff --git a/lib/pure/scgi.nim b/lib/pure/scgi.nim index f3e2b583c..3de422c87 100644 --- a/lib/pure/scgi.nim +++ b/lib/pure/scgi.nim @@ -126,7 +126,7 @@ proc close*(s: var ScgiState) = s.server.close() proc next*(s: var ScgiState, timeout: int = -1): bool = - ## proceed to the first/next request. Waits ``timeout`` miliseconds for a + ## proceed to the first/next request. Waits ``timeout`` milliseconds for a ## request, if ``timeout`` is `-1` then this function will never time out. ## Returns `true` if a new request has been processed. var rsocks = @[s.server] diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 3afb545c8..64e2cdcd3 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -986,7 +986,7 @@ proc select*(readfds, writefds, exceptfds: var seq[Socket], ## Traditional select function. This function will return the number of ## sockets that are ready to be read from, written to, or which have errors. ## If there are none; 0 is returned. - ## ``Timeout`` is in miliseconds and -1 can be specified for no timeout. + ## ``Timeout`` is in milliseconds and -1 can be specified for no timeout. ## ## Sockets which are **not** ready for reading, writing or which don't have ## errors waiting on them are removed from the ``readfds``, ``writefds``, @@ -1040,7 +1040,7 @@ proc selectWrite*(writefds: var seq[Socket], ## written to. The sockets which **cannot** be written to will also be removed ## from ``writefds``. ## - ## ``timeout`` is specified in miliseconds and ``-1`` can be specified for + ## ``timeout`` is specified in milliseconds and ``-1`` can be specified for ## an unlimited time. var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) @@ -1174,7 +1174,7 @@ proc waitFor(socket: Socket, waited: var float, timeout, size: int, proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {. tags: [ReadIOEffect, TimeEffect].} = - ## overload with a ``timeout`` parameter in miliseconds. + ## overload with a ``timeout`` parameter in milliseconds. var waited = 0.0 # number of seconds already waited var read = 0 @@ -1197,7 +1197,7 @@ proc recv*(socket: Socket, data: var string, size: int, timeout = -1): int = ## This function will throw an EOS exception when an error occurs. A value ## lower than 0 is never returned. ## - ## A timeout may be specified in miliseconds, if enough data is not received + ## A timeout may be specified in milliseconds, if enough data is not received ## within the time specified an ETimeout exception will be raised. ## ## **Note**: ``data`` must be initialised. @@ -1258,7 +1258,7 @@ proc recvLine*(socket: Socket, line: var TaintedString, timeout = -1): bool {. ## If the socket is disconnected, ``line`` will be set to ``""`` and ``True`` ## will be returned. ## - ## A timeout can be specified in miliseconds, if data is not received within + ## A timeout can be specified in milliseconds, if data is not received within ## the specified time an ETimeout exception will be raised. ## ## **Deprecated since version 0.9.2**: This function has been deprecated in @@ -1302,7 +1302,7 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1) {. ## ## An EOS exception will be raised in the case of a socket error. ## - ## A timeout can be specified in miliseconds, if data is not received within + ## A timeout can be specified in milliseconds, if data is not received within ## the specified time an ETimeout exception will be raised. template addNLIfEmpty(): stmt = @@ -1433,7 +1433,7 @@ proc recv*(socket: Socket): TaintedString {.tags: [ReadIOEffect], deprecated.} = proc recvTimeout*(socket: Socket, timeout: int): TaintedString {. tags: [ReadIOEffect], deprecated.} = ## overloaded variant to support a ``timeout`` parameter, the ``timeout`` - ## parameter specifies the amount of miliseconds to wait for data on the + ## parameter specifies the amount of milliseconds to wait for data on the ## socket. ## ## **Deprecated since version 0.9.2**: This function is not safe for use. @@ -1554,7 +1554,7 @@ proc skip*(socket: Socket) {.tags: [ReadIOEffect], deprecated.} = proc skip*(socket: Socket, size: int, timeout = -1) = ## Skips ``size`` amount of bytes. ## - ## An optional timeout can be specified in miliseconds, if skipping the + ## An optional timeout can be specified in milliseconds, if skipping the ## bytes takes longer than specified an ETimeout exception will be raised. ## ## Returns the number of skipped bytes. @@ -1708,7 +1708,7 @@ proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, af: Domain = AF_INET) {.tags: [ReadIOEffect, WriteIOEffect].} = ## Connects to server as specified by ``address`` on port specified by ``port``. ## - ## The ``timeout`` paremeter specifies the time in miliseconds to allow for + ## The ``timeout`` paremeter specifies the time in milliseconds to allow for ## the connection to the server to be made. let originalStatus = not socket.nonblocking socket.setBlocking(false) diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 1b9fa4599..b8836c15b 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -134,7 +134,7 @@ type ## everything should be positive or everything negative. Zero is ## fine too. Mixed signs will lead to unexpected results. TimeInterval* = object ## a time interval - miliseconds*: int ## The number of miliseconds + milliseconds*: int ## The number of milliseconds seconds*: int ## The number of seconds minutes*: int ## The number of minutes hours*: int ## The number of hours @@ -145,6 +145,11 @@ type {.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time, 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.} ## gets the current calendar time as a UNIX epoch value (number of seconds ## elapsed since 1970) with integer precission. Use epochTime for higher @@ -208,13 +213,13 @@ proc getTimezone*(): int {.tags: [TimeEffect], raises: [], benign.} ## returns the offset of the local (non-DST) timezone in seconds west of UTC. proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.} - ## get the miliseconds from the start of the program. **Deprecated since + ## get the milliseconds from the start of the program. **Deprecated since ## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead. -proc initInterval*(miliseconds, seconds, minutes, hours, days, months, +proc initInterval*(milliseconds, seconds, minutes, hours, days, months, years: int = 0): TimeInterval = ## creates a new ``TimeInterval``. - result.miliseconds = miliseconds + result.milliseconds = milliseconds result.seconds = seconds result.minutes = minutes result.hours = hours @@ -264,7 +269,7 @@ proc toSeconds(a: TimeInfo, interval: TimeInterval): float = result += float(newinterv.hours * 60 * 60) result += float(newinterv.minutes * 60) result += float(newinterv.seconds) - result += newinterv.miliseconds / 1000 + result += newinterv.milliseconds / 1000 proc `+`*(a: TimeInfo, interval: TimeInterval): TimeInfo = ## adds ``interval`` time. @@ -530,7 +535,7 @@ elif defined(JS): startMilsecs = getTime() proc getStartMilsecs(): int = - ## get the miliseconds from the start of the program + ## get the milliseconds from the start of the program return int(getTime() - startMilsecs) proc valueOf(time: Time): float {.importcpp: "getTime", tags:[]} diff --git a/tests/macros/tgettype.nim b/tests/macros/tgettype.nim new file mode 100644 index 000000000..0eab6c0a0 --- /dev/null +++ b/tests/macros/tgettype.nim @@ -0,0 +1,20 @@ +discard """ +msg: '''ObjectTy(Sym(Model), RecList(Sym(name), Sym(password))) +BracketExpr(Sym(typeDesc), Sym(User))''' +""" +import strutils, macros + +type + Model = object of RootObj + User = object of Model + name : string + password : string + +macro testUser: expr = + return newLit(User.getType.lispRepr) + +macro testGeneric(T: typedesc[Model]): expr = + return newLit(T.getType.lispRepr) + +echo testUser +echo User.testGeneric diff --git a/web/news.txt b/web/news.txt index 9719fb8d7..22ea03157 100644 --- a/web/news.txt +++ b/web/news.txt @@ -9,6 +9,10 @@ News Changes affecting backwards compatibility ----------------------------------------- + - The ``miliseconds`` property of ``times.TimeInterval`` is now ``milliseconds``. + Code accessing that property is deprecated and code using ``miliseconds`` + during object initialization or as a named parameter of ``initInterval()`` + will need to be updated. Language Additions ------------------ @@ -223,6 +227,7 @@ Library additions space between ``.. <`` and ``.. ^`` is not necessary anymore. - Added ``system.xlen`` for strings and sequences to get back the old ``len`` operation that doesn't check for ``nil`` for efficiency. +- Added sexp.nim to parse and generate sexp. Bugfixes |