Merge branch 'devel' into fix_bracket_expr
This commit is contained in:
commit
c9a2fa54c7
10 changed files with 155 additions and 13 deletions
|
|
@ -146,7 +146,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
|
||||||
# go down recursively; this is quite demanding:
|
# go down recursively; this is quite demanding:
|
||||||
const
|
const
|
||||||
Ix0Kinds = {nkDotExpr, nkBracketExpr, nkObjUpConv, nkObjDownConv,
|
Ix0Kinds = {nkDotExpr, nkBracketExpr, nkObjUpConv, nkObjDownConv,
|
||||||
nkCheckedFieldExpr}
|
nkCheckedFieldExpr, nkHiddenAddr}
|
||||||
Ix1Kinds = {nkHiddenStdConv, nkHiddenSubConv, nkConv}
|
Ix1Kinds = {nkHiddenStdConv, nkHiddenSubConv, nkConv}
|
||||||
DerefKinds = {nkHiddenDeref, nkDerefExpr}
|
DerefKinds = {nkHiddenDeref, nkDerefExpr}
|
||||||
case b.kind
|
case b.kind
|
||||||
|
|
|
||||||
|
|
@ -116,8 +116,7 @@ proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
|
||||||
[name, genTypeInfo(p, typ.sons[0])])
|
[name, genTypeInfo(p, typ.sons[0])])
|
||||||
|
|
||||||
proc genTypeInfo(p: PProc, typ: PType): Rope =
|
proc genTypeInfo(p: PProc, typ: PType): Rope =
|
||||||
var t = typ
|
let t = typ.skipTypes({tyGenericInst})
|
||||||
if t.kind == tyGenericInst: t = lastSon(t)
|
|
||||||
result = "NTI$1" % [rope(t.id)]
|
result = "NTI$1" % [rope(t.id)]
|
||||||
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
|
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
|
||||||
case t.kind
|
case t.kind
|
||||||
|
|
@ -141,7 +140,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
|
||||||
[result, rope(ord(t.kind))]
|
[result, rope(ord(t.kind))]
|
||||||
prepend(p.g.typeInfo, s)
|
prepend(p.g.typeInfo, s)
|
||||||
addf(p.g.typeInfo, "$1.base = $2;$n",
|
addf(p.g.typeInfo, "$1.base = $2;$n",
|
||||||
[result, genTypeInfo(p, typ.sons[1])])
|
[result, genTypeInfo(p, t.sons[1])])
|
||||||
of tyEnum: genEnumInfo(p, t, result)
|
of tyEnum: genEnumInfo(p, t, result)
|
||||||
of tyObject: genObjectInfo(p, t, result)
|
of tyObject: genObjectInfo(p, t, result)
|
||||||
of tyTuple: genTupleInfo(p, t, result)
|
of tyTuple: genTupleInfo(p, t, result)
|
||||||
|
|
|
||||||
|
|
@ -320,7 +320,18 @@ proc opConv*(dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool =
|
||||||
dest.node.strVal = if src.intVal == 0: "false" else: "true"
|
dest.node.strVal = if src.intVal == 0: "false" else: "true"
|
||||||
of tyFloat..tyFloat128:
|
of tyFloat..tyFloat128:
|
||||||
dest.node.strVal = $src.floatVal
|
dest.node.strVal = $src.floatVal
|
||||||
of tyString, tyCString:
|
of tyString:
|
||||||
|
dest.node.strVal = src.node.strVal
|
||||||
|
of tyCString:
|
||||||
|
if src.node.kind == nkBracket:
|
||||||
|
# Array of chars
|
||||||
|
var strVal = ""
|
||||||
|
for son in src.node.sons:
|
||||||
|
let c = char(son.intVal)
|
||||||
|
if c == '\0': break
|
||||||
|
strVal.add(c)
|
||||||
|
dest.node.strVal = strVal
|
||||||
|
else:
|
||||||
dest.node.strVal = src.node.strVal
|
dest.node.strVal = src.node.strVal
|
||||||
of tyChar:
|
of tyChar:
|
||||||
dest.node.strVal = $chr(src.intVal)
|
dest.node.strVal = $chr(src.intVal)
|
||||||
|
|
|
||||||
|
|
@ -1074,9 +1074,9 @@ when not defined(js):
|
||||||
## for nice error messages.
|
## for nice error messages.
|
||||||
var p: JsonParser
|
var p: JsonParser
|
||||||
p.open(s, filename)
|
p.open(s, filename)
|
||||||
|
defer: p.close()
|
||||||
discard getTok(p) # read first token
|
discard getTok(p) # read first token
|
||||||
result = p.parseJson()
|
result = p.parseJson()
|
||||||
p.close()
|
|
||||||
|
|
||||||
proc parseJson*(buffer: string): JsonNode =
|
proc parseJson*(buffer: string): JsonNode =
|
||||||
## Parses JSON from `buffer`.
|
## Parses JSON from `buffer`.
|
||||||
|
|
@ -1203,6 +1203,17 @@ when isMainModule:
|
||||||
testJson{["c", "d"]} = %true
|
testJson{["c", "d"]} = %true
|
||||||
assert(testJson["c"]["d"].bval)
|
assert(testJson["c"]["d"].bval)
|
||||||
|
|
||||||
|
# make sure no memory leek when parsing invalid string
|
||||||
|
let startMemory = getOccupiedMem()
|
||||||
|
for i in 0 .. 10000:
|
||||||
|
try:
|
||||||
|
discard parseJson"""{ invalid"""
|
||||||
|
except:
|
||||||
|
discard
|
||||||
|
# memory diff should less than 2M
|
||||||
|
assert(abs(getOccupiedMem() - startMemory) < 2 * 1024 * 1024)
|
||||||
|
|
||||||
|
|
||||||
# test `$`
|
# test `$`
|
||||||
let stringified = $testJson
|
let stringified = $testJson
|
||||||
let parsedAgain = parseJson(stringified)
|
let parsedAgain = parseJson(stringified)
|
||||||
|
|
|
||||||
|
|
@ -533,6 +533,18 @@ proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {.
|
||||||
var res = getSockOptInt(socket.fd, cint(level), toCInt(opt))
|
var res = getSockOptInt(socket.fd, cint(level), toCInt(opt))
|
||||||
result = res != 0
|
result = res != 0
|
||||||
|
|
||||||
|
proc getLocalAddr*(socket: Socket): (string, Port) =
|
||||||
|
## Get the socket's local address and port number.
|
||||||
|
##
|
||||||
|
## This is high-level interface for `getsockname`:idx:.
|
||||||
|
getLocalAddr(socket.fd, socket.domain)
|
||||||
|
|
||||||
|
proc getPeerAddr*(socket: Socket): (string, Port) =
|
||||||
|
## Get the socket's peer address and port number.
|
||||||
|
##
|
||||||
|
## This is high-level interface for `getpeername`:idx:.
|
||||||
|
getPeerAddr(socket.fd, socket.domain)
|
||||||
|
|
||||||
proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {.
|
proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {.
|
||||||
tags: [WriteIOEffect].} =
|
tags: [WriteIOEffect].} =
|
||||||
## Sets option ``opt`` to a boolean value specified by ``value``.
|
## Sets option ``opt`` to a boolean value specified by ``value``.
|
||||||
|
|
|
||||||
|
|
@ -371,6 +371,76 @@ proc getSockName*(socket: SocketHandle): Port =
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = Port(rawsockets.ntohs(name.sin_port))
|
result = Port(rawsockets.ntohs(name.sin_port))
|
||||||
|
|
||||||
|
proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||||
|
## returns the socket's local address and port number.
|
||||||
|
##
|
||||||
|
## Similar to POSIX's `getsockname`:idx:.
|
||||||
|
case domain
|
||||||
|
of AF_INET:
|
||||||
|
var name: Sockaddr_in
|
||||||
|
when useWinVersion:
|
||||||
|
name.sin_family = int16(ord(AF_INET))
|
||||||
|
else:
|
||||||
|
name.sin_family = posix.AF_INET
|
||||||
|
var namelen = sizeof(name).SockLen
|
||||||
|
if getsockname(socket, cast[ptr SockAddr](addr(name)),
|
||||||
|
addr(namelen)) == -1'i32:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
|
||||||
|
of AF_INET6:
|
||||||
|
var name: Sockaddr_in6
|
||||||
|
when useWinVersion:
|
||||||
|
name.sin6_family = int16(ord(AF_INET6))
|
||||||
|
else:
|
||||||
|
name.sin6_family = posix.AF_INET6
|
||||||
|
var namelen = sizeof(name).SockLen
|
||||||
|
if getsockname(socket, cast[ptr SockAddr](addr(name)),
|
||||||
|
addr(namelen)) == -1'i32:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
|
||||||
|
var buf: array[64, char]
|
||||||
|
if inet_ntop(name.sin6_family.cint,
|
||||||
|
addr name, buf.cstring, sizeof(buf).int32).isNil:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
|
||||||
|
else:
|
||||||
|
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
|
||||||
|
|
||||||
|
proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||||
|
## returns the socket's peer address and port number.
|
||||||
|
##
|
||||||
|
## Similar to POSIX's `getpeername`:idx:
|
||||||
|
case domain
|
||||||
|
of AF_INET:
|
||||||
|
var name: Sockaddr_in
|
||||||
|
when useWinVersion:
|
||||||
|
name.sin_family = int16(ord(AF_INET))
|
||||||
|
else:
|
||||||
|
name.sin_family = posix.AF_INET
|
||||||
|
var namelen = sizeof(name).SockLen
|
||||||
|
if getpeername(socket, cast[ptr SockAddr](addr(name)),
|
||||||
|
addr(namelen)) == -1'i32:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
|
||||||
|
of AF_INET6:
|
||||||
|
var name: Sockaddr_in6
|
||||||
|
when useWinVersion:
|
||||||
|
name.sin6_family = int16(ord(AF_INET6))
|
||||||
|
else:
|
||||||
|
name.sin6_family = posix.AF_INET6
|
||||||
|
var namelen = sizeof(name).SockLen
|
||||||
|
if getpeername(socket, cast[ptr SockAddr](addr(name)),
|
||||||
|
addr(namelen)) == -1'i32:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
|
||||||
|
var buf: array[64, char]
|
||||||
|
if inet_ntop(name.sin6_family.cint,
|
||||||
|
addr name, buf.cstring, sizeof(buf).int32).isNil:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
|
||||||
|
else:
|
||||||
|
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
|
||||||
|
|
||||||
proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {.
|
proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {.
|
||||||
tags: [ReadIOEffect].} =
|
tags: [ReadIOEffect].} =
|
||||||
## getsockopt for integer options.
|
## getsockopt for integer options.
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,22 @@ proc reprPointer(x: pointer): string {.compilerproc.} =
|
||||||
return $buf
|
return $buf
|
||||||
|
|
||||||
proc `$`(x: uint64): string =
|
proc `$`(x: uint64): string =
|
||||||
var buf: array [0..59, char]
|
if x == 0:
|
||||||
discard c_sprintf(buf, "%llu", x)
|
result = "0"
|
||||||
return $buf
|
else:
|
||||||
|
var buf: array [60, char]
|
||||||
|
var i = 0
|
||||||
|
var n = x
|
||||||
|
while n != 0:
|
||||||
|
let nn = n div 10'u64
|
||||||
|
buf[i] = char(n - 10'u64 * nn + ord('0'))
|
||||||
|
inc i
|
||||||
|
n = nn
|
||||||
|
|
||||||
|
let half = i div 2
|
||||||
|
# Reverse
|
||||||
|
for t in 0 .. < half: swap(buf[t], buf[i-t-1])
|
||||||
|
result = $buf
|
||||||
|
|
||||||
proc reprStrAux(result: var string, s: string) =
|
proc reprStrAux(result: var string, s: string) =
|
||||||
if cast[pointer](s) == nil:
|
if cast[pointer](s) == nil:
|
||||||
|
|
@ -294,4 +307,3 @@ when not defined(useNimRtl):
|
||||||
reprAux(result, addr(p), typ, cl)
|
reprAux(result, addr(p), typ, cl)
|
||||||
add result, "\n"
|
add result, "\n"
|
||||||
deinitReprClosure(cl)
|
deinitReprClosure(cl)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,7 @@ type
|
||||||
bytes*: array[0..15, char]
|
bytes*: array[0..15, char]
|
||||||
|
|
||||||
Sockaddr_in6* {.importc: "SOCKADDR_IN6",
|
Sockaddr_in6* {.importc: "SOCKADDR_IN6",
|
||||||
header: "winsock2.h".} = object
|
header: "ws2tcpip.h".} = object
|
||||||
sin6_family*: int16
|
sin6_family*: int16
|
||||||
sin6_port*: int16 # unsigned
|
sin6_port*: int16 # unsigned
|
||||||
sin6_flowinfo*: int32 # unsigned
|
sin6_flowinfo*: int32 # unsigned
|
||||||
|
|
@ -511,6 +511,9 @@ proc connect*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {.
|
||||||
proc getsockname*(s: SocketHandle, name: ptr SockAddr,
|
proc getsockname*(s: SocketHandle, name: ptr SockAddr,
|
||||||
namelen: ptr SockLen): cint {.
|
namelen: ptr SockLen): cint {.
|
||||||
stdcall, importc: "getsockname", dynlib: ws2dll.}
|
stdcall, importc: "getsockname", dynlib: ws2dll.}
|
||||||
|
proc getpeername*(s: SocketHandle, name: ptr SockAddr,
|
||||||
|
namelen: ptr SockLen): cint {.
|
||||||
|
stdcall, importc, dynlib: ws2dll.}
|
||||||
proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer,
|
proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer,
|
||||||
optlen: ptr SockLen): cint {.
|
optlen: ptr SockLen): cint {.
|
||||||
stdcall, importc: "getsockopt", dynlib: ws2dll.}
|
stdcall, importc: "getsockopt", dynlib: ws2dll.}
|
||||||
|
|
@ -572,6 +575,9 @@ proc freeaddrinfo*(ai: ptr AddrInfo) {.
|
||||||
proc inet_ntoa*(i: InAddr): cstring {.
|
proc inet_ntoa*(i: InAddr): cstring {.
|
||||||
stdcall, importc, dynlib: ws2dll.}
|
stdcall, importc, dynlib: ws2dll.}
|
||||||
|
|
||||||
|
proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
|
||||||
|
stringBufSize: int32): cstring {.stdcall, importc, dynlib: ws2dll.}
|
||||||
|
|
||||||
const
|
const
|
||||||
MAXIMUM_WAIT_OBJECTS* = 0x00000040
|
MAXIMUM_WAIT_OBJECTS* = 0x00000040
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ type
|
||||||
c: char
|
c: char
|
||||||
se: seq[TA]
|
se: seq[TA]
|
||||||
|
|
||||||
proc p(param1, param2: TC): TC =
|
proc p(param1, param2: TC, param3: var TC): TC =
|
||||||
var
|
var
|
||||||
local: TC
|
local: TC
|
||||||
plocal: ptr TC
|
plocal: ptr TC
|
||||||
|
|
@ -43,6 +43,7 @@ proc p(param1, param2: TC): TC =
|
||||||
plocal2[] ?<| local
|
plocal2[] ?<| local
|
||||||
|
|
||||||
param1 ?<| param2
|
param1 ?<| param2
|
||||||
|
local ?<| param3
|
||||||
|
|
||||||
local.arr[0] !<| param1
|
local.arr[0] !<| param1
|
||||||
local.arr !<| param1
|
local.arr !<| param1
|
||||||
|
|
@ -62,5 +63,5 @@ var
|
||||||
a <| a
|
a <| a
|
||||||
a !<| b
|
a !<| b
|
||||||
|
|
||||||
discard p(x, x)
|
discard p(x, x, x)
|
||||||
|
|
||||||
|
|
|
||||||
20
web/news.txt
20
web/news.txt
|
|
@ -305,6 +305,26 @@ News
|
||||||
(`#2183 <https://github.com/Araq/Nim/issues/2183>`_)
|
(`#2183 <https://github.com/Araq/Nim/issues/2183>`_)
|
||||||
- Fixed "gctest segfaults with --gc:markandsweep on x86_64"
|
- Fixed "gctest segfaults with --gc:markandsweep on x86_64"
|
||||||
(`#2305 <https://github.com/Araq/Nim/issues/2305>`_)
|
(`#2305 <https://github.com/Araq/Nim/issues/2305>`_)
|
||||||
|
- Fixed "Coroutine changes break compilation on unsupported architectures"
|
||||||
|
(`#3245 <https://github.com/Araq/Nim/issues/3245>`_)
|
||||||
|
- Fixed "Bugfix: Windows 32bit TinyCC support issue fixed"
|
||||||
|
(`#3237 <https://github.com/Araq/Nim/issues/3237>`_)
|
||||||
|
- Fixed "db_mysql getValue() followed by exec() causing error"
|
||||||
|
(`#3220 <https://github.com/Araq/Nim/issues/3220>`_)
|
||||||
|
- Fixed "xmltree.newEntity creates xnCData instead of xnEntity"
|
||||||
|
(`#3282 <https://github.com/Araq/Nim/issues/3282>`_)
|
||||||
|
- Fixed "Methods and modules don't work together"
|
||||||
|
(`#2590 <https://github.com/Araq/Nim/issues/2590>`_)
|
||||||
|
- Fixed "String slicing not working in the vm"
|
||||||
|
(`#3300 <https://github.com/Araq/Nim/issues/3300>`_)
|
||||||
|
- Fixed "internal error: evalOp(mTypeOf)"
|
||||||
|
(`#3230 <https://github.com/Araq/Nim/issues/3230>`_)
|
||||||
|
- Fixed "#! source code prefix collides with Unix Shebang"
|
||||||
|
(`#2559 <https://github.com/Araq/Nim/issues/2559>`_)
|
||||||
|
- Fixed "wrong codegen for constant object"
|
||||||
|
(`#3195 <https://github.com/Araq/Nim/issues/3195>`_)
|
||||||
|
- Fixed "Doc comments inside procs with implicit returns don't work"
|
||||||
|
(`#1528 <https://github.com/Araq/Nim/issues/1528>`_)
|
||||||
|
|
||||||
|
|
||||||
2015-05-04 Version 0.11.2 released
|
2015-05-04 Version 0.11.2 released
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue