diff options
author | Zahary Karadjov <zahary@gmail.com> | 2012-10-15 16:36:00 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2012-10-15 21:00:29 +0300 |
commit | 3c9e3a6a716326c48e509e7b09596e2a1bf900fa (patch) | |
tree | 23e098d426ec369ef49215ffb50e147a65117963 /tests/run | |
parent | 7424a60ba103fc5a6ddcee71a771e8a68c4699a7 (diff) | |
download | Nim-3c9e3a6a716326c48e509e7b09596e2a1bf900fa.tar.gz |
Improved support for nkSymChoices in type coercions
For example, this allows you to pick up a proc with a specific signature from an overload set. bugfix: nimrod generated invalid code when a RVO function had a single compile-time param bugfix: nkHiddenDerefs were not neutralised properly for indirect proc calls
Diffstat (limited to 'tests/run')
-rwxr-xr-x | tests/run/tvtable.nim | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/tests/run/tvtable.nim b/tests/run/tvtable.nim new file mode 100755 index 000000000..36b67277a --- /dev/null +++ b/tests/run/tvtable.nim @@ -0,0 +1,74 @@ +discard """ + output: ''' +OBJ 1 foo +10 +OBJ 1 bar +OBJ 2 foo +5 +OBJ 2 bar +''' +""" + +type + # these are the signatures of the virtual procs for each type + fooProc[T] = proc (o: var T): int + barProc[T] = proc (o: var T) + + # an untyped table to store the proc pointers + # it's also possible to use a strontly typed tuple here + VTable = array[0..1, pointer] + + TBase = object {.inheritable.} + vtbl: ptr VTable + + TUserObject1 = object of TBase + x: int + + TUserObject2 = object of TBase + y: int + +proc foo(o: var TUserObject1): int = + echo "OBJ 1 foo" + return 10 + +proc bar(o: var TUserObject1) = + echo "OBJ 1 bar" + +proc foo(o: var TUserObject2): int = + echo "OBJ 2 foo" + return 5 + +proc bar(o: var TUserObject2) = + echo "OBJ 2 bar" + +proc getVTable(T: typedesc): ptr VTable = + # pay attention to what's going on here + # this will initialize the vtable for each type at program start-up + # + # fooProc[T](foo) is a type coercion - it looks for a proc named foo + # matching the signature fooProc[T] (e.g. proc (o: var TUserObject1): int) + var vtbl {.global.} = [ + cast[pointer](fooProc[T](foo)), + cast[pointer](barProc[T](bar)) + ] + + return vtbl.addr + +proc create(T: typedesc): T = + result.vtbl = getVTable(T) + +proc baseFoo(o: var TBase): int = + return cast[fooProc[TBase]](o.vtbl[0]) (o) + +proc baseBar(o: var TBase) = + cast[barProc[TBase]](o.vtbl[1]) (o) + +var a = TUserObject1.create +var b = TUserObject2.create + +echo a.baseFoo +a.baseBar + +echo b.baseFoo +b.baseBar + |