Merge branch 'devel' into araq-devel

This commit is contained in:
Andreas Rumpf
2018-07-04 19:25:53 +02:00
16 changed files with 151 additions and 43 deletions

View File

@@ -20,6 +20,8 @@
- The parser now warns about inconsistent spacing around binary operators as
these can easily be confused with unary operators. This warning will likely
become an error in the future.
- The ``'c`` and ``'C'`` prefix for octal literals is now deprecated to
bring the language in line with the standard library (e.g. ``parseOct``).
#### Breaking changes in the standard library

View File

@@ -359,9 +359,8 @@ proc getNumber(L: var TLexer, result: var TToken) =
inc(pos)
L.bufpos = pos
proc lexMessageLitNum(L: var TLexer, msg: string, startpos: int) =
proc lexMessageLitNum(L: var TLexer, msg: string, startpos: int, msgKind = errGenerated) =
# Used to get slightly human friendlier err messages.
# Note: the erroneous 'O' char in the character set is intentional
const literalishChars = {'A'..'F', 'a'..'f', '0'..'9', 'X', 'x', 'o', 'O',
'c', 'C', 'b', 'B', '_', '.', '\'', 'd', 'i', 'u'}
var msgPos = L.bufpos
@@ -380,7 +379,7 @@ proc getNumber(L: var TLexer, result: var TToken) =
add(t.literal, L.buf[L.bufpos])
matchChars(L, t, {'0'..'9'})
L.bufpos = msgPos
lexMessage(L, errGenerated, msg % t.literal)
lexMessage(L, msgKind, msg % t.literal)
var
startpos, endpos: int
@@ -388,7 +387,8 @@ proc getNumber(L: var TLexer, result: var TToken) =
isBase10 = true
numDigits = 0
const
baseCodeChars = {'X', 'x', 'o', 'c', 'C', 'b', 'B'}
# 'c', 'C' is deprecated
baseCodeChars = {'X', 'x', 'o', 'b', 'B', 'c', 'C'}
literalishChars = baseCodeChars + {'A'..'F', 'a'..'f', '0'..'9', '_', '\''}
floatTypes = {tkFloatLit, tkFloat32Lit, tkFloat64Lit, tkFloat128Lit}
result.tokType = tkIntLit # int literal until we know better
@@ -398,17 +398,27 @@ proc getNumber(L: var TLexer, result: var TToken) =
tokenBegin(result, startPos)
# First stage: find out base, make verifications, build token literal string
if L.buf[L.bufpos] == '0' and L.buf[L.bufpos + 1] in baseCodeChars + {'O'}:
# {'c', 'C'} is added for deprecation reasons to provide a clear error message
if L.buf[L.bufpos] == '0' and L.buf[L.bufpos + 1] in baseCodeChars + {'c', 'C', 'O'}:
isBase10 = false
eatChar(L, result, '0')
case L.buf[L.bufpos]
of 'c', 'C':
lexMessageLitNum(L,
"$1 will soon be invalid for oct literals; Use '0o' " &
"for octals. 'c', 'C' prefix",
startpos,
warnDeprecated)
eatChar(L, result, 'c')
numDigits = matchUnderscoreChars(L, result, {'0'..'7'})
of 'O':
lexMessageLitNum(L, "$1 is not a valid number; did you mean octal? Then use one of '0o', '0c' or '0C'.", startpos)
lexMessageLitNum(L, "$1 is an invalid int literal; For octal literals " &
"use the '0o' prefix.", startpos)
of 'x', 'X':
eatChar(L, result, 'x')
numDigits = matchUnderscoreChars(L, result, {'0'..'9', 'a'..'f', 'A'..'F'})
of 'o', 'c', 'C':
eatChar(L, result, 'c')
of 'o':
eatChar(L, result, 'o')
numDigits = matchUnderscoreChars(L, result, {'0'..'7'})
of 'b', 'B':
eatChar(L, result, 'b')
@@ -511,6 +521,7 @@ proc getNumber(L: var TLexer, result: var TToken) =
if L.buf[pos] != '_':
xi = `shl`(xi, 1) or (ord(L.buf[pos]) - ord('0'))
inc(pos)
# 'c', 'C' is deprecated
of 'o', 'c', 'C':
result.base = base8
while pos < endpos:

View File

@@ -873,7 +873,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
if base.isMetaType and procKind == skMacro:
localError(c.config, info, errMacroBodyDependsOnGenericTypes % paramName)
result = addImplicitGeneric(c.newTypeWithSons(tyStatic, @[base]))
result.flags.incl({tfHasStatic, tfUnresolved})
if result != nil: result.flags.incl({tfHasStatic, tfUnresolved})
of tyTypeDesc:
if tfUnresolved notin paramType.flags:

View File

@@ -2308,6 +2308,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
m.firstMismatch = f
return
if m.baseTypeMatch:
assert formal.typ.kind == tyVarargs
#assert(container == nil)
if container.isNil:
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
@@ -2321,10 +2322,19 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
# pick the formal from the end, so that 'x, y, varargs, z' works:
f = max(f, formalLen - n.len + a + 1)
else:
elif formal.typ.kind != tyVarargs or container == nil:
setSon(m.call, formal.position + 1, arg)
inc(f)
container = nil
else:
# we end up here if the argument can be converted into the varargs
# formal (eg. seq[T] -> varargs[T]) but we have already instantiated
# a container
assert arg.kind == nkHiddenStdConv
localError(c.config, n.sons[a].info, "cannot convert $1 to $2" % [
typeToString(n.sons[a].typ), typeToString(formal.typ) ])
m.state = csNoMatch
return
checkConstraint(n.sons[a])
inc(a)

View File

@@ -413,7 +413,7 @@ Numerical constants are of a single type and have the form::
bindigit = '0'..'1'
HEX_LIT = '0' ('x' | 'X' ) hexdigit ( ['_'] hexdigit )*
DEC_LIT = digit ( ['_'] digit )*
OCT_LIT = '0' ('o' | 'c' | 'C') octdigit ( ['_'] octdigit )*
OCT_LIT = '0' 'o' octdigit ( ['_'] octdigit )*
BIN_LIT = '0' ('b' | 'B' ) bindigit ( ['_'] bindigit )*
INT_LIT = HEX_LIT
@@ -444,7 +444,7 @@ Numerical constants are of a single type and have the form::
As can be seen in the productions, numerical constants can contain underscores
for readability. Integer and floating point literals may be given in decimal (no
prefix), binary (prefix ``0b``), octal (prefix ``0o`` or ``0c``) and hexadecimal
prefix), binary (prefix ``0b``), octal (prefix ``0o``) and hexadecimal
(prefix ``0x``) notation.
There exists a literal for each numerical type that is

View File

@@ -36,26 +36,26 @@
# platforms - where do they come from and why are they here?
when false:
const
C_IRUSR = 0c000400 ## Read by owner.
C_IWUSR = 0c000200 ## Write by owner.
C_IXUSR = 0c000100 ## Execute by owner.
C_IRGRP = 0c000040 ## Read by group.
C_IWGRP = 0c000020 ## Write by group.
C_IXGRP = 0c000010 ## Execute by group.
C_IROTH = 0c000004 ## Read by others.
C_IWOTH = 0c000002 ## Write by others.
C_IXOTH = 0c000001 ## Execute by others.
C_ISUID = 0c004000 ## Set user ID.
C_ISGID = 0c002000 ## Set group ID.
C_ISVTX = 0c001000 ## On directories, restricted deletion flag.
C_ISDIR = 0c040000 ## Directory.
C_ISFIFO = 0c010000 ##FIFO.
C_ISREG = 0c100000 ## Regular file.
C_ISBLK = 0c060000 ## Block special.
C_ISCHR = 0c020000 ## Character special.
C_ISCTG = 0c110000 ## Reserved.
C_ISLNK = 0c120000 ## Symbolic link.</p>
C_ISSOCK = 0c140000 ## Socket.
C_IRUSR = 0o000400 ## Read by owner.
C_IWUSR = 0o000200 ## Write by owner.
C_IXUSR = 0o000100 ## Execute by owner.
C_IRGRP = 0o000040 ## Read by group.
C_IWGRP = 0o000020 ## Write by group.
C_IXGRP = 0o000010 ## Execute by group.
C_IROTH = 0o000004 ## Read by others.
C_IWOTH = 0o000002 ## Write by others.
C_IXOTH = 0o000001 ## Execute by others.
C_ISUID = 0o004000 ## Set user ID.
C_ISGID = 0o002000 ## Set group ID.
C_ISVTX = 0o001000 ## On directories, restricted deletion flag.
C_ISDIR = 0o040000 ## Directory.
C_ISFIFO = 0o010000 ##FIFO.
C_ISREG = 0o100000 ## Regular file.
C_ISBLK = 0o060000 ## Block special.
C_ISCHR = 0o020000 ## Character special.
C_ISCTG = 0o110000 ## Reserved.
C_ISLNK = 0o120000 ## Symbolic link.</p>
C_ISSOCK = 0o140000 ## Socket.
const
MM_NULLLBL* = nil

View File

@@ -304,6 +304,7 @@ proc retrFile*(ftp: AsyncFtpClient, file, dest: string,
raise newException(ReplyError, "Reply has no file size.")
await getFile(ftp, destFile, fileSize, onProgressChanged)
destFile.close()
proc doUpload(ftp: AsyncFtpClient, file: File,
onProgressChanged: ProgressChangedProc) {.async.} =

View File

@@ -449,6 +449,9 @@ proc unixToNativePath*(path: string, drive=""): string {.
when defined(unix):
result = path
else:
if path.len == 0:
return ""
var start: int
if path[0] == '/':
# an absolute path
@@ -462,10 +465,10 @@ proc unixToNativePath*(path: string, drive=""): string {.
else:
result = $DirSep
start = 1
elif path[0] == '.' and path[1] == '/':
elif path[0] == '.' and (path.len == 1 or path[1] == '/'):
# current directory
result = $CurDir
start = 2
start = when doslikeFileSystem: 1 else: 2
else:
result = ""
start = 0

View File

@@ -59,9 +59,4 @@ proc supportsCopyMem*(t: typedesc): bool {.magic: "TypeTrait".}
when isMainModule:
# echo type(42)
import streams
var ss = newStringStream()
ss.write($type(42)) # needs `$`
ss.setPosition(0)
doAssert ss.readAll() == "int"
doAssert $type(42) == "int"

9
tests/errmsgs/t6281.nim Normal file
View File

@@ -0,0 +1,9 @@
discard """
errormsg: "invalid type: 'SomeNumber' in this context: 'seq[SomeNumber]' for var"
line: 6
"""
var seqwat: seq[SomeNumber] = @[]
proc foo(x: SomeNumber) =
seqwat.add(x)

View File

@@ -0,0 +1,9 @@
# test the valid literals
assert 0b10 == 2
assert 0B10 == 2
assert 0x10 == 16
assert 0X10 == 16
assert 0o10 == 8
# the following is deprecated:
assert 0c10 == 8
assert 0C10 == 8

View File

@@ -0,0 +1,7 @@
discard """
file: "tinvalidintegerliteral3.nim"
line: 7
errormsg: "0O5 is an invalid int literal; For octal literals use the '0o' prefix."
"""
echo 0O5

View File

@@ -9,7 +9,7 @@ discard """
# 8 bit
let ref1 = 128'u8 shr 7
let hex1 = 0x80'u8 shr 7
let oct1 = 0c200'u8 shr 7
let oct1 = 0o200'u8 shr 7
let dig1 = 0b10000000'u8 shr 7
doAssert(ref1 == 1)
@@ -20,7 +20,7 @@ doAssert(ref1 == dig1)
# 16 bit
let ref2 = 32768'u16 shr 15
let hex2 = 0x8000'u16 shr 15
let oct2 = 0c100000'u16 shr 15
let oct2 = 0o100000'u16 shr 15
let dig2 = 0b1000000000000000'u16 shr 15
doAssert(ref2 == 1)
@@ -31,7 +31,7 @@ doAssert(ref2 == dig2)
# 32 bit
let ref3 = 2147483648'u32 shr 31
let hex3 = 0x80000000'u32 shr 31
let oct3 = 0c20000000000'u32 shr 31
let oct3 = 0o20000000000'u32 shr 31
let dig3 = 0b10000000000000000000000000000000'u32 shr 31
doAssert(ref3 == 1)

View File

@@ -107,3 +107,12 @@ when true:
assert aw2.data.high == 6
assert aw3.data.high == 9
# #6077
block:
type
Backend = enum
Cpu
Tensor[B: static[Backend]; T] = object
BackProp[B: static[Backend],T] = proc (gradient: Tensor[B,T]): Tensor[B,T]

41
tests/stdlib/tospaths.nim Normal file
View File

@@ -0,0 +1,41 @@
discard """
file: "tospaths.nim"
output: ""
"""
# test the ospaths module
import os
doAssert unixToNativePath("") == ""
doAssert unixToNativePath(".") == $CurDir
doAssert unixToNativePath("..") == $ParDir
doAssert isAbsolute(unixToNativePath("/"))
doAssert isAbsolute(unixToNativePath("/", "a"))
doAssert isAbsolute(unixToNativePath("/a"))
doAssert isAbsolute(unixToNativePath("/a", "a"))
doAssert isAbsolute(unixToNativePath("/a/b"))
doAssert isAbsolute(unixToNativePath("/a/b", "a"))
doAssert unixToNativePath("a/b") == joinPath("a", "b")
when defined(macos):
doAssert unixToNativePath("./") == ":"
doAssert unixToNativePath("./abc") == ":abc"
doAssert unixToNativePath("../abc") == "::abc"
doAssert unixToNativePath("../../abc") == ":::abc"
doAssert unixToNativePath("/abc", "a") == "abc"
doAssert unixToNativePath("/abc/def", "a") == "abc:def"
elif doslikeFileSystem:
doAssert unixToNativePath("./") == ".\\"
doAssert unixToNativePath("./abc") == ".\\abc"
doAssert unixToNativePath("../abc") == "..\\abc"
doAssert unixToNativePath("../../abc") == "..\\..\\abc"
doAssert unixToNativePath("/abc", "a") == "a:\\abc"
doAssert unixToNativePath("/abc/def", "a") == "a:\\abc\\def"
else:
#Tests for unix
doAssert unixToNativePath("./") == "./"
doAssert unixToNativePath("./abc") == "./abc"
doAssert unixToNativePath("../abc") == "../abc"
doAssert unixToNativePath("../../abc") == "../../abc"
doAssert unixToNativePath("/abc", "a") == "/abc"
doAssert unixToNativePath("/abc/def", "a") == "/abc/def"

11
tests/typerel/t8172.nim Normal file
View File

@@ -0,0 +1,11 @@
discard """
line: 11
errormsg: "cannot convert array[0..0, string] to varargs[string]"
"""
proc f(v: varargs[string]) =
echo(v)
f("b", "c") # Works
f(["b", "c"]) # Works
f("b", ["c"]) # Fails