Skip to content

Commit 303e92b

Browse files
authored
Merge pull request #1559 from ton-blockchain/tolk-v0.10
Tolk v0.10: preparing for serialization; types `intN`, `bytesN`, `coins`
2 parents 020dbc8 + 6ba2355 commit 303e92b

File tree

244 files changed

+2123
-864
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

244 files changed

+2123
-864
lines changed

crypto/smartcont/tolk-stdlib/common.tolk

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Standard library for Tolk (LGPL licence).
22
// It contains common functions that are available out of the box, the user doesn't have to import anything.
33
// More specific functions are required to be imported explicitly, like "@stdlib/tvm-dicts".
4-
tolk 0.9
4+
tolk 0.10
55

66
/**
77
Tuple manipulation primitives.
@@ -54,6 +54,13 @@ fun tupleLast<T>(self: tuple): T
5454
Mathematical primitives.
5555
*/
5656

57+
/// Converts a constant floating-point string to nanotoncoins.
58+
/// Example: `ton("0.05")` is equal to 50000000.
59+
/// Note, that `ton()` requires a constant string; `ton(some_var)` is an error
60+
@pure
61+
fun ton(floatString: slice): coins
62+
builtin;
63+
5764
/// Computes the minimum of two integers.
5865
@pure
5966
fun min(x: int, y: int): int
@@ -187,6 +194,42 @@ fun commitContractDataAndActions(): void
187194
Signature checks, hashing, cryptography.
188195
*/
189196

197+
/// Compile-time function that calculates crc32 of a constant string.
198+
/// Example: `const op = stringCrc32("some_str")` = 4013618352 = 0xEF3AF4B0
199+
/// Note: stringCrc32(slice_var) does not work! It accepts a constant string and works at compile-time.
200+
@pure
201+
fun stringCrc32(constString: slice): int
202+
builtin;
203+
204+
/// Compile-time function that calculates crc16 (XMODEM) of a constant string.
205+
/// Example: `const op = stringCrc16("some_str")` = 53407 = 0xD09F
206+
/// Note: stringCrc16(slice_var) does not work! It accepts a constant string and works at compile-time.
207+
@pure
208+
fun stringCrc16(constString: slice): int
209+
builtin;
210+
211+
/// Compile-time function that calculates sha256 of a constant string and returns 256-bit integer.
212+
/// Example: `const hash = stringSha256("some_crypto_key")`
213+
/// Note: it's a compile-time function, `stringSha256(slice_var)` does not work.
214+
/// Use `sliceBitsHash` or `sliceHash` (declared below) to hash a slice without/with its refs at runtime.
215+
@pure
216+
fun stringSha256(constString: slice): int
217+
builtin;
218+
219+
/// Compile-time function that calculates sha256 of a constant string and takes the first 32 bits.
220+
/// Example: `const minihash = stringSha256_32("some_crypto_key")`
221+
/// Note: stringSha256_32(slice_var) does not work! It accepts a constant string and works at compile-time.
222+
@pure
223+
fun stringSha256_32(constString: slice): int
224+
builtin;
225+
226+
/// Compile-time function that takes N-chars ascii string and interprets it as a number in base 256.
227+
/// Example: `const value = stringToBase256("AB")` = 16706 (65*256 + 66)
228+
/// Note: stringToBase256(slice_var) does not work! It accepts a constant string and works at compile-time.
229+
@pure
230+
fun stringToBase256(constString: slice): int
231+
builtin;
232+
190233
/// Computes the representation hash of a `cell` [c] and returns it as a 256-bit unsigned integer `x`.
191234
/// Useful for signing and checking signatures of arbitrary entities represented by a tree of cells.
192235
@pure
@@ -203,7 +246,7 @@ fun sliceHash(s: slice): int
203246
/// Computes sha256 of the data bits of `slice` [s]. If the bit length of `s` is not divisible by eight,
204247
/// throws a cell underflow exception. The hash value is returned as a 256-bit unsigned integer `x`.
205248
@pure
206-
fun stringHash(s: slice): int
249+
fun sliceBitsHash(s: slice): int
207250
asm "SHA256U";
208251

209252
/// Checks the Ed25519-`signature` of a `hash` (a 256-bit unsigned integer, usually computed as the hash of some data)
@@ -333,6 +376,22 @@ fun debugDumpStack(): void
333376
When you _preload_ some data, you just get the result without mutating the slice.
334377
*/
335378

379+
/// Compile-time function that converts a constant string to TL-encoded MsgAddressInt (TVM slice).
380+
/// Example: stringAddressToSlice("EQCRDM9h4k3UJdOePPuyX40mCgA4vxge5Dc5vjBR8djbEKC5")
381+
/// Example: stringAddressToSlice("0:527964d55cfa6eb731f4bfc07e9d025098097ef8505519e853986279bd8400d8")
382+
/// Note: it's a compile-time function, `stringAddressToSlice(slice_var)` does not work.
383+
/// Use `parseStandardAddress` to decode a slice at runtime into workchain and hash.
384+
@pure
385+
fun stringAddressToSlice(constStringAddress: slice): slice
386+
builtin;
387+
388+
/// Compile-time function that converts a constant hex-encoded string to N/2 bytes.
389+
/// Example: `const v = stringHexToSlice("abcdef")` = slice with 3 bytes `[ 0xAB, 0xCD, 0xEF ]`
390+
/// Note: stringHexToSlice(slice_var) does not work! It accepts a constant string and works at compile-time.
391+
@pure
392+
fun stringHexToSlice(constStringBytesHex: slice): slice
393+
builtin;
394+
336395
/// Converts a `cell` [c] into a `slice`. Notice that [c] must be either an ordinary cell,
337396
/// or an exotic cell (see [TVM.pdf](https://ton-blockchain.github.io/docs/tvm.pdf), 3.1.2)
338397
/// which is automatically loaded to yield an ordinary cell `c'`, converted into a `slice` afterwards.
@@ -386,7 +445,7 @@ fun preloadBits(self: slice, len: int): slice
386445

387446
/// Loads serialized amount of Toncoins (any unsigned integer up to `2^120 - 1`).
388447
@pure
389-
fun loadCoins(mutate self: slice): int
448+
fun loadCoins(mutate self: slice): coins
390449
asm( -> 1 0) "LDGRAMS";
391450

392451
/// Loads bool (-1 or 0) from a slice
@@ -485,7 +544,7 @@ fun storeSlice(mutate self: builder, s: slice): self
485544

486545
/// Stores amount of Toncoins into a builder.
487546
@pure
488-
fun storeCoins(mutate self: builder, x: int): self
547+
fun storeCoins(mutate self: builder, x: coins): self
489548
asm "STGRAMS";
490549

491550
/// Stores bool (-1 or 0) into a builder.

crypto/smartcont/tolk-stdlib/gas-payments.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// A part of standard library for Tolk
2-
tolk 0.9
2+
tolk 0.10
33

44
/**
55
Gas and payment related primitives.

crypto/smartcont/tolk-stdlib/lisp-lists.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// A part of standard library for Tolk
2-
tolk 0.9
2+
tolk 0.10
33

44
/**
55
Lisp-style lists are nested 2-elements tuples: `(1, (2, (3, null)))` represents list `[1, 2, 3]`.

crypto/smartcont/tolk-stdlib/tvm-dicts.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// A part of standard library for Tolk
2-
tolk 0.9
2+
tolk 0.10
33

44
/**
55
Dictionaries are represented as `cell` data type (cells can store anything, dicts in particular).

crypto/smartcont/tolk-stdlib/tvm-lowlevel.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// A part of standard library for Tolk
2-
tolk 0.9
2+
tolk 0.10
33

44
/// Usually `c3` has a continuation initialized by the whole code of the contract. It is used for function calls.
55
/// The primitive returns the current value of `c3`.

tolk-tester/tests/a6.tolk renamed to tolk-tester/tests/a-tests.tolk

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ fun f(a: int, b: int, c: int, d: int, e: int, f: int): (int, int) {
44
__expect_type(D, "int");
55
__expect_type(D*D, "int");
66
__expect_type(calc_phi, "() -> int");
7-
return (Dx/D,Dy/D);
7+
return (Dx/D,Dy/D,);
88
};;;;
99

1010
fun calc_phi(): int {
@@ -16,7 +16,7 @@ fun calc_phi(): int {
1616
do {
1717
(p,q)=(q,p+q);
1818
} while (q <= n); //;;
19-
return mulDivRound(p, n, q);
19+
return mulDivRound(p, n, q,);
2020
}
2121

2222
fun calc_sqrt2(): int {
@@ -31,10 +31,10 @@ fun calc_sqrt2(): int {
3131
return mulDivRound(p, n, q);
3232
}
3333

34-
fun calc_root(m: int) {
34+
fun calc_root(m: int,) {
3535
var base: int=1;
3636
repeat(70) { base *= 10; }
37-
var (a, b, c) = (1,0,-m);
37+
var (a, b, c) = (1,0,-m,);
3838
var (p1, q1, p2, q2) = (1, 0, 0, 1);
3939
do {
4040
var k: int=-1;
@@ -76,7 +76,7 @@ fun main(): int {
7676
}
7777

7878
/**
79-
method_id | in | out
79+
method_id | in | out
8080
@testcase | 0 | | 31415926535897932384626433832795028841971693993751058209749445923078164
8181

8282
@code_hash 84337043972311674339187056298873613816389434478842780265748859098303774481976

tolk-tester/tests/a6_1.tolk

Lines changed: 0 additions & 22 deletions
This file was deleted.

tolk-tester/tests/a6_5.tolk

Lines changed: 0 additions & 26 deletions
This file was deleted.

tolk-tester/tests/a7.tolk

Lines changed: 0 additions & 24 deletions
This file was deleted.

tolk-tester/tests/allow_post_modification.tolk renamed to tolk-tester/tests/allow-post-modification.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ fun test_call_1(x: int): (int, int, int, int, int, int, int) {
4747
return foo1(x, x.`~inc`(x / 20), x, x = x * 2, x, x += 1, x);
4848
}
4949

50-
fun foo2(x1: int, x2: int, x3456: (int, int, int, int), x7: int): (int, int, int, int, int, int, int) {
50+
fun foo2(x1: int, x2: int, x3456: (int, int, int, int), x7: int, ): (int, int, int, int, int, int, int) {
5151
var (x3: int, x4: int, x5: int, x6: int) = x3456;
5252
return (x1, x2, x3, x4, x5, x6, x7);
5353
}

tolk-tester/tests/assignment-tests.tolk

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ fun extractFromTypedTuple(params: [int]) {
55

66
@method_id(101)
77
fun test101(x: int) {
8-
var params = [x];
8+
var params = [x, ];
99
return extractFromTypedTuple(params);
1010
}
1111

@@ -38,7 +38,7 @@ fun getTensor_1X(x: int) {
3838
}
3939
fun getTuple_12() {
4040
callOrder.tuplePush(110);
41-
return [1, 2];
41+
return [1, 2, ];
4242
}
4343
fun getTuple_1X(x: int) {
4444
callOrder.tuplePush(111);
@@ -133,7 +133,7 @@ fun test108() {
133133
fun test109() {
134134
callOrder = createEmptyTuple();
135135
var x = 0;
136-
[getTuple_12().0, getTuple_1X(x = getIntValue5()).1, getTuple_1X(x += 10).0] = [getIntValue5(), getIntValue5(), getIntValueX(x)];
136+
[getTuple_12().0, getTuple_1X(x = getIntValue5()).1, getTuple_1X(x += 10).0] = [getIntValue5(), getIntValue5(), getIntValueX(x), ];
137137
return (callOrder, x);
138138
}
139139

@@ -203,9 +203,18 @@ fun test116() {
203203
return (a, b, c, d, rhs2);
204204
}
205205

206+
@method_id(117)
207+
fun test117() {
208+
var c = [((1, ), ), ];
209+
__expect_type(c, "[int]");
210+
c.0 = 10;
211+
c.0 = (20, );
212+
return c;
213+
}
214+
206215

207216

208-
fun main(value: int) {
217+
fun main(value: int, ) {
209218
var (x: int?, y) = (autoInferIntNull(value), autoInferIntNull(value * 2));
210219
if (x == null && y == null) { return null; }
211220
return x == null || y == null ? -1 : x! + y!;
@@ -231,6 +240,7 @@ fun main(value: int) {
231240
@testcase | 114 | | 13 [ 1 14 ] 1 3
232241
@testcase | 115 | | [ 101 111 ] 9 9
233242
@testcase | 116 | | 1 2 3 4 [ 1 2 3 4 ]
243+
@testcase | 117 | | [ 20 ]
234244

235245

236246
@fif_codegen

tolk-tester/tests/bytesN-tests.tolk

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
fun takeAnySlice(slice: slice) {}
2+
fun getSomeSlice() { return beginCell().endCell().beginParse(); }
3+
fun getNullableBytes16(): bytes16? { return getSomeSlice() as bytes16; }
4+
5+
const someBytes = "asdf" as bytes16;
6+
const anotherBytes: bytes16 = "asdf" as bytes16;
7+
8+
fun autoInferBytes16() {
9+
if (random()) { return someBytes; }
10+
else if (random()) { return true ? "" as bytes16 : anotherBytes; }
11+
else { return someBytes!; }
12+
}
13+
14+
@method_id(101)
15+
fun test1() {
16+
var ss = beginCell().storeInt(1, 32).storeInt(2, 32).endCell().beginParse() as bits32;
17+
__expect_type(ss, "bits32");
18+
__expect_type(ss as slice, "slice");
19+
__expect_type(ss as slice?, "slice?");
20+
__expect_type(ss as bytes128, "bytes128");
21+
__expect_type(someBytes, "bytes16");
22+
__expect_type(10>3 ? (null, ss as bits1) : (ss as bytes1, null), "(bytes1?, bits1?)");
23+
return (getRemainingBitsCount(ss as slice), loadInt(mutate ss as slice, 32), (ss as slice).loadInt(32));
24+
}
25+
26+
fun test2(a: bytes8, b: bits64) {
27+
a = b as bytes8;
28+
b = a as bits64;
29+
(a as slice).loadRef();
30+
(b as slice?)!.loadRef();
31+
}
32+
33+
@method_id(103)
34+
fun test3() {
35+
var slice = beginCell().storeInt(1, 32).storeInt(2, 32).endCell().beginParse();
36+
var bq = slice as bits16?;
37+
if (bq != null) {
38+
return (bq as slice).loadInt(32 as uint8) + (slice = bq as slice).getRemainingBitsCount();
39+
}
40+
return -1;
41+
}
42+
43+
fun main() {}
44+
45+
/**
46+
@testcase | 101 | | 64 1 2
47+
@testcase | 103 | | 33
48+
*/

0 commit comments

Comments
 (0)