Merge branch 'devel' of github.com:nim-lang/Nim into devel

This commit is contained in:
Araq
2017-05-09 17:26:54 +02:00
12 changed files with 318 additions and 27 deletions

View File

@@ -1864,8 +1864,8 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
proc genSetConstr(p: PProc, n: PNode, r: var TCompRes) =
var
a, b: TCompRes
useMagic(p, "SetConstr")
r.res = rope("SetConstr(")
useMagic(p, "setConstr")
r.res = rope("setConstr(")
r.kind = resExpr
for i in countup(0, sonsLen(n) - 1):
if i > 0: add(r.res, ", ")
@@ -1878,6 +1878,12 @@ proc genSetConstr(p: PProc, n: PNode, r: var TCompRes) =
gen(p, it, a)
add(r.res, a.res)
add(r.res, ")")
# emit better code for constant sets:
if p.target == targetJS and isDeepConstExpr(n):
inc(p.g.unique)
let tmp = rope("ConstSet") & rope(p.g.unique)
addf(p.g.constants, "var $1 = $2;$n", [tmp, r.res])
r.res = tmp
proc genArrayConstr(p: PProc, n: PNode, r: var TCompRes) =
var a: TCompRes

View File

@@ -96,7 +96,7 @@ proc isDeepConstExpr*(n: PNode): bool =
result = true
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv:
result = isDeepConstExpr(n.sons[1])
of nkCurly, nkBracket, nkPar, nkObjConstr, nkClosure:
of nkCurly, nkBracket, nkPar, nkObjConstr, nkClosure, nkRange:
for i in ord(n.kind == nkObjConstr) .. <n.len:
if not isDeepConstExpr(n.sons[i]): return false
if n.typ.isNil: result = true

View File

@@ -1651,8 +1651,16 @@ proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode,
for i in 0 .. <gp.len:
if sfImmediate notin sym.flags:
let idx = sym.typ.len + i
tos.slots[idx] = setupMacroParam(n.sons[idx], gp[i].sym.typ)
if idx < n.len:
tos.slots[idx] = setupMacroParam(n.sons[idx], gp[i].sym.typ)
else:
dec(evalMacroCounter)
c.callsite = nil
localError(n.info, "expected " & $gp.len &
" generic parameter(s)")
elif gp[i].sym.typ.kind in {tyStatic, tyTypeDesc}:
dec(evalMacroCounter)
c.callsite = nil
globalError(n.info, "static[T] or typedesc nor supported for .immediate macros")
# temporary storage:
#for i in L .. <maxSlots: tos.slots[i] = newNode(nkEmpty)

View File

@@ -242,6 +242,11 @@ when defined(windows) or defined(nimdoc):
if gDisp.isNil: gDisp = newDispatcher()
result = gDisp
proc setGlobalDispatcher*(disp: PDispatcher) =
if not gDisp.isNil:
assert gDisp.callbacks.len == 0
gDisp = disp
proc register*(fd: AsyncFD) =
## Registers ``fd`` with the dispatcher.
let p = getGlobalDispatcher()
@@ -931,6 +936,11 @@ else:
if gDisp.isNil: gDisp = newDispatcher()
result = gDisp
proc setGlobalDispatcher*(disp: PDispatcher) =
if not gDisp.isNil:
assert gDisp.callbacks.len == 0
gDisp = disp
proc update(fd: AsyncFD, events: set[Event]) =
let p = getGlobalDispatcher()
assert fd.SocketHandle in p.selector

View File

@@ -269,6 +269,18 @@ proc del*[A, B](t: var Table[A, B], key: A) =
## deletes `key` from hash table `t`.
delImpl()
proc take*[A, B](t: var Table[A, B], key: A, val: var B): bool =
## Deletes the ``key`` from the table.
## Returns ``true``, if the ``key`` existed, and sets ``val`` to the
## mapping of the key. Otherwise, returns ``false``, and the ``val`` is
## unchanged.
var hc: Hash
var index = rawGet(t, key, hc)
result = index >= 0
if result:
shallowCopy(val, t.data[index].val)
delImplIdx(t, index)
proc enlarge[A, B](t: var Table[A, B]) =
var n: KeyValuePairSeq[A, B]
newSeq(n, len(t.data) * growthFactor)
@@ -424,6 +436,13 @@ proc del*[A, B](t: TableRef[A, B], key: A) =
## deletes `key` from hash table `t`.
t[].del(key)
proc take*[A, B](t: TableRef[A, B], key: A, val: var B): bool =
## Deletes the ``key`` from the table.
## Returns ``true``, if the ``key`` existed, and sets ``val`` to the
## mapping of the key. Otherwise, returns ``false``, and the ``val`` is
## unchanged.
result = t[].take(key, val)
proc newTable*[A, B](initialSize=64): TableRef[A, B] =
new(result)
result[] = initTable[A, B](initialSize)
@@ -625,7 +644,7 @@ proc `==`*[A, B](s, t: OrderedTable[A, B]): bool =
while ht >= 0 and hs >= 0:
var nxtt = t.data[ht].next
var nxts = s.data[hs].next
if isFilled(t.data[ht].hcode) and isFilled(s.data[hs].hcode):
if isFilled(t.data[ht].hcode) and isFilled(s.data[hs].hcode):
if (s.data[hs].key != t.data[ht].key) and (s.data[hs].val != t.data[ht].val):
return false
ht = nxtt
@@ -829,7 +848,7 @@ proc clear*[A](t: CountTableRef[A]) =
proc clear*[A](t: var CountTable[A]) =
## Resets the table so that it is empty.
clearImpl()
iterator pairs*[A](t: CountTable[A]): (A, int) =
## iterates over any (key, value) pair in the table `t`.
for h in 0..high(t.data):
@@ -1256,17 +1275,17 @@ when isMainModule:
var b = newOrderedTable[string, string](initialSize=2)
b.add("wrong?", "foo")
b.add("wrong?", "foo2")
assert a == b
assert a == b
block: #5482
var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
var b = newOrderedTable[string, string](initialSize=2)
b.add("wrong?", "foo")
b.add("wrong?", "foo2")
assert a == b
assert a == b
block: #5487
var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
var b = newOrderedTable[string, string]() # notice, default size!
b.add("wrong?", "foo")
b.add("wrong?", "foo2")
@@ -1279,13 +1298,13 @@ when isMainModule:
b.add("wrong?", "foo2")
assert a == b
block:
var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
var b = [("wrong?","foo"), ("wrong?", "foo2")].newOrderedTable()
block:
var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
var b = [("wrong?","foo"), ("wrong?", "foo2")].newOrderedTable()
var c = newOrderedTable[string, string]() # notice, default size!
c.add("wrong?", "foo")
c.add("wrong?", "foo2")
c.add("wrong?", "foo2")
assert a == b
assert a == c

View File

@@ -335,7 +335,8 @@ proc execProcesses*(cmds: openArray[string],
if afterRunEvent != nil: afterRunEvent(i, p)
close(p)
proc select*(readfds: var seq[Process], timeout = 500): int {.benign.}
proc select*(readfds: var seq[Process], timeout = 500): int
{.benign, deprecated.}
## `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
@@ -343,6 +344,9 @@ proc select*(readfds: var seq[Process], timeout = 500): int {.benign.}
##
## **Warning**: This function may give unexpected or completely wrong
## results on Windows.
##
## **Deprecated since version 0.17.0**: This procedure isn't cross-platform
## and so should not be used in newly written code.
when not defined(useNimRtl):
proc execProcess(command: string,

View File

@@ -201,7 +201,7 @@ proc parseWhile*(s: string, token: var string, validChars: set[char],
proc captureBetween*(s: string, first: char, second = '\0', start = 0): string =
## Finds the first occurrence of ``first``, then returns everything from there
## up to ``second``(if ``second`` is '\0', then ``first`` is used).
## up to ``second`` (if ``second`` is '\0', then ``first`` is used).
var i = skipUntil(s, first, start)+1+start
result = ""
discard s.parseUntil(result, if second == '\0': first else: second, i)

View File

@@ -172,7 +172,7 @@ proc raiseIndexError() {.compilerproc, noreturn.} =
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
raise newException(FieldError, f & " is not accessible")
proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} =
proc setConstr() {.varargs, asmNoStackFrame, compilerproc.} =
when defined(nimphp):
asm """
$args = func_get_args();

View File

@@ -219,6 +219,11 @@ when defined(windows) or defined(nimdoc):
if gDisp.isNil: gDisp = newDispatcher()
result = gDisp
proc setGlobalDispatcher*(disp: PDispatcher) =
if not gDisp.isNil:
assert gDisp.callbacks.len == 0
gDisp = disp
proc register*(fd: AsyncFD) =
## Registers ``fd`` with the dispatcher.
let p = getGlobalDispatcher()
@@ -1080,6 +1085,11 @@ else:
if gDisp.isNil: gDisp = newDispatcher()
result = gDisp
proc setGlobalDispatcher*(disp: PDispatcher) =
if not gDisp.isNil:
assert gDisp.callbacks.len == 0
gDisp = disp
proc register*(fd: AsyncFD) =
let p = getGlobalDispatcher()
var data = newAsyncData()

View File

@@ -235,6 +235,21 @@ block withKeyTest:
except KeyError:
discard
block takeTest:
var t = initTable[string, int]()
t["key"] = 123
var val = 0
assert(t.take("key", val))
assert(val == 123)
val = -1
assert(not t.take("key", val))
assert(val == -1)
assert(not t.take("otherkey", val))
assert(val == -1)
proc orderedTableSortTest() =
var t = initOrderedTable[string, int](2)
for key, val in items(data): t[key] = val

View File

@@ -104,15 +104,17 @@ proc syncTest() =
client.close()
# Timeout test.
client = newHttpClient(timeout = 1)
try:
resp = client.request("http://example.com/")
doAssert false, "TimeoutError should have been raised."
except TimeoutError:
discard
except:
doAssert false, "TimeoutError should have been raised."
when false:
# Disabled for now because it causes troubles with AppVeyor
# Timeout test.
client = newHttpClient(timeout = 1)
try:
resp = client.request("http://example.com/")
doAssert false, "TimeoutError should have been raised."
except TimeoutError:
discard
except:
doAssert false, "TimeoutError should have been raised."
proc makeIPv6HttpServer(hostname: string, port: Port): AsyncFD =
let fd = newNativeSocket(AF_INET6)

217
tests/stdlib/tparseipv6.nim Normal file
View File

@@ -0,0 +1,217 @@
discard """
output: "all ok"
"""
import net
const
positives = [
"::f:8:a8f:218.17.235.229",
"::b:228.19.241.2",
"::8:c:a:f:8.35.8.096",
"::3:e:a:bc:04.19.2.9",
"::2:212.242.248.19",
"::df:a5f:3.250.208.9",
"::8:c:5:e63:250.208.249.0",
"::b:f:181.12.9.98",
"::a:f8:77.08.243.232",
"::a:b:85:e4d9:252.9.229.056",
"941:c:8a:c:e::917",
"e8:7a:e:ad:88a:8:203.235.225.46",
"139c:9e::f8:254.08.21.249",
"b38:f0:e::f9:89.6.12.18",
"ef::8",
"5::ab",
"a::8:255.247.96.253",
"b:c0::c:254.248.95.254",
"::8c:2:99.251.024.3",
"98::c:247.240.249.57",
"9::9",
"628::f1ed:f",
"c::cca8",
"2::3:c",
"fde::8fcc:92:e",
"f::3",
"e85::7",
"8::b:f6",
"0::6:8ca",
"c8::6e:be8",
"87::e",
"6:9::a7:9",
"c::5",
"49::1:62",
"df:c0::f:9",
"a09a:8::21:887a",
"2:f::c",
"8bf5:5::2a6e:f8f",
"a:9e::bc:a",
"f:60::c:fd",
"59::52f:0:fa7",
"8268:6cf::f:9",
"c:abb::f",
"a:ff8d::9:7",
"05:c87::9c:9a",
"e:f::c:9a:1",
"ff6:8::962:e",
"9::bd",
"68:ec::6",
"3b8:f::94:3e9:9952",
"49b4:ae::899:b4",
"cb9:8e8:af::f4",
"8::10:9ae6:f9",
"b9::2:57",
"ff:fba9::d",
"4::a:8",
"caa:c:85a::2:3",
"5::a5:9",
"c:ad::a",
"9a:f:f65::b",
"f:df::9:0",
"c:b9::8de",
"d:f::a",
"ab88:d4:0::fc:8d",
"8f:ee2::3",
"f:f8::bf2:8c8",
"8::efc",
"e:5a::b",
"c:48::94",
"a:b:5::8",
"f:88f::f0a6",
"9:f:e::3",
"b::fedd",
"7b:f::c",
"edf4:7d::88",
"89::d",
"c0:a:62::ac",
"7:f::b",
"8::a2",
"0f::1",
"::",
"b:8::",
"44:a::",
"ef8f::",
"b:4:d::",
"a::",
"5a:8::",
"ddaf:ecbf::",
"f:bb:a1::",
"f8:f::",
"::e:38:ab:f8",
"::cd:c",
"::aa3:eb",
"::bf:9f9",
"::7ef:bf8a",
"::9",
"::a:9af",
"::315",
"::a:a",
"::aed3:a",
"f0eb:0:e8:b:c:a:254.098.233.17",
"bfa:7fc:c66d:15:e9a:ded:254.119.9.9",
"d:ffa8:9:a:879:3:202.39.08.245",
"8e:2:8:fa8a:f1d1:1aa8:252.254.245.81",
"5:d4:a:e9:8:8:06.38.98.253",
"9c5:4:a5c:f:a6:8c9d:05.250.8.2",
"d19a:2:f808:be:f:c:98.86.197.249",
"8:26ac:8:8:cb:f:242.00.254.85",
"38:e:1:0b88:f:0:8.89.248.92",
"e7:ff96:a:f:f:b:253.91.052.195",
"d:8:2:5:894:5:254.0.240.199",
"2:98:9:8aa:9c8f:fa:252.98.248.17",
"e9:d4f:890:ccbe:5:8:088.200.228.216",
"3:3:9:5:6a:df5:255.251.8.12",
"0280:3:8:8:4:9:255.000.251.249",
"8:af7:db:aa:0:9:238.248.250.255",
"ff:ee:9a:9252:a:289:059.083.18.255",
"9f6:5:fc9:b:a89:a:142.1.250.254",
"e:981a:da:bf94:9:f8:254.242.18.95",
"3c:1:4:f2:89:f:8.91.255.14",
"e::9a2:c:9.050.80.8",
"9::4a:07:fb:211.241.254.228",
"9be::2:e:215.189.48.188",
"f::f:d:069.148.99.168",
"f::a:97.18.240.47",
"c::a98e:1:251.253.252.254",
"668::82:214.87.208.9",
"9c0::cf0:ecb:253.208.238.255",
"a::0:f1:210.240.238.049",
"8::a:1:251.238.34.09",
"81:dfe::b8:8.255.249.248",
"d3::7:b:9:83.189.08.244",
"8::9:8:8:00.7.11.252",
"2:8::c:a8:250.221.9.249",
"2::f:99.8.249.247",
"c:22f5::5:2c:243.15.79.89",
"e:8e::da:251.243.255.2",
"f15f:9::a:255.70.247.218",
"f:b::9f38:31.220.94.022",
"9::9a48:03.98.249.119",
"d:d:9b87::2d:a:249.253.38.8",
"d86d:99b::a9b:5:242.236.8.244",
"eb:3::f:9cf:1.253.1.228",
"b::ba2:255.247.114.64",
"2f:ec:bcb::9:219.254.250.094",
"da8a:f6::a:e0:19.251.241.251",
"5e:c1::a:021.250.8.254",
"c:9::8c9b:248.219.212.252",
"2:a::8d4a:216.255.198.223",
"1f::66:255.30.08.150",
"bc2b:8f::2ff9:6.245.99.230",
"a:8::a8:9.251.246.255",
"f:7:7::98:06.14.1.208",
"e:2::9:218.249.255.254",
"79:f::6:250.255.98.246",
"47:9:fb9f::9:038.136.17.251",
"ed::a:247.9.23.239",
"6f::f1:88.254.119.9",
"a::d:218.199.236.0",
"fc88::9:203.196.04.95",
"::8.048.255.85",
"::253.07.255.36",
"9:d::253.7.178.229",
"::250.84.158.253",
"::8.55.204.248",
"2d:c::253.18.18.252",
"df9:88ca::248.255.108.17",
"8e9b::250.206.0.82",
"::209.8.254.209",
"::247.088.8.8",
"::cb:f:ba41:250.208.19.249",
"::fe:0e8:243.240.229.5",
"::c:223.251.5.226",
"::8:08.03.8.250",
"::f:8.88.11.255",
"::fda:48:aa:05.189.07.2",
"::8:c3f:f:240.06.212.255",
"::f:0aa:244.123.99.16",
"::c9b5:c:034.8.090.196",
"::98:c9:254.14.241.81"
]
negatives = ["foo.bar",
"::::::::::::",
"yet another failure",
"de:6:c:ab5:6a::9:252.06.06.249",
"f9:5f7:fa38:9:b::b6:09.255.248.252",
"97:c:5b:81:8a::f5dd:144.252.250.9",
"9:8:cd:8:a9::f:247.255.09.255",
"18:1:8c:2:3::9:8.254.252.139",
"e:c298:3:e:a::bb12:254.246.05.250",
"e:e:c:8e:fd::8:253.8.49.231",
"9:97f:f:e929:8a::c9:0.8.252.10",
"0df:b24:7:89:c::2b:16.249.240.092",
"b:8f5f:485:c:9a::84c:178.7.249.34",
]
proc ok(pos: openarray[string]) =
for p in pos:
if not isIpAddress(p):
echo "failure ", p
proc notok(neg: openarray[string]) =
for n in neg:
if isIpAddress(n):
echo "failure ", n
ok(positives)
notok(negatives)
echo "all ok"