@@ -25,6 +25,24 @@ 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
+ }
37
+
38
+ public split<T>(self: &Self.T<T>, coin: &mut T, amount: u64): T {
39
+ let split: |&mut T, u64| (T);
40
+ let ret: T;
41
+ label b0:
42
+ split = *&move(self).T<T>::split;
43
+ ret = call_function_pointer<|&mut T, u64| (T)>(move(coin), move(amount), move(split));
44
+ return move(ret);
45
+ }
28
46
}
29
47
30
48
//# publish
@@ -80,6 +98,59 @@ module 0x42.BasicCoin1 {
80
98
}
81
99
}
82
100
101
+
102
+ //# publish
103
+ module 0x42.BasicCoin2 {
104
+ import 0x42.CoinInterface;
105
+
106
+ struct Coin has store, drop { value: u64 }
107
+
108
+ public zero(): Self.Coin {
109
+ label b0:
110
+ return Coin { value: 0 };
111
+ }
112
+
113
+ public mint(value: u64): Self.Coin {
114
+ label b0:
115
+ return Coin { value: move(value) };
116
+ }
117
+
118
+ public value(c: &Self.Coin): u64 {
119
+ label b0:
120
+ return *&move(c).Coin::value;
121
+ }
122
+
123
+ public merge(c: &mut Self.Coin, other: Self.Coin) {
124
+ let value: u64;
125
+ label b0:
126
+ Coin { value } = move(other);
127
+ *&mut move(c).Coin::value = (*©(c).Coin::value) + 1;
128
+ return;
129
+ }
130
+
131
+
132
+ public split(c: &mut Self.Coin, value: u64): Self.Coin {
133
+ let coin_value: u64;
134
+ label b0:
135
+ coin_value = *©(c).Coin::value;
136
+ assert(copy(coin_value) >= copy(value), 0);
137
+ *&mut copy(c).Coin::value = move(coin_value) - copy(value);
138
+ return Coin { value: move(value) };
139
+ }
140
+
141
+ public coin_interface(): CoinInterface.T<Self.Coin> {
142
+ let value: |&Self.Coin| (u64);
143
+ let split: |&mut Self.Coin, u64| (Self.Coin);
144
+ let merge: |&mut Self.Coin, Self.Coin| ();
145
+ let interface: CoinInterface.T<Self.Coin>;
146
+ label b0:
147
+ value = get_function_pointer(Self.value);
148
+ split = get_function_pointer(Self.split);
149
+ merge = get_function_pointer(Self.merge);
150
+ interface = CoinInterface.new_interface<Self.Coin>(move(value), move(split), move(merge));
151
+ return move(interface);
152
+ }
153
+ }
83
154
//# publish
84
155
module 0x42.CoinType {
85
156
struct Foo has drop {
@@ -91,13 +162,11 @@ module 0x42.CoinType {
91
162
module 0x42.GenericAdder {
92
163
import 0x42.CoinInterface;
93
164
public add_coins<T>(interface: &CoinInterface.T<T>, coin1: &T, coin2: &T): u64 {
94
- let value: |&T| (u64);
95
165
let v1: u64;
96
166
let v2: u64;
97
167
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));
168
+ v1 = CoinInterface.value<T>(copy(interface), move(coin1));
169
+ v2 = CoinInterface.value<T>(move(interface), move(coin2));
101
170
return move(v1) + move(v2);
102
171
}
103
172
}
@@ -123,3 +192,46 @@ label b0:
123
192
return;
124
193
}
125
194
195
+ //# run
196
+ import 0x42.CoinInterface;
197
+ import 0x42.BasicCoin2;
198
+ import 0x42.GenericAdder;
199
+
200
+ main() {
201
+ let interface: CoinInterface.T<BasicCoin2.Coin>;
202
+ let coin1: BasicCoin2.Coin;
203
+ let coin2: BasicCoin2.Coin;
204
+ let v: u64;
205
+ label b0:
206
+ coin1 = BasicCoin2.mint(10);
207
+ coin2 = BasicCoin2.mint(20);
208
+ interface = BasicCoin2.coin_interface();
209
+
210
+ v = GenericAdder.add_coins<BasicCoin2.Coin>(&interface, &coin1, &coin2);
211
+ assert(move(v) == 30, 0);
212
+ return;
213
+ }
214
+
215
+
216
+
217
+ //# run
218
+ import 0x42.CoinInterface;
219
+ import 0x42.BasicCoin2;
220
+ import 0x42.GenericAdder;
221
+
222
+ main() {
223
+ let interface: CoinInterface.T<BasicCoin2.Coin>;
224
+ let coin1: BasicCoin2.Coin;
225
+ let coin2: BasicCoin2.Coin;
226
+ let v: u64;
227
+ label b0:
228
+ coin1 = BasicCoin2.mint(10);
229
+ interface = BasicCoin2.coin_interface();
230
+
231
+ coin2 = CoinInterface.split<BasicCoin2.Coin>(&interface, &mut coin1, 5);
232
+ v = BasicCoin2.value(&coin2);
233
+
234
+ assert(move(v) == 5, 0);
235
+ return;
236
+ }
237
+
0 commit comments