-
Notifications
You must be signed in to change notification settings - Fork 1
/
overload.t
77 lines (63 loc) · 1.92 KB
/
overload.t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
-- SPDX-FileCopyrightText: 2024 René Hiemstra <[email protected]>
-- SPDX-FileCopyrightText: 2024 Torsten Keßler <[email protected]>
--
-- SPDX-License-Identifier: MIT
local io = terralib.includec("stdio.h")
local Interface, AbstractSelf = unpack(require("interface"))
local struct S{
a: double
}
do
-- Free function are not avaible outside, only via the overloaded function.
local terra S_int(self: &S, a: int)
self.a = 23
end
local terra S_double(self: &S, a: double)
self.a = -23
end
-- Overloaded methods cannot be declared with the ":" notation, that is
-- S:foo = ...
-- Instead, we have to manually add them to the methods table of the struct
S.methods.foo = terralib.overloadedfunction("foo", {S_int, S_double})
end
do
-- We can always append definitions later
local terra S_float(self: &S, a: float)
self.a = 0
end
S.methods.foo:adddefinition(S_float)
end
terra S:bar()
return 1
end
-- Interfaces can check for members or methods. The latter can also be
-- overloaded.
local function MyInterface(T)
return Interface{
foo = {&AbstractSelf, T} -> {},
bar = &AbstractSelf -> int,
a = double
}
end
local InterfaceDouble = MyInterface(double)
local InterfaceInt = MyInterface(int)
local InterfaceFloat = MyInterface(float)
local InterfaceUInt = MyInterface(uint)
local res, msg = pcall(function(S) InterfaceDouble:isimplemented(S) end, S)
assert(res == true)
local res, msg = pcall(function(S) InterfaceInt:isimplemented(S) end, S)
assert(res == true)
local res, msg = pcall(function(S) InterfaceFloat:isimplemented(S) end, S)
assert(res == true)
local res, msg = pcall(function(S) InterfaceUInt:isimplemented(S) end, S)
assert(res == false)
terra main()
var s = S {}
s:foo(1)
io.printf("Int %g\n", s.a)
s:foo(1.0)
io.printf("Double %g\n", s.a)
s:foo(1.0f)
io.printf("Float %g\n", s.a)
end
main()