diff options
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/algorithm.nim | 59 | ||||
-rw-r--r-- | lib/pure/asyncdispatch.nim.cfg (renamed from lib/pure/asyncdispatch.nimrod.cfg) | 0 | ||||
-rw-r--r-- | lib/pure/collections/sequtils.nim | 8 | ||||
-rw-r--r-- | lib/pure/json.nim | 77 | ||||
-rw-r--r-- | lib/pure/logging.nim | 2 | ||||
-rw-r--r-- | lib/pure/nimprof.nim.cfg (renamed from lib/pure/nimprof.nimrod.cfg) | 0 | ||||
-rw-r--r-- | lib/pure/os.nim | 8 | ||||
-rw-r--r-- | lib/pure/smtp.nim.cfg (renamed from lib/pure/smtp.nimrod.cfg) | 0 | ||||
-rw-r--r-- | lib/pure/strtabs.nim | 4 | ||||
-rw-r--r-- | lib/pure/unittest.nim | 3 |
10 files changed, 148 insertions, 13 deletions
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 0358a9a81..20bfc5c7c 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -220,3 +220,62 @@ proc product*[T](x: openArray[seq[T]]): seq[seq[T]] = result.add(res) index = 0 indexes[index] -=1 + +proc nextPermutation*[T](x: var openarray[T]): bool {.discardable.} = + ## Calculates the next lexicographic permutation, directly modifying ``x``. + ## The result is whether a permutation happened, otherwise we have reached + ## the last-ordered permutation. + ## + ## .. code-block:: nim + ## + ## var v = @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + ## v.nextPermutation() + ## echo v + if x.len < 2: + return false + + var i = x.high + while i > 0 and x[i-1] >= x[i]: + dec i + + if i == 0: + return false + + var j = x.high + while j >= i and x[j] <= x[i-1]: + dec j + + swap x[j], x[i-1] + x.reverse(i, x.high) + + result = true + +proc prevPermutation*[T](x: var openarray[T]): bool {.discardable.} = + ## Calculates the previous lexicographic permutation, directly modifying + ## ``x``. The result is whether a permutation happened, otherwise we have + ## reached the first-ordered permutation. + ## + ## .. code-block:: nim + ## + ## var v = @[0, 1, 2, 3, 4, 5, 6, 7, 9, 8] + ## v.prevPermutation() + ## echo v + if x.len < 2: + return false + + var i = x.high + while i > 0 and x[i-1] <= x[i]: + dec i + + if i == 0: + return false + + x.reverse(i, x.high) + + var j = x.high + while j >= i and x[j-1] < x[i-1]: + dec j + + swap x[i-1], x[j] + + result = true diff --git a/lib/pure/asyncdispatch.nimrod.cfg b/lib/pure/asyncdispatch.nim.cfg index e88f8eec3..e88f8eec3 100644 --- a/lib/pure/asyncdispatch.nimrod.cfg +++ b/lib/pure/asyncdispatch.nim.cfg diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index befc9bacb..b527b9368 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -382,7 +382,7 @@ template foldr*(sequence, operation: expr): expr = result = operation result -template mapIt*(seq1, typ, pred: expr): expr = +template mapIt*(seq1, typ, op: expr): expr = ## Convenience template around the ``map`` proc to reduce typing. ## ## The template injects the ``it`` variable which you can use directly in an @@ -397,10 +397,10 @@ template mapIt*(seq1, typ, pred: expr): expr = ## assert strings == @["4", "8", "12", "16"] var result {.gensym.}: seq[typ] = @[] for it {.inject.} in items(seq1): - result.add(pred) + result.add(op) result -template mapIt*(varSeq, pred: expr) = +template mapIt*(varSeq, op: expr) = ## Convenience template around the mutable ``map`` proc to reduce typing. ## ## The template injects the ``it`` variable which you can use directly in an @@ -413,7 +413,7 @@ template mapIt*(varSeq, pred: expr) = ## assert nums[0] + nums[3] == 15 for i in 0 .. <len(varSeq): let it {.inject.} = varSeq[i] - varSeq[i] = pred + varSeq[i] = op template newSeqWith*(len: int, init: expr): expr = ## creates a new sequence, calling `init` to initialize each value. Example: diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 873e4b78e..2a40b4f1f 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -30,9 +30,28 @@ ## ## 1.3000000000000000e+00 ## true +## +## This module can also be used to comfortably create JSON using the `%*` +## operator: +## +## .. code-block:: nim +## +## var hisName = "John" +## let herAge = 31 +## var j = %* +## [ +## { +## "name": hisName, +## "age": 30 +## }, +## { +## "name": "Susan", +## "age": herAge +## } +## ] import - hashes, strutils, lexbase, streams, unicode + hashes, strutils, lexbase, streams, unicode, macros type JsonEventKind* = enum ## enumeration of all events that may occur when parsing @@ -625,6 +644,29 @@ proc `%`*(elements: openArray[JsonNode]): JsonNode = newSeq(result.elems, elements.len) for i, p in pairs(elements): result.elems[i] = p +proc toJson(x: PNimrodNode): PNimrodNode {.compiletime.} = + case x.kind + of nnkBracket: + result = newNimNode(nnkBracket) + for i in 0 .. <x.len: + result.add(toJson(x[i])) + + of nnkTableConstr: + result = newNimNode(nnkTableConstr) + for i in 0 .. <x.len: + assert x[i].kind == nnkExprColonExpr + result.add(newNimNode(nnkExprColonExpr).add(x[i][0]).add(toJson(x[i][1]))) + + else: + result = x + + result = prefix(result, "%") + +macro `%*`*(x: expr): expr = + ## Convert an expression to a JsonNode directly, without having to specify + ## `%` for every element. + result = toJson(x) + proc `==`* (a,b: JsonNode): bool = ## Check two nodes for equality if a.isNil: @@ -864,7 +906,7 @@ proc pretty*(node: JsonNode, indent = 2): string = proc `$`*(node: JsonNode): string = ## Converts `node` to its JSON Representation on one line. result = "" - toPretty(result, node, 1, false) + toPretty(result, node, 0, false) iterator items*(node: JsonNode): JsonNode = ## Iterator for the items of `node`. `node` has to be a JArray. @@ -1101,6 +1143,37 @@ when isMainModule: except: assert(false, "EInvalidIndex thrown for valid index") + # Generator: + var j = %* [{"name": "John", "age": 30}, {"name": "Susan", "age": 31}] + assert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}] + + var j2 = %* + [ + { + "name": "John", + "age": 30 + }, + { + "name": "Susan", + "age": 31 + } + ] + assert j2 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}] + + var name = "John" + let herAge = 30 + const hisAge = 31 + + var j3 = %* + [ { "name": "John" + , "age": herAge + } + , { "name": "Susan" + , "age": hisAge + } + ] + assert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}] + discard """ while true: var json = stdin.readLine() diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim index bb1835ed7..de733b75c 100644 --- a/lib/pure/logging.nim +++ b/lib/pure/logging.nim @@ -186,7 +186,7 @@ proc newRollingFileLogger*(filename = defaultFilename(), ## a new log file will be started and the old will be renamed. new(result) result.levelThreshold = levelThreshold - result.fmtStr = defaultFmtStr + result.fmtStr = fmtStr result.maxLines = maxLines result.f = open(filename, mode) result.curLine = 0 diff --git a/lib/pure/nimprof.nimrod.cfg b/lib/pure/nimprof.nim.cfg index 1589e7394..1589e7394 100644 --- a/lib/pure/nimprof.nimrod.cfg +++ b/lib/pure/nimprof.nim.cfg diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 147614d3d..f01343673 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1074,8 +1074,12 @@ when defined(windows): # because we support Windows GUI applications, things get really # messy here... when useWinUnicode: - proc strEnd(cstr: WideCString, c = 0'i32): WideCString {. - importc: "wcschr", header: "<string.h>".} + when defined(cpp): + proc strEnd(cstr: WideCString, c = 0'i32): WideCString {. + importcpp: "(NI16*)wcschr((const wchar_t *)#, #)", header: "<string.h>".} + else: + proc strEnd(cstr: WideCString, c = 0'i32): WideCString {. + importc: "wcschr", header: "<string.h>".} else: proc strEnd(cstr: cstring, c = 0'i32): cstring {. importc: "strchr", header: "<string.h>".} diff --git a/lib/pure/smtp.nimrod.cfg b/lib/pure/smtp.nim.cfg index 521e21de4..521e21de4 100644 --- a/lib/pure/smtp.nimrod.cfg +++ b/lib/pure/smtp.nim.cfg diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim index 5b7149d8e..727d5a386 100644 --- a/lib/pure/strtabs.nim +++ b/lib/pure/strtabs.nim @@ -112,7 +112,7 @@ proc `[]`*(t: StringTableRef, key: string): string {.rtl, extern: "nstGet".} = proc mget*(t: StringTableRef, key: string): var string {. rtl, extern: "nstTake".} = ## retrieves the location at ``t[key]``. If `key` is not in `t`, the - ## ``EInvalidKey`` exception is raised. + ## ``KeyError`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val else: raise newException(KeyError, "key does not exist: " & key) @@ -158,7 +158,7 @@ proc getValue(t: StringTableRef, flags: set[FormatFlag], key: string): string = else: result = "" if result.len == 0: if useKey in flags: result = '$' & key - elif not (useEmpty in flags): raiseFormatException(key) + elif useEmpty notin flags: raiseFormatException(key) proc newStringTable*(mode: StringTableMode): StringTableRef {. rtl, extern: "nst$1".} = diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 8dc9fe0d4..f4e42ee63 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -39,6 +39,7 @@ when declared(stdout): when not defined(ECMAScript): import terminal + system.addQuitProc(resetAttributes) type TestStatus* = enum OK, FAILED @@ -234,5 +235,3 @@ if envOutLvl.len > 0: if $opt == envOutLvl: outputLevel = opt break - -system.addQuitProc(resetAttributes) |