mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-22 07:15:22 +00:00
Merge branch 'upstream' into devel
Conflicts: compiler/ccgutils.nim compiler/msgs.nim compiler/sem.nim compiler/semexprs.nim compiler/seminst.nim compiler/semmagic.nim compiler/semstmts.nim compiler/semtypes.nim compiler/semtypinst.nim compiler/sigmatch.nim compiler/types.nim compiler/vmgen.nim lib/core/macros.nim lib/system.nim tests/reject/tenummix.nim web/news.txt
This commit is contained in:
@@ -16,10 +16,10 @@ type
|
||||
TBar = tuple
|
||||
x, y: int
|
||||
|
||||
template good(e: expr) =
|
||||
template accept(e: expr) =
|
||||
static: assert(compiles(e))
|
||||
|
||||
template bad(e: expr) =
|
||||
template reject(e: expr) =
|
||||
static: assert(not compiles(e))
|
||||
|
||||
proc genericParamRepeated[T: typedesc](a: T, b: T) =
|
||||
@@ -27,22 +27,22 @@ proc genericParamRepeated[T: typedesc](a: T, b: T) =
|
||||
echo a.name
|
||||
echo b.name
|
||||
|
||||
good(genericParamRepeated(int, int))
|
||||
good(genericParamRepeated(float, float))
|
||||
accept genericParamRepeated(int, int)
|
||||
accept genericParamRepeated(float, float)
|
||||
|
||||
bad(genericParamRepeated(string, int))
|
||||
bad(genericParamRepeated(int, float))
|
||||
reject genericParamRepeated(string, int)
|
||||
reject genericParamRepeated(int, float)
|
||||
|
||||
proc genericParamOnce[T: typedesc](a, b: T) =
|
||||
static:
|
||||
echo a.name
|
||||
echo b.name
|
||||
|
||||
good(genericParamOnce(int, int))
|
||||
good(genericParamOnce(TFoo, TFoo))
|
||||
accept genericParamOnce(int, int)
|
||||
accept genericParamOnce(TFoo, TFoo)
|
||||
|
||||
bad(genericParamOnce(string, int))
|
||||
bad(genericParamOnce(TFoo, float))
|
||||
reject genericParamOnce(string, int)
|
||||
reject genericParamOnce(TFoo, float)
|
||||
|
||||
type
|
||||
type1 = typedesc
|
||||
@@ -50,42 +50,42 @@ type
|
||||
|
||||
proc typePairs(A, B: type1; C, D: type2) = nil
|
||||
|
||||
good(typePairs(int, int, TFoo, TFOO))
|
||||
good(typePairs(TBAR, TBar, TBAR, TBAR))
|
||||
good(typePairs(int, int, string, string))
|
||||
accept typePairs(int, int, TFoo, TFOO)
|
||||
accept typePairs(TBAR, TBar, TBAR, TBAR)
|
||||
accept typePairs(int, int, string, string)
|
||||
|
||||
bad(typePairs(TBAR, TBar, TBar, TFoo))
|
||||
bad(typePairs(string, int, TBAR, TBAR))
|
||||
reject typePairs(TBAR, TBar, TBar, TFoo)
|
||||
reject typePairs(string, int, TBAR, TBAR)
|
||||
|
||||
proc typePairs2[T: typedesc, U: typedesc](A, B: T; C, D: U) = nil
|
||||
|
||||
good(typePairs2(int, int, TFoo, TFOO))
|
||||
good(typePairs2(TBAR, TBar, TBAR, TBAR))
|
||||
good(typePairs2(int, int, string, string))
|
||||
accept typePairs2(int, int, TFoo, TFOO)
|
||||
accept typePairs2(TBAR, TBar, TBAR, TBAR)
|
||||
accept typePairs2(int, int, string, string)
|
||||
|
||||
bad(typePairs2(TBAR, TBar, TBar, TFoo))
|
||||
bad(typePairs2(string, int, TBAR, TBAR))
|
||||
reject typePairs2(TBAR, TBar, TBar, TFoo)
|
||||
reject typePairs2(string, int, TBAR, TBAR)
|
||||
|
||||
proc dontBind(a: typedesc, b: typedesc) =
|
||||
static:
|
||||
echo a.name
|
||||
echo b.name
|
||||
|
||||
good(dontBind(int, float))
|
||||
good(dontBind(TFoo, TFoo))
|
||||
accept dontBind(int, float)
|
||||
accept dontBind(TFoo, TFoo)
|
||||
|
||||
proc dontBind2(a, b: typedesc) = nil
|
||||
|
||||
good(dontBind2(int, float))
|
||||
good(dontBind2(TBar, int))
|
||||
accept dontBind2(int, float)
|
||||
accept dontBind2(TBar, int)
|
||||
|
||||
proc bindArg(T: typedesc, U: typedesc, a, b: T, c, d: U) = nil
|
||||
|
||||
good(bindArg(int, string, 10, 20, "test", "nest"))
|
||||
good(bindArg(int, int, 10, 20, 30, 40))
|
||||
accept bindArg(int, string, 10, 20, "test", "nest")
|
||||
accept bindArg(int, int, 10, 20, 30, 40)
|
||||
|
||||
bad(bindArg(int, string, 10, "test", "test", "nest"))
|
||||
bad(bindArg(int, int, 10, 20, 30, "test"))
|
||||
bad(bindArg(int, string, 10.0, 20, "test", "nest"))
|
||||
bad(bindArg(int, string, "test", "nest", 10, 20))
|
||||
reject bindArg(int, string, 10, "test", "test", "nest")
|
||||
reject bindArg(int, int, 10, 20, 30, "test")
|
||||
reject bindArg(int, string, 10.0, 20, "test", "nest")
|
||||
reject bindArg(int, string, "test", "nest", 10, 20)
|
||||
|
||||
|
||||
35
tests/compile/tcompositetypeclasses.nim
Normal file
35
tests/compile/tcompositetypeclasses.nim
Normal file
@@ -0,0 +1,35 @@
|
||||
template accept(e) =
|
||||
static: assert(compiles(e))
|
||||
|
||||
template reject(e) =
|
||||
static: assert(not compiles(e))
|
||||
|
||||
type
|
||||
TFoo[T, U] = tuple
|
||||
x: T
|
||||
y: U
|
||||
|
||||
TBar[K] = TFoo[K, K]
|
||||
|
||||
TUserClass = int|string
|
||||
|
||||
TBaz = TBar[TUserClass]
|
||||
|
||||
var
|
||||
vfoo: TFoo[int, string]
|
||||
vbar: TFoo[string, string]
|
||||
vbaz: TFoo[int, int]
|
||||
vnotbaz: TFoo[TObject, TObject]
|
||||
|
||||
proc foo(x: TFoo) = echo "foo"
|
||||
proc bar(x: TBar) = echo "bar"
|
||||
proc baz(x: TBaz) = echo "baz"
|
||||
|
||||
accept foo(vfoo)
|
||||
accept bar(vbar)
|
||||
accept baz(vbar)
|
||||
accept baz(vbaz)
|
||||
|
||||
reject baz(vnotbaz)
|
||||
reject bar(vfoo)
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
# Test nested loops and some other things
|
||||
|
||||
proc andTest() =
|
||||
var a = 0 == 5 and 6 == 6
|
||||
|
||||
proc incx(x: var int) = # is built-in proc
|
||||
x = x + 1
|
||||
|
||||
proc decx(x: var int) =
|
||||
x = x - 1
|
||||
|
||||
proc First(y: var int) =
|
||||
var x: int
|
||||
i_ncx(x)
|
||||
if x == 10:
|
||||
y = 0
|
||||
else:
|
||||
if x == 0:
|
||||
incx(x)
|
||||
else:
|
||||
x=11
|
||||
|
||||
proc TestLoops() =
|
||||
var i, j: int
|
||||
while i >= 0:
|
||||
if i mod 3 == 0:
|
||||
break
|
||||
i = i + 1
|
||||
while j == 13:
|
||||
j = 13
|
||||
break
|
||||
break
|
||||
|
||||
while True:
|
||||
break
|
||||
|
||||
|
||||
proc Foo(n: int): int =
|
||||
var
|
||||
a, old: int
|
||||
b, c: bool
|
||||
F_irst(a)
|
||||
if a == 10:
|
||||
a = 30
|
||||
elif a == 11:
|
||||
a = 22
|
||||
elif a == 12:
|
||||
a = 23
|
||||
elif b:
|
||||
old = 12
|
||||
else:
|
||||
a = 40
|
||||
|
||||
#
|
||||
b = false or 2 == 0 and 3 == 9
|
||||
a = 0 + 3 * 5 + 6 + 7 + +8 # 36
|
||||
while b:
|
||||
a = a + 3
|
||||
a = a + 5
|
||||
write(stdout, "Hello!")
|
||||
|
||||
|
||||
# We should come till here :-)
|
||||
discard Foo(345)
|
||||
# Test nested loops and some other things
|
||||
|
||||
proc andTest() =
|
||||
var a = 0 == 5 and 6 == 6
|
||||
|
||||
proc incx(x: var int) = # is built-in proc
|
||||
x = x + 1
|
||||
|
||||
proc decx(x: var int) =
|
||||
x = x - 1
|
||||
|
||||
proc First(y: var int) =
|
||||
var x: int
|
||||
i_ncx(x)
|
||||
if x == 10:
|
||||
y = 0
|
||||
else:
|
||||
if x == 0:
|
||||
incx(x)
|
||||
else:
|
||||
x=11
|
||||
|
||||
proc TestLoops() =
|
||||
var i, j: int
|
||||
while i >= 0:
|
||||
if i mod 3 == 0:
|
||||
break
|
||||
i = i + 1
|
||||
while j == 13:
|
||||
j = 13
|
||||
break
|
||||
break
|
||||
|
||||
while True:
|
||||
break
|
||||
|
||||
|
||||
proc Foo(n: int): int =
|
||||
var
|
||||
a, old: int
|
||||
b, c: bool
|
||||
F_irst(a)
|
||||
if a == 10:
|
||||
a = 30
|
||||
elif a == 11:
|
||||
a = 22
|
||||
elif a == 12:
|
||||
a = 23
|
||||
elif b:
|
||||
old = 12
|
||||
else:
|
||||
a = 40
|
||||
|
||||
#
|
||||
b = false or 2 == 0 and 3 == 9
|
||||
a = 0 + 3 * 5 + 6 + 7 + +8 # 36
|
||||
while b:
|
||||
a = a + 3
|
||||
a = a + 5
|
||||
write(stdout, "Hello!")
|
||||
|
||||
|
||||
# We should come till here :-)
|
||||
discard Foo(345)
|
||||
|
||||
# test the new type symbol lookup feature:
|
||||
|
||||
|
||||
@@ -3,15 +3,14 @@ discard """
|
||||
line: 13
|
||||
errormsg: "illegal recursion in type \'TIllegal\'"
|
||||
"""
|
||||
# test illegal recursive types
|
||||
|
||||
type
|
||||
TLegal {.final.} = object
|
||||
x: int
|
||||
kids: seq[TLegal]
|
||||
|
||||
TIllegal {.final.} = object #ERROR_MSG illegal recursion in type 'TIllegal'
|
||||
y: Int
|
||||
x: array[0..3, TIllegal]
|
||||
# test illegal recursive types
|
||||
|
||||
type
|
||||
TLegal {.final.} = object
|
||||
x: int
|
||||
kids: seq[TLegal]
|
||||
|
||||
TIllegal {.final.} = object #ERROR_MSG illegal recursion in type 'TIllegal'
|
||||
y: Int
|
||||
x: array[0..3, TIllegal]
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ discard """
|
||||
line: 7
|
||||
errormsg: "illegal recursion in type \'Uint8\'"
|
||||
"""
|
||||
type
|
||||
Uint8 = Uint8 #ERROR_MSG illegal recursion in type 'Uint8'
|
||||
|
||||
|
||||
type
|
||||
Uint8 = Uint8 #ERROR_MSG illegal recursion in type 'Uint8'
|
||||
|
||||
|
||||
51
tests/run/tfailedassert.nim
Normal file
51
tests/run/tfailedassert.nim
Normal file
@@ -0,0 +1,51 @@
|
||||
discard """
|
||||
output: '''
|
||||
WARNING: false first asseertion from bar
|
||||
ERROR: false second assertion from bar
|
||||
-1
|
||||
tests/run/tfailedassert.nim:27 false assertion from foo
|
||||
'''
|
||||
"""
|
||||
|
||||
type
|
||||
TLineInfo = tuple[filename: string, line: int]
|
||||
|
||||
TMyError = object of E_Base
|
||||
lineinfo: TLineInfo
|
||||
|
||||
EMyError = ref TMyError
|
||||
|
||||
# module-wide policy to change the failed assert
|
||||
# exception type in order to include a lineinfo
|
||||
onFailedAssert(msg):
|
||||
var e = new(TMyError)
|
||||
e.msg = msg
|
||||
e.lineinfo = instantiationInfo(-2)
|
||||
raise e
|
||||
|
||||
proc foo =
|
||||
assert(false, "assertion from foo")
|
||||
|
||||
proc bar: int =
|
||||
# local overrides that are active only
|
||||
# in this proc
|
||||
onFailedAssert(msg): echo "WARNING: " & msg
|
||||
|
||||
assert(false, "first asseertion from bar")
|
||||
|
||||
onFailedAssert(msg):
|
||||
echo "ERROR: " & msg
|
||||
return -1
|
||||
|
||||
assert(false, "second assertion from bar")
|
||||
return 10
|
||||
|
||||
echo("")
|
||||
echo(bar())
|
||||
|
||||
try:
|
||||
foo()
|
||||
except:
|
||||
let e = EMyError(getCurrentException())
|
||||
echo e.lineinfo.filename, ":", e.lineinfo.line, " ", e.msg
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
discard """
|
||||
msg: "test 1\ntest 2"
|
||||
output: "TEST 1\nTEST 2\nTEST 2"
|
||||
msg: "test 1\ntest 2\ntest 3"
|
||||
output: "TEST 1\nTEST 2\nTEST 3"
|
||||
"""
|
||||
|
||||
import strutils
|
||||
|
||||
proc foo(s: expr[string]): string =
|
||||
proc foo(s: static[string]): string =
|
||||
static: echo s
|
||||
|
||||
const R = s.toUpper
|
||||
return R
|
||||
|
||||
|
||||
echo foo("test 1")
|
||||
echo foo("test 2")
|
||||
echo foo("test " & $2)
|
||||
echo foo("test " & $3)
|
||||
|
||||
|
||||
24
tests/run/tsemistatic.nim
Normal file
24
tests/run/tsemistatic.nim
Normal file
@@ -0,0 +1,24 @@
|
||||
discard """
|
||||
msg: "static 10\ndynamic\nstatic 20\n"
|
||||
output: "s\nd\nd\ns"
|
||||
"""
|
||||
|
||||
proc foo(x: semistatic[int]) =
|
||||
when isStatic(x):
|
||||
static: echo "static ", x
|
||||
echo "s"
|
||||
else:
|
||||
static: echo "dynamic"
|
||||
echo "d"
|
||||
|
||||
foo 10
|
||||
|
||||
var
|
||||
x = 10
|
||||
y: int
|
||||
|
||||
foo x
|
||||
foo y
|
||||
|
||||
foo 20
|
||||
|
||||
@@ -4,15 +4,15 @@ discard """
|
||||
"""
|
||||
|
||||
type
|
||||
TFoo[T; Val: expr[string]] = object
|
||||
TFoo[T; Val: static[string]] = object
|
||||
data: array[4, T]
|
||||
|
||||
TBar[T; I: expr[int]] = object
|
||||
TBar[T; I: static[int]] = object
|
||||
data: array[I, T]
|
||||
|
||||
TA1[T; I: expr[int]] = array[I, T]
|
||||
TA2[T; I: expr[int]] = array[0..I, T]
|
||||
TA3[T; I: expr[int]] = array[I-1, T]
|
||||
TA1[T; I: static[int]] = array[I, T]
|
||||
# TA2[T; I: static[int]] = array[0..I, T]
|
||||
# TA3[T; I: static[int]] = array[I-1, T]
|
||||
|
||||
proc takeFoo(x: TFoo) =
|
||||
echo "abracadabra"
|
||||
@@ -25,7 +25,7 @@ var y: TBar[float, 4]
|
||||
echo high(y.data)
|
||||
|
||||
var
|
||||
t1: TA1
|
||||
t2: TA2
|
||||
t3: TA3
|
||||
t1: TA1[float, 1]
|
||||
# t2: TA2[string, 4]
|
||||
# t3: TA3[int, 10]
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
discard """
|
||||
msg: "int\nstring\nTBar[int]"
|
||||
output: "int\nstring\nTBar[int]\nint\nrange 0..2\nstring"
|
||||
output: "int\nstring\nTBar[int]\nint\nrange 0..2(int)\nstring"
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
||||
@@ -8,25 +8,11 @@ import
|
||||
|
||||
# This macro mimics the using statement from C#
|
||||
#
|
||||
# XXX:
|
||||
# It doen't match the C# version exactly yet.
|
||||
# In particular, it's not recursive, which prevents it from dealing
|
||||
# with exceptions thrown from the variable initializers when multiple.
|
||||
# variables are used.
|
||||
# It's kept only as a test for the macro system
|
||||
# Nimrod's destructors offer a mechanism for automatic
|
||||
# disposal of resources.
|
||||
#
|
||||
# Also, since nimrod relies less on exceptions in general, a more
|
||||
# idiomatic definition could be:
|
||||
# var x = init()
|
||||
# if opened(x):
|
||||
# try:
|
||||
# body
|
||||
# finally:
|
||||
# close(x)
|
||||
#
|
||||
# `opened` here could be an overloaded proc which any type can define.
|
||||
# A common practice can be returing an Optional[Resource] obj for which
|
||||
# `opened` is defined to `optional.hasValue`
|
||||
macro using(e: expr): stmt {.immediate.} =
|
||||
macro autoClose(e: expr): stmt {.immediate.} =
|
||||
let e = callsite()
|
||||
if e.len != 3:
|
||||
error "Using statement: unexpected number of arguments. Got " &
|
||||
@@ -97,7 +83,7 @@ proc close(r: var TResource) =
|
||||
proc use(r: var TResource) =
|
||||
write(stdout, "Using " & r.field & ".")
|
||||
|
||||
using(r = openResource("test")):
|
||||
autoClose(r = openResource("test")):
|
||||
use r
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user