Merge branch 'devel' into araq-newlines

This commit is contained in:
Araq
2018-01-28 11:38:52 +01:00
13 changed files with 246 additions and 64 deletions

View File

@@ -1344,6 +1344,9 @@ proc genArgs(p: PProc, n: PNode, r: var TCompRes; start=1) =
proc genOtherArg(p: PProc; n: PNode; i: int; typ: PType;
generated: var int; r: var TCompRes) =
if i >= n.len:
globalError(n.info, "wrong importcpp pattern; expected parameter at position " & $i &
" but got only: " & $(n.len-1))
let it = n[i]
var paramType: PNode = nil
if i < sonsLen(typ):

View File

@@ -30,7 +30,12 @@ proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode =
case skipTypes(n.typ, abstractVarRange).kind
of tyInt:
result = newIntNode(nkIntLit, intVal)
result.typ = getIntLitType(result)
# See bug #6989. 'pred' et al only produce an int literal type if the
# original type was 'int', not a distinct int etc.
if n.typ.kind == tyInt:
result.typ = getIntLitType(result)
else:
result.typ = n.typ
# hrm, this is not correct: 1 + high(int) shouldn't produce tyInt64 ...
#setIntLitType(result)
of tyChar:

View File

@@ -944,6 +944,19 @@ proc toHex*[T](x: T): string =
## Shortcut for ``toHex(x, T.sizeOf * 2)``
toHex(BiggestInt(x), T.sizeOf * 2)
proc toHex*(s: string): string {.noSideEffect, rtl.} =
## Converts a bytes string to its hexadecimal representation.
##
## The output is twice the input long. No prefix like
## ``0x`` is generated.
const HexChars = "0123456789ABCDEF"
result = newString(s.len * 2)
for pos, c in s:
var n = ord(c)
result[pos * 2 + 1] = HexChars[n and 0xF]
n = n shr 4
result[pos * 2] = HexChars[n]
proc intToStr*(x: int, minchars: Positive = 1): string {.noSideEffect,
rtl, extern: "nsuIntToStr".} =
## Converts `x` to its decimal representation.
@@ -1026,6 +1039,43 @@ proc parseHexInt*(s: string): int {.noSideEffect, procvar,
of '\0': break
else: raise newException(ValueError, "invalid integer: " & s)
proc generateHexCharToValueMap(): string =
## Generate a string to map a hex digit to uint value
result = ""
for inp in 0..255:
let ch = chr(inp)
let o =
case ch:
of '0'..'9': inp - ord('0')
of 'a'..'f': inp - ord('a') + 10
of 'A'..'F': inp - ord('A') + 10
else: 17 # indicates an invalid hex char
result.add chr(o)
const hexCharToValueMap = generateHexCharToValueMap()
proc parseHexStr*(s: string): string {.noSideEffect, procvar,
rtl, extern: "nsuParseHexStr".} =
## Convert hex-encoded string to byte string, e.g.:
##
## .. code-block:: nim
## hexToStr("00ff") == "\0\255"
##
## Raises ``ValueError`` for an invalid hex values. The comparison is
## case-insensitive.
if s.len mod 2 != 0:
raise newException(ValueError, "Incorrect hex string len")
result = newString(s.len div 2)
var buf = 0
for pos, c in s:
let val = hexCharToValueMap[ord(c)].ord
if val == 17:
raise newException(ValueError, "Invalid hex char " & repr(c))
if pos mod 2 == 0:
buf = val
else:
result[pos div 2] = chr(val + buf shl 4)
proc parseBool*(s: string): bool =
## Parses a value into a `bool`.
##

View File

@@ -318,7 +318,7 @@ type
Slice*[T] = HSlice[T, T] ## an alias for ``HSlice[T, T]``
proc `..`*[T, U](a: T, b: U): HSlice[T, U] {.noSideEffect, inline, magic: "DotDot".} =
## `slice`:idx: operator that constructs an interval ``[a, b]``, both `a`
## binary `slice`:idx: operator that constructs an interval ``[a, b]``, both `a`
## and `b` are inclusive. Slices can also be used in the set constructor
## and in ordinal case statements, but then they are special-cased by the
## compiler.
@@ -326,7 +326,7 @@ proc `..`*[T, U](a: T, b: U): HSlice[T, U] {.noSideEffect, inline, magic: "DotDo
result.b = b
proc `..`*[T](b: T): HSlice[int, T] {.noSideEffect, inline, magic: "DotDot".} =
## `slice`:idx: operator that constructs an interval ``[default(int), b]``
## unary `slice`:idx: operator that constructs an interval ``[default(int), b]``
result.b = b
when not defined(niminheritable):
@@ -677,12 +677,12 @@ proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect, deprecated.}
## write ``0 ..< 10`` instead of ``0 .. < 10`` (look at the spacing).
## For ``<x`` write ``pred(x)``.
proc succ*[T](x: Ordinal[T], y = 1): T {.magic: "Succ", noSideEffect.}
proc succ*[T: Ordinal](x: T, y = 1): T {.magic: "Succ", noSideEffect.}
## returns the ``y``-th successor of the value ``x``. ``T`` has to be
## an ordinal type. If such a value does not exist, ``EOutOfRange`` is raised
## or a compile time error occurs.
proc pred*[T](x: Ordinal[T], y = 1): T {.magic: "Pred", noSideEffect.}
proc pred*[T: Ordinal](x: T, y = 1): T {.magic: "Pred", noSideEffect.}
## returns the ``y``-th predecessor of the value ``x``. ``T`` has to be
## an ordinal type. If such a value does not exist, ``EOutOfRange`` is raised
## or a compile time error occurs.
@@ -3505,8 +3505,8 @@ template `..^`*(a, b: untyped): untyped =
a .. ^b
template `..<`*(a, b: untyped): untyped =
## a shortcut for 'a..pred(b)'.
a .. pred(b)
## a shortcut for 'a .. (when b is BackwardsIndex: succ(b) else: pred(b))'.
a .. (when b is BackwardsIndex: succ(b) else: pred(b))
when defined(nimNewRoof):
iterator `..<`*[T](a, b: T): T =

View File

@@ -35,7 +35,7 @@ proc isUndefined[T](x: T): bool {.inline.} = {.emit: "`result` = `x` === undefin
proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
if not typ.node.sons[e].isUndefined:
result = $typ.node.sons[e].name
result = makeNimstrLit(typ.node.sons[e].name)
else:
result = $e & " (invalid data!)"

View File

@@ -92,7 +92,7 @@ This project exists thanks to all the people who contribute. [Read on to find ou
<a href="https://github.com/nim-lang/Nim/graphs/contributors"><img src="https://opencollective.com/Nim/contributors.svg?width=890" /></a>
## Contributing
[![Backers on Open Collective](https://opencollective.com/nim/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/nim/sponsors/badge.svg)](#sponsors) [![Contribute to Nim via Gratipay][badge-nim-gratipay]][nim-gratipay]
[![Backers on Open Collective](https://opencollective.com/nim/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/nim/sponsors/badge.svg)](#sponsors)
[![Setup a bounty via Bountysource][badge-nim-bountysource]][nim-bountysource]
[![Donate Bitcoins][badge-nim-bitcoin]][nim-bitcoin]
@@ -137,7 +137,6 @@ You can also help with the development of Nim by making donations. Donations can
made using:
* [Open Collective](https://opencollective.com/nim)
* [Gratipay][nim-gratipay]
* [Bountysource][nim-bountysource]
* [Bitcoin][nim-bitcoin]
@@ -189,7 +188,6 @@ Copyright © 2006-2017 Andreas Rumpf, all rights reserved.
[nim-stackoverflow]: https://stackoverflow.com/questions/tagged/nim
[nim-stackoverflow-newest]: https://stackoverflow.com/questions/tagged/nim?sort=newest&pageSize=15
[nim-gitter]: https://gitter.im/nim-lang/Nim
[nim-gratipay]: https://gratipay.com/nim/
[nim-bountysource]: https://www.bountysource.com/teams/nim
[nim-bitcoin]: https://blockchain.info/address/1BXfuKM2uvoD6mbx4g5xM3eQhLzkCK77tJ
[nimble-repo]: https://github.com/nim-lang/nimble
@@ -201,7 +199,6 @@ Copyright © 2006-2017 Andreas Rumpf, all rights reserved.
[badge-nim-forum-gethelp]: https://img.shields.io/badge/Forum-get%20help-4eb899.svg?style=flat-square
[badge-nim-twitter]: https://img.shields.io/twitter/follow/nim_lang.svg?style=social
[badge-nim-stackoverflow]: https://img.shields.io/badge/stackoverflow-nim_tag-yellow.svg?style=flat-square
[badge-nim-gratipay]: https://img.shields.io/gratipay/team/nim.svg?style=flat-square
[badge-nim-bountysource]: https://img.shields.io/bountysource/team/nim/activity.svg?style=flat-square
[badge-nim-bitcoin]: https://img.shields.io/badge/bitcoin-1BXfuKM2uvoD6mbx4g5xM3eQhLzkCK77tJ-D69134.svg?style=flat-square
[pull-request-instructions]: https://help.github.com/articles/using-pull-requests/

View File

@@ -0,0 +1,102 @@
discard """
output: '''OK
OK
OK
OK
OK
dflfdjkl__abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajs
dflfdjkl__abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajsdf
kgdchlfniambejop
fjpmholcibdgeakn
'''
"""
import strutils, sequtils, typetraits, os
# bug #6989
type Dist = distinct int
proc mypred[T: Ordinal](x: T): T = T(int(x)-1)
proc cons(x: int): Dist = Dist(x)
var d: Dist
template `^+`(s, i: untyped): untyped =
(when i is BackwardsIndex: s.len - int(i) else: int(i))
proc `...`*[T, U](a: T, b: U): HSlice[T, U] =
result.a = a
result.b = b
proc `...`*[T](b: T): HSlice[int, T] =
result.b = b
template `...<`*(a, b: untyped): untyped =
## a shortcut for 'a..pred(b)'.
a ... pred(b)
template check(a, b) =
if $a == b: echo "OK"
else: echo "Failure ", a, " != ", b
check type(4 ...< 1), "HSlice[system.int, system.int]"
check type(4 ...< ^1), "HSlice[system.int, system.BackwardsIndex]"
check type(4 ... pred(^1)), "HSlice[system.int, system.BackwardsIndex]"
check type(4 ... mypred(8)), "HSlice[system.int, system.int]"
check type(4 ... mypred(^1)), "HSlice[system.int, system.BackwardsIndex]"
var rot = 8
proc bug(s: string): string =
result = s
result = result[result.len - rot .. ^1] & "__" & result[0 ..< ^rot]
const testStr = "abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajsdflfdjkl"
echo bug(testStr)
echo testStr[testStr.len - 8 .. testStr.len - 1] & "__" & testStr[0 .. testStr.len - pred(rot)]
var
instructions = readFile(getAppDir() / "troofregression2.txt").split(',')
programs = "abcdefghijklmnop"
proc dance(dancers: string): string =
result = dancers
for instr in instructions:
let rem = instr[1 .. instr.high]
case instr[0]
of 's':
let rot = rem.parseInt
result = result[result.len - rot .. ^1] & result[0 ..< ^rot]
of 'x':
let
x = rem.split('/')
a = x[0].parseInt
b = x[1].parseInt
swap(result[a], result[b])
of 'p':
let
a = result.find(rem[0])
b = result.find(rem[^1])
result[a] = rem[^1]
result[b] = rem[0]
else: discard
proc longDance(dancers: string, iterations = 1_000_000_000): string =
var
dancers = dancers
seen = @[dancers]
for i in 1 .. iterations:
dancers = dancers.dance()
if dancers in seen:
return seen[iterations mod i]
seen.add(dancers)
echo dance(programs)
echo longDance(programs)

File diff suppressed because one or more lines are too long

View File

@@ -3,7 +3,7 @@ discard """
"""
block ints:
let
let
na: int8 = -120'i8
nb: int16 = -32700'i16
nc: int32 = -2147483000'i32
@@ -12,9 +12,9 @@ block ints:
pa: int8 = 120'i8
pb: int16 = 32700'i16
pc: int32 = 2147483000'i32
pd: int64 = 9223372036854775000'i64
pd: int64 = 9223372036854775000'i64
pe: int = 1234567
doAssert(repr(na) == "-120")
doAssert(repr(nb) == "-32700")
doAssert(repr(nc) == "-2147483000")
@@ -27,13 +27,13 @@ block ints:
doAssert(repr(pe) == "1234567")
block uints:
let
let
a: uint8 = 254'u8
b: uint16 = 65300'u16
c: uint32 = 4294967290'u32
# d: uint64 = 18446744073709551610'u64 -> unknown node type
e: uint = 1234567
doAssert(repr(a) == "254")
doAssert(repr(b) == "65300")
doAssert(repr(c) == "4294967290")
@@ -41,26 +41,26 @@ block uints:
doAssert(repr(e) == "1234567")
block floats:
let
let
a: float32 = 3.4e38'f32
b: float64 = 1.7976931348623157e308'f64
c: float = 1234.567e89
when defined js:
when defined js:
doAssert(repr(a) == "3.4e+38") # in C: 3.399999952144364e+038
doAssert(repr(b) == "1.7976931348623157e+308") # in C: 1.797693134862316e+308
doAssert(repr(c) == "1.234567e+92") # in C: 1.234567e+092
block bools:
let
let
a: bool = true
b: bool = false
doAssert(repr(a) == "true")
doAssert(repr(a) == "true")
doAssert(repr(b) == "false")
block enums:
type
type
AnEnum = enum
aeA
aeB
@@ -69,28 +69,34 @@ block enums:
heA = -12
heB = 15
heC = 123
doAssert(repr(aeA) == "aeA")
doAssert(repr(aeA) == "aeA")
doAssert(repr(aeB) == "aeB")
doAssert(repr(aeC) == "aeC")
doAssert(repr(aeC) == "aeC")
doAssert(repr(heA) == "heA")
doAssert(repr(heB) == "heB")
doAssert(repr(heB) == "heB")
doAssert(repr(heC) == "heC")
block emums_and_unicode: #6741
type K = enum Kanji = "漢字"
let kanji = Kanji
doAssert(kanji == Kanji, "Enum values are not equal")
doAssert($kanji == $Kanji, "Enum string values are not equal")
block chars:
let
a = 'a'
b = 'z'
one = '1'
nl = '\x0A'
doAssert(repr(a) == "'a'")
doAssert(repr(b) == "'z'")
doAssert(repr(one) == "'1'")
doAssert(repr(nl) == "'\\10'")
block strings:
let
let
a: string = "12345"
b: string = "hello,repr"
c: string = "hi\nthere"
@@ -103,19 +109,19 @@ block sets:
let
a: set[int16] = {1'i16, 2'i16, 3'i16}
b: set[char] = {'A', 'k'}
doAssert(repr(a) == "{1, 2, 3}")
doAssert(repr(b) == "{'A', 'k'}")
block ranges:
let
let
a: range[0..12] = 6
b: range[-12..0] = -6
doAssert(repr(a) == "6")
doAssert(repr(b) == "-6")
block tuples:
type
type
ATuple = tuple
a: int
b: float
@@ -124,7 +130,7 @@ block tuples:
OtherTuple = tuple
a: bool
b: int8
let
ot: OtherTuple = (a: true, b: 120'i8)
t: ATuple = (a: 42, b: 12.34, c: "tuple", d: ot)
@@ -176,7 +182,7 @@ block arrays:
o = AObj(x: 42, y: a)
c = [o, o, o]
d = ["hi", "array", "!"]
doAssert(repr(a) == "[0.0, 1.0, 2.0]\n")
doAssert(repr(b) == "[[0.0, 1.0, 2.0], [0.0, 1.0, 2.0], [0.0, 1.0, 2.0]]\n")
doAssert(repr(c) == """
@@ -198,7 +204,7 @@ block seqs:
o = AObj(x: 42, y: a)
c = @[o, o, o]
d = @["hi", "array", "!"]
doAssert(repr(a) == "@[0.0, 1.0, 2.0]\n")
doAssert(repr(b) == "@[@[0.0, 1.0, 2.0], @[0.0, 1.0, 2.0], @[0.0, 1.0, 2.0]]\n")
doAssert(repr(c) == """
@@ -210,16 +216,16 @@ y = @[0.0, 1.0, 2.0]]]
doAssert(repr(d) == "@[\"hi\", \"array\", \"!\"]\n")
block ptrs:
type
type
AObj = object
x: ptr array[2, AObj]
y: int
var
var
a = [12.0, 13.0, 14.0]
b = addr a[0]
c = addr a[2]
d = AObj()
doAssert(repr(a) == "[12.0, 13.0, 14.0]\n")
doAssert(repr(b) == "ref 0 --> 12.0\n")
doAssert(repr(c) == "ref 2 --> 14.0\n")
@@ -229,13 +235,13 @@ y = 0]
""")
block ptrs:
type
type
AObj = object
x: ref array[2, AObj]
y: int
var
var
a = AObj()
new(a.x)
doAssert(repr(a) == """
@@ -248,10 +254,10 @@ y = 0]
block procs:
proc test(): int =
echo "hello"
var
var
ptest = test
nilproc: proc(): int
doAssert(repr(test) == "0\n")
doAssert(repr(ptest) == "0\n")
doAssert(repr(nilproc) == "nil\n")
@@ -262,7 +268,7 @@ block bunch:
eA, eB, eC
B = object
a: string
b: seq[char]
b: seq[char]
A = object
a: uint32
b: int
@@ -281,17 +287,17 @@ block bunch:
o: tuple[x: B, y: string]
p: proc(b: B): ref B
q: cstring
proc refB(b:B):ref B =
new result
result[] = b
var
aa: A
bb: B = B(a: "inner", b: @['o', 'b', 'j'])
cc: A = A(a: 12, b: 1, c: 1.2, d: '\0', e: eC,
f: "hello", g: {'A'}, h: {2'i16},
i: ["hello", "world", "array"],
i: ["hello", "world", "array"],
j: @["hello", "world", "seq"], k: -1,
l: bb, m: refB(bb), n: addr bb,
o: (bb, "tuple!"), p: refB, q: "cstringtest" )
@@ -344,12 +350,12 @@ q = "cstringtest"]
""")
block another:
type
Size1 = enum
type
Size1 = enum
s1a, s1b
Size2 = enum
Size2 = enum
s2c=0, s2d=20000
Size3 = enum
Size3 = enum
s3e=0, s3f=2000000000
doAssert(repr([s1a, s1b]) == "[s1a, s1b]\n")
@@ -357,7 +363,7 @@ block another:
doAssert(repr([s3e, s3f]) == "[s3e, s3f]\n")
block another2:
type
AnEnum = enum
en1, en2, en3, en4, en5, en6

View File

@@ -1,8 +1,8 @@
#ifdef WIN
#include <windows.h>
#else
#include <dlfcn.h>
#include <unistd.h> /* for sleep(3) */
#endif
#include <stdio.h>
#include <stdlib.h>

View File

@@ -1,21 +1,21 @@
Test the realtime GC without linking nimrtl.dll/so.
Note, this is a long running test, default is 35 minutes. To change the
the run time see RUNTIME in main.nim and main.c.
the run time see RUNTIME in nmain.nim and cmain.c.
You can build shared.nim, main.nim, and main.c by running make (nix systems)
or maike.bat (Windows systems). They both assume GCC and that it's in your
path. Output: shared.(dll/so), camin(.exe), nmain(.exe).
You can build shared.nim, nmain.nim, and cmain.c by running make (nix systems)
or make.bat (Windows systems). They both assume GCC and that it's in your
path. Output: shared.(dll/so), cmain(.exe), nmain(.exe).
To run the test: execute either nmain or cmain in a shell window.
To build buy hand:
To build by hand:
- build the shared object (shared.nim):
$ nim c shared.nim
$ nim c tests/realtimeGC/shared.nim
- build the client executables:
$ nim c -o:nmain main.nim
$ gcc -o cmain main.c -ldl
$ nim c --threads:on tests/realtimeGC/nmain.nim
$ gcc -o tests/realtimeGC/cmain tests/realtimeGC/cmain.c -ldl

View File

@@ -229,6 +229,24 @@ assert "/1/2/3".rfind('0') == -1
assert(toHex(100i16, 32) == "00000000000000000000000000000064")
assert(toHex(-100i16, 32) == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C")
assert "".parseHexStr == ""
assert "00Ff80".parseHexStr == "\0\xFF\x80"
try:
discard "00Ff8".parseHexStr
assert false, "Should raise ValueError"
except ValueError:
discard
try:
discard "0k".parseHexStr
assert false, "Should raise ValueError"
except ValueError:
discard
assert "".toHex == ""
assert "\x00\xFF\x80".toHex == "00FF80"
assert "0123456789abcdef".parseHexStr.toHex == "0123456789ABCDEF"
assert(' '.repeat(8)== " ")
assert(" ".repeat(8) == " ")
assert(spaces(8) == " ")

View File

@@ -167,9 +167,9 @@ proc gcTests(r: var TResults, cat: Category, options: string) =
proc longGCTests(r: var TResults, cat: Category, options: string) =
when defined(windows):
let cOptions = "gcc -ldl -DWIN"
let cOptions = "-ldl -DWIN"
else:
let cOptions = "gcc -ldl"
let cOptions = "-ldl"
var c = initResults()
# According to ioTests, this should compile the file