@@ -25,6 +25,24 @@ module 0x42.CoinInterface {
2525 label b0:
2626 return *&move(self).T<T>::merge;
2727 }
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+ }
2846}
2947
3048//# publish
@@ -80,6 +98,59 @@ module 0x42.BasicCoin1 {
8098 }
8199}
82100
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+ }
83154//# publish
84155module 0x42.CoinType {
85156 struct Foo has drop {
@@ -91,13 +162,11 @@ module 0x42.CoinType {
91162module 0x42.GenericAdder {
92163 import 0x42.CoinInterface;
93164 public add_coins<T>(interface: &CoinInterface.T<T>, coin1: &T, coin2: &T): u64 {
94- let value: |&T| (u64);
95165 let v1: u64;
96166 let v2: u64;
97167 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));
101170 return move(v1) + move(v2);
102171 }
103172}
@@ -123,3 +192,46 @@ label b0:
123192 return;
124193}
125194
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