Merge branch 'devel' into araq-devel

This commit is contained in:
Andreas Rumpf 2018-07-04 19:25:53 +02:00
commit 86a7054c88
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 - The parser now warns about inconsistent spacing around binary operators as
these can easily be confused with unary operators. This warning will likely these can easily be confused with unary operators. This warning will likely
become an error in the future. 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 #### Breaking changes in the standard library

View file

@ -359,9 +359,8 @@ proc getNumber(L: var TLexer, result: var TToken) =
inc(pos) inc(pos)
L.bufpos = 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. # 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', const literalishChars = {'A'..'F', 'a'..'f', '0'..'9', 'X', 'x', 'o', 'O',
'c', 'C', 'b', 'B', '_', '.', '\'', 'd', 'i', 'u'} 'c', 'C', 'b', 'B', '_', '.', '\'', 'd', 'i', 'u'}
var msgPos = L.bufpos var msgPos = L.bufpos
@ -380,7 +379,7 @@ proc getNumber(L: var TLexer, result: var TToken) =
add(t.literal, L.buf[L.bufpos]) add(t.literal, L.buf[L.bufpos])
matchChars(L, t, {'0'..'9'}) matchChars(L, t, {'0'..'9'})
L.bufpos = msgPos L.bufpos = msgPos
lexMessage(L, errGenerated, msg % t.literal) lexMessage(L, msgKind, msg % t.literal)
var var
startpos, endpos: int startpos, endpos: int
@ -388,7 +387,8 @@ proc getNumber(L: var TLexer, result: var TToken) =
isBase10 = true isBase10 = true
numDigits = 0 numDigits = 0
const 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', '_', '\''} literalishChars = baseCodeChars + {'A'..'F', 'a'..'f', '0'..'9', '_', '\''}
floatTypes = {tkFloatLit, tkFloat32Lit, tkFloat64Lit, tkFloat128Lit} floatTypes = {tkFloatLit, tkFloat32Lit, tkFloat64Lit, tkFloat128Lit}
result.tokType = tkIntLit # int literal until we know better result.tokType = tkIntLit # int literal until we know better
@ -398,17 +398,27 @@ proc getNumber(L: var TLexer, result: var TToken) =
tokenBegin(result, startPos) tokenBegin(result, startPos)
# First stage: find out base, make verifications, build token literal string # 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 isBase10 = false
eatChar(L, result, '0') eatChar(L, result, '0')
case L.buf[L.bufpos] 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': 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': of 'x', 'X':
eatChar(L, result, 'x') eatChar(L, result, 'x')
numDigits = matchUnderscoreChars(L, result, {'0'..'9', 'a'..'f', 'A'..'F'}) numDigits = matchUnderscoreChars(L, result, {'0'..'9', 'a'..'f', 'A'..'F'})
of 'o', 'c', 'C': of 'o':
eatChar(L, result, 'c') eatChar(L, result, 'o')
numDigits = matchUnderscoreChars(L, result, {'0'..'7'}) numDigits = matchUnderscoreChars(L, result, {'0'..'7'})
of 'b', 'B': of 'b', 'B':
eatChar(L, result, 'b') eatChar(L, result, 'b')
@ -511,6 +521,7 @@ proc getNumber(L: var TLexer, result: var TToken) =
if L.buf[pos] != '_': if L.buf[pos] != '_':
xi = `shl`(xi, 1) or (ord(L.buf[pos]) - ord('0')) xi = `shl`(xi, 1) or (ord(L.buf[pos]) - ord('0'))
inc(pos) inc(pos)
# 'c', 'C' is deprecated
of 'o', 'c', 'C': of 'o', 'c', 'C':
result.base = base8 result.base = base8
while pos < endpos: while pos < endpos:

View file

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

View file

@ -2308,6 +2308,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
m.firstMismatch = f m.firstMismatch = f
return return
if m.baseTypeMatch: if m.baseTypeMatch:
assert formal.typ.kind == tyVarargs
#assert(container == nil) #assert(container == nil)
if container.isNil: if container.isNil:
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg)) 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: # pick the formal from the end, so that 'x, y, varargs, z' works:
f = max(f, formalLen - n.len + a + 1) f = max(f, formalLen - n.len + a + 1)
else: elif formal.typ.kind != tyVarargs or container == nil:
setSon(m.call, formal.position + 1, arg) setSon(m.call, formal.position + 1, arg)
inc(f) inc(f)
container = nil 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]) checkConstraint(n.sons[a])
inc(a) inc(a)

View file

@ -413,7 +413,7 @@ Numerical constants are of a single type and have the form::
bindigit = '0'..'1' bindigit = '0'..'1'
HEX_LIT = '0' ('x' | 'X' ) hexdigit ( ['_'] hexdigit )* HEX_LIT = '0' ('x' | 'X' ) hexdigit ( ['_'] hexdigit )*
DEC_LIT = digit ( ['_'] digit )* 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 )* BIN_LIT = '0' ('b' | 'B' ) bindigit ( ['_'] bindigit )*
INT_LIT = HEX_LIT 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 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 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. (prefix ``0x``) notation.
There exists a literal for each numerical type that is 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? # platforms - where do they come from and why are they here?
when false: when false:
const const
C_IRUSR = 0c000400 ## Read by owner. C_IRUSR = 0o000400 ## Read by owner.
C_IWUSR = 0c000200 ## Write by owner. C_IWUSR = 0o000200 ## Write by owner.
C_IXUSR = 0c000100 ## Execute by owner. C_IXUSR = 0o000100 ## Execute by owner.
C_IRGRP = 0c000040 ## Read by group. C_IRGRP = 0o000040 ## Read by group.
C_IWGRP = 0c000020 ## Write by group. C_IWGRP = 0o000020 ## Write by group.
C_IXGRP = 0c000010 ## Execute by group. C_IXGRP = 0o000010 ## Execute by group.
C_IROTH = 0c000004 ## Read by others. C_IROTH = 0o000004 ## Read by others.
C_IWOTH = 0c000002 ## Write by others. C_IWOTH = 0o000002 ## Write by others.
C_IXOTH = 0c000001 ## Execute by others. C_IXOTH = 0o000001 ## Execute by others.
C_ISUID = 0c004000 ## Set user ID. C_ISUID = 0o004000 ## Set user ID.
C_ISGID = 0c002000 ## Set group ID. C_ISGID = 0o002000 ## Set group ID.
C_ISVTX = 0c001000 ## On directories, restricted deletion flag. C_ISVTX = 0o001000 ## On directories, restricted deletion flag.
C_ISDIR = 0c040000 ## Directory. C_ISDIR = 0o040000 ## Directory.
C_ISFIFO = 0c010000 ##FIFO. C_ISFIFO = 0o010000 ##FIFO.
C_ISREG = 0c100000 ## Regular file. C_ISREG = 0o100000 ## Regular file.
C_ISBLK = 0c060000 ## Block special. C_ISBLK = 0o060000 ## Block special.
C_ISCHR = 0c020000 ## Character special. C_ISCHR = 0o020000 ## Character special.
C_ISCTG = 0c110000 ## Reserved. C_ISCTG = 0o110000 ## Reserved.
C_ISLNK = 0c120000 ## Symbolic link.</p> C_ISLNK = 0o120000 ## Symbolic link.</p>
C_ISSOCK = 0c140000 ## Socket. C_ISSOCK = 0o140000 ## Socket.
const const
MM_NULLLBL* = nil MM_NULLLBL* = nil

View file

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

View file

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

View file

@ -59,9 +59,4 @@ proc supportsCopyMem*(t: typedesc): bool {.magic: "TypeTrait".}
when isMainModule: when isMainModule:
# echo type(42) doAssert $type(42) == "int"
import streams
var ss = newStringStream()
ss.write($type(42)) # needs `$`
ss.setPosition(0)
doAssert ss.readAll() == "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 # 8 bit
let ref1 = 128'u8 shr 7 let ref1 = 128'u8 shr 7
let hex1 = 0x80'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 let dig1 = 0b10000000'u8 shr 7
doAssert(ref1 == 1) doAssert(ref1 == 1)
@ -20,7 +20,7 @@ doAssert(ref1 == dig1)
# 16 bit # 16 bit
let ref2 = 32768'u16 shr 15 let ref2 = 32768'u16 shr 15
let hex2 = 0x8000'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 let dig2 = 0b1000000000000000'u16 shr 15
doAssert(ref2 == 1) doAssert(ref2 == 1)
@ -31,7 +31,7 @@ doAssert(ref2 == dig2)
# 32 bit # 32 bit
let ref3 = 2147483648'u32 shr 31 let ref3 = 2147483648'u32 shr 31
let hex3 = 0x80000000'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 let dig3 = 0b10000000000000000000000000000000'u32 shr 31
doAssert(ref3 == 1) doAssert(ref3 == 1)

View file

@ -107,3 +107,12 @@ when true:
assert aw2.data.high == 6 assert aw2.data.high == 6
assert aw3.data.high == 9 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