@@ -25,6 +25,15 @@ module 0x42.CoinInterface {
25
25
label b0:
26
26
return *&move(self).T<T>::merge;
27
27
}
28
+
29
+ public value<T>(self: &Self.T<T>, coin: &T): u64 {
30
+ let value: |&T| (u64);
31
+ let ret: u64;
32
+ label b0:
33
+ value = *&move(self).T<T>::value;
34
+ ret = call_function_pointer<|&T| (u64)>(move(coin), move(value));
35
+ return move(ret);
36
+ }
28
37
}
29
38
30
39
//# publish
@@ -80,6 +89,59 @@ module 0x42.BasicCoin1 {
80
89
}
81
90
}
82
91
92
+
93
+ //# publish
94
+ module 0x42.BasicCoin2 {
95
+ import 0x42.CoinInterface;
96
+
97
+ struct Coin has store, drop { value: u64 }
98
+
99
+ public zero(): Self.Coin {
100
+ label b0:
101
+ return Coin { value: 0 };
102
+ }
103
+
104
+ public mint(value: u64): Self.Coin {
105
+ label b0:
106
+ return Coin { value: move(value) };
107
+ }
108
+
109
+ public value(c: &Self.Coin): u64 {
110
+ label b0:
111
+ return *&move(c).Coin::value;
112
+ }
113
+
114
+ public merge(c: &mut Self.Coin, other: Self.Coin) {
115
+ let value: u64;
116
+ label b0:
117
+ Coin { value } = move(other);
118
+ *&mut move(c).Coin::value = (*©(c).Coin::value) + 1;
119
+ return;
120
+ }
121
+
122
+
123
+ public split(c: &mut Self.Coin, value: u64): Self.Coin {
124
+ let coin_value: u64;
125
+ label b0:
126
+ coin_value = *©(c).Coin::value;
127
+ assert(copy(coin_value) >= copy(value), 0);
128
+ *&mut copy(c).Coin::value = move(coin_value) - copy(value);
129
+ return Coin { value: move(value) };
130
+ }
131
+
132
+ public coin_interface(): CoinInterface.T<Self.Coin> {
133
+ let value: |&Self.Coin| (u64);
134
+ let split: |&mut Self.Coin, u64| (Self.Coin);
135
+ let merge: |&mut Self.Coin, Self.Coin| ();
136
+ let interface: CoinInterface.T<Self.Coin>;
137
+ label b0:
138
+ value = get_function_pointer(Self.value);
139
+ split = get_function_pointer(Self.split);
140
+ merge = get_function_pointer(Self.merge);
141
+ interface = CoinInterface.new_interface<Self.Coin>(move(value), move(split), move(merge));
142
+ return move(interface);
143
+ }
144
+ }
83
145
//# publish
84
146
module 0x42.CoinType {
85
147
struct Foo has drop {
@@ -91,13 +153,11 @@ module 0x42.CoinType {
91
153
module 0x42.GenericAdder {
92
154
import 0x42.CoinInterface;
93
155
public add_coins<T>(interface: &CoinInterface.T<T>, coin1: &T, coin2: &T): u64 {
94
- let value: |&T| (u64);
95
156
let v1: u64;
96
157
let v2: u64;
97
158
label b0:
98
- value = CoinInterface.value_func<T>(move(interface));
99
- v1 = call_function_pointer<|&T| (u64)>(move(coin1), copy(value));
100
- v2 = call_function_pointer<|&T| (u64)>(move(coin2), copy(value));
159
+ v1 = CoinInterface.value<T>(copy(interface), move(coin1));
160
+ v2 = CoinInterface.value<T>(move(interface), move(coin2));
101
161
return move(v1) + move(v2);
102
162
}
103
163
}
@@ -123,3 +183,23 @@ label b0:
123
183
return;
124
184
}
125
185
186
+ //# run
187
+ import 0x42.CoinInterface;
188
+ import 0x42.BasicCoin2;
189
+ import 0x42.GenericAdder;
190
+
191
+ main() {
192
+ let interface: CoinInterface.T<BasicCoin2.Coin>;
193
+ let coin1: BasicCoin2.Coin;
194
+ let coin2: BasicCoin2.Coin;
195
+ let v: u64;
196
+ label b0:
197
+ coin1 = BasicCoin2.mint(10);
198
+ coin2 = BasicCoin2.mint(20);
199
+ interface = BasicCoin2.coin_interface();
200
+
201
+ v = GenericAdder.add_coins<BasicCoin2.Coin>(&interface, &coin1, &coin2);
202
+ assert(move(v) == 30, 0);
203
+ return;
204
+ }
205
+
0 commit comments