next steps for closure iterators

This commit is contained in:
Araq
2014-01-22 17:32:38 +01:00
parent 85a5bfe605
commit 37229df7fc
28 changed files with 164 additions and 71 deletions

View File

@@ -0,0 +1,41 @@
discard """
output: '''(k: kindA, a: (x: abc, z: [1, 1, 3]), empty: ())
(k: kindA, a: (x: abc, z: [1, 2, 3]), empty: ())
(k: kindA, a: (x: abc, z: [1, 3, 3]), empty: ())
(k: kindA, a: (x: abc, z: [1, 4, 3]), empty: ())
(k: kindA, a: (x: abc, z: [1, 5, 3]), empty: ())
(k: kindA, a: (x: abc, z: [1, 6, 3]), empty: ())
(k: kindA, a: (x: abc, z: [1, 7, 3]), empty: ())
(k: kindA, a: (x: abc, z: [1, 8, 3]), empty: ())
(k: kindA, a: (x: abc, z: [1, 9, 3]), empty: ())
(k: kindA, a: (x: abc, z: [1, 10, 3]), empty: ())'''
"""
type
TArg = object
x: string
z: seq[int]
TKind = enum kindXY, kindA
TEmpty = object
TDummy = ref object
case k: TKind
of kindXY: x, y: int
of kindA:
a: TArg
empty: TEmpty
proc `$`[T](s: seq[T]): string =
# XXX why is that not in the stdlib?
result = "["
for i, x in s:
if i > 0: result.add(", ")
result.add($x)
result.add("]")
proc main() =
for i in 1..10:
let d = TDummy(k: kindA, a: TArg(x: "abc", z: @[1,i,3]), empty: TEmpty())
echo d[]
main()

View File

@@ -0,0 +1,22 @@
type TFoo{.exportc.} = object
x:int
var s{.exportc.}: seq[TFoo] = @[]
s.add TFoo(x: 42)
echo s[0].x
# bug #563
type
Foo =
object {.inheritable.}
x: int
Bar =
object of Foo
y: int
var a = Bar(y: 100, x: 200) # works
var b = Bar(x: 100, y: 200) # used to fail

17
tests/objects/tobjcov.nim Normal file
View File

@@ -0,0 +1,17 @@
# Covariance is not type safe:
type
TA = object of TObject
a: int
TB = object of TA
b: array[0..5000_000, int]
proc ap(x: var TA) = x.a = -1
proc bp(x: var TB) = x.b[high(x.b)] = -1
# in Nimrod proc (x: TB) is compatible to proc (x: TA),
# but this is not type safe:
var f = cast[proc (x: var TA) {.nimcall.}](bp)
var a: TA
f(a) # bp expects a TB, but gets a TA

15
tests/objects/tobject.nim Normal file
View File

@@ -0,0 +1,15 @@
import unittest
type Obj = object
foo: int
proc makeObj(x: int): Obj =
result.foo = x
suite "object basic methods":
test "it should convert an object to a string":
var obj = makeObj(1)
# Should be "obj: (foo: 1)" or similar.
check($obj == "(foo: 1)")
test "it should test equality based on fields":
check(makeObj(1) == makeObj(1))

View File

@@ -0,0 +1,21 @@
# Tests the object implementation
type
TPoint2d {.inheritable.} = object
x, y: int
TPoint3d = object of TPoint2d
z: int # added a field
proc getPoint( p: var TPoint2d) =
{.breakpoint.}
writeln(stdout, p.x)
var
p: TPoint3d
TPoint2d(p).x = 34
p.y = 98
p.z = 343
getPoint(p)

View File

@@ -0,0 +1,28 @@
type
TFoo = ref object of TObject
Data: int
TBar = ref object of TFoo
nil
TBar2 = ref object of TBar
d2: int
template super(self: TBar): TFoo = self
template super(self: TBar2): TBar = self
proc Foo(self: TFoo) =
echo "TFoo"
#proc Foo(self: TBar) =
# echo "TBar"
# Foo(super(self))
# works when this code is uncommented
proc Foo(self: TBar2) =
echo "TBar2"
Foo(super(self))
var b: TBar2
new(b)
Foo(b)

26
tests/objects/tofopr.nim Normal file
View File

@@ -0,0 +1,26 @@
discard """
file: "tofopr.nim"
output: "falsetrue"
"""
# Test is operator
type
TMyType = object {.inheritable.}
len: int
data: string
TOtherType = object of TMyType
proc p(x: TMyType): bool =
return x of TOtherType
var
m: TMyType
n: TOtherType
write(stdout, p(m))
write(stdout, p(n))
#OUT falsetrue

21
tests/objects/toop.nim Normal file
View File

@@ -0,0 +1,21 @@
discard """
output: "b"
"""
type
TA = object of TObject
x, y: int
TB = object of TA
z: int
TC = object of TB
whatever: string
proc p(a: var TA) = echo "a"
proc p(b: var TB) = echo "b"
var c: TC
p(c)

89
tests/objects/toop1.nim Normal file
View File

@@ -0,0 +1,89 @@
discard """
file: "toop1.nim"
output: "34[]o 5"
"""
# Test the stuff in the tutorial
import macros
type
TFigure = object of TObject # abstract base class:
draw: proc (my: var TFigure) {.nimcall.} # concrete classes implement this
proc init(f: var TFigure) =
f.draw = nil
type
TCircle = object of TFigure
radius: int
proc drawCircle(my: var TCircle) = stdout.writeln("o " & $my.radius)
proc init(my: var TCircle) =
init(TFigure(my)) # call base constructor
my.radius = 5
my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawCircle)
type
TRectangle = object of TFigure
width, height: int
proc drawRectangle(my: var TRectangle) = stdout.write("[]")
proc init(my: var TRectangle) =
init(TFigure(my)) # call base constructor
my.width = 5
my.height = 10
my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawRectangle)
macro `!` (n: expr): stmt {.immediate.} =
let n = callsite()
result = newNimNode(nnkCall, n)
var dot = newNimNode(nnkDotExpr, n)
dot.add(n[1]) # obj
if n[2].kind == nnkCall:
# transforms ``obj!method(arg1, arg2, ...)`` to
# ``(obj.method)(obj, arg1, arg2, ...)``
dot.add(n[2][0]) # method
result.add(dot)
result.add(n[1]) # obj
for i in 1..n[2].len-1:
result.add(n[2][i])
else:
# transforms ``obj!method`` to
# ``(obj.method)(obj)``
dot.add(n[2]) # method
result.add(dot)
result.add(n[1]) # obj
type
TSocket* = object of TObject
FHost: int # cannot be accessed from the outside of the module
# the `F` prefix is a convention to avoid clashes since
# the accessors are named `host`
proc `host=`*(s: var TSocket, value: int) {.inline.} =
## setter of hostAddr
s.FHost = value
proc host*(s: TSocket): int {.inline.} =
## getter of hostAddr
return s.FHost
var
s: TSocket
s.host = 34 # same as `host=`(s, 34)
stdout.write(s.host)
# now use these classes:
var
r: TRectangle
c: TCircle
init(r)
init(c)
r!draw
c!draw()
#OUT 34[]o 5