Merge branch 'devel' into underscore-tuple-unpack

Conflicts:
	compiler/semstmts.nim
This commit is contained in:
Dominik Picheta 2015-04-23 00:26:17 +01:00
commit 9e69e4e078
171 changed files with 6910 additions and 5403 deletions

View file

@ -30,7 +30,7 @@ proc bar: int =
# local overrides that are active only
# in this proc
onFailedAssert(msg): echo "WARNING: " & msg
assert(false, "first assertion from bar")
onFailedAssert(msg):

View file

@ -0,0 +1,10 @@
type
Concrete* = object
a*, b*: string
rc*: int # refcount
proc `=`(d: var Concrete; src: Concrete) =
shallowCopy(d.a, src.a)
shallowCopy(d.b, src.b)
dec d.rc
d.rc = src.rc + 1

View file

@ -0,0 +1,75 @@
discard """
output: '''Concrete '='
Concrete '='
Concrete '='
Concrete '='
Concrete '='
GenericT[T] '=' int
GenericT[T] '=' float
GenericT[T] '=' float
GenericT[T] '=' float
GenericT[T] '=' string
GenericT[T] '=' int8
GenericT[T] '=' bool
GenericT[T] '=' bool
GenericT[T] '=' bool
GenericT[T] '=' bool'''
"""
import typetraits
type
Concrete = object
a, b: string
proc `=`(d: var Concrete; src: Concrete) =
shallowCopy(d.a, src.a)
shallowCopy(d.b, src.b)
echo "Concrete '='"
var x, y: array[0..2, Concrete]
var cA, cB: Concrete
var cATup, cBTup: tuple[x: int, ha: Concrete]
x = y
cA = cB
cATup = cBTup
type
GenericT[T] = object
a, b: T
proc `=`[T](d: var GenericT[T]; src: GenericT[T]) =
shallowCopy(d.a, src.a)
shallowCopy(d.b, src.b)
echo "GenericT[T] '=' ", type(T).name
var ag: GenericT[int]
var bg: GenericT[int]
ag = bg
var xg, yg: array[0..2, GenericT[float]]
var cAg, cBg: GenericT[string]
var cATupg, cBTupg: tuple[x: int, ha: GenericT[int8]]
xg = yg
cAg = cBg
cATupg = cBTupg
var caSeqg, cbSeqg: seq[GenericT[bool]]
newSeq(cbSeqg, 4)
caSeqg = cbSeqg
when false:
type
Foo = object
case b: bool
of false: xx: GenericT[int]
of true: yy: bool
var
a, b: Foo
a = b

View file

@ -0,0 +1,22 @@
discard """
output: '''i value 88
2aa'''
"""
import moverload_asgn2
proc passAround(i: int): Concrete =
echo "i value ", i
result = Concrete(a: "aa", b: "bb", rc: 0)
proc main =
let
i = 88
v = passAround(i)
z = v.a
var
x: Concrete
x = v
echo x.rc, z # 2aa
main()

View file

@ -1,17 +1,17 @@
discard """
line: 18
errormsg: "type mismatch: got (proc (TScgi) | proc (AsyncSocket, StringTableRef, string)"
errormsg: "type mismatch: got (proc (s: TScgi) | proc (client: AsyncSocket, headers: StringTableRef, input: string){.gcsafe, locks: 0.}"
"""
#bug #442
import scgi, sockets, asyncio, strtabs
proc handleSCGIRequest[TScgi: ScgiState | AsyncScgiState](s: TScgi) =
discard
proc handleSCGIRequest(client: AsyncSocket, headers: StringTableRef,
proc handleSCGIRequest(client: AsyncSocket, headers: StringTableRef,
input: string) =
discard
proc test(handle: proc (client: AsyncSocket, headers: StringTableRef,
proc test(handle: proc (client: AsyncSocket, headers: StringTableRef,
input: string), b: int) =
discard

View file

@ -0,0 +1,15 @@
discard """
output: '''true
true'''
"""
# bug #2489
let a = [1]
let b = [1]
echo a == b
# bug #2498
var x: array[0, int]
var y: array[0, int]
echo x == y

View file

@ -1,6 +1,6 @@
discard """
line: 12
errormsg: "type mismatch: got (proc (int){.closure, gcsafe, locks: 0.})"
errormsg: "type mismatch: got (proc (x: int){.closure, gcsafe, locks: 0.})"
"""
proc ugh[T](x: T) {.closure.} =

View file

@ -0,0 +1,23 @@
discard """
cmd: "nim cpp $file"
"""
{.emit: """
namespace System {
struct Input {};
}
struct SystemManager {
template <class T>
static T* getSubsystem() { return new T; }
};
""".}
type Input {.importcpp: "System::Input".} = object
proc getSubsystem*[T](): ptr T {.
importcpp: "SystemManager::getSubsystem<'*0>()", nodecl.}
let input: ptr Input = getSubsystem[Input]()

View file

@ -0,0 +1,19 @@
discard """
cmd: "nim cpp $file"
"""
{.emit: """
template <class T>
struct Vector {
struct Iterator {};
};
""".}
type
Vector {.importcpp: "Vector".} [T] = object
VectorIterator {.importcpp: "Vector<'0>::Iterator".} [T] = object
var x: VectorIterator[void]

View file

@ -40,7 +40,7 @@ type
x: A
y: B
z: C
TObjKind = enum A, B, C, D
TCaseObj = object
@ -57,14 +57,14 @@ type
q: TMyGeneric3[TMyObj, int, int]
r: string
proc destroy(o: var TMyObj) {.override.} =
proc `=destroy`(o: var TMyObj) =
if o.p != nil: dealloc o.p
echo "myobj destroyed"
proc destroy(o: var TMyGeneric1) {.override.} =
proc `=destroy`(o: var TMyGeneric1) =
echo "mygeneric1 destroyed"
proc destroy[A, B](o: var TMyGeneric2[A, B]) {.override.} =
proc `=destroy`[A, B](o: var TMyGeneric2[A, B]) =
echo "mygeneric2 destroyed"
proc open: TMyObj =
@ -83,12 +83,12 @@ proc mygeneric1() =
proc mygeneric2[T](val: T) =
var a = open()
var b = TMyGeneric2[int, T](x: 10, y: val)
echo "mygeneric2 constructed"
var c = TMyGeneric3[int, int, string](x: 10, y: 20, z: "test")
proc mygeneric3 =
var x = TMyGeneric3[int, string, TMyGeneric1[int]](
x: 10, y: "test", z: TMyGeneric1[int](x: 10))
@ -111,11 +111,11 @@ proc caseobj =
block:
echo "----"
var o1 = TCaseObj(kind: A, x: TMyGeneric1[int](x: 10))
block:
echo "----"
var o2 = TCaseObj(kind: B, y: open())
block:
echo "----"
var o3 = TCaseObj(kind: D, innerKind: B, r: "test",

View file

@ -5,14 +5,14 @@ discard """
{.experimental.}
type
type
TMyObj = object
x, y: int
p: pointer
proc destroy(o: var TMyObj) {.override.} =
proc `=destroy`(o: var TMyObj) =
if o.p != nil: dealloc o.p
proc open: TMyObj =
result = TMyObj(x: 1, y: 2, p: alloc(3))

View file

@ -1,5 +1,5 @@
discard """
line: 16
line: 17
errormsg: "'mainUnsafe' is not GC-safe"
cmd: "nim $target --hints:on --threads:on $options $file"
"""

View file

@ -35,9 +35,9 @@ echo ""
proc reraise_in_except =
try:
echo "BEFORE"
raise newException(EIO, "")
raise newException(IOError, "")
except EIO:
except IOError:
echo "EXCEPT"
raise
@ -52,7 +52,7 @@ echo ""
proc return_in_except =
try:
echo "BEFORE"
raise newException(EIO, "")
raise newException(IOError, "")
except:
echo "EXCEPT"

View file

@ -4,8 +4,8 @@ discard """
exitcode: "1"
"""
type
ESomething = object of E_Base
ESomeOtherErr = object of E_Base
ESomething = object of Exception
ESomeOtherErr = object of Exception
proc genErrors(s: string) =
if s == "error!":

View file

@ -0,0 +1,21 @@
discard """
errormsg: "cannot instantiate: 'GenericNodeObj'"
line: 21
"""
# bug #2509
type
GenericNodeObj[T] = ref object
obj: T
Node* = ref object
children*: seq[Node]
parent*: Node
nodeObj*: GenericNodeObj # [int]
proc newNode*(nodeObj: GenericNodeObj): Node =
result = Node(nodeObj: nodeObj)
newSeq(result.children, 10)
var genericObj = GenericNodeObj[int]()
var myNode = newNode(genericObj)

View file

@ -1,6 +1,7 @@
discard """
output: '''foo
js 3.14'''
js 3.14
7'''
"""
# This file tests the JavaScript generator
@ -20,3 +21,11 @@ else:
proc foo(val: float): string = "js " & $val
echo foo(3.14)
# #2495
type C = concept x
proc test(x: C, T: typedesc): T =
cast[T](x)
echo 7.test(int8)

24
tests/js/tstringitems.nim Normal file
View file

@ -0,0 +1,24 @@
discard """
output: '''Hello
Hello'''
"""
# bug #2581
const someVars = [ "Hello" ]
var someVars2 = [ "Hello" ]
proc getSomeVar: string =
for i in someVars:
if i == "Hello":
result = i
break
proc getSomeVar2: string =
for i in someVars2:
if i == "Hello":
result = i
break
echo getSomeVar()
echo getSomeVar2()

View file

@ -1,3 +1,10 @@
discard """
disabled: "true"
"""
# Unittest uses lambdalifting at compile-time which we disable for the JS
# codegen! So this cannot and will not work for quite some time.
import unittest
suite "Bacon":

16
tests/macros/tlexerex.nim Normal file
View file

@ -0,0 +1,16 @@
import macros
macro match*(s: cstring|string; pos: int; sections: untyped): untyped =
for sec in sections.children:
expectKind sec, nnkOfBranch
expectLen sec, 2
result = newStmtList()
when isMainModule:
var input = "the input"
var pos = 0
match input, pos:
of r"[a-zA-Z_]\w+": echo "an identifier"
of r"\d+": echo "an integer"
of r".": echo "something else"

View file

@ -15,5 +15,6 @@ const
valid = 45
a = test("foo&&")
b = test("valid")
c = test("\"") # bug #2504
echo a, " ", b

View file

@ -1,4 +1,4 @@
# tests to see if a symbol returned from macros.getType() can
# tests to see if a symbol returned from macros.getType() can
# be used as a type
import macros
@ -20,7 +20,7 @@ static: assert iii is TestFN
proc foo11 : testTypesym(void) =
echo "HI!"
static: assert foo11 is proc():void
static: assert foo11 is (proc():void {.nimcall.})
var sss: testTypesym(seq[int])
static: assert sss is seq[int]

View file

@ -1,11 +1,13 @@
discard """
errormsg: "expression 'generate(builder)' has no type (or is ambiguous)"
output: "empty"
"""
# bug #898
import typetraits
proc measureTime(e: auto) =
discard
echo e.type.name
proc generate(a: int): void =
discard

View file

@ -10,3 +10,17 @@ let t1 = v1 mod 2 # works
let t2 = 7'u64 mod 2'u64 # works
let t3 = v2 mod 2'u64 # Error: invalid type: 'range 0..1(uint64)
let t4 = (v2 mod 2'u64).uint64 # works
# bug #2550
var x: uint # doesn't work
echo x mod 2 == 0
var y: uint64 # doesn't work
echo y mod 2 == 0
var z: uint32 # works
echo z mod 2 == 0
var a: int # works
echo a mod 2 == 0

View file

@ -0,0 +1,14 @@
discard """
output: '''253'''
"""
# bug #2427
import unsigned
var x = 0'u8
dec x # OverflowError
x -= 1 # OverflowError
x = x - 1 # No error
echo x

View file

@ -0,0 +1,7 @@
discard """
errormsg: "illegal recursion in type 'object'"
line: 7
"""
# bug #1691
type
Foo = ref object of Foo

View file

@ -0,0 +1,15 @@
discard """
output: "is Nil false"
"""
# bug #1658
type
Loop* = ref object
onBeforeSelect*: proc (L: Loop)
var L: Loop
new L
L.onBeforeSelect = proc (bar: Loop) =
echo "is Nil ", bar.isNil
L.onBeforeSelect(L)

View file

@ -0,0 +1,19 @@
# bug #2508
type
GenericNodeObj[T] = ref object
obj: T
Node* = ref object
children*: seq[Node]
parent*: Node
nodeObj*: GenericNodeObj[int]
proc newNode*(nodeObj: GenericNodeObj): Node =
result = Node(nodeObj: nodeObj)
newSeq(result.children, 10)
var genericObj = GenericNodeObj[int]()
var myNode = newNode(genericObj)

View file

@ -0,0 +1,38 @@
# bug #2481
import math
template test(loopCount: int, extraI: int, testBody: stmt): stmt =
block:
for i in 0..loopCount-1:
testBody
echo "done extraI=", extraI
template test(loopCount: int, extraF: float, testBody: stmt): stmt =
block:
test(loopCount, round(extraF), testBody)
template test(loopCount: int, testBody: stmt): stmt =
block:
test(loopCount, 0, testBody)
echo "done extraI passed 0"
when isMainModule:
var
loops = 0
test 0, 0:
loops += 1
echo "test 0 complete, loops=", loops
test 1, 1.0:
loops += 1
echo "test 1.0 complete, loops=", loops
when true:
# when true we get the following compile time error:
# b.nim(35, 6) Error: expression 'loops += 1' has no type (or is ambiguous)
loops = 0
test 2:
loops += 1
echo "test no extra complete, loops=", loops

View file

@ -0,0 +1,39 @@
discard """
line: 28
nimout: '''tgc_unsafe2.nim(22, 5) Warning: 'trick' is not GC-safe as it accesses 'global' which is a global using GC'ed memory
tgc_unsafe2.nim(26, 5) Warning: 'track' is not GC-safe as it calls 'trick'
tgc_unsafe2.nim(28, 5) Error: 'consumer' is not GC-safe as it calls 'track'
'''
errormsg: "'consumer' is not GC-safe as it calls 'track'"
"""
import threadpool
type StringChannel = TChannel[string]
var channels: array[1..3, StringChannel]
type
MyObject[T] = object
x: T
var global: MyObject[string]
var globalB: MyObject[float]
proc trick(ix: int) =
echo global.x
echo channels[ix].recv()
proc track(ix: int) = trick(ix)
proc consumer(ix: int) {.thread.} =
track(ix)
proc main =
for ix in 1..3: channels[ix].open()
for ix in 1..3: spawn consumer(ix)
for ix in 1..3: channels[ix].send("test")
sync()
for ix in 1..3: channels[ix].close()
when isMainModule:
main()

View file

@ -0,0 +1,53 @@
discard """
output: "Success"
"""
import math, threadPool
# ---
type
Person = object
age: int
friend: ref Person
var
people: seq[ref Person] = @[]
proc newPerson(age:int): ref Person =
result.new()
result.age = age
proc greet(p:Person) =
#echo p.age, ", ", p.friend.age
p.friend.age += 1
# ---
proc setup =
for i in 0 .. <20:
people.add newPerson(i + 1)
for i in 0 .. <20:
people[i].friend = people[random(20)]
proc update =
var countA: array[20, int]
var countB: array[20, int]
for i, p in people:
countA[i] = getRefCount(p)
parallel:
for i in 0 .. people.high:
spawn greet(people[i][])
for i, p in people:
countB[i] = getRefCount(p)
for i in 0 .. <20:
doAssert countA[i] == countB[i]
echo "Success"
# ---
when isMainModule:
setup()
update()

View file

@ -2,6 +2,12 @@
discard """
output: '''35
true
true
4
true
1
false
77
(Field0: 1, Field1: 2, Field2: 2)
ha
@ -9,11 +15,26 @@ true
tester args
all
all args
19
-3
false
-2
'''
"""
echo 2+5 * 5
# Keyword operators
echo 1 + 16 shl 1 == 1 + (16 shl 1)
echo 2 and 1 in {0, 30}
echo 2+2 * 2 shr 1
echo false or 2 and 1 in {0, 30}
proc `^`(a, b: int): int = a + b div 2
echo 19 mod 16 ^ 4 + 2 and 1
echo 18 mod 16 ^ 4 > 0
# echo $foo gotcha
let foo = 77
echo $foo
@ -27,7 +48,7 @@ when true:
let b = 66
let c = 90
let bar = 8000
if foo+4 * 4 == 8 and b&c | 9 ++
if foo+4 * 4 == 8 and b&c | 9 ++
bar:
echo "ho"
else:
@ -50,3 +71,13 @@ const
echo tester & " " & args|"all"
echo "all" | tester & " " & args
echo "all"|tester & " " & args
# Test arrow like operators. See also tests/macros/tclosuremacro.nim
proc `+->`(a, b: int): int = a + b*4
template `===>`(a, b: int): expr = a - b shr 1
echo 3 +-> 2 + 2 and 4
var arrowed = 3+->2 + 2 and 4 # arrowed = 4
echo arrowed ===> 15
echo (2 * 3+->2) == (2*3 +-> 2)
echo arrowed ===> 2 + 3+->2

9
tests/stdlib/treloop.nim Normal file
View file

@ -0,0 +1,9 @@
discard """
output: "@[(, +, 1, 2, )]"
"""
import re
let str = "(+ 1 2)"
var tokenRE = re"""[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)"""
echo str.findAll(tokenRE)

View file

@ -0,0 +1,30 @@
# bug #2585
type
RenderPass = object
state: ref int
RenderData* = object
fb: int
walls: seq[RenderPass]
Mat2 = int
Vector2[T] = T
Pixels=int
template use*(fb: int, st: stmt) : stmt =
echo "a ", $fb
st
echo "a ", $fb
proc render(rdat: var RenderData; passes: var openarray[RenderPass]; proj: Mat2;
indexType = 1) =
for i in 0 .. <len(passes):
echo "blah ", repr(passes[i])
proc render2*(rdat: var RenderData; screenSz: Vector2[Pixels]; proj: Mat2) =
use rdat.fb:
render(rdat, rdat.walls, proj, 1)

View file

@ -3,12 +3,12 @@ discard """
line: 18
errormsg: "undeclared identifier: \'b\'"
"""
template declareInScope(x: expr, t: typeDesc): stmt {.immediate.} =
template declareInScope(x: untyped, t: typeDesc): untyped {.immediate.} =
var x: t
template declareInNewScope(x: expr, t: typeDesc): stmt {.immediate.} =
template declareInNewScope(x: untyped, t: typeDesc): untyped {.immediate.} =
# open a new scope:
block:
block:
var x: t
declareInScope(a, int)

View file

@ -42,7 +42,8 @@ type
action*: TTestAction
file*, cmd*: string
outp*: string
line*, exitCode*: int
line*, column*: int
exitCode*: int
msg*: string
ccodeCheck*: string
err*: TResultEnum
@ -98,6 +99,8 @@ proc parseSpec*(filename: string): TSpec =
result.nimout = ""
result.ccodeCheck = ""
result.cmd = cmdTemplate
result.line = 0
result.column = 0
parseSpecAux:
case normalize(e.key)
of "action":
@ -108,6 +111,7 @@ proc parseSpec*(filename: string): TSpec =
else: echo ignoreMsg(p, e)
of "file": result.file = e.value
of "line": discard parseInt(e.value, result.line)
of "column": discard parseInt(e.value, result.column)
of "output":
result.action = actionRun
result.outp = e.value

View file

@ -50,7 +50,7 @@ type
let
pegLineError =
peg"{[^(]*} '(' {\d+} ', ' \d+ ') ' ('Error') ':' \s* {.*}"
peg"{[^(]*} '(' {\d+} ', ' {\d+} ') ' ('Error') ':' \s* {.*}"
pegOtherError = peg"'Error:' \s* {.*}"
pegSuccess = peg"'Hint: operation successful'.*"
pegOfInterest = pegLineError / pegOtherError
@ -77,11 +77,13 @@ proc callCompiler(cmdTemplate, filename, options: string,
result.msg = ""
result.file = ""
result.outp = ""
result.line = -1
result.line = 0
result.column = 0
if err =~ pegLineError:
result.file = extractFilename(matches[0])
result.line = parseInt(matches[1])
result.msg = matches[2]
result.column = parseInt(matches[2])
result.msg = matches[3]
elif err =~ pegOtherError:
result.msg = matches[0]
elif suc =~ pegSuccess:
@ -130,8 +132,11 @@ proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest) =
elif extractFilename(expected.file) != extractFilename(given.file) and
"internal error:" notin expected.msg:
r.addResult(test, expected.file, given.file, reFilesDiffer)
elif expected.line != given.line and expected.line != 0:
r.addResult(test, $expected.line, $given.line, reLinesDiffer)
elif expected.line != given.line and expected.line != 0 or
expected.column != given.column and expected.column != 0:
r.addResult(test, $expected.line & ':' & $expected.column,
$given.line & ':' & $given.column,
reLinesDiffer)
else:
r.addResult(test, expected.msg, given.msg, reSuccess)
inc(r.passed)

View file

@ -0,0 +1,10 @@
# bug #1986 found by gdmoore
proc test(): int64 =
return 0xdeadbeef.int64
const items = [
(var1: test(), var2: 100'u32),
(var1: test(), var2: 192'u32)
]

View file

@ -1,5 +1,11 @@
discard """
output: '''true true false yes'''
output: '''true true false yes
false
false
false
true
true
no'''
"""
proc IsVoid[T](): string =
@ -28,7 +34,7 @@ no s.items is iterator: float
yes s.items is iterator: TNumber
no s.items is iterator: object
type
type
Iter[T] = iterator: T
yes s.items is Iter[TNumber]
@ -51,3 +57,34 @@ yes Foo[4, int] is Bar[int]
no Foo[4, int] is Baz[4]
yes Foo[4, float] is Baz[4]
# bug #2505
echo(8'i8 is int32)
# bug #1853
type SeqOrSet[E] = seq[E] or set[E]
type SeqOfInt = seq[int]
type SeqOrSetOfInt = SeqOrSet[int]
# This prints "false", which seems less correct that (1) printing "true" or (2)
# raising a compiler error.
echo seq is SeqOrSet
# This prints "false", as expected.
echo seq is SeqOrSetOfInt
# This prints "true", as expected.
echo SeqOfInt is SeqOrSet
# This causes an internal error (filename: compiler/semtypes.nim, line: 685).
echo SeqOfInt is SeqOrSetOfInt
# bug #2522
proc test[T](x: T) =
when T is typedesc:
echo "yes"
else:
echo "no"
test(7)