mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-05 19:34:12 +00:00
Merge remote-tracking branch 'upstream/devel' into devel
This commit is contained in:
@@ -71,7 +71,12 @@ type
|
||||
nnkEnumTy,
|
||||
nnkEnumFieldDef,
|
||||
nnkArglist, nnkPattern
|
||||
nnkReturnToken
|
||||
nnkReturnToken,
|
||||
nnkClosure,
|
||||
nnkGotoState,
|
||||
nnkState,
|
||||
nnkBreakState
|
||||
|
||||
NimNodeKinds* = set[NimNodeKind]
|
||||
NimTypeKind* = enum
|
||||
ntyNone, ntyBool, ntyChar, ntyEmpty,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2015 Nim Contributers
|
||||
# (c) Copyright 2015 Nim Contributors
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -508,7 +508,7 @@ iterator findIter*(str: string, pattern: Regex, start = 0, endpos = int.high): R
|
||||
## Variants:
|
||||
##
|
||||
## - ``proc findAll(...)`` returns a ``seq[string]``
|
||||
# see pcredemo for explaination
|
||||
# see pcredemo for explanation
|
||||
let matchesCrLf = pattern.matchesCrLf()
|
||||
let unicode = uint32(getinfo[culong](pattern, pcre.INFO_OPTIONS) and
|
||||
pcre.UTF8) > 0u32
|
||||
|
||||
@@ -91,10 +91,25 @@ __clang__
|
||||
# define NIM_CONST const
|
||||
#endif
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||||
# define NIM_THREADVAR __declspec(thread)
|
||||
#else
|
||||
/*
|
||||
NIM_THREADVAR declaration based on
|
||||
http://stackoverflow.com/questions/18298280/how-to-declare-a-variable-as-thread-local-portably
|
||||
*/
|
||||
#if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__
|
||||
# define NIM_THREADVAR _Thread_local
|
||||
#elif defined _WIN32 && ( \
|
||||
defined _MSC_VER || \
|
||||
defined __ICL || \
|
||||
defined __DMC__ || \
|
||||
defined __BORLANDC__ )
|
||||
# define NIM_THREADVAR __declspec(thread)
|
||||
/* note that ICC (linux) and Clang are covered by __GNUC__ */
|
||||
#elif defined __GNUC__ || \
|
||||
defined __SUNPRO_C || \
|
||||
defined __xlC__
|
||||
# define NIM_THREADVAR __thread
|
||||
#else
|
||||
# error "Cannot define NIM_THREADVAR"
|
||||
#endif
|
||||
|
||||
/* --------------- how int64 constants should be declared: ----------- */
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2015 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## PHP compatibility layer.
|
||||
|
||||
type
|
||||
PhpArray*[Key, Val] = ref object
|
||||
|
||||
PhpObj* = ref object ## can be a string, an int etc.
|
||||
|
||||
proc explode*(sep, x: string): seq[string] {.importc: "explode".}
|
||||
template split*(x, sep: string): seq[string] = explode(sep, x)
|
||||
|
||||
proc `$`*(x: PhpObj): string {.importcpp: "(#)".}
|
||||
proc `++`*(x: PhpObj) {.importcpp: "++(#)".}
|
||||
|
||||
proc `==`*(x, y: PhpObj): string {.importcpp: "((#) == (#))".}
|
||||
proc `<=`*(x, y: PhpObj): string {.importcpp: "((#) <= (#))".}
|
||||
proc `<`*(x, y: PhpObj): string {.importcpp: "((#) < (#))".}
|
||||
|
||||
proc toUpper*(x: string): string {.importc: "strtoupper".}
|
||||
proc toLower*(x: string): string {.importc: "strtolower".}
|
||||
|
||||
proc strtr*(s: string, replacePairs: PhpArray[string, string]): string {.importc.}
|
||||
proc strtr*(s, fromm, to: string): string {.importc.}
|
||||
|
||||
proc toArray*[K,V](pairs: openarray[(K,V)]): PhpArray[K,V] {.magic:
|
||||
"Array".}
|
||||
template strtr*(s: string, replacePairs: openarray[(string, string)]): string =
|
||||
strtr(toArray(replacePairs))
|
||||
|
||||
iterator pairs*[K,V](d: PhpArray[K,V]): (K,V) =
|
||||
var k: K
|
||||
var v: V
|
||||
{.emit: "foreach (`d` as `k`=>`v`) {".}
|
||||
yield (k, v)
|
||||
{.emit: "}".}
|
||||
|
||||
proc `[]`*[K,V](d: PhpArray[K,V]; k: K): V {.importcpp: "#[#]".}
|
||||
proc `[]=`*[K,V](d: PhpArray[K,V]; k: K; v: V) {.importcpp: "#[#] = #".}
|
||||
|
||||
proc ksort*[K,V](d: PhpArray[K,V]) {.importc.}
|
||||
proc krsort*[K,V](d: PhpArray[K,V]) {.importc.}
|
||||
proc keys*[K,V](d: PhpArray[K,V]): seq[K] {.importc.}
|
||||
@@ -163,7 +163,11 @@ proc `[]`*[A](s: var HashSet[A], key: A): var A =
|
||||
var hc: Hash
|
||||
var index = rawGet(s, key, hc)
|
||||
if index >= 0: result = s.data[index].key
|
||||
else: raise newException(KeyError, "key not found: " & $key)
|
||||
else:
|
||||
when compiles($key):
|
||||
raise newException(KeyError, "key not found: " & $key)
|
||||
else:
|
||||
raise newException(KeyError, "key not found")
|
||||
|
||||
proc mget*[A](s: var HashSet[A], key: A): var A {.deprecated.} =
|
||||
## returns the element that is actually stored in 's' which has the same
|
||||
|
||||
@@ -51,7 +51,10 @@
|
||||
## ]
|
||||
|
||||
import
|
||||
hashes, strutils, lexbase, streams, unicode, macros
|
||||
hashes, tables, strutils, lexbase, streams, unicode, macros
|
||||
|
||||
export
|
||||
tables.`$`
|
||||
|
||||
type
|
||||
JsonEventKind* = enum ## enumeration of all events that may occur when parsing
|
||||
@@ -567,7 +570,7 @@ type
|
||||
of JNull:
|
||||
nil
|
||||
of JObject:
|
||||
fields*: seq[tuple[key: string, val: JsonNode]]
|
||||
fields*: Table[string, JsonNode]
|
||||
of JArray:
|
||||
elems*: seq[JsonNode]
|
||||
|
||||
@@ -617,7 +620,7 @@ proc newJObject*(): JsonNode =
|
||||
## Creates a new `JObject JsonNode`
|
||||
new(result)
|
||||
result.kind = JObject
|
||||
result.fields = @[]
|
||||
result.fields = initTable[string, JsonNode](4)
|
||||
|
||||
proc newJArray*(): JsonNode =
|
||||
## Creates a new `JArray JsonNode`
|
||||
@@ -657,8 +660,8 @@ proc getBVal*(n: JsonNode, default: bool = false): bool =
|
||||
else: return n.bval
|
||||
|
||||
proc getFields*(n: JsonNode,
|
||||
default: seq[tuple[key: string, val: JsonNode]] = @[]):
|
||||
seq[tuple[key: string, val: JsonNode]] =
|
||||
default = initTable[string, JsonNode](4)):
|
||||
Table[string, JsonNode] =
|
||||
## Retrieves the key, value pairs of a `JObject JsonNode`.
|
||||
##
|
||||
## Returns ``default`` if ``n`` is not a ``JObject``, or if ``n`` is nil.
|
||||
@@ -700,8 +703,8 @@ proc `%`*(keyVals: openArray[tuple[key: string, val: JsonNode]]): JsonNode =
|
||||
## Generic constructor for JSON data. Creates a new `JObject JsonNode`
|
||||
new(result)
|
||||
result.kind = JObject
|
||||
newSeq(result.fields, keyVals.len)
|
||||
for i, p in pairs(keyVals): result.fields[i] = p
|
||||
result.fields = initTable[string, JsonNode](4)
|
||||
for key, val in items(keyVals): result.fields[key] = val
|
||||
|
||||
proc `%`*(elements: openArray[JsonNode]): JsonNode =
|
||||
## Generic constructor for JSON data. Creates a new `JArray JsonNode`
|
||||
@@ -761,7 +764,9 @@ proc `==`* (a,b: JsonNode): bool =
|
||||
of JObject:
|
||||
a.fields == b.fields
|
||||
|
||||
proc hash* (n:JsonNode): Hash =
|
||||
proc hash*(n: Table[string, JsonNode]): Hash {.noSideEffect.}
|
||||
|
||||
proc hash*(n: JsonNode): Hash =
|
||||
## Compute the hash for a JSON node
|
||||
case n.kind
|
||||
of JArray:
|
||||
@@ -779,6 +784,11 @@ proc hash* (n:JsonNode): Hash =
|
||||
of JNull:
|
||||
result = hash(0)
|
||||
|
||||
proc hash*(n: Table[string, JsonNode]): Hash =
|
||||
for key, val in n:
|
||||
result = result !& hash(key) !& hash(val)
|
||||
result = !$result
|
||||
|
||||
proc len*(n: JsonNode): int =
|
||||
## If `n` is a `JArray`, it returns the number of elements.
|
||||
## If `n` is a `JObject`, it returns the number of pairs.
|
||||
@@ -793,10 +803,7 @@ proc `[]`*(node: JsonNode, name: string): JsonNode {.inline.} =
|
||||
## If the value at `name` does not exist, returns nil
|
||||
assert(not isNil(node))
|
||||
assert(node.kind == JObject)
|
||||
for key, item in items(node.fields):
|
||||
if key == name:
|
||||
return item
|
||||
return nil
|
||||
result = node.fields.getOrDefault(name)
|
||||
|
||||
proc `[]`*(node: JsonNode, index: int): JsonNode {.inline.} =
|
||||
## Gets the node at `index` in an Array. Result is undefined if `index`
|
||||
@@ -808,8 +815,7 @@ proc `[]`*(node: JsonNode, index: int): JsonNode {.inline.} =
|
||||
proc hasKey*(node: JsonNode, key: string): bool =
|
||||
## Checks if `key` exists in `node`.
|
||||
assert(node.kind == JObject)
|
||||
for k, item in items(node.fields):
|
||||
if k == key: return true
|
||||
result = node.fields.hasKey(key)
|
||||
|
||||
proc existsKey*(node: JsonNode, key: string): bool {.deprecated.} = node.hasKey(key)
|
||||
## Deprecated for `hasKey`
|
||||
@@ -820,20 +826,14 @@ proc add*(father, child: JsonNode) =
|
||||
father.elems.add(child)
|
||||
|
||||
proc add*(obj: JsonNode, key: string, val: JsonNode) =
|
||||
## Adds ``(key, val)`` pair to the JObject node `obj`. For speed
|
||||
## reasons no check for duplicate keys is performed!
|
||||
## But ``[]=`` performs the check.
|
||||
## Sets a field from a `JObject`.
|
||||
assert obj.kind == JObject
|
||||
obj.fields.add((key, val))
|
||||
obj.fields[key] = val
|
||||
|
||||
proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) {.inline.} =
|
||||
## Sets a field from a `JObject`. Performs a check for duplicate keys.
|
||||
## Sets a field from a `JObject`.
|
||||
assert(obj.kind == JObject)
|
||||
for i in 0..obj.fields.len-1:
|
||||
if obj.fields[i].key == key:
|
||||
obj.fields[i].val = val
|
||||
return
|
||||
obj.fields.add((key, val))
|
||||
obj.fields[key] = val
|
||||
|
||||
proc `{}`*(node: JsonNode, keys: varargs[string]): JsonNode =
|
||||
## Traverses the node and gets the given value. If any of the
|
||||
@@ -856,13 +856,11 @@ proc `{}=`*(node: JsonNode, keys: varargs[string], value: JsonNode) =
|
||||
node[keys[keys.len-1]] = value
|
||||
|
||||
proc delete*(obj: JsonNode, key: string) =
|
||||
## Deletes ``obj[key]`` preserving the order of the other (key, value)-pairs.
|
||||
## Deletes ``obj[key]``.
|
||||
assert(obj.kind == JObject)
|
||||
for i in 0..obj.fields.len-1:
|
||||
if obj.fields[i].key == key:
|
||||
obj.fields.delete(i)
|
||||
return
|
||||
raise newException(IndexError, "key not in object")
|
||||
if not obj.fields.hasKey(key):
|
||||
raise newException(IndexError, "key not in object")
|
||||
obj.fields.del(key)
|
||||
|
||||
proc copy*(p: JsonNode): JsonNode =
|
||||
## Performs a deep copy of `a`.
|
||||
@@ -879,8 +877,8 @@ proc copy*(p: JsonNode): JsonNode =
|
||||
result = newJNull()
|
||||
of JObject:
|
||||
result = newJObject()
|
||||
for key, field in items(p.fields):
|
||||
result.fields.add((key, copy(field)))
|
||||
for key, val in pairs(p.fields):
|
||||
result.fields[key] = copy(val)
|
||||
of JArray:
|
||||
result = newJArray()
|
||||
for i in items(p.elems):
|
||||
@@ -924,15 +922,17 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
||||
if node.fields.len > 0:
|
||||
result.add("{")
|
||||
result.nl(ml) # New line
|
||||
for i in 0..len(node.fields)-1:
|
||||
var i = 0
|
||||
for key, val in pairs(node.fields):
|
||||
if i > 0:
|
||||
result.add(", ")
|
||||
result.nl(ml) # New Line
|
||||
inc i
|
||||
# Need to indent more than {
|
||||
result.indent(newIndent(currIndent, indent, ml))
|
||||
result.add(escapeJson(node.fields[i].key))
|
||||
result.add(escapeJson(key))
|
||||
result.add(": ")
|
||||
toPretty(result, node.fields[i].val, indent, ml, false,
|
||||
toPretty(result, val, indent, ml, false,
|
||||
newIndent(currIndent, indent, ml))
|
||||
result.nl(ml)
|
||||
result.indent(currIndent) # indent the same as {
|
||||
@@ -994,7 +994,7 @@ proc toUgly*(result: var string, node: JsonNode) =
|
||||
result.add "]"
|
||||
of JObject:
|
||||
result.add "{"
|
||||
for key, value in items(node.fields):
|
||||
for key, value in pairs(node.fields):
|
||||
if comma: result.add ","
|
||||
else: comma = true
|
||||
result.add key.escapeJson()
|
||||
@@ -1033,15 +1033,15 @@ iterator mitems*(node: var JsonNode): var JsonNode =
|
||||
iterator pairs*(node: JsonNode): tuple[key: string, val: JsonNode] =
|
||||
## Iterator for the child elements of `node`. `node` has to be a JObject.
|
||||
assert node.kind == JObject
|
||||
for key, val in items(node.fields):
|
||||
for key, val in pairs(node.fields):
|
||||
yield (key, val)
|
||||
|
||||
iterator mpairs*(node: var JsonNode): var tuple[key: string, val: JsonNode] =
|
||||
iterator mpairs*(node: var JsonNode): tuple[key: string, val: var JsonNode] =
|
||||
## Iterator for the child elements of `node`. `node` has to be a JObject.
|
||||
## Items can be modified
|
||||
## Values can be modified
|
||||
assert node.kind == JObject
|
||||
for keyVal in mitems(node.fields):
|
||||
yield keyVal
|
||||
for key, val in mpairs(node.fields):
|
||||
yield (key, val)
|
||||
|
||||
proc eat(p: var JsonParser, tok: TokKind) =
|
||||
if p.tok == tok: discard getTok(p)
|
||||
@@ -1123,9 +1123,9 @@ else:
|
||||
|
||||
proc parseNativeJson(x: cstring): JSObject {.importc: "JSON.parse".}
|
||||
|
||||
proc getVarType(x): JsonNodeKind =
|
||||
proc getVarType(x: JSObject): JsonNodeKind =
|
||||
result = JNull
|
||||
proc getProtoName(y): cstring
|
||||
proc getProtoName(y: JSObject): cstring
|
||||
{.importc: "Object.prototype.toString.call".}
|
||||
case $getProtoName(x) # TODO: Implicit returns fail here.
|
||||
of "[object Array]": return JArray
|
||||
@@ -1216,23 +1216,27 @@ when false:
|
||||
# To get that we shall use, obj["json"]
|
||||
|
||||
when isMainModule:
|
||||
var parsed = parseFile("tests/testdata/jsontest.json")
|
||||
var parsed2 = parseFile("tests/testdata/jsontest2.json")
|
||||
when not defined(js):
|
||||
var parsed = parseFile("tests/testdata/jsontest.json")
|
||||
|
||||
try:
|
||||
discard parsed["key2"][12123]
|
||||
assert(false)
|
||||
except IndexError: assert(true)
|
||||
try:
|
||||
discard parsed["key2"][12123]
|
||||
doAssert(false)
|
||||
except IndexError: doAssert(true)
|
||||
|
||||
var parsed2 = parseFile("tests/testdata/jsontest2.json")
|
||||
doAssert(parsed2{"repository", "description"}.str=="IRC Library for Haskell", "Couldn't fetch via multiply nested key using {}")
|
||||
|
||||
let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd", "c": "\ud83c\udf83", "d": "\u00E6"}"""
|
||||
# nil passthrough
|
||||
assert(testJson{"doesnt_exist"}{"anything"}.isNil)
|
||||
doAssert(testJson{"doesnt_exist"}{"anything"}.isNil)
|
||||
testJson{["e", "f"]} = %true
|
||||
assert(testJson["e"]["f"].bval)
|
||||
doAssert(testJson["e"]["f"].bval)
|
||||
|
||||
# make sure UTF-16 decoding works.
|
||||
assert(testJson["c"].str == "🎃")
|
||||
assert(testJson["d"].str == "æ")
|
||||
when not defined(js): # TODO: The following line asserts in JS
|
||||
doAssert(testJson["c"].str == "🎃")
|
||||
doAssert(testJson["d"].str == "æ")
|
||||
|
||||
# make sure no memory leek when parsing invalid string
|
||||
let startMemory = getOccupiedMem()
|
||||
@@ -1242,41 +1246,43 @@ when isMainModule:
|
||||
except:
|
||||
discard
|
||||
# memory diff should less than 2M
|
||||
assert(abs(getOccupiedMem() - startMemory) < 2 * 1024 * 1024)
|
||||
doAssert(abs(getOccupiedMem() - startMemory) < 2 * 1024 * 1024)
|
||||
|
||||
|
||||
# test `$`
|
||||
let stringified = $testJson
|
||||
let parsedAgain = parseJson(stringified)
|
||||
assert(parsedAgain["b"].str == "asd")
|
||||
doAssert(parsedAgain["b"].str == "asd")
|
||||
|
||||
parsedAgain["abc"] = %5
|
||||
doAssert parsedAgain["abc"].num == 5
|
||||
|
||||
# Bounds checking
|
||||
try:
|
||||
let a = testJson["a"][9]
|
||||
assert(false, "EInvalidIndex not thrown")
|
||||
doAssert(false, "EInvalidIndex not thrown")
|
||||
except IndexError:
|
||||
discard
|
||||
try:
|
||||
let a = testJson["a"][-1]
|
||||
assert(false, "EInvalidIndex not thrown")
|
||||
doAssert(false, "EInvalidIndex not thrown")
|
||||
except IndexError:
|
||||
discard
|
||||
try:
|
||||
assert(testJson["a"][0].num == 1, "Index doesn't correspond to its value")
|
||||
doAssert(testJson["a"][0].num == 1, "Index doesn't correspond to its value")
|
||||
except:
|
||||
assert(false, "EInvalidIndex thrown for valid index")
|
||||
doAssert(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(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")
|
||||
doAssert(testJson{"b"}.str=="asd", "Couldn't fetch a singly nested key with {}")
|
||||
doAssert(isNil(testJson{"nonexistent"}), "Non-existent keys should return nil")
|
||||
doAssert(isNil(testJson{"a", "b"}), "Indexing through a list should return nil")
|
||||
doAssert(isNil(testJson{"a", "b"}), "Indexing through a list should return nil")
|
||||
doAssert(testJson{"a"}==parseJson"[1, 2, 3, 4]", "Didn't return a non-JObject when there was one to be found")
|
||||
doAssert(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}]
|
||||
doAssert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||
|
||||
var j2 = %*
|
||||
[
|
||||
@@ -1289,7 +1295,7 @@ when isMainModule:
|
||||
"age": 31
|
||||
}
|
||||
]
|
||||
assert j2 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||
doAssert j2 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||
|
||||
var name = "John"
|
||||
let herAge = 30
|
||||
@@ -1303,4 +1309,4 @@ when isMainModule:
|
||||
, "age": hisAge
|
||||
}
|
||||
]
|
||||
assert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||
doAssert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||
|
||||
@@ -616,7 +616,7 @@ proc readIntoBuf(socket: Socket, flags: int32): int =
|
||||
else:
|
||||
result = recv(socket.fd, addr(socket.buffer), cint(socket.buffer.high), flags)
|
||||
if result < 0:
|
||||
# Save it in case it gets reset (the Nim codegen occassionally may call
|
||||
# Save it in case it gets reset (the Nim codegen occasionally may call
|
||||
# Win API functions which reset it).
|
||||
socket.lastError = osLastError()
|
||||
if result <= 0:
|
||||
|
||||
@@ -288,19 +288,19 @@ proc rawGetTok(c: var CfgParser, tok: var Token) =
|
||||
else: getSymbol(c, tok)
|
||||
|
||||
proc errorStr*(c: CfgParser, msg: string): string {.rtl, extern: "npc$1".} =
|
||||
## returns a properly formated error message containing current line and
|
||||
## returns a properly formatted error message containing current line and
|
||||
## column information.
|
||||
result = `%`("$1($2, $3) Error: $4",
|
||||
[c.filename, $getLine(c), $getColumn(c), msg])
|
||||
|
||||
proc warningStr*(c: CfgParser, msg: string): string {.rtl, extern: "npc$1".} =
|
||||
## returns a properly formated warning message containing current line and
|
||||
## returns a properly formatted warning message containing current line and
|
||||
## column information.
|
||||
result = `%`("$1($2, $3) Warning: $4",
|
||||
[c.filename, $getLine(c), $getColumn(c), msg])
|
||||
|
||||
proc ignoreMsg*(c: CfgParser, e: CfgEvent): string {.rtl, extern: "npc$1".} =
|
||||
## returns a properly formated warning message containing that
|
||||
## returns a properly formatted warning message containing that
|
||||
## an entry is ignored.
|
||||
case e.kind
|
||||
of cfgSectionStart: result = c.warningStr("section ignored: " & e.section)
|
||||
|
||||
@@ -344,7 +344,7 @@ proc roots*(p:Poly,tol=1.0e-9,zerotol=1.0e-6,mergetol=1.0e-12,maxiter=1000):seq[
|
||||
## `tol` is the tolerance used to break searching for each root when reached.
|
||||
## `zerotol` is the tolerance, which is 'close enough' to zero to be considered a root
|
||||
## and is used to find roots for curves that only 'touch' the x-axis.
|
||||
## `mergetol` is the tolerance, of which two x-values are considered beeing the same root.
|
||||
## `mergetol` is the tolerance, of which two x-values are considered being the same root.
|
||||
## `maxiter` can be used to limit the number of iterations for each root.
|
||||
## Returns a (possibly empty) sorted sequence with the solutions.
|
||||
var deg=p.degree
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# The Nim Compiler
|
||||
# (c) Copyright 2015 Nim Contributers
|
||||
# (c) Copyright 2015 Nim Contributors
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
||||
@@ -189,7 +189,7 @@ proc readBool*(s: Stream): bool =
|
||||
read(s, result)
|
||||
|
||||
proc peekBool*(s: Stream): bool =
|
||||
## peeks a bool from the stream `s`. Raises `EIO` if an error occured.
|
||||
## peeks a bool from the stream `s`. Raises `EIO` if an error occurred.
|
||||
peek(s, result)
|
||||
|
||||
proc readInt8*(s: Stream): int8 =
|
||||
|
||||
@@ -635,7 +635,7 @@ elif defined(JS):
|
||||
|
||||
proc toSeconds(time: Time): float = result = time.getTime() / 1000
|
||||
|
||||
proc getTimezone(): int = result = newDate().getTimezoneOffset()
|
||||
proc getTimezone(): int = result = newDate().getTimezoneOffset() * 60
|
||||
|
||||
proc epochTime*(): float {.tags: [TimeEffect].} = newDate().toSeconds()
|
||||
|
||||
@@ -1245,7 +1245,7 @@ proc getDayOfWeek*(day, month, year: int): WeekDay =
|
||||
result = (d-1).WeekDay
|
||||
|
||||
proc getDayOfWeekJulian*(day, month, year: int): WeekDay =
|
||||
## Returns the day of the week enum from day, month and year, according to the Julian calender.
|
||||
## Returns the day of the week enum from day, month and year, according to the Julian calendar.
|
||||
# Day & month start from one.
|
||||
let
|
||||
a = (14 - month) div 12
|
||||
|
||||
@@ -255,13 +255,13 @@ proc `/`*(x: Uri, path: string): Uri =
|
||||
## Examples:
|
||||
##
|
||||
## .. code-block::
|
||||
## let foo = parseUri("http://example.com/foo/bar") / parseUri("/baz")
|
||||
## let foo = parseUri("http://example.com/foo/bar") / "/baz"
|
||||
## assert foo.path == "/foo/bar/baz"
|
||||
##
|
||||
## let bar = parseUri("http://example.com/foo/bar") / parseUri("baz")
|
||||
## let bar = parseUri("http://example.com/foo/bar") / "baz"
|
||||
## assert bar.path == "/foo/bar/baz"
|
||||
##
|
||||
## let bar = parseUri("http://example.com/foo/bar/") / parseUri("baz")
|
||||
## let bar = parseUri("http://example.com/foo/bar/") / "baz"
|
||||
## assert bar.path == "/foo/bar/baz"
|
||||
result = x
|
||||
if result.path[result.path.len-1] == '/':
|
||||
|
||||
@@ -279,11 +279,6 @@ when not defined(niminheritable):
|
||||
when not defined(nimunion):
|
||||
{.pragma: unchecked.}
|
||||
|
||||
when defined(nimNewShared):
|
||||
type
|
||||
`shared`* {.magic: "Shared".}
|
||||
guarded* {.magic: "Guarded".}
|
||||
|
||||
# comparison operators:
|
||||
proc `==` *[Enum: enum](x, y: Enum): bool {.magic: "EqEnum", noSideEffect.}
|
||||
## Checks whether values within the *same enum* have the same underlying value
|
||||
@@ -2624,6 +2619,12 @@ when not defined(JS): #and not defined(nimscript):
|
||||
elif x > y: result = 1
|
||||
else: result = 0
|
||||
|
||||
when defined(nimscript):
|
||||
proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], benign.}
|
||||
## Opens a file named `filename` for writing. Then writes the
|
||||
## `content` completely to the file and closes the file afterwards.
|
||||
## Raises an IO exception in case of an error.
|
||||
|
||||
when not defined(nimscript) and hostOS != "standalone":
|
||||
when defined(windows):
|
||||
# work-around C's sucking abstraction:
|
||||
|
||||
@@ -103,9 +103,9 @@ else:
|
||||
proc c_setjmp(jmpb: C_JmpBuf): cint {.
|
||||
header: "<setjmp.h>", importc: "setjmp".}
|
||||
|
||||
proc c_signal(sig: cint, handler: proc (a: cint) {.noconv.}) {.
|
||||
proc c_signal(sign: cint, handler: proc (a: cint) {.noconv.}) {.
|
||||
importc: "signal", header: "<signal.h>".}
|
||||
proc c_raise(sig: cint) {.importc: "raise", header: "<signal.h>".}
|
||||
proc c_raise(sign: cint) {.importc: "raise", header: "<signal.h>".}
|
||||
|
||||
proc c_fputs(c: cstring, f: C_TextFileStar) {.importc: "fputs",
|
||||
header: "<stdio.h>".}
|
||||
|
||||
@@ -316,7 +316,7 @@ when defined(endb):
|
||||
dbgAborting: bool # whether the debugger wants to abort
|
||||
|
||||
when not defined(noSignalHandler):
|
||||
proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
|
||||
proc signalHandler(sign: cint) {.exportc: "signalHandler", noconv.} =
|
||||
template processSignal(s, action: expr) {.immediate, dirty.} =
|
||||
if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n")
|
||||
elif s == SIGSEGV:
|
||||
@@ -342,13 +342,13 @@ when not defined(noSignalHandler):
|
||||
GC_disable()
|
||||
var buf = newStringOfCap(2000)
|
||||
rawWriteStackTrace(buf)
|
||||
processSignal(sig, buf.add) # nice hu? currying a la Nim :-)
|
||||
processSignal(sign, buf.add) # nice hu? currying a la Nim :-)
|
||||
showErrorMessage(buf)
|
||||
GC_enable()
|
||||
else:
|
||||
var msg: cstring
|
||||
template asgn(y: expr) = msg = y
|
||||
processSignal(sig, asgn)
|
||||
processSignal(sign, asgn)
|
||||
showErrorMessage(msg)
|
||||
when defined(endb): dbgAborting = true
|
||||
quit(1) # always quit when SIGABRT
|
||||
@@ -367,6 +367,6 @@ when not defined(noSignalHandler):
|
||||
|
||||
proc setControlCHook(hook: proc () {.noconv.} not nil) =
|
||||
# ugly cast, but should work on all architectures:
|
||||
type SignalHandler = proc (sig: cint) {.noconv, benign.}
|
||||
type SignalHandler = proc (sign: cint) {.noconv, benign.}
|
||||
{.deprecated: [TSignalHandler: SignalHandler].}
|
||||
c_signal(SIGINT, cast[SignalHandler](hook))
|
||||
|
||||
@@ -91,7 +91,7 @@ when allowForeignThreadGc:
|
||||
## this thread will only be initialized once per thread, no matter how often
|
||||
## it is called.
|
||||
##
|
||||
## This function is availble only when ``--threads:on`` and ``--tlsEmulation:off``
|
||||
## This function is available only when ``--threads:on`` and ``--tlsEmulation:off``
|
||||
## switches are used
|
||||
if not localGcInitialized:
|
||||
localGcInitialized = true
|
||||
@@ -100,7 +100,7 @@ when allowForeignThreadGc:
|
||||
initGC()
|
||||
else:
|
||||
template setupForeignThreadGc*(): stmt =
|
||||
{.error: "setupForeignThreadGc is availble only when ``--threads:on`` and ``--tlsEmulation:off`` are used".}
|
||||
{.error: "setupForeignThreadGc is available only when ``--threads:on`` and ``--tlsEmulation:off`` are used".}
|
||||
|
||||
# ----------------- stack management --------------------------------------
|
||||
# inspired from Smart Eiffel
|
||||
|
||||
@@ -74,7 +74,7 @@ proc getEnv*(key: string): string {.tags: [ReadIOEffect].} =
|
||||
builtin
|
||||
|
||||
proc existsEnv*(key: string): bool {.tags: [ReadIOEffect].} =
|
||||
## Checks for the existance of an environment variable named `key`.
|
||||
## Checks for the existence of an environment variable named `key`.
|
||||
builtin
|
||||
|
||||
proc fileExists*(filename: string): bool {.tags: [ReadIOEffect].} =
|
||||
@@ -189,7 +189,7 @@ proc get*(key: string): string =
|
||||
builtin
|
||||
|
||||
proc exists*(key: string): bool =
|
||||
## Checks for the existance of a configuration 'key'
|
||||
## Checks for the existence of a configuration 'key'
|
||||
## like 'gcc.options.always'.
|
||||
builtin
|
||||
|
||||
|
||||
Reference in New Issue
Block a user