Merge branch 'devel' into fix_bracket_expr

This commit is contained in:
Araq
2015-09-16 11:36:49 +02:00
10 changed files with 155 additions and 13 deletions

View File

@@ -146,7 +146,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
# go down recursively; this is quite demanding:
const
Ix0Kinds = {nkDotExpr, nkBracketExpr, nkObjUpConv, nkObjDownConv,
nkCheckedFieldExpr}
nkCheckedFieldExpr, nkHiddenAddr}
Ix1Kinds = {nkHiddenStdConv, nkHiddenSubConv, nkConv}
DerefKinds = {nkHiddenDeref, nkDerefExpr}
case b.kind

View File

@@ -116,8 +116,7 @@ proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
[name, genTypeInfo(p, typ.sons[0])])
proc genTypeInfo(p: PProc, typ: PType): Rope =
var t = typ
if t.kind == tyGenericInst: t = lastSon(t)
let t = typ.skipTypes({tyGenericInst})
result = "NTI$1" % [rope(t.id)]
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
case t.kind
@@ -141,7 +140,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
[result, rope(ord(t.kind))]
prepend(p.g.typeInfo, s)
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 tyObject: genObjectInfo(p, t, result)
of tyTuple: genTupleInfo(p, t, result)

View File

@@ -320,8 +320,19 @@ proc opConv*(dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool =
dest.node.strVal = if src.intVal == 0: "false" else: "true"
of tyFloat..tyFloat128:
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
of tyChar:
dest.node.strVal = $chr(src.intVal)
else:

View File

@@ -1074,9 +1074,9 @@ when not defined(js):
## for nice error messages.
var p: JsonParser
p.open(s, filename)
defer: p.close()
discard getTok(p) # read first token
result = p.parseJson()
p.close()
proc parseJson*(buffer: string): JsonNode =
## Parses JSON from `buffer`.
@@ -1203,6 +1203,17 @@ when isMainModule:
testJson{["c", "d"]} = %true
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 `$`
let stringified = $testJson
let parsedAgain = parseJson(stringified)

View File

@@ -533,6 +533,18 @@ proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {.
var res = getSockOptInt(socket.fd, cint(level), toCInt(opt))
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) {.
tags: [WriteIOEffect].} =
## Sets option ``opt`` to a boolean value specified by ``value``.

View File

@@ -371,6 +371,76 @@ proc getSockName*(socket: SocketHandle): Port =
raiseOSError(osLastError())
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 {.
tags: [ReadIOEffect].} =
## getsockopt for integer options.

View File

@@ -21,9 +21,22 @@ proc reprPointer(x: pointer): string {.compilerproc.} =
return $buf
proc `$`(x: uint64): string =
var buf: array [0..59, char]
discard c_sprintf(buf, "%llu", x)
return $buf
if x == 0:
result = "0"
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) =
if cast[pointer](s) == nil:
@@ -294,4 +307,3 @@ when not defined(useNimRtl):
reprAux(result, addr(p), typ, cl)
add result, "\n"
deinitReprClosure(cl)

View File

@@ -409,7 +409,7 @@ type
bytes*: array[0..15, char]
Sockaddr_in6* {.importc: "SOCKADDR_IN6",
header: "winsock2.h".} = object
header: "ws2tcpip.h".} = object
sin6_family*: int16
sin6_port*: int16 # 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,
namelen: ptr SockLen): cint {.
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,
optlen: ptr SockLen): cint {.
stdcall, importc: "getsockopt", dynlib: ws2dll.}
@@ -572,6 +575,9 @@ proc freeaddrinfo*(ai: ptr AddrInfo) {.
proc inet_ntoa*(i: InAddr): cstring {.
stdcall, importc, dynlib: ws2dll.}
proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
stringBufSize: int32): cstring {.stdcall, importc, dynlib: ws2dll.}
const
MAXIMUM_WAIT_OBJECTS* = 0x00000040

View File

@@ -30,7 +30,7 @@ type
c: char
se: seq[TA]
proc p(param1, param2: TC): TC =
proc p(param1, param2: TC, param3: var TC): TC =
var
local: TC
plocal: ptr TC
@@ -43,6 +43,7 @@ proc p(param1, param2: TC): TC =
plocal2[] ?<| local
param1 ?<| param2
local ?<| param3
local.arr[0] !<| param1
local.arr !<| param1
@@ -62,5 +63,5 @@ var
a <| a
a !<| b
discard p(x, x)
discard p(x, x, x)

View File

@@ -305,6 +305,26 @@ News
(`#2183 <https://github.com/Araq/Nim/issues/2183>`_)
- Fixed "gctest segfaults with --gc:markandsweep on x86_64"
(`#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